diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2013-08-25 21:54:41 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2013-08-25 21:54:41 +0000 |
| commit | 57f6086735175ec16d6ba1b51128a7ae2dadd373 (patch) | |
| tree | c2b1016fdbcd18b8a7c9f33a21b6c2bb2b755348 /sys | |
| parent | ffeed888425ad57e8754ee30aa58e86c2a411470 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/conf/files | 1 | ||||
| -rw-r--r-- | sys/netinet/in_kdtrace.c | 127 | ||||
| -rw-r--r-- | sys/netinet/in_kdtrace.h | 59 | ||||
| -rw-r--r-- | sys/netinet/ip_fastfwd.c | 5 | ||||
| -rw-r--r-- | sys/netinet/ip_input.c | 5 | ||||
| -rw-r--r-- | sys/netinet/ip_output.c | 7 | ||||
| -rw-r--r-- | sys/netinet/tcp_input.c | 40 | ||||
| -rw-r--r-- | sys/netinet/tcp_output.c | 20 | ||||
| -rw-r--r-- | sys/netinet/tcp_subr.c | 27 | ||||
| -rw-r--r-- | sys/netinet/tcp_syncache.c | 2 | ||||
| -rw-r--r-- | sys/netinet/tcp_usrreq.c | 14 | ||||
| -rw-r--r-- | sys/netinet/tcp_var.h | 1 | ||||
| -rw-r--r-- | sys/netinet/udp_usrreq.c | 7 | ||||
| -rw-r--r-- | sys/netinet/udp_var.h | 1 | ||||
| -rw-r--r-- | sys/netinet6/ip6_input.c | 5 | ||||
| -rw-r--r-- | sys/netinet6/ip6_mroute.c | 5 | ||||
| -rw-r--r-- | sys/netinet6/nd6.c | 5 | ||||
| -rw-r--r-- | sys/netinet6/send.c | 6 | ||||
| -rw-r--r-- | sys/netinet6/udp6_usrreq.c | 8 |
19 files changed, 322 insertions, 23 deletions
diff --git a/sys/conf/files b/sys/conf/files index 6b811f3bbbc8..ec59771573ae 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3228,6 +3228,7 @@ netinet/if_ether.c optional inet ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_debug.c optional inet ddb +netinet/in_kdtrace.c optional inet | inet6 netinet/ip_carp.c optional inet carp | inet6 carp netinet/in_gif.c optional gif inet | netgraph_gif inet netinet/ip_gre.c optional gre inet diff --git a/sys/netinet/in_kdtrace.c b/sys/netinet/in_kdtrace.c new file mode 100644 index 000000000000..85a5a4ead495 --- /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 000000000000..1759fac5128c --- /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 989318ed35f2..7d8147566cd9 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 ca55c5e183de..707d2be2b2a2 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 0a87e7a3311b..464c85289e41 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 99bbbd3c41b6..0d7eb1933498 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 b4342f3b7b3f..00d541596b02 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 c466bf470c73..5d37b504707f 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 cd7b424e0b13..1c27d7a02187 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 ef0aad1639e6..88755e739dd3 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 cfba5d9ccdaf..b22713fc8da7 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 afd11e68c019..66aa6d418b94 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 0c26b88cd436..461c9861b697 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 diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 02bbf75b1b81..31f048f1886e 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" #include "opt_ipfw.h" #include "opt_ipsec.h" +#include "opt_kdtrace.h" #include "opt_route.h" #include <sys/param.h> @@ -76,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/domain.h> #include <sys/protosw.h> +#include <sys/sdt.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/errno.h> @@ -92,6 +94,7 @@ __FBSDID("$FreeBSD$"); #include <net/vnet.h> #include <netinet/in.h> +#include <netinet/in_kdtrace.h> #include <netinet/ip_var.h> #include <netinet/in_systm.h> #include <net/if_llatbl.h> @@ -538,6 +541,8 @@ ip6_input(struct mbuf *m) IP6STAT_INC(ip6s_nxthist[ip6->ip6_nxt]); + IP_PROBE(receive, NULL, NULL, ip6, m->m_pkthdr.rcvif, NULL, ip6); + /* * Check against address spoofing/corruption. */ diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 40c8c44c4db5..96346367aa8b 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" +#include "opt_kdtrace.h" #include <sys/param.h> #include <sys/callout.h> @@ -93,6 +94,7 @@ __FBSDID("$FreeBSD$"); #include <sys/module.h> #include <sys/domain.h> #include <sys/protosw.h> +#include <sys/sdt.h> #include <sys/signalvar.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -114,6 +116,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip_encap.h> #include <netinet/ip6.h> +#include <netinet/in_kdtrace.h> #include <netinet6/ip6_var.h> #include <netinet6/scope6_var.h> #include <netinet6/nd6.h> @@ -1644,6 +1647,8 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) dst6.sin6_len = sizeof(struct sockaddr_in6); dst6.sin6_family = AF_INET6; dst6.sin6_addr = ip6->ip6_dst; + + IP_PROBE(send, NULL, NULL, ip6, ifp, NULL, ip6); /* * We just call if_output instead of nd6_output here, since * we need no ND for a multicast forwarded packet...right? diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 7755da1fbb43..e76121d3d4b1 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" +#include "opt_kdtrace.h" #include <sys/param.h> #include <sys/systm.h> @@ -50,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include <sys/lock.h> #include <sys/rwlock.h> #include <sys/queue.h> +#include <sys/sdt.h> #include <sys/sysctl.h> #include <net/if.h> @@ -62,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include <net/vnet.h> #include <netinet/in.h> +#include <netinet/in_kdtrace.h> #include <net/if_llatbl.h> #define L3_ADDR_SIN6(le) ((struct sockaddr_in6 *) L3_ADDR(le)) #include <netinet/if_ether.h> @@ -2083,6 +2086,8 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m0, return (error); } m_clrprotoflags(m); /* Avoid confusing lower layers. */ + IP_PROBE(send, NULL, NULL, mtod(m, struct ip6_hdr *), ifp, NULL, + mtod(m, struct ip6_hdr *)); if ((ifp->if_flags & IFF_LOOPBACK) != 0) { return ((*ifp->if_output)(origifp, m, (struct sockaddr *)dst, NULL)); diff --git a/sys/netinet6/send.c b/sys/netinet6/send.c index 233abdb1fef6..aa6ec673fcd5 100644 --- a/sys/netinet6/send.c +++ b/sys/netinet6/send.c @@ -27,12 +27,15 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_kdtrace.h" + #include <sys/param.h> #include <sys/kernel.h> #include <sys/mbuf.h> #include <sys/module.h> #include <sys/priv.h> #include <sys/protosw.h> +#include <sys/sdt.h> #include <sys/systm.h> #include <sys/socket.h> #include <sys/sockstate.h> @@ -46,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <net/vnet.h> #include <netinet/in.h> +#include <netinet/in_kdtrace.h> #include <netinet/ip_var.h> #include <netinet/ip6.h> #include <netinet/icmp6.h> @@ -182,6 +186,8 @@ send_output(struct mbuf *m, struct ifnet *ifp, int direction) m_clrprotoflags(m); /* Avoid confusing lower layers. */ + IP_PROBE(send, NULL, NULL, ip6, ifp, NULL, ip6); + /* * Output the packet as nd6.c:nd6_output_lle() would do. * The mbuf is always consumed, so we do not have to care diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 6aadae10d47d..7df0db753778 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" #include "opt_ipfw.h" #include "opt_ipsec.h" +#include "opt_kdtrace.h" #include <sys/param.h> #include <sys/jail.h> @@ -82,6 +83,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> @@ -95,6 +97,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> @@ -377,6 +380,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) INP_RLOCK(last); INP_INFO_RUNLOCK(&V_udbinfo); up = intoudpcb(last); + UDP_PROBE(receive, NULL, last, ip6, last, uh); if (up->u_tun_func == NULL) { udp6_append(last, m, off, &fromsa); } else { @@ -455,6 +459,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } INP_RLOCK_ASSERT(inp); up = intoudpcb(inp); + UDP_PROBE(receive, NULL, inp, ip6, inp, uh); if (up->u_tun_func == NULL) { udp6_append(inp, m, off, &fromsa); } else { @@ -771,9 +776,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, ip6->ip6_flow = inp->inp_flow & IPV6_FLOWINFO_MASK; ip6->ip6_vfc &= ~IPV6_VERSION_MASK; ip6->ip6_vfc |= IPV6_VERSION; -#if 0 /* ip6_plen will be filled in ip6_output. */ ip6->ip6_plen = htons((u_short)plen); -#endif ip6->ip6_nxt = IPPROTO_UDP; ip6->ip6_hlim = in6_selecthlim(inp, NULL); ip6->ip6_src = *laddr; @@ -785,6 +788,7 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6, flags = 0; + UDP_PROBE(send, NULL, inp, ip6, inp, udp6); UDPSTAT_INC(udps_opackets); error = ip6_output(m, optp, NULL, flags, inp->in6p_moptions, NULL, inp); |
