Print this page
11547 Want connstat(1M) command to display per-connection TCP statistics
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Portions contributed by: Ahmed G <ahmedg@delphix.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>


1214         CONN_DEC_REF(tcp->tcp_connp);
1215 }
1216 
1217 /*
1218  * The tcp_t is going away. Remove it from all lists and set it
1219  * to TCPS_CLOSED. The freeing up of memory is deferred until
1220  * tcp_inactive. This is needed since a thread in tcp_rput might have
1221  * done a CONN_INC_REF on this structure before it was removed from the
1222  * hashes.
1223  */
1224 void
1225 tcp_closei_local(tcp_t *tcp)
1226 {
1227         conn_t          *connp = tcp->tcp_connp;
1228         tcp_stack_t     *tcps = tcp->tcp_tcps;
1229         int32_t         oldstate;
1230 
1231         if (!TCP_IS_SOCKET(tcp))
1232                 tcp_acceptor_hash_remove(tcp);
1233 
1234         TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
1235         tcp->tcp_ibsegs = 0;
1236         TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
1237         tcp->tcp_obsegs = 0;
1238 
1239         /*
1240          * This can be called via tcp_time_wait_processing() if TCP gets a
1241          * SYN with sequence number outside the TIME-WAIT connection's
1242          * window.  So we need to check for TIME-WAIT state here as the
1243          * connection counter is already decremented.  See SET_TIME_WAIT()
1244          * macro
1245          */
1246         if (tcp->tcp_state >= TCPS_ESTABLISHED &&
1247             tcp->tcp_state < TCPS_TIME_WAIT) {
1248                 TCPS_CONN_DEC(tcps);
1249         }
1250 
1251         /*
1252          * If we are an eager connection hanging off a listener that
1253          * hasn't formally accepted the connection yet, get off its
1254          * list and blow off any data that we have accumulated.
1255          */
1256         if (tcp->tcp_listener != NULL) {
1257                 tcp_t   *listener = tcp->tcp_listener;
1258                 mutex_enter(&listener->tcp_eager_lock);


1887  */
1888 static void
1889 tcp_reinit(tcp_t *tcp)
1890 {
1891         mblk_t          *mp;
1892         tcp_stack_t     *tcps = tcp->tcp_tcps;
1893         conn_t          *connp  = tcp->tcp_connp;
1894         int32_t         oldstate;
1895 
1896         /* tcp_reinit should never be called for detached tcp_t's */
1897         ASSERT(tcp->tcp_listener == NULL);
1898         ASSERT((connp->conn_family == AF_INET &&
1899             connp->conn_ipversion == IPV4_VERSION) ||
1900             (connp->conn_family == AF_INET6 &&
1901             (connp->conn_ipversion == IPV4_VERSION ||
1902             connp->conn_ipversion == IPV6_VERSION)));
1903 
1904         /* Cancel outstanding timers */
1905         tcp_timers_stop(tcp);
1906 
1907         /*
1908          * Reset everything in the state vector, after updating global
1909          * MIB data from instance counters.
1910          */
1911         TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
1912         tcp->tcp_ibsegs = 0;
1913         TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
1914         tcp->tcp_obsegs = 0;
1915 
1916         tcp_close_mpp(&tcp->tcp_xmit_head);
1917         if (tcp->tcp_snd_zcopy_aware)
1918                 tcp_zcopy_notify(tcp);
1919         tcp->tcp_xmit_last = tcp->tcp_xmit_tail = NULL;
1920         tcp->tcp_unsent = tcp->tcp_xmit_tail_unsent = 0;
1921         mutex_enter(&tcp->tcp_non_sq_lock);
1922         if (tcp->tcp_flow_stopped &&
1923             TCP_UNSENT_BYTES(tcp) <= connp->conn_sndlowat) {
1924                 tcp_clrqfull(tcp);
1925         }
1926         mutex_exit(&tcp->tcp_non_sq_lock);
1927         tcp_close_mpp(&tcp->tcp_reass_head);
1928         tcp->tcp_reass_tail = NULL;
1929         if (tcp->tcp_rcv_list != NULL) {
1930                 /* Free b_next chain */
1931                 tcp_close_mpp(&tcp->tcp_rcv_list);
1932                 tcp->tcp_rcv_last_head = NULL;
1933                 tcp->tcp_rcv_last_tail = NULL;
1934                 tcp->tcp_rcv_cnt = 0;
1935         }


2067 
2068         /* Should be ASSERT NULL on these with new code! */
2069         ASSERT(tcp->tcp_time_wait_next == NULL);
2070         ASSERT(tcp->tcp_time_wait_prev == NULL);
2071         ASSERT(tcp->tcp_time_wait_expire == 0);
2072         PRESERVE(tcp->tcp_state);
2073         PRESERVE(connp->conn_rq);
2074         PRESERVE(connp->conn_wq);
2075 
2076         ASSERT(tcp->tcp_xmit_head == NULL);
2077         ASSERT(tcp->tcp_xmit_last == NULL);
2078         ASSERT(tcp->tcp_unsent == 0);
2079         ASSERT(tcp->tcp_xmit_tail == NULL);
2080         ASSERT(tcp->tcp_xmit_tail_unsent == 0);
2081 
2082         tcp->tcp_snxt = 0;                   /* Displayed in mib */
2083         tcp->tcp_suna = 0;                   /* Displayed in mib */
2084         tcp->tcp_swnd = 0;
2085         DONTCARE(tcp->tcp_cwnd);     /* Init in tcp_process_options */
2086 
2087         ASSERT(tcp->tcp_ibsegs == 0);
2088         ASSERT(tcp->tcp_obsegs == 0);
2089 
2090         if (connp->conn_ht_iphc != NULL) {
2091                 kmem_free(connp->conn_ht_iphc, connp->conn_ht_iphc_allocated);
2092                 connp->conn_ht_iphc = NULL;
2093                 connp->conn_ht_iphc_allocated = 0;
2094                 connp->conn_ht_iphc_len = 0;
2095                 connp->conn_ht_ulp = NULL;
2096                 connp->conn_ht_ulp_len = 0;
2097                 tcp->tcp_ipha = NULL;
2098                 tcp->tcp_ip6h = NULL;
2099                 tcp->tcp_tcpha = NULL;
2100         }
2101 
2102         /* We clear any IP_OPTIONS and extension headers */
2103         ip_pkt_free(&connp->conn_xmit_ipp);
2104 
2105         DONTCARE(tcp->tcp_naglim);           /* Init in tcp_init_values */
2106         DONTCARE(tcp->tcp_ipha);
2107         DONTCARE(tcp->tcp_ip6h);
2108         DONTCARE(tcp->tcp_tcpha);
2109         tcp->tcp_valid_bits = 0;


2161         tcp->tcp_initial_pmtu = 0;
2162 
2163         ASSERT(tcp->tcp_reass_head == NULL);
2164         ASSERT(tcp->tcp_reass_tail == NULL);
2165 
2166         tcp->tcp_cwnd_cnt = 0;
2167 
2168         ASSERT(tcp->tcp_rcv_list == NULL);
2169         ASSERT(tcp->tcp_rcv_last_head == NULL);
2170         ASSERT(tcp->tcp_rcv_last_tail == NULL);
2171         ASSERT(tcp->tcp_rcv_cnt == 0);
2172 
2173         DONTCARE(tcp->tcp_cwnd_ssthresh); /* Init in tcp_set_destination */
2174         DONTCARE(tcp->tcp_cwnd_max);         /* Init in tcp_init_values */
2175         tcp->tcp_csuna = 0;
2176 
2177         tcp->tcp_rto = 0;                    /* Displayed in MIB */
2178         DONTCARE(tcp->tcp_rtt_sa);           /* Init in tcp_init_values */
2179         DONTCARE(tcp->tcp_rtt_sd);           /* Init in tcp_init_values */
2180         tcp->tcp_rtt_update = 0;


2181 
2182         DONTCARE(tcp->tcp_swl1); /* Init in case TCPS_LISTEN/TCPS_SYN_SENT */
2183         DONTCARE(tcp->tcp_swl2); /* Init in case TCPS_LISTEN/TCPS_SYN_SENT */
2184 
2185         tcp->tcp_rack = 0;                   /* Displayed in mib */
2186         tcp->tcp_rack_cnt = 0;
2187         tcp->tcp_rack_cur_max = 0;
2188         tcp->tcp_rack_abs_max = 0;
2189 
2190         tcp->tcp_max_swnd = 0;
2191 
2192         ASSERT(tcp->tcp_listener == NULL);
2193 
2194         DONTCARE(tcp->tcp_irs);                      /* tcp_valid_bits cleared */
2195         DONTCARE(tcp->tcp_iss);                      /* tcp_valid_bits cleared */
2196         DONTCARE(tcp->tcp_fss);                      /* tcp_valid_bits cleared */
2197         DONTCARE(tcp->tcp_urg);                      /* tcp_valid_bits cleared */
2198 
2199         ASSERT(tcp->tcp_conn_req_cnt_q == 0);
2200         ASSERT(tcp->tcp_conn_req_cnt_q0 == 0);




1214         CONN_DEC_REF(tcp->tcp_connp);
1215 }
1216 
1217 /*
1218  * The tcp_t is going away. Remove it from all lists and set it
1219  * to TCPS_CLOSED. The freeing up of memory is deferred until
1220  * tcp_inactive. This is needed since a thread in tcp_rput might have
1221  * done a CONN_INC_REF on this structure before it was removed from the
1222  * hashes.
1223  */
1224 void
1225 tcp_closei_local(tcp_t *tcp)
1226 {
1227         conn_t          *connp = tcp->tcp_connp;
1228         tcp_stack_t     *tcps = tcp->tcp_tcps;
1229         int32_t         oldstate;
1230 
1231         if (!TCP_IS_SOCKET(tcp))
1232                 tcp_acceptor_hash_remove(tcp);
1233 





1234         /*
1235          * This can be called via tcp_time_wait_processing() if TCP gets a
1236          * SYN with sequence number outside the TIME-WAIT connection's
1237          * window.  So we need to check for TIME-WAIT state here as the
1238          * connection counter is already decremented.  See SET_TIME_WAIT()
1239          * macro
1240          */
1241         if (tcp->tcp_state >= TCPS_ESTABLISHED &&
1242             tcp->tcp_state < TCPS_TIME_WAIT) {
1243                 TCPS_CONN_DEC(tcps);
1244         }
1245 
1246         /*
1247          * If we are an eager connection hanging off a listener that
1248          * hasn't formally accepted the connection yet, get off its
1249          * list and blow off any data that we have accumulated.
1250          */
1251         if (tcp->tcp_listener != NULL) {
1252                 tcp_t   *listener = tcp->tcp_listener;
1253                 mutex_enter(&listener->tcp_eager_lock);


1882  */
1883 static void
1884 tcp_reinit(tcp_t *tcp)
1885 {
1886         mblk_t          *mp;
1887         tcp_stack_t     *tcps = tcp->tcp_tcps;
1888         conn_t          *connp  = tcp->tcp_connp;
1889         int32_t         oldstate;
1890 
1891         /* tcp_reinit should never be called for detached tcp_t's */
1892         ASSERT(tcp->tcp_listener == NULL);
1893         ASSERT((connp->conn_family == AF_INET &&
1894             connp->conn_ipversion == IPV4_VERSION) ||
1895             (connp->conn_family == AF_INET6 &&
1896             (connp->conn_ipversion == IPV4_VERSION ||
1897             connp->conn_ipversion == IPV6_VERSION)));
1898 
1899         /* Cancel outstanding timers */
1900         tcp_timers_stop(tcp);
1901 









1902         tcp_close_mpp(&tcp->tcp_xmit_head);
1903         if (tcp->tcp_snd_zcopy_aware)
1904                 tcp_zcopy_notify(tcp);
1905         tcp->tcp_xmit_last = tcp->tcp_xmit_tail = NULL;
1906         tcp->tcp_unsent = tcp->tcp_xmit_tail_unsent = 0;
1907         mutex_enter(&tcp->tcp_non_sq_lock);
1908         if (tcp->tcp_flow_stopped &&
1909             TCP_UNSENT_BYTES(tcp) <= connp->conn_sndlowat) {
1910                 tcp_clrqfull(tcp);
1911         }
1912         mutex_exit(&tcp->tcp_non_sq_lock);
1913         tcp_close_mpp(&tcp->tcp_reass_head);
1914         tcp->tcp_reass_tail = NULL;
1915         if (tcp->tcp_rcv_list != NULL) {
1916                 /* Free b_next chain */
1917                 tcp_close_mpp(&tcp->tcp_rcv_list);
1918                 tcp->tcp_rcv_last_head = NULL;
1919                 tcp->tcp_rcv_last_tail = NULL;
1920                 tcp->tcp_rcv_cnt = 0;
1921         }


2053 
2054         /* Should be ASSERT NULL on these with new code! */
2055         ASSERT(tcp->tcp_time_wait_next == NULL);
2056         ASSERT(tcp->tcp_time_wait_prev == NULL);
2057         ASSERT(tcp->tcp_time_wait_expire == 0);
2058         PRESERVE(tcp->tcp_state);
2059         PRESERVE(connp->conn_rq);
2060         PRESERVE(connp->conn_wq);
2061 
2062         ASSERT(tcp->tcp_xmit_head == NULL);
2063         ASSERT(tcp->tcp_xmit_last == NULL);
2064         ASSERT(tcp->tcp_unsent == 0);
2065         ASSERT(tcp->tcp_xmit_tail == NULL);
2066         ASSERT(tcp->tcp_xmit_tail_unsent == 0);
2067 
2068         tcp->tcp_snxt = 0;                   /* Displayed in mib */
2069         tcp->tcp_suna = 0;                   /* Displayed in mib */
2070         tcp->tcp_swnd = 0;
2071         DONTCARE(tcp->tcp_cwnd);     /* Init in tcp_process_options */
2072 



2073         if (connp->conn_ht_iphc != NULL) {
2074                 kmem_free(connp->conn_ht_iphc, connp->conn_ht_iphc_allocated);
2075                 connp->conn_ht_iphc = NULL;
2076                 connp->conn_ht_iphc_allocated = 0;
2077                 connp->conn_ht_iphc_len = 0;
2078                 connp->conn_ht_ulp = NULL;
2079                 connp->conn_ht_ulp_len = 0;
2080                 tcp->tcp_ipha = NULL;
2081                 tcp->tcp_ip6h = NULL;
2082                 tcp->tcp_tcpha = NULL;
2083         }
2084 
2085         /* We clear any IP_OPTIONS and extension headers */
2086         ip_pkt_free(&connp->conn_xmit_ipp);
2087 
2088         DONTCARE(tcp->tcp_naglim);           /* Init in tcp_init_values */
2089         DONTCARE(tcp->tcp_ipha);
2090         DONTCARE(tcp->tcp_ip6h);
2091         DONTCARE(tcp->tcp_tcpha);
2092         tcp->tcp_valid_bits = 0;


2144         tcp->tcp_initial_pmtu = 0;
2145 
2146         ASSERT(tcp->tcp_reass_head == NULL);
2147         ASSERT(tcp->tcp_reass_tail == NULL);
2148 
2149         tcp->tcp_cwnd_cnt = 0;
2150 
2151         ASSERT(tcp->tcp_rcv_list == NULL);
2152         ASSERT(tcp->tcp_rcv_last_head == NULL);
2153         ASSERT(tcp->tcp_rcv_last_tail == NULL);
2154         ASSERT(tcp->tcp_rcv_cnt == 0);
2155 
2156         DONTCARE(tcp->tcp_cwnd_ssthresh); /* Init in tcp_set_destination */
2157         DONTCARE(tcp->tcp_cwnd_max);         /* Init in tcp_init_values */
2158         tcp->tcp_csuna = 0;
2159 
2160         tcp->tcp_rto = 0;                    /* Displayed in MIB */
2161         DONTCARE(tcp->tcp_rtt_sa);           /* Init in tcp_init_values */
2162         DONTCARE(tcp->tcp_rtt_sd);           /* Init in tcp_init_values */
2163         tcp->tcp_rtt_update = 0;
2164         tcp->tcp_rtt_sum = 0;
2165         tcp->tcp_rtt_cnt = 0;
2166 
2167         DONTCARE(tcp->tcp_swl1); /* Init in case TCPS_LISTEN/TCPS_SYN_SENT */
2168         DONTCARE(tcp->tcp_swl2); /* Init in case TCPS_LISTEN/TCPS_SYN_SENT */
2169 
2170         tcp->tcp_rack = 0;                   /* Displayed in mib */
2171         tcp->tcp_rack_cnt = 0;
2172         tcp->tcp_rack_cur_max = 0;
2173         tcp->tcp_rack_abs_max = 0;
2174 
2175         tcp->tcp_max_swnd = 0;
2176 
2177         ASSERT(tcp->tcp_listener == NULL);
2178 
2179         DONTCARE(tcp->tcp_irs);                      /* tcp_valid_bits cleared */
2180         DONTCARE(tcp->tcp_iss);                      /* tcp_valid_bits cleared */
2181         DONTCARE(tcp->tcp_fss);                      /* tcp_valid_bits cleared */
2182         DONTCARE(tcp->tcp_urg);                      /* tcp_valid_bits cleared */
2183 
2184         ASSERT(tcp->tcp_conn_req_cnt_q == 0);
2185         ASSERT(tcp->tcp_conn_req_cnt_q0 == 0);