summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
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/tcp_input.c
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/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c40
1 files changed, 30 insertions, 10 deletions
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;
/*
OpenPOWER on IntegriCloud