1 /* 2 * Copyright (c) 2025 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 _NET_AOP_STATS_H_ 30 #define _NET_AOP_STATS_H_ 31 32 /* ip stats definitions */ 33 #define AOP_IP_STATS_TABLE(X) \ 34 /* Input stats */ \ 35 X(AOP_IP_STATS_TOTAL, "TotalRcvd", "\t%llu total packet received\n") \ 36 X(AOP_IP_STATS_BADSUM, "BadCsum", "\t\t%llu bad header checksum\n") \ 37 X(AOP_IP_STATS_TOOSMALL, "DataTooSmall", "\t\t%llu with size smaller than minimum\n")\ 38 X(AOP_IP_STATS_TOOSHORT, "PktTooShort", "\t\t%llu with data size < data length\n") \ 39 X(AOP_IP_STATS_ADJ, "TotalAdj", "\t\t%llu with data size > data length\n") \ 40 X(AOP_IP_STATS_TOOLONG, "TooLong", "\t\t%llu with ip length > max ip packet size\n") \ 41 X(AOP_IP_STATS_BADHLEN, "BadHdrLen", "\t\t%llu with header length < data size\n") \ 42 X(AOP_IP_STATS_BADLEN, "BadLen", "\t\t%llu with data length < header length\n") \ 43 X(AOP_IP_STATS_BADOPTIONS, "BadOptions", "\t\t%llu with bad options\n") \ 44 X(AOP_IP_STATS_BADVERS, "BadVer", "\t\t%llu with incorrect version number\n") \ 45 X(AOP_IP_STATS_FRAGMENTS, "FragRcvd", "\t\t%llu fragment received\n") \ 46 X(AOP_IP_STATS_FRAGDROPPED, "FragDrop", "\t\t\t%llu dropped (dup or out of space)\n") \ 47 X(AOP_IP_STATS_FRAGTIMEOUT, "FragTimeO", "\t\t\t%llu dropped after timeout\n") \ 48 X(AOP_IP_STATS_REASSEMBLED, "Reassembled", "\t\t\t%llu reassembled ok\n") \ 49 X(AOP_IP_STATS_DELIVERED, "Delivered", "\t\t%llu packet for this host\n") \ 50 X(AOP_IP_STATS_NOPROTO, "UnkwnProto", "\t\t%llu packet for unknown/unsupported protocol\n") \ 51 /* Output stats */ \ 52 X(AOP_IP_STATS_LOCALOUT, "LocalOut", "\t%llu packet sent from this host\n") \ 53 X(AOP_IP_STATS_ODROPPED, "DropNoBuf", "\t\t%llu output packet dropped due to no bufs, etc.\n") \ 54 X(AOP_IP_STATS_NOROUTE, "NoRoute", "\t\t%llu output packet discarded due to no route\n") \ 55 X(AOP_IP_STATS_FRAGMENTED, "Fragmented", "\t\t%llu output datagram fragmented\n") \ 56 X(AOP_IP_STATS_OFRAGMENTS, "OutFraged", "\t\t%llu fragment created\n") \ 57 X(AOP_IP_STATS_CANTFRAG, "CantFrag", "\t\t%llu datagram that can't be fragmented\n") \ 58 X(__AOP_IP_STATS_MAX, "", "end of ip stats") 59 60 /* ipv6 stats definitions */ 61 #define AOP_IP6_STATS_TABLE(X) \ 62 /* Input Stats */ \ 63 X(AOP_IP6_STATS_TOTAL, "TotalRcvd", "\t%llu total packet received\n") \ 64 X(AOP_IP6_STATS_TOOSMALL, "DataTooSmall", "\t\t%llu with size smaller than minimum\n") \ 65 X(AOP_IP6_STATS_TOOSHORT, "PktTooShort", "\t\t%llu with data size < data length\n") \ 66 X(AOP_IP6_STATS_ADJ, "TotalAdj", "\t\t%llu with data size > data length\n") \ 67 X(AOP_IP6_STATS_BADOPTIONS, "BadOptions", "\t\t%llu with bad options\n") \ 68 X(AOP_IP6_STATS_BADVERS, "BadVer", "\t\t%llu with incorrect version number\n") \ 69 X(AOP_IP6_STATS_FRAGMENTS, "FrafRcvd", "\t\t%llu fragment received\n") \ 70 X(AOP_IP6_STATS_FRAGDROPPED, "FragDrop", "\t\t\t%llu dropped (dup or out of space)\n") \ 71 X(AOP_IP6_STATS_FRAGTIMEOUT, "FragTimeO", "\t\t\t%llu dropped after timeout\n") \ 72 X(AOP_IP6_STATS_FRAGOVERFLOW, "FragOverFlow", "\t\t\t%llu exceeded limit\n") \ 73 X(AOP_IP6_STATS_REASSEMBLED, "FragReassembled","\t\t\t%llu reassembled ok\n") \ 74 X(AOP_IP6_STATS_DELIVERED, "Delivered", "\t\t%llu packet for this host\n") \ 75 X(AOP_IP6_STATS_TOOMANYHDR, "TooManyHdr", "\t\t%llu packet discarded due to too may headers\n") \ 76 /* Output stats */ \ 77 X(AOP_IP6_STATS_LOCALOUT, "LocalOut", "\t%llu packet sent from this host\n") \ 78 X(AOP_IP6_STATS_ODROPPED, "DropNoBuf", "\t\t%llu output packet dropped due to no bufs, etc.\n") \ 79 X(AOP_IP6_STATS_NOROUTE, "NoRoute", "\t\t%llu output packet discarded due to no route\n") \ 80 X(AOP_IP6_STATS_FRAGMENTED, "Fragmented", "\t\t%llu output datagram fragmented\n") \ 81 X(AOP_IP6_STATS_OFRAGMENTS, "OutFraged", "\t\t%llu fragment created\n") \ 82 X(AOP_IP6_STATS_CANTFRAG, "CantFrag", "\t\t%llu datagram that can't be fragmented\n")\ 83 X(__AOP_IP6_STATS_MAX, "", "end of ipv6 stats") 84 85 /* tcp stats definitions */ 86 #define AOP_TCP_STATS_TABLE(X) \ 87 /* Output stats */ \ 88 X(AOP_TCP_STATS_SNDTOTAL, "SndTotalPkt", "\t%llu packet sent\n") \ 89 X(AOP_TCP_STATS_SNDPACK, "SndTotalDP", "\t\t%llu data packet") \ 90 X(AOP_TCP_STATS_SNDBYTE, "SndDataByte", " (%llu byte)\n") \ 91 X(AOP_TCP_STATS_SNDREXMITPACK, "SndDPktReXmt", "\t\t%llu data packet retransmitted") \ 92 X(AOP_TCP_STATS_SNDREXMITBYTE, "SndDByteReXmt"," (%llu byte)\n") \ 93 X(AOP_TCP_STATS_MTURESENT, "MTUReSnd", "\t\t%llu resend initiated by MTU discovery\n") \ 94 X(AOP_TCP_STATS_SNDACKS, "SndAck", "\t\t%llu ack-only packet") \ 95 X(AOP_TCP_STATS_DELACK, "DelayAck", " (%llu delayed)\n") \ 96 X(AOP_TCP_STATS_SNDURG, "SndURG", "\t\t%llu URG only packet\n") \ 97 X(AOP_TCP_STATS_SNDPROBE, "SndWinProb", "\t\t%llu window probe packet\n") \ 98 X(AOP_TCP_STATS_SNDWINUP, "SndWinUpd", "\t\t%llu window update packet\n") \ 99 X(AOP_TCP_STATS_SNDCTRL, "SndCtlPkt", "\t\t%llu control packet\n") \ 100 X(AOP_TCP_STATS_SYNCHALLENGE, "SYNChallenge", "\t\t%llu challenge ACK sent due to unexpected SYN\n") \ 101 X(AOP_TCP_STATS_RSTCHALLENGE, "RSTChallenge", "\t\t%llu challenge ACK sent due to unexpected RST\n") \ 102 \ 103 /* Input stats */ \ 104 X(AOP_TCP_STATS_RCVTOTAL, "RcvTotalPkt", "\t%llu packet received\n") \ 105 X(AOP_TCP_STATS_RCVACKPACK, "RcvAckPkt", "\t\t%llu ack") \ 106 X(AOP_TCP_STATS_RCVACKBYTE, "RcvAckByte", " (for %llu byte)\n") \ 107 X(AOP_TCP_STATS_RCVDUPACK, "RcvDupAck", "\t\t%llu duplicate ack\n") \ 108 X(AOP_TCP_STATS_RCVACKTOOMUCH, "RcvAckUnSnd", "\t\t%llu ack for unsent data\n") \ 109 X(AOP_TCP_STATS_RCVPACK, "RcvPktInSeq", "\t\t%llu packet received in-sequence") \ 110 X(AOP_TCP_STATS_RCVBYTE, "RcvBInSeq", " (%llu byte)\n") \ 111 X(AOP_TCP_STATS_RCVDUPPACK, "RcvDupPkt", "\t\t%llu completely duplicate packet") \ 112 X(AOP_TCP_STATS_RCVDUPBYTE, "RcvDupByte", " (%llu byte)\n") \ 113 X(AOP_TCP_STATS_PAWSDROP, "PAWSDrop", "\t\t%llu old duplicate packet\n") \ 114 X(AOP_TCP_STATS_RCVMEMDROP, "RcvMemDrop", "\t\t%llu received packet dropped due to low memory\n") \ 115 X(AOP_TCP_STATS_RCVPARTDUPPACK, "RcvDupData", "\t\t%llu packet with some dup. data") \ 116 X(AOP_TCP_STATS_RCVPARTDUPBYTE, "RcvPDupByte", " (%llu byte duped)\n") \ 117 X(AOP_TCP_STATS_RCVOOPACK, "RcvOOPkt", "\t\t%llu out-of-order packet") \ 118 X(AOP_TCP_STATS_RCVOOBYTE, "RcvOOByte", " (%llu byte)\n") \ 119 X(AOP_TCP_STATS_RCVPACKAFTERWIN, "RcvAftWinPkt", "\t\t%llu packet of data after window") \ 120 X(AOP_TCP_STATS_RCVBYTEAFTERWIN, "RcvAftWinByte"," (%llu byte)\n") \ 121 X(AOP_TCP_STATS_RCVWINPROBE, "RcvWinProbPkt","\t\t%llu window probe\n") \ 122 X(AOP_TCP_STATS_RCVWINUPD, "RcvWinUpdPkt", "\t\t%llu window update packet\n") \ 123 X(AOP_TCP_STATS_RCVAFTERCLOSE, "RcvAftCloPkt", "\t\t%llu packet received after close\n") \ 124 X(AOP_TCP_STATS_BADRST, "BadRST", "\t\t%llu bad reset\n") \ 125 X(AOP_TCP_STATS_RCVBADSUM, "RcvBadCsum", "\t\t%llu discarded for bad checksum\n") \ 126 X(AOP_TCP_STATS_RCVBADOFF, "RcvBadOff", "\t\t%llu discarded for bad header offset field\n") \ 127 X(AOP_TCP_STATS_RCVSHORT, "RcvTooShort", "\t\t%llu discarded because packet too short\n") \ 128 X(AOP_TCP_STATS_CONNATTEMPT, "ConnInit", "\t\t%llu discarded because packet too short\n") \ 129 \ 130 /* Connection stats */ \ 131 X(AOP_TCP_STATS_CONNECTS, "ConnEst", "\t%llu connection established (including accepts)\n") \ 132 X(AOP_TCP_STATS_CLOSED, "ConnClosed", "\t%llu connection closed") \ 133 X(AOP_TCP_STATS_DROPS, "ConnDrop", " (including %llu drop)\n") \ 134 X(AOP_TCP_STATS_RTTUPDATED, "RTTUpdated", "\t%llu segment updated rtt") \ 135 X(AOP_TCP_STATS_SEGSTIMED, "RTTTimed", " (of %llu attempt)\n") \ 136 X(AOP_TCP_STATS_REXMTTIMEO, "ReXmtTO", "\t%llu retransmit timeout\n") \ 137 X(AOP_TCP_STATS_TIMEOUTDROP, "DropTO", "\t\t%llu connection dropped by rexmit timeout\n") \ 138 X(AOP_TCP_STATS_RXTFINDROP, "ReXmtFINDrop", "\t\t%llu connection dropped after retransmitting FIN\n") \ 139 X(AOP_TCP_STATS_PERSISTTIMEO, "PersistTO", "\t%llu persist timeout\n") \ 140 X(AOP_TCP_STATS_PERSISTDROP, "PersisStateTO","\t\t%llu connection dropped by persist timeout\n") \ 141 X(AOP_TCP_STATS_KEEPTIMEO, "KATO", "\t%llu keepalive timeout\n") \ 142 X(AOP_TCP_STATS_KEEPPROBE, "KAProbe", "\t\t%llu keepalive probe sent\n") \ 143 X(AOP_TCP_STATS_KEEPDROPS, "KADrop", "\t\t%llu connection dropped by keepalive\n") \ 144 \ 145 /* SACK/RACK related stats */ \ 146 X(AOP_TCP_STATS_SACK_RECOVERY_EPISODE, "SACKRecEpi", "\t%llu SACK recovery episode\n") \ 147 X(AOP_TCP_STATS_SACK_REXMITS, "SACKReXmt", "\t%llu segment rexmit in SACK recovery episodes\n") \ 148 X(AOP_TCP_STATS_SACK_REXMIT_BYTES, "SACKReXmtB", "\t%llu byte rexmit in SACK recovery episodes\n") \ 149 X(AOP_TCP_STATS_SACK_RCV_BLOCKS, "SACKRcvBlk", "\t%llu SACK option (SACK blocks) received\n") \ 150 X(AOP_TCP_STATS_SACK_SEND_BLOCKS, "SACKSntBlk", "\t%llu SACK option (SACK blocks) sent\n") \ 151 X(AOP_TCP_STATS_SACK_SBOVERFLOW, "SACKSndBlkOF", "\t%llu SACK scoreboard overflow\n") \ 152 \ 153 X(AOP_TCP_STATS_LIMITED_TXT, "LimitedXmt", "\t%llu limited transmit done\n") \ 154 X(AOP_TCP_STATS_EARLY_REXMT, "EarlyReXmt", "\t%llu early retransmit done\n") \ 155 X(AOP_TCP_STATS_SACK_ACKADV, "SACKAdvAck", "\t%llu time cumulative ack advanced along with SACK\n") \ 156 X(AOP_TCP_STATS_PTO, "ProbTO", "\t%llu probe timeout\n") \ 157 X(AOP_TCP_STATS_RTO_AFTER_PTO, "RTOAfProb", "\t\t%llu time retransmit timeout triggered after probe\n") \ 158 X(AOP_TCP_STATS_PROBE_IF, "ProbeIF", "\t\t%llu time probe packets were sent for an interface\n") \ 159 X(AOP_TCP_STATS_PROBE_IF_CONFLICT, "ProbeIFConfl", "\t\t%llu time couldn't send probe packets for an interface\n") \ 160 X(AOP_TCP_STATS_TLP_RECOVERY, "TLPFastRecvr", "\t\t%llu time fast recovery after tail loss\n") \ 161 X(AOP_TCP_STATS_TLP_RECOVERLASTPKT, "TLPRecvrLPkt", "\t\t%llu time recovered last packet \n") \ 162 X(AOP_TCP_STATS_PTO_IN_RECOVERY, "PTOInRecvr", "\t\t%llu SACK based rescue retransmit\n") \ 163 \ 164 /* DSACK related statistics */ \ 165 X(AOP_TCP_STATS_DSACK_SENT, "DSACKSnd", "\t%llu time DSACK option was sent\n") \ 166 X(AOP_TCP_STATS_DSACK_RECVD, "DSACKRcv", "\t\t%llu time DSACK option was received\n") \ 167 X(AOP_TCP_STATS_DSACK_DISABLE, "DSACKDisable", "\t\t%llu time DSACK was disabled on a connection\n") \ 168 X(AOP_TCP_STATS_DSACK_BADREXMT, "DSACKBadReXmt","\t\t%llu time recovered from bad retransmission using DSACK\n") \ 169 X(AOP_TCP_STATS_DSACK_ACKLOSS, "DSACKAckLoss", "\t\t%llu time ignored DSACK due to ack loss\n") \ 170 X(AOP_TCP_STATS_DSACK_RECVD_OLD, "DSACKRcvOld", "\t\t%llu time ignored old DSACK options\n") \ 171 X(AOP_TCP_STATS_PMTUDBH_REVERTED, "PMTUDBHRevert","\t%llu time PMTU Blackhole detection, size reverted\n") \ 172 X(AOP_TCP_STATS_DROP_AFTER_SLEEP, "DropAPSleep", "\t%llu connection were dropped after long sleep\n") \ 173 X(__AOP_TCP_STATS_MAX, "", "end of tcp stats") 174 175 #define AOP_UDP_STATS_TABLE(X) \ 176 /* Input stats */ \ 177 X(AOP_UDP_STATS_IPACKETS, "RcvPkt", "\t%llu datagram received\n") \ 178 X(AOP_UDP_STATS_HDROPS, "HdrDrop", "\t\t%llu with incomplete header\n") \ 179 X(AOP_UDP_STATS_BADSUM, "BadCsum", "\t\t%llu with bad data length field\n") \ 180 X(AOP_UDP_STATS_BADLEN, "BadLen", "\t\t%llu with bad checksum\n") \ 181 X(AOP_UDP_STATS_NOSUM, "NoCsum", "\t\t%llu with no checksum\n") \ 182 X(AOP_UDP_STATS_NOPORT, "NoPort", "\t\t%llu dropped due to no socket\n") \ 183 X(AOP_UDP_STATS_FULLSOCK, "FullSock", "\t\t%llu dropped due to full socket buffers\n") \ 184 \ 185 /* Output stats */ \ 186 X(AOP_UDP_STATS_OPACKETS, "SndPkt", "\t%llu datagram output\n") \ 187 \ 188 X(__AOP_UDP_STATS_MAX, "", "end of UDP stats") 189 190 #define AOP_DRIVER_STATS_TABLE(X) \ 191 /* AOP driver stats */ \ 192 X(AOP_DRIVER_STATS_TXDROP, "TxDrop", "\t%llu total Tx dropped\n") \ 193 X(AOP_DRIVER_STATS_TXPENDING, "TxPending", "\t%llu total pending Tx not completed\n") \ 194 X(AOP_DRIVER_STATS_RXDROP, "RxDrop", "\t%llu total Rx dropped\n") \ 195 X(AOP_DRIVER_STATS_RXPENDING, "RxPending", "\t%llu total pending Rx not completed\n") \ 196 X(__AOP_DRIVER_STATS_MAX, "", "end of driver stats") 197 198 /* 199 * Common stats operation and macro 200 */ 201 #define EXPAND_TO_ENUMERATION(a, b, c) a, 202 #define EXPAND_TO_STRING(a, b, c) b, 203 #define EXPAND_TO_FORMAT(a, b, c) c, 204 205 #define DEFINE_STATS_STR_FUNC(type, table) \ 206 __attribute__((always_inline)) \ 207 static inline const char * \ 208 type##_str(enum _##type value) \ 209 { \ 210 static const char *table[] = { \ 211 table(EXPAND_TO_STRING) \ 212 }; \ 213 return (table[value]); \ 214 } 215 216 #define DEFINE_STATS_FMT_FUNC(type, table) \ 217 __attribute__((always_inline)) \ 218 static inline const char * \ 219 type##_fmt(enum _##type value) \ 220 { \ 221 static const char *table[] = { \ 222 table(EXPAND_TO_FORMAT) \ 223 }; \ 224 return (table[value]); \ 225 } 226 227 #define STATS_ALIGN 16 /* align for vector instruction */ 228 229 #define STATS_REGISTER(name, NAME) \ 230 enum _##name { NAME##_TABLE(EXPAND_TO_ENUMERATION) }; \ 231 struct name { \ 232 uint64_t _arr[__##NAME##_MAX]; \ 233 } __attribute__((aligned(STATS_ALIGN))); \ 234 DEFINE_STATS_STR_FUNC(name, NAME##_TABLE) \ 235 DEFINE_STATS_FMT_FUNC(name, NAME##_TABLE) 236 237 /* Stats registration stub */ 238 STATS_REGISTER(aop_ip_stats, AOP_IP_STATS); 239 STATS_REGISTER(aop_ip6_stats, AOP_IP6_STATS); 240 STATS_REGISTER(aop_tcp_stats, AOP_TCP_STATS); 241 STATS_REGISTER(aop_udp_stats, AOP_UDP_STATS); 242 STATS_REGISTER(aop_driver_stats, AOP_DRIVER_STATS); 243 244 #undef STATS_REGISTER 245 #undef DEFINE_STATS_STR_FUNC 246 #undef EXPAND_TO_STRING 247 #undef EXPAND_TO_ENUMERATION 248 249 #define NET_AOP_PROTOCOL_STATS "net.aop.protocol_stats" 250 #define NET_AOP_DRIVER_STATS "net.aop.driver_stats" 251 #define NET_AOP_ACTIVITY_BITMAP "net.aop.proc_activity_bitmaps" 252 253 struct net_aop_protocol_stats { 254 struct aop_ip_stats aop_ip; 255 struct aop_ip6_stats aop_ip6; 256 struct aop_tcp_stats aop_tcp; 257 struct aop_udp_stats aop_udp; 258 }; 259 260 struct net_aop_global_stats { 261 struct net_aop_protocol_stats aop_proto_stats; 262 struct aop_driver_stats aop_driver; 263 }__attribute__((aligned(64))); 264 265 struct aop_activity_bitmap { 266 /* 267 * `start` maintains the start time of the 268 * bitmap. The value is set based on 269 * mach_continuous_time(). 270 */ 271 uint64_t start; 272 /* 273 * AOP maintains a larger bitmap to track 274 * state when AP goes to sleep. A bitmap of 275 * size 8 allows tracking network activity for 276 * more than 60 mins. 277 */ 278 uint64_t bitmap[8]; 279 }; 280 281 #define AOP_MAX_PROC_BUNDLE_ID_LEN 256 282 struct aop_proc_activity_bitmap { 283 char proc_bundle_id[AOP_MAX_PROC_BUNDLE_ID_LEN]; 284 struct aop_activity_bitmap wifi_bitmap; 285 struct aop_activity_bitmap cell_bitmap; 286 }; 287 288 #endif /*_NET_AOP_STATS_H_*/ 289