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