xref: /xnu-12377.81.4/bsd/skywalk/os_stats_private.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2015-2021 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef _SKYWALK_OS_STATS_H_
30 #define _SKYWALK_OS_STATS_H_
31 
32 #if defined(PRIVATE) || defined(BSD_KERNEL_PRIVATE)
33 #include <skywalk/os_channel.h>
34 #include <skywalk/os_nexus_private.h>
35 #include <skywalk/os_packet.h>
36 #include <netinet/in.h>
37 #include <netinet/in_private.h>
38 #include <netinet/in_stat.h>
39 #include <net/if.h>
40 #include <net/if_var_private.h>
41 #include <net/ethernet.h>
42 
43 /*
44  * [Intro]
45  * This file defines new statistics infrastructure using enum and uin64_t array
46  * for skywalk. BSD network stack statistics definition would be kept for
47  * backward compatibility.
48  *
49  * This new scheme has several advantages over legacy statistics definition.
50  *  1. Using array based data structure allows efficient folding with vector
51  *     instructions.
52  *  2. It also allows simple indexing of statistics field using enum value
53  *     rather than struct field name.
54  *  3. Coupled with descriptive string per statistics enum, it allows convenient
55  *     printing.
56  *
57  * The new statistics enum and data structure follows naming convention as:
58  *  1. It should resemble legacy names to make transition easy.
59  *  2. It should be easily distinguishable from legacy data structure.
60  *
61  *
62  * [Naming]
63  * The new data structures are named with suffix _stats (plural) v.s legacy stat
64  * and are always in snake case, e.g.
65  *          New                      |   Legacy
66  *          -------------------------+--------------------------
67  *          ip_stats                 |   ipstat
68  *          ip6_stats                |   ip6stat
69  *          tcp_stats                |   tcpstat
70  *          if_tcp_ecn_stats         |   if_tcp_ecn_stat
71  *          if_tcp_ecn_perf_stats    |   if_tcp_ecn_perf_stat
72  *          udp_stats                |   udpstat
73  *
74  *
75  * Enums are named as <stats_family>_<type>, e.g.
76  *          New                      |   Legacy
77  *          -------------------------+--------------------------
78  *          IP_STATS_TOTAL           |   ipstat.ips_total
79  *          TCP_STATS_CONNATTEMPT    |   tcpstat.tcps_connattempt
80  *
81  *
82  * [Usage]
83  * Declare a statistics data structure:
84  *
85  *     struct ip_stats sample_ip_stats;
86  *
87  * To increment a statistics value by one:
88  *
89  *     STATS_INC(&sample_ip_stats, IP_STATS_TOTAL);
90  *
91  * To add to a statistics value by a certain value:
92  *
93  *     STATS_ADD(&sample_ip_stats, IP_STATS_TOTAL, n_pkts);
94  *
95  * To fold one statistics data structure into another one:
96  *
97  *     ip_stats_fold(&sample_ip_stats, &another_ip_stats);
98  *
99  * To reset statistics:
100  *
101  *     ip_stats_reset(&sample_ip_stats);
102  *
103  *
104  * [Note]
105  * Some legacy stats member has been removed for convenience reason, e.g.
106  *
107  *     ip6stat.ip6s_nxthist[256]
108  *     ip6stat.ip6s_sources_sameif[SCOPE6_ID_MAX];
109  *
110  * are removed, as they don't have easy mapping into array based statistics
111  * scheme and doesn't have explicit usage within the kernel.
112  * That's been said, those are treated as exceptions and could be reconsidered
113  * if they are needed in the future.
114  *
115  *
116  * [Adding Stats]
117  * To add new stats definition, a X-Macro table and STATS_REGISTER is needed.
118  *
119  *     #define NEW_STATS_TABLE(X)\
120  *         X(sub_type_1, "sub_type_1_short_name", "sub_type_1_fmt_string")\
121  *         X(sub_type_2, "sub_type_2_short_name", "sub_type_2_fmt_string")\
122  *         X(__NEW_STATS_MAX, "", "")
123  *
124  *     STATS_REGISTER(new_stats, NEW_STATS);
125  *
126  *  where new_stats is the lower case name, and NEW_STATS is its upper case.
127  *  The following would be generated by STATS_REGISTER Macro:
128  *
129  *     enum _new_stats {
130  *         sub_type_1,
131  *         sub_type_2,
132  *         __NEW_STATS_MAX,
133  *     };
134  *
135  *     struct new_stats {
136  *         uint64_t _arr[__NEW_STATS_NEW];
137  *     }
138  *
139  *     static inline const char* new_stats_str(enum _new_stats);
140  *     static inline const char* new_stats_fmt(enum _new_stats);
141  *
142  *     static inline void __attribute__((always_inline))
143  *         new_stats_fold(struct new_stats *dst, struct new_stats *src);
144  *
145  *     static inline void __attribute__((always_inline))
146  *         new_stats_reset(struct new_stats *s);
147  *
148  * The fmt_string should conform to printf convention. Note here as uint64_t is
149  * used to store stats value, `%llu` is used to format the print value (PRIu64
150  * could be used but since long long is guaranteed to be 64bit long, casting
151  * to llu should work well without introducing definitions from `inttypes.h`.
152  */
153 
154 /* BEGIN CSTYLED */
155 
156 /* ip stats definitions */
157 #define IP_STATS_TABLE(X)       \
158 	/* Input stats */      \
159 	X(IP_STATS_TOTAL,		"TotalRcvd",	"\t%llu total packet received\n")       \
160 	X(IP_STATS_BADSUM,		"BadCsum",	"\t\t%llu bad header checksum\n")       \
161 	X(IP_STATS_RCV_SWCSUM,		"RcvSWCsumPkt",	"\t\t%llu header checksummed in software")      \
162 	X(IP_STATS_RCV_SWCSUM_BYTES,	"RcvSWCsumByte"," (%llu byte)\n")       \
163 	X(IP_STATS_TOOSMALL,		"DataTooSmall",	"\t\t%llu with size smaller than minimum\n")\
164 	X(IP_STATS_TOOSHORT,		"PktTooShort",	"\t\t%llu with data size < data length\n")      \
165 	X(IP_STATS_ADJ,			"TotalAdj",	"\t\t%llu with data size > data length\n")      \
166 	X(IP_STATS_ADJ_HWCSUM_CLR,	"HWCsumDisc",	"\t\t\t%llu packet forced to software checksum\n")      \
167 	X(IP_STATS_TOOLONG,		"TooLong",	"\t\t%llu with ip length > max ip packet size\n")       \
168 	X(IP_STATS_BADHLEN,		"BadHdrLen",	"\t\t%llu with header length < data size\n")    \
169 	X(IP_STATS_BADLEN,		"BadLen",	"\t\t%llu with data length < header length\n")  \
170 	X(IP_STATS_BADOPTIONS,		"BadOptions",	"\t\t%llu with bad options\n")  \
171 	X(IP_STATS_BADVERS,		"BadVer",	"\t\t%llu with incorrect version number\n")     \
172 	X(IP_STATS_FRAGMENTS,		"FragRcvd",	"\t\t%llu fragment received\n") \
173 	X(IP_STATS_FRAGDROPPED,		"FragDrop",	"\t\t\t%llu dropped (dup or out of space)\n")   \
174 	X(IP_STATS_FRAGTIMEOUT,		"FragTimeO",	"\t\t\t%llu dropped after timeout\n")   \
175 	X(IP_STATS_REASSEMBLED,		"Reassembled",	"\t\t\t%llu reassembled ok\n")  \
176 	X(IP_STATS_DELIVERED,		"Delivered",	"\t\t%llu packet for this host\n")      \
177 	X(IP_STATS_NOPROTO,		"UnkwnProto",	"\t\t%llu packet for unknown/unsupported protocol\n")   \
178 	X(IP_STATS_FORWARD,		"Fwd",		"\t\t%llu packet forwarded")    \
179 	X(IP_STATS_FASTFORWARD,		"FastFwd",	" (%llu packet fast forwarded)\n")      \
180 	X(IP_STATS_CANTFORWARD,		"CantFwd",	"\t\t%llu packet not forwardable\n")    \
181 	X(IP_STATS_NOTMEMBER,		"UnRegGroup",	"\t\t%llu packet received for unknown multicast group\n")       \
182 	X(IP_STATS_REDIRECTSENT,	"FwdSameNet",	"\t\t%llu redirect sent\n")     \
183 	X(IP_STATS_RXC_COLLISIONS,	"RxChnColl",	"\t\t%llu input packet not chained due to collision\n") \
184 	X(IP_STATS_RXC_CHAINED,		"RxChn",	"\t\t%llu input packet processed in a chain\n") \
185 	X(IP_STATS_RXC_NOTCHAIN,	"RxBypChn",	"\t\t%llu input packet unable to chain\n")      \
186 	X(IP_STATS_RXC_CHAINSZ_GT2,	"RxChnGT2",	"\t\t%llu input packet chain processed with length greater than 2\n")   \
187 	X(IP_STATS_RXC_CHAINSZ_GT4,	"RxChnGT4",	"\t\t%llu input packet chain processed with length greater than 4\n")   \
188         \
189 	/* Output stats */      \
190 	X(IP_STATS_LOCALOUT,		"LocalOut",	"\t%llu packet sent from this host\n")  \
191 	X(IP_STATS_RAWOUT,		"RawPktOut",	"\t\t%llu packet sent with fabricated ip header\n")     \
192 	X(IP_STATS_ODROPPED,		"DropNoBuf",	"\t\t%llu output packet dropped due to no bufs, etc.\n")        \
193 	X(IP_STATS_NOROUTE,		"NoRoute",	"\t\t%llu output packet discarded due to no route\n")   \
194 	X(IP_STATS_FRAGMENTED,		"Fragmented",	"\t\t%llu output datagram fragmented\n")        \
195 	X(IP_STATS_OFRAGMENTS,		"OutFraged",	"\t\t%llu fragment created\n")  \
196 	X(IP_STATS_CANTFRAG,		"CantFrag",	"\t\t%llu datagram that can't be fragmented\n") \
197 	X(IP_STATS_NOGIF,		"NoGif",	"\t\t%llu tunneling packet that can't find gif\n")      \
198 	X(IP_STATS_BADADDR,		"BadAddr",	"\t\t%llu datagram with bad address in header\n")       \
199 	X(IP_STATS_PKTDROPCNTRL,	"DropNoCtl",	"\t\t%llu packet dropped due to no bufs for control data\n")    \
200 	X(IP_STATS_SND_SWCSUM,		"SndSWCsumPkt",	"\t\t%llu header checksummed in software")      \
201 	X(IP_STATS_SND_SWCSUM_BYTES,	"SndSWCsumByte"," (%llu byte)\n")       \
202 	X(IP_STATS_RXC_NOTLIST,		"IPInPkt",	"\t\t%llu input packet did not go through list processing path\n")      \
203 	X(__IP_STATS_MAX,		"",		"end of ip stats")
204 
205 /* ipv6 stats definitions */
206 #define IP6_STATS_TABLE(X)      \
207 	/* Input Stats */       \
208 	X(IP6_STATS_TOTAL,		"TotalRcvd",	"\t%llu total packet received\n")       \
209 	X(IP6_STATS_TOOSMALL,		"DataTooSmall",	"\t\t%llu with size smaller than minimum\n")    \
210 	X(IP6_STATS_TOOSHORT,		"PktTooShort",	"\t\t%llu with data size < data length\n")      \
211 	X(IP6_STATS_ADJ,		"TotalAdj",	"\t\t%llu with data size > data length\n")      \
212 	X(IP6_STATS_ADJ_HWCSUM_CLR,	"HWCsumDisc",	"\t\t\t%llu packet forced to software checksum\n")      \
213 	X(IP6_STATS_BADOPTIONS,		"BadOptions",	"\t\t%llu with bad options\n")  \
214 	X(IP6_STATS_BADVERS,		"BadVer",	"\t\t%llu with incorrect version number\n")     \
215 	X(IP6_STATS_FRAGMENTS,		"FrafRcvd",	"\t\t%llu fragment received\n") \
216 	X(IP6_STATS_FRAGDROPPED,	"FragDrop",	"\t\t\t%llu dropped (dup or out of space)\n")   \
217 	X(IP6_STATS_FRAGTIMEOUT,	"FragTimeO",	"\t\t\t%llu dropped after timeout\n")   \
218 	X(IP6_STATS_FRAGOVERFLOW,	"FragOverFlow",	"\t\t\t%llu exceeded limit\n")  \
219 	X(IP6_STATS_REASSEMBLED,	"FragReassembled","\t\t\t%llu reassembled ok\n")                \
220 	X(IP6_STATS_ATMFRAG_RCVD,	"RAtomicFrag",	"\t\t\t%llu atomic fragments received\n")               \
221 	X(IP6_STATS_DELIVERED,		"Delivered",	"\t\t%llu packet for this host\n")      \
222 	X(IP6_STATS_FORWARD,		"Fwd",		"\t\t%llu packet forwarded\n")  \
223 	X(IP6_STATS_CANTFORWARD,	"CantFwd",	"\t\t%llu packet not forwardable\n")    \
224 	X(IP6_STATS_REDIRECTSENT,	"RedirectSent",	"\t\t%llu redirect sent\n")     \
225 	X(IP6_STATS_NOTMEMBER,		"NoMCGrp",	"\t\t%llu multicast packet which we don't join\n")      \
226 	X(IP6_STATS_EXTHDRTOOLONG,	"ExtHdrNotCont","\t\t\t%llu packet whose headers are not continuous\n") \
227 	X(IP6_STATS_NOGIF,		"NoGif",	"\t\t%llu tunneling packet that can't find gif\n")      \
228 	X(IP6_STATS_TOOMANYHDR,		"TooManyHdr",	"\t\t%llu packet discarded due to too may headers\n")   \
229 	X(IP6_STATS_FORWARD_CACHEHIT,	"FwdCacheHit",	"\t\t%llu forward cache hit\n") \
230 	X(IP6_STATS_FORWARD_CACHEMISS,	"FwdCacheMiss",	"\t\t%llu forward cache miss\n")        \
231 	X(IP6_STATS_PKTDROPCNTRL,	"DropNoCtl",	"\t\t%llu packet dropped due to no bufs for control data\n")    \
232 	/* Output stats */      \
233 	X(IP6_STATS_LOCALOUT,		"LocalOut",	"\t%llu packet sent from this host\n")  \
234 	X(IP6_STATS_RAWOUT,		"RawPktOut",	"\t\t%llu packet sent with fabricated ip header\n")     \
235 	X(IP6_STATS_ODROPPED,		"DropNoBuf",	"\t\t%llu output packet dropped due to no bufs, etc.\n")        \
236 	X(IP6_STATS_NOROUTE,		"NoRoute",	"\t\t%llu output packet discarded due to no route\n")   \
237 	X(IP6_STATS_FRAGMENTED,		"Fragmented",	"\t\t%llu output datagram fragmented\n")        \
238 	X(IP6_STATS_OFRAGMENTS,		"OutFraged",	"\t\t%llu fragment created\n")  \
239 	X(IP6_STATS_CANTFRAG,		"CantFrag",	"\t\t%llu datagram that can't be fragmented\n")\
240 	X(IP6_STATS_BADSCOPE,		"BadScope",	"\t\t%llu packet that violated scope rules\n")  \
241 	X(IP6_STATS_SOURCES_NONE,	"AddrSelFail",	"\t\t%llu failure of source address selection\n")       \
242 	X(IP6_STATS_DAD_COLLIDE,	"DADColl",	"\t\t%llu duplicate address detection collision\n")     \
243 	X(IP6_STATS_DAD_LOOPCOUNT,	"DADLoop",	"\t\t%llu duplicate address detection NS loop\n")       \
244 	X(IP6_STATS_SOURCES_SKIP6_EXPENSIVE_SECONDARY_IF,"Ign2ndIf",	"\t\t%llu time ignored source on secondary expensive I/F\n")    \
245 	X(__IP6_STATS_MAX,		"",		"end of ipv6 stats")
246 
247 /* tcp stats definitions */
248 #define TCP_STATS_TABLE(X)      \
249 	/* Output stats */      \
250 	X(TCP_STATS_SNDTOTAL,		"SndTotalPkt",	"\t%llu packet sent\n") \
251 	X(TCP_STATS_SNDPACK,		"SndTotalDP",	"\t\t%llu data packet") \
252 	X(TCP_STATS_SNDBYTE,		"SndDataByte",	" (%llu byte)\n")       \
253 	X(TCP_STATS_SNDREXMITPACK,	"SndDPktReXmt",	"\t\t%llu data packet retransmitted")   \
254 	X(TCP_STATS_SNDREXMITBYTE,	"SndDByteReXmt"," (%llu byte)\n")       \
255 	X(TCP_STATS_MTURESENT,		"MTUReSnd",	"\t\t%llu resend initiated by MTU discovery\n") \
256 	X(TCP_STATS_SNDACKS,		"SndAck",	"\t\t%llu ack-only packet")     \
257 	X(TCP_STATS_DELACK,		"DelayAck",	" (%llu delayed)\n")    \
258 	X(TCP_STATS_SNDURG,		"SndURG",	"\t\t%llu URG only packet\n")   \
259 	X(TCP_STATS_SNDPROBE,		"SndWinProb",	"\t\t%llu window probe packet\n")       \
260 	X(TCP_STATS_SNDWINUP,		"SndWinUpd",	"\t\t%llu window update packet\n")      \
261 	X(TCP_STATS_SNDCTRL,		"SndCtlPkt",	"\t\t%llu control packet\n")    \
262 	X(TCP_STATS_FCHOLDPACKET,	"FlowCtlWh",	"\t\t%llu data packet sent after flow control\n")       \
263 	X(TCP_STATS_SYNCHALLENGE,	"SYNChallenge",	"\t\t%llu challenge ACK sent due to unexpected SYN\n")  \
264 	X(TCP_STATS_RSTCHALLENGE,	"RSTChallenge",	"\t\t%llu challenge ACK sent due to unexpected RST\n")  \
265 	X(TCP_STATS_SND_SWCSUM,		"SndSWCsumPkt",	"\t\t%llu checksummed in software")     \
266 	X(TCP_STATS_SND_SWCSUM_BYTES,	"SndSWCsumByte"," (%llu byte) over IPv4\n")     \
267 	X(TCP_STATS_SND6_SWCSUM,	"SndSWCsumPkt6","\t\t%llu checksummed in software")     \
268 	X(TCP_STATS_SND6_SWCSUM_BYTES,	"SndSWCsumByte6"," (%llu byte) over IPv6\n")    \
269         \
270 	/* Input stats */       \
271 	X(TCP_STATS_RCVTOTAL,		"RcvTotalPkt",	"\t%llu packet received\n")     \
272 	X(TCP_STATS_RCVACKPACK,		"RcvAckPkt",	"\t\t%llu ack") \
273 	X(TCP_STATS_RCVACKBYTE,		"RcvAckByte",	" (for %llu byte)\n")   \
274 	X(TCP_STATS_RCVDUPACK,		"RcvDupAck",	"\t\t%llu duplicate ack\n")     \
275 	X(TCP_STATS_RCVACKTOOMUCH,	"RcvAckUnSnd",	"\t\t%llu ack for unsent data\n")       \
276 	X(TCP_STATS_RCVPACK,		"RcvPktInSeq",	"\t\t%llu packet received in-sequence") \
277 	X(TCP_STATS_RCVBYTE,		"RcvBInSeq",	" (%llu byte)\n")       \
278 	X(TCP_STATS_RCVDUPPACK,		"RcvDupPkt",	"\t\t%llu completely duplicate packet") \
279 	X(TCP_STATS_RCVDUPBYTE,		"RcvDupByte",	" (%llu byte)\n")       \
280 	X(TCP_STATS_PAWSDROP,		"PAWSDrop",	"\t\t%llu old duplicate packet\n")      \
281 	X(TCP_STATS_RCVMEMDROP,		"RcvMemDrop",	"\t\t%llu received packet dropped due to low memory\n") \
282 	X(TCP_STATS_RCVPARTDUPPACK,	"RcvDupData",	"\t\t%llu packet with some dup. data")  \
283 	X(TCP_STATS_RCVPARTDUPBYTE,	"RcvPDupByte",	" (%llu byte duped)\n") \
284 	X(TCP_STATS_RCVOOPACK,		"RcvOOPkt",	"\t\t%llu out-of-order packet") \
285 	X(TCP_STATS_RCVOOBYTE,		"RcvOOByte",	" (%llu byte)\n")               \
286 	X(TCP_STATS_RCVPACKAFTERWIN,	"RcvAftWinPkt",	"\t\t%llu packet of data after window") \
287 	X(TCP_STATS_RCVBYTEAFTERWIN,	"RcvAftWinByte"," (%llu byte)\n")               \
288 	X(TCP_STATS_RCVWINPROBE,	"RcvWinProbPkt","\t\t%llu window probe\n")              \
289 	X(TCP_STATS_RCVWINUPD,		"RcvWinUpdPkt",	"\t\t%llu window update packet\n")              \
290 	X(TCP_STATS_RCVAFTERCLOSE,	"RcvAftCloPkt",	"\t\t%llu packet received after close\n")       \
291 	X(TCP_STATS_BADRST,		"BadRST",	"\t\t%llu bad reset\n") \
292 	X(TCP_STATS_RCVBADSUM,		"RcvBadCsum",	"\t\t%llu discarded for bad checksum\n")        \
293 	X(TCP_STATS_RCV_SWCSUM,		"RcvSWCsumPkt",	"\t\t%llu checksummed in software")     \
294 	X(TCP_STATS_RCV_SWCSUM_BYTES,	"RcvSWCsumByte"," (%llu byte) over IPv4\n")     \
295 	X(TCP_STATS_RCV6_SWCSUM,	"RcvSWCsumPkt6","\t\t%llu checksummed in software")     \
296 	X(TCP_STATS_RCV6_SWCSUM_BYTES,	"RcvSWCsumByte6"," (%llu byte) over IPv6\n")    \
297 	X(TCP_STATS_RCVBADOFF,		"RcvBadOff",	"\t\t%llu discarded for bad header offset field\n")     \
298 	X(TCP_STATS_RCVSHORT,		"RcvTooShort",	"\t\t%llu discarded because packet too short\n")        \
299 	X(TCP_STATS_CONNATTEMPT,	"ConnInit",	"\t\t%llu discarded because packet too short\n")        \
300         \
301 	/* Connection stats */  \
302 	X(TCP_STATS_ACCEPTS,		"ConnAcpt",	"\t%llu connection accept\n")   \
303 	X(TCP_STATS_BADSYN,		"BadSYN",	"\t%llu bad connection attempt\n")      \
304 	X(TCP_STATS_LISTENDROP,		"ListenDrop",	"\t%llu listen queue overflow\n")               \
305 	X(TCP_STATS_CONNECTS,		"ConnEst",	"\t%llu connection established (including accepts)\n")  \
306 	X(TCP_STATS_CLOSED,		"ConnClosed",	"\t%llu connection closed")     \
307 	X(TCP_STATS_DROPS,		"ConnDrop",	" (including %llu drop)\n")     \
308 	X(TCP_STATS_CACHEDRTT,		"RTTCacheUpd",	"\t\t%llu connection updated cached RTT on close\n")    \
309 	X(TCP_STATS_CACHEDRTTVAR,	"RTTVarCacheUpd","\t\t%llu connection updated cached RTT variance on close\n")  \
310 	X(TCP_STATS_CACHEDSSTHRESH,	"SSTholdCacheUpd","\t\t%llu connection updated cached ssthresh on close\n")     \
311 	X(TCP_STATS_CONNDROPS,		"EConnDrop",	"\t%llu embryonic connection dropped\n")        \
312 	X(TCP_STATS_RTTUPDATED,		"RTTUpdated",	"\t%llu segment updated rtt")   \
313 	X(TCP_STATS_SEGSTIMED,		"RTTTimed",	" (of %llu attempt)\n") \
314 	X(TCP_STATS_REXMTTIMEO,		"ReXmtTO",	"\t%llu retransmit timeout\n")  \
315 	X(TCP_STATS_TIMEOUTDROP,	"DropTO",	"\t\t%llu connection dropped by rexmit timeout\n")      \
316 	X(TCP_STATS_RXTFINDROP,		"ReXmtFINDrop",	"\t\t%llu connection dropped after retransmitting FIN\n")       \
317 	X(TCP_STATS_PERSISTTIMEO,	"PersistTO",	"\t%llu persist timeout\n")                     \
318 	X(TCP_STATS_PERSISTDROP,	"PersisStateTO","\t\t%llu connection dropped by persist timeout\n")     \
319 	X(TCP_STATS_KEEPTIMEO,		"KATO",		"\t%llu keepalive timeout\n")   \
320 	X(TCP_STATS_KEEPPROBE,		"KAProbe",	"\t\t%llu keepalive probe sent\n")      \
321 	X(TCP_STATS_KEEPDROPS,		"KADrop",	"\t\t%llu connection dropped by keepalive\n")   \
322 	X(TCP_STATS_PREDACK,		"PredAck",	"\t%llu correct ACK header prediction\n")       \
323 	X(TCP_STATS_PREDDAT,		"PredData",	"\t%llu correct data packet header prediction\n")       \
324 	X(TCP_STATS_PCBCACHEMISS,	"Pcb$Miss",	"\t%llu times pcb cahce miss")  \
325         \
326 	/* SACK/RACK related stats */        \
327 	X(TCP_STATS_SACK_RECOVERY_EPISODE,	"SACKRecEpi",	"\t%llu SACK recovery episode\n")       \
328 	X(TCP_STATS_SACK_REXMITS,	        "SACKReXmt",	"\t%llu segment rexmit in SACK recovery episodes\n")    \
329 	X(TCP_STATS_SACK_REXMIT_BYTES,		"SACKReXmtB",	"\t%llu byte rexmit in SACK recovery episodes\n")       \
330 	X(TCP_STATS_SACK_RCV_BLOCKS,		"SACKRcvBlk",	"\t%llu SACK option (SACK blocks) received\n")  \
331 	X(TCP_STATS_SACK_SEND_BLOCKS,		"SACKSntBlk",	"\t%llu SACK option (SACK blocks) sent\n")      \
332 	X(TCP_STATS_SACK_SBOVERFLOW,		"SACKSndBlkOF",	"\t%llu SACK scoreboard overflow\n")    \
333 	X(TCP_STATS_RACK_REXMITS,			"RACKReXmt",	"\t%llu segment rexmit in RACK recovery episodes\n")    \
334 	X(TCP_STATS_RACK_RECOVERY_EPISODE,	"RACKRecEpi",	"\t%llu RACK recovery episode\n")    \
335 	X(TCP_STATS_RACK_REORDERING_TIMEOUT_RECOVERY_EPISODE,	"RACKReorderTimeoutRecEpi",	"\t%llu RACK recovery episode due to reordering timeout\n")    \
336         \
337 	/* LRO related stats */ \
338 	X(TCP_STATS_COALESCED_PACK,		"CoalPkt",	"\t%llu LRO coalesced packet\n")        \
339 	X(TCP_STATS_FLOWTBL_FULL,		"FlowTblFull",	"\t\t%llu time LRO flow table was full\n")      \
340 	X(TCP_STATS_FLOWTBL_COLLISION,		"FlowTblColl",	"\t\t%llu collision in LRO flow table\n")               \
341 	X(TCP_STATS_LRO_TWOPACK,		"LRO2Pkt",	"\t\t%llu time LRO coalesced 2 packets\n")              \
342 	X(TCP_STATS_LRO_MULTPACK,		"LROMultiPkt",	"\t\t%llu time LRO coalesced 3 or 4 packets\n") \
343 	X(TCP_STATS_LRO_LARGEPACK,		"LROLargePkt",	"\t\t%llu time LRO coalesced 5 or more packets\n")      \
344         \
345 	X(TCP_STATS_LIMITED_TXT,		"LimitedXmt",	"\t%llu limited transmit done\n")               \
346 	X(TCP_STATS_EARLY_REXMT,		"EarlyReXmt",	"\t%llu early retransmit done\n")               \
347 	X(TCP_STATS_SACK_ACKADV,		"SACKAdvAck",	"\t%llu time cumulative ack advanced along with SACK\n")        \
348 	X(TCP_STATS_PTO,			"ProbTO",	"\t%llu probe timeout\n")               \
349 	X(TCP_STATS_RTO_AFTER_PTO,		"RTOAfProb",	"\t\t%llu time retransmit timeout triggered after probe\n")     \
350 	X(TCP_STATS_PROBE_IF,			"ProbeIF",	"\t\t%llu time probe packets were sent for an interface\n")     \
351 	X(TCP_STATS_PROBE_IF_CONFLICT,		"ProbeIFConfl",	"\t\t%llu time couldn't send probe packets for an interface\n") \
352 	X(TCP_STATS_TLP_RECOVERY,		"TLPFastRecvr", "\t\t%llu time fast recovery after tail loss\n")        \
353 	X(TCP_STATS_TLP_RECOVERLASTPKT,		"TLPRecvrLPkt",	"\t\t%llu time recovered last packet \n")       \
354 	X(TCP_STATS_PTO_IN_RECOVERY,		"PTOInRecvr",	"\t\t%llu SACK based rescue retransmit\n")      \
355         \
356 	/* ECN related stats */ \
357 	X(TCP_STATS_ECN_CLIENT_SETUP,		"ECNCliSetup",	"\t%llu client connection attempted to negotiate ECN\n")        \
358 	X(TCP_STATS_ECN_CLIENT_SUCCESS,		"ECNNegoSucc",	"\t\t%llu client connection successfully negotiated ECN\n")     \
359 	X(TCP_STATS_ECN_NOT_SUPPORTED,		"ECNSvrNoSupt", "\t\t%llu time graceful fallback to Non-ECN connection\n")      \
360 	X(TCP_STATS_ECN_LOST_SYN,		"ECNLOSSSYN",	"\t\t%llu time lost ECN negotiating SYN, followed by retransmission\n") \
361 	X(TCP_STATS_ECN_SERVER_SETUP,		"ECNSvrSetup",	"\t\t%llu server connection attempted to negotiate ECN\n")      \
362 	X(TCP_STATS_ECN_SERVER_SUCCESS,		"ECNSvrSucc",	"\t\t%llu server connection successfully negotiate ECN\n")      \
363 	X(TCP_STATS_ECN_ACE_SYN_NOT_ECT,	"ACESynNotECT",	"\t\t%llu received AccECN SYN packet with Not-ECT\n")           \
364 	X(TCP_STATS_ECN_ACE_SYN_ECT1,		"ACESynECT1",	"\t\t%llu received AccECN SYN packet with ECT1\n")              \
365 	X(TCP_STATS_ECN_ACE_SYN_ECT0,		"ACESynECT0",	"\t\t%llu received AccECN SYN packet with ECT0\n")              \
366 	X(TCP_STATS_ECN_ACE_SYN_CE,		"ACESynCE",	"\t\t%llu received AccECN SYN packet with CE\n")                \
367 	X(TCP_STATS_ECN_LOST_SYNACK,		"ECNLossSYNACK","\t\t%llu time lost ECN negotiating SYN-ACK, followed by retransmission\n")     \
368 	X(TCP_STATS_ECN_RECV_CE,		"ECNRcv",	"\t\t%llu time received congestion experienced (CE) notification\n")    \
369 	X(TCP_STATS_ECN_RECV_ECE,		"ECNRcvECE",	"\t\t%llu time CWR was sent in response to ECE\n")      \
370 	X(TCP_STATS_ECN_SENT_ECE,		"ECNSndECE",	"\t\t%llu time sent ECE notification\n")        \
371 	X(TCP_STATS_ECN_ACE_RECV_CE,            "ACERcvECE",    "\t\t%llu CE count received in ACE field\n")      \
372 	X(TCP_STATS_ECN_CONN_RECV_CE,		"ECNConnRcvCE",	"\t\t%llu connection received CE atleast once\n")       \
373 	X(TCP_STATS_ECN_CONN_RECV_ECE,		"ECNConnRcvECE","\t\t%llu connection received ECE atleast once\n")      \
374 	X(TCP_STATS_ECN_CONN_PLNOCE,		"ECNConnPLNoCE","\t\t%llu connection using ECN have seen packet loss but no CE\n")      \
375 	X(TCP_STATS_ECN_CONN_PL_CE,		"ECNConnPLCE",	"\t\t%llu connection using ECN have seen packet loss and CE\n")         \
376 	X(TCP_STATS_ECN_CONN_NOPL_CE,		"ECNConnNoPLCE","\t\t%llu connection using ECN received CE but no packet loss\n")               \
377 	X(TCP_STATS_ECN_FALLBACK_SYNLOSS,	"ECNFbSYNLoss",	"\t\t%llu connection fell back to non-ECN due to SYN-loss\n")   \
378 	X(TCP_STATS_ECN_FALLBACK_REORDER,	"ECNFbReOrd",	"\t\t%llu connection fell back to non-ECN due to reordering\n") \
379 	X(TCP_STATS_ECN_FALLBACK_CE,		"ECNFbCE",	"\t\t%llu connection fell back to non-ECN due to excessive CE-markings\n")      \
380 	X(TCP_STATS_ECN_FALLBACK_DROPRST,	"ECNFbDrpRST",	"\t\t%llu ECN fallback caused by connection drop due to RST\n") \
381 	X(TCP_STATS_ECN_FALLBACK_DROPRXMT,	"ECNFbDrpReXmt","\t\t%llu ECN fallback due to drop after multiple retransmits\n")       \
382 	X(TCP_STATS_DETECT_REORDERING,		"ReOrdDetect",	"\t%llu time packet reordering was detected on a connection\n") \
383 	X(TCP_STATS_REORDERED_PKTS,		"ReOrdPkt",	"\t\t%llu time transmitted packets were reordered\n")   \
384 	X(TCP_STATS_DELAY_RECOVERY,		"DlyFastRecvr",	"\t\t%llu time fast recovery was delayed to handle reordering\n")               \
385 	X(TCP_STATS_AVOID_RXMT,			"AvoidReXmt",	"\t\t%llu time retransmission was avoided by delaying recovery\n")      \
386 	X(TCP_STATS_UNNECESSARY_RXMT,		"UnNeedReXmt",	"\t\t%llu retransmission not needed\n")\
387         \
388 	/* DSACK related statistics */  \
389 	X(TCP_STATS_DSACK_SENT,			"DSACKSnd",	"\t%llu time DSACK option was sent\n")  \
390 	X(TCP_STATS_DSACK_RECVD,		"DSACKRcv",	"\t\t%llu time DSACK option was received\n")    \
391 	X(TCP_STATS_DSACK_DISABLE,		"DSACKDisable",	"\t\t%llu time DSACK was disabled on a connection\n")   \
392 	X(TCP_STATS_DSACK_BADREXMT,		"DSACKBadReXmt","\t\t%llu time recovered from bad retransmission using DSACK\n")        \
393 	X(TCP_STATS_DSACK_ACKLOSS,		"DSACKAckLoss",	"\t\t%llu time ignored DSACK due to ack loss\n")        \
394 	X(TCP_STATS_DSACK_RECVD_OLD,		"DSACKRcvOld",	"\t\t%llu time ignored old DSACK options\n")    \
395 	X(TCP_STATS_PMTUDBH_REVERTED,		"PMTUDBHRevert","\t%llu time PMTU Blackhole detection, size reverted\n")        \
396 	X(TCP_STATS_DROP_AFTER_SLEEP,		"DropAPSleep",	"\t%llu connection were dropped after long sleep\n")    \
397         \
398 	/* TFO-related statistics */    \
399 	X(TCP_STATS_TFO_COOKIE_SENT,		"TFOCkSnd",	"\t%llu time a TFO-cookie has been announced\n")        \
400 	X(TCP_STATS_TFO_SYN_DATA_RCV,		"TFOSYNDataRcv","\t%llu SYN with data and a valid TFO-cookie have been received\n")     \
401 	X(TCP_STATS_TFO_COOKIE_REQ_RCV,		"TFOCkReqRcv",	"\t%llu SYN with TFO-cookie-request received\n")        \
402 	X(TCP_STATS_TFO_COOKIE_INVALID,		"TFOCkInv",	"\t%llu time an invalid TFO-cookie has been received\n")        \
403 	X(TCP_STATS_TFO_COOKIE_REQ,		"TFOCkReq",	"\t%llu time we requested a TFO-cookie\n")      \
404 	X(TCP_STATS_TFO_COOKIE_RCV,		"TFOCkRcv",	"\t\t%llu time the peer announced a TFO-cookie\n")      \
405 	X(TCP_STATS_TFO_SYN_DATA_SENT,		"TFOSYNDataSnd","\t%llu time we combined SYN with data and a TFO-cookie\n")     \
406 	X(TCP_STATS_TFO_SYN_DATA_ACKED,		"TDOSYNDataAck","\t\t%llu time our SYN with data has been acknowledged\n")      \
407 	X(TCP_STATS_TFO_SYN_LOSS,		"TFOSYNLoss",	"\t%llu time a connection-attempt with TFO fell back to regular TCP\n") \
408 	X(TCP_STATS_TFO_BLACKHOLE,		"TFOBlackhole",	"\t%llu time a TFO-connection blackhole'd\n")   \
409 	X(TCP_STATS_TFO_COOKIE_WRONG,		"TFOCkWrong",	"\t%llu time TFO-cookie we sent was wrong\n")   \
410 	X(TCP_STATS_TFO_NO_COOKIE_RCV,		"TFONoCkRcv",	"\t%llu time ee asked for a cookie but didn't get one\n")       \
411 	X(TCP_STATS_TFO_HEURISTICS_DISABLE,	"TFOHeuDisable","\t%llu time TFO got disabled due to heuristics\n")     \
412 	X(TCP_STATS_TFO_SNDBLACKHOLE,		"TFOSndBH",	"\t%llu time TFO got blackholed in the sending direction\n")    \
413 	X(TCP_STATS_MSS_TO_DEFAULT,		"MSSToDefault",	"\t%llu time maximum segment size was changed to default\n")    \
414 	X(TCP_STATS_MSS_TO_MEDIUM,		"MSSToMedium",	"\t%llu time maximum segment size was changed to medium\n")     \
415 	X(TCP_STATS_MSS_TO_LOW,			"MSSToLow",	"\t%llu time maximum segment size was changed to low\n")        \
416         \
417 	/* TCP timer statistics */      \
418 	X(TCP_STATS_TIMER_DRIFT_LE_1_MS,	"TmrDriftLE1Ms",	"\t%llu timer drift less or equal to 1 ms\n")   \
419 	X(TCP_STATS_TIMER_DRIFT_LE_10_MS,	"TmrDriftLE10Ms",	"\t%llu timer drift less or equal to 10 ms\n")  \
420 	X(TCP_STATS_TIMER_DRIFT_LE_20_MS,	"TmrDriftLE20Ms",	"\t%llu timer drift less or equal to 20 ms\n")  \
421 	X(TCP_STATS_TIMER_DRIFT_LE_50_MS,	"TmrDriftLE50Ms",	"\t%llu timer drift less or equal to 50 ms\n")  \
422 	X(TCP_STATS_TIMER_DRIFT_LE_100_MS,	"TmrDriftLE100Ms",	"\t%llu timer drift less or equal to 100 ms\n") \
423 	X(TCP_STATS_TIMER_DRIFT_LE_200_MS,	"TmrDriftLE200Ms",	"\t%llu timer drift less or equal to 200 ms\n") \
424 	X(TCP_STATS_TIMER_DRIFT_LE_500_MS,	"TmrDriftLE500Ms",	"\t%llu timer drift less or equal to 500 ms\n") \
425 	X(TCP_STATS_TIMER_DRIFT_LE_1000_MS,	"TmrDriftLE1000Ms",	"\t%llu timer drift less or equal to 1000 ms\n")        \
426 	X(TCP_STATS_TIMER_DRIFT_GT_1000_MS,	"TmrDriftGT1000Ms",	"\t%llu timer drift greater than 1000 ms\n")    \
427 	X(TCP_STATS_USEDRTT,			"RTTUsed",	"\t%llu times RTT initialized from route\n")    \
428 	X(TCP_STATS_USEDRTTVAR,			"RTTVarUsed",	"\t%llu times RTTVAR initialized from rt\n")    \
429 	X(TCP_STATS_USEDSSTHRESH,		"SSTholdUsed",	"\t%llu times ssthresh initialized from rt\n")  \
430 	X(TCP_STATS_MINMSSDROPS,		"MinMssDrop",	"\t%llu average minmss too low drops\n")        \
431 	X(TCP_STATS_SNDREXMITBAD,		"BadReXmt",	"\t%llu unnecessary packet retransmissions\n")  \
432         \
433 	/* SYN Cache relaetd stats */   \
434 	X(TCP_STATS_SC_ADDED,			"SCAdded",	"\t%llu entry added to syncache\n")     \
435 	X(TCP_STATS_SC_RETRANSMITTED,		"SCReXmt",	"\t%llu syncache entry was retransmitted\n")    \
436 	X(TCP_STATS_SC_DUPSYN,			"SCDupSYN",	"\t%llu duplicate SYN packet\n")        \
437 	X(TCP_STATS_SC_DROPPED,			"SCDrop",	"\t%llu could not reply to packet\n")   \
438 	X(TCP_STATS_SC_COMPLETED,		"SCCompl",	"\t%llu successful extraction of entry\n")      \
439 	X(TCP_STATS_SC_BUCKETOVERFLOW,		"SCBktOF",	"\t%llu syncache per-bucket limit hit\n")       \
440 	X(TCP_STATS_SC_CACHEOVERFLOW,		"SCOF",		"\t%llu syncache cache limit hit\n")    \
441 	X(TCP_STATS_SC_RESET,			"SCReset",	"\t%llu RST removed entry from syncache\n")     \
442 	X(TCP_STATS_SC_STALE,			"SCStale",	"\t%llu timed out or listen socket gone\n")     \
443 	X(TCP_STATS_SC_ABORTED,			"SCAbrt",	"\t%llu syncache entry aborted\n")      \
444 	X(TCP_STATS_SC_BADACK,			"SCBadAck",	"\t%llu removed due to bad ACK\n")      \
445 	X(TCP_STATS_SC_UNREACH,			"SCUnReach",	"\t%llu ICMP unreachable received\n")   \
446 	X(TCP_STATS_SC_ZONEFAIL,		"SCZoneFail",	"\t%llu zalloc() failed\n")     \
447 	X(TCP_STATS_SC_SENDCOOKIE,		"SCSndCookie",	"\t%llu SYN cookie sent\n")     \
448 	X(TCP_STATS_SC_RECVCOOKIE,		"SCRvcCookie",	"\t%llu SYN cookie received\n") \
449         \
450 	/* Host Cache related stats */  \
451 	X(TCP_STATS_HC_ADDED,			"HCAdd",	"\t%llu entry added to hostcache\n")            \
452 	X(TCP_STATS_HC_BUCKETOVERFLOW,		"HCBktOF",	"\t%llu hostcache per bucket limit hit\n")      \
453         \
454 	/* Misc. */     \
455 	X(TCP_STATS_BG_RCVTOTAL,		"RcvBkgrdPkt",	"\t%llu total background packets received\n")   \
456 	X(TCP_STATS_MSG_UNOPKTS,		"MsgUnOrdPkt",	"\t%llu unordered packet on TCP msg stream\n")  \
457 	X(TCP_STATS_MSG_UNOAPPENDFAIL,		"MsgUnOrdFail",	"\t%llu failed to append unordered pkt\n")      \
458 	X(TCP_STATS_MSG_SNDWAITHIPRI,		"MsgSndW8HPrio","\t%llu send waiting for high priority data\n") \
459         \
460 	/* MPTCP Related stats */       \
461 	X(TCP_STATS_MP_SNDPACKS,		"MPSndPkt",	"\t%llu data packet sent\n")    \
462 	X(TCP_STATS_MP_SNDBYTES,		"MPSndByte",	"\t%llu data byte sent\n")      \
463 	X(TCP_STATS_MP_RCVTOTAL,		"MPRcvTotal",	"\t%llu data packet received\n")        \
464 	X(TCP_STATS_MP_RCVBYTES,		"MPRcvByte",	"\t%llu data byte received\n")  \
465 	X(TCP_STATS_INVALID_MPCAP,		"InvMPCap",	"\t%llu packet with an invalid MPCAP option\n") \
466 	X(TCP_STATS_INVALID_JOINS,		"InvMPJoin",	"\t%llu packet with an invalid MPJOIN option\n")        \
467 	X(TCP_STATS_MPCAP_FALLBACK,		"MPCapFail",	"\t%llu time primary subflow fell back to TCP\n")       \
468 	X(TCP_STATS_JOIN_FALLBACK,		"MPJoinFallBk",	"\t%llu time secondary subflow fell back to TCP\n")     \
469 	X(TCP_STATS_ESTAB_FALLBACK,		"EstFallBk",	"\t%llu DSS option drop\n")     \
470 	X(TCP_STATS_INVALID_OPT,		"InvOpt",	"\t%llu other invalid MPTCP option\n")  \
471 	X(TCP_STATS_MP_REDUCEDWIN,		"MPReducedWin",	"\t%llu time the MPTCP subflow window was reduced\n")   \
472 	X(TCP_STATS_MP_BADCSUM,			"MPBadCSum",	"\t%llu bad DSS checksum\n")    \
473 	X(TCP_STATS_MP_OODATA,			"MPOOData",	"\t%llu time received out of order data\n")     \
474 	X(TCP_STATS_MP_OUTOFWIN,		"MPOutOfWin",	"\t%llu Packet lies outside the shared recv window\n")  \
475 	X(TCP_STATS_JOIN_RXMTS,			"JoinAckReXmt",	"\t%llu join ack retransmits\n")        \
476 	X(TCP_STATS_TAILLOSS_RTO,		"TailLossTRO",	"\t%llu RTO due to tail loss\n")        \
477 	X(TCP_STATS_RECOVERED_PKTS,		"RecoveryPkt",	"\t%llu recovered after loss\n")        \
478 	/* ToDo - to be removed */    \
479 	X(TCP_STATS_NOSTRETCHACK,		"NoStrechAck",  "\t%llu disabled stretch ack algorithm on a connection\n")    \
480 	X(TCP_STATS_RESCUE_RXMT,		"SACKRsqReXmt", "\t%llu SACK rescue retransmit\n")      \
481         \
482 	/* MPTCP Subflow selection stats */     \
483 	X(TCP_STATS_MP_SWITCHES,		"MPSwitches",	"\t%llu subflow switch\n")      \
484 	X(TCP_STATS_MP_SEL_SYMTOMSD,		"MPSelSymp",	"\t%llu subflow switch due to advisory\n")      \
485 	X(TCP_STATS_MP_SEL_RTT,			"MPSelRTT",	"\t%llu subflow switch due to rtt\n")   \
486 	X(TCP_STATS_MP_SEL_RTO,			"MPSelRTO",	"\t%llu subflow switch due to rto\n")   \
487 	X(TCP_STATS_MP_SEL_PEER,		"MPSelPeer",	"\t%llu subflow switch due to peer\n")  \
488 	X(TCP_STATS_MP_NUM_PROBES,		"MPProbe",	"\t%llu number of subflow probe\n")     \
489 	X(TCP_STATS_MP_VERDOWNGRADE,		"MPVerDowngrd",	"\t%llu times MPTCP version downgrade\n")       \
490         \
491 	/* Miscellaneous statistics */  \
492 	X(TCP_STATS_TW_PCBCOUNT,		"TWPcbCount",	"\t%llu pcbs in time-wait state\n")     \
493         \
494 	/* RST compression statistics */  \
495 	X(TCP_STATS_RST_DUP_SUPPRESSED,		"RSTDupSup",	"\t%llu RST duplicate suppressed\n")     \
496 	X(TCP_STATS_RST_NOT_SUPPRESSED,		"RSTNotSup",	"\t%llu RST not suppressed\n")     \
497         \
498 	X(__TCP_STATS_MAX,			"",		"end of tcp stats")
499 
500 #define UDP_STATS_TABLE(X)                                              \
501 	/* Input stats */       \
502 	X(UDP_STATS_IPACKETS,			"RcvPkt",		"\t%llu datagram received\n")   \
503 	X(UDP_STATS_HDROPS,			"HdrDrop",		"\t\t%llu with incomplete header\n")    \
504 	X(UDP_STATS_BADSUM,			"BadCsum",		"\t\t%llu with bad data length field\n")        \
505 	X(UDP_STATS_BADLEN,			"BadLen",		"\t\t%llu with bad checksum\n") \
506 	X(UDP_STATS_NOSUM,			"NoCsum",		"\t\t%llu with no checksum\n")  \
507 	X(UDP_STATS_RCV_SWCSUM,			"RcvSWCsum",		"\t\t%llu checksummed in software")     \
508 	X(UDP_STATS_RCV_SWCSUM_BYTES,		"RcvSWCsumBytes",	" (%llu bytes) over IPv4\n")    \
509 	X(UDP_STATS_RCV6_SWCSUM,		"RcvSWCsum",		"\t\t%llu checksummed in software")     \
510 	X(UDP_STATS_RCV6_SWCSUM_BYTES,		"RcvSWCsumBytes",	" (%llu bytes) over IPv6\n")    \
511 	X(UDP_STATS_NOPORT,			"NoPort",		"\t\t%llu dropped due to no socket\n")  \
512 	X(UDP_STATS_NOPORTBCAST,		"NoPortBCast",		"\t\t%llu broadcast/multicast datagram undelivered\n")  \
513 	X(UDP_STATS_FILTERMCAST,		"FilterMCast",		"\t\t%llu time multicast source filter matched\n")      \
514 	X(UDP_STATS_FULLSOCK,			"FullSock",		"\t\t%llu dropped due to full socket buffers\n")        \
515 	X(UDP_STATS_PCBCACHEMISS,		"PCBCacheMiss",		"\t\t%llu not for hashed pcb\n")        \
516 	X(UDP_STATS_PCBHASHMISS,		"PCBHashMiss",		"\t\t%llu input packets not for hashed pcb")    \
517         \
518 	/* Output stats */      \
519 	X(UDP_STATS_OPACKETS,			"SndPkt",		"\t%llu datagram output\n")     \
520 	X(UDP_STATS_SND_SWCSUM,			"SndSWCsum",		"\t\t%llu checksummed in software")     \
521 	X(UDP_STATS_SND_SWCSUM_BYTES,		"SndSWCsumBytes",	" (%llu bytes) over IPv4\n")    \
522 	X(UDP_STATS_SND6_SWCSUM,		"SndSWCsum6",		"\t\t%llu checksummed in software")     \
523 	X(UDP_STATS_SND6_SWCSUM_BYTES,		"SndSWCsumBytes6",	" (%llu bytes) over IPv6\n")    \
524 	X(UDP_STATS_FASTOUT,			"SndFastPath",		"\t\t%llu output packets on fast path\n")       \
525 	X(UDP_STATS_NOPORTMCAST,		"SndNoPortMCast",	"\t\t%llu output no socket on port, multicast\n")       \
526         \
527 	X(__UDP_STATS_MAX,			"",			"end of UDP stats")
528 
529 #define QUIC_STATS_TABLE(X)                                      \
530 	/* Tx */        \
531 	X(QUIC_STATS_SNDPKT,			"SndTotalPkt",		"\t%llu packets sent")  \
532 	X(QUIC_STATS_SNDBYTE,			"SndTotalByte",		" (%llu bytes)\n")      \
533 	/* Tx Stream */ \
534 	X(QUIC_STATS_SNDSTREAMFRAME,		"SndStreamFrame",	"\t\tSTREAM\n\t\t\t%llu stream frames sent")    \
535 	X(QUIC_STATS_SNDSTREAMBYTE,		"SndStreamByte",	" (%llu bytes)\n")      \
536 	X(QUIC_STATS_SNDSTREAMRESET,		"SndStreamReset",	"\t\t\t%llu RESET_STREAM frames sent\n")        \
537 	X(QUIC_STATS_SNDSTOPSENDING,		"SndStopSending",	"\t\t\t%llu STOP_SENDING frames sent\n")        \
538 	X(QUIC_STATS_SNDSTREAMBLKFRAME,		"SndStreamBlockedFrame","\t\t\t%llu STREAM_BLOCKED frames sent\n")      \
539 	X(QUIC_STATS_SNDSTMDATABLKFRAME,	"SndStreamDataBlocked",	"\t\t\t%llu STREAM_DATA_BLOCKED frames sent\n") \
540 	/* Tx CRYPTO */ \
541 	X(QUIC_STATS_SNDINITCRYPTOFRAME,	"SndInitCryptoFrame",	"\t\tCRYPTO\n\t\t\t%llu initial CRYPTO frames sent")    \
542 	X(QUIC_STATS_SNDINITCRYPTOBYTE,		"SndInitCryptoByte",	" (%llu bytes)\n")      \
543 	X(QUIC_STATS_SNDHDSHKCRYPTOFRAME,	"SndHdShkCryptoFrame",	"\t\t\t%llu handshake CRYPTO frames sent")      \
544 	X(QUIC_STATS_SNDHDSHKCRYPTOBYTE,	"SndHdShkCryptoByte",	" (%llu bytes)\n")      \
545 	X(QUIC_STATS_SND1RTTCRYPTOFRAME,	"Snd1RttCryptoFrame",	"\t\t\t%llu 1-RTT CRYPTO frames sent")  \
546 	X(QUIC_STATS_SND1RTTCRYPTOBYTE,		"Snd1RttCryptoByte",	" (%llu bytes)\n")      \
547 	X(QUIC_STATS_SND0RTTCRYPTOFRAME,	"Snd1RttCryptoFrame",	"\t\t\t%llu 0-RTT CRYPTO frames sent")  \
548 	X(QUIC_STATS_SND0RTTCRYPTOBYTE,		"Snd1RttCryptoByte",	" (%llu bytes)\n")      \
549 	X(QUIC_STATS_SNDCRYPTOREXMTFRAME,	"SndReXmtCryptoFrame",	"\t\t\t%llu CRYPTO frames retransmitted")       \
550 	X(QUIC_STATS_SNDCRYPTOREXMTBYTE,	"SndReXmtCryptoByte",	" (%llu bytes)\n")      \
551 	X(QUIC_STATS_SNDDATABLKFRAME,		"SndDataBlockedFrame",	"\t\t%llu DATA_BLOCKED frames sent\n")  \
552 	X(QUIC_STATS_SNDREXMTPKT,		"SndReXmtPkt",		"\t\t%llu packets retransmitted")       \
553 	X(QUIC_STATS_SNDREXMTBYTE,		"SndReXmtByte",		" (%llu bytes)\n")      \
554 	X(QUIC_STATS_SNDLOSTPKT,		"SndLostPkt",		"\t\t%llu packets lost")        \
555 	X(QUIC_STATS_SNDLOSTBYTE,		"SndLostByte",		" (%llu bytes)\n")      \
556 	/* End of Tx */ \
557 	/* Rx */        \
558 	X(QUIC_STATS_RCVPKT,			"RcvTotalPkt",		"\t%llu packets received")      \
559 	X(QUIC_STATS_RECVBYTE,			"RcvTotalByte",		" (%llu bytes)\n")      \
560 	/* Rx Stream */ \
561 	X(QUIC_STATS_RCVSTREAMFRAME,		"RcvStreamFrame",	"\t\tSTREAM\n\t\t\t%llu stream frames received")        \
562 	X(QUIC_STATS_RCVSTREAMBYTE,		"RcvStreamByte",	" (%llu bytes)\n")      \
563 	X(QUIC_STATS_RCVSTREAMRESET,		"RcvStreamReset",	"\t\t\t%llu RESET_STREAM frames received\n")    \
564 	X(QUIC_STATS_RCVSTOPSENDING,		"RcvStopSending",	"\t\t\t%llu STOP_SENDING frames received\n")    \
565 	X(QUIC_STATS_RCVSTREAMBLKFRAME,		"RcvStreamBlockedFrame","\t\t\t%llu STREAM_BLOCKED frames received\n")  \
566 	X(QUIC_STATS_RCVSTMDATABLKFRAME,	"RcvStreamDataBlocked",	"\t\t\t%llu STREAM_DATA_BLOCKED frames received\n")     \
567 	/* Rx CRYPTO */ \
568 	X(QUIC_STATS_RCVINITCRYPTOFRAME,	"RcvInitCryptoFrame",	"\t\tCRYPTO\n\t\t\t%llu initial CRYPTO frames received")        \
569 	X(QUIC_STATS_RCVINITCRYPTOBYTE,		"RcvInitCryptoByte",	" (%llu bytes)\n")      \
570 	X(QUIC_STATS_RCVHDSHKCRYPTOFRAME,	"RcvHdShkCryptoFrame",	"\t\t\t%llu handshake CRYPTO frames received")  \
571 	X(QUIC_STATS_RCVHDSHKCRYPTOBYTE,	"RcvHdShkCryptoByte",	" (%llu bytes)\n")      \
572 	X(QUIC_STATS_RCV1RTTCRYPTOFRAME,	"Rcv1RttCryptoFrame",	"\t\t\t%llu 1-RTT CRYPTO frames received")      \
573 	X(QUIC_STATS_RCV1RTTCRYPTOBYTE,		"Rcv1RttCryptoByte",	" (%llu bytes)\n")      \
574 	X(QUIC_STATS_RCV0RTTCRYPTOFRAME,	"Rcv0RttCryptoFrame",	"\t\t\t%llu 0-RTT CRYPTO frames received")      \
575 	X(QUIC_STATS_RCV0RTTCRYPTOBYTE,		"Rcv0RttCryptoByte",	" (%llu bytes)\n")      \
576 	X(QUIC_STATS_RCVDATABLKFRAME,		"RcvDataBlockedFrame",	"\t\t%llu DATA_BLOCKED frames received\n")      \
577 	X(QUIC_STATS_RCVREORDERPKT,		"RcvReorderedPkt",	"\t\t%llu packets received reordered")  \
578 	X(QUIC_STATS_RCVREORDERBYTE,		"RcvReorderedByte",	" (%llu bytes)\n")      \
579 	/* Connections */       \
580 	X(QUIC_STATS_CONNECTS,			"ConnEst",		"\t%llu connections established\n")     \
581 	X(QUIC_STATS_SNDCCR,			"SndCCR",		"\t\t%llu connection close reasons sent\n")     \
582 	X(QUIC_STATS_SNDCCRINTERROR,		"SndCCRInternalError",	"\t\t\t%llu INTERNAL_ERROR sent\n")     \
583 	X(QUIC_STATS_SNDCCRSVRBUSY,		"SndCCRSererBusy",	"\t\t\t%llu SERVER_BUSY sent\n")        \
584 	X(QUIC_STATS_SNDCCRFLOWCTLERR,		"SndCCRFlowCtl",	"\t\t\t%llu FLOW_CONTROL_ERROR sent\n") \
585 	X(QUIC_STATS_SNDCCRSTREAMLIMIT,		"SndCCRStreamLimit",	"\t\t\t%llu STREAM_LIMIT_ERROR sent\n") \
586 	X(QUIC_STATS_SNDCCRSTREAMSTATE,		"SndCCRStreamState",	"\t\t\t%llu STREAM_STATE_ERROR sent\n") \
587 	X(QUIC_STATS_SNDCCRFINALOFFSET,		"SndCCRFinalOffset",	"\t\t\t%llu FINAL_SIZE_ERROR sent\n")   \
588 	X(QUIC_STATS_SNDCCRFRAMEENCODING,	"SndCCRFrameEncoding",	"\t\t\t%llu FRAME_ENCODING_ERROR sent\n")       \
589 	X(QUIC_STATS_SNDCCRTRNASPARAMS,		"SndCCRTransportParams","\t\t\t%llu TRANSPORT_PARAMETER_ERROR sent\n")  \
590 	X(QUIC_STATS_SNDCCRVERSIONNEGO,		"SndCCRVersionNego",	"\t\t\t%llu VERSION_NEGOTIATION_ERROR sent\n")  \
591 	X(QUIC_STATS_SNDCCRPROTOVIOLATION,	"SndCCRProtoViolation",	"\t\t\t%llu PROTOCOL_VIOLATION sent\n") \
592 	X(QUIC_STATS_SNDCCRINVALMIGRATION,	"SndCCRInvalMigration",	"\t\t\t%llu INVALID_MIGRATION sent\n")  \
593 	X(QUIC_STATS_SNDCCRCRYPTO,		"SndCCRCryptoError",	"\t\t\t%llu CRYPTO_ERROR sent\n")       \
594 	X(QUIC_STATS_RCVCCR,			"RcvCCR",		"\t\t%llu connection close reasons received\n") \
595 	X(QUIC_STATS_RCVCCRINTERROR,		"RcvCCRInternalError",	"\t\t\t%llu INTERNAL_ERROR received\n") \
596 	X(QUIC_STATS_RCVCCRSVRBUSY,		"RcvCCRSererBusy",	"\t\t\t%llu SERVER_BUSY received\n")    \
597 	X(QUIC_STATS_RCVCCRFLOWCTLERR,		"RcvCCRFlowCtl",	"\t\t\t%llu FLOW_CONTROL_ERROR received\n")     \
598 	X(QUIC_STATS_RCVCCRSTREAMLIMIT,		"RcvCCRStreamLimit",	"\t\t\t%llu STREAM_LIMIT_ERROR received\n")     \
599 	X(QUIC_STATS_RCVCCRSTREAMSTATE,		"RcvCCRStreamState",	"\t\t\t%llu STREAM_STATE_ERROR received\n")     \
600 	X(QUIC_STATS_RCVCCRFINALOFFSET,		"RcvCCRFinalOffset",	"\t\t\t%llu FINAL_SIZE_ERROR received\n")       \
601 	X(QUIC_STATS_RCVCCRFRAMEENCODING,	"RcvCCRFrameEncoding",	"\t\t\t%llu FRAME_ENCODING_ERROR received\n")   \
602 	X(QUIC_STATS_RCVCCRTRNASPARAMS,		"RcvCCRTransportParams","\t\t\t%llu TRANSPORT_PARAMETER_ERROR received\n")      \
603 	X(QUIC_STATS_RCVCCRVERSIONNEGO,		"RcvCCRVersionNego",	"\t\t\t%llu VERSION_NEGOTIATION_ERROR received\n")      \
604 	X(QUIC_STATS_RCVCCRPROTOVIOLATION,	"RcvCCRProtoViolation",	"\t\t\t%llu PROTOCOL_VIOLATION received\n")     \
605 	X(QUIC_STATS_RCVCCRINVALMIGRATION,	"RcvCCRInvalMigration",	"\t\t\t%llu INVALID_MIGRATION received\n")      \
606 	X(QUIC_STATS_RCVCCRCRYPTO,		"RcvCCRCryptoError",	"\t\t\t%llu CRYPTO_ERROR received\n")   \
607 	X(QUIC_STATS_SNDECT0,			"SndECT0",		"\t%llu ECT0 sent\n")   \
608 	X(QUIC_STATS_RCVECT0,			"RcvECT0",		"\t%llu ECT0 received\n")       \
609 	X(QUIC_STATS_SNDECT1,			"SndECT1",		"\t%llu ECT1 sent\n")   \
610 	X(QUIC_STATS_RCVECT1,			"RcvECT1",		"\t%llu ECT1 received\n")       \
611 	X(QUIC_STATS_SNDECTCE,			"SndECTCE",		"\t%llu ECT-CE sent\n") \
612 	X(QUIC_STATS_RCVECTCE,			"RcvECTCE",		"\t%llu ECT-CE received\n")     \
613 	X(QUIC_STATS_REXMTTIMEOUT,		"ReXmtTimeOut",		"\t%llu retransmit timeout\n")  \
614 	X(QUIC_STATS_KEEPALIVETTIMEOUT,		"KeepAliveTimeOut",	"\t%llu keepalive timeout\n")   \
615 	X(QUIC_STATS_PTO,			"ProbeTimeOut",		"\t%llu probe timeout\n")       \
616         \
617 	X(__QUIC_STATS_MAX,			"",			"end of quic stats\n")
618 
619 #define NETIF_STATS_TABLE(X)                                            \
620 	/* Rx stats */  \
621 	X(NETIF_STATS_RX_PACKETS,		"RxPackets",		"\t%llu total Rx packets\n")    \
622 	X(NETIF_STATS_RX_IRQ,			"RxIRQ",		"\t\t%llu interrupts\n")        \
623 	X(NETIF_STATS_RX_IRQ_MIT,		"RxIRQMIT",		"\t\t\t%llu interrupt mitigation thread wakeup\n")      \
624 	X(NETIF_STATS_RX_IRQ_BUSY,		"RxIRQBusy",		"\t\t\t%llu interrupt notify return busy\n")    \
625 	X(NETIF_STATS_RX_IRQ_AGAIN,		"RxIRQAgain",		"\t\t\t%llu interrupt notify return retry again\n")     \
626 	X(NETIF_STATS_RX_IRQ_ERR,		"RxIRQErr",		"\t\t\t%llu interrupt notify return error\n")   \
627 	X(NETIF_STATS_RX_COPY_SUM,		"RxCopySum",		"\t\t%llu copy+checksumed\n")   \
628 	X(NETIF_STATS_RX_COPY_DIRECT,		"RxCopyDirect",         "\t\t%llu copy from pkt\n")     \
629 	X(NETIF_STATS_RX_COPY_MBUF,		"RxCopyMbuf",		"\t\t%llu copy from mbuf\n")    \
630 	X(NETIF_STATS_RX_COPY_ATTACH,		"RxCopyAttach",         "\t\t%llu copy by attaching mbuf under pkt\n")  \
631 	X(NETIF_STATS_RX_SYNC,			"RxSYNC",		"\t\t%llu sync\n")      \
632         \
633 	/* Tx stats */  \
634 	X(NETIF_STATS_TX_PACKETS,		"TxPkt",		"\t%llu total Tx packets\n")    \
635 	X(NETIF_STATS_TX_IRQ,			"TxIRQ",		"\t\t%llu interupts\n") \
636 	X(NETIF_STATS_TX_IRQ_MIT,		"TxIRQMIT",		"\t\t\t%llu interrupt mitigation thread wakeup\n")      \
637 	X(NETIF_STATS_TX_IRQ_BUSY,		"TxIRQBusy",		"\t\t\t%llu interrupt notify return busy\n")    \
638 	X(NETIF_STATS_TX_IRQ_AGAIN,		"TxIRQAgain",		"\t\t\t%llu interrupt notify return retry again\n")     \
639 	X(NETIF_STATS_TX_IRQ_ERR,		"TxIRQErr",		"\t\t\t%llu interrupt notify return error\n")   \
640 	X(NETIF_STATS_TX_COPY_SUM,		"TxCopySum",		"\t\t%llu copy+checksumed\n")   \
641 	X(NETIF_STATS_TX_COPY_DIRECT,		"TxCopyDirect",		"\t\t%llu copy from pkt\n")     \
642 	X(NETIF_STATS_TX_COPY_MBUF,		"TxCopyMbuf",		"\t\t%llu copy from mbuf\n")    \
643 	X(NETIF_STATS_TX_SYNC,			"TxSYNC",		"\t\t%llu sync\n")      \
644 	X(NETIF_STATS_TX_REPL,			"TxRepl",		"\t\t%llu pool replenished\n")  \
645 	X(NETIF_STATS_TX_DROP_ENQ_AQM,		"TxDropEnqueueAQM",     "\t\t%llu dropped due to AQM enqueue failure\n")        \
646 	X(NETIF_STATS_GSO_SEG,			"GSOSegments",          "\t\t%llu GSO segments created\n") \
647 	X(NETIF_STATS_GSO_PKT,			"GSOPackets",           "\t\t%llu GSO packets \n") \
648 	X(NETIF_STATS_GSO_PKT_DROP_NOMEM,	"GSODropNoMem",         "\t\t%llu GSO packet dropped due to allocation failure\n") \
649 	X(NETIF_STATS_GSO_PKT_DROP_NA_INACTIVE,	"GSODropNaInactive",    "\t\t%llu GSO packet dropped due to inactive netif\n") \
650 	X(NETIF_STATS_GSO_PKT_DROP_BADLEN,	"GSODropBadLen",        "\t\t%llu GSO packet dropped due to bad packet length\n") \
651 	X(NETIF_STATS_GSO_PKT_DROP_NONTCP,	"GSODropNonTcp",        "\t\t%llu GSO packet dropped as it is not a TCP packet\n") \
652         \
653 	X(NETIF_STATS_DROP,			"Drop",			"\t%llu dropped\n")     \
654 	X(NETIF_STATS_DROP_NOMEM_BUF,		"DropNoMemBuf",		"\t\t%llu dropped due to packet alloc failure\n")       \
655 	X(NETIF_STATS_DROP_NOMEM_PKT,		"DropNoMemPkt",		"\t\t%llu dropped due to buflet alloc failure\n")       \
656 	X(NETIF_STATS_DROP_NOMEM_MBUF,		"DropNoMemMbuf",	"\t\t%llu dropped due to mbuf alloc failure\n") \
657 	X(NETIF_STATS_DROP_BADLEN,		"DropBadLen",		"\t\t%llu dropped due to bad packet length\n")  \
658 	X(NETIF_STATS_DROP_NA_INACTIVE,		"DropNaInactive",	"\t\t%llu dropped due to dst na inactive\n")    \
659 	X(NETIF_STATS_DROP_KRDROP_MODE,		"DropKrDropMode",	"\t\t%llu dropped due to dst kring in drop mode\n")     \
660 	X(NETIF_STATS_DROP_RXQ_OVFL,		"DropRxqOverflow",	"\t\t%llu dropped due to RX Queue overflow\n")     \
661 	X(NETIF_STATS_DROP_NO_RX_CB,		"DropNoRxCallback",	"\t\t%llu dropped due to missing RX callback\n") \
662 	X(NETIF_STATS_DROP_NO_DELEGATE,		"DropNoDelegate",	"\t\t%llu dropped due to missing delegate interface\n") \
663 	X(NETIF_STATS_DROP_INPUT_DISABLED,	"DropInputDisabled",	"\t\t%llu dropped due to input disabled on interface\n") \
664         \
665 	/* Channel event stats */  \
666 	X(NETIF_STATS_EV_RECV,			"EvRecv",		"\t%llu channel event received\n")     \
667 	X(NETIF_STATS_EV_RECV_TX_STATUS,	"EvRecvTxStatus",	"\t\t%llu channel event received, TX status\n")     \
668 	X(NETIF_STATS_EV_RECV_TX_EXPIRED,       "EvRecvTxExpired",	"\t\t%llu channel event received, TX expired\n")     \
669 	X(NETIF_STATS_EV_SENT,			"EvSent",		"\t%llu channel event delivered\n")     \
670 	X(NETIF_STATS_EV_DROP,			"EvDrop",		"\t%llu channel event dropped\n")     \
671 	X(NETIF_STATS_EV_DROP_NOMEM_PKT,	"EvDropNoMemPkt",	"\t%llu channel event dropped due to packet alloc failure\n")     \
672 	X(NETIF_STATS_EV_DROP_NA_INACTIVE,	"EvDropNaInactive",	"\t%llu channel event dropped due to na inactive\n")     \
673 	X(NETIF_STATS_EV_DROP_NA_DEFUNCT,	"EvDropNaDefunct",	"\t%llu channel event dropped due to na defunct\n")     \
674 	X(NETIF_STATS_EV_DROP_KRDROP_MODE,	"EvDropKrDropMode",	"\t%llu channel event dropped due to dst kring in drop mode\n")     \
675 	X(NETIF_STATS_EV_DROP_KEVENT_INACTIVE,	"EvDropKevInactive",	"\t%llu channel event dropped due to kevent not registered on channel\n")     \
676 	X(NETIF_STATS_EV_DROP_KRSPACE,		"EvDropKrSpaceDrop",	"\t%llu channel event dropped due to lack of space in user channel ring\n") \
677 	X(NETIF_STATS_EV_DROP_DEMUX_ERR,	"EvDropDemuxErr",	"\t%llu channel event dropped due to demux error\n") \
678 	X(NETIF_STATS_EV_DROP_EV_VPNA_NOTSUP,	"EvDropVpnaEvNotSup",	"\t%llu channel event dropped due to vpna not having event ring\n") \
679 	X(NETIF_STATS_EV_DROP_NO_VPNA,		"EvDropNoVpna",		"\t%llu channel event dropped due to no vpna ports\n") \
680         \
681 	/* Interface advisory update stats */  \
682 	X(NETIF_STATS_IF_ADV_UPD_RECV,		"IfAdvUpdRecv",		"\t%llu interface advisory update received\n") \
683 	X(NETIF_STATS_IF_ADV_UPD_SENT,		"IfAdvUpdSent",		"\t%llu interface advisory update event sent\n") \
684 	X(NETIF_STATS_IF_ADV_UPD_DROP,		"IfAdvUpdDrop",		"\t%llu interface advisory update event dropped\n") \
685         \
686 	/* Interface filter stats */ \
687 	X(NETIF_STATS_FILTER_DROP_NO_RX_CB,	"FilterDropNoRxCB",	"\t%llu dropped due to missing RX callback\n") \
688 	X(NETIF_STATS_FILTER_DROP_DISABLED,	"FilterDropDisabled",	"\t%llu dropped due to disabled filter\n") \
689 	X(NETIF_STATS_FILTER_DROP_REMOVED,	"FilterDropRemoved",	"\t%llu dropped due to removed filter\n") \
690 	X(NETIF_STATS_FILTER_DROP_PKTQ_FULL,	"FilterDropPktqFull",	"\t%llu dropped due to packet queue full\n") \
691 	X(NETIF_STATS_FILTER_DROP_MBQ_FULL,	"FilterDropMbqFull",	"\t%llu dropped due to mbuf queue full\n") \
692 	X(NETIF_STATS_FILTER_DROP_DISABLED_RING,"FilterDropDisabledRing","\t%llu dropped due to disabled ring\n") \
693 	X(NETIF_STATS_FILTER_DROP_NO_SPACE,	"FilterDropNoSpace",	"\t%llu dropped due to lack of space in RX ring\n") \
694 	X(NETIF_STATS_FILTER_DROP_INTERNALIZE,	"FilterDropInternalize","\t%llu dropped due to internalize failure\n") \
695 	X(NETIF_STATS_FILTER_DROP_PKT_ALLOC_FAIL,"FilterDropPktAllocFail","\t%llu dropped due to packet allocation failure\n") \
696 	X(NETIF_STATS_FILTER_DROP_DEFAULT,	"FilterDropDefault",	"\t%llu dropped due to default drop policy\n") \
697 	X(NETIF_STATS_FILTER_PKT_TRUNCATED,	"FilterPktTruncated",	"\t%llu inbound packets truncated\n") \
698 	X(NETIF_STATS_FILTER_TX_DELIVER,	"FilterTxDeliver",	"\t%llu outbound packets delivered to filter\n") \
699 	X(NETIF_STATS_FILTER_RX_DELIVER,	"FilterRxDeliver",	"\t%llu inbound packets delivered to filter\n") \
700 	X(NETIF_STATS_FILTER_TX_INJECT,		"FilterTxInject",	"\t%llu outbound packets injected by filter\n") \
701 	X(NETIF_STATS_FILTER_RX_INJECT,		"FilterRxInject",	"\t%llu inbound packets injected by filter\n") \
702 	X(NETIF_STATS_FILTER_TX_ENTER,		"FilterTxEnter",	"\t%llu outbound packets entered the filter chain\n") \
703 	X(NETIF_STATS_FILTER_RX_ENTER,		"FilterRxEnter",	"\t%llu inbound packets entered the filter chain\n") \
704 	X(NETIF_STATS_FILTER_TX_EXIT,		"FilterTxExit",		"\t%llu outbound packets exited the filter chain\n") \
705 	X(NETIF_STATS_FILTER_RX_EXIT,		"FilterRxExit",		"\t%llu inbound packets exited the filter chain\n") \
706 	X(NETIF_STATS_FILTER_SYNC_NO_PKTS,	"FilterSyncNoPkts",	"\t%llu filter syncs called with an empty ring\n") \
707 	X(NETIF_STATS_FILTER_ADD,		"FilterAdd",		"\t%llu filters added\n") \
708 	X(NETIF_STATS_FILTER_REMOVE,		"FilterRemove",		"\t%llu filters removed\n") \
709 	X(NETIF_STATS_FILTER_TX_FLUSH,		"FilterTxFlush",	"\t%llu TX packets flushed due to closing filters\n") \
710 	X(NETIF_STATS_FILTER_RX_NOT_FILTERABLE,	"FilterRxNotFilterable","\t%llu RX packets not filterable\n") \
711 	X(NETIF_STATS_FILTER_BAD_PKT_LEN,	"FilterBadPktLen",	"\t%llu invalid packet length\n") \
712         \
713 	/* Custom ether and sidecar stats */ \
714 	X(NETIF_STATS_VP_DROP_USER_RING_DISABLED,"VPDropUserRingDisabled","\t%llu dropped due to disabled user ring\n") \
715 	X(NETIF_STATS_VP_DROP_DEV_RING_DISABLED,"VPDropDevRingDisabled","\t%llu dropped due to disabled device ring\n") \
716 	X(NETIF_STATS_VP_DROP_USER_RING_NO_SPACE,"VPDropUserRingNoSpace","\t%llu dropped due to lack of user ring space\n") \
717 	X(NETIF_STATS_VP_DROP_DEV_RING_NO_SPACE,"VPDropDevRingNoSpace",	"\t%llu dropped due to lack of device ring space\n") \
718 	X(NETIF_STATS_VP_DROP_RX_ALLOC_FAIL,	"VPDropRxAllocFail",	"\t%llu dropped due to RX allocation failure\n") \
719 	X(NETIF_STATS_VP_DROP_TX_ALLOC_FAIL,	"VPDropTxAllocFail",	"\t%llu dropped due to TX allocation failure\n") \
720 	X(NETIF_STATS_VP_DROP_PKT_TOO_BIG,	"VPDropPktTooBig",	"\t%llu dropped due to packet being too big\n") \
721 	X(NETIF_STATS_VP_DROP_INTERNALIZE_FAIL,	"VPDropInternalizeFail","\t%llu dropped due to internalize failure\n") \
722 	X(NETIF_STATS_VP_DROP_UNEXPECTED_ERR,	"VPDropUnexpectedErr",	"\t%llu dropped due to unexpected TX sync error\n") \
723 	X(NETIF_STATS_VP_BAD_MADDR_LEN,		"VPBadMaddrLen",	"\t%llu packets with invalid mac address length\n") \
724 	X(NETIF_STATS_VP_BAD_MADDR,		"VPBadMaddr",		"\t%llu packets with invalid mac address\n") \
725 	X(NETIF_STATS_VP_BAD_PKT_LEN,		"VPBadPktLen",		"\t%llu packets invalid packet length\n") \
726 	X(NETIF_STATS_VP_FLOW_INFO_ERR,		"VPFlowInfoErr",	"\t%llu packets cannot be classified due to flow info error\n") \
727 	X(NETIF_STATS_VP_FLOW_NOT_MATCH,	"VPFlowNotMatch",	"\t%llu packets not matching flow description\n") \
728 	X(NETIF_STATS_VP_KR_ENTER_FAIL,		"VPKrEnterFail",	"\t%llu failed attempts to acquire RX ring lock\n") \
729 	X(NETIF_STATS_VP_DEV_RING_DISABLED,	"VPDevRingDisabled",	"\t%llu failed attempts to get packets due to disabled dev ring\n") \
730 	X(NETIF_STATS_VP_SYNC_UNKNOWN_ERR,	"VPSyncUnknownErr",	"\t%llu unknown errors returned by RX sync\n") \
731 	X(NETIF_STATS_VP_SYNC_NO_PKTS,		"VPSyncNoPkts",		"\t%llu syncs called with an empty ring\n") \
732 	X(NETIF_STATS_VP_SPURIOUS_NOTIFY,	"VPSpuriousNotify",	"\t%llu spurious notifies delivered\n") \
733 	X(NETIF_STATS_VP_ENQUEUE_FAILED,	"VPEnqueueFailed",	"\t%llu packets failed to enqueue\n") \
734 	X(NETIF_STATS_VP_ENQUEUED,		"VPEnqueued",		"\t%llu packets enqueued\n") \
735 	X(NETIF_STATS_VP_LL_ENQUEUED,		"VPLLEnqueued",		"\t%llu low latency packets enqueued\n") \
736 	X(NETIF_STATS_VP_LL_SENT,		"VPLLSent",		"\t%llu low latency packets sent\n") \
737 	X(NETIF_STATS_VP_LL_DELIVERED,		"VPLLDelivered",	"\t%llu low latency packets delivered\n") \
738 	X(NETIF_STATS_VP_DELIVERED,		"VPDelivered",		"\t%llu packets delivered\n") \
739 	X(NETIF_STATS_VP_FLOW_FOUND,		"VPFlowFound",		"\t%llu packets found a matching flow\n") \
740 	X(NETIF_STATS_VP_FLOW_NOT_FOUND,	"VPFlowNotFound",	"\t%llu packets found no matching flow\n") \
741 	X(NETIF_STATS_VP_FLOW_DISABLED,		"VPFlowDisabled",	"\t%llu lookup failures due to disabled flow\n") \
742 	X(NETIF_STATS_VP_FLOW_EMPTY_TABLE,	"VPFlowEmptyTable",	"\t%llu lookup failures due to empty flow table\n") \
743 	X(NETIF_STATS_VP_FLOW_TABLE_INIT_FAIL,	"VPFlowTableInitFail",	"\t%llu failed attempts to initialize flow table\n") \
744 	X(NETIF_STATS_VP_FLOW_INSERT_FAIL,	"VPFlowInsertFail",	"\t%llu failed attempts to insert flow\n") \
745 	X(NETIF_STATS_VP_FLOW_ADD,		"VPFlowAdd",		"\t%llu flows added\n") \
746 	X(NETIF_STATS_VP_FLOW_REMOVE,		"VPFlowRemove",		"\t%llu flows removed\n") \
747         \
748 	/* Netif agent stats */ \
749 	X(NETIF_STATS_AGENT_BAD_ETHERTYPE,	"AgentBadEthertype",	"\t%llu flow add failures due to invalid ethertype\n") \
750 	X(NETIF_STATS_AGENT_BAD_IPV6_ADDR,	"AgentBadIPv6Addr",	"\t%llu flow add failures due to invalid IPv6 address\n") \
751 	X(NETIF_STATS_AGENT_DUP_FLOW,		"AgentDupFlow",		"\t%llu duplicate flows added\n") \
752         \
753 	/* Netif llink stats */ \
754 	X(NETIF_STATS_LLINK_ADD,		"LLinkAdd",		"\t%llu logical links added\n") \
755 	X(NETIF_STATS_LLINK_REMOVE,		"LLinkRemove",		"\t%llu logical links removed\n") \
756 	X(NETIF_STATS_LLINK_DEF_QSET_USED,	"LLinkDefQSetUsed",	"\t%llu uses of the default qset\n") \
757 	X(NETIF_STATS_LLINK_NONDEF_QSET_USED,	"LLinkNonDefQSetUsed",	"\t%llu uses of a non-default qset\n") \
758 	X(NETIF_STATS_LLINK_HINT_NOT_USEFUL,	"LLinkHintNotUseful",	"\t%llu hints specified but qset not found\n") \
759 	X(NETIF_STATS_LLINK_DUP_INT_ID_GENERATED, "LLinkDupIntIDGenerated", "\t%llu duplicate internal llink IDs generated\n") \
760 	X(NETIF_STATS_LLINK_DUP_ID_GIVEN,	"LLinkDupIDGiven",	"\t%llu duplicate llink IDs given by the provider\n") \
761 	X(NETIF_STATS_LLINK_QSET_INIT_FAIL,	"LLinkQSetInitFail",	"\t%llu queue set initialization failures\n") \
762 	X(NETIF_STATS_LLINK_RXQ_INIT_FAIL,	"LLinkRXQInitFail",	"\t%llu RX queue initialization failures\n") \
763 	X(NETIF_STATS_LLINK_TXQ_INIT_FAIL,	"LLinkTXQInitFail",	"\t%llu TX queue initialization failures\n") \
764 	X(NETIF_STATS_LLINK_NOT_FOUND_REMOVE,	"LLinkNotFoundRemove",	"\t%llu not found during remove\n") \
765 	X(NETIF_STATS_LLINK_TX_DROP_BAD_STATE,	"LLinkTxDroppedBadState", "\t%llu TX packets dropped due to bad llink state\n") \
766 	X(NETIF_STATS_LLINK_RX_DROP_BAD_STATE,	"LLinkRxDroppedBadState", "\t%llu RX packets dropped due to bad llink state\n") \
767 	X(NETIF_STATS_LLINK_AQM_QFULL,		"LLinkAQMQFull",	"\t%llu occurances of the queue full condition\n") \
768 	X(NETIF_STATS_LLINK_AQM_DROPPED,	"LLinkAQMDropped",	"\t%llu packets dropped due to AQM\n") \
769 	X(NETIF_STATS_LLINK_AQM_DEQ_BAD_STATE,	"LLinkAQMDeqBadState",	"\t%llu dequeues occurred while llink is in a bad state\n") \
770 	X(NETIF_STATS_LLINK_QSET_BAD_STATE,	"LLinkQSetAccessBadState", "\t%llu attempts to access a queue set while in bad llink state\n") \
771 	X(NETIF_STATS_LLINK_ADD_BAD_PARAMS,	"LLinkAddBadParams",	"\t%llu attempts to add an llink with bad parameters\n") \
772         \
773 	X(__NETIF_STATS_MAX,			"",			"end of netif stats")
774 
775 #define FSW_FPD_STATS(X)        \
776 	X(FSW_STATS_FPD_0,			"",	"\t%llu")       \
777 	X(FSW_STATS_FPD_1,			"",	"\t%llu")       \
778 	X(FSW_STATS_FPD_2,			"",	"\t%llu")       \
779 	X(FSW_STATS_FPD_3,			"",	"\t%llu")       \
780 	X(FSW_STATS_FPD_4,			"",	"\t%llu")       \
781 	X(FSW_STATS_FPD_5,			"",	"\t%llu")       \
782 	X(FSW_STATS_FPD_6,			"",	"\t%llu")       \
783 	X(FSW_STATS_FPD_7,			"",	"\t%llu")       \
784 	X(FSW_STATS_FPD_8,			"",	"\t%llu")       \
785 	X(FSW_STATS_FPD_9,			"",	"\t%llu")       \
786 	X(FSW_STATS_FPD_10,		        "",	"\t%llu")       \
787 	X(FSW_STATS_FPD_11,			"",	"\t%llu")
788 
789 #define FSW_STATS_TABLE(X)                                      \
790 	/* Rx stats */  \
791 	X(FSW_STATS_RX_PACKETS,			"RxPackets",		"\t%llu total Rx packet\n")     \
792 	X(FSW_STATS_RX_DEMUX_ERR,		"RxDemuxErr",		"\t\t%llu demux error (passed to BSD)\n")       \
793 	X(FSW_STATS_RX_DEMUX_UNSPEC,		"RxDemuxUnspec",	"\t\t%llu demux AF unkown (passed to BSD)\n")       \
794 	X(FSW_STATS_RX_DEMUX_PROMISC,		"RxDemuxPromisc",	"\t\t%llu promiscuous packets (passed to BSD)\n")  \
795 	X(FSW_STATS_RX_FLOW_EXTRACT_ERR,	"RxFlowExtractErr",	"\t\t%llu flow extract error (passed to BSD)\n")       \
796 	X(FSW_STATS_RX_PKT_NOT_FINALIZED,	"RxPktNotFinalized",	"\t\t%llu packet not finalized\n")  \
797 	X(FSW_STATS_RX_FLOW_NOT_FOUND,		"RxFlowNotFound",	"\t\t%llu dropped, flow lookup failure\n")        \
798 	X(FSW_STATS_RX_FLOW_TRACK_ERR,		"RxFlowTrackErr",	"\t\t%llu dropped, flow tracker error\n") \
799 	X(FSW_STATS_RX_FLOW_NONVIABLE,		"RxFlowNonviable",	"\t\t%llu dropped, flow already nonviable\n") \
800 	X(FSW_STATS_RX_FLOW_TORNDOWN,		"RxFlowTornDown",	"\t\t%llu dropped, flow already torndown\n")      \
801 	X(FSW_STATS_RX_DST_RING_FULL,		"RxDstRingFull",	"\t\t%llu dropped, destination ring full\n") \
802 	X(FSW_STATS_RX_COPY_PKT2PKT,		"RxCopyPktToPkt",	"\t\t%llu copied pkt  -> pkt\n")        \
803 	X(FSW_STATS_RX_COPY_PKT2MBUF,		"RxCopyPktToMbuf",	"\t\t%llu copied pkt  -> mbuf\n")       \
804 	X(FSW_STATS_RX_COPY_MBUF2PKT,		"RxCopyMbufToPkt",	"\t\t%llu copied mbuf -> pkt\n")        \
805 	X(FSW_STATS_RX_COPY_SUM,		"RxCopySum",		"\t\t%llu copy+checksumed\n")   \
806 	X(FSW_STATS_RX_COPY_BAD_LEN,		"RxCopyBadLen",		"\t\t%llu dropped, bad packet length\n")  \
807 	X(FSW_STATS_RX_DROP_NOMEM_BUF,		"RxDropNoMemBuf",	"\t\t%llu dropped due to mbuf alloc failure\n") \
808 	X(FSW_STATS_RX_DEMUX_SHORT_ERR,		"RxDemuxShortErr",	"\t\t%llu demux failed, classify length short\n") \
809 	X(FSW_STATS_RX_WASTED_16KMBUF,		 "RxWasted16KMbuf",	"\t\t%llu wasted an entire pre-allocated 16K mbuf\n") \
810 	X(FSW_STATS_RX_PKT_NOT_LISTENER,	"RxPktNotListener",	"\t\t%llu packet not for listener\n") \
811 	X(FSW_STATS_RX_FLOW_IN_USE,		    "RxFlowInUse",	"\t\t%llu flow in use\n") \
812 	X(FSW_STATS_RX_STALL,                    "RxRingStall",         "\t\t%llu Rx rings stalled\n") \
813 	X(FSW_STATS_RX_DISABLED,                 "RxDisabled",          "\t\t%llu dropped, flow Rx disabled\n") \
814 	/* Rx frag stats (fsw doesn't manage fragments on Tx) */        \
815 	X(FSW_STATS_RX_FRAG_V4,			"RxFragV4",		"\t\t%llu total received ipv4 fragments\n")     \
816 	X(FSW_STATS_RX_FRAG_V6,			"RxFragV6",		"\t\t%llu total received ipv6 fragments\n")     \
817 	X(FSW_STATS_RX_FRAG_REASSED,		"RxFragReassed",	"\t\t\t%llu frag successfully reassembled\n")   \
818 	X(FSW_STATS_RX_FRAG_DROP_NOSLOT,	"RxFragDropNoSlot",	"\t\t\t%llu dropped no slot in dring\n")        \
819 	X(FSW_STATS_RX_FRAG_BAD,		"RxFragBad",		"\t\t\t%llu dropped due to bad fragments\n")    \
820 	X(FSW_STATS_RX_FRAG_DROP_BAD_LEN,	"RxFragBadLen",		"\t\t\t%llu dropped due to bad fragment length\n")      \
821 	X(FSW_STATS_RX_FRAG_DROP_NOMEM,		"RxFragNoMem",		"\t\t\t%llu dropped due to no memory\n")        \
822 	X(FSW_STATS_RX_FRAG_DROP_TIMEOUT,	"RxFragTimeOut",	"\t\t\t%llu dropped due to time out\n") \
823 	X(FSW_STATS_RX_FRAG_DROP_FRAG_LIMIT,	"RxFragHitFragLimit",	"\t\t\t%llu dropped due to ipf max limit\n")    \
824 	X(FSW_STATS_RX_FRAG_DROP_REAPED,	"RxFragDrained",	"\t\t\t%llu dropped due to draining\n") \
825 	X(FSW_STATS_RX_FRAG_DROP_PER_QUEUE_LIMIT,"RxFragHitPerQueueLimit","\t\t\t%llu dropped due to ipf max per queue limit\n")        \
826 	/* Rx aggregation stats */                                      \
827 	X(FSW_STATS_RX_AGG_PKT2PKT,             "RxAggPktToPkt",        "\t\t%llu aggregated pkt  -> super pkt\n")             \
828 	X(FSW_STATS_RX_AGG_PKT2MBUF,            "RxAggPktToMbuf",       "\t\t%llu aggregated pkt  -> super mbuf\n")          \
829 	X(FSW_STATS_RX_AGG_MBUF2PKT,            "RxAggMbufToPkt",       "\t\t%llu aggregated mbuf  -> super pkt\n")          \
830 	X(FSW_STATS_RX_AGG_MBUF2MBUF,           "RxAggMbufToMbuf",      "\t\t%llu aggregated mbuf  -> super mbuf\n")       \
831 	X(FSW_STATS_RX_AGG_LIMIT,               "RxAggHitAggLimit",     "\t\t%llu reached aggregation limit\n") \
832 	X(FSW_STATS_RX_AGG_NO_HLEN_IP,          "RxAggNoHdrLenIP",      "\t\t%llu IP header length compare mismatch\n") \
833 	X(FSW_STATS_RX_AGG_NO_TTL_IP,           "RxAggNoTTLIP",         "\t\t%llu IP TTL compare mismatch\n") \
834 	X(FSW_STATS_RX_AGG_NO_TOS_IP,           "RxAggNoTOSIP",         "\t\t%llu IP TOS compare mismatch\n") \
835 	X(FSW_STATS_RX_AGG_NO_OFF_IP,           "RxAggNoOffsetIP",      "\t\t%llu IP offset compare mismatch\n") \
836 	X(FSW_STATS_RX_AGG_NO_OPT_IP,           "RxAggNoOptionIP",      "\t\t%llu IP option compare mismatch\n") \
837 	X(FSW_STATS_RX_AGG_MERGE_FASTPATH_IP,   "RxAggMergeFastpathIP", "\t\t%llu IP header merge via fastpath\n") \
838 	X(FSW_STATS_RX_AGG_MERGE_SLOWPATH_IP,   "RxAggMergeSlowpathIP", "\t\t%llu IP header merge via slowpath\n") \
839 	X(FSW_STATS_RX_AGG_MERGE_FASTPATH_TCP,  "RxAggMergeFastpathTCP", "\t\t%llu TCP header merge via fastpath\n") \
840 	X(FSW_STATS_RX_AGG_MERGE_SLOWPATH_TCP,  "RxAggMergeSlowpathTCP", "\t\t%llu TCP header merge via slowpath\n") \
841 	X(FSW_STATS_RX_AGG_OK_FASTPATH_TCP,     "RxAggFastpathTCP",     "\t\t%llu TCP aggregation via fastpath\n") \
842 	X(FSW_STATS_RX_AGG_OK_SLOWPATH_TCP,     "RxAggSlowpathTCP",     "\t\t%llu TCP aggregation via slowpath\n") \
843 	X(FSW_STATS_RX_AGG_NO_SHORT_TCP,        "RxAggNoShortTCP",      "\t\t%llu TCP packet too short for mask compare\n") \
844 	X(FSW_STATS_RX_AGG_NO_MASK_TCP,         "RxAggNoMaskTCP",       "\t\t%llu TCP mask compare mismatch\n") \
845 	X(FSW_STATS_RX_AGG_NO_HLEN_TCP,         "RxAggNoHdrLenTCP",     "\t\t%llu TCP header length compare mismatch\n") \
846 	X(FSW_STATS_RX_AGG_NO_ULEN_TCP,         "RxAggNoULenTCP",       "\t\t%llu TCP ulength compare mismatch\n") \
847 	X(FSW_STATS_RX_AGG_NO_SEQN_TCP,         "RxAggNoSeqNTCP",       "\t\t%llu TCP sequence number compare mismatch\n") \
848 	X(FSW_STATS_RX_AGG_NO_ACKWIN_TCP,       "RxAggNoAckWinTCP",     "\t\t%llu TCP ACK or window compare mismatch\n") \
849 	X(FSW_STATS_RX_AGG_NO_FLAGS_TCP,        "RxAggNoFlagsTCP",      "\t\t%llu TCP flags compare mismatch\n") \
850 	X(FSW_STATS_RX_AGG_NO_EXOPT_TCP,        "RxAggNoExtraOptionTCP",  "\t\t%llu TCP extra option compare mismatch\n") \
851 	X(FSW_STATS_RX_AGG_NO_OPTTS_TCP,        "RxAggNoOptionTStampTCP", "\t\t%llu TCP timestamp option compare mismatch\n") \
852 	X(FSW_STATS_RX_AGG_BAD_CSUM,            "RxAggIncorrectChecksum", "\t\t%llu Incorrect TCP/IP checksum\n") \
853 	X(FSW_STATS_RX_AGG_NO_SHORT_MBUF,       "RxAggNoShortMbuf",      "\t\t%llu mbuf too short for mask compare\n") \
854 	X(FSW_STATS_RX_WASTED_MBUF,                     "RxAggWastedMbuf",      "\t\t%llu wasted pre-allocate mbufs\n") \
855 	X(FSW_STATS_RX_WASTED_BFLT,                     "RxAggWastedBflt",      "\t\t%llu wasted pre-allocate buflets\n") \
856         \
857 	/* Tx stats */  \
858 	X(FSW_STATS_TX_PACKETS,			"TXPackets",		"\t%llu total Tx packets\n")    \
859 	X(FSW_STATS_TX_DEMUX_ERR,		"TxDemuxErr",		"\t\t%llu dropped, demux error\n")        \
860 	X(FSW_STATS_TX_FLOW_EXTRACT_ERR,	"TxFlowExtractErr",	"\t\t%llu dropped, flow extract error\n") \
861 	X(FSW_STATS_TX_FRAG_BAD_ID,		"TxFragID",		"\t\t%llu dropped, invalid fragment ID\n")    \
862 	X(FSW_STATS_TX_FRAG_BAD_CONT,		"TxContFrag",		"\t\t%llu dropped, invalid continuation fragment\n")    \
863 	X(FSW_STATS_TX_FLOW_NOT_FOUND,		"TxFlowNotFound",	"\t\t%llu dropped, flow lookup failure\n")        \
864 	X(FSW_STATS_TX_FLOW_TRACK_ERR,		"TxFlowTrackErr",	"\t\t%llu dropped, flow tracker error\n") \
865 	X(FSW_STATS_TX_FLOW_BAD_ID,		"TxFLowBadID",		"\t\t%llu dropped, flow id invalid\n") \
866 	X(FSW_STATS_TX_FLOW_NONVIABLE,		"TxFlowNonviable",	"\t\t%llu dropped, flow already nonviable\n") \
867 	X(FSW_STATS_TX_FLOW_TORNDOWN,		"TxFlowTornDown",	"\t\t%llu dropped, flow already torndown\n") \
868 	X(FSW_STATS_TX_BAD_LISTENER,		"TxBadListener",	"\t\t%llu dropped, flow as listener only\n")      \
869 	X(FSW_STATS_TX_AQM_DROP,		"TxAQMDrop",		"\t\t%llu dropped, AQM enqueue failure\n")        \
870 	X(FSW_STATS_TX_RESOLV_PENDING,		"TxResolvePending",	"\t\t%llu pending resolve\n")   \
871 	X(FSW_STATS_TX_RESOLV_FAIL,		"TxResolveFail",	"\t\t%llu dropped due to resolution failure\n") \
872 	X(FSW_STATS_TX_RESOLV_STALE,		"TxResolveStale",	"\t\t%llu resolved using existing info\n")      \
873 	X(FSW_STATS_TX_COPY_PKT2PKT,		"TxCopyPktToPkt",	"\t\t%llu copied pkt  ->  pkt\n")       \
874 	X(FSW_STATS_TX_COPY_PKT2MBUF,		"TxCopyPktToMbuf",	"\t\t%llu copied pkt  ->  mbuf\n")      \
875 	X(FSW_STATS_TX_COPY_SUM,		"TxCopySum",		"\t\t%llu copy+checksumed\n")   \
876 	X(FSW_STATS_TX_COPY_BAD_LEN,		"TxCopyBadLen",		"\t\t%llu dropped, bad packet length\n")  \
877 	X(FSW_STATS_TX_DISABLED,		"TxDisabled",		"\t\t%llu dropped, flow tx disabled\n")  \
878         \
879 	/* Drop stats (generic bidirectional) */ \
880 	X(FSW_STATS_DROP,			"Drop",			"\t%llu total dropped\n")       \
881 	X(FSW_STATS_DROP_NOMEM_PKT,		"DropNoMemPkt",		"\t\t%llu dropped, packet alloc failure\n")       \
882 	X(FSW_STATS_DROP_NOMEM_MBUF,		"DropNoMemMbuf",	"\t\t%llu dropped, mbuf alloc failure\n") \
883         \
884 	/* Channel event stats */  \
885 	X(FSW_STATS_EV_RECV,			"EvRecv",		"\t%llu channel event received\n")     \
886 	X(FSW_STATS_EV_RECV_TX_STATUS,		"EvRecvTxStatus",	"\t\t%llu channel event received, TX status\n")     \
887 	X(FSW_STATS_EV_RECV_TX_EXPIRED,		"EvRecvTxExpired",	"\t\t%llu channel event received, TX expired\n")     \
888 	X(FSW_STATS_EV_SENT,			"EvSent",		"\t%llu channel event delivered\n")     \
889 	X(FSW_STATS_EV_DROP,			"EvDrop",		"\t%llu channel event dropped\n")     \
890 	X(FSW_STATS_EV_DROP_NOMEM_PKT,	"EvDropNoMemPkt",	"\t%llu channel event dropped due to packet alloc failure\n")     \
891 	X(FSW_STATS_EV_DROP_NA_INACTIVE,	"EvDropNaInactive",	"\t%llu channel event dropped due to na inactive\n")     \
892 	X(FSW_STATS_EV_DROP_NA_DEFUNCT,	"EvDropNaDefunct",	"\t%llu channel event dropped due to na defunct\n")     \
893 	X(FSW_STATS_EV_DROP_KRDROP_MODE,	"EvDropKrDropMode",	"\t%llu channel event dropped due to dst kring in drop mode\n")     \
894 	X(FSW_STATS_EV_DROP_KEVENT_INACTIVE,	"EvDropKevInactive",	"\t%llu channel event dropped due to kevent not registered on channel\n")     \
895 	X(FSW_STATS_EV_DROP_KRSPACE,		"EvDropKrSpaceDrop",	"\t%llu channel event dropped due to lack of space in user channel ring\n") \
896 	X(FSW_STATS_EV_DROP_DEMUX_ERR,	"EvDropDemuxErr",	"\t%llu channel event dropped due to demux error\n") \
897 	X(FSW_STATS_EV_DROP_EV_VPNA_NOTSUP,	"EvDropVpnaEvNotSup",	"\t%llu channel event dropped due to vpna not having event ring\n") \
898 	/* Misc. stats */ \
899 	X(FSW_STATS_FLOWS_ABORTED,		"FlowsAborted",		"\t%llu flow aborted\n")        \
900 	X(FSW_STATS_DST_NXPORT_INVALID,		"DestNexusPortInvalid", "\t%llu times dst nexus port invalid\n")        \
901 	X(FSW_STATS_DST_NXPORT_INACTIVE,	"DestNexusPortInactive","\t%llu times dst nexus port inactive\n")       \
902 	X(FSW_STATS_DST_NXPORT_DEFUNCT,		"DestNexusPortDefunct", "\t%llu times dst nexus port defunct\n")        \
903 	X(FSW_STATS_DST_RING_DROPMODE,		"DestRingDropMode",	"\t\t%llu dropped, dst kring in drop mode\n")     \
904 	X(FSW_STATS_CHAN_ERR_UPP_ALLOC,		"ChanErrUppAlloc",	"\t%llu user packet pool alloc failure\n")      \
905 	X(FSW_STATS_CHAN_DEFUNCT_SKIP,		"ChanDefunctSkipped",	"\t%llu defunct skipped due to outstanding packets\n")  \
906         \
907 	X(_FSW_STATS_ERROR_INJECTIONS,		"_ErrorInjections",	"(\t%llu errors injected)\n")  \
908 	X(FSW_STATS_IF_ADV_UPD_SENT,		"IfAdvUpdSent",		"\t%llu interface advisory update event sent\n") \
909         \
910 	X(FSW_STATS_IF_ADV_UPD_DROP,		"IfAdvUpdDrop",		"\t%llu interface advisory update event dropped\n") \
911         \
912 	/* FPD stats */ \
913 	FSW_FPD_STATS(X)        \
914         \
915 	/* Rx Flow Steering stats */  \
916 	X(FSW_STATS_RX_FS_ADD_SUCCESS,		"RxFSAddSuccess",	"\t%llu rx flow steering add success\n") \
917 	X(FSW_STATS_RX_FS_REMOVE_SUCCESS,	"RxFSRemoveSuccess",	"\t%llu rx flow steering remove success\n") \
918 	X(FSW_STATS_RX_FS_ADD_FAILURE,		"RxFSAddFailure",	"\t%llu rx flow steering add failure\n") \
919 	X(FSW_STATS_RX_FS_REMOVE_FAILURE,	"RxFSRemoveFailure",	"\t%llu rx flow steering remove failure\n") \
920 	X(FSW_STATS_RX_FS_REMOVE_SKIPPED,	"RxFSRemoveSkipped",	"\t%llu rx flow steering remove skipped\n") \
921         \
922 	X(__FSW_STATS_MAX, "", "end of flowswitch stats")
923 
924 /* END CSTYLED */
925 
926 /*
927  * Common stats operation and macro
928  */
929 #define EXPAND_TO_ENUMERATION(a, b, c) a,
930 #define EXPAND_TO_STRING(a, b, c) b,
931 #define EXPAND_TO_FORMAT(a, b, c) c,
932 
933 #define DEFINE_STATS_STR_FUNC(type, table)                      \
934 __attribute__((always_inline))                                  \
935 static inline const char *                                      \
936 type##_str(enum _##type value)                                  \
937 {                                                               \
938 	static const char *table[] = {                          \
939 	    table(EXPAND_TO_STRING)                             \
940 	};                                                      \
941 	return (table[value]);                                  \
942 }
943 
944 #define DEFINE_STATS_FMT_FUNC(type, table)                      \
945 __attribute__((always_inline))                                  \
946 static inline const char *                                      \
947 type##_fmt(enum _##type value)                                  \
948 {                                                               \
949 	static const char *table[] = {                          \
950 	    table(EXPAND_TO_FORMAT)                             \
951 	};                                                      \
952 	return (table[value]);                                  \
953 }
954 
955 #define STATS_VAL(s_ptr, t) ((s_ptr)->_arr[(t)])
956 #define STATS_INC(s_ptr, t) ((s_ptr)->_arr[(t)]++)
957 #define STATS_DEC(s_ptr, t) ((s_ptr)->_arr[(t)]--)
958 #define STATS_ADD(s_ptr, t, v) ((s_ptr)->_arr[(t)] += (v))
959 
960 static inline void __attribute__((always_inline))
__stats_fold(uint64_t * __counted_by (len)dst,uint64_t * __counted_by (len)src,size_t len)961 __stats_fold(uint64_t *__counted_by(len)dst, uint64_t *__counted_by(len)src, size_t len)
962 {
963 	// TODO replace with vector instruction once veclib is ready for xnu
964 	size_t i;
965 	for (i = 0; i < len; i++) {
966 		dst[i] += src[i];
967 	}
968 }
969 
970 #define DEFINE_STATS_FOLD_FUNC(type, len)               \
971 static inline void __attribute__((always_inline))       \
972 type##_fold(struct type *dst, struct type *src)         \
973 {                                                       \
974 	__stats_fold(dst->_arr, src->_arr, len);        \
975 }
976 
977 static inline void __attribute__((always_inline))
__stats_reset(uint64_t * __counted_by (len)_arr,size_t len)978 __stats_reset(uint64_t *__counted_by(len)_arr, size_t len)
979 {
980 	// TODO replace with vector instruction once veclib is ready for xnu
981 	size_t i;
982 	for (i = 0; i < len; i++) {
983 		_arr[i] = 0;
984 	}
985 }
986 
987 #define DEFINE_STATS_RESET_FUNC(type, len)              \
988 static inline void __attribute__((always_inline))       \
989 type##_reset(struct type *s)                            \
990 {                                                       \
991 	__stats_reset(s->_arr, len);                    \
992 }
993 
994 #define STATS_ALIGN 16  /* align for vector instruction */
995 
996 #define STATS_REGISTER(name, NAME)                      \
997 enum _##name { NAME##_TABLE(EXPAND_TO_ENUMERATION) };   \
998 struct name {                                           \
999 	uint64_t	_arr[__##NAME##_MAX];           \
1000 } __attribute__((aligned(STATS_ALIGN)));                \
1001 DEFINE_STATS_STR_FUNC(name, NAME##_TABLE)               \
1002 DEFINE_STATS_FMT_FUNC(name, NAME##_TABLE)               \
1003 DEFINE_STATS_FOLD_FUNC(name, __##NAME##_MAX)            \
1004 DEFINE_STATS_RESET_FUNC(name, __##NAME##_MAX)
1005 
1006 /* Stats registration stub */
1007 STATS_REGISTER(ip_stats, IP_STATS);
1008 STATS_REGISTER(ip6_stats, IP6_STATS);
1009 STATS_REGISTER(tcp_stats, TCP_STATS);
1010 STATS_REGISTER(udp_stats, UDP_STATS);
1011 STATS_REGISTER(quic_stats, QUIC_STATS);
1012 
1013 STATS_REGISTER(fsw_stats, FSW_STATS);
1014 STATS_REGISTER(netif_stats, NETIF_STATS);
1015 
1016 #undef  STATS_REGISTER
1017 #undef  DEFINE_STATS_RESET_FUNC
1018 #undef  DEFINE_STATS_FOLD_FUNC
1019 #undef  DEFINE_STATS_RESET_FUNC
1020 #undef  DEFINE_STATS_FOLD_FUNC
1021 #undef  DEFINE_STATS_STR_FUNC
1022 #undef  DEFINE_STATS_STR_FUNC
1023 #undef  EXPAND_TO_STRING
1024 #undef  EXPAND_TO_ENUMERATION
1025 
1026 /*
1027  * Channel/Ring stats
1028  */
1029 typedef struct {
1030 	uint32_t        cres_pkt_alloc_failures;
1031 	uint32_t        __cres_reserved[1];
1032 } channel_ring_error_stats, *channel_ring_error_stats_t;
1033 
1034 typedef struct {
1035 	uint64_t        crsu_total_slots_transferred;
1036 	uint64_t        crsu_total_bytes_transferred;
1037 	uint64_t        crsu_number_of_syncs;
1038 	uint64_t        crsu_bytes_per_sync;
1039 	uint64_t        crsu_bytes_per_sync_ma;
1040 	uint32_t        crsu_min_slots_transferred;
1041 	uint32_t        crsu_max_slots_transferred;
1042 	uint32_t        crsu_slots_per_sync;
1043 	uint32_t        crsu_slots_per_sync_ma;
1044 } channel_ring_user_stats, *channel_ring_user_stats_t;
1045 
1046 typedef struct {
1047 	uint64_t        crs_total_slots_transferred;
1048 	uint64_t        crs_total_bytes_transferred;
1049 	uint64_t        crs_number_of_transfers;
1050 	union {
1051 		uint64_t        crs_last_update_net_uptime;/* used by kernel as timestamp */
1052 		uint64_t        crs_seconds_since_last_update;/* published to userspace as time lapsed */
1053 	};
1054 	uint64_t        crs_slots_per_second;
1055 	uint64_t        crs_slots_per_second_ma;
1056 	uint64_t        crs_bytes_per_second;
1057 	uint64_t        crs_bytes_per_second_ma;
1058 	uint32_t        crs_min_slots_transferred;
1059 	uint32_t        crs_max_slots_transferred;
1060 } channel_ring_stats, *channel_ring_stats_t;
1061 
1062 struct netif_qstats {
1063 	uint64_t        nq_total_pkts;  /* total pkts transferred */
1064 	uint64_t        nq_total_bytes; /* total bytes transferred */
1065 	uint64_t        nq_num_xfers;   /* number of transfers */
1066 	uint32_t        nq_min_pkts;    /* min pkts transferred */
1067 	uint32_t        nq_max_pkts;    /* max pkts transferred */
1068 	uint32_t        nq_pkts_ps;     /* pkts transferred per second */
1069 	uint32_t        nq_pkts_ps_ma;  /* moving avg of pkts transferred per second */
1070 	uint64_t        nq_bytes_ps;    /* bytes transferred per second */
1071 	uint64_t        nq_bytes_ps_ma; /* moving avg of bytes transferred per second */
1072 };
1073 
1074 /*
1075  * Netif queue set queue stats
1076  * Output: An array of netif_qstats_info struct
1077  */
1078 #define SK_STATS_NETIF_QUEUE_SYSCTL             "kern.skywalk.stats.netif_queue"
1079 
1080 /* Valid value for nqi_queue_flag */
1081 #define NQI_QUEUE_FLAG_IS_RX            0x00000001
1082 struct netif_qstats_info {
1083 	uint64_t                            nqi_qset_id;
1084 	uint16_t                            nqi_queue_flag;
1085 	uint16_t                            nqi_queue_idx;
1086 	packet_svc_class_t                  nqi_svc;
1087 	struct netif_qstats                 nqi_stats;
1088 };
1089 
1090 /*
1091  * Nexus provider information.
1092  * Provides information about the provider including any registered instances.
1093  * Used with "kern.skywalk.nexus_provider_list" sysctl.
1094  */
1095 #define NEXUS_PROVIDER_LIST_SYSCTL      "kern.skywalk.nexus_provider_list"
1096 
1097 typedef struct {
1098 	uuid_t          npi_prov_uuid;          /* nexus provider UUID */
1099 	struct nxprov_params npi_prov_params;   /* nexus provider parameters */
1100 	uint32_t        npi_instance_uuids_count;
1101 	uint32_t        __npi_align_reserved;
1102 	uuid_t          npi_instance_uuids[0];  /* nexus instance UUIDs */
1103 } nexus_provider_info, *nexus_provider_info_t;
1104 
1105 #define NEXUS_PROVIDER_INFO_SIZE(a) \
1106 	offsetof(nexus_provider_info, npi_instance_uuids[a])
1107 
1108 /*
1109  * Nexus channel information.
1110  * Provides information about every channel in the system.
1111  * Used with "kern.skywalk.nexus_channel_list" sysctl.
1112  */
1113 #define NEXUS_CHANNEL_LIST_SYSCTL       "kern.skywalk.nexus_channel_list"
1114 
1115 /* Enable/Disable channel ring stats collection */
1116 #define NEXUS_CHANNEL_RING_STAT_ENABLE_SYSCTL   "kern.skywalk.ring_stat_enable"
1117 
1118 typedef struct {
1119 	ring_id_t               ncre_ring_id;
1120 	uint32_t                __ncre_align_reserved;
1121 	channel_ring_stats              ncre_stats;
1122 	channel_ring_user_stats         ncre_user_stats;
1123 	channel_ring_error_stats        ncre_error_stats;
1124 } nexus_channel_ring_entry, *nexus_channel_ring_entry_t;
1125 
1126 typedef struct {
1127 	uuid_t          nce_uuid;       /* channel uuid */
1128 	uint32_t        nce_flags;      /* SCHF_* */
1129 	pid_t           nce_pid;        /* channel owner pid */
1130 	int             nce_fd;         /* channel pid */
1131 	nexus_port_t    nce_port;       /* connected nexus port */
1132 	uint32_t        nce_tx_rings;   /* num of tx rings */
1133 	uint32_t        nce_rx_rings;   /* num of rx rings */
1134 	uint32_t        __nce_align_reserved;
1135 	uint32_t        nce_ring_count; /* -fbounds-safety: only TX and RX rings*/
1136 	nexus_channel_ring_entry nce_ring_entries[__counted_by(nce_ring_count)]; /* tx followed by rx */
1137 } nexus_channel_entry, *nexus_channel_entry_t;
1138 
1139 #define SCHF_USER_PACKET_POOL   0x00000008
1140 #define SCHF_DEFUNCT_OK         0x00000010
1141 #define SCHF_EXCLUSIVE          0x00000020
1142 #define SCHF_FILTER             0x00000040
1143 #define SCHF_EVENT_RING         0x00000080
1144 #define SCHF_IF_ADV             0x00000100
1145 #define SCHF_DEFUNCT_SKIP       0x00000200
1146 #define SCHF_LOW_LATENCY        0x00000400
1147 #define SCHF_CLOSING            0x40000000
1148 #define SCHF_DEFUNCT            0x80000000
1149 
1150 #define SCHF_BITS                                                          \
1151 	"\020\01MON_TX\02MON_RX\03NO_COPY\04USER_PACKET_POOL\05DEFUNCT_OK" \
1152 	"\06EXCLUSIVE\07FILTER\010EVENT_RING\011IF_ADV\012DEFUNCT_SKIP"    \
1153 	"\013LOW_LATENCY\037CLOSING\040DEFUNCT"
1154 
1155 #define NEXUS_CHANNEL_ENTRY_SIZE(n_rings)               \
1156 	offsetof(nexus_channel_entry, nce_ring_entries[n_rings])
1157 
1158 typedef struct {
1159 	uuid_t          nci_instance_uuid;      /* nexus instance UUID */
1160 	uint32_t        nci_channel_entries_count;
1161 	uint32_t        __nci_align_reserved;
1162 	nexus_channel_entry     nci_channel_entries[__counted_by(nci_channel_entries_count)]; /* variable length */
1163 } nexus_channel_info, *nexus_channel_info_t;
1164 
1165 /*
1166  * Nexus statistics types.
1167  */
1168 typedef enum {
1169 	NEXUS_STATS_TYPE_INVALID = 0,   /* invalid type */
1170 	NEXUS_STATS_TYPE_FSW,           /* flowswitch */
1171 	NEXUS_STATS_TYPE_CHAN_ERRORS,   /* Channel error stats */
1172 } nexus_stats_type_t;
1173 
1174 /*
1175  * Flowswitch statistics (NEXUS_STATS_TYPE_FSW).
1176  */
1177 struct __nx_stats_fsw {
1178 	struct ip_stats                 nxs_ipstat;
1179 	struct ip6_stats                nxs_ip6stat;
1180 	struct tcp_stats                nxs_tcpstat;
1181 	struct udp_stats                nxs_udpstat;
1182 	struct quic_stats               nxs_quicstat;
1183 };
1184 
1185 /*
1186  * Channel error statistics
1187  */
1188 struct __nx_stats_channel_errors {
1189 	channel_ring_error_stats_t      nxs_cres;
1190 };
1191 
1192 /*
1193  * Nexus advisories.
1194  */
1195 #define NX_INTF_ADV_SIZE (sizeof(uint64_t) + sizeof(struct ifnet_interface_advisory))
1196 
1197 #if defined(LIBSYSCALL_INTERFACE) || defined(BSD_KERNEL_PRIVATE)
1198 /*
1199  * Nexus advisory region types.
1200  */
1201 typedef enum {
1202 #if defined(BSD_KERNEL_PRIVATE)
1203 	NEXUS_ADVISORY_TYPE_INVALID = 0,
1204 #endif /* BSD_KERNEL_PRIVATE */
1205 	NEXUS_ADVISORY_TYPE_FLOWSWITCH = 1,   /* struct sk_nexusadv */
1206 	NEXUS_ADVISORY_TYPE_NETIF,   /* struct netif_nexus_advisory */
1207 } nexus_advisory_type_t;
1208 
1209 /*
1210  * The metadata object is placed at the begining of nexus advisory region.
1211  */
1212 struct __kern_nexus_adv_metadata {
1213 	uint16_t                 knam_version;
1214 	uint16_t                 __reserved;
1215 	nexus_advisory_type_t    knam_type;
1216 };
1217 #define NX_ADVISORY_MD_VERSION            1
1218 #define NX_ADVISORY_MD_CURRENT_VERSION    NX_ADVISORY_MD_VERSION
1219 
1220 struct __kern_netif_intf_advisory {
1221 	uint32_t                           cksum;
1222 	uint32_t                           _reserved;
1223 	struct ifnet_interface_advisory    adv;
1224 } __attribute__((aligned(sizeof(uint64_t))));
1225 
1226 /*
1227  * Netif nexus advisory.
1228  * currently this structure is not exposed to the user, but in future we
1229  * can expose it via os_channel_get_advisory_region() API.
1230  */
1231 struct netif_nexus_advisory {
1232 	uint64_t nna_version;
1233 	/*
1234 	 * __nna_intf_adv has been defined as an opaque blob here as the
1235 	 * atomicity of the data can be guaranteed only if accessed using
1236 	 * the os_channel_get_interface_advisory() API.
1237 	 */
1238 	union {
1239 #if defined(LIBSYSCALL_INTERFACE) || defined(BSD_KERNEL_PRIVATE)
1240 		struct __kern_netif_intf_advisory __kern_intf_adv;
1241 #endif /* LIBSYSCALL_INTERFACE || BSD_KERNEL_PRIVATE */
1242 		uint8_t __nna_intf_adv[NX_INTF_ADV_SIZE];
1243 	};
1244 } __attribute__((aligned(sizeof(uint64_t))));
1245 
1246 /* Netif nexus advisory version */
1247 #define NX_NETIF_ADVISORY_VERSION            1
1248 #define NX_NETIF_ADVISORY_CURRENT_VERSION    NX_NETIF_ADVISORY_VERSION
1249 #endif /* LIBSYSCALL_INTERFACE || BSD_KERNEL_PRIVATE */
1250 
1251 /*
1252  * Flowswitch nexus advisory.
1253  *
1254  * Note: add new field members at the bottom; if layout changes in the
1255  * middle, bump up NX_ADVISORY_VERSION and recompile userland clients
1256  * accessing this structure.
1257  *
1258  * Timestamps are stored in nanoseconds, based on microuptime().
1259  * Use mach_timebase_info() to acquire numerator and denominator,
1260  * and then compute current time using the following:
1261  *
1262  * uint64_t now = (mach_absolute_time() * tb_info.numer) / tb_info.denom;
1263  *
1264  * Comparisons can then be done against that current time.
1265  */
1266 struct sk_nexusadv {
1267 	uint64_t nxadv_ver;             /* see NX_ADVISORY_VERSION */
1268 	uint64_t nxadv_fg_sendts;       /* foreground traffic timestamp */
1269 	uint64_t nxadv_rt_sendts;       /* realtime traffic timestamp */
1270 	union {
1271 #if defined(LIBSYSCALL_INTERFACE) || defined(BSD_KERNEL_PRIVATE)
1272 		struct __kern_netif_intf_advisory _nxadv_intf_adv;
1273 #endif /* LIBSYSCALL_INTERFACE || BSD_KERNEL_PRIVATE */
1274 		uint8_t _nxadv_reserved[NX_INTF_ADV_SIZE];
1275 	};
1276 } __attribute__((aligned(sizeof(uint64_t))));
1277 
1278 /* Flowswitch nexus advisory version */
1279 #define NX_ADVISORY_VERSION     1
1280 #define NX_ADVISORY_VERSION_2   2
1281 #define NX_ADVISORY_CURRENT_VERSION     NX_ADVISORY_VERSION_2
1282 #define NX_FLOWSWITCH_ADVISORY_CURRENT_VERSION    NX_ADVISORY_CURRENT_VERSION
1283 
1284 typedef enum {
1285 	/*
1286 	 * TCP states.
1287 	 */
1288 	SFT_STATE_CLOSED = 0,           /* closed */
1289 	SFT_STATE_LISTEN,               /* listening for connection */
1290 	SFT_STATE_SYN_SENT,             /* active, have sent SYN */
1291 	SFT_STATE_SYN_RECEIVED,         /* have sent and rcvd SYN */
1292 	SFT_STATE_ESTABLISHED,          /* established */
1293 	SFT_STATE_CLOSE_WAIT,           /* rcvd FIN, waiting close */
1294 	SFT_STATE_FIN_WAIT_1,           /* have sent FIN */
1295 	SFT_STATE_CLOSING,              /* exchanged FINs, waiting FIN|ACK */
1296 	SFT_STATE_LAST_ACK,             /* rcvd FIN, closed, waiting FIN|ACK */
1297 	SFT_STATE_FIN_WAIT_2,           /* closed, FIN is ACK'd */
1298 	SFT_STATE_TIME_WAIT,            /* quiet wait after close */
1299 
1300 	/*
1301 	 * UDP states.
1302 	 */
1303 	SFT_STATE_NO_TRAFFIC = 20,      /* no packet observed */
1304 	SFT_STATE_SINGLE,               /* single packet */
1305 	SFT_STATE_MULTIPLE,             /* multiple packets */
1306 
1307 	SFT_STATE_MAX = 255
1308 } sk_stats_flow_track_state_t;
1309 
1310 struct sk_stats_flow_track {
1311 	uint64_t        sft_bytes;      /* bytes */
1312 	uint64_t        sft_packets;    /* packets */
1313 	uint64_t        sft_spackets;   /* super packets */
1314 	sk_stats_flow_track_state_t sft_state;  /* SFT_STATE_* */
1315 	uint32_t        sft_rtt;        /* avg ack rtt at flowswith */
1316 	uint32_t        sft_seq;        /* max sequence number sent */
1317 	uint16_t        sft_max_win;    /* largest window (pre scaling) */
1318 	uint8_t         sft_wscale;     /* window scaling factor */
1319 };
1320 
1321 #define FLOW_STATS_IN_ADD(fe, stat, cnt) { \
1322 	volatile struct sk_stats_flow_track *fst; \
1323 	fst = &(fe)->fe_stats->fs_rtrack; \
1324 	fst->sft_##stat += (cnt); \
1325 }
1326 
1327 #define FLOW_STATS_OUT_ADD(fe, stat, cnt) { \
1328 	volatile struct sk_stats_flow_track *fst; \
1329 	fst = &(fe)->fe_stats->fs_ltrack; \
1330 	fst->sft_##stat += (cnt); \
1331 }
1332 
1333 /*
1334  * Skywalk flow (in kernel), equivalent of "net.inet.*.pcblist_n".
1335  * Output: Array of struct sk_stats_flow (per flow).
1336  */
1337 #define SK_STATS_FLOW   "kern.skywalk.stats.flow"
1338 struct sk_stats_flow {
1339 	uuid_t          sf_nx_uuid;             /* nexus instance uuid */
1340 	uuid_t          sf_uuid;                /* flow uuid */
1341 	char            sf_if_name[IFNAMSIZ];   /* interface name */
1342 	uint32_t        sf_if_index;            /* interface index */
1343 	uint32_t        sf_bucket_idx;          /* flow bucket index */
1344 
1345 	pid_t           sf_pid;                 /* flow pid */
1346 	pid_t           sf_epid;                /* flow effective pid */
1347 	char            sf_proc_name[32];       /* flow proc name */
1348 	char            sf_eproc_name[32];      /* flow effecitve proc name */
1349 
1350 	uint32_t        sf_flags;               /* SFLOWF_* */
1351 	nexus_port_t    sf_nx_port;             /* nexus port */
1352 
1353 	uint8_t         sf_protocol;            /* effective protocol */
1354 	packet_svc_class_t sf_svc_class;        /* service class */
1355 	flowadv_idx_t   sf_adv_idx;             /* flow advistory table index */
1356 	struct flow_key sf_key __attribute__((__aligned__(16)));
1357 
1358 	volatile struct sk_stats_flow_track sf_ltrack; /* local states */
1359 	volatile struct sk_stats_flow_track sf_rtrack; /* remote states */
1360 #define sf_obytes       sf_ltrack.sft_bytes
1361 #define sf_opackets     sf_ltrack.sft_packets
1362 #define sf_ospackets    sf_ltrack.sft_spackets
1363 #define sf_ibytes       sf_rtrack.sft_bytes
1364 #define sf_ipackets     sf_rtrack.sft_packets
1365 #define sf_ispackets    sf_rtrack.sft_spackets
1366 #define sf_lrtt         sf_ltrack.sft_rtt
1367 #define sf_rrtt         sf_rtrack.sft_rtt
1368 #define sf_lseq         sf_ltrack.sft_seq
1369 #define sf_rseq         sf_rtrack.sft_seq
1370 #define sf_lmax_win     sf_ltrack.sft_max_win
1371 #define sf_rmax_win     sf_rtrack.sft_max_win
1372 #define sf_lwscale      sf_ltrack.sft_wscale
1373 #define sf_rwscale      sf_rtrack.sft_wscale
1374 
1375 	activity_bitmap_t sf_activity;          /* flow activity bitmap */
1376 };
1377 
1378 /* valid values for sf_flags */
1379 #define SFLOWF_TRACK            0x00000010      /* flow is tracked */
1380 #define SFLOWF_CONNECTED        0x00000020      /* connected mode */
1381 #define SFLOWF_LISTENER         0x00000040      /* listener mode */
1382 #define SFLOWF_AOP_OFFLOAD      0x00000080      /* AOP offloaded flow */
1383 #define SFLOWF_QOS_MARKING      0x00000100      /* flow can have qos marking */
1384 #define SFLOWF_BOUND_IP         0x00000200      /* src addr explicity bound */
1385 #define SFLOWF_ONLINK           0x00000400      /* dst directly on the link */
1386 #define SFLOWF_LOW_LATENCY      0x00000800      /* low latency flow */
1387 #define SFLOWF_WAIT_CLOSE       0x00001000      /* defer free after close */
1388 #define SFLOWF_CLOSE_NOTIFY     0x00002000      /* notify NECP upon tear down */
1389 #define SFLOWF_NOWAKEFROMSLEEP  0x00004000      /* don't wake for this flow */
1390 #define SFLOWF_CONNECTION_IDLE  0x00008000      /* connection is idle */
1391 #define SFLOWF_ABORTED          0x01000000      /* has sent RST to peer */
1392 #define SFLOWF_NONVIABLE        0x02000000      /* disabled; to be torn down */
1393 #define SFLOWF_WITHDRAWN        0x04000000      /* flow has been withdrawn */
1394 #define SFLOWF_TORN_DOWN        0x08000000      /* torn down, to be destroyed */
1395 #define SFLOWF_PARENT           0x10000000      /* parent flow */
1396 #define SFLOWF_CHILD            0x20000000      /* child flow */
1397 #define SFLOWF_DESTROYED        0x40000000      /* not in RB trees anymore */
1398 #define SFLOWF_LINGERING        0x80000000      /* destroyed and lingering */
1399 
1400 #define SFLOW_BUCKET_NONE       ((uint32_t)-1)
1401 
1402 #if defined(BSD_KERNEL_PRIVATE)
1403 #include <os/refcnt.h>
1404 
1405 /*
1406  * flow_stats is the kernel stats object that serves as efficient conduit
1407  * between stats producer (the Skywalk flowswitch) and consumers
1408  * (e.g. necp_client/ntstat). It embeds the sk_stats_flow along with a
1409  * reference count. The flow_stats object would be freed when released and
1410  * refcnt reaches 0. There must be only one producer and/or multiple consumers.
1411  * There is no lock protecting the stats object as inconsistent intermediate
1412  * state data is tolerable for stats consumers and most fields, e.g. integer
1413  * counters, are updated atomically. Synchronization of producer/consumer
1414  * should be done via other means, e.g. necp/ntstat events, rather than on the
1415  * flow_stats itself.
1416  *
1417  * Fields in flow_stats.fs_stats are published in different phases:
1418  *     - Descriptor fields
1419  *         ID, names, address, etc. which are immutable during flow lifetime,
1420  *         which are initialized during creation time.
1421  *     - State fields
1422  *         Flow state, track state, etc. which are mutable. They are
1423  *         initialized during flow creation time, but lazily updated during
1424  *         runtime and upon synchronous retrieval.
1425  *     - Runtime fields
1426  *         Counters (packets in/out, bytes in/out, rtt, etc.), which are
1427  *         mutable and updated in real-time.
1428  *
1429  * Note the reduced alignment for sk_stats_flow and sk_stats_flow_track to
1430  * reduce the allocation size.
1431  */
1432 struct flow_stats {
1433 	struct sk_stats_flow    fs_stats;
1434 #define fs_ltrack       fs_stats.sf_ltrack
1435 #define fs_rtrack       fs_stats.sf_rtrack
1436 #define fs_activity     fs_stats.sf_activity
1437 #define fs_lrtt         fs_stats.sf_lrtt
1438 #define fs_rrtt         fs_stats.sf_rrtt
1439 
1440 	os_refcnt_t             fs_refcnt;
1441 };
1442 
1443 extern void flow_stats_free(struct flow_stats *fs);
1444 
1445 __attribute__((always_inline))
1446 static inline void
flow_stats_retain(struct flow_stats * fs)1447 flow_stats_retain(struct flow_stats *fs)
1448 {
1449 	os_ref_retain(&fs->fs_refcnt);
1450 }
1451 
1452 __attribute__((always_inline))
1453 static inline void
flow_stats_release(struct flow_stats * fs)1454 flow_stats_release(struct flow_stats *fs)
1455 {
1456 	if (__improbable(os_ref_release(&fs->fs_refcnt) == 0)) {
1457 		flow_stats_free(fs);
1458 	}
1459 }
1460 
1461 __attribute__((always_inline))
1462 static inline os_ref_count_t
flow_stats_refcnt(struct flow_stats * fs)1463 flow_stats_refcnt(struct flow_stats *fs)
1464 {
1465 	return os_ref_get_count(&fs->fs_refcnt);
1466 }
1467 #endif /* BSD_KERNEL_PRIVATE */
1468 
1469 #define SK_STATS_FLOW_OWNER     "kern.skywalk.stats.flow_owner"
1470 struct sk_stats_flow_owner {
1471 	uuid_t          sfo_nx_uuid;            /* nexus instance uuid */
1472 	char            sfo_if_name[IFNAMSIZ];  /* attached interface name */
1473 	uint32_t        sfo_bucket_idx;         /* flow owner bucket index */
1474 
1475 	char            sfo_name[32];           /* flow owner name */
1476 	pid_t           sfo_pid;                /* flow owner pid */
1477 
1478 	nexus_port_t    sfo_nx_port;            /* flow owner nexus port */
1479 	boolean_t       sfo_nx_port_pid_bound;  /* flow owner port pid bound */
1480 	boolean_t       sfo_nx_port_destroyed;  /* flow owner port destroyed */
1481 } __attribute__((aligned(64)));
1482 
1483 #define SK_STATS_FLOW_ROUTE     "kern.skywalk.stats.flow_route"
1484 struct sk_stats_flow_route {
1485 	uuid_t          sfr_nx_uuid;            /* nexus instance UUID */
1486 	uuid_t          sfr_uuid;               /* flow route UUID */
1487 	char            sfr_if_name[IFNAMSIZ];  /* interface name */
1488 
1489 	uint32_t        sfr_bucket_idx;         /* flow route bucket index */
1490 	uint32_t        sfr_id_bucket_idx;      /* flow route id bucket index */
1491 
1492 	uint32_t        sfr_flags;              /* SFLOWRTF_* */
1493 	uint32_t        sfr_usecnt;             /* flow route usecnt */
1494 	int64_t         sfr_expire;             /* seconds left to expire */
1495 
1496 	union sockaddr_in_4_6 sfr_laddr;        /* local address */
1497 	union sockaddr_in_4_6 sfr_faddr;        /* foreign address */
1498 	union sockaddr_in_4_6 sfr_gaddr;        /* gateway address */
1499 
1500 	uint8_t         sfr_ether_dhost[ETHER_ADDR_LEN]
1501 	__attribute__((aligned(64)));
1502 };
1503 
1504 /* valid values for sfr_flags */
1505 #define SFLOWRTF_ATTACHED       0x00000001 /* attached to RB trees */
1506 #define SFLOWRTF_ONLINK         0x00000010 /* dst directly on the link */
1507 #define SFLOWRTF_GATEWAY        0x00000020 /* gw IP address is valid */
1508 #define SFLOWRTF_RESOLVED       0x00000040 /* flow route is resolved */
1509 #define SFLOWRTF_HAS_LLINFO     0x00000080 /* has dst link-layer address */
1510 #define SFLOWRTF_DELETED        0x00000100 /* route has been deleted */
1511 #define SFLOWRTF_DST_LL_MCAST   0x00000200 /* dst is link layer multicast */
1512 #define SFLOWRTF_DST_LL_BCAST   0x00000400 /* dst is link layer broadcast */
1513 
1514 /*
1515  * Skywalk netif stats
1516  * Output: Array of struct sk_stats_net_if entry (per netif nexus instance).
1517  */
1518 #define SK_STATS_NET_IF         "kern.skywalk.stats.net_if"
1519 struct sk_stats_net_if {
1520 	uuid_t          sns_nx_uuid;            /* nexus netif instance uuid */
1521 	char            sns_if_name[IFNAMSIZ];  /* attached interface name */
1522 
1523 	struct netif_stats      sns_nifs;       /* netif stats */
1524 } __attribute__((aligned(64)));
1525 
1526 /*
1527  * Skywalk flowswitch stats
1528  * Output: Array of struct sk_stats_flow_switch entry (per fsw nexus instance).
1529  */
1530 #define SK_STATS_FLOW_SWITCH    "kern.skywalk.stats.flow_switch"
1531 struct sk_stats_flow_switch {
1532 	uuid_t          sfs_nx_uuid;            /* nexus fsw instance uuid */
1533 	char            sfs_if_name[IFNAMSIZ];  /* attached interface name */
1534 
1535 	struct fsw_stats        sfs_fsws;       /* flowswitch stats */
1536 } __attribute__((aligned(64)));
1537 
1538 /*
1539  * Skywalkuserstack stats
1540  *
1541  * With Skywalk, traditional kernel space stacks like tcp/udp/ip/ip6 are now
1542  * moved to userspace process. Together with this, stack statistics are now kept
1543  * per process via shared memory described by skywalk channel, which is in a
1544  * memory mapped region from a kernel nexus to a userspace process.
1545  *
1546  * Output: Array of struct sk_stats_userstack (per process, per nexus
1547  *         instance) Entries with nts_owner_pid == 0 are reserved for nexus
1548  *         stats collected from closed nexus ports.
1549  */
1550 #define SK_STATS_USERSTACK      "kern.skywalk.stats.userstack"
1551 struct sk_stats_userstack {
1552 	uuid_t                  sus_nx_uuid;    /* nexus instance uuid */
1553 	char            sus_if_name[IFNAMSIZ];  /* attached interface name */
1554 	pid_t                   sus_owner_pid;  /* owner process */
1555 
1556 	struct ip_stats         sus_ip;         /* process ip stats */
1557 	struct ip6_stats        sus_ip6;        /* process ip6 stats */
1558 	struct tcp_stats        sus_tcp;        /* process tcp stats */
1559 	struct udp_stats        sus_udp;        /* process udp stats */
1560 	struct quic_stats       sus_quic;       /* process quic stats */
1561 } __attribute__((aligned(64)));
1562 
1563 /*
1564  * Skywalk flow advisory table dump
1565  */
1566 struct sk_stats_flow_adv_ent {
1567 	uuid_t          sfae_flow_id;           /* flow ID */
1568 	uint32_t        sfae_flags;             /* flags, FLOWADVF_* */
1569 };
1570 
1571 #define SK_STATS_FLOW_ADV       "kern.skywalk.stats.flow_adv"
1572 struct sk_stats_flow_adv {
1573 	uuid_t          sfa_nx_uuid;            /* nexus instance uuid */
1574 	char            sfa_if_name[IFNAMSIZ];  /* attached interface name */
1575 	pid_t           sfa_owner_pid;          /* owner process */
1576 
1577 	uint32_t        sfa_entries_count;      /* number of flow adv entries */
1578 	struct sk_stats_flow_adv_ent    sfa_entries[__counted_by(sfa_entries_count)]; /* flow adv entries */
1579 };
1580 
1581 /*
1582  * struct netns_ctl_dump_header is used for sysctl 'kern.skywalk.stats.netns'
1583  * which returns a buffer containing the contents of every netns namespace.
1584  * The buffer is formatted as a series headers, each immediately followed by
1585  * some number of records:
1586  *    { struct netns_ctl_dump_header h,
1587  *      struct netns_ctl_dump_record r[h->ncdh_n_records] } * total_namespaces
1588  */
1589 #define SK_STATS_NETNS          "kern.skywalk.stats.netns"
1590 struct netns_ctl_dump_header {
1591 	union {
1592 		uint32_t        ncdh_addr[4];
1593 		struct in_addr  ncdh_inaddr;
1594 		struct in6_addr ncdh_in6addr;
1595 	};
1596 	uint8_t         ncdh_addr_len;
1597 	uint8_t         ncdh_proto;
1598 	uint32_t        ncdh_n_records;
1599 	/*
1600 	 * In a 'kern.skywalk.stats.netns' response, followed by
1601 	 * {ncdh_n_records} struct netns_ctl_dump_records
1602 	 */
1603 } __attribute__((aligned(32)));
1604 
1605 struct netns_ctl_dump_record {
1606 	in_port_t ncdr_port;
1607 	in_port_t ncdr_port_end;
1608 	uint32_t  ncdr_skywalk_refs;
1609 	uint32_t  ncdr_bsd_refs;
1610 	uint32_t  ncdr_pf_refs;
1611 	uint32_t  ncdr_listener_refs;
1612 } __attribute__((aligned(32)));
1613 
1614 #define NS_DUMP_SIZE(records)   (sizeof (struct netns_ctl_dump_header) + \
1615 	records * sizeof (struct netns_ctl_dump_record))
1616 
1617 #define SK_STATS_PROTONS        "kern.skywalk.stats.protons"
1618 struct sk_stats_protons_token {
1619 	uint8_t                 spt_protocol;
1620 	uint32_t                spt_refcnt;
1621 	pid_t                   spt_pid;
1622 	pid_t                   spt_epid;
1623 };
1624 
1625 /*
1626  * struct sk_stats_flowidns_header is used for
1627  * sysctl 'kern.skywalk.stats.flowidns' * which returns a buffer containing
1628  * the contents of every flowid.
1629  * The buffer is formatted as a series headers, each immediately followed by
1630  * some number of records:
1631  * { struct sk_stats_flowidns_header h,
1632  *   struct sk_stats_flowidns_record r[h->sfh_nrecords] } * num_flow_domains
1633  */
1634 #define SK_STATS_FLOWIDNS    "kern.skywalk.stats.flowidns"
1635 struct sk_stats_flowidns_header {
1636 	uint64_t sfh_nallocs;
1637 	uint64_t sfh_nreleases;
1638 	uint64_t sfh_ncollisions;
1639 	uint32_t sfh_domain;
1640 	uint32_t sfh_nrecords;
1641 	/*
1642 	 * In a 'kern.skywalk.stats.flowidns' response, followed by
1643 	 * {sfh_n_records} struct sk_stats_flowidns_record
1644 	 */
1645 } __attribute__((aligned(32)));
1646 
1647 /* valid values for sfh_domain */
1648 #define SFH_DOMAIN_IPSEC         0
1649 #define SFH_DOMAIN_FLOWSWITCH    1
1650 #define SFH_DOMAIN_INPCB         2
1651 #define SFH_DOMAIN_PF            3
1652 
1653 
1654 struct sk_stats_flowidns_record {
1655 	union {
1656 		uint32_t        _addr[4];
1657 		struct in_addr  _v4;
1658 		struct in6_addr _v6;
1659 	} sfr_laddr;
1660 	union {
1661 		uint32_t        _addr[4];
1662 		struct in_addr  _v4;
1663 		struct in6_addr _v6;
1664 	} sfr_raddr;
1665 	union {
1666 		struct {
1667 			uint16_t _lport;
1668 			uint16_t _rport;
1669 		} sfr_ports;
1670 		uint32_t sfr_spi;
1671 		uint32_t sfr_protoid;
1672 	};
1673 	uint32_t sfr_flowid;
1674 	uint8_t  sfr_ipproto;
1675 	uint8_t  sfr_af;
1676 } __attribute__((aligned(32)));
1677 
1678 #define sfr_laddr_v4    sfr_laddr._v4
1679 #define sfr_laddr_v6    sfr_laddr._v6
1680 #define sfr_raddr_v4    sfr_raddr._v4
1681 #define sfr_raddr_v6    sfr_raddr._v6
1682 #define sfr_lport       sfr_ports._lport
1683 #define sfr_rport       sfr_ports._rport
1684 
1685 
1686 #define FLOWIDNS_BUFFER_SIZE(_records)                       \
1687 	(sizeof (struct sk_stats_flowidns_header) +          \
1688 	_records * sizeof (struct sk_stats_flowidns_record))
1689 
1690 typedef enum {
1691 	/*
1692 	 * The following are user task mappable.
1693 	 */
1694 	SREG_GUARD_HEAD = 0,    /* leading guard page(s) */
1695 	SREG_SCHEMA,            /* channel layout */
1696 	SREG_RING,              /* rings */
1697 	SREG_BUF_DEF,           /* Default rx/tx buffers */
1698 	SREG_BUF_LARGE,         /* Large rx/tx buffers */
1699 	SREG_RXBUF_DEF,         /* Default rx only buffers */
1700 	SREG_RXBUF_LARGE,       /* Large rx only buffers */
1701 	SREG_TXBUF_DEF,         /* Default tx only buffers */
1702 	SREG_TXBUF_LARGE,       /* Large tx only buffers */
1703 	SREG_UMD,               /* userland metadata */
1704 	SREG_TXAUSD,            /* tx/alloc user slot descriptors */
1705 	SREG_RXFUSD,            /* rx/free user slot descriptors */
1706 	SREG_UBFT,              /* userland buflet metadata */
1707 	SREG_USTATS,            /* statistics */
1708 	SREG_FLOWADV,           /* flow advisories */
1709 	SREG_NEXUSADV,          /* nexus advisories */
1710 	SREG_SYSCTLS,           /* sysctl */
1711 	SREG_GUARD_TAIL,        /* trailing guard page(s) */
1712 
1713 	/*
1714 	 * The following are NOT user task mappable.
1715 	 */
1716 	SREG_KMD,               /* rx/tx kernel metadata */
1717 	SREG_RXKMD,             /* rx only kernel metadata */
1718 	SREG_TXKMD,             /* tx only kernel metadata */
1719 	SREG_KBFT,              /* rx/tx kernel buflet metadata */
1720 	SREG_RXKBFT,            /* rx only kernel buflet metadata */
1721 	SREG_TXKBFT,            /* tx only kernel buflet metadata */
1722 	SREG_TXAKSD,            /* tx/alloc kernel slot descriptors */
1723 	SREG_RXFKSD,            /* rx/free kernel slot descriptors */
1724 	SREG_KSTATS,            /* kernel statistics snapshot */
1725 	SREG_INSTRINSIC,        /* intrinsic objects */
1726 
1727 	SREG_MAX                /* max */
1728 } sk_stats_region_id_t;
1729 
1730 #define SK_STATS_REGION         "kern.skywalk.stats.region"
1731 struct sk_stats_region {
1732 	/*
1733 	 * Region properties.
1734 	 */
1735 	char            sreg_name[64];          /* region name */
1736 	uuid_t          sreg_uuid;              /* region uuid */
1737 	sk_stats_region_id_t sreg_id;           /* region ID */
1738 	uint32_t        sreg_mode;              /* region mode flags */
1739 
1740 	/*
1741 	 * Region parameters.
1742 	 */
1743 	uint64_t        sreg_r_seg_size;        /* requested seg size */
1744 	uint64_t        sreg_c_seg_size;        /* configured seg size */
1745 	uint64_t        sreg_seg_cnt;           /* number of segments */
1746 	uint64_t        sreg_seg_objs;          /* # of objects per segment */
1747 	uint64_t        sreg_r_obj_size;        /* requested obj size */
1748 	uint64_t        sreg_r_obj_cnt;         /* requested obj count */
1749 	uint64_t        sreg_c_obj_size;        /* configured obj size */
1750 	uint64_t        sreg_c_obj_cnt;         /* configured obj count */
1751 	uint64_t        sreg_align;             /* object alignment */
1752 	uint64_t        sreg_max_frags;         /* max number of buflets */
1753 
1754 	/*
1755 	 * Region statistics.
1756 	 */
1757 	uint64_t        sreg_meminuse;          /* memory in use */
1758 	uint64_t        sreg_w_meminuse;        /* wired memory in use */
1759 	uint64_t        sreg_memtotal;          /* total memory in region */
1760 	uint64_t        sreg_seginuse;          /* total unfreed segments */
1761 	uint64_t        sreg_rescale;           /* # of hash table rescales */
1762 	uint64_t        sreg_hash_size;         /* size of hash table */
1763 	uint64_t        sreg_alloc;             /* number of allocations */
1764 	uint64_t        sreg_free;              /* number of frees */
1765 };
1766 
1767 /* valid values for sreg_mode */
1768 #define SREG_MODE_NOREDIRECT    0x1     /* unaffected by defunct */
1769 #define SREG_MODE_MMAPOK        0x2     /* can be mapped to user task */
1770 #define SREG_MODE_KREADONLY     0x4     /* kernel read-only */
1771 #define SREG_MODE_UREADONLY     0x8     /* if user map, map it read-only */
1772 #define SREG_MODE_PERSISTENT    0x10    /* memory stays non-volatile */
1773 #define SREG_MODE_MONOLITHIC    0x20    /* monolithic region */
1774 #define SREG_MODE_NOMAGAZINES   0x40    /* disable magazines layer */
1775 #define SREG_MODE_NOCACHE       0x80    /* caching-inhibited */
1776 #define SREG_MODE_SEGPHYSCONTIG 0x100   /* phys. contiguous segment */
1777 #define SREG_MODE_SHAREOK       0x200   /* allow object sharing */
1778 #define SREG_MODE_IODIR_IN      0x400   /* I/O direction In */
1779 #define SREG_MODE_IODIR_OUT     0x800   /* I/O direction Out */
1780 #define SREG_MODE_GUARD         0x1000  /* guard pages region */
1781 #define SREG_MODE_PUREDATA      0x2000  /* purely data; no pointers */
1782 #define SREG_MODE_PSEUDO        0x4000  /* external backing store */
1783 #define SREG_MODE_THREADSAFE    0x8000  /* external backing store */
1784 #define SREG_MODE_SLAB          (1U << 30) /* backend for slab layer */
1785 #define SREG_MODE_MIRRORED      (1U << 31) /* controlled by another region */
1786 
1787 #define SREG_MODE_BITS                                                  \
1788 	"\020\01NOREDIRECT\02MMAPOK\03KREADONLY\04UREADONLY"            \
1789 	"\05PERSISTENT\06MONOLITHIC\07NOMAGAZINES\10NOCACHE"            \
1790 	"\11SEGPHYSCONTIG\012SHAREOK\013IODIR_IN\014IODIR_OUT"          \
1791 	"\015GUARD\016PUREDATA\017PSEUDO\020THREADSAFE\037SLAB"         \
1792 	"\040MIRRORED"
1793 
1794 typedef enum {
1795 	SAR_TYPE_NEXUS,
1796 	SAR_TYPE_NECP,
1797 	SAR_TYPE_SYSTEM,
1798 } sk_stats_arena_type_t;
1799 
1800 #define SK_STATS_ARENA          "kern.skywalk.stats.arena"
1801 struct sk_stats_arena {
1802 	char                    sar_name[64];
1803 	sk_stats_arena_type_t   sar_type;
1804 	uint64_t                sar_mapsize;
1805 	uuid_t                  sar_regions_uuid[SREG_MAX];
1806 #define SK_STATS_ARENA_MAPPED_PID_MAX   8
1807 	pid_t                   sar_mapped_pids[SK_STATS_ARENA_MAPPED_PID_MAX];
1808 };
1809 
1810 #define SK_STATS_CACHE          "kern.skywalk.stats.cache"
1811 struct sk_stats_cache {
1812 	/*
1813 	 * Cache parameters.
1814 	 */
1815 	char            sca_name[64];           /* cache name */
1816 	uuid_t          sca_uuid;               /* cache uuid */
1817 	uuid_t          sca_ruuid;              /* backing region uuid */
1818 	uint32_t        sca_mode;               /* cache mode flags */
1819 	uint64_t        sca_bufsize;            /* object size */
1820 	uint64_t        sca_objsize;            /* actual obj size in slab */
1821 	uint64_t        sca_chunksize;          /* bufsize + alignment */
1822 	uint64_t        sca_slabsize;           /* size of a slab */
1823 	uint64_t        sca_bufalign;           /* buffer alignment */
1824 	uint64_t        sca_objalign;           /* object alignment */
1825 
1826 	/*
1827 	 * Per-CPU caches statistics.
1828 	 */
1829 	uint64_t        sca_cpu_mag_size;       /* current magazine size */
1830 	uint64_t        sca_cpu_mag_resize;     /* # of magazine resizes */
1831 	uint64_t        sca_cpu_mag_purge;      /* # of magazine purges */
1832 	uint64_t        sca_cpu_mag_reap;       /* # of magazine reaps */
1833 	uint64_t        sca_depot_full;         /* # of full magazines */
1834 	uint64_t        sca_depot_empty;        /* # of empty magazines */
1835 	uint64_t        sca_depot_ws_zero;      /* # of working set flushes */
1836 	uint64_t        sca_depot_contention_factor; /* contention factor */
1837 
1838 	uint64_t        sca_cpu_rounds;         /* current rounds in all cpu */
1839 	uint64_t        sca_cpu_prounds;
1840 
1841 	/*
1842 	 * Slab statistics.
1843 	 */
1844 	uint64_t        sca_sl_create;          /* slab creates */
1845 	uint64_t        sca_sl_destroy;         /* slab destroys */
1846 	uint64_t        sca_sl_alloc;           /* slab layer allocations */
1847 	uint64_t        sca_sl_free;            /* slab layer frees */
1848 	uint64_t        sca_sl_alloc_fail;      /* total failed allocations */
1849 	uint64_t        sca_sl_partial;         /* # of partial slabs */
1850 	uint64_t        sca_sl_empty;           /* # of empty slabs */
1851 	uint64_t        sca_sl_bufinuse;        /* total unfreed buffers */
1852 	uint64_t        sca_sl_rescale;         /* # of hash table rescales */
1853 	uint64_t        sca_sl_hash_size;       /* size of hash table */
1854 };
1855 
1856 /* valid values for sca_mode */
1857 #define SCA_MODE_NOMAGAZINES    0x00000001      /* disable magazines layer */
1858 #define SCA_MODE_AUDIT          0x00000002      /* audit transactions */
1859 #define SCA_MODE_NOREDIRECT     0x00000004      /* unaffected by defunct */
1860 #define SCA_MODE_BATCH          0x00000008      /* supports batch alloc/free */
1861 #define SCA_MODE_DYNAMIC        0x00000010      /* enable magazine resizing */
1862 #define SCA_MODE_CLEARONFREE    0x00000020      /* zero-out upon slab free */
1863 #define SCA_MODE_PSEUDO         0x00000040      /* external backing store */
1864 #define SCA_MODE_RECLAIM        0x00000080      /* aggressive memory reclaim */
1865 
1866 #define SCA_MODE_BITS \
1867 	"\020\01NOMAGAZINES\02AUDIT\03NOREDIRECT\04BATCH\05DYNAMIC"     \
1868 	"\06CLEARONFREE\07PSEUDO\10RECLAIM"
1869 
1870 #endif /* PRIVATE || BSD_KERNEL_PRIVATE */
1871 #endif /* !_SKYWALK_OS_STATS_H_ */
1872