xref: /xnu-11417.101.15/bsd/net/dlil_var_private.h (revision e3723e1f17661b24996789d8afc084c0c3303b26)
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 	_CASSERT(!(offsetof(struct if_data_internal, f) % sizeof (u_int64_t)))
168 
169 #define IFNET_IF_DATA_REQUIRE_ALIGNED_64(f)     \
170 	_CASSERT(!(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 extern unsigned int ifnet_debug;
184 
185 
186 extern unsigned int net_rxpoll;
187 extern unsigned int net_affinity;
188 extern unsigned int net_async;     /* 0: synchronous, 1: asynchronous */
189 
190 #if SKYWALK
191 /*
192  * Skywalk ifnet attachment modes.
193  */
194 extern uint32_t if_attach_nx;
195 extern uint32_t if_enable_fsw_ip_netagent;
196 extern uint32_t if_enable_fsw_transport_netagent;
197 extern uint32_t if_netif_all;
198 #endif /* SKYWALK */
199 
200 #define DLIL_SDLDATALEN \
201 	(DLIL_SDLMAXLEN - offsetof(struct sockaddr_dl, sdl_data[0]))
202 
203 
204 /*
205  * In the common case, the LL address is stored in the
206  * `dl_if_lladdr' member of the `dlil_ifnet'. This is sufficient
207  * for LL addresses that do not exceed the `DLIL_SDLMAXLEN' constant.
208  */
209 struct dl_if_lladdr_std {
210 	struct ifaddr   ifa;
211 	u_int8_t        addr_sdl_bytes[DLIL_SDLMAXLEN];
212 	u_int8_t        mask_sdl_bytes[DLIL_SDLMAXLEN];
213 };
214 
215 /*
216  * However, in some rare cases we encounter LL addresses which
217  * would not fit in the `DLIL_SDLMAXLEN' limitation. In such cases
218  * we allocate the storage in the permanent arena, using this memory layout.
219  */
220 struct dl_if_lladdr_xtra_space {
221 	struct ifaddr   ifa;
222 	u_int8_t        addr_sdl_bytes[SOCK_MAXADDRLEN];
223 	u_int8_t        mask_sdl_bytes[SOCK_MAXADDRLEN];
224 };
225 
226 struct dlil_ifnet {
227 	struct ifnet    dl_if;                  /* public ifnet */
228 	/*
229 	 * DLIL private fields, protected by dl_if_lock
230 	 */
231 	decl_lck_mtx_data(, dl_if_lock);
232 	TAILQ_ENTRY(dlil_ifnet) dl_if_link;     /* dlil_ifnet link */
233 	u_int32_t dl_if_flags;                  /* flags (below) */
234 	u_int32_t dl_if_refcnt;                 /* refcnt */
235 	void (*dl_if_trace)(struct dlil_ifnet *, int); /* ref trace callback */
236 	void    *dl_if_uniqueid __sized_by_or_null(dl_if_uniqueid_len);                /* unique interface id */
237 	size_t  dl_if_uniqueid_len;             /* length of the unique id */
238 	char    dl_if_namestorage[IFNAMSIZ];    /* interface name storage */
239 	char    dl_if_xnamestorage[IFXNAMSIZ];  /* external name storage */
240 	struct dl_if_lladdr_std dl_if_lladdr;   /* link-level address storage*/
241 	u_int8_t dl_if_descstorage[IF_DESCSIZE]; /* desc storage */
242 	u_int8_t dl_if_permanent_ether[ETHER_ADDR_LEN]; /* permanent address */
243 	u_int8_t dl_if_permanent_ether_is_set;
244 	u_int8_t dl_if_unused;
245 	struct dlil_threading_info dl_if_inpstorage; /* input thread storage */
246 	ctrace_t        dl_if_attach;           /* attach PC stacktrace */
247 	ctrace_t        dl_if_detach;           /* detach PC stacktrace */
248 };
249 
250 
251 /* Values for dl_if_flags (private to DLIL) */
252 #define DLIF_INUSE      0x1     /* DLIL ifnet recycler, ifnet in use */
253 #define DLIF_REUSE      0x2     /* DLIL ifnet recycles, ifnet is not new */
254 #define DLIF_DEBUG      0x4     /* has debugging info */
255 
256 #define IF_REF_TRACE_HIST_SIZE  8       /* size of ref trace history */
257 
258 /* For gdb */
259 extern unsigned int if_ref_trace_hist_size;
260 
261 struct dlil_ifnet_dbg {
262 	struct dlil_ifnet       dldbg_dlif;             /* dlil_ifnet */
263 	u_int16_t               dldbg_if_refhold_cnt;   /* # ifnet references */
264 	u_int16_t               dldbg_if_refrele_cnt;   /* # ifnet releases */
265 	/*
266 	 * Circular lists of ifnet_{reference,release} callers.
267 	 */
268 	ctrace_t                dldbg_if_refhold[IF_REF_TRACE_HIST_SIZE];
269 	ctrace_t                dldbg_if_refrele[IF_REF_TRACE_HIST_SIZE];
270 };
271 
272 #define DLIL_TO_IFP(s)  (&s->dl_if)
273 #define IFP_TO_DLIL(s)  ((struct dlil_ifnet *)s)
274 
275 struct ifnet_filter {
276 	TAILQ_ENTRY(ifnet_filter)       filt_next;
277 	u_int32_t                       filt_skip;
278 	u_int32_t                       filt_flags;
279 	ifnet_t                         filt_ifp;
280 	const char                      *filt_name;
281 	void                            *filt_cookie;
282 	protocol_family_t               filt_protocol;
283 	iff_input_func                  filt_input;
284 	iff_output_func                 filt_output;
285 	iff_event_func                  filt_event;
286 	iff_ioctl_func                  filt_ioctl;
287 	iff_detached_func               filt_detached;
288 };
289 
290 
291 /* Mbuf queue used for freeing the excessive mbufs */
292 typedef MBUFQ_HEAD(dlil_freeq) dlil_freeq_t;
293 
294 typedef TAILQ_HEAD(, dlil_ifnet) dlil_ifnet_queue_t;
295 
296 extern dlil_ifnet_queue_t dlil_ifnet_head;
297 
298 struct proto_input_entry;
299 
300 /*
301  * Utility routines
302  */
303 extern kern_return_t dlil_affinity_set(struct thread *, u_int32_t);
304 extern boolean_t packet_has_vlan_tag(struct mbuf * m);
305 void log_hexdump(void *__sized_by(len) data, size_t len);
306 
307 /*
308  * Monitor routines.
309  */
310 extern void if_flt_monitor_busy(struct ifnet *);
311 extern void if_flt_monitor_unbusy(struct ifnet *);
312 extern void if_flt_monitor_enter(struct ifnet *);
313 extern void if_flt_monitor_leave(struct ifnet *);
314 
315 /*
316  * Allocation routines
317  */
318 extern void dlil_allocation_zones_init(void);
319 
320 extern struct dlil_ifnet * dlif_ifnet_alloc(void);
321 extern void dlif_ifnet_free(struct dlil_ifnet *);
322 
323 extern struct ifnet_filter * dlif_filt_alloc(void);
324 extern void dlif_filt_free(struct ifnet_filter *);
325 
326 extern struct if_proto * dlif_proto_alloc(void);
327 extern void dlif_proto_free(struct if_proto * );
328 
329 extern struct tcpstat_local * dlif_tcpstat_alloc(void);
330 extern void dlif_tcpstat_free(struct tcpstat_local *);
331 
332 extern struct udpstat_local * dlif_udpstat_alloc(void);
333 extern void dlif_udpstat_free(struct udpstat_local *);
334 
335 extern void if_proto_ref(struct if_proto *);
336 extern void if_proto_free(struct if_proto *);
337 
338 /*
339  * Prepare the storage for the first/permanent link address, which must
340  * must have the same lifetime as the ifnet itself.  Although the link
341  * address gets removed from if_addrhead and ifnet_addrs[] at detach time,
342  * its location in memory must never change as it may still be referred
343  * to by some parts of the system afterwards (unfortunate implementation
344  * artifacts inherited from BSD.)
345  *
346  * Caller must hold ifnet lock as writer.
347  */
348 extern struct ifaddr * dlil_alloc_lladdr(struct ifnet *ifp, const struct sockaddr_dl *ll_addr);
349 
350 
351 /*
352  * dlil_ifp_protolist
353  * - get the list of protocols attached to the interface, or just the number
354  *   of attached protocols
355  * - if the number returned is greater than 'list_count', truncation occurred
356  *
357  * Note:
358  * - caller must already be holding ifnet lock.
359  */
360 extern u_int32_t dlil_ifp_protolist(struct ifnet *ifp, protocol_family_t *list __counted_by(list_count),
361     u_int32_t list_count);
362 
363 extern uint64_t if_creation_generation_count;
364 
365 
366 /*
367  * Interface management functions
368  */
369 extern void dlil_if_trace(struct dlil_ifnet *, int);
370 
371 extern void _dlil_if_release(ifnet_t ifp, bool clear_in_use);
372 
373 /*
374  * Stats management
375  */
376 void dlil_input_stats_add(const struct ifnet_stat_increment_param *,
377     struct dlil_threading_info *, struct ifnet *, boolean_t);
378 
379 boolean_t dlil_input_stats_sync(struct ifnet *,
380     struct dlil_threading_info *);
381 
382 /*
383  * Thread management
384  */
385 extern uint32_t dlil_pending_thread_cnt;
386 
387 
388 /* DLIL data threshold thread call */
389 extern void dlil_dt_tcall_fn(thread_call_param_t, thread_call_param_t);
390 
391 extern void dlil_clean_threading_info(struct dlil_threading_info *inp);
392 
393 int dlil_create_input_thread(ifnet_t, struct dlil_threading_info *,
394     thread_continue_t *);
395 
396 void dlil_terminate_input_thread(struct dlil_threading_info *);
397 
398 extern boolean_t dlil_is_rxpoll_input(thread_continue_t func);
399 boolean_t dlil_is_native_netif_nexus(ifnet_t ifp);
400 
401 void dlil_incr_pending_thread_count(void);
402 void dlil_decr_pending_thread_count(void);
403 
404 struct if_proto * find_attached_proto(struct ifnet *ifp, u_int32_t protocol_family);
405 
406 int dlil_is_clat_needed(protocol_family_t proto_family, mbuf_t m);
407 errno_t dlil_clat46(ifnet_t ifp, protocol_family_t *proto_family, mbuf_t *m);
408 errno_t dlil_clat64(ifnet_t ifp, protocol_family_t *proto_family, mbuf_t *m);
409 
410 /*
411  * Lock management functions
412  */
413 extern lck_attr_t dlil_lck_attributes;
414 extern lck_rw_t ifnet_head_lock;
415 extern lck_mtx_t dlil_ifnet_lock;
416 extern lck_grp_t dlil_lock_group;
417 extern lck_grp_t ifnet_head_lock_group;
418 extern lck_grp_t ifnet_snd_lock_group;
419 extern lck_grp_t ifnet_rcv_lock_group;
420 extern lck_mtx_t dlil_thread_sync_lock;
421 
422 extern void dlil_if_lock(void);
423 
424 extern void dlil_if_unlock(void);
425 
426 extern void dlil_if_lock_assert(void);
427 
428 extern void ifnet_head_lock_assert(ifnet_lock_assert_t what);
429 
430 extern void ifnet_lock_assert(struct ifnet *ifp, ifnet_lock_assert_t what);
431 
432 extern void ifnet_lock_shared(struct ifnet *ifp);
433 
434 extern void ifnet_lock_exclusive(struct ifnet *ifp);
435 
436 extern void ifnet_lock_done(struct ifnet *ifp);
437 
438 #if INET
439 extern void if_inetdata_lock_shared(struct ifnet *ifp);
440 
441 extern void if_inetdata_lock_exclusive(struct ifnet *ifp);
442 
443 extern void if_inetdata_lock_done(struct ifnet *ifp);
444 
445 #endif /* INET */
446 
447 extern void if_inet6data_lock_shared(struct ifnet *ifp);
448 
449 extern void if_inet6data_lock_exclusive(struct ifnet *ifp);
450 
451 extern void if_inet6data_lock_done(struct ifnet *ifp);
452 
453 extern void ifnet_head_lock_shared(void);
454 
455 extern void ifnet_head_lock_exclusive(void);
456 
457 extern void ifnet_head_done(void);
458 
459 extern void ifnet_head_assert_exclusive(void);
460 
461 /*
462  * mcasts
463  */
464 errno_t if_mcasts_update_async(struct ifnet *);
465 
466 
467 #endif /* DLIL_VAR_PRIVATE_H */
468