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