xref: /xnu-11215.61.5/bsd/net/droptap.h (revision 4f1223e81cd707a65cc109d0b8ad6653699da3c4)
1 /*
2  * Copyright (c) 2024 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_DROPTAP_H_
30 #define _NET_DROPTAP_H_
31 
32 #ifdef PRIVATE
33 #include <net/pktap.h>
34 
35 #define DROPTAP_IFNAME "droptap"
36 #define DROPTAP_IFXNAMESIZE (IF_NAMESIZE + 8)
37 
38 #define DROPTAP_DROPFUNC_MAXLEN 64
39 
40 /*
41  * Droptap header is a special type of pktap header with droptap-specific
42  * metadata.
43  */
44 struct droptap_header {
45 	struct pktap_header     dth_pktap_hdr;
46 	uint32_t                dth_dropreason;
47 	uint8_t                 dth_dropfunc_size;
48 	uint16_t                dth_dropline;
49 	char                    dth_dropfunc[DROPTAP_DROPFUNC_MAXLEN];
50 };
51 
52 /*
53  * If we do not want to store function name and line number, client should pass
54  * NULL to dropfunc, and then droptap internally sets dth_dropfunc_size to 0 and
55  * copies fields up to dth_dropfunc_size to bpf.
56  */
57 #define DROPTAP_HDR_SIZE(dtaphdr)                                                                           \
58 	(((dtaphdr)->dth_dropfunc_size == 0) ?                                                              \
59 	    (__offsetof(struct droptap_header, dth_dropfunc_size) + sizeof((dtaphdr)->dth_dropfunc_size)) : \
60 	    (__offsetof(struct droptap_header, dth_dropfunc) + (dtaphdr)->dth_dropfunc_size + 1))
61 
62 /*
63  * Drop Reason is a 32-bit encoding of drop code, domain, and component.
64  *
65  *  Reserved  Component     Domain       Drop Code
66  * ╭─────────┬─────────┬─────────────┬───────────────╮
67  * │    4    │    4    │      8      │       16      │
68  * ╰─────────┴─────────┴─────────────┴───────────────╯
69  * ╰─────────────────────────────────────────────────╯
70  *                   Drop Reason
71  *
72  * [ 15:0] Drop Code: Specific reason why the drop happened (e.g. AQM full)
73  * [23:16] Domain   : Which domain the drop happened (e.g. Flowswitch, TCP, IP)
74  * [27:24] Component: Which component the drop happened (e.g. Skywalk, BSD, driver)
75  * [31:28] Reserved : Reserved for future use
76  *
77  */
78 #define DROP_COMPONENT_MASK   0x0f000000
79 #define DROP_COMPONENT_OFFSET 24
80 #define DROP_COMPONENT_MAX    0x0f
81 #define DROP_DOMAIN_MASK      0x00ff0000
82 #define DROP_DOMAIN_OFFSET    16
83 #define DROP_DOMAIN_MAX       0xff
84 #define DROP_CODE_MASK        0x0000ffff
85 #define DROP_CODE_OFFSET      0
86 #define DROP_CODE_MAX         0xffff
87 
88 /* 32-bit Drop Reason */
89 #define DROP_REASON(component, domain, code) \
90 	(((unsigned)((component) &   0x0f) << DROP_COMPONENT_OFFSET) | \
91 	 ((unsigned)((domain)    &   0xff) << DROP_DOMAIN_OFFSET)    | \
92 	 ((unsigned)((code)      & 0xffff) << DROP_CODE_OFFSET))
93 
94 /* All components */
95 #define DROPTAP_SKYWALK 1
96 #define DROPTAP_BSD     2
97 
98 /* All domains for Skywalk component */
99 #define DROPTAP_FSW     1
100 #define DROPTAP_NETIF   2
101 #define _DROPTAP_PAD_3  3
102 #define _DROPTAP_PAD_4  4
103 #define DROPTAP_AQM     5
104 
105 /* All domains for BSD component */
106 #define DROPTAP_TCP     1
107 #define DROPTAP_UDP     2
108 #define DROPTAP_IP      3
109 #define DROPTAP_SOCK    4
110 #define _DROPTAP_PAD_5  5
111 #define DROPTAP_IPSEC   6
112 #define DROPTAP_IP6     7
113 
114 #define DROPTAP_UNSPEC  0
115 
116 #define DROP_REASON_LIST                                                                                                         \
117 	X(DROP_REASON_UNSPECIFIED,                  DROPTAP_UNSPEC,  DROPTAP_UNSPEC, DROPTAP_UNSPEC, "Drop reason not specified")    \
118 	/* Skywalk component */                                                                                                      \
119 	X(DROP_REASON_FSW_PP_ALLOC_FAILED,          DROPTAP_SKYWALK, DROPTAP_FSW,  1,  "Flowswitch packet alloc failed")             \
120 	X(DROP_REASON_RX_DST_RING_FULL,             DROPTAP_SKYWALK, DROPTAP_FSW,  2,  "Flowswitch Rx destination ring full")        \
121 	X(DROP_REASON_FSW_QUIESCED,                 DROPTAP_SKYWALK, DROPTAP_FSW,  3,  "Flowswitch detached")                        \
122 	X(DROP_REASON_FSW_IFNET_NOT_ATTACHED,       DROPTAP_SKYWALK, DROPTAP_FSW,  4,  "Flowswitch ifnet not attached")              \
123 	X(DROP_REASON_FSW_DEMUX_FAILED,             DROPTAP_SKYWALK, DROPTAP_FSW,  5,  "Flowswitch demux error")                     \
124 	X(DROP_REASON_FSW_TX_DEVPORT_NOT_ATTACHED,  DROPTAP_SKYWALK, DROPTAP_FSW,  6,  "Flowswitch destination nexus port inactive") \
125 	X(DROP_REASON_FSW_TX_FLOW_EXTRACT_FAILED,   DROPTAP_SKYWALK, DROPTAP_FSW,  7,  "Flowswitch flow extract error")              \
126 	X(DROP_REASON_FSW_TX_FRAG_BAD_CONT,         DROPTAP_SKYWALK, DROPTAP_FSW,  8,  "Flowswitch invalid continuation fragment")   \
127 	X(DROP_REASON_FSW_TX_FLOW_NOT_FOUND,        DROPTAP_SKYWALK, DROPTAP_FSW,  9,  "Flowswitch flow lookup failed")              \
128 	X(DROP_REASON_FSW_TX_RESOLV_PENDING,        DROPTAP_SKYWALK, DROPTAP_FSW,  10, "Flowswitch resolution pending")              \
129 	X(DROP_REASON_FSW_TX_RESOLV_FAILED,         DROPTAP_SKYWALK, DROPTAP_FSW,  11, "Flowswitch resolution failed")               \
130 	X(DROP_REASON_FSW_FLOW_NONVIABLE,           DROPTAP_SKYWALK, DROPTAP_FSW,  12, "Flowswitch flow not viable")                 \
131 	X(DROP_REASON_FSW_RX_RING_NOT_FOUND,        DROPTAP_SKYWALK, DROPTAP_FSW,  13, "Flowswitch Rx ring not found")               \
132 	X(DROP_REASON_FSW_RX_PKT_NOT_FINALIZED,     DROPTAP_SKYWALK, DROPTAP_FSW,  14, "Flowswitch packet not finalized")            \
133 	X(DROP_REASON_FSW_FLOW_TRACK_ERR,           DROPTAP_SKYWALK, DROPTAP_FSW,  15, "Flowswitch flow tracker error")              \
134 	X(DROP_REASON_FSW_PKT_COPY_FAILED,          DROPTAP_SKYWALK, DROPTAP_FSW,  16, "Flowswitch packet copy failed")              \
135 	X(DROP_REASON_FSW_GSO_FAILED,               DROPTAP_SKYWALK, DROPTAP_FSW,  17, "Flowswitch GSO failed")                      \
136 	X(DROP_REASON_FSW_GSO_NOMEM_PKT,            DROPTAP_SKYWALK, DROPTAP_FSW,  18, "Flowswitch GSO not enough packet memory")    \
137 	X(DROP_REASON_FSW_GSO_NOMEM_MBUF,           DROPTAP_SKYWALK, DROPTAP_FSW,  19, "Flowswitch GSO not enough mbuf memory")      \
138 	X(DROP_REASON_FSW_DST_NXPORT_INVALID,       DROPTAP_SKYWALK, DROPTAP_FSW,  20, "Flowswitch dst nexus port invalid")          \
139 	X(DROP_REASON_AQM_FULL,                     DROPTAP_SKYWALK, DROPTAP_AQM,  1,  "AQM full")                                   \
140 	X(DROP_REASON_AQM_COMPRESSED,               DROPTAP_SKYWALK, DROPTAP_AQM,  2,  "AQM compressed")                             \
141 	X(DROP_REASON_AQM_BK_SYS_THROTTLED,         DROPTAP_SKYWALK, DROPTAP_AQM,  3,  "AQM BK_SYS throttled")                       \
142 	X(DROP_REASON_AQM_PURGE_FLOW,               DROPTAP_SKYWALK, DROPTAP_AQM,  4,  "AQM purge flow")                             \
143 	X(DROP_REASON_AQM_DROP,                     DROPTAP_SKYWALK, DROPTAP_AQM,  5,  "AQM drop")                             \
144 	/* Socket */                                                                                                                 \
145 	X(DROP_REASON_FULL_SOCK_RCVBUF,             DROPTAP_BSD,     DROPTAP_SOCK, 1,  "Socket receive buffer full")                 \
146 	/* TCP */                                                                                                                    \
147 	X(DROP_REASON_TCP_RST,                      DROPTAP_BSD,     DROPTAP_TCP,  1,  "TCP connection reset")                       \
148 	/* IP */                                                                                                                     \
149 	X(DROP_REASON_IP_UNKNOWN_MULTICAST_GROUP,   DROPTAP_BSD,     DROPTAP_IP,   2, "IP unknown multicast group join")             \
150 	X(DROP_REASON_IP_INVALID_ADDR,              DROPTAP_BSD,     DROPTAP_IP,   3, "Invalid IP address")                          \
151 	X(DROP_REASON_IP_TOO_SHORT,                 DROPTAP_BSD,     DROPTAP_IP,   4, "IP packet too short")                         \
152 	X(DROP_REASON_IP_TOO_SMALL,                 DROPTAP_BSD,     DROPTAP_IP,   5, "IP header too small")                         \
153 	X(DROP_REASON_IP_RCV_IF_NO_MATCH,           DROPTAP_BSD,     DROPTAP_IP,   6, "IP receive interface no match")               \
154 	X(DROP_REASON_IP_CANNOT_FORWARD,            DROPTAP_BSD,     DROPTAP_IP,   7, "IP cannot forward")                           \
155 	X(DROP_REASON_IP_BAD_VERSION,               DROPTAP_BSD,     DROPTAP_IP,   8, "IP bad version")                              \
156 	X(DROP_REASON_IP_BAD_CHECKSUM,              DROPTAP_BSD,     DROPTAP_IP,   9, "IP bad checksum")                             \
157 	X(DROP_REASON_IP_BAD_HDR_LENGTH,            DROPTAP_BSD,     DROPTAP_IP,   10, "IP bad header length")                       \
158 	X(DROP_REASON_IP_BAD_LENGTH,                DROPTAP_BSD,     DROPTAP_IP,   11, "IP bad length")                              \
159 	X(DROP_REASON_IP_BAD_TTL,                   DROPTAP_BSD,     DROPTAP_IP,   12, "IP bad TTL")                                 \
160 	X(DROP_REASON_IP_NO_PROTO,                  DROPTAP_BSD,     DROPTAP_IP,   13, "IP unknown protocol")                        \
161 	X(DROP_REASON_IP_FRAG_NOT_ACCEPTED,         DROPTAP_BSD,     DROPTAP_IP,   14, "IP fragment not accepted")                   \
162 	X(DROP_REASON_IP_FRAG_DROPPED,              DROPTAP_BSD,     DROPTAP_IP,   15, "IP fragment dropped")                        \
163 	X(DROP_REASON_IP_FRAG_TIMEOUT,              DROPTAP_BSD,     DROPTAP_IP,   16, "IP fragment timeout")                        \
164 	X(DROP_REASON_IP_FRAG_TOO_MANY,             DROPTAP_BSD,     DROPTAP_IP,   17, "IP fragment too many")                       \
165 	X(DROP_REASON_IP_FRAG_TOO_LONG,             DROPTAP_BSD,     DROPTAP_IP,   18, "IP fragment too long")                       \
166 	X(DROP_REASON_IP_FRAG_DRAINED,              DROPTAP_BSD,     DROPTAP_IP,   19, "IP fragment drained")                        \
167 	X(DROP_REASON_IP_FILTER_DROP,               DROPTAP_BSD,     DROPTAP_IP,   20, "IP filter drop")                             \
168 	X(DROP_REASON_IP_FRAG_TOO_SMALL,            DROPTAP_BSD,     DROPTAP_IP,   21, "IP too small to fragment")                   \
169 	X(DROP_REASON_IP_FRAG_NO_MEM,               DROPTAP_BSD,     DROPTAP_IP,   22, "IP no memory for fragmentation")             \
170 	X(DROP_REASON_IP_CANNOT_FRAGMENT,           DROPTAP_BSD,     DROPTAP_IP,   23, "IP cannot fragment")                         \
171 	X(DROP_REASON_IP_OUTBOUND_IPSEC_POLICY,     DROPTAP_BSD,     DROPTAP_IP,   24, "IP outbound IPsec policy")                   \
172 	X(DROP_REASON_IP_ZERO_NET,                  DROPTAP_BSD,     DROPTAP_IP,   25, "IP to network zero")                         \
173 	X(DROP_REASON_IP_SRC_ADDR_NO_AVAIL,         DROPTAP_BSD,     DROPTAP_IP,   26, "IP source address not available")            \
174 	X(DROP_REASON_IP_DST_ADDR_NO_AVAIL,         DROPTAP_BSD,     DROPTAP_IP,   27, "IP destination address not available")       \
175 	X(DROP_REASON_IP_TO_RESTRICTED_IF,          DROPTAP_BSD,     DROPTAP_IP,   28, "IP packet to a restricted interface")        \
176 	X(DROP_REASON_IP_NO_ROUTE,                  DROPTAP_BSD,     DROPTAP_IP,   29, "IP no route")                                \
177 	X(DROP_REASON_IP_IF_CANNOT_MULTICAST,       DROPTAP_BSD,     DROPTAP_IP,   30, "IP multicast not supported by interface")    \
178 	X(DROP_REASON_IP_SRC_ADDR_ANY,              DROPTAP_BSD,     DROPTAP_IP,   31, "IP source address any")                      \
179 	X(DROP_REASON_IP_IF_CANNOT_BROADCAST,       DROPTAP_BSD,     DROPTAP_IP,   32, "IP broadcast not supported by interface")    \
180 	X(DROP_REASON_IP_BROADCAST_NOT_ALLOWED,     DROPTAP_BSD,     DROPTAP_IP,   33, "IP broadcast not allowed")                   \
181 	X(DROP_REASON_IP_BROADCAST_TOO_BIG,         DROPTAP_BSD,     DROPTAP_IP,   34, "IP broadcast too big for MTU")               \
182 	X(DROP_REASON_IP_FILTER_TSO,                DROPTAP_BSD,     DROPTAP_IP,   35, "TSO packet to IP filter")                    \
183 	X(DROP_REASON_IP_NECP_POLICY_NO_ALLOW_IF,   DROPTAP_BSD,     DROPTAP_IP,   36, "NECP not allowed on interface")              \
184 	X(DROP_REASON_IP_NECP_POLICY_DROP,          DROPTAP_BSD,     DROPTAP_IP,   37, "NECP drop")                                  \
185 	X(DROP_REASON_IP_NECP_POLICY_SOCKET_DIVERT, DROPTAP_BSD,     DROPTAP_IP,   38, "NECP socket divert")                         \
186 	X(DROP_REASON_IP_NECP_POLICY_TUN_NO_ALLOW_IF, DROPTAP_BSD,   DROPTAP_IP,   39, "NECP tunnel not allowed on interface")       \
187 	X(DROP_REASON_IP_NECP_POLICY_TUN_REBIND_NO_ALLOW_IF, DROPTAP_BSD,     DROPTAP_IP,   40, "NECP rebind not allowed on interface") \
188 	X(DROP_REASON_IP_NECP_POLICY_TUN_NO_REBIND_IF, DROPTAP_BSD,  DROPTAP_IP,   41, "NECP rebind not allowed on interface")       \
189 	X(DROP_REASON_IP_NECP_NO_ALLOW_IF,          DROPTAP_BSD,     DROPTAP_IP,   42, "NECP packet not allowed on interface")       \
190 	X(DROP_REASON_IP_ENOBUFS,                   DROPTAP_BSD,     DROPTAP_IP,   43, "IP No buffer space available")               \
191 	X(DROP_REASON_IP_ILLEGAL_PORT,              DROPTAP_BSD,     DROPTAP_IP,   44, "IP Illegal port")                            \
192 	X(DROP_REASON_IP_UNREACHABLE_PORT,          DROPTAP_BSD,     DROPTAP_IP,   45, "IP Unreachable port")                        \
193 	X(DROP_REASON_IP_MULTICAST_NO_PORT,         DROPTAP_BSD,     DROPTAP_IP,   46, "IP Multicast no port")                       \
194 	X(DROP_REASON_IP_EISCONN,                   DROPTAP_BSD,     DROPTAP_IP,   47, "IP Socket is already connected")             \
195 	X(DROP_REASON_IP_EAFNOSUPPORT,              DROPTAP_BSD,     DROPTAP_IP,   48, "IP Address family not supported by protocol family") \
196 	X(DROP_REASON_IP_NO_SOCK,                   DROPTAP_BSD,     DROPTAP_IP,   49, "IP No matching sock") \
197 	/* IPsec */                                                                                                                  \
198 	X(DROP_REASON_IPSEC_REJECT,                 DROPTAP_BSD,     DROPTAP_IPSEC,1,  "IPsec reject")                               \
199 	/* IPv6 */                                                                                                                   \
200 	X(DROP_REASON_IP6_OPT_DISCARD,              DROPTAP_BSD,     DROPTAP_IP6,  1, "IPv6 discard option")                         \
201 	X(DROP_REASON_IP6_IF_IPV6_DISABLED,         DROPTAP_BSD,     DROPTAP_IP6,  2, "IPv6 is disabled on the interface")           \
202 	X(DROP_REASON_IP6_BAD_SCOPE,                DROPTAP_BSD,     DROPTAP_IP6,  3, "IPv6 bad scope")                              \
203 	X(DROP_REASON_IP6_UNPROXIED_NS,             DROPTAP_BSD,     DROPTAP_IP6,  4, "IPv6 unproxied mistargeted Neighbor Solicitation") \
204 	X(DROP_REASON_IP6_BAD_OPTION,               DROPTAP_BSD,     DROPTAP_IP6,  5, "IPv6 bad option")                             \
205 	X(DROP_REASON_IP6_TOO_MANY_OPTIONS,         DROPTAP_BSD,     DROPTAP_IP6,  6, "IPv6 too many header options")                \
206 	X(DROP_REASON_IP6_BAD_PATH_MTU,             DROPTAP_BSD,     DROPTAP_IP6,  7, "IPv6 bad path MTU")                           \
207 	X(DROP_REASON_IP6_NO_PREFERRED_SRC_ADDR,    DROPTAP_BSD,     DROPTAP_IP6,  8, "IPv6 no preferred source address")            \
208 	X(DROP_REASON_IP6_BAD_HLIM,                 DROPTAP_BSD,     DROPTAP_IP6,  9, "IPv6 bad HLIM")                               \
209 	X(DROP_REASON_IP6_BAD_DAD,                  DROPTAP_BSD,     DROPTAP_IP6,  10, "IPv6 bad DAD")                               \
210 	X(DROP_REASON_IP6_NO_ND6ALT_IF,             DROPTAP_BSD,     DROPTAP_IP6,  11, "IPv6 no ND6ALT interface")                   \
211 	X(DROP_REASON_IP6_BAD_ND_STATE,             DROPTAP_BSD,     DROPTAP_IP6,  12, "IPv6 Bad ND state")                          \
212 	X(DROP_REASON_IP6_ONLY,                     DROPTAP_BSD,     DROPTAP_IP6,  13, "IPv6 Only")                                  \
213 	X(DROP_REASON_IP6_ADDR_UNSPECIFIED,         DROPTAP_BSD,     DROPTAP_IP6,  14, "IPv6 Address is unspecified")                \
214 
215 
216 typedef enum drop_reason : uint32_t {
217 #define X(reason, component, domain, code, ...) \
218 	reason = DROP_REASON(component, domain, code),
219 	DROP_REASON_LIST
220 #undef X
221 } drop_reason_t;
222 
223 __attribute__((always_inline))
224 static inline const char *
drop_reason_str(drop_reason_t value)225 drop_reason_str(drop_reason_t value)
226 {
227 	switch (value) {
228 #define X(reason, ...) \
229 	case (reason): return #reason;
230 		DROP_REASON_LIST
231 #undef X
232 	default:
233 		return NULL;
234 	}
235 	;
236 }
237 
238 #ifdef BSD_KERNEL_PRIVATE
239 
240 #define DROPTAP_FLAG_DIR_IN     0x0001
241 #define DROPTAP_FLAG_DIR_OUT    0x0002
242 #define DROPTAP_FLAG_L2_MISSING 0x0004
243 
244 extern uint32_t droptap_total_tap_count;
245 extern uint32_t droptap_verbose;
246 
247 extern void droptap_init(void);
248 #if SKYWALK
249 #include <skywalk/os_skywalk.h>
250 extern void droptap_input_packet(kern_packet_t, drop_reason_t, const char *,
251     uint16_t, uint16_t, struct ifnet *, pid_t, const char *,
252     pid_t, const char *, uint8_t, uint32_t);
253 extern void droptap_output_packet(kern_packet_t, drop_reason_t, const char *,
254     uint16_t, uint16_t, struct ifnet *, pid_t, const char *, pid_t, const char *,
255     uint8_t, uint32_t);
256 typedef void
257 (*drop_func_t)(kern_packet_t, drop_reason_t, const char *, uint16_t, uint16_t,
258     struct ifnet *, pid_t, const char *, pid_t, const char *,
259     uint8_t, uint32_t);
260 #endif /* SKYWALK */
261 extern void droptap_input_mbuf(struct mbuf *, drop_reason_t, const char *,
262     uint16_t, uint16_t, struct ifnet *, char *);
263 extern void droptap_output_mbuf(struct mbuf *, drop_reason_t, const char *,
264     uint16_t, uint16_t, struct ifnet *);
265 
266 
267 #endif /* BSD_KERNEL_PRIVATE */
268 #endif /* PRIVATE */
269 #endif /* _NET_DROPTAP_H */
270