xref: /xnu-12377.1.9/bsd/net/dlil_var_private.h (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /*
2  * Copyright (c) 1999-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  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
30  * support for mandatory and extensible security protections.  This notice
31  * is included in support of clause 2.2 (b) of the Apple Public License,
32  * Version 2.0.
33  */
34 #ifndef DLIL_VAR_PRIVATE_H
35 #define DLIL_VAR_PRIVATE_H
36 
37 #include "kern/kern_types.h"
38 #include <sys/kernel_types.h>
39 
40 
41 #include <stddef.h>
42 #include <ptrauth.h>
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/mbuf.h>
49 #include <sys/socket.h>
50 #include <sys/domain.h>
51 #include <sys/user.h>
52 #include <sys/random.h>
53 #include <sys/socketvar.h>
54 #include <net/if_dl.h>
55 #include <net/if.h>
56 #include <net/route.h>
57 #include <net/if_var.h>
58 #include <net/dlil.h>
59 #include <net/if_arp.h>
60 #include <net/iptap.h>
61 #include <net/pktap.h>
62 #include <net/droptap.h>
63 #include <net/nwk_wq.h>
64 #include <sys/kern_event.h>
65 #include <sys/kdebug.h>
66 #include <sys/mcache.h>
67 #include <sys/syslog.h>
68 #include <sys/protosw.h>
69 #include <sys/priv.h>
70 
71 #include <kern/assert.h>
72 #include <kern/task.h>
73 #include <kern/thread.h>
74 #include <kern/sched_prim.h>
75 #include <kern/locks.h>
76 #include <kern/kalloc.h>
77 #include <kern/zalloc.h>
78 
79 #include <net/kpi_protocol.h>
80 #include <net/kpi_interface.h>
81 #include <net/if_types.h>
82 #include <net/if_ipsec.h>
83 #include <net/if_llreach.h>
84 #include <net/if_utun.h>
85 #include <net/kpi_interfacefilter.h>
86 #include <net/classq/classq.h>
87 #include <net/classq/classq_sfb.h>
88 #include <net/flowhash.h>
89 #include <net/ntstat.h>
90 
91 #include <net/net_api_stats.h>
92 #include <net/if_ports_used.h>
93 #include <net/if_vlan_var.h>
94 #include <netinet/in.h>
95 #if INET
96 #include <netinet/in_var.h>
97 #include <netinet/igmp_var.h>
98 #include <netinet/ip_var.h>
99 #include <netinet/tcp.h>
100 #include <netinet/tcp_var.h>
101 #include <netinet/udp.h>
102 #include <netinet/udp_var.h>
103 #include <netinet/if_ether.h>
104 #include <netinet/in_pcb.h>
105 #include <netinet/in_tclass.h>
106 #include <netinet/ip.h>
107 #include <netinet/ip_icmp.h>
108 #include <netinet/icmp_var.h>
109 #endif /* INET */
110 
111 #include <net/nat464_utils.h>
112 #include <netinet6/in6_var.h>
113 #include <netinet6/nd6.h>
114 #include <netinet6/mld6_var.h>
115 #include <netinet6/scope6_var.h>
116 #include <netinet/ip6.h>
117 #include <netinet/icmp6.h>
118 #include <net/pf_pbuf.h>
119 #include <libkern/OSAtomic.h>
120 #include <libkern/tree.h>
121 
122 #include <dev/random/randomdev.h>
123 #include <machine/machine_routines.h>
124 
125 #include <mach/thread_act.h>
126 #include <mach/sdt.h>
127 
128 #if CONFIG_MACF
129 #include <sys/kauth.h>
130 #include <security/mac_framework.h>
131 #include <net/ethernet.h>
132 #include <net/firewire.h>
133 #endif
134 
135 #if PF
136 #include <net/pfvar.h>
137 #endif /* PF */
138 #include <net/pktsched/pktsched.h>
139 #include <net/pktsched/pktsched_netem.h>
140 
141 #if NECP
142 #include <net/necp.h>
143 #endif /* NECP */
144 
145 #if SKYWALK
146 #include <skywalk/packet/packet_queue.h>
147 #include <skywalk/nexus/netif/nx_netif.h>
148 #include <skywalk/nexus/flowswitch/nx_flowswitch.h>
149 #endif /* SKYWALK */
150 
151 #include <net/sockaddr_utils.h>
152 
153 #include <os/log.h>
154 
155 #ifndef BSD_KERNEL_PRIVATE
156 #error __FILE__ ## " can only be privately included"
157 #endif /* BSD_KERNEL_PRIVATE */
158 
159 
160 #define DBG_LAYER_BEG           DLILDBG_CODE(DBG_DLIL_STATIC, 0)
161 #define DBG_LAYER_END           DLILDBG_CODE(DBG_DLIL_STATIC, 2)
162 #define DBG_FNC_DLIL_INPUT      DLILDBG_CODE(DBG_DLIL_STATIC, (1 << 8))
163 #define DBG_FNC_DLIL_OUTPUT     DLILDBG_CODE(DBG_DLIL_STATIC, (2 << 8))
164 #define DBG_FNC_DLIL_IFOUT      DLILDBG_CODE(DBG_DLIL_STATIC, (3 << 8))
165 
166 #define IF_DATA_REQUIRE_ALIGNED_64(f)   \
167 	static_assert(!(offsetof(struct if_data_internal, f) % sizeof(u_int64_t)))
168 
169 #define IFNET_IF_DATA_REQUIRE_ALIGNED_64(f)     \
170 	static_assert(!(offsetof(struct ifnet, if_data.f) % sizeof(u_int64_t)))
171 
172 enum {
173 	kProtoKPI_v1    = 1,
174 	kProtoKPI_v2    = 2
175 };
176 
177 #if 1
178 #define DLIL_PRINTF     printf
179 #else
180 #define DLIL_PRINTF     kprintf
181 #endif
182 
183 
184 extern unsigned int net_rxpoll;
185 extern unsigned int net_affinity;
186 extern unsigned int net_async;     /* 0: synchronous, 1: asynchronous */
187 
188 #if SKYWALK
189 /*
190  * Skywalk ifnet attachment modes.
191  */
192 extern uint32_t if_attach_nx;
193 extern uint32_t if_enable_fsw_ip_netagent;
194 extern uint32_t if_enable_fsw_transport_netagent;
195 extern uint32_t if_netif_all;
196 #endif /* SKYWALK */
197 
198 #define DLIL_SDLDATALEN \
199 	(DLIL_SDLMAXLEN - offsetof(struct sockaddr_dl, sdl_data[0]))
200 
201 
202 /*
203  * In the common case, the LL address is stored in the
204  * `dl_if_lladdr' member of the `dlil_ifnet'. This is sufficient
205  * for LL addresses that do not exceed the `DLIL_SDLMAXLEN' constant.
206  */
207 struct dl_if_lladdr_std {
208 	struct ifaddr   ifa;
209 	u_int8_t        addr_sdl_bytes[DLIL_SDLMAXLEN];
210 	u_int8_t        mask_sdl_bytes[DLIL_SDLMAXLEN];
211 };
212 
213 /*
214  * However, in some rare cases we encounter LL addresses which
215  * would not fit in the `DLIL_SDLMAXLEN' limitation. In such cases
216  * we allocate the storage in the permanent arena, using this memory layout.
217  */
218 struct dl_if_lladdr_xtra_space {
219 	struct ifaddr   ifa;
220 	u_int8_t        addr_sdl_bytes[SOCK_MAXADDRLEN];
221 	u_int8_t        mask_sdl_bytes[SOCK_MAXADDRLEN];
222 };
223 
224 struct dlil_ifnet {
225 	struct ifnet    dl_if;                  /* public ifnet */
226 	/*
227 	 * DLIL private fields, protected by dl_if_lock
228 	 */
229 	decl_lck_mtx_data(, dl_if_lock);
230 	TAILQ_ENTRY(dlil_ifnet) dl_if_link;     /* dlil_ifnet link */
231 	u_int32_t dl_if_flags;                  /* flags (below) */
232 	u_int32_t dl_if_refcnt;                 /* refcnt */
233 	void    *dl_if_uniqueid __sized_by_or_null(dl_if_uniqueid_len);                /* unique interface id */
234 	size_t  dl_if_uniqueid_len;             /* length of the unique id */
235 	char    dl_if_namestorage[IFNAMSIZ];    /* interface name storage */
236 	char    dl_if_xnamestorage[IFXNAMSIZ];  /* external name storage */
237 	struct dl_if_lladdr_std dl_if_lladdr;   /* link-level address storage*/
238 	u_int8_t dl_if_descstorage[IF_DESCSIZE]; /* desc storage */
239 	u_int8_t dl_if_permanent_ether[ETHER_ADDR_LEN]; /* permanent address */
240 	u_int8_t dl_if_permanent_ether_is_set;
241 	u_int8_t dl_if_unused;
242 	struct dlil_threading_info dl_if_inpstorage; /* input thread storage */
243 	ctrace_t        dl_if_attach;           /* attach PC stacktrace */
244 	ctrace_t        dl_if_detach;           /* detach PC stacktrace */
245 };
246 
247 
248 /* Values for dl_if_flags (private to DLIL) */
249 #define DLIF_INUSE      0x1     /* DLIL ifnet recycler, ifnet in use */
250 #define DLIF_REUSE      0x2     /* DLIL ifnet recycles, ifnet is not new */
251 
252 
253 #define DLIL_TO_IFP(s)  (&s->dl_if)
254 #define IFP_TO_DLIL(s)  ((struct dlil_ifnet *)s)
255 
256 struct ifnet_filter {
257 	TAILQ_ENTRY(ifnet_filter)       filt_next;
258 	u_int32_t                       filt_skip;
259 	u_int32_t                       filt_flags;
260 	ifnet_t                         filt_ifp;
261 	const char                      *filt_name;
262 	void                            *filt_cookie;
263 	protocol_family_t               filt_protocol;
264 	iff_input_func                  filt_input;
265 	iff_output_func                 filt_output;
266 	iff_event_func                  filt_event;
267 	iff_ioctl_func                  filt_ioctl;
268 	iff_detached_func               filt_detached;
269 };
270 
271 
272 /* Mbuf queue used for freeing the excessive mbufs */
273 typedef MBUFQ_HEAD(dlil_freeq) dlil_freeq_t;
274 
275 typedef TAILQ_HEAD(, dlil_ifnet) dlil_ifnet_queue_t;
276 
277 extern dlil_ifnet_queue_t dlil_ifnet_head;
278 
279 struct proto_input_entry;
280 
281 /*
282  * Utility routines
283  */
284 extern kern_return_t dlil_affinity_set(struct thread *, u_int32_t);
285 extern boolean_t packet_has_vlan_tag(struct mbuf * m);
286 
287 /*
288  * Monitor routines.
289  */
290 extern void if_flt_monitor_busy(struct ifnet *);
291 extern void if_flt_monitor_unbusy(struct ifnet *);
292 extern void if_flt_monitor_enter(struct ifnet *);
293 extern void if_flt_monitor_leave(struct ifnet *);
294 
295 /*
296  * Allocation routines
297  */
298 extern void dlil_allocation_zones_init(void);
299 
300 extern struct dlil_ifnet * dlif_ifnet_alloc(void);
301 extern void dlif_ifnet_free(struct dlil_ifnet *);
302 
303 extern struct ifnet_filter * dlif_filt_alloc(void);
304 extern void dlif_filt_free(struct ifnet_filter *);
305 
306 extern struct if_proto * dlif_proto_alloc(void);
307 extern void dlif_proto_free(struct if_proto * );
308 
309 extern struct tcpstat_local * dlif_tcpstat_alloc(void);
310 extern void dlif_tcpstat_free(struct tcpstat_local *);
311 
312 extern struct udpstat_local * dlif_udpstat_alloc(void);
313 extern void dlif_udpstat_free(struct udpstat_local *);
314 
315 extern void if_proto_ref(struct if_proto *);
316 extern void if_proto_free(struct if_proto *);
317 
318 /*
319  * Prepare the storage for the first/permanent link address, which must
320  * must have the same lifetime as the ifnet itself.  Although the link
321  * address gets removed from if_addrhead and ifnet_addrs[] at detach time,
322  * its location in memory must never change as it may still be referred
323  * to by some parts of the system afterwards (unfortunate implementation
324  * artifacts inherited from BSD.)
325  *
326  * Caller must hold ifnet lock as writer.
327  */
328 extern struct ifaddr * dlil_alloc_lladdr(struct ifnet *ifp, const struct sockaddr_dl *ll_addr);
329 
330 
331 /*
332  * dlil_ifp_protolist
333  * - get the list of protocols attached to the interface, or just the number
334  *   of attached protocols
335  * - if the number returned is greater than 'list_count', truncation occurred
336  *
337  * Note:
338  * - caller must already be holding ifnet lock.
339  */
340 extern u_int32_t dlil_ifp_protolist(struct ifnet *ifp, protocol_family_t *list __counted_by(list_count),
341     u_int32_t list_count);
342 
343 extern uint64_t if_creation_generation_count;
344 
345 
346 /*
347  * Interface management functions
348  */
349 extern void dlil_if_trace(struct dlil_ifnet *, int);
350 
351 extern void _dlil_if_release(ifnet_t ifp, bool clear_in_use);
352 
353 /*
354  * Stats management
355  */
356 void dlil_input_stats_add(const struct ifnet_stat_increment_param *,
357     struct dlil_threading_info *, struct ifnet *, boolean_t);
358 
359 boolean_t dlil_input_stats_sync(struct ifnet *,
360     struct dlil_threading_info *);
361 
362 /*
363  * Thread management
364  */
365 extern uint32_t dlil_pending_thread_cnt;
366 
367 
368 /* DLIL data threshold thread call */
369 extern void dlil_dt_tcall_fn(thread_call_param_t, thread_call_param_t);
370 
371 extern void dlil_clean_threading_info(struct dlil_threading_info *inp);
372 
373 int dlil_create_input_thread(ifnet_t, struct dlil_threading_info *,
374     thread_continue_t *);
375 
376 void dlil_terminate_input_thread(struct dlil_threading_info *);
377 
378 extern boolean_t dlil_is_rxpoll_input(thread_continue_t func);
379 boolean_t dlil_is_native_netif_nexus(ifnet_t ifp);
380 
381 void dlil_incr_pending_thread_count(void);
382 void dlil_decr_pending_thread_count(void);
383 
384 struct if_proto * find_attached_proto(struct ifnet *ifp, u_int32_t protocol_family);
385 
386 int dlil_is_clat_needed(protocol_family_t proto_family, mbuf_t m);
387 errno_t dlil_clat46(ifnet_t ifp, protocol_family_t *proto_family, mbuf_t *m);
388 errno_t dlil_clat64(ifnet_t ifp, protocol_family_t *proto_family, mbuf_t *m);
389 
390 /*
391  * Lock management functions
392  */
393 extern lck_attr_t dlil_lck_attributes;
394 extern lck_rw_t ifnet_head_lock;
395 extern lck_mtx_t dlil_ifnet_lock;
396 extern lck_grp_t dlil_lock_group;
397 extern lck_grp_t ifnet_head_lock_group;
398 extern lck_grp_t ifnet_snd_lock_group;
399 extern lck_grp_t ifnet_rcv_lock_group;
400 extern lck_mtx_t dlil_thread_sync_lock;
401 
402 extern void dlil_if_lock(void);
403 
404 extern void dlil_if_unlock(void);
405 
406 extern void dlil_if_lock_assert(void);
407 
408 extern void ifnet_head_lock_assert(ifnet_lock_assert_t what);
409 
410 extern void ifnet_lock_assert(struct ifnet *ifp, ifnet_lock_assert_t what);
411 
412 extern void ifnet_lock_shared(struct ifnet *ifp);
413 
414 extern void ifnet_lock_exclusive(struct ifnet *ifp);
415 
416 extern void ifnet_lock_done(struct ifnet *ifp);
417 
418 #if INET
419 extern void if_inetdata_lock_shared(struct ifnet *ifp);
420 
421 extern void if_inetdata_lock_exclusive(struct ifnet *ifp);
422 
423 extern void if_inetdata_lock_done(struct ifnet *ifp);
424 
425 #endif /* INET */
426 
427 extern void if_inet6data_lock_shared(struct ifnet *ifp);
428 
429 extern void if_inet6data_lock_exclusive(struct ifnet *ifp);
430 
431 extern void if_inet6data_lock_done(struct ifnet *ifp);
432 
433 extern void ifnet_head_lock_shared(void);
434 
435 extern void ifnet_head_lock_exclusive(void);
436 
437 extern void ifnet_head_done(void);
438 
439 extern void ifnet_head_assert_exclusive(void);
440 
441 /*
442  * mcasts
443  */
444 errno_t if_mcasts_update_async(struct ifnet *);
445 
446 
447 #endif /* DLIL_VAR_PRIVATE_H */
448