summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2013-08-25 21:54:41 +0000
committermarkj <markj@FreeBSD.org>2013-08-25 21:54:41 +0000
commit29e4661920638221bbffb4c527fb24daa4702b4c (patch)
treec2b1016fdbcd18b8a7c9f33a21b6c2bb2b755348 /sys/netinet
parent03a89a5fe0a80e1df50027d7d94266daffa41805 (diff)
downloadFreeBSD-src-29e4661920638221bbffb4c527fb24daa4702b4c.zip
FreeBSD-src-29e4661920638221bbffb4c527fb24daa4702b4c.tar.gz
Implement the ip, tcp, and udp DTrace providers. The probe definitions use
dynamic translation so that their arguments match the definitions for these providers in Solaris and illumos. Thus, existing scripts for these providers should work unmodified on FreeBSD. Tested by: gnn, hiren MFC after: 1 month
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_kdtrace.c127
-rw-r--r--sys/netinet/in_kdtrace.h59
-rw-r--r--sys/netinet/ip_fastfwd.c5
-rw-r--r--sys/netinet/ip_input.c5
-rw-r--r--sys/netinet/ip_output.c7
-rw-r--r--sys/netinet/tcp_input.c40
-rw-r--r--sys/netinet/tcp_output.c20
-rw-r--r--sys/netinet/tcp_subr.c27
-rw-r--r--sys/netinet/tcp_syncache.c2
-rw-r--r--sys/netinet/tcp_usrreq.c14
-rw-r--r--sys/netinet/tcp_var.h1
-rw-r--r--sys/netinet/udp_usrreq.c7
-rw-r--r--sys/netinet/udp_var.h1
13 files changed, 294 insertions, 21 deletions
diff --git a/sys/netinet/in_kdtrace.c b/sys/netinet/in_kdtrace.c
new file mode 100644
index 0000000..85a5a4e
--- /dev/null
+++ b/sys/netinet/in_kdtrace.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2013 Mark Johnston <markj@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_kdtrace.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sdt.h>
+
+SDT_PROVIDER_DEFINE(ip);
+SDT_PROVIDER_DEFINE(tcp);
+SDT_PROVIDER_DEFINE(udp);
+
+SDT_PROBE_DEFINE6_XLATE(ip, , , receive, receive,
+ "void *", "pktinfo_t *",
+ "void *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct ifnet *", "ifinfo_t *",
+ "struct ip *", "ipv4info_t *",
+ "struct ip6_hdr *", "ipv6info_t *");
+
+SDT_PROBE_DEFINE6_XLATE(ip, , , send, send,
+ "void *", "pktinfo_t *",
+ "void *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct ifnet *", "ifinfo_t *",
+ "struct ip *", "ipv4info_t *",
+ "struct ip6_hdr *", "ipv6info_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , accept_established, accept-established,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , accept_refused, accept-refused,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , connect_established, connect-established,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , connect_refused, connect-refused,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , connect_request, connect-request,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , receive, receive,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(tcp, , , send, send,
+ "void *", "pktinfo_t *",
+ "struct tcpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct tcpcb *", "tcpsinfo_t *" ,
+ "struct tcphdr *", "tcpinfo_t *");
+
+SDT_PROBE_DEFINE6_XLATE(tcp, , , state_change, state-change,
+ "void *", "void *",
+ "struct tcpcb *", "csinfo_t *",
+ "void *", "void *",
+ "struct tcpcb *", "tcpsinfo_t *",
+ "void *", "void *",
+ "int", "tcplsinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(udp, , , receive, receive,
+ "void *", "pktinfo_t *",
+ "struct inpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct inpcb *", "udpsinfo_t *",
+ "struct udphdr *", "udpinfo_t *");
+
+SDT_PROBE_DEFINE5_XLATE(udp, , , send, send,
+ "void *", "pktinfo_t *",
+ "struct inpcb *", "csinfo_t *",
+ "uint8_t *", "ipinfo_t *",
+ "struct inpcb *", "udpsinfo_t *",
+ "struct udphdr *", "udpinfo_t *");
diff --git a/sys/netinet/in_kdtrace.h b/sys/netinet/in_kdtrace.h
new file mode 100644
index 0000000..1759fac
--- /dev/null
+++ b/sys/netinet/in_kdtrace.h
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2013 Mark Johnston <markj@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_IN_KDTRACE_H_
+#define _SYS_IN_KDTRACE_H_
+
+#define IP_PROBE(probe, arg0, arg1, arg2, arg3, arg4, arg5) \
+ SDT_PROBE6(ip, , , probe, arg0, arg1, arg2, arg3, arg4, arg5)
+#define UDP_PROBE(probe, arg0, arg1, arg2, arg3, arg4) \
+ SDT_PROBE5(udp, , , probe, arg0, arg1, arg2, arg3, arg4)
+#define TCP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4) \
+ SDT_PROBE5(tcp, , , probe, arg0, arg1, arg2, arg3, arg4)
+#define TCP_PROBE6(probe, arg0, arg1, arg2, arg3, arg4, arg5) \
+ SDT_PROBE6(tcp, , , probe, arg0, arg1, arg2, arg3, arg4, arg5)
+
+SDT_PROVIDER_DECLARE(ip);
+SDT_PROVIDER_DECLARE(tcp);
+SDT_PROVIDER_DECLARE(udp);
+
+SDT_PROBE_DECLARE(ip, , , receive);
+SDT_PROBE_DECLARE(ip, , , send);
+
+SDT_PROBE_DECLARE(tcp, , , accept_established);
+SDT_PROBE_DECLARE(tcp, , , accept_refused);
+SDT_PROBE_DECLARE(tcp, , , connect_established);
+SDT_PROBE_DECLARE(tcp, , , connect_refused);
+SDT_PROBE_DECLARE(tcp, , , connect_request);
+SDT_PROBE_DECLARE(tcp, , , receive);
+SDT_PROBE_DECLARE(tcp, , , send);
+SDT_PROBE_DECLARE(tcp, , , state_change);
+
+SDT_PROBE_DECLARE(udp, , , receive);
+SDT_PROBE_DECLARE(udp, , , send);
+
+#endif
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index 989318e..7d81475 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -78,6 +78,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ipfw.h"
#include "opt_ipstealth.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -85,6 +86,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
+#include <sys/sdt.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -97,6 +99,7 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
@@ -531,6 +534,7 @@ passout:
/*
* Send off the packet via outgoing interface
*/
+ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, &ro);
} else {
@@ -562,6 +566,7 @@ passout:
*/
m_clrprotoflags(m);
+ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
error = (*ifp->if_output)(ifp, m,
(struct sockaddr *)dst, &ro);
if (error)
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index ca55c5e..707d2be 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ipfw.h"
#include "opt_ipstealth.h"
#include "opt_ipsec.h"
+#include "opt_kdtrace.h"
#include "opt_route.h"
#include <sys/param.h>
@@ -49,6 +50,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/rwlock.h>
+#include <sys/sdt.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
@@ -63,6 +65,7 @@ __FBSDID("$FreeBSD$");
#include <net/flowtable.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
@@ -429,6 +432,8 @@ ip_input(struct mbuf *m)
ip = mtod(m, struct ip *);
}
+ IP_PROBE(receive, NULL, NULL, ip, m->m_pkthdr.rcvif, ip, NULL);
+
/* 127/8 must not appear on wire - RFC1122 */
ifp = m->m_pkthdr.rcvif;
if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 0a87e7a..464c852 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -34,9 +34,10 @@ __FBSDID("$FreeBSD$");
#include "opt_ipfw.h"
#include "opt_ipsec.h"
-#include "opt_route.h"
+#include "opt_kdtrace.h"
#include "opt_mbuf_stress_test.h"
#include "opt_mpath.h"
+#include "opt_route.h"
#include "opt_sctp.h"
#include <sys/param.h>
@@ -47,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
+#include <sys/sdt.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
@@ -64,6 +66,7 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
@@ -622,6 +625,7 @@ passout:
* to avoid confusing lower layers.
*/
m_clrprotoflags(m);
+ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
error = (*ifp->if_output)(ifp, m,
(const struct sockaddr *)gw, ro);
goto done;
@@ -656,6 +660,7 @@ passout:
*/
m_clrprotoflags(m);
+ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
error = (*ifp->if_output)(ifp, m,
(const struct sockaddr *)gw, ro);
} else
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 99bbbd3..0d7eb19 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
+#include "opt_kdtrace.h"
#include "opt_tcpdebug.h"
#include <sys/param.h>
@@ -63,6 +64,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/proc.h> /* for proc0 declaration */
#include <sys/protosw.h>
+#include <sys/sdt.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -82,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/cc.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -688,7 +691,10 @@ tcp_input(struct mbuf *m, int off0)
bzero(ipov->ih_x1, sizeof(ipov->ih_x1));
ipov->ih_len = htons(tlen);
th->th_sum = in_cksum(m, len);
+ /* Reset length for SDT probes. */
+ ip->ip_len = htons(tlen + off0);
}
+
if (th->th_sum) {
TCPSTAT_INC(tcps_rcvbadsum);
goto drop;
@@ -1384,6 +1390,8 @@ relocked:
}
#endif
+ TCP_PROBE5(receive, NULL, tp, m->m_data, tp, th);
+
/*
* Segment belongs to a connection in SYN_SENT, ESTABLISHED or later
* state. tcp_do_segment() always consumes the mbuf chain, unlocks
@@ -1394,6 +1402,8 @@ relocked:
return;
dropwithreset:
+ TCP_PROBE5(receive, NULL, tp, m->m_data, tp, th);
+
if (ti_locked == TI_WLOCKED) {
INP_INFO_WUNLOCK(&V_tcbinfo);
ti_locked = TI_UNLOCKED;
@@ -1415,6 +1425,9 @@ dropwithreset:
goto drop;
dropunlock:
+ if (m != NULL)
+ TCP_PROBE5(receive, NULL, tp, m->m_data, tp, th);
+
if (ti_locked == TI_WLOCKED) {
INP_INFO_WUNLOCK(&V_tcbinfo);
ti_locked = TI_UNLOCKED;
@@ -1910,8 +1923,11 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
rstreason = BANDLIM_UNLIMITED;
goto dropwithreset;
}
- if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST))
+ if ((thflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) {
+ TCP_PROBE5(connect_refused, NULL, tp, m->m_data, tp,
+ th);
tp = tcp_drop(tp, ECONNREFUSED);
+ }
if (thflags & TH_RST)
goto drop;
if (!(thflags & TH_SYN))
@@ -1956,11 +1972,13 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
tp->t_starttime = ticks;
if (tp->t_flags & TF_NEEDFIN) {
- tp->t_state = TCPS_FIN_WAIT_1;
+ tcp_state_change(tp, TCPS_FIN_WAIT_1);
tp->t_flags &= ~TF_NEEDFIN;
thflags &= ~TH_SYN;
} else {
- tp->t_state = TCPS_ESTABLISHED;
+ tcp_state_change(tp, TCPS_ESTABLISHED);
+ TCP_PROBE5(connect_established, NULL, tp,
+ m->m_data, tp, th);
cc_conn_init(tp);
tcp_timer_activate(tp, TT_KEEP,
TP_KEEPIDLE(tp));
@@ -1978,7 +1996,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
tp->t_flags |= (TF_ACKNOW | TF_NEEDSYN);
tcp_timer_activate(tp, TT_REXMT, 0);
- tp->t_state = TCPS_SYN_RECEIVED;
+ tcp_state_change(tp, TCPS_SYN_RECEIVED);
}
KASSERT(ti_locked == TI_WLOCKED, ("%s: trimthenstep6: "
@@ -2116,7 +2134,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
ti_locked));
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
- tp->t_state = TCPS_CLOSED;
+ tcp_state_change(tp, TCPS_CLOSED);
TCPSTAT_INC(tcps_drops);
tp = tcp_close(tp);
break;
@@ -2361,10 +2379,12 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
tp->t_starttime = ticks;
if (tp->t_flags & TF_NEEDFIN) {
- tp->t_state = TCPS_FIN_WAIT_1;
+ tcp_state_change(tp, TCPS_FIN_WAIT_1);
tp->t_flags &= ~TF_NEEDFIN;
} else {
- tp->t_state = TCPS_ESTABLISHED;
+ tcp_state_change(tp, TCPS_ESTABLISHED);
+ TCP_PROBE5(accept_established, NULL, tp, m->m_data, tp,
+ th);
cc_conn_init(tp);
tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp));
}
@@ -2752,7 +2772,7 @@ process_ACK:
tcp_finwait2_timeout :
TP_MAXIDLE(tp)));
}
- tp->t_state = TCPS_FIN_WAIT_2;
+ tcp_state_change(tp, TCPS_FIN_WAIT_2);
}
break;
@@ -2978,7 +2998,7 @@ dodata: /* XXX */
tp->t_starttime = ticks;
/* FALLTHROUGH */
case TCPS_ESTABLISHED:
- tp->t_state = TCPS_CLOSE_WAIT;
+ tcp_state_change(tp, TCPS_CLOSE_WAIT);
break;
/*
@@ -2986,7 +3006,7 @@ dodata: /* XXX */
* enter the CLOSING state.
*/
case TCPS_FIN_WAIT_1:
- tp->t_state = TCPS_CLOSING;
+ tcp_state_change(tp, TCPS_CLOSING);
break;
/*
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index b4342f3..00d5415 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
+#include "opt_kdtrace.h"
#include "opt_tcpdebug.h"
#include <sys/param.h>
@@ -46,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/protosw.h>
+#include <sys/sdt.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
@@ -56,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/cc.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
@@ -1174,6 +1177,18 @@ send:
*/
ip6->ip6_hlim = in6_selecthlim(tp->t_inpcb, NULL);
+ /*
+ * Set the packet size here for the benefit of DTrace probes.
+ * ip6_output() will set it properly; it's supposed to include
+ * the option header lengths as well.
+ */
+ ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6));
+
+ if (tp->t_state == TCPS_SYN_SENT)
+ TCP_PROBE5(connect_request, NULL, tp, ip6, tp, th);
+
+ TCP_PROBE5(send, NULL, tp, ip6, tp, th);
+
/* TODO: IPv6 IP6TOS_ECT bit on */
error = ip6_output(m, tp->t_inpcb->in6p_outputopts, &ro,
((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0),
@@ -1208,6 +1223,11 @@ send:
if (V_path_mtu_discovery && tp->t_maxopd > V_tcp_minmss)
ip->ip_off |= htons(IP_DF);
+ if (tp->t_state == TCPS_SYN_SENT)
+ TCP_PROBE5(connect_request, NULL, tp, ip, tp, th);
+
+ TCP_PROBE5(send, NULL, tp, ip, tp, th);
+
error = ip_output(m, tp->t_inpcb->inp_options, &ro,
((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0,
tp->t_inpcb);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index c466bf4..5d37b50 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
+#include "opt_kdtrace.h"
#include "opt_tcpdebug.h"
#include <sys/param.h>
@@ -53,6 +54,7 @@ __FBSDID("$FreeBSD$");
#endif
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/sdt.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
@@ -66,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/cc.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -632,8 +635,8 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
ip6->ip6_flow = 0;
ip6->ip6_vfc = IPV6_VERSION;
ip6->ip6_nxt = IPPROTO_TCP;
- ip6->ip6_plen = 0; /* Set in ip6_output(). */
tlen += sizeof (struct ip6_hdr) + sizeof (struct tcphdr);
+ ip6->ip6_plen = htons(tlen - sizeof(*ip6));
}
#endif
#if defined(INET) && defined(INET6)
@@ -702,6 +705,10 @@ tcp_respond(struct tcpcb *tp, void *ipgen, struct tcphdr *th, struct mbuf *m,
if (tp == NULL || (inp->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_OUTPUT, 0, tp, mtod(m, void *), th, 0);
#endif
+ if (flags & TH_RST)
+ TCP_PROBE5(accept_refused, NULL, NULL, m->m_data, tp, nth);
+
+ TCP_PROBE5(send, NULL, tp, m->m_data, tp, nth);
#ifdef INET6
if (isipv6)
(void) ip6_output(m, NULL, NULL, ipflags, NULL, NULL, inp);
@@ -882,7 +889,7 @@ tcp_drop(struct tcpcb *tp, int errno)
INP_WLOCK_ASSERT(tp->t_inpcb);
if (TCPS_HAVERCVDSYN(tp->t_state)) {
- tp->t_state = TCPS_CLOSED;
+ tcp_state_change(tp, TCPS_CLOSED);
(void) tcp_output(tp);
TCPSTAT_INC(tcps_drops);
} else
@@ -2376,3 +2383,19 @@ tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th, void *ip4hdr,
panic("%s: string too long", __func__);
return (s);
}
+
+/*
+ * A subroutine which makes it easy to track TCP state changes with DTrace.
+ * This function shouldn't be called for t_state initializations that don't
+ * correspond to actual TCP state transitions.
+ */
+void
+tcp_state_change(struct tcpcb *tp, int newstate)
+{
+#if defined(KDTRACE_HOOKS)
+ int pstate = tp->t_state;
+#endif
+
+ tp->t_state = newstate;
+ TCP_PROBE6(state_change, NULL, tp, NULL, tp, NULL, pstate);
+}
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index cd7b424..1c27d7a 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -835,7 +835,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
#endif /* INET */
INP_HASH_WUNLOCK(&V_tcbinfo);
tp = intotcpcb(inp);
- tp->t_state = TCPS_SYN_RECEIVED;
+ tcp_state_change(tp, TCPS_SYN_RECEIVED);
tp->iss = sc->sc_iss;
tp->irs = sc->sc_irs;
tcp_rcvseqinit(tp);
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index ef0aad1..88755e7 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -367,7 +367,7 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td)
error = in_pcbbind(inp, (struct sockaddr *)0, td->td_ucred);
INP_HASH_WUNLOCK(&V_tcbinfo);
if (error == 0) {
- tp->t_state = TCPS_LISTEN;
+ tcp_state_change(tp, TCPS_LISTEN);
solisten_proto(so, backlog);
#ifdef TCP_OFFLOAD
if ((so->so_options & SO_NO_OFFLOAD) == 0)
@@ -412,7 +412,7 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td)
}
INP_HASH_WUNLOCK(&V_tcbinfo);
if (error == 0) {
- tp->t_state = TCPS_LISTEN;
+ tcp_state_change(tp, TCPS_LISTEN);
solisten_proto(so, backlog);
#ifdef TCP_OFFLOAD
if ((so->so_options & SO_NO_OFFLOAD) == 0)
@@ -1152,7 +1152,7 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
soisconnecting(so);
TCPSTAT_INC(tcps_connattempt);
- tp->t_state = TCPS_SYN_SENT;
+ tcp_state_change(tp, TCPS_SYN_SENT);
tp->iss = tcp_new_isn(tp);
tcp_sendseqinit(tp);
@@ -1224,7 +1224,7 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
soisconnecting(so);
TCPSTAT_INC(tcps_connattempt);
- tp->t_state = TCPS_SYN_SENT;
+ tcp_state_change(tp, TCPS_SYN_SENT);
tp->iss = tcp_new_isn(tp);
tcp_sendseqinit(tp);
@@ -1704,7 +1704,7 @@ tcp_usrclosed(struct tcpcb *tp)
#endif
/* FALLTHROUGH */
case TCPS_CLOSED:
- tp->t_state = TCPS_CLOSED;
+ tcp_state_change(tp, TCPS_CLOSED);
tp = tcp_close(tp);
/*
* tcp_close() should never return NULL here as the socket is
@@ -1720,11 +1720,11 @@ tcp_usrclosed(struct tcpcb *tp)
break;
case TCPS_ESTABLISHED:
- tp->t_state = TCPS_FIN_WAIT_1;
+ tcp_state_change(tp, TCPS_FIN_WAIT_1);
break;
case TCPS_CLOSE_WAIT:
- tp->t_state = TCPS_LAST_ACK;
+ tcp_state_change(tp, TCPS_LAST_ACK);
break;
}
if (tp->t_state >= TCPS_FIN_WAIT_2) {
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index cfba5d9..b22713f 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -701,6 +701,7 @@ struct inpcb *
struct tcpcb *
tcp_newtcpcb(struct inpcb *);
int tcp_output(struct tcpcb *);
+void tcp_state_change(struct tcpcb *, int);
void tcp_respond(struct tcpcb *, void *,
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
void tcp_tw_init(void);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index afd11e6..66aa6d4 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
+#include "opt_kdtrace.h"
#include <sys/param.h>
#include <sys/domain.h>
@@ -54,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/protosw.h>
+#include <sys/sdt.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -68,6 +70,7 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <netinet/in.h>
+#include <netinet/in_kdtrace.h>
#include <netinet/in_pcb.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -616,6 +619,8 @@ udp_input(struct mbuf *m, int off)
m_freem(m);
return;
}
+
+ UDP_PROBE(receive, NULL, inp, ip, ip, uh);
udp_append(inp, ip, m, iphlen, &udp_in);
INP_RUNLOCK(inp);
return;
@@ -1193,6 +1198,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
*/
ui = mtod(m, struct udpiphdr *);
bzero(ui->ui_x1, sizeof(ui->ui_x1)); /* XXX still needed? */
+ ui->ui_v = IPVERSION << 4;
ui->ui_pr = IPPROTO_UDP;
ui->ui_src = laddr;
ui->ui_dst = faddr;
@@ -1243,6 +1249,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
INP_HASH_WUNLOCK(&V_udbinfo);
else if (unlock_udbinfo == UH_RLOCKED)
INP_HASH_RUNLOCK(&V_udbinfo);
+ UDP_PROBE(send, NULL, inp, &ui->ui_i, inp, &ui->ui_u);
error = ip_output(m, inp->inp_options, NULL, ipflags,
inp->inp_moptions, inp);
if (unlock_udbinfo == UH_WLOCKED)
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index 0c26b88..461c986 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -42,6 +42,7 @@ struct udpiphdr {
struct udphdr ui_u; /* udp header */
};
#define ui_x1 ui_i.ih_x1
+#define ui_v ui_i.ih_x1[0]
#define ui_pr ui_i.ih_pr
#define ui_len ui_i.ih_len
#define ui_src ui_i.ih_src
OpenPOWER on IntegriCloud