Print this page
*** NO COMMENTS ***
@@ -3475,10 +3475,12 @@
* and other stuffs. Note that we don't check if the
* existing eager list meets the new tcp_conn_req_max
* requirement.
*/
if (tcp->tcp_state != TCPS_LISTEN) {
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_LISTEN);
tcp->tcp_state = TCPS_LISTEN;
/* Initialize the chain. Don't need the eager_lock */
tcp->tcp_eager_next_q0 = tcp->tcp_eager_prev_q0 = tcp;
tcp->tcp_eager_next_drop_q0 = tcp;
tcp->tcp_eager_prev_drop_q0 = tcp;
@@ -3771,10 +3773,12 @@
/*
* This port is ours. Insert in fanout and mark as
* bound to prevent others from getting the port
* number.
*/
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_BOUND);
tcp->tcp_state = TCPS_BOUND;
tcp->tcp_lport = htons(port);
*(uint16_t *)tcp->tcp_tcph->th_lport = tcp->tcp_lport;
ASSERT(&tcps->tcps_bind_fanout[TCP_BIND_HASH(
@@ -3902,10 +3906,13 @@
*/
tcp_closei_local(tcp);
if (!tcp->tcp_tconnind_started) {
CONN_DEC_REF(tcp->tcp_connp);
} else {
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp, int32_t,
+ TCPS_BOUND);
tcp->tcp_state = TCPS_BOUND;
}
} else {
tcp_close_detached(tcp);
}
@@ -4635,10 +4642,14 @@
/* Need to cleanup any pending ioctls */
ASSERT(tcp->tcp_time_wait_next == NULL);
ASSERT(tcp->tcp_time_wait_prev == NULL);
ASSERT(tcp->tcp_time_wait_expire == 0);
+ if (connp->conn_fully_bound) {
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_CLOSED);
+ }
tcp->tcp_state = TCPS_CLOSED;
/* Release any SSL context */
if (tcp->tcp_kssl_ent != NULL) {
kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY);
@@ -5876,10 +5887,13 @@
/*
* No need to check for multicast destination since ip will only pass
* up multicasts to those that have expressed interest
* TODO: what about rejecting broadcasts?
* Also check that source is not a multicast or broadcast address.
+ *
+ * DTrace tcp:::state-change is probed a little further down,
+ * where it is set for the second time.
*/
eager->tcp_state = TCPS_SYN_RCVD;
/*
@@ -5896,10 +5910,17 @@
/* Undo the bind_hash_insert */
tcp_bind_hash_remove(eager);
goto error3;
}
+ /*
+ * DTrace the first SYN as a tcp:::receive. This is placed after
+ * tcp_adapt_ire() so that tcp->tcp_loopback has been set.
+ */
+ DTRACE_TCP5(receive, mblk_t *, NULL, conn_t *, NULL, void_ip_t *,
+ mp->b_rptr, tcp_t *, tcp, tcph_t *, tcph);
+
/* Process all TCP options. */
tcp_process_options(eager, tcph);
/* Is the other end ECN capable? */
if (tcps->tcps_ecn_permitted >= 1 &&
@@ -6012,10 +6033,12 @@
eager->tcp_irs = seg_seq;
eager->tcp_rack = seg_seq;
eager->tcp_rnxt = seg_seq + 1;
U32_TO_ABE32(eager->tcp_rnxt, eager->tcp_tcph->th_ack);
BUMP_MIB(&tcps->tcps_mib, tcpPassiveOpens);
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, eager,
+ int32_t, TCPS_SYN_RCVD);
eager->tcp_state = TCPS_SYN_RCVD;
mp1 = tcp_xmit_mp(eager, eager->tcp_xmit_head, eager->tcp_mss,
NULL, NULL, eager->tcp_iss, B_FALSE, NULL, B_FALSE);
if (mp1 == NULL) {
/*
@@ -6121,10 +6144,27 @@
}
return;
error3:
CONN_DEC_REF(econnp);
error2:
+ /*
+ * DTrace this tcp:::receive event, as we skipped the previous receive
+ * probe. For DTrace only, we find the IP header length so that the
+ * TCP header can be found.
+ */
+ ipvers = IPH_HDR_VERSION(mp->b_rptr);
+ if (OK_32PTR(mp->b_rptr) &&
+ (ipvers == IPV4_VERSION || ipvers == IPV6_VERSION)) {
+ if (ipvers == IPV4_VERSION)
+ ip_hdr_len = IPH_HDR_LENGTH((ipha_t *)mp->b_rptr);
+ else
+ ip_hdr_len = ip_hdr_length_v6(mp, (ip6_t *)mp->b_rptr);
+ DTRACE_TCP5(receive, mblk_t *, NULL, conn_t *, NULL,
+ void_ip_t *, mp->b_rptr, tcp_t *, NULL, tcph_t *,
+ &mp->b_rptr[ip_hdr_len]);
+ }
+
freemsg(mp);
}
/*
* In an ideal case of vertical partition in NUMA architecture, its
@@ -6619,10 +6659,12 @@
if (lport == 0) {
mp = mi_tpi_err_ack_alloc(mp, TNOADDR, 0);
goto failed;
}
}
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_SYN_SENT);
tcp->tcp_state = TCPS_SYN_SENT;
/*
* TODO: allow data with connect requests
* by unlinking M_DATA trailers here and
@@ -6631,10 +6673,12 @@
* feed them to tcp_wput_data() rather than call
* tcp_timer().
*/
mp = mi_tpi_ok_ack_alloc(mp);
if (!mp) {
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, oldstate);
tcp->tcp_state = oldstate;
goto failed;
}
if (tcp->tcp_family == AF_INET) {
mp1 = tcp_ip_bind_mp(tcp, O_T_BIND_REQ,
@@ -6671,10 +6715,12 @@
if (mp1 != NULL)
tcp_rput_other(tcp, mp1);
return;
}
/* Error case */
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, oldstate);
tcp->tcp_state = oldstate;
mp = mi_tpi_err_ack_alloc(mp, TSYSERR, ENOMEM);
failed:
/* return error ack and blow away saved option results if any */
@@ -6827,10 +6873,12 @@
if (lport == 0) {
mp = mi_tpi_err_ack_alloc(mp, TNOADDR, 0);
goto failed;
}
}
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_SYN_SENT);
tcp->tcp_state = TCPS_SYN_SENT;
/*
* TODO: allow data with connect requests
* by unlinking M_DATA trailers here and
* linking them in behind the T_OK_ACK mblk.
@@ -6838,10 +6886,12 @@
* feed them to tcp_wput_data() rather than call
* tcp_timer().
*/
mp = mi_tpi_ok_ack_alloc(mp);
if (!mp) {
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, oldstate);
tcp->tcp_state = oldstate;
goto failed;
}
mp1 = tcp_ip_bind_mp(tcp, O_T_BIND_REQ, sizeof (ipa6_conn_t));
if (mp1) {
@@ -6864,10 +6914,12 @@
if (mp1 != NULL)
tcp_rput_other(tcp, mp1);
return;
}
/* Error case */
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, oldstate);
tcp->tcp_state = oldstate;
mp = mi_tpi_err_ack_alloc(mp, TSYSERR, ENOMEM);
failed:
/* return error ack and blow away saved option results if any */
@@ -7012,13 +7064,17 @@
tcp->tcp_connp->conn_zoneid, ipst);
if (connp != NULL)
ltcp = connp->conn_tcp;
}
if (tcp->tcp_conn_req_max && ltcp == NULL) {
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_LISTEN);
tcp->tcp_state = TCPS_LISTEN;
} else if (old_state > TCPS_BOUND) {
tcp->tcp_conn_req_max = 0;
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_BOUND);
tcp->tcp_state = TCPS_BOUND;
}
if (ltcp != NULL)
CONN_DEC_REF(ltcp->tcp_connp);
if (old_state == TCPS_SYN_SENT || old_state == TCPS_SYN_RCVD) {
@@ -7915,10 +7971,12 @@
* the global queue, TCP will do a tcp_lookup_listener()
* to find this stream. This works because this stream
* is only removed from connected hash.
*
*/
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_LISTEN);
tcp->tcp_state = TCPS_LISTEN;
tcp->tcp_eager_next_q0 = tcp->tcp_eager_prev_q0 = tcp;
tcp->tcp_eager_next_drop_q0 = tcp;
tcp->tcp_eager_prev_drop_q0 = tcp;
tcp->tcp_connp->conn_recv = tcp_conn_request;
@@ -7930,10 +7988,12 @@
ASSERT(!tcp->tcp_connp->conn_af_isv6);
(void) ipcl_bind_insert(tcp->tcp_connp, IPPROTO_TCP,
tcp->tcp_ipha->ipha_src, tcp->tcp_lport);
}
} else {
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_BOUND);
tcp->tcp_state = TCPS_BOUND;
}
/*
* Initialize to default values
@@ -8291,10 +8351,11 @@
{
int err;
tcp->tcp_rq = q;
tcp->tcp_wq = WR(q);
+ /* DTrace ignores this - it isn't a tcp:::state-change */
tcp->tcp_state = TCPS_IDLE;
if ((err = tcp_init_values(tcp)) != 0)
tcp_timers_stop(tcp);
return (err);
}
@@ -13292,10 +13353,17 @@
mp->b_wptr = (uchar_t *)tcph + TCP_HDR_LENGTH(tcph);
seg_len = 0;
}
}
+ DTRACE_TCP5(receive, mblk_t *, NULL, conn_t *, NULL, void_ip_t *,
+ iphdr, tcp_t *, tcp, tcph_t *, tcph);
+ if (tcp->tcp_state == TCPS_SYN_RCVD && (flags & TH_ACK)) {
+ DTRACE_TCP5(accept__established, mblk_t *, NULL, conn_t *,
+ NULL, void_ip_t *, iphdr, tcp_t *, tcp, tcph_t *, tcph);
+ }
+
switch (tcp->tcp_state) {
case TCPS_SYN_SENT:
if (flags & TH_ACK) {
/*
* Note that our stack cannot send data before a
@@ -13313,10 +13381,14 @@
return;
}
ASSERT(tcp->tcp_suna + 1 == seg_ack);
}
if (flags & TH_RST) {
+ DTRACE_TCP5(connect__refused, mblk_t *, NULL,
+ conn_t *, NULL, void_ip_t *, iphdr, tcp_t *, NULL,
+ tcph_t *, tcph);
+
freemsg(mp);
if (flags & TH_ACK)
(void) tcp_clean_death(tcp,
ECONNREFUSED, 13);
return;
@@ -13387,13 +13459,22 @@
tcp->tcp_ip_forward_progress = B_TRUE;
/* One for the SYN */
tcp->tcp_suna = tcp->tcp_iss + 1;
tcp->tcp_valid_bits &= ~TCP_ISS_VALID;
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_ESTABLISHED);
tcp->tcp_state = TCPS_ESTABLISHED;
/*
+ * For DTrace observability, remember that we just
+ * established a connection and are about to send
+ * the final ACK.
+ */
+ tcp->tcp_dtrace_connect_established = B_TRUE;
+
+ /*
* If SYN was retransmitted, need to reset all
* retransmission info. This is because this
* segment will be treated as a dup ACK.
*/
if (tcp->tcp_rexmit) {
@@ -13496,10 +13577,12 @@
flags &= ~TH_SYN;
seg_seq++;
break;
}
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_SYN_RCVD);
tcp->tcp_state = TCPS_SYN_RCVD;
mp1 = tcp_xmit_mp(tcp, tcp->tcp_xmit_head, tcp->tcp_mss,
NULL, NULL, tcp->tcp_iss, B_FALSE, NULL, B_FALSE);
if (mp1) {
DB_CPID(mp1) = tcp->tcp_cpid;
@@ -14415,10 +14498,12 @@
if (new_swnd > tcp->tcp_max_swnd)
tcp->tcp_max_swnd = new_swnd;
tcp->tcp_swl1 = seg_seq;
tcp->tcp_swl2 = seg_ack;
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL,
+ tcp_t *, tcp, int32_t, TCPS_ESTABLISHED);
tcp->tcp_state = TCPS_ESTABLISHED;
tcp->tcp_valid_bits &= ~TCP_ISS_VALID;
/* Fuse when both sides are in ESTABLISHED state */
if (tcp->tcp_loopback && do_tcp_fusion)
@@ -15051,10 +15136,13 @@
if (tcp->tcp_state > TCPS_ESTABLISHED) {
switch (tcp->tcp_state) {
case TCPS_FIN_WAIT_1:
if (tcp->tcp_fin_acked) {
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp, int32_t,
+ TCPS_FIN_WAIT_2);
tcp->tcp_state = TCPS_FIN_WAIT_2;
/*
* We implement the non-standard BSD/SunOS
* FIN_WAIT_2 flushing algorithm.
* If there is no user attached to this
@@ -15083,10 +15171,13 @@
return;
}
goto xmit_check;
case TCPS_CLOSING:
if (tcp->tcp_fin_acked) {
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp, int32_t,
+ TCPS_TIME_WAIT);
tcp->tcp_state = TCPS_TIME_WAIT;
/*
* Unconditionally clear the exclusive binding
* bit so this TIME-WAIT connection won't
* interfere with new ones.
@@ -15128,20 +15219,29 @@
!TCP_IS_DETACHED(tcp) && (!tcp->tcp_hard_binding))
flags |= TH_ORDREL_NEEDED;
switch (tcp->tcp_state) {
case TCPS_SYN_RCVD:
case TCPS_ESTABLISHED:
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp, int32_t,
+ TCPS_CLOSE_WAIT);
tcp->tcp_state = TCPS_CLOSE_WAIT;
/* Keepalive? */
break;
case TCPS_FIN_WAIT_1:
if (!tcp->tcp_fin_acked) {
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_CLOSING);
tcp->tcp_state = TCPS_CLOSING;
break;
}
/* FALLTHRU */
case TCPS_FIN_WAIT_2:
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp, int32_t,
+ TCPS_TIME_WAIT);
tcp->tcp_state = TCPS_TIME_WAIT;
/*
* Unconditionally clear the exclusive binding
* bit so this TIME-WAIT connection won't
* interfere with new ones.
@@ -15998,10 +16098,12 @@
default:
panic("tcp_bind_failed: unexpected TPI type");
/*NOTREACHED*/
}
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_IDLE);
tcp->tcp_state = TCPS_IDLE;
if (tcp->tcp_ipversion == IPV4_VERSION)
tcp->tcp_ipha->ipha_src = 0;
else
V6_SET_ZERO(tcp->tcp_ip6h->ip6_src);
@@ -16040,10 +16142,11 @@
mblk_t *mdti;
mblk_t *lsoi;
int retval;
mblk_t *ire_mp;
tcp_stack_t *tcps = tcp->tcp_tcps;
+ uint_t ip_hdr_len;
switch (mp->b_datap->db_type) {
case M_PROTO:
case M_PCPROTO:
ASSERT((uintptr_t)(mp->b_wptr - rptr) <= (uintptr_t)INT_MAX);
@@ -16224,10 +16327,28 @@
TCP_RECORD_TRACE(tcp, syn_mp,
TCP_TRACE_SEND_PKT);
mblk_setcred(syn_mp, cr);
DB_CPID(syn_mp) = pid;
+
+ /*
+ * DTrace sending the first SYN as a
+ * tcp:::connect-request event. For DTrace
+ * only, the IP header length is found
+ * so that the TCP header can be retrieved.
+ */
+ if (tcp->tcp_ipversion == IPV4_VERSION)
+ ip_hdr_len = IPH_HDR_LENGTH(
+ (ipha_t *)syn_mp->b_rptr);
+ else
+ ip_hdr_len = ip_hdr_length_v6(mp,
+ (ip6_t *)syn_mp->b_rptr);
+ DTRACE_TCP5(connect__request, mblk_t *, NULL,
+ conn_t *, NULL, void_ip_t *,
+ syn_mp->b_rptr, tcp_t *, tcp, tcph_t *,
+ &syn_mp->b_rptr[ip_hdr_len]);
+
tcp_send_data(tcp, tcp->tcp_wq, syn_mp);
}
after_syn_sent:
/*
* A trailer mblk indicates a waiting client upstream.
@@ -17843,10 +17964,12 @@
V6_SET_ZERO(tcp->tcp_ip6h->ip6_src);
}
V6_SET_ZERO(tcp->tcp_ip_src_v6);
bzero(tcp->tcp_tcph->th_lport, sizeof (tcp->tcp_tcph->th_lport));
tcp_bind_hash_remove(tcp);
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_IDLE);
tcp->tcp_state = TCPS_IDLE;
tcp->tcp_mdt = B_FALSE;
/* Send M_FLUSH according to TPI */
(void) putnextctl1(tcp->tcp_rq, M_FLUSH, FLUSHRW);
connp = tcp->tcp_connp;
@@ -19521,10 +19644,11 @@
uint32_t hcksum_txflags = 0;
mblk_t *ire_fp_mp;
uint_t ire_fp_mp_len;
tcp_stack_t *tcps = tcp->tcp_tcps;
ip_stack_t *ipst = tcps->tcps_netstack->netstack_ip;
+ uint_t ip_hdr_len;
ASSERT(DB_TYPE(mp) == M_DATA);
if (DB_CRED(mp) == NULL)
mblk_setcred(mp, CONN_CRED(connp));
@@ -19531,10 +19655,22 @@
ipha = (ipha_t *)mp->b_rptr;
src = ipha->ipha_src;
dst = ipha->ipha_dst;
+ if (tcp->tcp_ipversion == IPV4_VERSION) {
+ DTRACE_TCP5(send, mblk_t *, NULL, conn_t *, NULL,
+ void_ip_t *, ipha, tcp_t *, tcp, tcph_t *,
+ &mp->b_rptr[IPH_HDR_LENGTH(mp->b_rptr)]);
+ if (tcp->tcp_dtrace_connect_established) {
+ DTRACE_TCP5(connect__established, mblk_t *, NULL,
+ conn_t *, NULL, void_ip_t *, ipha, tcp_t *, tcp,
+ tcph_t *, &mp->b_rptr[IPH_HDR_LENGTH(mp->b_rptr)]);
+ tcp->tcp_dtrace_connect_established = B_FALSE;
+ }
+ }
+
/*
* Drop off fast path for IPv6 and also if options are present or
* we need to resolve a TS label.
*/
if (tcp->tcp_ipversion != IPV4_VERSION ||
@@ -19546,10 +19682,25 @@
ipha->ipha_version_and_hdr_length != IP_SIMPLE_HDR_VERSION ||
IPP_ENABLED(IPP_LOCAL_OUT, ipst)) {
if (tcp->tcp_snd_zcopy_aware)
mp = tcp_zcopy_disable(tcp, mp);
TCP_STAT(tcps, tcp_ip_send);
+
+ if (tcp->tcp_ipversion == IPV6_VERSION) {
+ ip_hdr_len = ip_hdr_length_v6(mp, (ip6_t *)mp->b_rptr);
+ DTRACE_TCP5(send, mblk_t *, NULL, conn_t *, NULL,
+ void_ip_t *, mp->b_rptr, tcp_t *, tcp, tcph_t *,
+ &mp->b_rptr[ip_hdr_len]);
+ if (tcp->tcp_dtrace_connect_established) {
+ DTRACE_TCP5(connect__established, mblk_t *,
+ NULL, conn_t *, NULL, void_ip_t *,
+ mp->b_rptr, tcp_t *, tcp, tcph_t *,
+ &mp->b_rptr[ip_hdr_len]);
+ tcp->tcp_dtrace_connect_established = B_FALSE;
+ }
+ }
+
CALL_IP_WPUT(connp, q, mp);
return;
}
if (!tcp_send_find_ire_ill(tcp, mp, &ire, &ill)) {
@@ -20954,10 +21105,13 @@
/*
* tcp state must be ESTABLISHED
* in order for us to get here in
* the first place.
*/
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_FIN_WAIT_1);
tcp->tcp_state = TCPS_FIN_WAIT_1;
/*
* Upon returning from this routine,
* tcp_wput_data() will set tcp_snxt
@@ -21589,10 +21743,13 @@
*up = 0;
IP_CKSUM_XMIT_FAST(ire->ire_ipversion, hcksum_txflags, mp, ipha, up,
IPPROTO_TCP, IP_SIMPLE_HDR_LENGTH, ntohs(ipha->ipha_length), cksum);
+ DTRACE_TCP5(send, mblk_t *, NULL, conn_t *, NULL, void_ip_t *, ipha,
+ tcp_t *, tcp, tcph_t *, &mp->b_rptr[IPH_HDR_LENGTH(mp->b_rptr)]);
+
/*
* Append LSO flag to DB_LSOFLAGS(mp) and set the mss to DB_LSOMSS(mp).
*/
DB_LSOFLAGS(mp) |= HW_LSO;
DB_LSOMSS(mp) = mss;
@@ -23234,10 +23391,17 @@
freemsg(ipsec_mp);
return;
}
ipsec_mp = nmp;
+ DTRACE_TCP5(send, mblk_t *, NULL, conn_t *, NULL, void_ip_t *,
+ mp->b_rptr, tcp_t *, NULL, tcph_t *, tcph);
+ if (tcph->th_flags[0] == (TH_RST|TH_ACK)) {
+ DTRACE_TCP5(accept__refused, mblk_t *, NULL, conn_t *, NULL,
+ void_ip_t *, mp->b_rptr, tcp_t *, NULL, tcph_t *, tcph);
+ }
+
/*
* NOTE: one might consider tracing a TCP packet here, but
* this function has no active TCP state and no tcp structure
* that has a trace buffer. If we traced here, we would have
* to keep a local trace buffer in tcp_record_trace().
@@ -23454,10 +23618,17 @@
tcph = (tcph_t *)&rptr[ip_hdr_len];
seg_seq = BE32_TO_U32(tcph->th_seq);
seg_ack = BE32_TO_U32(tcph->th_ack);
flags = tcph->th_flags[0];
+ /*
+ * DTrace this "unknown" segment as a tcp:::receive, as we did
+ * just receive something that was TCP.
+ */
+ DTRACE_TCP5(receive, mblk_t *, NULL, conn_t *, NULL, void_ip_t *, rptr,
+ tcp_t *, NULL, tcph_t *, tcph);
+
seg_len = msgdsize(mp) - (TCP_HDR_LENGTH(tcph) + ip_hdr_len);
if (flags & TH_RST) {
freemsg(ipsec_mp);
} else if (flags & TH_ACK) {
tcp_xmit_early_reset("no tcp, reset",
@@ -23791,13 +23962,19 @@
if (!tcp->tcp_fin_sent) {
tcp->tcp_fin_sent = B_TRUE;
switch (tcp->tcp_state) {
case TCPS_SYN_RCVD:
case TCPS_ESTABLISHED:
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_FIN_WAIT_1);
tcp->tcp_state = TCPS_FIN_WAIT_1;
break;
case TCPS_CLOSE_WAIT:
+ DTRACE_TCP4(state__change, void, NULL,
+ conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_LAST_ACK);
tcp->tcp_state = TCPS_LAST_ACK;
break;
}
if (tcp->tcp_suna == tcp->tcp_snxt)
TCP_TIMER_RESTART(tcp, tcp->tcp_rto);
@@ -24143,10 +24320,12 @@
/*
* Only initialize the necessary info in those structures. Note
* that since INADDR_ANY is all 0, we do not need to set
* tcp_bound_source to INADDR_ANY here.
*/
+ DTRACE_TCP4(state__change, void, NULL, conn_t *, NULL, tcp_t *, tcp,
+ int32_t, TCPS_BOUND);
tcp->tcp_state = TCPS_BOUND;
tcp->tcp_lport = port;
tcp->tcp_exclbind = 1;
tcp->tcp_reserved_port = 1;