111754SKacheong.Poon@Sun.COM /*
211754SKacheong.Poon@Sun.COM * CDDL HEADER START
311754SKacheong.Poon@Sun.COM *
411754SKacheong.Poon@Sun.COM * The contents of this file are subject to the terms of the
511754SKacheong.Poon@Sun.COM * Common Development and Distribution License (the "License").
611754SKacheong.Poon@Sun.COM * You may not use this file except in compliance with the License.
711754SKacheong.Poon@Sun.COM *
811754SKacheong.Poon@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911754SKacheong.Poon@Sun.COM * or http://www.opensolaris.org/os/licensing.
1011754SKacheong.Poon@Sun.COM * See the License for the specific language governing permissions
1111754SKacheong.Poon@Sun.COM * and limitations under the License.
1211754SKacheong.Poon@Sun.COM *
1311754SKacheong.Poon@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
1411754SKacheong.Poon@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1511754SKacheong.Poon@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
1611754SKacheong.Poon@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
1711754SKacheong.Poon@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
1811754SKacheong.Poon@Sun.COM *
1911754SKacheong.Poon@Sun.COM * CDDL HEADER END
2011754SKacheong.Poon@Sun.COM */
2111754SKacheong.Poon@Sun.COM
2211754SKacheong.Poon@Sun.COM /*
2312869SKacheong.Poon@Sun.COM * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
2411754SKacheong.Poon@Sun.COM */
2511754SKacheong.Poon@Sun.COM
2611754SKacheong.Poon@Sun.COM #include <sys/types.h>
2711754SKacheong.Poon@Sun.COM #include <sys/tihdr.h>
2811754SKacheong.Poon@Sun.COM #include <sys/policy.h>
2911754SKacheong.Poon@Sun.COM #include <sys/tsol/tnet.h>
3011754SKacheong.Poon@Sun.COM
3111754SKacheong.Poon@Sun.COM #include <inet/common.h>
3211754SKacheong.Poon@Sun.COM #include <inet/ip.h>
3311754SKacheong.Poon@Sun.COM #include <inet/tcp.h>
3411754SKacheong.Poon@Sun.COM #include <inet/tcp_impl.h>
3511754SKacheong.Poon@Sun.COM #include <inet/tcp_stats.h>
3611754SKacheong.Poon@Sun.COM #include <inet/kstatcom.h>
3711754SKacheong.Poon@Sun.COM #include <inet/snmpcom.h>
3811754SKacheong.Poon@Sun.COM
3911754SKacheong.Poon@Sun.COM static int tcp_kstat_update(kstat_t *kp, int rw);
4011754SKacheong.Poon@Sun.COM static int tcp_kstat2_update(kstat_t *kp, int rw);
4111754SKacheong.Poon@Sun.COM static void tcp_sum_mib(tcp_stack_t *, mib2_tcp_t *);
4211754SKacheong.Poon@Sun.COM
4312869SKacheong.Poon@Sun.COM static void tcp_add_mib(mib2_tcp_t *, mib2_tcp_t *);
4412869SKacheong.Poon@Sun.COM static void tcp_add_stats(tcp_stat_counter_t *, tcp_stat_t *);
4511754SKacheong.Poon@Sun.COM static void tcp_clr_stats(tcp_stat_t *);
4611754SKacheong.Poon@Sun.COM
4711754SKacheong.Poon@Sun.COM tcp_g_stat_t tcp_g_statistics;
4811754SKacheong.Poon@Sun.COM kstat_t *tcp_g_kstat;
4911754SKacheong.Poon@Sun.COM
5011754SKacheong.Poon@Sun.COM /* Translate TCP state to MIB2 TCP state. */
5111754SKacheong.Poon@Sun.COM static int
tcp_snmp_state(tcp_t * tcp)5211754SKacheong.Poon@Sun.COM tcp_snmp_state(tcp_t *tcp)
5311754SKacheong.Poon@Sun.COM {
5411754SKacheong.Poon@Sun.COM if (tcp == NULL)
5511754SKacheong.Poon@Sun.COM return (0);
5611754SKacheong.Poon@Sun.COM
5711754SKacheong.Poon@Sun.COM switch (tcp->tcp_state) {
5811754SKacheong.Poon@Sun.COM case TCPS_CLOSED:
5911754SKacheong.Poon@Sun.COM case TCPS_IDLE: /* RFC1213 doesn't have analogue for IDLE & BOUND */
6011754SKacheong.Poon@Sun.COM case TCPS_BOUND:
6111754SKacheong.Poon@Sun.COM return (MIB2_TCP_closed);
6211754SKacheong.Poon@Sun.COM case TCPS_LISTEN:
6311754SKacheong.Poon@Sun.COM return (MIB2_TCP_listen);
6411754SKacheong.Poon@Sun.COM case TCPS_SYN_SENT:
6511754SKacheong.Poon@Sun.COM return (MIB2_TCP_synSent);
6611754SKacheong.Poon@Sun.COM case TCPS_SYN_RCVD:
6711754SKacheong.Poon@Sun.COM return (MIB2_TCP_synReceived);
6811754SKacheong.Poon@Sun.COM case TCPS_ESTABLISHED:
6911754SKacheong.Poon@Sun.COM return (MIB2_TCP_established);
7011754SKacheong.Poon@Sun.COM case TCPS_CLOSE_WAIT:
7111754SKacheong.Poon@Sun.COM return (MIB2_TCP_closeWait);
7211754SKacheong.Poon@Sun.COM case TCPS_FIN_WAIT_1:
7311754SKacheong.Poon@Sun.COM return (MIB2_TCP_finWait1);
7411754SKacheong.Poon@Sun.COM case TCPS_CLOSING:
7511754SKacheong.Poon@Sun.COM return (MIB2_TCP_closing);
7611754SKacheong.Poon@Sun.COM case TCPS_LAST_ACK:
7711754SKacheong.Poon@Sun.COM return (MIB2_TCP_lastAck);
7811754SKacheong.Poon@Sun.COM case TCPS_FIN_WAIT_2:
7911754SKacheong.Poon@Sun.COM return (MIB2_TCP_finWait2);
8011754SKacheong.Poon@Sun.COM case TCPS_TIME_WAIT:
8111754SKacheong.Poon@Sun.COM return (MIB2_TCP_timeWait);
8211754SKacheong.Poon@Sun.COM default:
8311754SKacheong.Poon@Sun.COM return (0);
8411754SKacheong.Poon@Sun.COM }
8511754SKacheong.Poon@Sun.COM }
8611754SKacheong.Poon@Sun.COM
8711754SKacheong.Poon@Sun.COM /*
8811754SKacheong.Poon@Sun.COM * Return SNMP stuff in buffer in mpdata.
8911754SKacheong.Poon@Sun.COM */
9011754SKacheong.Poon@Sun.COM mblk_t *
tcp_snmp_get(queue_t * q,mblk_t * mpctl,boolean_t legacy_req)91*12897SBaban.Kenkre@Sun.COM tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
9211754SKacheong.Poon@Sun.COM {
9311754SKacheong.Poon@Sun.COM mblk_t *mpdata;
9411754SKacheong.Poon@Sun.COM mblk_t *mp_conn_ctl = NULL;
9511754SKacheong.Poon@Sun.COM mblk_t *mp_conn_tail;
9611754SKacheong.Poon@Sun.COM mblk_t *mp_attr_ctl = NULL;
9711754SKacheong.Poon@Sun.COM mblk_t *mp_attr_tail;
9811754SKacheong.Poon@Sun.COM mblk_t *mp6_conn_ctl = NULL;
9911754SKacheong.Poon@Sun.COM mblk_t *mp6_conn_tail;
10011754SKacheong.Poon@Sun.COM mblk_t *mp6_attr_ctl = NULL;
10111754SKacheong.Poon@Sun.COM mblk_t *mp6_attr_tail;
10211754SKacheong.Poon@Sun.COM struct opthdr *optp;
10311754SKacheong.Poon@Sun.COM mib2_tcpConnEntry_t tce;
10411754SKacheong.Poon@Sun.COM mib2_tcp6ConnEntry_t tce6;
10511754SKacheong.Poon@Sun.COM mib2_transportMLPEntry_t mlp;
10611754SKacheong.Poon@Sun.COM connf_t *connfp;
10711754SKacheong.Poon@Sun.COM int i;
10811754SKacheong.Poon@Sun.COM boolean_t ispriv;
10911754SKacheong.Poon@Sun.COM zoneid_t zoneid;
11011754SKacheong.Poon@Sun.COM int v4_conn_idx;
11111754SKacheong.Poon@Sun.COM int v6_conn_idx;
11211754SKacheong.Poon@Sun.COM conn_t *connp = Q_TO_CONN(q);
11311754SKacheong.Poon@Sun.COM tcp_stack_t *tcps;
11411754SKacheong.Poon@Sun.COM ip_stack_t *ipst;
11511754SKacheong.Poon@Sun.COM mblk_t *mp2ctl;
11611754SKacheong.Poon@Sun.COM mib2_tcp_t tcp_mib;
117*12897SBaban.Kenkre@Sun.COM size_t tcp_mib_size, tce_size, tce6_size;
11811754SKacheong.Poon@Sun.COM
11911754SKacheong.Poon@Sun.COM /*
12011754SKacheong.Poon@Sun.COM * make a copy of the original message
12111754SKacheong.Poon@Sun.COM */
12211754SKacheong.Poon@Sun.COM mp2ctl = copymsg(mpctl);
12311754SKacheong.Poon@Sun.COM
12411754SKacheong.Poon@Sun.COM if (mpctl == NULL ||
12511754SKacheong.Poon@Sun.COM (mpdata = mpctl->b_cont) == NULL ||
12611754SKacheong.Poon@Sun.COM (mp_conn_ctl = copymsg(mpctl)) == NULL ||
12711754SKacheong.Poon@Sun.COM (mp_attr_ctl = copymsg(mpctl)) == NULL ||
12811754SKacheong.Poon@Sun.COM (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
12911754SKacheong.Poon@Sun.COM (mp6_attr_ctl = copymsg(mpctl)) == NULL) {
13011754SKacheong.Poon@Sun.COM freemsg(mp_conn_ctl);
13111754SKacheong.Poon@Sun.COM freemsg(mp_attr_ctl);
13211754SKacheong.Poon@Sun.COM freemsg(mp6_conn_ctl);
13311754SKacheong.Poon@Sun.COM freemsg(mp6_attr_ctl);
13411754SKacheong.Poon@Sun.COM freemsg(mpctl);
13511754SKacheong.Poon@Sun.COM freemsg(mp2ctl);
13611754SKacheong.Poon@Sun.COM return (NULL);
13711754SKacheong.Poon@Sun.COM }
13811754SKacheong.Poon@Sun.COM
13911754SKacheong.Poon@Sun.COM ipst = connp->conn_netstack->netstack_ip;
14011754SKacheong.Poon@Sun.COM tcps = connp->conn_netstack->netstack_tcp;
14111754SKacheong.Poon@Sun.COM
142*12897SBaban.Kenkre@Sun.COM if (legacy_req) {
143*12897SBaban.Kenkre@Sun.COM tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
144*12897SBaban.Kenkre@Sun.COM tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
145*12897SBaban.Kenkre@Sun.COM tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
146*12897SBaban.Kenkre@Sun.COM } else {
147*12897SBaban.Kenkre@Sun.COM tcp_mib_size = sizeof (mib2_tcp_t);
148*12897SBaban.Kenkre@Sun.COM tce_size = sizeof (mib2_tcpConnEntry_t);
149*12897SBaban.Kenkre@Sun.COM tce6_size = sizeof (mib2_tcp6ConnEntry_t);
150*12897SBaban.Kenkre@Sun.COM }
151*12897SBaban.Kenkre@Sun.COM
15211754SKacheong.Poon@Sun.COM bzero(&tcp_mib, sizeof (tcp_mib));
15311754SKacheong.Poon@Sun.COM
15411754SKacheong.Poon@Sun.COM /* build table of connections -- need count in fixed part */
15511754SKacheong.Poon@Sun.COM SET_MIB(tcp_mib.tcpRtoAlgorithm, 4); /* vanj */
15611754SKacheong.Poon@Sun.COM SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
15711754SKacheong.Poon@Sun.COM SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
15811754SKacheong.Poon@Sun.COM SET_MIB(tcp_mib.tcpMaxConn, -1);
15911754SKacheong.Poon@Sun.COM SET_MIB(tcp_mib.tcpCurrEstab, 0);
16011754SKacheong.Poon@Sun.COM
16111754SKacheong.Poon@Sun.COM ispriv =
16211754SKacheong.Poon@Sun.COM secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
16311754SKacheong.Poon@Sun.COM zoneid = Q_TO_CONN(q)->conn_zoneid;
16411754SKacheong.Poon@Sun.COM
16511754SKacheong.Poon@Sun.COM v4_conn_idx = v6_conn_idx = 0;
16611754SKacheong.Poon@Sun.COM mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
16711754SKacheong.Poon@Sun.COM
16811754SKacheong.Poon@Sun.COM for (i = 0; i < CONN_G_HASH_SIZE; i++) {
16911754SKacheong.Poon@Sun.COM ipst = tcps->tcps_netstack->netstack_ip;
17011754SKacheong.Poon@Sun.COM
17111754SKacheong.Poon@Sun.COM connfp = &ipst->ips_ipcl_globalhash_fanout[i];
17211754SKacheong.Poon@Sun.COM
17311754SKacheong.Poon@Sun.COM connp = NULL;
17411754SKacheong.Poon@Sun.COM
17511754SKacheong.Poon@Sun.COM while ((connp =
17611754SKacheong.Poon@Sun.COM ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
17711754SKacheong.Poon@Sun.COM tcp_t *tcp;
17811754SKacheong.Poon@Sun.COM boolean_t needattr;
17911754SKacheong.Poon@Sun.COM
18011754SKacheong.Poon@Sun.COM if (connp->conn_zoneid != zoneid)
18111754SKacheong.Poon@Sun.COM continue; /* not in this zone */
18211754SKacheong.Poon@Sun.COM
18311754SKacheong.Poon@Sun.COM tcp = connp->conn_tcp;
18411754SKacheong.Poon@Sun.COM TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
18511754SKacheong.Poon@Sun.COM tcp->tcp_ibsegs = 0;
18611754SKacheong.Poon@Sun.COM TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
18711754SKacheong.Poon@Sun.COM tcp->tcp_obsegs = 0;
18811754SKacheong.Poon@Sun.COM
18911754SKacheong.Poon@Sun.COM tce6.tcp6ConnState = tce.tcpConnState =
19011754SKacheong.Poon@Sun.COM tcp_snmp_state(tcp);
19111754SKacheong.Poon@Sun.COM if (tce.tcpConnState == MIB2_TCP_established ||
19211754SKacheong.Poon@Sun.COM tce.tcpConnState == MIB2_TCP_closeWait)
19311772SKacheong.Poon@Sun.COM BUMP_MIB(&tcp_mib, tcpCurrEstab);
19411754SKacheong.Poon@Sun.COM
19511754SKacheong.Poon@Sun.COM needattr = B_FALSE;
19611754SKacheong.Poon@Sun.COM bzero(&mlp, sizeof (mlp));
19711754SKacheong.Poon@Sun.COM if (connp->conn_mlp_type != mlptSingle) {
19811754SKacheong.Poon@Sun.COM if (connp->conn_mlp_type == mlptShared ||
19911754SKacheong.Poon@Sun.COM connp->conn_mlp_type == mlptBoth)
20011754SKacheong.Poon@Sun.COM mlp.tme_flags |= MIB2_TMEF_SHARED;
20111754SKacheong.Poon@Sun.COM if (connp->conn_mlp_type == mlptPrivate ||
20211754SKacheong.Poon@Sun.COM connp->conn_mlp_type == mlptBoth)
20311754SKacheong.Poon@Sun.COM mlp.tme_flags |= MIB2_TMEF_PRIVATE;
20411754SKacheong.Poon@Sun.COM needattr = B_TRUE;
20511754SKacheong.Poon@Sun.COM }
20611754SKacheong.Poon@Sun.COM if (connp->conn_anon_mlp) {
20711754SKacheong.Poon@Sun.COM mlp.tme_flags |= MIB2_TMEF_ANONMLP;
20811754SKacheong.Poon@Sun.COM needattr = B_TRUE;
20911754SKacheong.Poon@Sun.COM }
21011754SKacheong.Poon@Sun.COM switch (connp->conn_mac_mode) {
21111754SKacheong.Poon@Sun.COM case CONN_MAC_DEFAULT:
21211754SKacheong.Poon@Sun.COM break;
21311754SKacheong.Poon@Sun.COM case CONN_MAC_AWARE:
21411754SKacheong.Poon@Sun.COM mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
21511754SKacheong.Poon@Sun.COM needattr = B_TRUE;
21611754SKacheong.Poon@Sun.COM break;
21711754SKacheong.Poon@Sun.COM case CONN_MAC_IMPLICIT:
21811754SKacheong.Poon@Sun.COM mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
21911754SKacheong.Poon@Sun.COM needattr = B_TRUE;
22011754SKacheong.Poon@Sun.COM break;
22111754SKacheong.Poon@Sun.COM }
22211754SKacheong.Poon@Sun.COM if (connp->conn_ixa->ixa_tsl != NULL) {
22311754SKacheong.Poon@Sun.COM ts_label_t *tsl;
22411754SKacheong.Poon@Sun.COM
22511754SKacheong.Poon@Sun.COM tsl = connp->conn_ixa->ixa_tsl;
22611754SKacheong.Poon@Sun.COM mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
22711754SKacheong.Poon@Sun.COM mlp.tme_doi = label2doi(tsl);
22811754SKacheong.Poon@Sun.COM mlp.tme_label = *label2bslabel(tsl);
22911754SKacheong.Poon@Sun.COM needattr = B_TRUE;
23011754SKacheong.Poon@Sun.COM }
23111754SKacheong.Poon@Sun.COM
23211754SKacheong.Poon@Sun.COM /* Create a message to report on IPv6 entries */
23311754SKacheong.Poon@Sun.COM if (connp->conn_ipversion == IPV6_VERSION) {
23411754SKacheong.Poon@Sun.COM tce6.tcp6ConnLocalAddress = connp->conn_laddr_v6;
23511754SKacheong.Poon@Sun.COM tce6.tcp6ConnRemAddress = connp->conn_faddr_v6;
23611754SKacheong.Poon@Sun.COM tce6.tcp6ConnLocalPort = ntohs(connp->conn_lport);
23711754SKacheong.Poon@Sun.COM tce6.tcp6ConnRemPort = ntohs(connp->conn_fport);
23811754SKacheong.Poon@Sun.COM if (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET) {
23911754SKacheong.Poon@Sun.COM tce6.tcp6ConnIfIndex =
24011754SKacheong.Poon@Sun.COM connp->conn_ixa->ixa_scopeid;
24111754SKacheong.Poon@Sun.COM } else {
24211754SKacheong.Poon@Sun.COM tce6.tcp6ConnIfIndex = connp->conn_bound_if;
24311754SKacheong.Poon@Sun.COM }
24411754SKacheong.Poon@Sun.COM /* Don't want just anybody seeing these... */
24511754SKacheong.Poon@Sun.COM if (ispriv) {
24611754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_snxt =
24711754SKacheong.Poon@Sun.COM tcp->tcp_snxt;
24811754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_suna =
24911754SKacheong.Poon@Sun.COM tcp->tcp_suna;
25011754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_rnxt =
25111754SKacheong.Poon@Sun.COM tcp->tcp_rnxt;
25211754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_rack =
25311754SKacheong.Poon@Sun.COM tcp->tcp_rack;
25411754SKacheong.Poon@Sun.COM } else {
25511754SKacheong.Poon@Sun.COM /*
25611754SKacheong.Poon@Sun.COM * Netstat, unfortunately, uses this to
25711754SKacheong.Poon@Sun.COM * get send/receive queue sizes. How to fix?
25811754SKacheong.Poon@Sun.COM * Why not compute the difference only?
25911754SKacheong.Poon@Sun.COM */
26011754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_snxt =
26111754SKacheong.Poon@Sun.COM tcp->tcp_snxt - tcp->tcp_suna;
26211754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_suna = 0;
26311754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_rnxt =
26411754SKacheong.Poon@Sun.COM tcp->tcp_rnxt - tcp->tcp_rack;
26511754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_rack = 0;
26611754SKacheong.Poon@Sun.COM }
26711754SKacheong.Poon@Sun.COM
26811754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
26911754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
27011754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_rto = tcp->tcp_rto;
27111754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_mss = tcp->tcp_mss;
27211754SKacheong.Poon@Sun.COM tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
27311754SKacheong.Poon@Sun.COM
27411754SKacheong.Poon@Sun.COM tce6.tcp6ConnCreationProcess =
27511754SKacheong.Poon@Sun.COM (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
27611754SKacheong.Poon@Sun.COM connp->conn_cpid;
27711754SKacheong.Poon@Sun.COM tce6.tcp6ConnCreationTime = connp->conn_open_time;
27811754SKacheong.Poon@Sun.COM
27911754SKacheong.Poon@Sun.COM (void) snmp_append_data2(mp6_conn_ctl->b_cont,
280*12897SBaban.Kenkre@Sun.COM &mp6_conn_tail, (char *)&tce6, tce6_size);
28111754SKacheong.Poon@Sun.COM
28211754SKacheong.Poon@Sun.COM mlp.tme_connidx = v6_conn_idx++;
28311754SKacheong.Poon@Sun.COM if (needattr)
28411754SKacheong.Poon@Sun.COM (void) snmp_append_data2(mp6_attr_ctl->b_cont,
28511754SKacheong.Poon@Sun.COM &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
28611754SKacheong.Poon@Sun.COM }
28711754SKacheong.Poon@Sun.COM /*
28811754SKacheong.Poon@Sun.COM * Create an IPv4 table entry for IPv4 entries and also
28911754SKacheong.Poon@Sun.COM * for IPv6 entries which are bound to in6addr_any
29011754SKacheong.Poon@Sun.COM * but don't have IPV6_V6ONLY set.
29111754SKacheong.Poon@Sun.COM * (i.e. anything an IPv4 peer could connect to)
29211754SKacheong.Poon@Sun.COM */
29311754SKacheong.Poon@Sun.COM if (connp->conn_ipversion == IPV4_VERSION ||
29411754SKacheong.Poon@Sun.COM (tcp->tcp_state <= TCPS_LISTEN &&
29511754SKacheong.Poon@Sun.COM !connp->conn_ipv6_v6only &&
29611754SKacheong.Poon@Sun.COM IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
29711754SKacheong.Poon@Sun.COM if (connp->conn_ipversion == IPV6_VERSION) {
29811754SKacheong.Poon@Sun.COM tce.tcpConnRemAddress = INADDR_ANY;
29911754SKacheong.Poon@Sun.COM tce.tcpConnLocalAddress = INADDR_ANY;
30011754SKacheong.Poon@Sun.COM } else {
30111754SKacheong.Poon@Sun.COM tce.tcpConnRemAddress =
30211754SKacheong.Poon@Sun.COM connp->conn_faddr_v4;
30311754SKacheong.Poon@Sun.COM tce.tcpConnLocalAddress =
30411754SKacheong.Poon@Sun.COM connp->conn_laddr_v4;
30511754SKacheong.Poon@Sun.COM }
30611754SKacheong.Poon@Sun.COM tce.tcpConnLocalPort = ntohs(connp->conn_lport);
30711754SKacheong.Poon@Sun.COM tce.tcpConnRemPort = ntohs(connp->conn_fport);
30811754SKacheong.Poon@Sun.COM /* Don't want just anybody seeing these... */
30911754SKacheong.Poon@Sun.COM if (ispriv) {
31011754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_snxt =
31111754SKacheong.Poon@Sun.COM tcp->tcp_snxt;
31211754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_suna =
31311754SKacheong.Poon@Sun.COM tcp->tcp_suna;
31411754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_rnxt =
31511754SKacheong.Poon@Sun.COM tcp->tcp_rnxt;
31611754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_rack =
31711754SKacheong.Poon@Sun.COM tcp->tcp_rack;
31811754SKacheong.Poon@Sun.COM } else {
31911754SKacheong.Poon@Sun.COM /*
32011754SKacheong.Poon@Sun.COM * Netstat, unfortunately, uses this to
32111754SKacheong.Poon@Sun.COM * get send/receive queue sizes. How
32211754SKacheong.Poon@Sun.COM * to fix?
32311754SKacheong.Poon@Sun.COM * Why not compute the difference only?
32411754SKacheong.Poon@Sun.COM */
32511754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_snxt =
32611754SKacheong.Poon@Sun.COM tcp->tcp_snxt - tcp->tcp_suna;
32711754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_suna = 0;
32811754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_rnxt =
32911754SKacheong.Poon@Sun.COM tcp->tcp_rnxt - tcp->tcp_rack;
33011754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_rack = 0;
33111754SKacheong.Poon@Sun.COM }
33211754SKacheong.Poon@Sun.COM
33311754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
33411754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
33511754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_rto = tcp->tcp_rto;
33611754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_mss = tcp->tcp_mss;
33711754SKacheong.Poon@Sun.COM tce.tcpConnEntryInfo.ce_state =
33811754SKacheong.Poon@Sun.COM tcp->tcp_state;
33911754SKacheong.Poon@Sun.COM
34011754SKacheong.Poon@Sun.COM tce.tcpConnCreationProcess =
34111754SKacheong.Poon@Sun.COM (connp->conn_cpid < 0) ?
34211754SKacheong.Poon@Sun.COM MIB2_UNKNOWN_PROCESS :
34311754SKacheong.Poon@Sun.COM connp->conn_cpid;
34411754SKacheong.Poon@Sun.COM tce.tcpConnCreationTime = connp->conn_open_time;
34511754SKacheong.Poon@Sun.COM
34611754SKacheong.Poon@Sun.COM (void) snmp_append_data2(mp_conn_ctl->b_cont,
347*12897SBaban.Kenkre@Sun.COM &mp_conn_tail, (char *)&tce, tce_size);
34811754SKacheong.Poon@Sun.COM
34911754SKacheong.Poon@Sun.COM mlp.tme_connidx = v4_conn_idx++;
35011754SKacheong.Poon@Sun.COM if (needattr)
35111754SKacheong.Poon@Sun.COM (void) snmp_append_data2(
35211754SKacheong.Poon@Sun.COM mp_attr_ctl->b_cont,
35311754SKacheong.Poon@Sun.COM &mp_attr_tail, (char *)&mlp,
35411754SKacheong.Poon@Sun.COM sizeof (mlp));
35511754SKacheong.Poon@Sun.COM }
35611754SKacheong.Poon@Sun.COM }
35711754SKacheong.Poon@Sun.COM }
35811754SKacheong.Poon@Sun.COM
35911772SKacheong.Poon@Sun.COM tcp_sum_mib(tcps, &tcp_mib);
36011754SKacheong.Poon@Sun.COM
361*12897SBaban.Kenkre@Sun.COM /* Fixed length structure for IPv4 and IPv6 counters */
362*12897SBaban.Kenkre@Sun.COM SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
363*12897SBaban.Kenkre@Sun.COM SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
364*12897SBaban.Kenkre@Sun.COM
36511772SKacheong.Poon@Sun.COM /*
36611772SKacheong.Poon@Sun.COM * Synchronize 32- and 64-bit counters. Note that tcpInSegs and
36711772SKacheong.Poon@Sun.COM * tcpOutSegs are not updated anywhere in TCP. The new 64 bits
36811772SKacheong.Poon@Sun.COM * counters are used. Hence the old counters' values in tcp_sc_mib
36911772SKacheong.Poon@Sun.COM * are always 0.
37011772SKacheong.Poon@Sun.COM */
37111754SKacheong.Poon@Sun.COM SYNC32_MIB(&tcp_mib, tcpInSegs, tcpHCInSegs);
37211754SKacheong.Poon@Sun.COM SYNC32_MIB(&tcp_mib, tcpOutSegs, tcpHCOutSegs);
37311754SKacheong.Poon@Sun.COM
37411754SKacheong.Poon@Sun.COM optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
37511754SKacheong.Poon@Sun.COM optp->level = MIB2_TCP;
37611754SKacheong.Poon@Sun.COM optp->name = 0;
377*12897SBaban.Kenkre@Sun.COM (void) snmp_append_data(mpdata, (char *)&tcp_mib, tcp_mib_size);
37811754SKacheong.Poon@Sun.COM optp->len = msgdsize(mpdata);
37911754SKacheong.Poon@Sun.COM qreply(q, mpctl);
38011754SKacheong.Poon@Sun.COM
38111754SKacheong.Poon@Sun.COM /* table of connections... */
38211754SKacheong.Poon@Sun.COM optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
38311754SKacheong.Poon@Sun.COM sizeof (struct T_optmgmt_ack)];
38411754SKacheong.Poon@Sun.COM optp->level = MIB2_TCP;
38511754SKacheong.Poon@Sun.COM optp->name = MIB2_TCP_CONN;
38611754SKacheong.Poon@Sun.COM optp->len = msgdsize(mp_conn_ctl->b_cont);
38711754SKacheong.Poon@Sun.COM qreply(q, mp_conn_ctl);
38811754SKacheong.Poon@Sun.COM
38911754SKacheong.Poon@Sun.COM /* table of MLP attributes... */
39011754SKacheong.Poon@Sun.COM optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
39111754SKacheong.Poon@Sun.COM sizeof (struct T_optmgmt_ack)];
39211754SKacheong.Poon@Sun.COM optp->level = MIB2_TCP;
39311754SKacheong.Poon@Sun.COM optp->name = EXPER_XPORT_MLP;
39411754SKacheong.Poon@Sun.COM optp->len = msgdsize(mp_attr_ctl->b_cont);
39511754SKacheong.Poon@Sun.COM if (optp->len == 0)
39611754SKacheong.Poon@Sun.COM freemsg(mp_attr_ctl);
39711754SKacheong.Poon@Sun.COM else
39811754SKacheong.Poon@Sun.COM qreply(q, mp_attr_ctl);
39911754SKacheong.Poon@Sun.COM
40011754SKacheong.Poon@Sun.COM /* table of IPv6 connections... */
40111754SKacheong.Poon@Sun.COM optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
40211754SKacheong.Poon@Sun.COM sizeof (struct T_optmgmt_ack)];
40311754SKacheong.Poon@Sun.COM optp->level = MIB2_TCP6;
40411754SKacheong.Poon@Sun.COM optp->name = MIB2_TCP6_CONN;
40511754SKacheong.Poon@Sun.COM optp->len = msgdsize(mp6_conn_ctl->b_cont);
40611754SKacheong.Poon@Sun.COM qreply(q, mp6_conn_ctl);
40711754SKacheong.Poon@Sun.COM
40811754SKacheong.Poon@Sun.COM /* table of IPv6 MLP attributes... */
40911754SKacheong.Poon@Sun.COM optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
41011754SKacheong.Poon@Sun.COM sizeof (struct T_optmgmt_ack)];
41111754SKacheong.Poon@Sun.COM optp->level = MIB2_TCP6;
41211754SKacheong.Poon@Sun.COM optp->name = EXPER_XPORT_MLP;
41311754SKacheong.Poon@Sun.COM optp->len = msgdsize(mp6_attr_ctl->b_cont);
41411754SKacheong.Poon@Sun.COM if (optp->len == 0)
41511754SKacheong.Poon@Sun.COM freemsg(mp6_attr_ctl);
41611754SKacheong.Poon@Sun.COM else
41711754SKacheong.Poon@Sun.COM qreply(q, mp6_attr_ctl);
41811754SKacheong.Poon@Sun.COM return (mp2ctl);
41911754SKacheong.Poon@Sun.COM }
42011754SKacheong.Poon@Sun.COM
42111754SKacheong.Poon@Sun.COM /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests */
42211754SKacheong.Poon@Sun.COM /* ARGSUSED */
42311754SKacheong.Poon@Sun.COM int
tcp_snmp_set(queue_t * q,int level,int name,uchar_t * ptr,int len)42411754SKacheong.Poon@Sun.COM tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
42511754SKacheong.Poon@Sun.COM {
42611754SKacheong.Poon@Sun.COM mib2_tcpConnEntry_t *tce = (mib2_tcpConnEntry_t *)ptr;
42711754SKacheong.Poon@Sun.COM
42811754SKacheong.Poon@Sun.COM switch (level) {
42911754SKacheong.Poon@Sun.COM case MIB2_TCP:
43011754SKacheong.Poon@Sun.COM switch (name) {
43111754SKacheong.Poon@Sun.COM case 13:
43211754SKacheong.Poon@Sun.COM if (tce->tcpConnState != MIB2_TCP_deleteTCB)
43311754SKacheong.Poon@Sun.COM return (0);
43411754SKacheong.Poon@Sun.COM /* TODO: delete entry defined by tce */
43511754SKacheong.Poon@Sun.COM return (1);
43611754SKacheong.Poon@Sun.COM default:
43711754SKacheong.Poon@Sun.COM return (0);
43811754SKacheong.Poon@Sun.COM }
43911754SKacheong.Poon@Sun.COM default:
44011754SKacheong.Poon@Sun.COM return (1);
44111754SKacheong.Poon@Sun.COM }
44211754SKacheong.Poon@Sun.COM }
44311754SKacheong.Poon@Sun.COM
44411754SKacheong.Poon@Sun.COM /*
44511754SKacheong.Poon@Sun.COM * TCP Kstats implementation
44611754SKacheong.Poon@Sun.COM */
44711754SKacheong.Poon@Sun.COM void *
tcp_kstat_init(netstackid_t stackid)44811754SKacheong.Poon@Sun.COM tcp_kstat_init(netstackid_t stackid)
44911754SKacheong.Poon@Sun.COM {
45011754SKacheong.Poon@Sun.COM kstat_t *ksp;
45111754SKacheong.Poon@Sun.COM
45211754SKacheong.Poon@Sun.COM tcp_named_kstat_t template = {
45311754SKacheong.Poon@Sun.COM { "rtoAlgorithm", KSTAT_DATA_INT32, 0 },
45411754SKacheong.Poon@Sun.COM { "rtoMin", KSTAT_DATA_INT32, 0 },
45511754SKacheong.Poon@Sun.COM { "rtoMax", KSTAT_DATA_INT32, 0 },
45611754SKacheong.Poon@Sun.COM { "maxConn", KSTAT_DATA_INT32, 0 },
45711754SKacheong.Poon@Sun.COM { "activeOpens", KSTAT_DATA_UINT32, 0 },
45811754SKacheong.Poon@Sun.COM { "passiveOpens", KSTAT_DATA_UINT32, 0 },
45911754SKacheong.Poon@Sun.COM { "attemptFails", KSTAT_DATA_UINT32, 0 },
46011754SKacheong.Poon@Sun.COM { "estabResets", KSTAT_DATA_UINT32, 0 },
46111754SKacheong.Poon@Sun.COM { "currEstab", KSTAT_DATA_UINT32, 0 },
46211754SKacheong.Poon@Sun.COM { "inSegs", KSTAT_DATA_UINT64, 0 },
46311754SKacheong.Poon@Sun.COM { "outSegs", KSTAT_DATA_UINT64, 0 },
46411754SKacheong.Poon@Sun.COM { "retransSegs", KSTAT_DATA_UINT32, 0 },
46511754SKacheong.Poon@Sun.COM { "connTableSize", KSTAT_DATA_INT32, 0 },
46611754SKacheong.Poon@Sun.COM { "outRsts", KSTAT_DATA_UINT32, 0 },
46711754SKacheong.Poon@Sun.COM { "outDataSegs", KSTAT_DATA_UINT32, 0 },
46811754SKacheong.Poon@Sun.COM { "outDataBytes", KSTAT_DATA_UINT32, 0 },
46911754SKacheong.Poon@Sun.COM { "retransBytes", KSTAT_DATA_UINT32, 0 },
47011754SKacheong.Poon@Sun.COM { "outAck", KSTAT_DATA_UINT32, 0 },
47111754SKacheong.Poon@Sun.COM { "outAckDelayed", KSTAT_DATA_UINT32, 0 },
47211754SKacheong.Poon@Sun.COM { "outUrg", KSTAT_DATA_UINT32, 0 },
47311754SKacheong.Poon@Sun.COM { "outWinUpdate", KSTAT_DATA_UINT32, 0 },
47411754SKacheong.Poon@Sun.COM { "outWinProbe", KSTAT_DATA_UINT32, 0 },
47511754SKacheong.Poon@Sun.COM { "outControl", KSTAT_DATA_UINT32, 0 },
47611754SKacheong.Poon@Sun.COM { "outFastRetrans", KSTAT_DATA_UINT32, 0 },
47711754SKacheong.Poon@Sun.COM { "inAckSegs", KSTAT_DATA_UINT32, 0 },
47811754SKacheong.Poon@Sun.COM { "inAckBytes", KSTAT_DATA_UINT32, 0 },
47911754SKacheong.Poon@Sun.COM { "inDupAck", KSTAT_DATA_UINT32, 0 },
48011754SKacheong.Poon@Sun.COM { "inAckUnsent", KSTAT_DATA_UINT32, 0 },
48111754SKacheong.Poon@Sun.COM { "inDataInorderSegs", KSTAT_DATA_UINT32, 0 },
48211754SKacheong.Poon@Sun.COM { "inDataInorderBytes", KSTAT_DATA_UINT32, 0 },
48311754SKacheong.Poon@Sun.COM { "inDataUnorderSegs", KSTAT_DATA_UINT32, 0 },
48411754SKacheong.Poon@Sun.COM { "inDataUnorderBytes", KSTAT_DATA_UINT32, 0 },
48511754SKacheong.Poon@Sun.COM { "inDataDupSegs", KSTAT_DATA_UINT32, 0 },
48611754SKacheong.Poon@Sun.COM { "inDataDupBytes", KSTAT_DATA_UINT32, 0 },
48711754SKacheong.Poon@Sun.COM { "inDataPartDupSegs", KSTAT_DATA_UINT32, 0 },
48811754SKacheong.Poon@Sun.COM { "inDataPartDupBytes", KSTAT_DATA_UINT32, 0 },
48911754SKacheong.Poon@Sun.COM { "inDataPastWinSegs", KSTAT_DATA_UINT32, 0 },
49011754SKacheong.Poon@Sun.COM { "inDataPastWinBytes", KSTAT_DATA_UINT32, 0 },
49111754SKacheong.Poon@Sun.COM { "inWinProbe", KSTAT_DATA_UINT32, 0 },
49211754SKacheong.Poon@Sun.COM { "inWinUpdate", KSTAT_DATA_UINT32, 0 },
49311754SKacheong.Poon@Sun.COM { "inClosed", KSTAT_DATA_UINT32, 0 },
49411754SKacheong.Poon@Sun.COM { "rttUpdate", KSTAT_DATA_UINT32, 0 },
49511754SKacheong.Poon@Sun.COM { "rttNoUpdate", KSTAT_DATA_UINT32, 0 },
49611754SKacheong.Poon@Sun.COM { "timRetrans", KSTAT_DATA_UINT32, 0 },
49711754SKacheong.Poon@Sun.COM { "timRetransDrop", KSTAT_DATA_UINT32, 0 },
49811754SKacheong.Poon@Sun.COM { "timKeepalive", KSTAT_DATA_UINT32, 0 },
49911754SKacheong.Poon@Sun.COM { "timKeepaliveProbe", KSTAT_DATA_UINT32, 0 },
50011754SKacheong.Poon@Sun.COM { "timKeepaliveDrop", KSTAT_DATA_UINT32, 0 },
50111754SKacheong.Poon@Sun.COM { "listenDrop", KSTAT_DATA_UINT32, 0 },
50211754SKacheong.Poon@Sun.COM { "listenDropQ0", KSTAT_DATA_UINT32, 0 },
50311754SKacheong.Poon@Sun.COM { "halfOpenDrop", KSTAT_DATA_UINT32, 0 },
50411754SKacheong.Poon@Sun.COM { "outSackRetransSegs", KSTAT_DATA_UINT32, 0 },
50511754SKacheong.Poon@Sun.COM { "connTableSize6", KSTAT_DATA_INT32, 0 }
50611754SKacheong.Poon@Sun.COM };
50711754SKacheong.Poon@Sun.COM
50811754SKacheong.Poon@Sun.COM ksp = kstat_create_netstack(TCP_MOD_NAME, 0, TCP_MOD_NAME, "mib2",
50911754SKacheong.Poon@Sun.COM KSTAT_TYPE_NAMED, NUM_OF_FIELDS(tcp_named_kstat_t), 0, stackid);
51011754SKacheong.Poon@Sun.COM
51111754SKacheong.Poon@Sun.COM if (ksp == NULL)
51211754SKacheong.Poon@Sun.COM return (NULL);
51311754SKacheong.Poon@Sun.COM
51411754SKacheong.Poon@Sun.COM template.rtoAlgorithm.value.ui32 = 4;
51511754SKacheong.Poon@Sun.COM template.maxConn.value.i32 = -1;
51611754SKacheong.Poon@Sun.COM
51711754SKacheong.Poon@Sun.COM bcopy(&template, ksp->ks_data, sizeof (template));
51811754SKacheong.Poon@Sun.COM ksp->ks_update = tcp_kstat_update;
51911754SKacheong.Poon@Sun.COM ksp->ks_private = (void *)(uintptr_t)stackid;
52011754SKacheong.Poon@Sun.COM
52111754SKacheong.Poon@Sun.COM kstat_install(ksp);
52211754SKacheong.Poon@Sun.COM return (ksp);
52311754SKacheong.Poon@Sun.COM }
52411754SKacheong.Poon@Sun.COM
52511754SKacheong.Poon@Sun.COM void
tcp_kstat_fini(netstackid_t stackid,kstat_t * ksp)52611754SKacheong.Poon@Sun.COM tcp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
52711754SKacheong.Poon@Sun.COM {
52811754SKacheong.Poon@Sun.COM if (ksp != NULL) {
52911754SKacheong.Poon@Sun.COM ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
53011754SKacheong.Poon@Sun.COM kstat_delete_netstack(ksp, stackid);
53111754SKacheong.Poon@Sun.COM }
53211754SKacheong.Poon@Sun.COM }
53311754SKacheong.Poon@Sun.COM
53411754SKacheong.Poon@Sun.COM static int
tcp_kstat_update(kstat_t * kp,int rw)53511754SKacheong.Poon@Sun.COM tcp_kstat_update(kstat_t *kp, int rw)
53611754SKacheong.Poon@Sun.COM {
53711754SKacheong.Poon@Sun.COM tcp_named_kstat_t *tcpkp;
53811754SKacheong.Poon@Sun.COM tcp_t *tcp;
53911754SKacheong.Poon@Sun.COM connf_t *connfp;
54011754SKacheong.Poon@Sun.COM conn_t *connp;
54111754SKacheong.Poon@Sun.COM int i;
54211754SKacheong.Poon@Sun.COM netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private;
54311754SKacheong.Poon@Sun.COM netstack_t *ns;
54411754SKacheong.Poon@Sun.COM tcp_stack_t *tcps;
54511754SKacheong.Poon@Sun.COM ip_stack_t *ipst;
54611754SKacheong.Poon@Sun.COM mib2_tcp_t tcp_mib;
54711754SKacheong.Poon@Sun.COM
54811754SKacheong.Poon@Sun.COM if (rw == KSTAT_WRITE)
54911754SKacheong.Poon@Sun.COM return (EACCES);
55011754SKacheong.Poon@Sun.COM
55111754SKacheong.Poon@Sun.COM ns = netstack_find_by_stackid(stackid);
55211754SKacheong.Poon@Sun.COM if (ns == NULL)
55311754SKacheong.Poon@Sun.COM return (-1);
55411754SKacheong.Poon@Sun.COM tcps = ns->netstack_tcp;
55511754SKacheong.Poon@Sun.COM if (tcps == NULL) {
55611754SKacheong.Poon@Sun.COM netstack_rele(ns);
55711754SKacheong.Poon@Sun.COM return (-1);
55811754SKacheong.Poon@Sun.COM }
55911754SKacheong.Poon@Sun.COM
56011754SKacheong.Poon@Sun.COM tcpkp = (tcp_named_kstat_t *)kp->ks_data;
56111754SKacheong.Poon@Sun.COM
56211754SKacheong.Poon@Sun.COM tcpkp->currEstab.value.ui32 = 0;
56311754SKacheong.Poon@Sun.COM tcpkp->rtoMin.value.ui32 = tcps->tcps_rexmit_interval_min;
56411754SKacheong.Poon@Sun.COM tcpkp->rtoMax.value.ui32 = tcps->tcps_rexmit_interval_max;
56511754SKacheong.Poon@Sun.COM
56611754SKacheong.Poon@Sun.COM ipst = ns->netstack_ip;
56711754SKacheong.Poon@Sun.COM
56811754SKacheong.Poon@Sun.COM for (i = 0; i < CONN_G_HASH_SIZE; i++) {
56911754SKacheong.Poon@Sun.COM connfp = &ipst->ips_ipcl_globalhash_fanout[i];
57011754SKacheong.Poon@Sun.COM connp = NULL;
57111754SKacheong.Poon@Sun.COM while ((connp =
57211754SKacheong.Poon@Sun.COM ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
57311754SKacheong.Poon@Sun.COM tcp = connp->conn_tcp;
57411754SKacheong.Poon@Sun.COM switch (tcp_snmp_state(tcp)) {
57511754SKacheong.Poon@Sun.COM case MIB2_TCP_established:
57611754SKacheong.Poon@Sun.COM case MIB2_TCP_closeWait:
57711754SKacheong.Poon@Sun.COM tcpkp->currEstab.value.ui32++;
57811754SKacheong.Poon@Sun.COM break;
57911754SKacheong.Poon@Sun.COM }
58011754SKacheong.Poon@Sun.COM }
58111754SKacheong.Poon@Sun.COM }
58211754SKacheong.Poon@Sun.COM bzero(&tcp_mib, sizeof (tcp_mib));
58311754SKacheong.Poon@Sun.COM tcp_sum_mib(tcps, &tcp_mib);
58411754SKacheong.Poon@Sun.COM
585*12897SBaban.Kenkre@Sun.COM /* Fixed length structure for IPv4 and IPv6 counters */
586*12897SBaban.Kenkre@Sun.COM SET_MIB(tcp_mib.tcpConnTableSize, sizeof (mib2_tcpConnEntry_t));
587*12897SBaban.Kenkre@Sun.COM SET_MIB(tcp_mib.tcp6ConnTableSize, sizeof (mib2_tcp6ConnEntry_t));
588*12897SBaban.Kenkre@Sun.COM
58911754SKacheong.Poon@Sun.COM tcpkp->activeOpens.value.ui32 = tcp_mib.tcpActiveOpens;
59011754SKacheong.Poon@Sun.COM tcpkp->passiveOpens.value.ui32 = tcp_mib.tcpPassiveOpens;
59111754SKacheong.Poon@Sun.COM tcpkp->attemptFails.value.ui32 = tcp_mib.tcpAttemptFails;
59211754SKacheong.Poon@Sun.COM tcpkp->estabResets.value.ui32 = tcp_mib.tcpEstabResets;
59311754SKacheong.Poon@Sun.COM tcpkp->inSegs.value.ui64 = tcp_mib.tcpHCInSegs;
59411754SKacheong.Poon@Sun.COM tcpkp->outSegs.value.ui64 = tcp_mib.tcpHCOutSegs;
59511754SKacheong.Poon@Sun.COM tcpkp->retransSegs.value.ui32 = tcp_mib.tcpRetransSegs;
59611754SKacheong.Poon@Sun.COM tcpkp->connTableSize.value.i32 = tcp_mib.tcpConnTableSize;
59711754SKacheong.Poon@Sun.COM tcpkp->outRsts.value.ui32 = tcp_mib.tcpOutRsts;
59811754SKacheong.Poon@Sun.COM tcpkp->outDataSegs.value.ui32 = tcp_mib.tcpOutDataSegs;
59911754SKacheong.Poon@Sun.COM tcpkp->outDataBytes.value.ui32 = tcp_mib.tcpOutDataBytes;
60011754SKacheong.Poon@Sun.COM tcpkp->retransBytes.value.ui32 = tcp_mib.tcpRetransBytes;
60111754SKacheong.Poon@Sun.COM tcpkp->outAck.value.ui32 = tcp_mib.tcpOutAck;
60211754SKacheong.Poon@Sun.COM tcpkp->outAckDelayed.value.ui32 = tcp_mib.tcpOutAckDelayed;
60311754SKacheong.Poon@Sun.COM tcpkp->outUrg.value.ui32 = tcp_mib.tcpOutUrg;
60411754SKacheong.Poon@Sun.COM tcpkp->outWinUpdate.value.ui32 = tcp_mib.tcpOutWinUpdate;
60511754SKacheong.Poon@Sun.COM tcpkp->outWinProbe.value.ui32 = tcp_mib.tcpOutWinProbe;
60611754SKacheong.Poon@Sun.COM tcpkp->outControl.value.ui32 = tcp_mib.tcpOutControl;
60711754SKacheong.Poon@Sun.COM tcpkp->outFastRetrans.value.ui32 = tcp_mib.tcpOutFastRetrans;
60811754SKacheong.Poon@Sun.COM tcpkp->inAckSegs.value.ui32 = tcp_mib.tcpInAckSegs;
60911754SKacheong.Poon@Sun.COM tcpkp->inAckBytes.value.ui32 = tcp_mib.tcpInAckBytes;
61011754SKacheong.Poon@Sun.COM tcpkp->inDupAck.value.ui32 = tcp_mib.tcpInDupAck;
61111754SKacheong.Poon@Sun.COM tcpkp->inAckUnsent.value.ui32 = tcp_mib.tcpInAckUnsent;
61211754SKacheong.Poon@Sun.COM tcpkp->inDataInorderSegs.value.ui32 = tcp_mib.tcpInDataInorderSegs;
61311754SKacheong.Poon@Sun.COM tcpkp->inDataInorderBytes.value.ui32 = tcp_mib.tcpInDataInorderBytes;
61411754SKacheong.Poon@Sun.COM tcpkp->inDataUnorderSegs.value.ui32 = tcp_mib.tcpInDataUnorderSegs;
61511754SKacheong.Poon@Sun.COM tcpkp->inDataUnorderBytes.value.ui32 = tcp_mib.tcpInDataUnorderBytes;
61611754SKacheong.Poon@Sun.COM tcpkp->inDataDupSegs.value.ui32 = tcp_mib.tcpInDataDupSegs;
61711754SKacheong.Poon@Sun.COM tcpkp->inDataDupBytes.value.ui32 = tcp_mib.tcpInDataDupBytes;
61811754SKacheong.Poon@Sun.COM tcpkp->inDataPartDupSegs.value.ui32 = tcp_mib.tcpInDataPartDupSegs;
61911754SKacheong.Poon@Sun.COM tcpkp->inDataPartDupBytes.value.ui32 = tcp_mib.tcpInDataPartDupBytes;
62011754SKacheong.Poon@Sun.COM tcpkp->inDataPastWinSegs.value.ui32 = tcp_mib.tcpInDataPastWinSegs;
62111754SKacheong.Poon@Sun.COM tcpkp->inDataPastWinBytes.value.ui32 = tcp_mib.tcpInDataPastWinBytes;
62211754SKacheong.Poon@Sun.COM tcpkp->inWinProbe.value.ui32 = tcp_mib.tcpInWinProbe;
62311754SKacheong.Poon@Sun.COM tcpkp->inWinUpdate.value.ui32 = tcp_mib.tcpInWinUpdate;
62411754SKacheong.Poon@Sun.COM tcpkp->inClosed.value.ui32 = tcp_mib.tcpInClosed;
62511754SKacheong.Poon@Sun.COM tcpkp->rttNoUpdate.value.ui32 = tcp_mib.tcpRttNoUpdate;
62611754SKacheong.Poon@Sun.COM tcpkp->rttUpdate.value.ui32 = tcp_mib.tcpRttUpdate;
62711754SKacheong.Poon@Sun.COM tcpkp->timRetrans.value.ui32 = tcp_mib.tcpTimRetrans;
62811754SKacheong.Poon@Sun.COM tcpkp->timRetransDrop.value.ui32 = tcp_mib.tcpTimRetransDrop;
62911754SKacheong.Poon@Sun.COM tcpkp->timKeepalive.value.ui32 = tcp_mib.tcpTimKeepalive;
63011754SKacheong.Poon@Sun.COM tcpkp->timKeepaliveProbe.value.ui32 = tcp_mib.tcpTimKeepaliveProbe;
63111754SKacheong.Poon@Sun.COM tcpkp->timKeepaliveDrop.value.ui32 = tcp_mib.tcpTimKeepaliveDrop;
63211754SKacheong.Poon@Sun.COM tcpkp->listenDrop.value.ui32 = tcp_mib.tcpListenDrop;
63311754SKacheong.Poon@Sun.COM tcpkp->listenDropQ0.value.ui32 = tcp_mib.tcpListenDropQ0;
63411754SKacheong.Poon@Sun.COM tcpkp->halfOpenDrop.value.ui32 = tcp_mib.tcpHalfOpenDrop;
63511754SKacheong.Poon@Sun.COM tcpkp->outSackRetransSegs.value.ui32 = tcp_mib.tcpOutSackRetransSegs;
63611754SKacheong.Poon@Sun.COM tcpkp->connTableSize6.value.i32 = tcp_mib.tcp6ConnTableSize;
63711754SKacheong.Poon@Sun.COM
63811754SKacheong.Poon@Sun.COM netstack_rele(ns);
63911754SKacheong.Poon@Sun.COM return (0);
64011754SKacheong.Poon@Sun.COM }
64111754SKacheong.Poon@Sun.COM
64211754SKacheong.Poon@Sun.COM /*
64311754SKacheong.Poon@Sun.COM * kstats related to squeues i.e. not per IP instance
64411754SKacheong.Poon@Sun.COM */
64511754SKacheong.Poon@Sun.COM void *
tcp_g_kstat_init(tcp_g_stat_t * tcp_g_statp)64611754SKacheong.Poon@Sun.COM tcp_g_kstat_init(tcp_g_stat_t *tcp_g_statp)
64711754SKacheong.Poon@Sun.COM {
64811754SKacheong.Poon@Sun.COM kstat_t *ksp;
64911754SKacheong.Poon@Sun.COM
65011754SKacheong.Poon@Sun.COM tcp_g_stat_t template = {
65111754SKacheong.Poon@Sun.COM { "tcp_timermp_alloced", KSTAT_DATA_UINT64 },
65211754SKacheong.Poon@Sun.COM { "tcp_timermp_allocfail", KSTAT_DATA_UINT64 },
65311754SKacheong.Poon@Sun.COM { "tcp_timermp_allocdblfail", KSTAT_DATA_UINT64 },
65411754SKacheong.Poon@Sun.COM { "tcp_freelist_cleanup", KSTAT_DATA_UINT64 },
65511754SKacheong.Poon@Sun.COM };
65611754SKacheong.Poon@Sun.COM
65711754SKacheong.Poon@Sun.COM ksp = kstat_create(TCP_MOD_NAME, 0, "tcpstat_g", "net",
65811754SKacheong.Poon@Sun.COM KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t),
65911754SKacheong.Poon@Sun.COM KSTAT_FLAG_VIRTUAL);
66011754SKacheong.Poon@Sun.COM
66111754SKacheong.Poon@Sun.COM if (ksp == NULL)
66211754SKacheong.Poon@Sun.COM return (NULL);
66311754SKacheong.Poon@Sun.COM
66411754SKacheong.Poon@Sun.COM bcopy(&template, tcp_g_statp, sizeof (template));
66511754SKacheong.Poon@Sun.COM ksp->ks_data = (void *)tcp_g_statp;
66611754SKacheong.Poon@Sun.COM
66711754SKacheong.Poon@Sun.COM kstat_install(ksp);
66811754SKacheong.Poon@Sun.COM return (ksp);
66911754SKacheong.Poon@Sun.COM }
67011754SKacheong.Poon@Sun.COM
67111754SKacheong.Poon@Sun.COM void
tcp_g_kstat_fini(kstat_t * ksp)67211754SKacheong.Poon@Sun.COM tcp_g_kstat_fini(kstat_t *ksp)
67311754SKacheong.Poon@Sun.COM {
67411754SKacheong.Poon@Sun.COM if (ksp != NULL) {
67511754SKacheong.Poon@Sun.COM kstat_delete(ksp);
67611754SKacheong.Poon@Sun.COM }
67711754SKacheong.Poon@Sun.COM }
67811754SKacheong.Poon@Sun.COM
67911754SKacheong.Poon@Sun.COM void *
tcp_kstat2_init(netstackid_t stackid)68011754SKacheong.Poon@Sun.COM tcp_kstat2_init(netstackid_t stackid)
68111754SKacheong.Poon@Sun.COM {
68211754SKacheong.Poon@Sun.COM kstat_t *ksp;
68311754SKacheong.Poon@Sun.COM
68411754SKacheong.Poon@Sun.COM tcp_stat_t template = {
68511754SKacheong.Poon@Sun.COM { "tcp_time_wait_syn_success", KSTAT_DATA_UINT64, 0 },
68611754SKacheong.Poon@Sun.COM { "tcp_clean_death_nondetached", KSTAT_DATA_UINT64, 0 },
68711754SKacheong.Poon@Sun.COM { "tcp_eager_blowoff_q", KSTAT_DATA_UINT64, 0 },
68811754SKacheong.Poon@Sun.COM { "tcp_eager_blowoff_q0", KSTAT_DATA_UINT64, 0 },
68911754SKacheong.Poon@Sun.COM { "tcp_no_listener", KSTAT_DATA_UINT64, 0 },
69011754SKacheong.Poon@Sun.COM { "tcp_listendrop", KSTAT_DATA_UINT64, 0 },
69111754SKacheong.Poon@Sun.COM { "tcp_listendropq0", KSTAT_DATA_UINT64, 0 },
69211754SKacheong.Poon@Sun.COM { "tcp_wsrv_called", KSTAT_DATA_UINT64, 0 },
69311754SKacheong.Poon@Sun.COM { "tcp_flwctl_on", KSTAT_DATA_UINT64, 0 },
69411754SKacheong.Poon@Sun.COM { "tcp_timer_fire_early", KSTAT_DATA_UINT64, 0 },
69511754SKacheong.Poon@Sun.COM { "tcp_timer_fire_miss", KSTAT_DATA_UINT64, 0 },
69611754SKacheong.Poon@Sun.COM { "tcp_zcopy_on", KSTAT_DATA_UINT64, 0 },
69711754SKacheong.Poon@Sun.COM { "tcp_zcopy_off", KSTAT_DATA_UINT64, 0 },
69811754SKacheong.Poon@Sun.COM { "tcp_zcopy_backoff", KSTAT_DATA_UINT64, 0 },
69911754SKacheong.Poon@Sun.COM { "tcp_fusion_flowctl", KSTAT_DATA_UINT64, 0 },
70011754SKacheong.Poon@Sun.COM { "tcp_fusion_backenabled", KSTAT_DATA_UINT64, 0 },
70111754SKacheong.Poon@Sun.COM { "tcp_fusion_urg", KSTAT_DATA_UINT64, 0 },
70211754SKacheong.Poon@Sun.COM { "tcp_fusion_putnext", KSTAT_DATA_UINT64, 0 },
70311754SKacheong.Poon@Sun.COM { "tcp_fusion_unfusable", KSTAT_DATA_UINT64, 0 },
70411754SKacheong.Poon@Sun.COM { "tcp_fusion_aborted", KSTAT_DATA_UINT64, 0 },
70511754SKacheong.Poon@Sun.COM { "tcp_fusion_unqualified", KSTAT_DATA_UINT64, 0 },
70611754SKacheong.Poon@Sun.COM { "tcp_fusion_rrw_busy", KSTAT_DATA_UINT64, 0 },
70711754SKacheong.Poon@Sun.COM { "tcp_fusion_rrw_msgcnt", KSTAT_DATA_UINT64, 0 },
70811754SKacheong.Poon@Sun.COM { "tcp_fusion_rrw_plugged", KSTAT_DATA_UINT64, 0 },
70911754SKacheong.Poon@Sun.COM { "tcp_in_ack_unsent_drop", KSTAT_DATA_UINT64, 0 },
71011754SKacheong.Poon@Sun.COM { "tcp_sock_fallback", KSTAT_DATA_UINT64, 0 },
71111754SKacheong.Poon@Sun.COM { "tcp_lso_enabled", KSTAT_DATA_UINT64, 0 },
71211754SKacheong.Poon@Sun.COM { "tcp_lso_disabled", KSTAT_DATA_UINT64, 0 },
71311754SKacheong.Poon@Sun.COM { "tcp_lso_times", KSTAT_DATA_UINT64, 0 },
71411754SKacheong.Poon@Sun.COM { "tcp_lso_pkt_out", KSTAT_DATA_UINT64, 0 },
71511754SKacheong.Poon@Sun.COM { "tcp_listen_cnt_drop", KSTAT_DATA_UINT64, 0 },
71611754SKacheong.Poon@Sun.COM { "tcp_listen_mem_drop", KSTAT_DATA_UINT64, 0 },
71711754SKacheong.Poon@Sun.COM { "tcp_zwin_mem_drop", KSTAT_DATA_UINT64, 0 },
71811754SKacheong.Poon@Sun.COM { "tcp_zwin_ack_syn", KSTAT_DATA_UINT64, 0 },
71911754SKacheong.Poon@Sun.COM { "tcp_rst_unsent", KSTAT_DATA_UINT64, 0 },
72011754SKacheong.Poon@Sun.COM { "tcp_reclaim_cnt", KSTAT_DATA_UINT64, 0 },
72111754SKacheong.Poon@Sun.COM { "tcp_reass_timeout", KSTAT_DATA_UINT64, 0 },
72211754SKacheong.Poon@Sun.COM #ifdef TCP_DEBUG_COUNTER
72311754SKacheong.Poon@Sun.COM { "tcp_time_wait", KSTAT_DATA_UINT64, 0 },
72411754SKacheong.Poon@Sun.COM { "tcp_rput_time_wait", KSTAT_DATA_UINT64, 0 },
72511754SKacheong.Poon@Sun.COM { "tcp_detach_time_wait", KSTAT_DATA_UINT64, 0 },
72611754SKacheong.Poon@Sun.COM { "tcp_timeout_calls", KSTAT_DATA_UINT64, 0 },
72711754SKacheong.Poon@Sun.COM { "tcp_timeout_cached_alloc", KSTAT_DATA_UINT64, 0 },
72811754SKacheong.Poon@Sun.COM { "tcp_timeout_cancel_reqs", KSTAT_DATA_UINT64, 0 },
72911754SKacheong.Poon@Sun.COM { "tcp_timeout_canceled", KSTAT_DATA_UINT64, 0 },
73011754SKacheong.Poon@Sun.COM { "tcp_timermp_freed", KSTAT_DATA_UINT64, 0 },
73111754SKacheong.Poon@Sun.COM { "tcp_push_timer_cnt", KSTAT_DATA_UINT64, 0 },
73211754SKacheong.Poon@Sun.COM { "tcp_ack_timer_cnt", KSTAT_DATA_UINT64, 0 },
73311754SKacheong.Poon@Sun.COM #endif
73411754SKacheong.Poon@Sun.COM };
73511754SKacheong.Poon@Sun.COM
73611754SKacheong.Poon@Sun.COM ksp = kstat_create_netstack(TCP_MOD_NAME, 0, "tcpstat", "net",
73711754SKacheong.Poon@Sun.COM KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t), 0,
73811754SKacheong.Poon@Sun.COM stackid);
73911754SKacheong.Poon@Sun.COM
74011754SKacheong.Poon@Sun.COM if (ksp == NULL)
74111754SKacheong.Poon@Sun.COM return (NULL);
74211754SKacheong.Poon@Sun.COM
74311754SKacheong.Poon@Sun.COM bcopy(&template, ksp->ks_data, sizeof (template));
74411754SKacheong.Poon@Sun.COM ksp->ks_private = (void *)(uintptr_t)stackid;
74511754SKacheong.Poon@Sun.COM ksp->ks_update = tcp_kstat2_update;
74611754SKacheong.Poon@Sun.COM
74711754SKacheong.Poon@Sun.COM kstat_install(ksp);
74811754SKacheong.Poon@Sun.COM return (ksp);
74911754SKacheong.Poon@Sun.COM }
75011754SKacheong.Poon@Sun.COM
75111754SKacheong.Poon@Sun.COM void
tcp_kstat2_fini(netstackid_t stackid,kstat_t * ksp)75211754SKacheong.Poon@Sun.COM tcp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
75311754SKacheong.Poon@Sun.COM {
75411754SKacheong.Poon@Sun.COM if (ksp != NULL) {
75511754SKacheong.Poon@Sun.COM ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
75611754SKacheong.Poon@Sun.COM kstat_delete_netstack(ksp, stackid);
75711754SKacheong.Poon@Sun.COM }
75811754SKacheong.Poon@Sun.COM }
75911754SKacheong.Poon@Sun.COM
76011754SKacheong.Poon@Sun.COM /*
76111754SKacheong.Poon@Sun.COM * Sum up all per CPU tcp_stat_t kstat counters.
76211754SKacheong.Poon@Sun.COM */
76311754SKacheong.Poon@Sun.COM static int
tcp_kstat2_update(kstat_t * kp,int rw)76411754SKacheong.Poon@Sun.COM tcp_kstat2_update(kstat_t *kp, int rw)
76511754SKacheong.Poon@Sun.COM {
76611754SKacheong.Poon@Sun.COM netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private;
76711754SKacheong.Poon@Sun.COM netstack_t *ns;
76811754SKacheong.Poon@Sun.COM tcp_stack_t *tcps;
76911754SKacheong.Poon@Sun.COM tcp_stat_t *stats;
77011754SKacheong.Poon@Sun.COM int i;
77111754SKacheong.Poon@Sun.COM int cnt;
77211754SKacheong.Poon@Sun.COM
77311754SKacheong.Poon@Sun.COM if (rw == KSTAT_WRITE)
77411754SKacheong.Poon@Sun.COM return (EACCES);
77511754SKacheong.Poon@Sun.COM
77611754SKacheong.Poon@Sun.COM ns = netstack_find_by_stackid(stackid);
77711754SKacheong.Poon@Sun.COM if (ns == NULL)
77811754SKacheong.Poon@Sun.COM return (-1);
77911754SKacheong.Poon@Sun.COM tcps = ns->netstack_tcp;
78011754SKacheong.Poon@Sun.COM if (tcps == NULL) {
78111754SKacheong.Poon@Sun.COM netstack_rele(ns);
78211754SKacheong.Poon@Sun.COM return (-1);
78311754SKacheong.Poon@Sun.COM }
78411754SKacheong.Poon@Sun.COM
78511754SKacheong.Poon@Sun.COM stats = (tcp_stat_t *)kp->ks_data;
78611754SKacheong.Poon@Sun.COM tcp_clr_stats(stats);
78711754SKacheong.Poon@Sun.COM
78811754SKacheong.Poon@Sun.COM /*
78911754SKacheong.Poon@Sun.COM * tcps_sc_cnt may change in the middle of the loop. It is better
79011754SKacheong.Poon@Sun.COM * to get its value first.
79111754SKacheong.Poon@Sun.COM */
79211754SKacheong.Poon@Sun.COM cnt = tcps->tcps_sc_cnt;
79311754SKacheong.Poon@Sun.COM for (i = 0; i < cnt; i++)
79412869SKacheong.Poon@Sun.COM tcp_add_stats(&tcps->tcps_sc[i]->tcp_sc_stats, stats);
79511754SKacheong.Poon@Sun.COM
79611754SKacheong.Poon@Sun.COM netstack_rele(ns);
79711754SKacheong.Poon@Sun.COM return (0);
79811754SKacheong.Poon@Sun.COM }
79911754SKacheong.Poon@Sun.COM
80011754SKacheong.Poon@Sun.COM /*
80112869SKacheong.Poon@Sun.COM * To add stats from one mib2_tcp_t to another. Static fields are not added.
80211754SKacheong.Poon@Sun.COM * The caller should set them up propertly.
80311754SKacheong.Poon@Sun.COM */
80411754SKacheong.Poon@Sun.COM void
tcp_add_mib(mib2_tcp_t * from,mib2_tcp_t * to)80512869SKacheong.Poon@Sun.COM tcp_add_mib(mib2_tcp_t *from, mib2_tcp_t *to)
80611754SKacheong.Poon@Sun.COM {
80711754SKacheong.Poon@Sun.COM to->tcpActiveOpens += from->tcpActiveOpens;
80811754SKacheong.Poon@Sun.COM to->tcpPassiveOpens += from->tcpPassiveOpens;
80911754SKacheong.Poon@Sun.COM to->tcpAttemptFails += from->tcpAttemptFails;
81011754SKacheong.Poon@Sun.COM to->tcpEstabResets += from->tcpEstabResets;
81111754SKacheong.Poon@Sun.COM to->tcpInSegs += from->tcpInSegs;
81211754SKacheong.Poon@Sun.COM to->tcpOutSegs += from->tcpOutSegs;
81311754SKacheong.Poon@Sun.COM to->tcpRetransSegs += from->tcpRetransSegs;
81411754SKacheong.Poon@Sun.COM to->tcpOutRsts += from->tcpOutRsts;
81511754SKacheong.Poon@Sun.COM
81611754SKacheong.Poon@Sun.COM to->tcpOutDataSegs += from->tcpOutDataSegs;
81711754SKacheong.Poon@Sun.COM to->tcpOutDataBytes += from->tcpOutDataBytes;
81811754SKacheong.Poon@Sun.COM to->tcpRetransBytes += from->tcpRetransBytes;
81911754SKacheong.Poon@Sun.COM to->tcpOutAck += from->tcpOutAck;
82011754SKacheong.Poon@Sun.COM to->tcpOutAckDelayed += from->tcpOutAckDelayed;
82111754SKacheong.Poon@Sun.COM to->tcpOutUrg += from->tcpOutUrg;
82211754SKacheong.Poon@Sun.COM to->tcpOutWinUpdate += from->tcpOutWinUpdate;
82311754SKacheong.Poon@Sun.COM to->tcpOutWinProbe += from->tcpOutWinProbe;
82411754SKacheong.Poon@Sun.COM to->tcpOutControl += from->tcpOutControl;
82511754SKacheong.Poon@Sun.COM to->tcpOutFastRetrans += from->tcpOutFastRetrans;
82611754SKacheong.Poon@Sun.COM
82711754SKacheong.Poon@Sun.COM to->tcpInAckBytes += from->tcpInAckBytes;
82811754SKacheong.Poon@Sun.COM to->tcpInDupAck += from->tcpInDupAck;
82911754SKacheong.Poon@Sun.COM to->tcpInAckUnsent += from->tcpInAckUnsent;
83011754SKacheong.Poon@Sun.COM to->tcpInDataInorderSegs += from->tcpInDataInorderSegs;
83111754SKacheong.Poon@Sun.COM to->tcpInDataInorderBytes += from->tcpInDataInorderBytes;
83211754SKacheong.Poon@Sun.COM to->tcpInDataUnorderSegs += from->tcpInDataUnorderSegs;
83311754SKacheong.Poon@Sun.COM to->tcpInDataUnorderBytes += from->tcpInDataUnorderBytes;
83411754SKacheong.Poon@Sun.COM to->tcpInDataDupSegs += from->tcpInDataDupSegs;
83511754SKacheong.Poon@Sun.COM to->tcpInDataDupBytes += from->tcpInDataDupBytes;
83611754SKacheong.Poon@Sun.COM to->tcpInDataPartDupSegs += from->tcpInDataPartDupSegs;
83711754SKacheong.Poon@Sun.COM to->tcpInDataPartDupBytes += from->tcpInDataPartDupBytes;
83811754SKacheong.Poon@Sun.COM to->tcpInDataPastWinSegs += from->tcpInDataPastWinSegs;
83911754SKacheong.Poon@Sun.COM to->tcpInDataPastWinBytes += from->tcpInDataPastWinBytes;
84011754SKacheong.Poon@Sun.COM to->tcpInWinProbe += from->tcpInWinProbe;
84111754SKacheong.Poon@Sun.COM to->tcpInWinUpdate += from->tcpInWinUpdate;
84211754SKacheong.Poon@Sun.COM to->tcpInClosed += from->tcpInClosed;
84311754SKacheong.Poon@Sun.COM
84411754SKacheong.Poon@Sun.COM to->tcpRttNoUpdate += from->tcpRttNoUpdate;
84511754SKacheong.Poon@Sun.COM to->tcpRttUpdate += from->tcpRttUpdate;
84611754SKacheong.Poon@Sun.COM to->tcpTimRetrans += from->tcpTimRetrans;
84711754SKacheong.Poon@Sun.COM to->tcpTimRetransDrop += from->tcpTimRetransDrop;
84811754SKacheong.Poon@Sun.COM to->tcpTimKeepalive += from->tcpTimKeepalive;
84911754SKacheong.Poon@Sun.COM to->tcpTimKeepaliveProbe += from->tcpTimKeepaliveProbe;
85011754SKacheong.Poon@Sun.COM to->tcpTimKeepaliveDrop += from->tcpTimKeepaliveDrop;
85111754SKacheong.Poon@Sun.COM to->tcpListenDrop += from->tcpListenDrop;
85211754SKacheong.Poon@Sun.COM to->tcpListenDropQ0 += from->tcpListenDropQ0;
85311754SKacheong.Poon@Sun.COM to->tcpHalfOpenDrop += from->tcpHalfOpenDrop;
85411754SKacheong.Poon@Sun.COM to->tcpOutSackRetransSegs += from->tcpOutSackRetransSegs;
85511754SKacheong.Poon@Sun.COM to->tcpHCInSegs += from->tcpHCInSegs;
85611754SKacheong.Poon@Sun.COM to->tcpHCOutSegs += from->tcpHCOutSegs;
85711754SKacheong.Poon@Sun.COM }
85811754SKacheong.Poon@Sun.COM
85911754SKacheong.Poon@Sun.COM /*
86011754SKacheong.Poon@Sun.COM * To sum up all MIB2 stats for a tcp_stack_t from all per CPU stats. The
86111754SKacheong.Poon@Sun.COM * caller should initialize the target mib2_tcp_t properly as this function
86211754SKacheong.Poon@Sun.COM * just adds up all the per CPU stats.
86311754SKacheong.Poon@Sun.COM */
86411754SKacheong.Poon@Sun.COM static void
tcp_sum_mib(tcp_stack_t * tcps,mib2_tcp_t * tcp_mib)86511754SKacheong.Poon@Sun.COM tcp_sum_mib(tcp_stack_t *tcps, mib2_tcp_t *tcp_mib)
86611754SKacheong.Poon@Sun.COM {
86711754SKacheong.Poon@Sun.COM int i;
86811754SKacheong.Poon@Sun.COM int cnt;
86911754SKacheong.Poon@Sun.COM
87011754SKacheong.Poon@Sun.COM /*
87111754SKacheong.Poon@Sun.COM * tcps_sc_cnt may change in the middle of the loop. It is better
87211754SKacheong.Poon@Sun.COM * to get its value first.
87311754SKacheong.Poon@Sun.COM */
87411754SKacheong.Poon@Sun.COM cnt = tcps->tcps_sc_cnt;
87511754SKacheong.Poon@Sun.COM for (i = 0; i < cnt; i++)
87612869SKacheong.Poon@Sun.COM tcp_add_mib(&tcps->tcps_sc[i]->tcp_sc_mib, tcp_mib);
87711754SKacheong.Poon@Sun.COM }
87811754SKacheong.Poon@Sun.COM
87911754SKacheong.Poon@Sun.COM /*
88011754SKacheong.Poon@Sun.COM * To set all tcp_stat_t counters to 0.
88111754SKacheong.Poon@Sun.COM */
88212869SKacheong.Poon@Sun.COM static void
tcp_clr_stats(tcp_stat_t * stats)88311754SKacheong.Poon@Sun.COM tcp_clr_stats(tcp_stat_t *stats)
88411754SKacheong.Poon@Sun.COM {
88511754SKacheong.Poon@Sun.COM stats->tcp_time_wait_syn_success.value.ui64 = 0;
88611754SKacheong.Poon@Sun.COM stats->tcp_clean_death_nondetached.value.ui64 = 0;
88711754SKacheong.Poon@Sun.COM stats->tcp_eager_blowoff_q.value.ui64 = 0;
88811754SKacheong.Poon@Sun.COM stats->tcp_eager_blowoff_q0.value.ui64 = 0;
88911754SKacheong.Poon@Sun.COM stats->tcp_no_listener.value.ui64 = 0;
89011754SKacheong.Poon@Sun.COM stats->tcp_listendrop.value.ui64 = 0;
89111754SKacheong.Poon@Sun.COM stats->tcp_listendropq0.value.ui64 = 0;
89211754SKacheong.Poon@Sun.COM stats->tcp_wsrv_called.value.ui64 = 0;
89311754SKacheong.Poon@Sun.COM stats->tcp_flwctl_on.value.ui64 = 0;
89411754SKacheong.Poon@Sun.COM stats->tcp_timer_fire_early.value.ui64 = 0;
89511754SKacheong.Poon@Sun.COM stats->tcp_timer_fire_miss.value.ui64 = 0;
89611754SKacheong.Poon@Sun.COM stats->tcp_zcopy_on.value.ui64 = 0;
89711754SKacheong.Poon@Sun.COM stats->tcp_zcopy_off.value.ui64 = 0;
89811754SKacheong.Poon@Sun.COM stats->tcp_zcopy_backoff.value.ui64 = 0;
89911754SKacheong.Poon@Sun.COM stats->tcp_fusion_flowctl.value.ui64 = 0;
90011754SKacheong.Poon@Sun.COM stats->tcp_fusion_backenabled.value.ui64 = 0;
90111754SKacheong.Poon@Sun.COM stats->tcp_fusion_urg.value.ui64 = 0;
90211754SKacheong.Poon@Sun.COM stats->tcp_fusion_putnext.value.ui64 = 0;
90311754SKacheong.Poon@Sun.COM stats->tcp_fusion_unfusable.value.ui64 = 0;
90411754SKacheong.Poon@Sun.COM stats->tcp_fusion_aborted.value.ui64 = 0;
90511754SKacheong.Poon@Sun.COM stats->tcp_fusion_unqualified.value.ui64 = 0;
90611754SKacheong.Poon@Sun.COM stats->tcp_fusion_rrw_busy.value.ui64 = 0;
90711754SKacheong.Poon@Sun.COM stats->tcp_fusion_rrw_msgcnt.value.ui64 = 0;
90811754SKacheong.Poon@Sun.COM stats->tcp_fusion_rrw_plugged.value.ui64 = 0;
90911754SKacheong.Poon@Sun.COM stats->tcp_in_ack_unsent_drop.value.ui64 = 0;
91011754SKacheong.Poon@Sun.COM stats->tcp_sock_fallback.value.ui64 = 0;
91111754SKacheong.Poon@Sun.COM stats->tcp_lso_enabled.value.ui64 = 0;
91211754SKacheong.Poon@Sun.COM stats->tcp_lso_disabled.value.ui64 = 0;
91311754SKacheong.Poon@Sun.COM stats->tcp_lso_times.value.ui64 = 0;
91411754SKacheong.Poon@Sun.COM stats->tcp_lso_pkt_out.value.ui64 = 0;
91511754SKacheong.Poon@Sun.COM stats->tcp_listen_cnt_drop.value.ui64 = 0;
91611754SKacheong.Poon@Sun.COM stats->tcp_listen_mem_drop.value.ui64 = 0;
91711754SKacheong.Poon@Sun.COM stats->tcp_zwin_mem_drop.value.ui64 = 0;
91811754SKacheong.Poon@Sun.COM stats->tcp_zwin_ack_syn.value.ui64 = 0;
91911754SKacheong.Poon@Sun.COM stats->tcp_rst_unsent.value.ui64 = 0;
92011754SKacheong.Poon@Sun.COM stats->tcp_reclaim_cnt.value.ui64 = 0;
92111754SKacheong.Poon@Sun.COM stats->tcp_reass_timeout.value.ui64 = 0;
92211754SKacheong.Poon@Sun.COM
92311754SKacheong.Poon@Sun.COM #ifdef TCP_DEBUG_COUNTER
92411754SKacheong.Poon@Sun.COM stats->tcp_time_wait.value.ui64 = 0;
92511754SKacheong.Poon@Sun.COM stats->tcp_rput_time_wait.value.ui64 = 0;
92611754SKacheong.Poon@Sun.COM stats->tcp_detach_time_wait.value.ui64 = 0;
92711754SKacheong.Poon@Sun.COM stats->tcp_timeout_calls.value.ui64 = 0;
92811754SKacheong.Poon@Sun.COM stats->tcp_timeout_cached_alloc.value.ui64 = 0;
92911754SKacheong.Poon@Sun.COM stats->tcp_timeout_cancel_reqs.value.ui64 = 0;
93011754SKacheong.Poon@Sun.COM stats->tcp_timeout_canceled.value.ui64 = 0;
93111754SKacheong.Poon@Sun.COM stats->tcp_timermp_freed.value.ui64 = 0;
93211754SKacheong.Poon@Sun.COM stats->tcp_push_timer_cnt.value.ui64 = 0;
93311754SKacheong.Poon@Sun.COM stats->tcp_ack_timer_cnt.value.ui64 = 0;
93411754SKacheong.Poon@Sun.COM #endif
93511754SKacheong.Poon@Sun.COM }
93611754SKacheong.Poon@Sun.COM
93711754SKacheong.Poon@Sun.COM /*
93812869SKacheong.Poon@Sun.COM * To add counters from the per CPU tcp_stat_counter_t to the stack
93912869SKacheong.Poon@Sun.COM * tcp_stat_t.
94011754SKacheong.Poon@Sun.COM */
94112869SKacheong.Poon@Sun.COM static void
tcp_add_stats(tcp_stat_counter_t * from,tcp_stat_t * to)94212869SKacheong.Poon@Sun.COM tcp_add_stats(tcp_stat_counter_t *from, tcp_stat_t *to)
94311754SKacheong.Poon@Sun.COM {
94411754SKacheong.Poon@Sun.COM to->tcp_time_wait_syn_success.value.ui64 +=
94512869SKacheong.Poon@Sun.COM from->tcp_time_wait_syn_success;
94611754SKacheong.Poon@Sun.COM to->tcp_clean_death_nondetached.value.ui64 +=
94712869SKacheong.Poon@Sun.COM from->tcp_clean_death_nondetached;
94811754SKacheong.Poon@Sun.COM to->tcp_eager_blowoff_q.value.ui64 +=
94912869SKacheong.Poon@Sun.COM from->tcp_eager_blowoff_q;
95011754SKacheong.Poon@Sun.COM to->tcp_eager_blowoff_q0.value.ui64 +=
95112869SKacheong.Poon@Sun.COM from->tcp_eager_blowoff_q0;
95211754SKacheong.Poon@Sun.COM to->tcp_no_listener.value.ui64 +=
95312869SKacheong.Poon@Sun.COM from->tcp_no_listener;
95411754SKacheong.Poon@Sun.COM to->tcp_listendrop.value.ui64 +=
95512869SKacheong.Poon@Sun.COM from->tcp_listendrop;
95611754SKacheong.Poon@Sun.COM to->tcp_listendropq0.value.ui64 +=
95712869SKacheong.Poon@Sun.COM from->tcp_listendropq0;
95811754SKacheong.Poon@Sun.COM to->tcp_wsrv_called.value.ui64 +=
95912869SKacheong.Poon@Sun.COM from->tcp_wsrv_called;
96011754SKacheong.Poon@Sun.COM to->tcp_flwctl_on.value.ui64 +=
96112869SKacheong.Poon@Sun.COM from->tcp_flwctl_on;
96211754SKacheong.Poon@Sun.COM to->tcp_timer_fire_early.value.ui64 +=
96312869SKacheong.Poon@Sun.COM from->tcp_timer_fire_early;
96411754SKacheong.Poon@Sun.COM to->tcp_timer_fire_miss.value.ui64 +=
96512869SKacheong.Poon@Sun.COM from->tcp_timer_fire_miss;
96611754SKacheong.Poon@Sun.COM to->tcp_zcopy_on.value.ui64 +=
96712869SKacheong.Poon@Sun.COM from->tcp_zcopy_on;
96811754SKacheong.Poon@Sun.COM to->tcp_zcopy_off.value.ui64 +=
96912869SKacheong.Poon@Sun.COM from->tcp_zcopy_off;
97011754SKacheong.Poon@Sun.COM to->tcp_zcopy_backoff.value.ui64 +=
97112869SKacheong.Poon@Sun.COM from->tcp_zcopy_backoff;
97211754SKacheong.Poon@Sun.COM to->tcp_fusion_flowctl.value.ui64 +=
97312869SKacheong.Poon@Sun.COM from->tcp_fusion_flowctl;
97411754SKacheong.Poon@Sun.COM to->tcp_fusion_backenabled.value.ui64 +=
97512869SKacheong.Poon@Sun.COM from->tcp_fusion_backenabled;
97611754SKacheong.Poon@Sun.COM to->tcp_fusion_urg.value.ui64 +=
97712869SKacheong.Poon@Sun.COM from->tcp_fusion_urg;
97811754SKacheong.Poon@Sun.COM to->tcp_fusion_putnext.value.ui64 +=
97912869SKacheong.Poon@Sun.COM from->tcp_fusion_putnext;
98011754SKacheong.Poon@Sun.COM to->tcp_fusion_unfusable.value.ui64 +=
98112869SKacheong.Poon@Sun.COM from->tcp_fusion_unfusable;
98211754SKacheong.Poon@Sun.COM to->tcp_fusion_aborted.value.ui64 +=
98312869SKacheong.Poon@Sun.COM from->tcp_fusion_aborted;
98411754SKacheong.Poon@Sun.COM to->tcp_fusion_unqualified.value.ui64 +=
98512869SKacheong.Poon@Sun.COM from->tcp_fusion_unqualified;
98611754SKacheong.Poon@Sun.COM to->tcp_fusion_rrw_busy.value.ui64 +=
98712869SKacheong.Poon@Sun.COM from->tcp_fusion_rrw_busy;
98811754SKacheong.Poon@Sun.COM to->tcp_fusion_rrw_msgcnt.value.ui64 +=
98912869SKacheong.Poon@Sun.COM from->tcp_fusion_rrw_msgcnt;
99011754SKacheong.Poon@Sun.COM to->tcp_fusion_rrw_plugged.value.ui64 +=
99112869SKacheong.Poon@Sun.COM from->tcp_fusion_rrw_plugged;
99211754SKacheong.Poon@Sun.COM to->tcp_in_ack_unsent_drop.value.ui64 +=
99312869SKacheong.Poon@Sun.COM from->tcp_in_ack_unsent_drop;
99411754SKacheong.Poon@Sun.COM to->tcp_sock_fallback.value.ui64 +=
99512869SKacheong.Poon@Sun.COM from->tcp_sock_fallback;
99611754SKacheong.Poon@Sun.COM to->tcp_lso_enabled.value.ui64 +=
99712869SKacheong.Poon@Sun.COM from->tcp_lso_enabled;
99811754SKacheong.Poon@Sun.COM to->tcp_lso_disabled.value.ui64 +=
99912869SKacheong.Poon@Sun.COM from->tcp_lso_disabled;
100011754SKacheong.Poon@Sun.COM to->tcp_lso_times.value.ui64 +=
100112869SKacheong.Poon@Sun.COM from->tcp_lso_times;
100211754SKacheong.Poon@Sun.COM to->tcp_lso_pkt_out.value.ui64 +=
100312869SKacheong.Poon@Sun.COM from->tcp_lso_pkt_out;
100411754SKacheong.Poon@Sun.COM to->tcp_listen_cnt_drop.value.ui64 +=
100512869SKacheong.Poon@Sun.COM from->tcp_listen_cnt_drop;
100611754SKacheong.Poon@Sun.COM to->tcp_listen_mem_drop.value.ui64 +=
100712869SKacheong.Poon@Sun.COM from->tcp_listen_mem_drop;
100811754SKacheong.Poon@Sun.COM to->tcp_zwin_mem_drop.value.ui64 +=
100912869SKacheong.Poon@Sun.COM from->tcp_zwin_mem_drop;
101011754SKacheong.Poon@Sun.COM to->tcp_zwin_ack_syn.value.ui64 +=
101112869SKacheong.Poon@Sun.COM from->tcp_zwin_ack_syn;
101211754SKacheong.Poon@Sun.COM to->tcp_rst_unsent.value.ui64 +=
101312869SKacheong.Poon@Sun.COM from->tcp_rst_unsent;
101411754SKacheong.Poon@Sun.COM to->tcp_reclaim_cnt.value.ui64 +=
101512869SKacheong.Poon@Sun.COM from->tcp_reclaim_cnt;
101611754SKacheong.Poon@Sun.COM to->tcp_reass_timeout.value.ui64 +=
101712869SKacheong.Poon@Sun.COM from->tcp_reass_timeout;
101811754SKacheong.Poon@Sun.COM
101911754SKacheong.Poon@Sun.COM #ifdef TCP_DEBUG_COUNTER
102011754SKacheong.Poon@Sun.COM to->tcp_time_wait.value.ui64 +=
102112869SKacheong.Poon@Sun.COM from->tcp_time_wait;
102211754SKacheong.Poon@Sun.COM to->tcp_rput_time_wait.value.ui64 +=
102312869SKacheong.Poon@Sun.COM from->tcp_rput_time_wait;
102411754SKacheong.Poon@Sun.COM to->tcp_detach_time_wait.value.ui64 +=
102512869SKacheong.Poon@Sun.COM from->tcp_detach_time_wait;
102611754SKacheong.Poon@Sun.COM to->tcp_timeout_calls.value.ui64 +=
102712869SKacheong.Poon@Sun.COM from->tcp_timeout_calls;
102811754SKacheong.Poon@Sun.COM to->tcp_timeout_cached_alloc.value.ui64 +=
102912869SKacheong.Poon@Sun.COM from->tcp_timeout_cached_alloc;
103011754SKacheong.Poon@Sun.COM to->tcp_timeout_cancel_reqs.value.ui64 +=
103112869SKacheong.Poon@Sun.COM from->tcp_timeout_cancel_reqs;
103211754SKacheong.Poon@Sun.COM to->tcp_timeout_canceled.value.ui64 +=
103312869SKacheong.Poon@Sun.COM from->tcp_timeout_canceled;
103411754SKacheong.Poon@Sun.COM to->tcp_timermp_freed.value.ui64 +=
103512869SKacheong.Poon@Sun.COM from->tcp_timermp_freed;
103611754SKacheong.Poon@Sun.COM to->tcp_push_timer_cnt.value.ui64 +=
103712869SKacheong.Poon@Sun.COM from->tcp_push_timer_cnt;
103811754SKacheong.Poon@Sun.COM to->tcp_ack_timer_cnt.value.ui64 +=
103912869SKacheong.Poon@Sun.COM from->tcp_ack_timer_cnt;
104011754SKacheong.Poon@Sun.COM #endif
104111754SKacheong.Poon@Sun.COM }
1042