1721fffe3SKacheong Poon /*
2721fffe3SKacheong Poon * CDDL HEADER START
3721fffe3SKacheong Poon *
4721fffe3SKacheong Poon * The contents of this file are subject to the terms of the
5721fffe3SKacheong Poon * Common Development and Distribution License (the "License").
6721fffe3SKacheong Poon * You may not use this file except in compliance with the License.
7721fffe3SKacheong Poon *
8721fffe3SKacheong Poon * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9721fffe3SKacheong Poon * or http://www.opensolaris.org/os/licensing.
10721fffe3SKacheong Poon * See the License for the specific language governing permissions
11721fffe3SKacheong Poon * and limitations under the License.
12721fffe3SKacheong Poon *
13721fffe3SKacheong Poon * When distributing Covered Code, include this CDDL HEADER in each
14721fffe3SKacheong Poon * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15721fffe3SKacheong Poon * If applicable, add the following below this CDDL HEADER, with the
16721fffe3SKacheong Poon * fields enclosed by brackets "[]" replaced with your own identifying
17721fffe3SKacheong Poon * information: Portions Copyright [yyyy] [name of copyright owner]
18721fffe3SKacheong Poon *
19721fffe3SKacheong Poon * CDDL HEADER END
20721fffe3SKacheong Poon */
21721fffe3SKacheong Poon
22721fffe3SKacheong Poon /*
235dd46ab5SKacheong Poon * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*4a0bd071SBill Pijewski * Copyright (c) 2011, Joyent Inc. All rights reserved.
25721fffe3SKacheong Poon */
26721fffe3SKacheong Poon
27721fffe3SKacheong Poon #include <sys/types.h>
28721fffe3SKacheong Poon #include <sys/tihdr.h>
29721fffe3SKacheong Poon #include <sys/policy.h>
30721fffe3SKacheong Poon #include <sys/tsol/tnet.h>
31*4a0bd071SBill Pijewski #include <sys/kstat.h>
32721fffe3SKacheong Poon
33721fffe3SKacheong Poon #include <inet/common.h>
34721fffe3SKacheong Poon #include <inet/ip.h>
35721fffe3SKacheong Poon #include <inet/tcp.h>
36721fffe3SKacheong Poon #include <inet/tcp_impl.h>
37721fffe3SKacheong Poon #include <inet/tcp_stats.h>
38721fffe3SKacheong Poon #include <inet/kstatcom.h>
39721fffe3SKacheong Poon #include <inet/snmpcom.h>
40721fffe3SKacheong Poon
41ca3c8f41SDavid Höppner static int tcp_kstat_update(kstat_t *, int);
42ca3c8f41SDavid Höppner static int tcp_kstat2_update(kstat_t *, int);
43721fffe3SKacheong Poon static void tcp_sum_mib(tcp_stack_t *, mib2_tcp_t *);
44721fffe3SKacheong Poon
455dd46ab5SKacheong Poon static void tcp_add_mib(mib2_tcp_t *, mib2_tcp_t *);
465dd46ab5SKacheong Poon static void tcp_add_stats(tcp_stat_counter_t *, tcp_stat_t *);
47721fffe3SKacheong Poon static void tcp_clr_stats(tcp_stat_t *);
48721fffe3SKacheong Poon
49721fffe3SKacheong Poon tcp_g_stat_t tcp_g_statistics;
50721fffe3SKacheong Poon kstat_t *tcp_g_kstat;
51721fffe3SKacheong Poon
52721fffe3SKacheong Poon /* Translate TCP state to MIB2 TCP state. */
53721fffe3SKacheong Poon static int
tcp_snmp_state(tcp_t * tcp)54721fffe3SKacheong Poon tcp_snmp_state(tcp_t *tcp)
55721fffe3SKacheong Poon {
56721fffe3SKacheong Poon if (tcp == NULL)
57721fffe3SKacheong Poon return (0);
58721fffe3SKacheong Poon
59721fffe3SKacheong Poon switch (tcp->tcp_state) {
60721fffe3SKacheong Poon case TCPS_CLOSED:
61721fffe3SKacheong Poon case TCPS_IDLE: /* RFC1213 doesn't have analogue for IDLE & BOUND */
62721fffe3SKacheong Poon case TCPS_BOUND:
63721fffe3SKacheong Poon return (MIB2_TCP_closed);
64721fffe3SKacheong Poon case TCPS_LISTEN:
65721fffe3SKacheong Poon return (MIB2_TCP_listen);
66721fffe3SKacheong Poon case TCPS_SYN_SENT:
67721fffe3SKacheong Poon return (MIB2_TCP_synSent);
68721fffe3SKacheong Poon case TCPS_SYN_RCVD:
69721fffe3SKacheong Poon return (MIB2_TCP_synReceived);
70721fffe3SKacheong Poon case TCPS_ESTABLISHED:
71721fffe3SKacheong Poon return (MIB2_TCP_established);
72721fffe3SKacheong Poon case TCPS_CLOSE_WAIT:
73721fffe3SKacheong Poon return (MIB2_TCP_closeWait);
74721fffe3SKacheong Poon case TCPS_FIN_WAIT_1:
75721fffe3SKacheong Poon return (MIB2_TCP_finWait1);
76721fffe3SKacheong Poon case TCPS_CLOSING:
77721fffe3SKacheong Poon return (MIB2_TCP_closing);
78721fffe3SKacheong Poon case TCPS_LAST_ACK:
79721fffe3SKacheong Poon return (MIB2_TCP_lastAck);
80721fffe3SKacheong Poon case TCPS_FIN_WAIT_2:
81721fffe3SKacheong Poon return (MIB2_TCP_finWait2);
82721fffe3SKacheong Poon case TCPS_TIME_WAIT:
83721fffe3SKacheong Poon return (MIB2_TCP_timeWait);
84721fffe3SKacheong Poon default:
85721fffe3SKacheong Poon return (0);
86721fffe3SKacheong Poon }
87721fffe3SKacheong Poon }
88721fffe3SKacheong Poon
89721fffe3SKacheong Poon /*
90721fffe3SKacheong Poon * Return SNMP stuff in buffer in mpdata.
91721fffe3SKacheong Poon */
92721fffe3SKacheong Poon mblk_t *
tcp_snmp_get(queue_t * q,mblk_t * mpctl,boolean_t legacy_req)936f773e29SBaban Kenkre tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
94721fffe3SKacheong Poon {
95721fffe3SKacheong Poon mblk_t *mpdata;
96721fffe3SKacheong Poon mblk_t *mp_conn_ctl = NULL;
97721fffe3SKacheong Poon mblk_t *mp_conn_tail;
98721fffe3SKacheong Poon mblk_t *mp_attr_ctl = NULL;
99721fffe3SKacheong Poon mblk_t *mp_attr_tail;
100721fffe3SKacheong Poon mblk_t *mp6_conn_ctl = NULL;
101721fffe3SKacheong Poon mblk_t *mp6_conn_tail;
102721fffe3SKacheong Poon mblk_t *mp6_attr_ctl = NULL;
103721fffe3SKacheong Poon mblk_t *mp6_attr_tail;
104721fffe3SKacheong Poon struct opthdr *optp;
105721fffe3SKacheong Poon mib2_tcpConnEntry_t tce;
106721fffe3SKacheong Poon mib2_tcp6ConnEntry_t tce6;
107721fffe3SKacheong Poon mib2_transportMLPEntry_t mlp;
108721fffe3SKacheong Poon connf_t *connfp;
109721fffe3SKacheong Poon int i;
110721fffe3SKacheong Poon boolean_t ispriv;
111721fffe3SKacheong Poon zoneid_t zoneid;
112721fffe3SKacheong Poon int v4_conn_idx;
113721fffe3SKacheong Poon int v6_conn_idx;
114721fffe3SKacheong Poon conn_t *connp = Q_TO_CONN(q);
115721fffe3SKacheong Poon tcp_stack_t *tcps;
116721fffe3SKacheong Poon ip_stack_t *ipst;
117721fffe3SKacheong Poon mblk_t *mp2ctl;
118721fffe3SKacheong Poon mib2_tcp_t tcp_mib;
1196f773e29SBaban Kenkre size_t tcp_mib_size, tce_size, tce6_size;
120721fffe3SKacheong Poon
121721fffe3SKacheong Poon /*
122721fffe3SKacheong Poon * make a copy of the original message
123721fffe3SKacheong Poon */
124721fffe3SKacheong Poon mp2ctl = copymsg(mpctl);
125721fffe3SKacheong Poon
126721fffe3SKacheong Poon if (mpctl == NULL ||
127721fffe3SKacheong Poon (mpdata = mpctl->b_cont) == NULL ||
128721fffe3SKacheong Poon (mp_conn_ctl = copymsg(mpctl)) == NULL ||
129721fffe3SKacheong Poon (mp_attr_ctl = copymsg(mpctl)) == NULL ||
130721fffe3SKacheong Poon (mp6_conn_ctl = copymsg(mpctl)) == NULL ||
131721fffe3SKacheong Poon (mp6_attr_ctl = copymsg(mpctl)) == NULL) {
132721fffe3SKacheong Poon freemsg(mp_conn_ctl);
133721fffe3SKacheong Poon freemsg(mp_attr_ctl);
134721fffe3SKacheong Poon freemsg(mp6_conn_ctl);
135721fffe3SKacheong Poon freemsg(mp6_attr_ctl);
136721fffe3SKacheong Poon freemsg(mpctl);
137721fffe3SKacheong Poon freemsg(mp2ctl);
138721fffe3SKacheong Poon return (NULL);
139721fffe3SKacheong Poon }
140721fffe3SKacheong Poon
141721fffe3SKacheong Poon ipst = connp->conn_netstack->netstack_ip;
142721fffe3SKacheong Poon tcps = connp->conn_netstack->netstack_tcp;
143721fffe3SKacheong Poon
1446f773e29SBaban Kenkre if (legacy_req) {
1456f773e29SBaban Kenkre tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
1466f773e29SBaban Kenkre tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
1476f773e29SBaban Kenkre tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
1486f773e29SBaban Kenkre } else {
1496f773e29SBaban Kenkre tcp_mib_size = sizeof (mib2_tcp_t);
1506f773e29SBaban Kenkre tce_size = sizeof (mib2_tcpConnEntry_t);
1516f773e29SBaban Kenkre tce6_size = sizeof (mib2_tcp6ConnEntry_t);
1526f773e29SBaban Kenkre }
1536f773e29SBaban Kenkre
154721fffe3SKacheong Poon bzero(&tcp_mib, sizeof (tcp_mib));
155721fffe3SKacheong Poon
156721fffe3SKacheong Poon /* build table of connections -- need count in fixed part */
157721fffe3SKacheong Poon SET_MIB(tcp_mib.tcpRtoAlgorithm, 4); /* vanj */
158721fffe3SKacheong Poon SET_MIB(tcp_mib.tcpRtoMin, tcps->tcps_rexmit_interval_min);
159721fffe3SKacheong Poon SET_MIB(tcp_mib.tcpRtoMax, tcps->tcps_rexmit_interval_max);
160721fffe3SKacheong Poon SET_MIB(tcp_mib.tcpMaxConn, -1);
161721fffe3SKacheong Poon SET_MIB(tcp_mib.tcpCurrEstab, 0);
162721fffe3SKacheong Poon
163721fffe3SKacheong Poon ispriv =
164721fffe3SKacheong Poon secpolicy_ip_config((Q_TO_CONN(q))->conn_cred, B_TRUE) == 0;
165721fffe3SKacheong Poon zoneid = Q_TO_CONN(q)->conn_zoneid;
166721fffe3SKacheong Poon
167721fffe3SKacheong Poon v4_conn_idx = v6_conn_idx = 0;
168721fffe3SKacheong Poon mp_conn_tail = mp_attr_tail = mp6_conn_tail = mp6_attr_tail = NULL;
169721fffe3SKacheong Poon
170721fffe3SKacheong Poon for (i = 0; i < CONN_G_HASH_SIZE; i++) {
171721fffe3SKacheong Poon ipst = tcps->tcps_netstack->netstack_ip;
172721fffe3SKacheong Poon
173721fffe3SKacheong Poon connfp = &ipst->ips_ipcl_globalhash_fanout[i];
174721fffe3SKacheong Poon
175721fffe3SKacheong Poon connp = NULL;
176721fffe3SKacheong Poon
177721fffe3SKacheong Poon while ((connp =
178721fffe3SKacheong Poon ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
179721fffe3SKacheong Poon tcp_t *tcp;
180721fffe3SKacheong Poon boolean_t needattr;
181721fffe3SKacheong Poon
182721fffe3SKacheong Poon if (connp->conn_zoneid != zoneid)
183721fffe3SKacheong Poon continue; /* not in this zone */
184721fffe3SKacheong Poon
185721fffe3SKacheong Poon tcp = connp->conn_tcp;
186721fffe3SKacheong Poon TCPS_UPDATE_MIB(tcps, tcpHCInSegs, tcp->tcp_ibsegs);
187721fffe3SKacheong Poon tcp->tcp_ibsegs = 0;
188721fffe3SKacheong Poon TCPS_UPDATE_MIB(tcps, tcpHCOutSegs, tcp->tcp_obsegs);
189721fffe3SKacheong Poon tcp->tcp_obsegs = 0;
190721fffe3SKacheong Poon
191721fffe3SKacheong Poon tce6.tcp6ConnState = tce.tcpConnState =
192721fffe3SKacheong Poon tcp_snmp_state(tcp);
193721fffe3SKacheong Poon if (tce.tcpConnState == MIB2_TCP_established ||
194721fffe3SKacheong Poon tce.tcpConnState == MIB2_TCP_closeWait)
19547b75f87SKacheong Poon BUMP_MIB(&tcp_mib, tcpCurrEstab);
196721fffe3SKacheong Poon
197721fffe3SKacheong Poon needattr = B_FALSE;
198721fffe3SKacheong Poon bzero(&mlp, sizeof (mlp));
199721fffe3SKacheong Poon if (connp->conn_mlp_type != mlptSingle) {
200721fffe3SKacheong Poon if (connp->conn_mlp_type == mlptShared ||
201721fffe3SKacheong Poon connp->conn_mlp_type == mlptBoth)
202721fffe3SKacheong Poon mlp.tme_flags |= MIB2_TMEF_SHARED;
203721fffe3SKacheong Poon if (connp->conn_mlp_type == mlptPrivate ||
204721fffe3SKacheong Poon connp->conn_mlp_type == mlptBoth)
205721fffe3SKacheong Poon mlp.tme_flags |= MIB2_TMEF_PRIVATE;
206721fffe3SKacheong Poon needattr = B_TRUE;
207721fffe3SKacheong Poon }
208721fffe3SKacheong Poon if (connp->conn_anon_mlp) {
209721fffe3SKacheong Poon mlp.tme_flags |= MIB2_TMEF_ANONMLP;
210721fffe3SKacheong Poon needattr = B_TRUE;
211721fffe3SKacheong Poon }
212721fffe3SKacheong Poon switch (connp->conn_mac_mode) {
213721fffe3SKacheong Poon case CONN_MAC_DEFAULT:
214721fffe3SKacheong Poon break;
215721fffe3SKacheong Poon case CONN_MAC_AWARE:
216721fffe3SKacheong Poon mlp.tme_flags |= MIB2_TMEF_MACEXEMPT;
217721fffe3SKacheong Poon needattr = B_TRUE;
218721fffe3SKacheong Poon break;
219721fffe3SKacheong Poon case CONN_MAC_IMPLICIT:
220721fffe3SKacheong Poon mlp.tme_flags |= MIB2_TMEF_MACIMPLICIT;
221721fffe3SKacheong Poon needattr = B_TRUE;
222721fffe3SKacheong Poon break;
223721fffe3SKacheong Poon }
224721fffe3SKacheong Poon if (connp->conn_ixa->ixa_tsl != NULL) {
225721fffe3SKacheong Poon ts_label_t *tsl;
226721fffe3SKacheong Poon
227721fffe3SKacheong Poon tsl = connp->conn_ixa->ixa_tsl;
228721fffe3SKacheong Poon mlp.tme_flags |= MIB2_TMEF_IS_LABELED;
229721fffe3SKacheong Poon mlp.tme_doi = label2doi(tsl);
230721fffe3SKacheong Poon mlp.tme_label = *label2bslabel(tsl);
231721fffe3SKacheong Poon needattr = B_TRUE;
232721fffe3SKacheong Poon }
233721fffe3SKacheong Poon
234721fffe3SKacheong Poon /* Create a message to report on IPv6 entries */
235721fffe3SKacheong Poon if (connp->conn_ipversion == IPV6_VERSION) {
236721fffe3SKacheong Poon tce6.tcp6ConnLocalAddress = connp->conn_laddr_v6;
237721fffe3SKacheong Poon tce6.tcp6ConnRemAddress = connp->conn_faddr_v6;
238721fffe3SKacheong Poon tce6.tcp6ConnLocalPort = ntohs(connp->conn_lport);
239721fffe3SKacheong Poon tce6.tcp6ConnRemPort = ntohs(connp->conn_fport);
240721fffe3SKacheong Poon if (connp->conn_ixa->ixa_flags & IXAF_SCOPEID_SET) {
241721fffe3SKacheong Poon tce6.tcp6ConnIfIndex =
242721fffe3SKacheong Poon connp->conn_ixa->ixa_scopeid;
243721fffe3SKacheong Poon } else {
244721fffe3SKacheong Poon tce6.tcp6ConnIfIndex = connp->conn_bound_if;
245721fffe3SKacheong Poon }
246721fffe3SKacheong Poon /* Don't want just anybody seeing these... */
247721fffe3SKacheong Poon if (ispriv) {
248721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_snxt =
249721fffe3SKacheong Poon tcp->tcp_snxt;
250721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_suna =
251721fffe3SKacheong Poon tcp->tcp_suna;
252721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_rnxt =
253721fffe3SKacheong Poon tcp->tcp_rnxt;
254721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_rack =
255721fffe3SKacheong Poon tcp->tcp_rack;
256721fffe3SKacheong Poon } else {
257721fffe3SKacheong Poon /*
258721fffe3SKacheong Poon * Netstat, unfortunately, uses this to
259721fffe3SKacheong Poon * get send/receive queue sizes. How to fix?
260721fffe3SKacheong Poon * Why not compute the difference only?
261721fffe3SKacheong Poon */
262721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_snxt =
263721fffe3SKacheong Poon tcp->tcp_snxt - tcp->tcp_suna;
264721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_suna = 0;
265721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_rnxt =
266721fffe3SKacheong Poon tcp->tcp_rnxt - tcp->tcp_rack;
267721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_rack = 0;
268721fffe3SKacheong Poon }
269721fffe3SKacheong Poon
270721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_swnd = tcp->tcp_swnd;
271721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
272721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_rto = tcp->tcp_rto;
273721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_mss = tcp->tcp_mss;
274721fffe3SKacheong Poon tce6.tcp6ConnEntryInfo.ce_state = tcp->tcp_state;
275721fffe3SKacheong Poon
276721fffe3SKacheong Poon tce6.tcp6ConnCreationProcess =
277721fffe3SKacheong Poon (connp->conn_cpid < 0) ? MIB2_UNKNOWN_PROCESS :
278721fffe3SKacheong Poon connp->conn_cpid;
279721fffe3SKacheong Poon tce6.tcp6ConnCreationTime = connp->conn_open_time;
280721fffe3SKacheong Poon
281721fffe3SKacheong Poon (void) snmp_append_data2(mp6_conn_ctl->b_cont,
2826f773e29SBaban Kenkre &mp6_conn_tail, (char *)&tce6, tce6_size);
283721fffe3SKacheong Poon
284721fffe3SKacheong Poon mlp.tme_connidx = v6_conn_idx++;
285721fffe3SKacheong Poon if (needattr)
286721fffe3SKacheong Poon (void) snmp_append_data2(mp6_attr_ctl->b_cont,
287721fffe3SKacheong Poon &mp6_attr_tail, (char *)&mlp, sizeof (mlp));
288721fffe3SKacheong Poon }
289721fffe3SKacheong Poon /*
290721fffe3SKacheong Poon * Create an IPv4 table entry for IPv4 entries and also
291721fffe3SKacheong Poon * for IPv6 entries which are bound to in6addr_any
292721fffe3SKacheong Poon * but don't have IPV6_V6ONLY set.
293721fffe3SKacheong Poon * (i.e. anything an IPv4 peer could connect to)
294721fffe3SKacheong Poon */
295721fffe3SKacheong Poon if (connp->conn_ipversion == IPV4_VERSION ||
296721fffe3SKacheong Poon (tcp->tcp_state <= TCPS_LISTEN &&
297721fffe3SKacheong Poon !connp->conn_ipv6_v6only &&
298721fffe3SKacheong Poon IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6))) {
299721fffe3SKacheong Poon if (connp->conn_ipversion == IPV6_VERSION) {
300721fffe3SKacheong Poon tce.tcpConnRemAddress = INADDR_ANY;
301721fffe3SKacheong Poon tce.tcpConnLocalAddress = INADDR_ANY;
302721fffe3SKacheong Poon } else {
303721fffe3SKacheong Poon tce.tcpConnRemAddress =
304721fffe3SKacheong Poon connp->conn_faddr_v4;
305721fffe3SKacheong Poon tce.tcpConnLocalAddress =
306721fffe3SKacheong Poon connp->conn_laddr_v4;
307721fffe3SKacheong Poon }
308721fffe3SKacheong Poon tce.tcpConnLocalPort = ntohs(connp->conn_lport);
309721fffe3SKacheong Poon tce.tcpConnRemPort = ntohs(connp->conn_fport);
310721fffe3SKacheong Poon /* Don't want just anybody seeing these... */
311721fffe3SKacheong Poon if (ispriv) {
312721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_snxt =
313721fffe3SKacheong Poon tcp->tcp_snxt;
314721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_suna =
315721fffe3SKacheong Poon tcp->tcp_suna;
316721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_rnxt =
317721fffe3SKacheong Poon tcp->tcp_rnxt;
318721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_rack =
319721fffe3SKacheong Poon tcp->tcp_rack;
320721fffe3SKacheong Poon } else {
321721fffe3SKacheong Poon /*
322721fffe3SKacheong Poon * Netstat, unfortunately, uses this to
323721fffe3SKacheong Poon * get send/receive queue sizes. How
324721fffe3SKacheong Poon * to fix?
325721fffe3SKacheong Poon * Why not compute the difference only?
326721fffe3SKacheong Poon */
327721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_snxt =
328721fffe3SKacheong Poon tcp->tcp_snxt - tcp->tcp_suna;
329721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_suna = 0;
330721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_rnxt =
331721fffe3SKacheong Poon tcp->tcp_rnxt - tcp->tcp_rack;
332721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_rack = 0;
333721fffe3SKacheong Poon }
334721fffe3SKacheong Poon
335721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_swnd = tcp->tcp_swnd;
336721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_rwnd = tcp->tcp_rwnd;
337721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_rto = tcp->tcp_rto;
338721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_mss = tcp->tcp_mss;
339721fffe3SKacheong Poon tce.tcpConnEntryInfo.ce_state =
340721fffe3SKacheong Poon tcp->tcp_state;
341721fffe3SKacheong Poon
342721fffe3SKacheong Poon tce.tcpConnCreationProcess =
343721fffe3SKacheong Poon (connp->conn_cpid < 0) ?
344721fffe3SKacheong Poon MIB2_UNKNOWN_PROCESS :
345721fffe3SKacheong Poon connp->conn_cpid;
346721fffe3SKacheong Poon tce.tcpConnCreationTime = connp->conn_open_time;
347721fffe3SKacheong Poon
348721fffe3SKacheong Poon (void) snmp_append_data2(mp_conn_ctl->b_cont,
3496f773e29SBaban Kenkre &mp_conn_tail, (char *)&tce, tce_size);
350721fffe3SKacheong Poon
351721fffe3SKacheong Poon mlp.tme_connidx = v4_conn_idx++;
352721fffe3SKacheong Poon if (needattr)
353721fffe3SKacheong Poon (void) snmp_append_data2(
354721fffe3SKacheong Poon mp_attr_ctl->b_cont,
355721fffe3SKacheong Poon &mp_attr_tail, (char *)&mlp,
356721fffe3SKacheong Poon sizeof (mlp));
357721fffe3SKacheong Poon }
358721fffe3SKacheong Poon }
359721fffe3SKacheong Poon }
360721fffe3SKacheong Poon
36147b75f87SKacheong Poon tcp_sum_mib(tcps, &tcp_mib);
362721fffe3SKacheong Poon
3636f773e29SBaban Kenkre /* Fixed length structure for IPv4 and IPv6 counters */
3646f773e29SBaban Kenkre SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
3656f773e29SBaban Kenkre SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
3666f773e29SBaban Kenkre
36747b75f87SKacheong Poon /*
36847b75f87SKacheong Poon * Synchronize 32- and 64-bit counters. Note that tcpInSegs and
36947b75f87SKacheong Poon * tcpOutSegs are not updated anywhere in TCP. The new 64 bits
37047b75f87SKacheong Poon * counters are used. Hence the old counters' values in tcp_sc_mib
37147b75f87SKacheong Poon * are always 0.
37247b75f87SKacheong Poon */
373721fffe3SKacheong Poon SYNC32_MIB(&tcp_mib, tcpInSegs, tcpHCInSegs);
374721fffe3SKacheong Poon SYNC32_MIB(&tcp_mib, tcpOutSegs, tcpHCOutSegs);
375721fffe3SKacheong Poon
376721fffe3SKacheong Poon optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
377721fffe3SKacheong Poon optp->level = MIB2_TCP;
378721fffe3SKacheong Poon optp->name = 0;
3796f773e29SBaban Kenkre (void) snmp_append_data(mpdata, (char *)&tcp_mib, tcp_mib_size);
380721fffe3SKacheong Poon optp->len = msgdsize(mpdata);
381721fffe3SKacheong Poon qreply(q, mpctl);
382721fffe3SKacheong Poon
383721fffe3SKacheong Poon /* table of connections... */
384721fffe3SKacheong Poon optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
385721fffe3SKacheong Poon sizeof (struct T_optmgmt_ack)];
386721fffe3SKacheong Poon optp->level = MIB2_TCP;
387721fffe3SKacheong Poon optp->name = MIB2_TCP_CONN;
388721fffe3SKacheong Poon optp->len = msgdsize(mp_conn_ctl->b_cont);
389721fffe3SKacheong Poon qreply(q, mp_conn_ctl);
390721fffe3SKacheong Poon
391721fffe3SKacheong Poon /* table of MLP attributes... */
392721fffe3SKacheong Poon optp = (struct opthdr *)&mp_attr_ctl->b_rptr[
393721fffe3SKacheong Poon sizeof (struct T_optmgmt_ack)];
394721fffe3SKacheong Poon optp->level = MIB2_TCP;
395721fffe3SKacheong Poon optp->name = EXPER_XPORT_MLP;
396721fffe3SKacheong Poon optp->len = msgdsize(mp_attr_ctl->b_cont);
397721fffe3SKacheong Poon if (optp->len == 0)
398721fffe3SKacheong Poon freemsg(mp_attr_ctl);
399721fffe3SKacheong Poon else
400721fffe3SKacheong Poon qreply(q, mp_attr_ctl);
401721fffe3SKacheong Poon
402721fffe3SKacheong Poon /* table of IPv6 connections... */
403721fffe3SKacheong Poon optp = (struct opthdr *)&mp6_conn_ctl->b_rptr[
404721fffe3SKacheong Poon sizeof (struct T_optmgmt_ack)];
405721fffe3SKacheong Poon optp->level = MIB2_TCP6;
406721fffe3SKacheong Poon optp->name = MIB2_TCP6_CONN;
407721fffe3SKacheong Poon optp->len = msgdsize(mp6_conn_ctl->b_cont);
408721fffe3SKacheong Poon qreply(q, mp6_conn_ctl);
409721fffe3SKacheong Poon
410721fffe3SKacheong Poon /* table of IPv6 MLP attributes... */
411721fffe3SKacheong Poon optp = (struct opthdr *)&mp6_attr_ctl->b_rptr[
412721fffe3SKacheong Poon sizeof (struct T_optmgmt_ack)];
413721fffe3SKacheong Poon optp->level = MIB2_TCP6;
414721fffe3SKacheong Poon optp->name = EXPER_XPORT_MLP;
415721fffe3SKacheong Poon optp->len = msgdsize(mp6_attr_ctl->b_cont);
416721fffe3SKacheong Poon if (optp->len == 0)
417721fffe3SKacheong Poon freemsg(mp6_attr_ctl);
418721fffe3SKacheong Poon else
419721fffe3SKacheong Poon qreply(q, mp6_attr_ctl);
420721fffe3SKacheong Poon return (mp2ctl);
421721fffe3SKacheong Poon }
422721fffe3SKacheong Poon
423721fffe3SKacheong Poon /* Return 0 if invalid set request, 1 otherwise, including non-tcp requests */
424721fffe3SKacheong Poon /* ARGSUSED */
425721fffe3SKacheong Poon int
tcp_snmp_set(queue_t * q,int level,int name,uchar_t * ptr,int len)426721fffe3SKacheong Poon tcp_snmp_set(queue_t *q, int level, int name, uchar_t *ptr, int len)
427721fffe3SKacheong Poon {
428721fffe3SKacheong Poon mib2_tcpConnEntry_t *tce = (mib2_tcpConnEntry_t *)ptr;
429721fffe3SKacheong Poon
430721fffe3SKacheong Poon switch (level) {
431721fffe3SKacheong Poon case MIB2_TCP:
432721fffe3SKacheong Poon switch (name) {
433721fffe3SKacheong Poon case 13:
434721fffe3SKacheong Poon if (tce->tcpConnState != MIB2_TCP_deleteTCB)
435721fffe3SKacheong Poon return (0);
436721fffe3SKacheong Poon /* TODO: delete entry defined by tce */
437721fffe3SKacheong Poon return (1);
438721fffe3SKacheong Poon default:
439721fffe3SKacheong Poon return (0);
440721fffe3SKacheong Poon }
441721fffe3SKacheong Poon default:
442721fffe3SKacheong Poon return (1);
443721fffe3SKacheong Poon }
444721fffe3SKacheong Poon }
445721fffe3SKacheong Poon
446721fffe3SKacheong Poon /*
447721fffe3SKacheong Poon * TCP Kstats implementation
448721fffe3SKacheong Poon */
449721fffe3SKacheong Poon void *
tcp_kstat_init(netstackid_t stackid)450721fffe3SKacheong Poon tcp_kstat_init(netstackid_t stackid)
451721fffe3SKacheong Poon {
452721fffe3SKacheong Poon kstat_t *ksp;
453721fffe3SKacheong Poon
454721fffe3SKacheong Poon tcp_named_kstat_t template = {
455721fffe3SKacheong Poon { "rtoAlgorithm", KSTAT_DATA_INT32, 0 },
456721fffe3SKacheong Poon { "rtoMin", KSTAT_DATA_INT32, 0 },
457721fffe3SKacheong Poon { "rtoMax", KSTAT_DATA_INT32, 0 },
458721fffe3SKacheong Poon { "maxConn", KSTAT_DATA_INT32, 0 },
459721fffe3SKacheong Poon { "activeOpens", KSTAT_DATA_UINT32, 0 },
460721fffe3SKacheong Poon { "passiveOpens", KSTAT_DATA_UINT32, 0 },
461721fffe3SKacheong Poon { "attemptFails", KSTAT_DATA_UINT32, 0 },
462721fffe3SKacheong Poon { "estabResets", KSTAT_DATA_UINT32, 0 },
463721fffe3SKacheong Poon { "currEstab", KSTAT_DATA_UINT32, 0 },
464721fffe3SKacheong Poon { "inSegs", KSTAT_DATA_UINT64, 0 },
465721fffe3SKacheong Poon { "outSegs", KSTAT_DATA_UINT64, 0 },
466721fffe3SKacheong Poon { "retransSegs", KSTAT_DATA_UINT32, 0 },
467721fffe3SKacheong Poon { "connTableSize", KSTAT_DATA_INT32, 0 },
468721fffe3SKacheong Poon { "outRsts", KSTAT_DATA_UINT32, 0 },
469721fffe3SKacheong Poon { "outDataSegs", KSTAT_DATA_UINT32, 0 },
470721fffe3SKacheong Poon { "outDataBytes", KSTAT_DATA_UINT32, 0 },
471721fffe3SKacheong Poon { "retransBytes", KSTAT_DATA_UINT32, 0 },
472721fffe3SKacheong Poon { "outAck", KSTAT_DATA_UINT32, 0 },
473721fffe3SKacheong Poon { "outAckDelayed", KSTAT_DATA_UINT32, 0 },
474721fffe3SKacheong Poon { "outUrg", KSTAT_DATA_UINT32, 0 },
475721fffe3SKacheong Poon { "outWinUpdate", KSTAT_DATA_UINT32, 0 },
476721fffe3SKacheong Poon { "outWinProbe", KSTAT_DATA_UINT32, 0 },
477721fffe3SKacheong Poon { "outControl", KSTAT_DATA_UINT32, 0 },
478721fffe3SKacheong Poon { "outFastRetrans", KSTAT_DATA_UINT32, 0 },
479721fffe3SKacheong Poon { "inAckSegs", KSTAT_DATA_UINT32, 0 },
480721fffe3SKacheong Poon { "inAckBytes", KSTAT_DATA_UINT32, 0 },
481721fffe3SKacheong Poon { "inDupAck", KSTAT_DATA_UINT32, 0 },
482721fffe3SKacheong Poon { "inAckUnsent", KSTAT_DATA_UINT32, 0 },
483721fffe3SKacheong Poon { "inDataInorderSegs", KSTAT_DATA_UINT32, 0 },
484721fffe3SKacheong Poon { "inDataInorderBytes", KSTAT_DATA_UINT32, 0 },
485721fffe3SKacheong Poon { "inDataUnorderSegs", KSTAT_DATA_UINT32, 0 },
486721fffe3SKacheong Poon { "inDataUnorderBytes", KSTAT_DATA_UINT32, 0 },
487721fffe3SKacheong Poon { "inDataDupSegs", KSTAT_DATA_UINT32, 0 },
488721fffe3SKacheong Poon { "inDataDupBytes", KSTAT_DATA_UINT32, 0 },
489721fffe3SKacheong Poon { "inDataPartDupSegs", KSTAT_DATA_UINT32, 0 },
490721fffe3SKacheong Poon { "inDataPartDupBytes", KSTAT_DATA_UINT32, 0 },
491721fffe3SKacheong Poon { "inDataPastWinSegs", KSTAT_DATA_UINT32, 0 },
492721fffe3SKacheong Poon { "inDataPastWinBytes", KSTAT_DATA_UINT32, 0 },
493721fffe3SKacheong Poon { "inWinProbe", KSTAT_DATA_UINT32, 0 },
494721fffe3SKacheong Poon { "inWinUpdate", KSTAT_DATA_UINT32, 0 },
495721fffe3SKacheong Poon { "inClosed", KSTAT_DATA_UINT32, 0 },
496721fffe3SKacheong Poon { "rttUpdate", KSTAT_DATA_UINT32, 0 },
497721fffe3SKacheong Poon { "rttNoUpdate", KSTAT_DATA_UINT32, 0 },
498721fffe3SKacheong Poon { "timRetrans", KSTAT_DATA_UINT32, 0 },
499721fffe3SKacheong Poon { "timRetransDrop", KSTAT_DATA_UINT32, 0 },
500721fffe3SKacheong Poon { "timKeepalive", KSTAT_DATA_UINT32, 0 },
501721fffe3SKacheong Poon { "timKeepaliveProbe", KSTAT_DATA_UINT32, 0 },
502721fffe3SKacheong Poon { "timKeepaliveDrop", KSTAT_DATA_UINT32, 0 },
503721fffe3SKacheong Poon { "listenDrop", KSTAT_DATA_UINT32, 0 },
504721fffe3SKacheong Poon { "listenDropQ0", KSTAT_DATA_UINT32, 0 },
505721fffe3SKacheong Poon { "halfOpenDrop", KSTAT_DATA_UINT32, 0 },
506721fffe3SKacheong Poon { "outSackRetransSegs", KSTAT_DATA_UINT32, 0 },
507721fffe3SKacheong Poon { "connTableSize6", KSTAT_DATA_INT32, 0 }
508721fffe3SKacheong Poon };
509721fffe3SKacheong Poon
510*4a0bd071SBill Pijewski ksp = kstat_create_netstack(TCP_MOD_NAME, stackid, TCP_MOD_NAME, "mib2",
511721fffe3SKacheong Poon KSTAT_TYPE_NAMED, NUM_OF_FIELDS(tcp_named_kstat_t), 0, stackid);
512721fffe3SKacheong Poon
513721fffe3SKacheong Poon if (ksp == NULL)
514721fffe3SKacheong Poon return (NULL);
515721fffe3SKacheong Poon
516721fffe3SKacheong Poon template.rtoAlgorithm.value.ui32 = 4;
517721fffe3SKacheong Poon template.maxConn.value.i32 = -1;
518721fffe3SKacheong Poon
519721fffe3SKacheong Poon bcopy(&template, ksp->ks_data, sizeof (template));
520721fffe3SKacheong Poon ksp->ks_update = tcp_kstat_update;
521721fffe3SKacheong Poon ksp->ks_private = (void *)(uintptr_t)stackid;
522721fffe3SKacheong Poon
523*4a0bd071SBill Pijewski /*
524*4a0bd071SBill Pijewski * If this is an exclusive netstack for a local zone, the global zone
525*4a0bd071SBill Pijewski * should still be able to read the kstat.
526*4a0bd071SBill Pijewski */
527*4a0bd071SBill Pijewski if (stackid != GLOBAL_NETSTACKID)
528*4a0bd071SBill Pijewski kstat_zone_add(ksp, GLOBAL_ZONEID);
529*4a0bd071SBill Pijewski
530721fffe3SKacheong Poon kstat_install(ksp);
531721fffe3SKacheong Poon return (ksp);
532721fffe3SKacheong Poon }
533721fffe3SKacheong Poon
534721fffe3SKacheong Poon void
tcp_kstat_fini(netstackid_t stackid,kstat_t * ksp)535721fffe3SKacheong Poon tcp_kstat_fini(netstackid_t stackid, kstat_t *ksp)
536721fffe3SKacheong Poon {
537721fffe3SKacheong Poon if (ksp != NULL) {
538721fffe3SKacheong Poon ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
539721fffe3SKacheong Poon kstat_delete_netstack(ksp, stackid);
540721fffe3SKacheong Poon }
541721fffe3SKacheong Poon }
542721fffe3SKacheong Poon
543721fffe3SKacheong Poon static int
tcp_kstat_update(kstat_t * kp,int rw)544721fffe3SKacheong Poon tcp_kstat_update(kstat_t *kp, int rw)
545721fffe3SKacheong Poon {
546721fffe3SKacheong Poon tcp_named_kstat_t *tcpkp;
547721fffe3SKacheong Poon tcp_t *tcp;
548721fffe3SKacheong Poon connf_t *connfp;
549721fffe3SKacheong Poon conn_t *connp;
550721fffe3SKacheong Poon int i;
551721fffe3SKacheong Poon netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private;
552721fffe3SKacheong Poon netstack_t *ns;
553721fffe3SKacheong Poon tcp_stack_t *tcps;
554721fffe3SKacheong Poon ip_stack_t *ipst;
555721fffe3SKacheong Poon mib2_tcp_t tcp_mib;
556721fffe3SKacheong Poon
557721fffe3SKacheong Poon if (rw == KSTAT_WRITE)
558721fffe3SKacheong Poon return (EACCES);
559721fffe3SKacheong Poon
560721fffe3SKacheong Poon ns = netstack_find_by_stackid(stackid);
561721fffe3SKacheong Poon if (ns == NULL)
562721fffe3SKacheong Poon return (-1);
563721fffe3SKacheong Poon tcps = ns->netstack_tcp;
564721fffe3SKacheong Poon if (tcps == NULL) {
565721fffe3SKacheong Poon netstack_rele(ns);
566721fffe3SKacheong Poon return (-1);
567721fffe3SKacheong Poon }
568721fffe3SKacheong Poon
569721fffe3SKacheong Poon tcpkp = (tcp_named_kstat_t *)kp->ks_data;
570721fffe3SKacheong Poon
571721fffe3SKacheong Poon tcpkp->currEstab.value.ui32 = 0;
572721fffe3SKacheong Poon tcpkp->rtoMin.value.ui32 = tcps->tcps_rexmit_interval_min;
573721fffe3SKacheong Poon tcpkp->rtoMax.value.ui32 = tcps->tcps_rexmit_interval_max;
574721fffe3SKacheong Poon
575721fffe3SKacheong Poon ipst = ns->netstack_ip;
576721fffe3SKacheong Poon
577721fffe3SKacheong Poon for (i = 0; i < CONN_G_HASH_SIZE; i++) {
578721fffe3SKacheong Poon connfp = &ipst->ips_ipcl_globalhash_fanout[i];
579721fffe3SKacheong Poon connp = NULL;
580721fffe3SKacheong Poon while ((connp =
581721fffe3SKacheong Poon ipcl_get_next_conn(connfp, connp, IPCL_TCPCONN)) != NULL) {
582721fffe3SKacheong Poon tcp = connp->conn_tcp;
583721fffe3SKacheong Poon switch (tcp_snmp_state(tcp)) {
584721fffe3SKacheong Poon case MIB2_TCP_established:
585721fffe3SKacheong Poon case MIB2_TCP_closeWait:
586721fffe3SKacheong Poon tcpkp->currEstab.value.ui32++;
587721fffe3SKacheong Poon break;
588721fffe3SKacheong Poon }
589721fffe3SKacheong Poon }
590721fffe3SKacheong Poon }
591721fffe3SKacheong Poon bzero(&tcp_mib, sizeof (tcp_mib));
592721fffe3SKacheong Poon tcp_sum_mib(tcps, &tcp_mib);
593721fffe3SKacheong Poon
5946f773e29SBaban Kenkre /* Fixed length structure for IPv4 and IPv6 counters */
5956f773e29SBaban Kenkre SET_MIB(tcp_mib.tcpConnTableSize, sizeof (mib2_tcpConnEntry_t));
5966f773e29SBaban Kenkre SET_MIB(tcp_mib.tcp6ConnTableSize, sizeof (mib2_tcp6ConnEntry_t));
5976f773e29SBaban Kenkre
598721fffe3SKacheong Poon tcpkp->activeOpens.value.ui32 = tcp_mib.tcpActiveOpens;
599721fffe3SKacheong Poon tcpkp->passiveOpens.value.ui32 = tcp_mib.tcpPassiveOpens;
600721fffe3SKacheong Poon tcpkp->attemptFails.value.ui32 = tcp_mib.tcpAttemptFails;
601721fffe3SKacheong Poon tcpkp->estabResets.value.ui32 = tcp_mib.tcpEstabResets;
602721fffe3SKacheong Poon tcpkp->inSegs.value.ui64 = tcp_mib.tcpHCInSegs;
603721fffe3SKacheong Poon tcpkp->outSegs.value.ui64 = tcp_mib.tcpHCOutSegs;
604721fffe3SKacheong Poon tcpkp->retransSegs.value.ui32 = tcp_mib.tcpRetransSegs;
605721fffe3SKacheong Poon tcpkp->connTableSize.value.i32 = tcp_mib.tcpConnTableSize;
606721fffe3SKacheong Poon tcpkp->outRsts.value.ui32 = tcp_mib.tcpOutRsts;
607721fffe3SKacheong Poon tcpkp->outDataSegs.value.ui32 = tcp_mib.tcpOutDataSegs;
608721fffe3SKacheong Poon tcpkp->outDataBytes.value.ui32 = tcp_mib.tcpOutDataBytes;
609721fffe3SKacheong Poon tcpkp->retransBytes.value.ui32 = tcp_mib.tcpRetransBytes;
610721fffe3SKacheong Poon tcpkp->outAck.value.ui32 = tcp_mib.tcpOutAck;
611721fffe3SKacheong Poon tcpkp->outAckDelayed.value.ui32 = tcp_mib.tcpOutAckDelayed;
612721fffe3SKacheong Poon tcpkp->outUrg.value.ui32 = tcp_mib.tcpOutUrg;
613721fffe3SKacheong Poon tcpkp->outWinUpdate.value.ui32 = tcp_mib.tcpOutWinUpdate;
614721fffe3SKacheong Poon tcpkp->outWinProbe.value.ui32 = tcp_mib.tcpOutWinProbe;
615721fffe3SKacheong Poon tcpkp->outControl.value.ui32 = tcp_mib.tcpOutControl;
616721fffe3SKacheong Poon tcpkp->outFastRetrans.value.ui32 = tcp_mib.tcpOutFastRetrans;
617721fffe3SKacheong Poon tcpkp->inAckSegs.value.ui32 = tcp_mib.tcpInAckSegs;
618721fffe3SKacheong Poon tcpkp->inAckBytes.value.ui32 = tcp_mib.tcpInAckBytes;
619721fffe3SKacheong Poon tcpkp->inDupAck.value.ui32 = tcp_mib.tcpInDupAck;
620721fffe3SKacheong Poon tcpkp->inAckUnsent.value.ui32 = tcp_mib.tcpInAckUnsent;
621721fffe3SKacheong Poon tcpkp->inDataInorderSegs.value.ui32 = tcp_mib.tcpInDataInorderSegs;
622721fffe3SKacheong Poon tcpkp->inDataInorderBytes.value.ui32 = tcp_mib.tcpInDataInorderBytes;
623721fffe3SKacheong Poon tcpkp->inDataUnorderSegs.value.ui32 = tcp_mib.tcpInDataUnorderSegs;
624721fffe3SKacheong Poon tcpkp->inDataUnorderBytes.value.ui32 = tcp_mib.tcpInDataUnorderBytes;
625721fffe3SKacheong Poon tcpkp->inDataDupSegs.value.ui32 = tcp_mib.tcpInDataDupSegs;
626721fffe3SKacheong Poon tcpkp->inDataDupBytes.value.ui32 = tcp_mib.tcpInDataDupBytes;
627721fffe3SKacheong Poon tcpkp->inDataPartDupSegs.value.ui32 = tcp_mib.tcpInDataPartDupSegs;
628721fffe3SKacheong Poon tcpkp->inDataPartDupBytes.value.ui32 = tcp_mib.tcpInDataPartDupBytes;
629721fffe3SKacheong Poon tcpkp->inDataPastWinSegs.value.ui32 = tcp_mib.tcpInDataPastWinSegs;
630721fffe3SKacheong Poon tcpkp->inDataPastWinBytes.value.ui32 = tcp_mib.tcpInDataPastWinBytes;
631721fffe3SKacheong Poon tcpkp->inWinProbe.value.ui32 = tcp_mib.tcpInWinProbe;
632721fffe3SKacheong Poon tcpkp->inWinUpdate.value.ui32 = tcp_mib.tcpInWinUpdate;
633721fffe3SKacheong Poon tcpkp->inClosed.value.ui32 = tcp_mib.tcpInClosed;
634721fffe3SKacheong Poon tcpkp->rttNoUpdate.value.ui32 = tcp_mib.tcpRttNoUpdate;
635721fffe3SKacheong Poon tcpkp->rttUpdate.value.ui32 = tcp_mib.tcpRttUpdate;
636721fffe3SKacheong Poon tcpkp->timRetrans.value.ui32 = tcp_mib.tcpTimRetrans;
637721fffe3SKacheong Poon tcpkp->timRetransDrop.value.ui32 = tcp_mib.tcpTimRetransDrop;
638721fffe3SKacheong Poon tcpkp->timKeepalive.value.ui32 = tcp_mib.tcpTimKeepalive;
639721fffe3SKacheong Poon tcpkp->timKeepaliveProbe.value.ui32 = tcp_mib.tcpTimKeepaliveProbe;
640721fffe3SKacheong Poon tcpkp->timKeepaliveDrop.value.ui32 = tcp_mib.tcpTimKeepaliveDrop;
641721fffe3SKacheong Poon tcpkp->listenDrop.value.ui32 = tcp_mib.tcpListenDrop;
642721fffe3SKacheong Poon tcpkp->listenDropQ0.value.ui32 = tcp_mib.tcpListenDropQ0;
643721fffe3SKacheong Poon tcpkp->halfOpenDrop.value.ui32 = tcp_mib.tcpHalfOpenDrop;
644721fffe3SKacheong Poon tcpkp->outSackRetransSegs.value.ui32 = tcp_mib.tcpOutSackRetransSegs;
645721fffe3SKacheong Poon tcpkp->connTableSize6.value.i32 = tcp_mib.tcp6ConnTableSize;
646721fffe3SKacheong Poon
647721fffe3SKacheong Poon netstack_rele(ns);
648721fffe3SKacheong Poon return (0);
649721fffe3SKacheong Poon }
650721fffe3SKacheong Poon
651721fffe3SKacheong Poon /*
652721fffe3SKacheong Poon * kstats related to squeues i.e. not per IP instance
653721fffe3SKacheong Poon */
654721fffe3SKacheong Poon void *
tcp_g_kstat_init(tcp_g_stat_t * tcp_g_statp)655721fffe3SKacheong Poon tcp_g_kstat_init(tcp_g_stat_t *tcp_g_statp)
656721fffe3SKacheong Poon {
657721fffe3SKacheong Poon kstat_t *ksp;
658721fffe3SKacheong Poon
659721fffe3SKacheong Poon tcp_g_stat_t template = {
660721fffe3SKacheong Poon { "tcp_timermp_alloced", KSTAT_DATA_UINT64 },
661721fffe3SKacheong Poon { "tcp_timermp_allocfail", KSTAT_DATA_UINT64 },
662721fffe3SKacheong Poon { "tcp_timermp_allocdblfail", KSTAT_DATA_UINT64 },
663721fffe3SKacheong Poon { "tcp_freelist_cleanup", KSTAT_DATA_UINT64 },
664721fffe3SKacheong Poon };
665721fffe3SKacheong Poon
666721fffe3SKacheong Poon ksp = kstat_create(TCP_MOD_NAME, 0, "tcpstat_g", "net",
667721fffe3SKacheong Poon KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t),
668721fffe3SKacheong Poon KSTAT_FLAG_VIRTUAL);
669721fffe3SKacheong Poon
670721fffe3SKacheong Poon if (ksp == NULL)
671721fffe3SKacheong Poon return (NULL);
672721fffe3SKacheong Poon
673721fffe3SKacheong Poon bcopy(&template, tcp_g_statp, sizeof (template));
674721fffe3SKacheong Poon ksp->ks_data = (void *)tcp_g_statp;
675721fffe3SKacheong Poon
676721fffe3SKacheong Poon kstat_install(ksp);
677721fffe3SKacheong Poon return (ksp);
678721fffe3SKacheong Poon }
679721fffe3SKacheong Poon
680721fffe3SKacheong Poon void
tcp_g_kstat_fini(kstat_t * ksp)681721fffe3SKacheong Poon tcp_g_kstat_fini(kstat_t *ksp)
682721fffe3SKacheong Poon {
683721fffe3SKacheong Poon if (ksp != NULL) {
684721fffe3SKacheong Poon kstat_delete(ksp);
685721fffe3SKacheong Poon }
686721fffe3SKacheong Poon }
687721fffe3SKacheong Poon
688721fffe3SKacheong Poon void *
tcp_kstat2_init(netstackid_t stackid)689721fffe3SKacheong Poon tcp_kstat2_init(netstackid_t stackid)
690721fffe3SKacheong Poon {
691721fffe3SKacheong Poon kstat_t *ksp;
692721fffe3SKacheong Poon
693721fffe3SKacheong Poon tcp_stat_t template = {
694721fffe3SKacheong Poon { "tcp_time_wait_syn_success", KSTAT_DATA_UINT64, 0 },
695721fffe3SKacheong Poon { "tcp_clean_death_nondetached", KSTAT_DATA_UINT64, 0 },
696721fffe3SKacheong Poon { "tcp_eager_blowoff_q", KSTAT_DATA_UINT64, 0 },
697721fffe3SKacheong Poon { "tcp_eager_blowoff_q0", KSTAT_DATA_UINT64, 0 },
698721fffe3SKacheong Poon { "tcp_no_listener", KSTAT_DATA_UINT64, 0 },
699721fffe3SKacheong Poon { "tcp_listendrop", KSTAT_DATA_UINT64, 0 },
700721fffe3SKacheong Poon { "tcp_listendropq0", KSTAT_DATA_UINT64, 0 },
701721fffe3SKacheong Poon { "tcp_wsrv_called", KSTAT_DATA_UINT64, 0 },
702721fffe3SKacheong Poon { "tcp_flwctl_on", KSTAT_DATA_UINT64, 0 },
703721fffe3SKacheong Poon { "tcp_timer_fire_early", KSTAT_DATA_UINT64, 0 },
704721fffe3SKacheong Poon { "tcp_timer_fire_miss", KSTAT_DATA_UINT64, 0 },
705721fffe3SKacheong Poon { "tcp_zcopy_on", KSTAT_DATA_UINT64, 0 },
706721fffe3SKacheong Poon { "tcp_zcopy_off", KSTAT_DATA_UINT64, 0 },
707721fffe3SKacheong Poon { "tcp_zcopy_backoff", KSTAT_DATA_UINT64, 0 },
708721fffe3SKacheong Poon { "tcp_fusion_flowctl", KSTAT_DATA_UINT64, 0 },
709721fffe3SKacheong Poon { "tcp_fusion_backenabled", KSTAT_DATA_UINT64, 0 },
710721fffe3SKacheong Poon { "tcp_fusion_urg", KSTAT_DATA_UINT64, 0 },
711721fffe3SKacheong Poon { "tcp_fusion_putnext", KSTAT_DATA_UINT64, 0 },
712721fffe3SKacheong Poon { "tcp_fusion_unfusable", KSTAT_DATA_UINT64, 0 },
713721fffe3SKacheong Poon { "tcp_fusion_aborted", KSTAT_DATA_UINT64, 0 },
714721fffe3SKacheong Poon { "tcp_fusion_unqualified", KSTAT_DATA_UINT64, 0 },
715721fffe3SKacheong Poon { "tcp_fusion_rrw_busy", KSTAT_DATA_UINT64, 0 },
716721fffe3SKacheong Poon { "tcp_fusion_rrw_msgcnt", KSTAT_DATA_UINT64, 0 },
717721fffe3SKacheong Poon { "tcp_fusion_rrw_plugged", KSTAT_DATA_UINT64, 0 },
718721fffe3SKacheong Poon { "tcp_in_ack_unsent_drop", KSTAT_DATA_UINT64, 0 },
719721fffe3SKacheong Poon { "tcp_sock_fallback", KSTAT_DATA_UINT64, 0 },
720721fffe3SKacheong Poon { "tcp_lso_enabled", KSTAT_DATA_UINT64, 0 },
721721fffe3SKacheong Poon { "tcp_lso_disabled", KSTAT_DATA_UINT64, 0 },
722721fffe3SKacheong Poon { "tcp_lso_times", KSTAT_DATA_UINT64, 0 },
723721fffe3SKacheong Poon { "tcp_lso_pkt_out", KSTAT_DATA_UINT64, 0 },
724721fffe3SKacheong Poon { "tcp_listen_cnt_drop", KSTAT_DATA_UINT64, 0 },
725721fffe3SKacheong Poon { "tcp_listen_mem_drop", KSTAT_DATA_UINT64, 0 },
726721fffe3SKacheong Poon { "tcp_zwin_mem_drop", KSTAT_DATA_UINT64, 0 },
727721fffe3SKacheong Poon { "tcp_zwin_ack_syn", KSTAT_DATA_UINT64, 0 },
728721fffe3SKacheong Poon { "tcp_rst_unsent", KSTAT_DATA_UINT64, 0 },
729721fffe3SKacheong Poon { "tcp_reclaim_cnt", KSTAT_DATA_UINT64, 0 },
730721fffe3SKacheong Poon { "tcp_reass_timeout", KSTAT_DATA_UINT64, 0 },
731721fffe3SKacheong Poon #ifdef TCP_DEBUG_COUNTER
732721fffe3SKacheong Poon { "tcp_time_wait", KSTAT_DATA_UINT64, 0 },
733721fffe3SKacheong Poon { "tcp_rput_time_wait", KSTAT_DATA_UINT64, 0 },
734721fffe3SKacheong Poon { "tcp_detach_time_wait", KSTAT_DATA_UINT64, 0 },
735721fffe3SKacheong Poon { "tcp_timeout_calls", KSTAT_DATA_UINT64, 0 },
736721fffe3SKacheong Poon { "tcp_timeout_cached_alloc", KSTAT_DATA_UINT64, 0 },
737721fffe3SKacheong Poon { "tcp_timeout_cancel_reqs", KSTAT_DATA_UINT64, 0 },
738721fffe3SKacheong Poon { "tcp_timeout_canceled", KSTAT_DATA_UINT64, 0 },
739721fffe3SKacheong Poon { "tcp_timermp_freed", KSTAT_DATA_UINT64, 0 },
740721fffe3SKacheong Poon { "tcp_push_timer_cnt", KSTAT_DATA_UINT64, 0 },
741721fffe3SKacheong Poon { "tcp_ack_timer_cnt", KSTAT_DATA_UINT64, 0 },
742721fffe3SKacheong Poon #endif
743721fffe3SKacheong Poon };
744721fffe3SKacheong Poon
745*4a0bd071SBill Pijewski ksp = kstat_create_netstack(TCP_MOD_NAME, stackid, "tcpstat", "net",
746721fffe3SKacheong Poon KSTAT_TYPE_NAMED, sizeof (template) / sizeof (kstat_named_t), 0,
747721fffe3SKacheong Poon stackid);
748721fffe3SKacheong Poon
749721fffe3SKacheong Poon if (ksp == NULL)
750721fffe3SKacheong Poon return (NULL);
751721fffe3SKacheong Poon
752721fffe3SKacheong Poon bcopy(&template, ksp->ks_data, sizeof (template));
753721fffe3SKacheong Poon ksp->ks_private = (void *)(uintptr_t)stackid;
754721fffe3SKacheong Poon ksp->ks_update = tcp_kstat2_update;
755721fffe3SKacheong Poon
756*4a0bd071SBill Pijewski /*
757*4a0bd071SBill Pijewski * If this is an exclusive netstack for a local zone, the global zone
758*4a0bd071SBill Pijewski * should still be able to read the kstat.
759*4a0bd071SBill Pijewski */
760*4a0bd071SBill Pijewski if (stackid != GLOBAL_NETSTACKID)
761*4a0bd071SBill Pijewski kstat_zone_add(ksp, GLOBAL_ZONEID);
762*4a0bd071SBill Pijewski
763721fffe3SKacheong Poon kstat_install(ksp);
764721fffe3SKacheong Poon return (ksp);
765721fffe3SKacheong Poon }
766721fffe3SKacheong Poon
767721fffe3SKacheong Poon void
tcp_kstat2_fini(netstackid_t stackid,kstat_t * ksp)768721fffe3SKacheong Poon tcp_kstat2_fini(netstackid_t stackid, kstat_t *ksp)
769721fffe3SKacheong Poon {
770721fffe3SKacheong Poon if (ksp != NULL) {
771721fffe3SKacheong Poon ASSERT(stackid == (netstackid_t)(uintptr_t)ksp->ks_private);
772721fffe3SKacheong Poon kstat_delete_netstack(ksp, stackid);
773721fffe3SKacheong Poon }
774721fffe3SKacheong Poon }
775721fffe3SKacheong Poon
776721fffe3SKacheong Poon /*
777721fffe3SKacheong Poon * Sum up all per CPU tcp_stat_t kstat counters.
778721fffe3SKacheong Poon */
779721fffe3SKacheong Poon static int
tcp_kstat2_update(kstat_t * kp,int rw)780721fffe3SKacheong Poon tcp_kstat2_update(kstat_t *kp, int rw)
781721fffe3SKacheong Poon {
782721fffe3SKacheong Poon netstackid_t stackid = (netstackid_t)(uintptr_t)kp->ks_private;
783721fffe3SKacheong Poon netstack_t *ns;
784721fffe3SKacheong Poon tcp_stack_t *tcps;
785721fffe3SKacheong Poon tcp_stat_t *stats;
786721fffe3SKacheong Poon int i;
787721fffe3SKacheong Poon int cnt;
788721fffe3SKacheong Poon
789721fffe3SKacheong Poon if (rw == KSTAT_WRITE)
790721fffe3SKacheong Poon return (EACCES);
791721fffe3SKacheong Poon
792721fffe3SKacheong Poon ns = netstack_find_by_stackid(stackid);
793721fffe3SKacheong Poon if (ns == NULL)
794721fffe3SKacheong Poon return (-1);
795721fffe3SKacheong Poon tcps = ns->netstack_tcp;
796721fffe3SKacheong Poon if (tcps == NULL) {
797721fffe3SKacheong Poon netstack_rele(ns);
798721fffe3SKacheong Poon return (-1);
799721fffe3SKacheong Poon }
800721fffe3SKacheong Poon
801721fffe3SKacheong Poon stats = (tcp_stat_t *)kp->ks_data;
802721fffe3SKacheong Poon tcp_clr_stats(stats);
803721fffe3SKacheong Poon
804721fffe3SKacheong Poon /*
805721fffe3SKacheong Poon * tcps_sc_cnt may change in the middle of the loop. It is better
806721fffe3SKacheong Poon * to get its value first.
807721fffe3SKacheong Poon */
808721fffe3SKacheong Poon cnt = tcps->tcps_sc_cnt;
809721fffe3SKacheong Poon for (i = 0; i < cnt; i++)
8105dd46ab5SKacheong Poon tcp_add_stats(&tcps->tcps_sc[i]->tcp_sc_stats, stats);
811721fffe3SKacheong Poon
812721fffe3SKacheong Poon netstack_rele(ns);
813721fffe3SKacheong Poon return (0);
814721fffe3SKacheong Poon }
815721fffe3SKacheong Poon
816721fffe3SKacheong Poon /*
8175dd46ab5SKacheong Poon * To add stats from one mib2_tcp_t to another. Static fields are not added.
818721fffe3SKacheong Poon * The caller should set them up propertly.
819721fffe3SKacheong Poon */
820ca3c8f41SDavid Höppner static void
tcp_add_mib(mib2_tcp_t * from,mib2_tcp_t * to)8215dd46ab5SKacheong Poon tcp_add_mib(mib2_tcp_t *from, mib2_tcp_t *to)
822721fffe3SKacheong Poon {
823721fffe3SKacheong Poon to->tcpActiveOpens += from->tcpActiveOpens;
824721fffe3SKacheong Poon to->tcpPassiveOpens += from->tcpPassiveOpens;
825721fffe3SKacheong Poon to->tcpAttemptFails += from->tcpAttemptFails;
826721fffe3SKacheong Poon to->tcpEstabResets += from->tcpEstabResets;
827721fffe3SKacheong Poon to->tcpInSegs += from->tcpInSegs;
828721fffe3SKacheong Poon to->tcpOutSegs += from->tcpOutSegs;
829721fffe3SKacheong Poon to->tcpRetransSegs += from->tcpRetransSegs;
830721fffe3SKacheong Poon to->tcpOutRsts += from->tcpOutRsts;
831721fffe3SKacheong Poon
832721fffe3SKacheong Poon to->tcpOutDataSegs += from->tcpOutDataSegs;
833721fffe3SKacheong Poon to->tcpOutDataBytes += from->tcpOutDataBytes;
834721fffe3SKacheong Poon to->tcpRetransBytes += from->tcpRetransBytes;
835721fffe3SKacheong Poon to->tcpOutAck += from->tcpOutAck;
836721fffe3SKacheong Poon to->tcpOutAckDelayed += from->tcpOutAckDelayed;
837721fffe3SKacheong Poon to->tcpOutUrg += from->tcpOutUrg;
838721fffe3SKacheong Poon to->tcpOutWinUpdate += from->tcpOutWinUpdate;
839721fffe3SKacheong Poon to->tcpOutWinProbe += from->tcpOutWinProbe;
840721fffe3SKacheong Poon to->tcpOutControl += from->tcpOutControl;
841721fffe3SKacheong Poon to->tcpOutFastRetrans += from->tcpOutFastRetrans;
842721fffe3SKacheong Poon
843721fffe3SKacheong Poon to->tcpInAckBytes += from->tcpInAckBytes;
844721fffe3SKacheong Poon to->tcpInDupAck += from->tcpInDupAck;
845721fffe3SKacheong Poon to->tcpInAckUnsent += from->tcpInAckUnsent;
846721fffe3SKacheong Poon to->tcpInDataInorderSegs += from->tcpInDataInorderSegs;
847721fffe3SKacheong Poon to->tcpInDataInorderBytes += from->tcpInDataInorderBytes;
848721fffe3SKacheong Poon to->tcpInDataUnorderSegs += from->tcpInDataUnorderSegs;
849721fffe3SKacheong Poon to->tcpInDataUnorderBytes += from->tcpInDataUnorderBytes;
850721fffe3SKacheong Poon to->tcpInDataDupSegs += from->tcpInDataDupSegs;
851721fffe3SKacheong Poon to->tcpInDataDupBytes += from->tcpInDataDupBytes;
852721fffe3SKacheong Poon to->tcpInDataPartDupSegs += from->tcpInDataPartDupSegs;
853721fffe3SKacheong Poon to->tcpInDataPartDupBytes += from->tcpInDataPartDupBytes;
854721fffe3SKacheong Poon to->tcpInDataPastWinSegs += from->tcpInDataPastWinSegs;
855721fffe3SKacheong Poon to->tcpInDataPastWinBytes += from->tcpInDataPastWinBytes;
856721fffe3SKacheong Poon to->tcpInWinProbe += from->tcpInWinProbe;
857721fffe3SKacheong Poon to->tcpInWinUpdate += from->tcpInWinUpdate;
858721fffe3SKacheong Poon to->tcpInClosed += from->tcpInClosed;
859721fffe3SKacheong Poon
860721fffe3SKacheong Poon to->tcpRttNoUpdate += from->tcpRttNoUpdate;
861721fffe3SKacheong Poon to->tcpRttUpdate += from->tcpRttUpdate;
862721fffe3SKacheong Poon to->tcpTimRetrans += from->tcpTimRetrans;
863721fffe3SKacheong Poon to->tcpTimRetransDrop += from->tcpTimRetransDrop;
864721fffe3SKacheong Poon to->tcpTimKeepalive += from->tcpTimKeepalive;
865721fffe3SKacheong Poon to->tcpTimKeepaliveProbe += from->tcpTimKeepaliveProbe;
866721fffe3SKacheong Poon to->tcpTimKeepaliveDrop += from->tcpTimKeepaliveDrop;
867721fffe3SKacheong Poon to->tcpListenDrop += from->tcpListenDrop;
868721fffe3SKacheong Poon to->tcpListenDropQ0 += from->tcpListenDropQ0;
869721fffe3SKacheong Poon to->tcpHalfOpenDrop += from->tcpHalfOpenDrop;
870721fffe3SKacheong Poon to->tcpOutSackRetransSegs += from->tcpOutSackRetransSegs;
871721fffe3SKacheong Poon to->tcpHCInSegs += from->tcpHCInSegs;
872721fffe3SKacheong Poon to->tcpHCOutSegs += from->tcpHCOutSegs;
873721fffe3SKacheong Poon }
874721fffe3SKacheong Poon
875721fffe3SKacheong Poon /*
876721fffe3SKacheong Poon * To sum up all MIB2 stats for a tcp_stack_t from all per CPU stats. The
877721fffe3SKacheong Poon * caller should initialize the target mib2_tcp_t properly as this function
878721fffe3SKacheong Poon * just adds up all the per CPU stats.
879721fffe3SKacheong Poon */
880721fffe3SKacheong Poon static void
tcp_sum_mib(tcp_stack_t * tcps,mib2_tcp_t * tcp_mib)881721fffe3SKacheong Poon tcp_sum_mib(tcp_stack_t *tcps, mib2_tcp_t *tcp_mib)
882721fffe3SKacheong Poon {
883721fffe3SKacheong Poon int i;
884721fffe3SKacheong Poon int cnt;
885721fffe3SKacheong Poon
886721fffe3SKacheong Poon /*
887721fffe3SKacheong Poon * tcps_sc_cnt may change in the middle of the loop. It is better
888721fffe3SKacheong Poon * to get its value first.
889721fffe3SKacheong Poon */
890721fffe3SKacheong Poon cnt = tcps->tcps_sc_cnt;
891721fffe3SKacheong Poon for (i = 0; i < cnt; i++)
8925dd46ab5SKacheong Poon tcp_add_mib(&tcps->tcps_sc[i]->tcp_sc_mib, tcp_mib);
893721fffe3SKacheong Poon }
894721fffe3SKacheong Poon
895721fffe3SKacheong Poon /*
896721fffe3SKacheong Poon * To set all tcp_stat_t counters to 0.
897721fffe3SKacheong Poon */
8985dd46ab5SKacheong Poon static void
tcp_clr_stats(tcp_stat_t * stats)899721fffe3SKacheong Poon tcp_clr_stats(tcp_stat_t *stats)
900721fffe3SKacheong Poon {
901721fffe3SKacheong Poon stats->tcp_time_wait_syn_success.value.ui64 = 0;
902721fffe3SKacheong Poon stats->tcp_clean_death_nondetached.value.ui64 = 0;
903721fffe3SKacheong Poon stats->tcp_eager_blowoff_q.value.ui64 = 0;
904721fffe3SKacheong Poon stats->tcp_eager_blowoff_q0.value.ui64 = 0;
905721fffe3SKacheong Poon stats->tcp_no_listener.value.ui64 = 0;
906721fffe3SKacheong Poon stats->tcp_listendrop.value.ui64 = 0;
907721fffe3SKacheong Poon stats->tcp_listendropq0.value.ui64 = 0;
908721fffe3SKacheong Poon stats->tcp_wsrv_called.value.ui64 = 0;
909721fffe3SKacheong Poon stats->tcp_flwctl_on.value.ui64 = 0;
910721fffe3SKacheong Poon stats->tcp_timer_fire_early.value.ui64 = 0;
911721fffe3SKacheong Poon stats->tcp_timer_fire_miss.value.ui64 = 0;
912721fffe3SKacheong Poon stats->tcp_zcopy_on.value.ui64 = 0;
913721fffe3SKacheong Poon stats->tcp_zcopy_off.value.ui64 = 0;
914721fffe3SKacheong Poon stats->tcp_zcopy_backoff.value.ui64 = 0;
915721fffe3SKacheong Poon stats->tcp_fusion_flowctl.value.ui64 = 0;
916721fffe3SKacheong Poon stats->tcp_fusion_backenabled.value.ui64 = 0;
917721fffe3SKacheong Poon stats->tcp_fusion_urg.value.ui64 = 0;
918721fffe3SKacheong Poon stats->tcp_fusion_putnext.value.ui64 = 0;
919721fffe3SKacheong Poon stats->tcp_fusion_unfusable.value.ui64 = 0;
920721fffe3SKacheong Poon stats->tcp_fusion_aborted.value.ui64 = 0;
921721fffe3SKacheong Poon stats->tcp_fusion_unqualified.value.ui64 = 0;
922721fffe3SKacheong Poon stats->tcp_fusion_rrw_busy.value.ui64 = 0;
923721fffe3SKacheong Poon stats->tcp_fusion_rrw_msgcnt.value.ui64 = 0;
924721fffe3SKacheong Poon stats->tcp_fusion_rrw_plugged.value.ui64 = 0;
925721fffe3SKacheong Poon stats->tcp_in_ack_unsent_drop.value.ui64 = 0;
926721fffe3SKacheong Poon stats->tcp_sock_fallback.value.ui64 = 0;
927721fffe3SKacheong Poon stats->tcp_lso_enabled.value.ui64 = 0;
928721fffe3SKacheong Poon stats->tcp_lso_disabled.value.ui64 = 0;
929721fffe3SKacheong Poon stats->tcp_lso_times.value.ui64 = 0;
930721fffe3SKacheong Poon stats->tcp_lso_pkt_out.value.ui64 = 0;
931721fffe3SKacheong Poon stats->tcp_listen_cnt_drop.value.ui64 = 0;
932721fffe3SKacheong Poon stats->tcp_listen_mem_drop.value.ui64 = 0;
933721fffe3SKacheong Poon stats->tcp_zwin_mem_drop.value.ui64 = 0;
934721fffe3SKacheong Poon stats->tcp_zwin_ack_syn.value.ui64 = 0;
935721fffe3SKacheong Poon stats->tcp_rst_unsent.value.ui64 = 0;
936721fffe3SKacheong Poon stats->tcp_reclaim_cnt.value.ui64 = 0;
937721fffe3SKacheong Poon stats->tcp_reass_timeout.value.ui64 = 0;
938721fffe3SKacheong Poon
939721fffe3SKacheong Poon #ifdef TCP_DEBUG_COUNTER
940721fffe3SKacheong Poon stats->tcp_time_wait.value.ui64 = 0;
941721fffe3SKacheong Poon stats->tcp_rput_time_wait.value.ui64 = 0;
942721fffe3SKacheong Poon stats->tcp_detach_time_wait.value.ui64 = 0;
943721fffe3SKacheong Poon stats->tcp_timeout_calls.value.ui64 = 0;
944721fffe3SKacheong Poon stats->tcp_timeout_cached_alloc.value.ui64 = 0;
945721fffe3SKacheong Poon stats->tcp_timeout_cancel_reqs.value.ui64 = 0;
946721fffe3SKacheong Poon stats->tcp_timeout_canceled.value.ui64 = 0;
947721fffe3SKacheong Poon stats->tcp_timermp_freed.value.ui64 = 0;
948721fffe3SKacheong Poon stats->tcp_push_timer_cnt.value.ui64 = 0;
949721fffe3SKacheong Poon stats->tcp_ack_timer_cnt.value.ui64 = 0;
950721fffe3SKacheong Poon #endif
951721fffe3SKacheong Poon }
952721fffe3SKacheong Poon
953721fffe3SKacheong Poon /*
9545dd46ab5SKacheong Poon * To add counters from the per CPU tcp_stat_counter_t to the stack
9555dd46ab5SKacheong Poon * tcp_stat_t.
956721fffe3SKacheong Poon */
9575dd46ab5SKacheong Poon static void
tcp_add_stats(tcp_stat_counter_t * from,tcp_stat_t * to)9585dd46ab5SKacheong Poon tcp_add_stats(tcp_stat_counter_t *from, tcp_stat_t *to)
959721fffe3SKacheong Poon {
960721fffe3SKacheong Poon to->tcp_time_wait_syn_success.value.ui64 +=
9615dd46ab5SKacheong Poon from->tcp_time_wait_syn_success;
962721fffe3SKacheong Poon to->tcp_clean_death_nondetached.value.ui64 +=
9635dd46ab5SKacheong Poon from->tcp_clean_death_nondetached;
964721fffe3SKacheong Poon to->tcp_eager_blowoff_q.value.ui64 +=
9655dd46ab5SKacheong Poon from->tcp_eager_blowoff_q;
966721fffe3SKacheong Poon to->tcp_eager_blowoff_q0.value.ui64 +=
9675dd46ab5SKacheong Poon from->tcp_eager_blowoff_q0;
968721fffe3SKacheong Poon to->tcp_no_listener.value.ui64 +=
9695dd46ab5SKacheong Poon from->tcp_no_listener;
970721fffe3SKacheong Poon to->tcp_listendrop.value.ui64 +=
9715dd46ab5SKacheong Poon from->tcp_listendrop;
972721fffe3SKacheong Poon to->tcp_listendropq0.value.ui64 +=
9735dd46ab5SKacheong Poon from->tcp_listendropq0;
974721fffe3SKacheong Poon to->tcp_wsrv_called.value.ui64 +=
9755dd46ab5SKacheong Poon from->tcp_wsrv_called;
976721fffe3SKacheong Poon to->tcp_flwctl_on.value.ui64 +=
9775dd46ab5SKacheong Poon from->tcp_flwctl_on;
978721fffe3SKacheong Poon to->tcp_timer_fire_early.value.ui64 +=
9795dd46ab5SKacheong Poon from->tcp_timer_fire_early;
980721fffe3SKacheong Poon to->tcp_timer_fire_miss.value.ui64 +=
9815dd46ab5SKacheong Poon from->tcp_timer_fire_miss;
982721fffe3SKacheong Poon to->tcp_zcopy_on.value.ui64 +=
9835dd46ab5SKacheong Poon from->tcp_zcopy_on;
984721fffe3SKacheong Poon to->tcp_zcopy_off.value.ui64 +=
9855dd46ab5SKacheong Poon from->tcp_zcopy_off;
986721fffe3SKacheong Poon to->tcp_zcopy_backoff.value.ui64 +=
9875dd46ab5SKacheong Poon from->tcp_zcopy_backoff;
988721fffe3SKacheong Poon to->tcp_fusion_flowctl.value.ui64 +=
9895dd46ab5SKacheong Poon from->tcp_fusion_flowctl;
990721fffe3SKacheong Poon to->tcp_fusion_backenabled.value.ui64 +=
9915dd46ab5SKacheong Poon from->tcp_fusion_backenabled;
992721fffe3SKacheong Poon to->tcp_fusion_urg.value.ui64 +=
9935dd46ab5SKacheong Poon from->tcp_fusion_urg;
994721fffe3SKacheong Poon to->tcp_fusion_putnext.value.ui64 +=
9955dd46ab5SKacheong Poon from->tcp_fusion_putnext;
996721fffe3SKacheong Poon to->tcp_fusion_unfusable.value.ui64 +=
9975dd46ab5SKacheong Poon from->tcp_fusion_unfusable;
998721fffe3SKacheong Poon to->tcp_fusion_aborted.value.ui64 +=
9995dd46ab5SKacheong Poon from->tcp_fusion_aborted;
1000721fffe3SKacheong Poon to->tcp_fusion_unqualified.value.ui64 +=
10015dd46ab5SKacheong Poon from->tcp_fusion_unqualified;
1002721fffe3SKacheong Poon to->tcp_fusion_rrw_busy.value.ui64 +=
10035dd46ab5SKacheong Poon from->tcp_fusion_rrw_busy;
1004721fffe3SKacheong Poon to->tcp_fusion_rrw_msgcnt.value.ui64 +=
10055dd46ab5SKacheong Poon from->tcp_fusion_rrw_msgcnt;
1006721fffe3SKacheong Poon to->tcp_fusion_rrw_plugged.value.ui64 +=
10075dd46ab5SKacheong Poon from->tcp_fusion_rrw_plugged;
1008721fffe3SKacheong Poon to->tcp_in_ack_unsent_drop.value.ui64 +=
10095dd46ab5SKacheong Poon from->tcp_in_ack_unsent_drop;
1010721fffe3SKacheong Poon to->tcp_sock_fallback.value.ui64 +=
10115dd46ab5SKacheong Poon from->tcp_sock_fallback;
1012721fffe3SKacheong Poon to->tcp_lso_enabled.value.ui64 +=
10135dd46ab5SKacheong Poon from->tcp_lso_enabled;
1014721fffe3SKacheong Poon to->tcp_lso_disabled.value.ui64 +=
10155dd46ab5SKacheong Poon from->tcp_lso_disabled;
1016721fffe3SKacheong Poon to->tcp_lso_times.value.ui64 +=
10175dd46ab5SKacheong Poon from->tcp_lso_times;
1018721fffe3SKacheong Poon to->tcp_lso_pkt_out.value.ui64 +=
10195dd46ab5SKacheong Poon from->tcp_lso_pkt_out;
1020721fffe3SKacheong Poon to->tcp_listen_cnt_drop.value.ui64 +=
10215dd46ab5SKacheong Poon from->tcp_listen_cnt_drop;
1022721fffe3SKacheong Poon to->tcp_listen_mem_drop.value.ui64 +=
10235dd46ab5SKacheong Poon from->tcp_listen_mem_drop;
1024721fffe3SKacheong Poon to->tcp_zwin_mem_drop.value.ui64 +=
10255dd46ab5SKacheong Poon from->tcp_zwin_mem_drop;
1026721fffe3SKacheong Poon to->tcp_zwin_ack_syn.value.ui64 +=
10275dd46ab5SKacheong Poon from->tcp_zwin_ack_syn;
1028721fffe3SKacheong Poon to->tcp_rst_unsent.value.ui64 +=
10295dd46ab5SKacheong Poon from->tcp_rst_unsent;
1030721fffe3SKacheong Poon to->tcp_reclaim_cnt.value.ui64 +=
10315dd46ab5SKacheong Poon from->tcp_reclaim_cnt;
1032721fffe3SKacheong Poon to->tcp_reass_timeout.value.ui64 +=
10335dd46ab5SKacheong Poon from->tcp_reass_timeout;
1034721fffe3SKacheong Poon
1035721fffe3SKacheong Poon #ifdef TCP_DEBUG_COUNTER
1036721fffe3SKacheong Poon to->tcp_time_wait.value.ui64 +=
10375dd46ab5SKacheong Poon from->tcp_time_wait;
1038721fffe3SKacheong Poon to->tcp_rput_time_wait.value.ui64 +=
10395dd46ab5SKacheong Poon from->tcp_rput_time_wait;
1040721fffe3SKacheong Poon to->tcp_detach_time_wait.value.ui64 +=
10415dd46ab5SKacheong Poon from->tcp_detach_time_wait;
1042721fffe3SKacheong Poon to->tcp_timeout_calls.value.ui64 +=
10435dd46ab5SKacheong Poon from->tcp_timeout_calls;
1044721fffe3SKacheong Poon to->tcp_timeout_cached_alloc.value.ui64 +=
10455dd46ab5SKacheong Poon from->tcp_timeout_cached_alloc;
1046721fffe3SKacheong Poon to->tcp_timeout_cancel_reqs.value.ui64 +=
10475dd46ab5SKacheong Poon from->tcp_timeout_cancel_reqs;
1048721fffe3SKacheong Poon to->tcp_timeout_canceled.value.ui64 +=
10495dd46ab5SKacheong Poon from->tcp_timeout_canceled;
1050721fffe3SKacheong Poon to->tcp_timermp_freed.value.ui64 +=
10515dd46ab5SKacheong Poon from->tcp_timermp_freed;
1052721fffe3SKacheong Poon to->tcp_push_timer_cnt.value.ui64 +=
10535dd46ab5SKacheong Poon from->tcp_push_timer_cnt;
1054721fffe3SKacheong Poon to->tcp_ack_timer_cnt.value.ui64 +=
10555dd46ab5SKacheong Poon from->tcp_ack_timer_cnt;
1056721fffe3SKacheong Poon #endif
1057721fffe3SKacheong Poon }
1058