2  * Copyright (c) 1999-2007 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  *      Data Link Inteface Layer 
  33  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 
  34  * support for mandatory and extensible security protections.  This notice 
  35  * is included in support of clause 2.2 (b) of the Apple Public License, 
  39 #include <sys/param.h> 
  40 #include <sys/systm.h> 
  41 #include <sys/kernel.h> 
  42 #include <sys/malloc.h> 
  44 #include <sys/socket.h> 
  45 #include <sys/domain.h> 
  47 #include <sys/random.h> 
  48 #include <net/if_dl.h> 
  50 #include <net/route.h> 
  51 #include <net/if_var.h> 
  53 #include <net/if_arp.h> 
  54 #include <sys/kern_event.h> 
  55 #include <sys/kdebug.h> 
  57 #include <kern/assert.h> 
  58 #include <kern/task.h> 
  59 #include <kern/thread.h> 
  60 #include <kern/sched_prim.h> 
  61 #include <kern/locks.h> 
  62 #include <net/kpi_protocol.h> 
  64 #include <net/if_types.h> 
  65 #include <net/kpi_interfacefilter.h> 
  67 #include <libkern/OSAtomic.h> 
  69 #include <machine/machine_routines.h> 
  71 #include <mach/thread_act.h> 
  74 #include <security/mac_framework.h> 
  77 #define DBG_LAYER_BEG                   DLILDBG_CODE(DBG_DLIL_STATIC, 0) 
  78 #define DBG_LAYER_END                   DLILDBG_CODE(DBG_DLIL_STATIC, 2) 
  79 #define DBG_FNC_DLIL_INPUT      DLILDBG_CODE(DBG_DLIL_STATIC, (1 << 8)) 
  80 #define DBG_FNC_DLIL_OUTPUT     DLILDBG_CODE(DBG_DLIL_STATIC, (2 << 8)) 
  81 #define DBG_FNC_DLIL_IFOUT      DLILDBG_CODE(DBG_DLIL_STATIC, (3 << 8)) 
  84 #define MAX_FRAME_TYPE_SIZE 4 /* LONGWORDS */ 
  85 #define MAX_LINKADDR        4 /* LONGWORDS */ 
  86 #define M_NKE M_IFADDR 
  89 #define DLIL_PRINTF     printf 
  91 #define DLIL_PRINTF     kprintf 
 101     SLIST_ENTRY(if_proto
)        next_hash
; 
 105     struct domain                        
*dl_domain
; 
 106     protocol_family_t           protocol_family
; 
 110                         proto_media_input                       input
; 
 111                         proto_media_preout                      pre_output
; 
 112                         proto_media_event                       event
; 
 113                         proto_media_ioctl                       ioctl
; 
 114                         proto_media_detached            detached
; 
 115                         proto_media_resolve_multi       resolve_multi
; 
 116                         proto_media_send_arp            send_arp
; 
 119                         proto_media_input_v2            input
; 
 120                         proto_media_preout                      pre_output
; 
 121                         proto_media_event                       event
; 
 122                         proto_media_ioctl                       ioctl
; 
 123                         proto_media_detached            detached
; 
 124                         proto_media_resolve_multi       resolve_multi
; 
 125                         proto_media_send_arp            send_arp
; 
 130 SLIST_HEAD(proto_hash_entry
, if_proto
); 
 134     /* ifnet and drvr_ext are used by the stack and drivers 
 135     drvr_ext extends the public ifnet and must follow dl_if */ 
 136     struct ifnet        dl_if
;                  /* public ifnet */ 
 138     /* dlil private fields */ 
 139     TAILQ_ENTRY(dlil_ifnet
) dl_if_link
; /* dlil_ifnet are link together */ 
 140                                                                 /* it is not the ifnet list */ 
 141     void                *if_uniqueid
;   /* unique id identifying the interface */ 
 142     size_t              if_uniqueid_len
;/* length of the unique id */ 
 143     char                if_namestorage
[IFNAMSIZ
]; /* interface name storage */ 
 146 struct ifnet_filter 
{ 
 147         TAILQ_ENTRY(ifnet_filter
)       filt_next
; 
 151         const char                                      *filt_name
; 
 153     protocol_family_t                   filt_protocol
; 
 154     iff_input_func                              filt_input
; 
 155     iff_output_func                             filt_output
; 
 156     iff_event_func                              filt_event
; 
 157     iff_ioctl_func                              filt_ioctl
; 
 158     iff_detached_func                   filt_detached
; 
 161 struct proto_input_entry
; 
 163 static TAILQ_HEAD(, dlil_ifnet
) dlil_ifnet_head
; 
 164 static lck_grp_t 
*dlil_lock_group
; 
 165 static lck_grp_t 
*ifnet_lock_group
; 
 166 static lck_grp_t 
*ifnet_head_lock_group
; 
 167 static lck_attr_t 
*ifnet_lock_attr
; 
 168 static lck_rw_t 
*ifnet_head_mutex
; 
 169 static lck_mtx_t 
*dlil_ifnet_mutex
; 
 170 static lck_mtx_t 
*dlil_mutex
; 
 171 static unsigned long dlil_read_count 
= 0; 
 172 static unsigned long dlil_detach_waiting 
= 0; 
 173 extern u_int32_t        ipv4_ll_arp_aware
; 
 175 static struct dlil_threading_info dlil_lo_thread
; 
 176 __private_extern__  
struct dlil_threading_info 
*dlil_lo_thread_ptr 
= &dlil_lo_thread
; 
 178 static struct mbuf 
*dlil_lo_input_mbuf_head 
= NULL
; 
 179 static struct mbuf 
*dlil_lo_input_mbuf_tail 
= NULL
; 
 181 #if IFNET_INPUT_SANITY_CHK 
 182 static int dlil_lo_input_mbuf_count 
= 0; 
 183 int dlil_input_sanity_check 
= 0;        /* sanity checking of input packet lists received */ 
 185 int dlil_multithreaded_input 
= 1; 
 186 static int cur_dlil_input_threads 
= 0;  
 188 static int dlil_event_internal(struct ifnet 
*ifp
, struct kev_msg 
*msg
); 
 189 static int dlil_detach_filter_internal(interface_filter_t filter
, int detached
); 
 190 static void dlil_call_delayed_detach_thread(void); 
 192 static void     dlil_read_begin(void); 
 193 static __inline__ 
void  dlil_read_end(void); 
 194 static int      dlil_write_begin(void); 
 195 static void     dlil_write_end(void); 
 197 unsigned int net_affinity 
= 1; 
 198 static kern_return_t 
dlil_affinity_set(struct thread 
*, u_int32_t
); 
 200 extern void bpfdetach(struct ifnet
*); 
 201 extern void proto_input_run(void); // new run_netisr 
 203 void dlil_input_packet_list(struct ifnet  
*ifp
, struct mbuf 
*m
); 
 204 static void dlil_input_thread_func(struct dlil_threading_info 
*inpthread
);  
 205 __private_extern__ 
int dlil_create_input_thread( 
 206                 ifnet_t
, struct dlil_threading_info 
*); 
 207 __private_extern__ 
void dlil_terminate_input_thread( 
 208                 struct dlil_threading_info 
*); 
 210 __private_extern__ 
void link_rtrequest(int, struct rtentry 
*, struct sockaddr 
*); 
 214 extern u_int32_t        inject_buckets
; 
 216 static const u_int32_t dlil_writer_waiting 
= 0x80000000; 
 217 static  lck_grp_attr_t  
*dlil_grp_attributes 
= NULL
; 
 218 static  lck_attr_t      
*dlil_lck_attributes 
= NULL
; 
 219 static  lck_grp_t       
*dlil_input_lock_grp 
= NULL
; 
 222 _cast_non_const(const void * ptr
) { 
 232 /* Should these be inline? */ 
 234 dlil_read_begin(void) 
 236         unsigned long new_value
; 
 237         unsigned long old_value
; 
 238         struct uthread 
*uth 
= get_bsdthread_info(current_thread()); 
 240         if (uth
->dlil_incremented_read 
== dlil_writer_waiting
) 
 241                 panic("dlil_read_begin - thread is already a writer"); 
 245                 old_value 
= dlil_read_count
; 
 247                 if ((old_value 
& dlil_writer_waiting
) != 0 && uth
->dlil_incremented_read 
== 0) 
 249                         tsleep(&dlil_read_count
, PRIBIO
, "dlil_read_count", 1); 
 253                 new_value 
= old_value 
+ 1; 
 254         } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)new_value
, (UInt32
*)&dlil_read_count
)); 
 256         uth
->dlil_incremented_read
++; 
 262         struct uthread 
*uth 
= get_bsdthread_info(current_thread()); 
 264         OSDecrementAtomic((SInt32
*)&dlil_read_count
); 
 265         uth
->dlil_incremented_read
--; 
 266         if (dlil_read_count 
== dlil_writer_waiting
) 
 267                 wakeup(_cast_non_const(&dlil_writer_waiting
)); 
 271 dlil_write_begin(void) 
 273         struct uthread 
*uth 
= get_bsdthread_info(current_thread()); 
 275         if (uth
->dlil_incremented_read 
!= 0) { 
 278         lck_mtx_lock(dlil_mutex
); 
 279         OSBitOrAtomic((UInt32
)dlil_writer_waiting
, (UInt32
*)&dlil_read_count
); 
 281         if (dlil_read_count 
== dlil_writer_waiting
) { 
 282                 uth
->dlil_incremented_read 
= dlil_writer_waiting
; 
 286                 tsleep(_cast_non_const(&dlil_writer_waiting
), PRIBIO
, "dlil_writer_waiting", 1); 
 294         struct uthread 
*uth 
= get_bsdthread_info(current_thread()); 
 296         if (uth
->dlil_incremented_read 
!= dlil_writer_waiting
) 
 297                 panic("dlil_write_end - thread is not a writer"); 
 298         OSBitAndAtomic((UInt32
)~dlil_writer_waiting
, (UInt32
*)&dlil_read_count
); 
 299         lck_mtx_unlock(dlil_mutex
); 
 300         uth
->dlil_incremented_read 
= 0; 
 301         wakeup(&dlil_read_count
); 
 304 #define PROTO_HASH_SLOTS        0x5 
 307  * Internal functions. 
 311 proto_hash_value(u_long protocol_family
) 
 314          * dlil_proto_unplumb_all() depends on the mapping between 
 315          * the hash bucket index and the protocol family defined 
 316          * here; future changes must be applied there as well. 
 318         switch(protocol_family
) { 
 332 static struct if_proto
* 
 333 find_attached_proto(struct ifnet 
*ifp
, u_long protocol_family
) 
 335         struct if_proto 
*proto 
= NULL
; 
 336         u_long i 
= proto_hash_value(protocol_family
); 
 337         if (ifp
->if_proto_hash
) { 
 338                 proto 
= SLIST_FIRST(&ifp
->if_proto_hash
[i
]); 
 341         while(proto 
&& proto
->protocol_family 
!= protocol_family
) { 
 342                 proto 
= SLIST_NEXT(proto
, next_hash
); 
 349 if_proto_ref(struct if_proto 
*proto
) 
 351         OSAddAtomic(1, (SInt32
*)&proto
->refcount
); 
 355 if_proto_free(struct if_proto 
*proto
) 
 357         int oldval 
= OSAddAtomic(-1, (SInt32
*)&proto
->refcount
); 
 359         if (oldval 
== 1) { /* This was the last reference */ 
 360                 FREE(proto
, M_IFADDR
); 
 364 __private_extern__ 
void 
 366         __unused 
struct ifnet 
*ifp
, 
 371          * Not implemented for rw locks. 
 373          * Function exists so when/if we use mutex we can 
 377         lck_mtx_assert(ifp
->if_lock
, what
); 
 381 __private_extern__ 
void 
 386         lck_rw_lock_shared(ifp
->if_lock
); 
 388         lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_NOTOWNED
); 
 389         lck_mtx_lock(ifp
->if_lock
); 
 393 __private_extern__ 
void 
 394 ifnet_lock_exclusive( 
 398         lck_rw_lock_exclusive(ifp
->if_lock
); 
 400         lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_NOTOWNED
); 
 401         lck_mtx_lock(ifp
->if_lock
); 
 405 __private_extern__ 
void 
 410         lck_rw_done(ifp
->if_lock
); 
 412         lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_OWNED
); 
 413         lck_mtx_unlock(ifp
->if_lock
); 
 417 __private_extern__ 
void 
 418 ifnet_head_lock_shared(void) 
 420         lck_rw_lock_shared(ifnet_head_mutex
); 
 423 __private_extern__ 
void 
 424 ifnet_head_lock_exclusive(void) 
 426         lck_rw_lock_exclusive(ifnet_head_mutex
); 
 429 __private_extern__ 
void 
 430 ifnet_head_done(void) 
 432         lck_rw_done(ifnet_head_mutex
); 
 435 static int dlil_ifp_proto_count(struct ifnet 
* ifp
)  
 440         if (ifp
->if_proto_hash 
!= NULL
) {        
 441                 for (i 
= 0; i 
< PROTO_HASH_SLOTS
; i
++) { 
 442                         struct if_proto 
*proto
; 
 443                         SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) { 
 452 __private_extern__ 
void 
 453 dlil_post_msg(struct ifnet 
*ifp
, u_long event_subclass
, u_long event_code
,  
 454                    struct net_event_data 
*event_data
, u_long event_data_len
)  
 456         struct net_event_data   ev_data
; 
 457         struct kev_msg                  ev_msg
; 
 460          * a net event always starts with a net_event_data structure 
 461          * but the caller can generate a simple net event or 
 462          * provide a longer event structure to post 
 465         ev_msg
.vendor_code    
= KEV_VENDOR_APPLE
; 
 466         ev_msg
.kev_class      
= KEV_NETWORK_CLASS
; 
 467         ev_msg
.kev_subclass   
= event_subclass
; 
 468         ev_msg
.event_code         
= event_code
;     
 470         if (event_data 
== 0) { 
 471                 event_data 
= &ev_data
; 
 472                 event_data_len 
= sizeof(struct net_event_data
); 
 475         strncpy(&event_data
->if_name
[0], ifp
->if_name
, IFNAMSIZ
); 
 476         event_data
->if_family 
= ifp
->if_family
; 
 477         event_data
->if_unit   
= (unsigned long) ifp
->if_unit
; 
 479         ev_msg
.dv
[0].data_length 
= event_data_len
; 
 480         ev_msg
.dv
[0].data_ptr    
= event_data
;   
 481         ev_msg
.dv
[1].data_length 
= 0; 
 483         dlil_event_internal(ifp
, &ev_msg
); 
 486 __private_extern__ 
int 
 487 dlil_create_input_thread( 
 488         ifnet_t ifp
, struct dlil_threading_info 
*inputthread
) 
 492         bzero(inputthread
, sizeof(*inputthread
)); 
 493         // loopback ifp may not be configured at dlil_init time. 
 495                 strlcat(inputthread
->input_name
, "dlil_input_main_thread_mtx", 32); 
 497                 snprintf(inputthread
->input_name
, 32, "dlil_input_%s%d_mtx", ifp
->if_name
, ifp
->if_unit
);        
 499         inputthread
->lck_grp 
= lck_grp_alloc_init(inputthread
->input_name
, dlil_grp_attributes
); 
 500         inputthread
->input_lck  
= lck_mtx_alloc_init(inputthread
->lck_grp
, dlil_lck_attributes
); 
 502         error
= kernel_thread_start((thread_continue_t
)dlil_input_thread_func
, inputthread
, &inputthread
->input_thread
); 
 504                 ml_thread_policy(inputthread
->input_thread
, MACHINE_GROUP
, 
 505                                  (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
)); 
 507                  * Except for the loopback dlil input thread, we create 
 508                  * an affinity set so that the matching workloop thread 
 509                  * can be scheduled on the same processor set. 
 511                 if (net_affinity 
&& inputthread 
!= dlil_lo_thread_ptr
) { 
 512                         struct thread 
*tp 
= inputthread
->input_thread
; 
 515                          * Randomize to reduce the probability 
 516                          * of affinity tag namespace collision. 
 518                         read_random(&tag
, sizeof (tag
)); 
 519                         if (dlil_affinity_set(tp
, tag
) == KERN_SUCCESS
) { 
 520                                 thread_reference(tp
); 
 521                                 inputthread
->tag 
= tag
; 
 522                                 inputthread
->net_affinity 
= TRUE
; 
 526                 panic("dlil_create_input_thread: couldn't create thread\n"); 
 528         OSAddAtomic(1, (SInt32
*)&cur_dlil_input_threads
); 
 530         printf("dlil_create_input_thread: threadinfo: %p input_thread=%p threads: cur=%d max=%d\n",  
 531                 inputthread
, inputthread
->input_thread
, dlil_multithreaded_input
, cur_dlil_input_threads
); 
 535 __private_extern__ 
void 
 536 dlil_terminate_input_thread( 
 537         struct dlil_threading_info 
*inputthread
) 
 539         OSAddAtomic(-1, (SInt32
*)&cur_dlil_input_threads
); 
 541         lck_mtx_unlock(inputthread
->input_lck
); 
 542         lck_mtx_free(inputthread
->input_lck
, inputthread
->lck_grp
); 
 543         lck_grp_free(inputthread
->lck_grp
); 
 545         FREE(inputthread
, M_NKE
); 
 547         /* For the extra reference count from kernel_thread_start() */ 
 548         thread_deallocate(current_thread()); 
 550         thread_terminate(current_thread()); 
 554 dlil_affinity_set(struct thread 
*tp
, u_int32_t tag
) 
 556         thread_affinity_policy_data_t policy
; 
 558         bzero(&policy
, sizeof (policy
)); 
 559         policy
.affinity_tag 
= tag
; 
 560         return (thread_policy_set(tp
, THREAD_AFFINITY_POLICY
, 
 561             (thread_policy_t
)&policy
, THREAD_AFFINITY_POLICY_COUNT
)); 
 567         PE_parse_boot_argn("net_affinity", &net_affinity
, sizeof (net_affinity
)); 
 569         TAILQ_INIT(&dlil_ifnet_head
); 
 570         TAILQ_INIT(&ifnet_head
); 
 572         /* Setup the lock groups we will use */ 
 573         dlil_grp_attributes 
= lck_grp_attr_alloc_init(); 
 575         dlil_lock_group 
= lck_grp_alloc_init("dlil internal locks", dlil_grp_attributes
); 
 576         ifnet_lock_group 
= lck_grp_alloc_init("ifnet locks", dlil_grp_attributes
); 
 577         ifnet_head_lock_group 
= lck_grp_alloc_init("ifnet head lock", dlil_grp_attributes
); 
 578         dlil_input_lock_grp 
= lck_grp_alloc_init("dlil input lock", dlil_grp_attributes
); 
 580         /* Setup the lock attributes we will use */ 
 581         dlil_lck_attributes 
= lck_attr_alloc_init(); 
 583         ifnet_lock_attr 
= lck_attr_alloc_init(); 
 586         ifnet_head_mutex 
= lck_rw_alloc_init(ifnet_head_lock_group
, dlil_lck_attributes
); 
 587         dlil_ifnet_mutex 
= lck_mtx_alloc_init(dlil_lock_group
, dlil_lck_attributes
); 
 588         dlil_mutex 
= lck_mtx_alloc_init(dlil_lock_group
, dlil_lck_attributes
); 
 590         lck_attr_free(dlil_lck_attributes
); 
 591         dlil_lck_attributes 
= NULL
; 
 594          * Create and start up the first dlil input thread once everything is initialized 
 596         dlil_create_input_thread(0, dlil_lo_thread_ptr
); 
 598         (void) kernel_thread(kernel_task
, dlil_call_delayed_detach_thread
); 
 601 __private_extern__ 
int 
 604         const struct iff_filter 
*if_filter
, 
 605         interface_filter_t              
*filter_ref
) 
 608     struct ifnet_filter 
*filter
; 
 610         MALLOC(filter
, struct ifnet_filter 
*, sizeof(*filter
), M_NKE
, M_WAITOK
); 
 613         bzero(filter
, sizeof(*filter
)); 
 616         filter
->filt_ifp 
= ifp
; 
 617         filter
->filt_cookie 
= if_filter
->iff_cookie
; 
 618         filter
->filt_name 
= if_filter
->iff_name
; 
 619         filter
->filt_protocol 
= if_filter
->iff_protocol
; 
 620         filter
->filt_input 
= if_filter
->iff_input
; 
 621         filter
->filt_output 
= if_filter
->iff_output
; 
 622         filter
->filt_event 
= if_filter
->iff_event
; 
 623         filter
->filt_ioctl 
= if_filter
->iff_ioctl
; 
 624         filter
->filt_detached 
= if_filter
->iff_detached
; 
 626         if ((retval 
= dlil_write_begin()) != 0) { 
 627                 /* Failed to acquire the write lock */ 
 631         TAILQ_INSERT_TAIL(&ifp
->if_flt_head
, filter
, filt_next
); 
 633         *filter_ref 
= filter
; 
 638 dlil_detach_filter_internal( 
 639         interface_filter_t      filter
, 
 646                 interface_filter_t      entry 
= NULL
; 
 648                 /* Take the write lock */ 
 649                 retval 
= dlil_write_begin(); 
 650                 if (retval 
!= 0 && retval 
!= EDEADLK
) 
 654                  * At this point either we have the write lock (retval == 0) 
 655                  * or we couldn't get it (retval == EDEADLK) because someone 
 656                  * else up the stack is holding the read lock. It is safe to 
 657                  * read, either the read or write is held. Verify the filter 
 658                  * parameter before proceeding. 
 660                 ifnet_head_lock_shared(); 
 661                 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) { 
 662                         TAILQ_FOREACH(entry
, &ifp
->if_flt_head
, filt_next
) { 
 671                 if (entry 
!= filter
) { 
 672                         /* filter parameter is not a valid filter ref */ 
 679                 if (retval 
== EDEADLK
) { 
 680                         /* Perform a delayed detach */ 
 681                         filter
->filt_detaching 
= 1; 
 682                         dlil_detach_waiting 
= 1; 
 683                         wakeup(&dlil_detach_waiting
); 
 687                 /* Remove the filter from the list */ 
 688                 TAILQ_REMOVE(&ifp
->if_flt_head
, filter
, filt_next
); 
 692         /* Call the detached funciton if there is one */ 
 693         if (filter
->filt_detached
) 
 694                 filter
->filt_detached(filter
->filt_cookie
, filter
->filt_ifp
); 
 696         /* Free the filter */ 
 702 __private_extern__ 
void 
 703 dlil_detach_filter(interface_filter_t filter
) 
 707         dlil_detach_filter_internal(filter
, 0); 
 711 dlil_input_thread_func( 
 712         struct dlil_threading_info 
*inputthread
) 
 715                 struct mbuf 
*m 
= NULL
, *m_loop 
= NULL
; 
 716 #if IFNET_INPUT_SANITY_CHK 
 717                 int             loop_cnt 
= 0, mbuf_cnt
; 
 720 #endif /* IFNET_INPUT_SANITY_CHK */ 
 722                 lck_mtx_lock(inputthread
->input_lck
); 
 724                 /* Wait until there is work to be done */ 
 725                 while ((inputthread
->input_waiting 
& ~DLIL_INPUT_RUNNING
) == 0) { 
 726                         inputthread
->input_waiting 
&= ~DLIL_INPUT_RUNNING
; 
 727                         msleep(&inputthread
->input_waiting
, inputthread
->input_lck
, 0, inputthread
->input_name
, 0); 
 731                 lck_mtx_assert(inputthread
->input_lck
, LCK_MTX_ASSERT_OWNED
); 
 733                 m 
= inputthread
->mbuf_head
; 
 734                 inputthread
->mbuf_head 
= NULL
; 
 735                 inputthread
->mbuf_tail 
= NULL
; 
 737                 if (inputthread
->input_waiting 
& DLIL_INPUT_TERMINATE
) { 
 740                                 /* this is the end */ 
 741                                 dlil_terminate_input_thread(inputthread
); 
 745                 inputthread
->input_waiting 
|= DLIL_INPUT_RUNNING
; 
 746                 inputthread
->input_waiting 
&= ~DLIL_INPUT_WAITING
; 
 748                 if (inputthread 
== dlil_lo_thread_ptr
) { 
 749                         m_loop 
= dlil_lo_input_mbuf_head
; 
 750                         dlil_lo_input_mbuf_head 
= NULL
; 
 751                         dlil_lo_input_mbuf_tail 
= NULL
; 
 754 #if IFNET_INPUT_SANITY_CHK 
 755                 if (dlil_input_sanity_check 
!= 0) { 
 756                         mbuf_cnt 
= inputthread
->mbuf_count
; 
 757                         inputthread
->mbuf_count 
= 0; 
 758                         if (inputthread 
== dlil_lo_thread_ptr
) { 
 759                                 loop_cnt 
= dlil_lo_input_mbuf_count
; 
 760                                 dlil_lo_input_mbuf_count 
= 0; 
 763                         lck_mtx_unlock(inputthread
->input_lck
); 
 765                         for (m1 
= m
, count 
= 0; m1
; m1 
= mbuf_nextpkt(m1
)) { 
 768                         if (count 
!= mbuf_cnt
) { 
 769                                 panic("dlil_input_func - thread=%p reg. loop queue has %d packets, should have %d\n", 
 770                                           inputthread
, count
, mbuf_cnt
); 
 773                         if (inputthread 
== dlil_lo_thread_ptr
) { 
 774                                 for (m1 
= m_loop
, count 
= 0; m1
; m1 
= mbuf_nextpkt(m1
)) { 
 777                                 if (count 
!= loop_cnt
) { 
 778                                         panic("dlil_input_func - thread=%p loop queue has %d packets, should have %d\n", 
 779                                           inputthread
, count
, loop_cnt
); 
 783 #endif /* IFNET_INPUT_SANITY_CHK */ 
 785                         lck_mtx_unlock(inputthread
->input_lck
); 
 790                 * NOTE warning %%% attention !!!! 
 791                 * We should think about putting some thread starvation safeguards if  
 792                 * we deal with long chains of packets. 
 795                         if (inputthread 
== dlil_lo_thread_ptr
) 
 796                                 dlil_input_packet_list(lo_ifp
, m_loop
); 
 797 #if IFNET_INPUT_SANITY_CHK 
 799                                 panic("dlil_input_func - thread=%p loop queue has %d packets, should have none!\n", 
 800                                   inputthread
, loop_cnt
); 
 801 #endif /* IFNET_INPUT_SANITY_CHK */ 
 806                         dlil_input_packet_list(0, m
); 
 809                 lck_mtx_lock(inputthread
->input_lck
); 
 811                 if ((inputthread
->input_waiting 
& (DLIL_PROTO_WAITING 
| DLIL_PROTO_REGISTER
)) != 0)  { 
 812                         lck_mtx_unlock(inputthread
->input_lck
); 
 816                         lck_mtx_unlock(inputthread
->input_lck
); 
 824         const struct ifnet_stat_increment_param 
*stats
) 
 826         struct thread 
*tp 
= current_thread(); 
 828         struct dlil_threading_info 
*inp
; 
 829 #if IFNET_INPUT_SANITY_CHK 
 830         u_int32_t       pkt_count 
= 0; 
 831 #endif /* IFNET_INPUT_SANITY_CHK */ 
 833         if (ifp 
== NULL 
|| m_head 
== NULL
) { 
 835                         mbuf_freem_list(m_head
); 
 841 #if IFNET_INPUT_SANITY_CHK 
 842                 if (dlil_input_sanity_check 
!= 0) { 
 845                         rcvif 
= mbuf_pkthdr_rcvif(m_tail
); 
 849                                 (ifp
->if_type 
!= IFT_LOOP 
&& rcvif 
!= ifp
) || 
 850                                 (mbuf_flags(m_head
) & MBUF_PKTHDR
) == 0) { 
 851                                 panic("ifnet_input - invalid mbuf %p\n", m_tail
); 
 854 #endif /* IFNET_INPUT_SANITY_CHK */ 
 855                 if (mbuf_nextpkt(m_tail
) == NULL
) 
 857                 m_tail 
= mbuf_nextpkt(m_tail
); 
 860         inp 
= ifp
->if_input_thread
; 
 862         if (dlil_multithreaded_input 
== 0 || inp 
== NULL
)  
 863                 inp 
= dlil_lo_thread_ptr
; 
 866          * If there is a matching dlil input thread associated with an 
 867          * affinity set, associate this workloop thread with the same set. 
 868          * We will only do this once. 
 870         lck_mtx_lock(inp
->input_lck
); 
 871         if (inp
->net_affinity 
&& inp
->workloop_thread 
== NULL
) { 
 872                 u_int32_t tag 
= inp
->tag
; 
 873                 inp
->workloop_thread 
= tp
; 
 874                 lck_mtx_unlock(inp
->input_lck
); 
 876                 /* Associated the current thread with the new affinity tag */ 
 877                 (void) dlil_affinity_set(tp
, tag
); 
 880                  * Take a reference on the workloop (current) thread; during 
 881                  * detach, we will need to refer to it in order ot tear down 
 884                 thread_reference(tp
); 
 885                 lck_mtx_lock(inp
->input_lck
); 
 889          * Because of loopbacked multicast we cannot stuff the ifp in 
 890          * the rcvif of the packet header: loopback has its own dlil 
 894         if (inp 
== dlil_lo_thread_ptr 
&& ifp
->if_type 
== IFT_LOOP
) { 
 895                 if (dlil_lo_input_mbuf_head 
== NULL
) 
 896                         dlil_lo_input_mbuf_head 
= m_head
; 
 897                 else if (dlil_lo_input_mbuf_tail 
!= NULL
) 
 898                         dlil_lo_input_mbuf_tail
->m_nextpkt 
= m_head
; 
 899                 dlil_lo_input_mbuf_tail 
= m_tail
; 
 900 #if IFNET_INPUT_SANITY_CHK 
 901                 if (dlil_input_sanity_check 
!= 0) { 
 902                         dlil_lo_input_mbuf_count 
+= pkt_count
; 
 903                         inp
->input_mbuf_cnt 
+= pkt_count
; 
 904                         inp
->input_wake_cnt
++; 
 906                         lck_mtx_assert(inp
->input_lck
, LCK_MTX_ASSERT_OWNED
); 
 911                 if (inp
->mbuf_head 
== NULL
) 
 912                         inp
->mbuf_head 
= m_head
; 
 913                 else if (inp
->mbuf_tail 
!= NULL
) 
 914                         inp
->mbuf_tail
->m_nextpkt 
= m_head
; 
 915                 inp
->mbuf_tail 
= m_tail
; 
 916 #if IFNET_INPUT_SANITY_CHK 
 917                 if (dlil_input_sanity_check 
!= 0) { 
 918                         inp
->mbuf_count 
+= pkt_count
; 
 919                         inp
->input_mbuf_cnt 
+= pkt_count
; 
 920                         inp
->input_wake_cnt
++; 
 922                         lck_mtx_assert(inp
->input_lck
, LCK_MTX_ASSERT_OWNED
); 
 928         inp
->input_waiting 
|= DLIL_INPUT_WAITING
; 
 929         if ((inp
->input_waiting 
& DLIL_INPUT_RUNNING
) == 0) { 
 930                 wakeup((caddr_t
)&inp
->input_waiting
); 
 933                 ifp
->if_data
.ifi_ipackets 
+= stats
->packets_in
; 
 934                 ifp
->if_data
.ifi_ibytes 
+= stats
->bytes_in
; 
 935                 ifp
->if_data
.ifi_ierrors 
+= stats
->errors_in
; 
 937                 ifp
->if_data
.ifi_opackets 
+= stats
->packets_out
; 
 938                 ifp
->if_data
.ifi_obytes 
+= stats
->bytes_out
; 
 939                 ifp
->if_data
.ifi_oerrors 
+= stats
->errors_out
; 
 941                 ifp
->if_data
.ifi_collisions 
+= stats
->collisions
; 
 942                 ifp
->if_data
.ifi_iqdrops 
+= stats
->dropped
; 
 945         lck_mtx_unlock(inp
->input_lck
); 
 951 dlil_interface_filters_input(struct ifnet 
* ifp
, struct mbuf 
* * m_p
, 
 952                              char * * frame_header_p
, 
 953                              protocol_family_t protocol_family
) 
 955         struct ifnet_filter 
*           filter
; 
 957         TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) { 
 960                 if (filter
->filt_input 
 
 961                     && (filter
->filt_protocol 
== 0 
 962                         || filter
->filt_protocol 
== protocol_family
)) { 
 963                         result 
= (*filter
->filt_input
)(filter
->filt_cookie
, 
 964                                                        ifp
, protocol_family
, 
 965                                                        m_p
, frame_header_p
); 
 975 dlil_ifproto_input(struct if_proto 
* ifproto
, mbuf_t m
) 
 979         if (ifproto
->proto_kpi 
== kProtoKPI_v1
) { 
 980                 /* Version 1 protocols get one packet at a time */ 
 985                         next_packet 
= m
->m_nextpkt
; 
 987                         frame_header 
= m
->m_pkthdr
.header
; 
 988                         m
->m_pkthdr
.header 
= NULL
; 
 989                         error 
= (*ifproto
->kpi
.v1
.input
)(ifproto
->ifp
,  
 990                                                          ifproto
->protocol_family
, 
 992                         if (error 
!= 0 && error 
!= EJUSTRETURN
) 
 997         else if (ifproto
->proto_kpi 
== kProtoKPI_v2
) { 
 998                 /* Version 2 protocols support packet lists */ 
 999                 error 
= (*ifproto
->kpi
.v2
.input
)(ifproto
->ifp
, 
1000                                                  ifproto
->protocol_family
, 
1002                 if (error 
!= 0 && error 
!= EJUSTRETURN
) 
1008 __private_extern__ 
void 
1009 dlil_input_packet_list(struct ifnet 
* ifp_param
, struct mbuf 
*m
) 
1013         protocol_family_t               protocol_family
; 
1015         ifnet_t                         ifp 
= ifp_param
; 
1016         char *                          frame_header
; 
1017         struct if_proto 
*               last_ifproto 
= NULL
; 
1018         mbuf_t                          pkt_first 
= NULL
; 
1019         mbuf_t 
*                        pkt_next 
= NULL
; 
1021         KERNEL_DEBUG(DBG_FNC_DLIL_INPUT 
| DBG_FUNC_START
,0,0,0,0,0); 
1024                 struct if_proto 
*       ifproto 
= NULL
; 
1026                 next_packet 
= m
->m_nextpkt
; 
1027                 m
->m_nextpkt 
= NULL
; 
1028                 if (ifp_param 
== NULL
) 
1029                         ifp 
= m
->m_pkthdr
.rcvif
; 
1030                 frame_header 
= m
->m_pkthdr
.header
; 
1031                 m
->m_pkthdr
.header 
= NULL
; 
1034                         /* dlil lock protects the demux and interface filters */ 
1038                 /* find which protocol family this packet is for */ 
1039                 error 
= (*ifp
->if_demux
)(ifp
, m
, frame_header
, 
1042                         if (error 
== EJUSTRETURN
) { 
1045                         protocol_family 
= 0; 
1049                 if (m
->m_flags 
& (M_BCAST
|M_MCAST
)) 
1052                 /* run interface filters, exclude VLAN packets PR-3586856 */ 
1053                 if ((m
->m_pkthdr
.csum_flags 
& CSUM_VLAN_TAG_VALID
) == 0) { 
1056                         filter_result 
= dlil_interface_filters_input(ifp
, &m
,  
1059                         if (filter_result 
!= 0) { 
1060                                 if (filter_result 
!= EJUSTRETURN
) { 
1066                 if (error 
!= 0 || ((m
->m_flags 
& M_PROMISC
) != 0) ) { 
1071                 /* Lookup the protocol attachment to this interface */ 
1072                 if (protocol_family 
== 0) { 
1075                 else if (last_ifproto 
!= NULL
 
1076                          && last_ifproto
->ifp 
== ifp
 
1077                          && (last_ifproto
->protocol_family
 
1078                              == protocol_family
)) { 
1079                         ifproto 
= last_ifproto
; 
1082                         ifproto 
= find_attached_proto(ifp
, protocol_family
); 
1084                 if (ifproto 
== NULL
) { 
1085                         /* no protocol for this packet, discard */ 
1089                 if (ifproto 
!= last_ifproto
) { 
1090                         /* make sure ifproto can't go away during input */ 
1091                         if_proto_ref(ifproto
); 
1092                         if (last_ifproto 
!= NULL
) { 
1093                                 /* pass up the list for the previous protocol */ 
1096                                 dlil_ifproto_input(last_ifproto
, pkt_first
); 
1098                                 if_proto_free(last_ifproto
); 
1101                         last_ifproto 
= ifproto
; 
1103                 /* extend the list */ 
1104                 m
->m_pkthdr
.header 
= frame_header
; 
1105                 if (pkt_first 
== NULL
) { 
1110                 pkt_next 
= &m
->m_nextpkt
; 
1113                 if (next_packet 
== NULL 
&& last_ifproto 
!= NULL
) { 
1114                         /* pass up the last list of packets */ 
1117                         dlil_ifproto_input(last_ifproto
, pkt_first
); 
1118                         if_proto_free(last_ifproto
); 
1127         KERNEL_DEBUG(DBG_FNC_DLIL_INPUT 
| DBG_FUNC_END
,0,0,0,0,0); 
1132 dlil_event_internal(struct ifnet 
*ifp
, struct kev_msg 
*event
) 
1134         struct ifnet_filter 
*filter
; 
1136         if (ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
) == 0) { 
1139                 /* Pass the event to the interface filters */ 
1140                 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) { 
1141                         if (filter
->filt_event
) 
1142                                 filter
->filt_event(filter
->filt_cookie
, ifp
, filter
->filt_protocol
, event
); 
1145                 if (ifp
->if_proto_hash
) { 
1148                         for (i 
= 0; i 
< PROTO_HASH_SLOTS
; i
++) { 
1149                                 struct if_proto 
*proto
; 
1151                                 SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) { 
1152                                         proto_media_event eventp 
= proto
->proto_kpi 
== kProtoKPI_v1
 
1153                                                  ? proto
->kpi
.v1
.event 
: proto
->kpi
.v2
.event
; 
1156                                                 eventp(ifp
, proto
->protocol_family
, event
); 
1163                 /* Pass the event to the interface */ 
1165                         ifp
->if_event(ifp
, event
); 
1168                         ifp_use_reached_zero(ifp
); 
1171         return kev_post_msg(event
); 
1177         struct kern_event_msg   
*event
) 
1179         struct kev_msg               kev_msg
; 
1182         if (ifp 
== NULL 
|| event 
== NULL
) return EINVAL
; 
1184         kev_msg
.vendor_code    
= event
->vendor_code
; 
1185         kev_msg
.kev_class      
= event
->kev_class
; 
1186         kev_msg
.kev_subclass   
= event
->kev_subclass
; 
1187         kev_msg
.event_code     
= event
->event_code
; 
1188         kev_msg
.dv
[0].data_ptr 
= &event
->event_data
[0]; 
1189         kev_msg
.dv
[0].data_length 
= event
->total_size 
- KEV_MSG_HEADER_SIZE
; 
1190         kev_msg
.dv
[1].data_length 
= 0; 
1192         result 
= dlil_event_internal(ifp
, &kev_msg
); 
1198 #include <netinet/ip6.h> 
1199 #include <netinet/ip.h> 
1200 static int dlil_get_socket_type(struct mbuf 
**mp
, int family
, int raw
) 
1204         struct ip6_hdr 
*ip6
; 
1205         int type 
= SOCK_RAW
; 
1210                         m 
= m_pullup(*mp
, sizeof(struct ip
)); 
1214                         ip 
= mtod(m
, struct ip 
*); 
1215                         if (ip
->ip_p 
== IPPROTO_TCP
) 
1217                         else if (ip
->ip_p 
== IPPROTO_UDP
) 
1221                         m 
= m_pullup(*mp
, sizeof(struct ip6_hdr
)); 
1225                         ip6 
= mtod(m
, struct ip6_hdr 
*); 
1226                         if (ip6
->ip6_nxt 
== IPPROTO_TCP
) 
1228                         else if (ip6
->ip6_nxt 
== IPPROTO_UDP
) 
1242         u_long proto_family
, 
1243         struct mbuf             
*packetlist
, 
1245         const struct sockaddr   
*dest
, 
1248         char                    *frame_type 
= NULL
; 
1249         char                    *dst_linkaddr 
= NULL
; 
1251         char                    frame_type_buffer
[MAX_FRAME_TYPE_SIZE 
* 4]; 
1252         char                    dst_linkaddr_buffer
[MAX_LINKADDR 
* 4]; 
1253         struct ifnet_filter 
*filter
; 
1254         struct if_proto 
*proto 
= 0; 
1256         mbuf_t  send_head 
= NULL
; 
1257         mbuf_t  
*send_tail 
= &send_head
; 
1259         KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT 
| DBG_FUNC_START
,0,0,0,0,0); 
1263         frame_type         
= frame_type_buffer
; 
1264         dst_linkaddr   
= dst_linkaddr_buffer
; 
1267                 proto 
= find_attached_proto(ifp
, proto_family
); 
1268                 if (proto 
== NULL
) { 
1275         if (packetlist 
== NULL
) 
1278         packetlist 
= packetlist
->m_nextpkt
; 
1279         m
->m_nextpkt 
= NULL
; 
1282                 proto_media_preout preoutp 
= proto
->proto_kpi 
== kProtoKPI_v1
 
1283                          ? proto
->kpi
.v1
.pre_output 
: proto
->kpi
.v2
.pre_output
; 
1286                         retval 
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
); 
1289                         if (retval 
== EJUSTRETURN
) { 
1300                 retval 
= mac_ifnet_check_transmit(ifp
, m
, proto_family
, 
1301                     dlil_get_socket_type(&m
, proto_family
, raw
)); 
1308                 if (raw 
== 0 && ifp
->if_framer
) { 
1309                         retval 
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);  
1311                                 if (retval 
!= EJUSTRETURN
) { 
1321                  * Need to consider how to handle this. 
1322                  * Also note that return should be a goto cleanup 
1326                         struct mbuf 
*m0 
= m
; 
1327                         struct ether_header 
*eh 
= mtod(m
, struct ether_header 
*); 
1329                         if (m
->m_pkthdr
.rcvif
) 
1330                                 m
->m_pkthdr
.rcvif 
= NULL
; 
1331                         ifp 
= bridge_dst_lookup(eh
); 
1332                         bdg_forward(&m0
, ifp
); 
1336                         return 0 - should be 
goto cleanup
? 
1341                  * Let interface filters (if any) do their thing ... 
1343                 /* Do not pass VLAN tagged packets to filters PR-3586856 */ 
1344                 if ((m
->m_pkthdr
.csum_flags 
& CSUM_VLAN_TAG_VALID
) == 0) { 
1345                         TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) { 
1346                                 if ((filter
->filt_protocol 
== 0 || (filter
->filt_protocol 
== proto_family
)) && 
1347                                         filter
->filt_output
) { 
1348                                         retval 
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
); 
1350                                                 if (retval 
!= EJUSTRETURN
) 
1359                  * Finally, call the driver. 
1362                 if ((ifp
->if_eflags 
& IFEF_SENDLIST
) != 0) { 
1364                         send_tail 
= &m
->m_nextpkt
; 
1367                         KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_START
, 0,0,0,0,0); 
1368                         retval 
= ifp
->if_output(ifp
, m
); 
1370                                 printf("dlil_output: output error retval = %x\n", retval
); 
1372                         KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
1374                 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
1379                         packetlist 
= packetlist
->m_nextpkt
; 
1380                         m
->m_nextpkt 
= NULL
; 
1385                 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_START
, 0,0,0,0,0); 
1386                 retval 
= ifp
->if_output(ifp
, send_head
); 
1388                         printf("dlil_output: output error retval = %x\n", retval
); 
1390                 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
1393         KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT 
| DBG_FUNC_END
,0,0,0,0,0); 
1397         if (packetlist
) /* if any packet left, clean up */ 
1398                 mbuf_freem_list(packetlist
); 
1399         if (retval 
== EJUSTRETURN
) 
1408  * Caller should have a lock on the protocol domain if the protocol 
1409  * doesn't support finer grained locking. In most cases, the lock 
1410  * will be held from the socket layer and won't be released until 
1411  * we return back to the socket layer. 
1413  * This does mean that we must take a protocol lock before we take 
1414  * an interface lock if we're going to take both. This makes sense 
1415  * because a protocol is likely to interact with an ifp while it 
1416  * is under the protocol lock. 
1418 __private_extern__ errno_t
 
1421         protocol_family_t               proto_family
, 
1424         const struct sockaddr   
*dest
, 
1427         char                    *frame_type 
= NULL
; 
1428         char                    *dst_linkaddr 
= NULL
; 
1430         char                    frame_type_buffer
[MAX_FRAME_TYPE_SIZE 
* 4]; 
1431         char                    dst_linkaddr_buffer
[MAX_LINKADDR 
* 4]; 
1432         struct ifnet_filter 
*filter
; 
1433         struct if_proto 
*proto 
= 0; 
1435         mbuf_t  send_head 
= NULL
; 
1436         mbuf_t  
*send_tail 
= &send_head
; 
1438         KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT 
| DBG_FUNC_START
,0,0,0,0,0); 
1442         frame_type         
= frame_type_buffer
; 
1443         dst_linkaddr   
= dst_linkaddr_buffer
; 
1446                 proto 
= find_attached_proto(ifp
, proto_family
); 
1447                 if (proto 
== NULL
) { 
1454         if (packetlist 
== NULL
) 
1457         packetlist 
= packetlist
->m_nextpkt
; 
1458         m
->m_nextpkt 
= NULL
; 
1461                 proto_media_preout preoutp 
= proto
->proto_kpi 
== kProtoKPI_v1
 
1462                          ? proto
->kpi
.v1
.pre_output 
: proto
->kpi
.v2
.pre_output
; 
1465                         retval 
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
); 
1468                         if (retval 
== EJUSTRETURN
) { 
1478         retval 
= mac_ifnet_check_transmit(ifp
, m
, proto_family
, 
1479             dlil_get_socket_type(&m
, proto_family
, raw
)); 
1487                 if (raw 
== 0 && ifp
->if_framer
) { 
1488                         retval 
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);  
1490                                 if (retval 
!= EJUSTRETURN
) { 
1500                  * Need to consider how to handle this. 
1501                  * Also note that return should be a goto cleanup 
1505                         struct mbuf 
*m0 
= m
; 
1506                         struct ether_header 
*eh 
= mtod(m
, struct ether_header 
*); 
1508                         if (m
->m_pkthdr
.rcvif
) 
1509                                 m
->m_pkthdr
.rcvif 
= NULL
; 
1510                         ifp 
= bridge_dst_lookup(eh
); 
1511                         bdg_forward(&m0
, ifp
); 
1515                         return 0 - should be 
goto cleanup
? 
1520                  * Let interface filters (if any) do their thing ... 
1522                 /* Do not pass VLAN tagged packets to filters PR-3586856 */ 
1523                 if ((m
->m_pkthdr
.csum_flags 
& CSUM_VLAN_TAG_VALID
) == 0) { 
1524                         TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) { 
1525                                 if ((filter
->filt_protocol 
== 0 || (filter
->filt_protocol 
== proto_family
)) && 
1526                                         filter
->filt_output
) { 
1527                                         retval 
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
); 
1529                                                 if (retval 
!= EJUSTRETURN
) 
1538                  * If the underlying interface is not capable of handling a 
1539                  * packet whose data portion spans across physically disjoint 
1540                  * pages, we need to "normalize" the packet so that we pass 
1541                  * down a chain of mbufs where each mbuf points to a span that 
1542                  * resides in the system page boundary.  If the packet does 
1543                  * not cross page(s), the following is a no-op. 
1545                 if (!(ifp
->if_hwassist 
& IFNET_MULTIPAGES
)) { 
1546                         if ((m 
= m_normalize(m
)) == NULL
) 
1551                  * Finally, call the driver. 
1554                 if ((ifp
->if_eflags 
& IFEF_SENDLIST
) != 0) { 
1556                         send_tail 
= &m
->m_nextpkt
; 
1559                         KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_START
, 0,0,0,0,0); 
1560                         retval 
= ifp
->if_output(ifp
, m
); 
1562                                 printf("dlil_output: output error retval = %x\n", retval
); 
1564                         KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
1566                 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
1571                         packetlist 
= packetlist
->m_nextpkt
; 
1572                         m
->m_nextpkt 
= NULL
; 
1577                 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_START
, 0,0,0,0,0); 
1578                 retval 
= ifp
->if_output(ifp
, send_head
); 
1580                         printf("dlil_output: output error retval = %x\n", retval
); 
1582                 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
1585         KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT 
| DBG_FUNC_END
,0,0,0,0,0); 
1589         if (packetlist
) /* if any packet left, clean up */ 
1590                 mbuf_freem_list(packetlist
); 
1591         if (retval 
== EJUSTRETURN
) 
1599         protocol_family_t       proto_fam
, 
1600         u_int32_t                       ioctl_code
, 
1603         struct ifnet_filter             
*filter
; 
1604         int                                             retval 
= EOPNOTSUPP
; 
1606         int                                             holding_read 
= 0; 
1608         if (ifp 
== NULL 
|| ioctl_code 
== 0) 
1611         /* Attempt to increment the use count. If it's zero, bail out, the ifp is invalid */ 
1612         result 
= ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
); 
1619         /* Run the interface filters first. 
1620          * We want to run all filters before calling the protocol, 
1621          * interface family, or interface. 
1623         TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) { 
1624                 if ((filter
->filt_protocol 
== 0 || (filter
->filt_protocol 
== proto_fam
)) && 
1625                         filter
->filt_ioctl 
!= NULL
) { 
1626                         result 
= filter
->filt_ioctl(filter
->filt_cookie
, ifp
, proto_fam
, ioctl_code
, ioctl_arg
); 
1627                         /* Only update retval if no one has handled the ioctl */ 
1628                         if (retval 
== EOPNOTSUPP 
|| result 
== EJUSTRETURN
) { 
1629                                 if (result 
== ENOTSUP
) 
1630                                         result 
= EOPNOTSUPP
; 
1632                                 if (retval 
&& retval 
!= EOPNOTSUPP
) { 
1639         /* Allow the protocol to handle the ioctl */ 
1641                 struct if_proto 
*proto 
= find_attached_proto(ifp
, proto_fam
); 
1644                         proto_media_ioctl ioctlp 
= proto
->proto_kpi 
== kProtoKPI_v1
 
1645                                  ? proto
->kpi
.v1
.ioctl 
: proto
->kpi
.v2
.ioctl
; 
1646                         result 
= EOPNOTSUPP
; 
1648                                 result 
= ioctlp(ifp
, proto_fam
, ioctl_code
, ioctl_arg
); 
1650                         /* Only update retval if no one has handled the ioctl */ 
1651                         if (retval 
== EOPNOTSUPP 
|| result 
== EJUSTRETURN
) { 
1652                                 if (result 
== ENOTSUP
) 
1653                                         result 
= EOPNOTSUPP
; 
1655                                 if (retval 
&& retval 
!= EOPNOTSUPP
) { 
1663          * Since we have incremented the use count on the ifp, we are guaranteed 
1664          * that the ifp will not go away (the function pointers may not be changed). 
1665          * We release the dlil read lock so the interface ioctl may trigger a 
1666          * protocol attach. This happens with vlan and may occur with other virtual 
1672         /* retval is either 0 or EOPNOTSUPP */ 
1675          * Let the interface handle this ioctl. 
1676          * If it returns EOPNOTSUPP, ignore that, we may have 
1677          * already handled this in the protocol or family. 
1680                 result 
= (*ifp
->if_ioctl
)(ifp
, ioctl_code
, ioctl_arg
); 
1682         /* Only update retval if no one has handled the ioctl */ 
1683         if (retval 
== EOPNOTSUPP 
|| result 
== EJUSTRETURN
) { 
1684                 if (result 
== ENOTSUP
) 
1685                         result 
= EOPNOTSUPP
; 
1687                 if (retval 
&& retval 
!= EOPNOTSUPP
) { 
1696                 ifp_use_reached_zero(ifp
); 
1698         if (retval 
== EJUSTRETURN
) 
1703 __private_extern__ errno_t
 
1707         bpf_packet_func callback
) 
1712         if (ifp
->if_set_bpf_tap
) 
1713                 error 
= ifp
->if_set_bpf_tap(ifp
, mode
, callback
); 
1722         const struct sockaddr 
*proto_addr
, 
1723         struct sockaddr 
*ll_addr
, 
1726         errno_t result 
= EOPNOTSUPP
; 
1727         struct if_proto 
*proto
; 
1728         const struct sockaddr 
*verify
; 
1729         proto_media_resolve_multi resolvep
; 
1733         bzero(ll_addr
, ll_len
); 
1735         /* Call the protocol first */ 
1736         proto 
= find_attached_proto(ifp
, proto_addr
->sa_family
); 
1737         if (proto 
!= NULL
) { 
1738                 resolvep 
= proto
->proto_kpi 
== kProtoKPI_v1
 
1739                          ? proto
->kpi
.v1
.resolve_multi 
: proto
->kpi
.v2
.resolve_multi
; 
1740                 if (resolvep 
!= NULL
) 
1741                         result 
= resolvep(ifp
, proto_addr
,(struct sockaddr_dl
*)ll_addr
, 
1745         /* Let the interface verify the multicast address */ 
1746         if ((result 
== EOPNOTSUPP 
|| result 
== 0) && ifp
->if_check_multi
) { 
1750                         verify 
= proto_addr
; 
1751                 result 
= ifp
->if_check_multi(ifp
, verify
); 
1759 __private_extern__ errno_t
 
1760 dlil_send_arp_internal( 
1763         const struct sockaddr_dl
* sender_hw
, 
1764         const struct sockaddr
* sender_proto
, 
1765         const struct sockaddr_dl
* target_hw
, 
1766         const struct sockaddr
* target_proto
) 
1768         struct if_proto 
*proto
; 
1773         proto 
= find_attached_proto(ifp
, target_proto
->sa_family
); 
1774         if (proto 
== NULL
) { 
1778                 proto_media_send_arp    arpp
; 
1779                 arpp 
= proto
->proto_kpi 
== kProtoKPI_v1
 
1780                          ? proto
->kpi
.v1
.send_arp 
: proto
->kpi
.v2
.send_arp
; 
1784                         result 
= arpp(ifp
, arpop
, sender_hw
, sender_proto
, target_hw
, 
1793 static __inline__ 
int 
1794 _is_announcement(const struct sockaddr_in 
* sender_sin
, 
1795                      const struct sockaddr_in 
* target_sin
) 
1797         if (sender_sin 
== NULL
) { 
1800         return (sender_sin
->sin_addr
.s_addr 
== target_sin
->sin_addr
.s_addr
); 
1803 __private_extern__ errno_t
 
1807         const struct sockaddr_dl
* sender_hw
, 
1808         const struct sockaddr
* sender_proto
, 
1809         const struct sockaddr_dl
* target_hw
, 
1810         const struct sockaddr
* target_proto
) 
1813         const struct sockaddr_in 
* sender_sin
; 
1814         const struct sockaddr_in 
* target_sin
; 
1816         if (target_proto 
== NULL 
|| (sender_proto 
&& 
1817                 sender_proto
->sa_family 
!= target_proto
->sa_family
)) 
1821          * If this is an ARP request and the target IP is IPv4LL, 
1822          * send the request on all interfaces.  The exception is 
1823          * an announcement, which must only appear on the specific 
1826         sender_sin 
= (const struct sockaddr_in 
*)sender_proto
; 
1827         target_sin 
= (const struct sockaddr_in 
*)target_proto
; 
1828         if (target_proto
->sa_family 
== AF_INET
 
1829             && IN_LINKLOCAL(ntohl(target_sin
->sin_addr
.s_addr
)) 
1830             && ipv4_ll_arp_aware 
!= 0 
1831             && arpop 
== ARPOP_REQUEST
 
1832             && !_is_announcement(target_sin
, sender_sin
)) { 
1839                 if (ifnet_list_get(IFNET_FAMILY_ANY
, &ifp_list
, &count
) == 0) { 
1840                         for (ifp_on 
= 0; ifp_on 
< count
; ifp_on
++) { 
1842                                 ifaddr_t                        source_hw 
= NULL
; 
1843                                 ifaddr_t                        source_ip 
= NULL
; 
1844                                 struct sockaddr_in      source_ip_copy
; 
1847                                  * Only arp on interfaces marked for IPv4LL ARPing. This may 
1848                                  * mean that we don't ARP on the interface the subnet route 
1851                                 if ((ifp_list
[ifp_on
]->if_eflags 
& IFEF_ARPLL
) == 0) { 
1855                                 source_hw 
= TAILQ_FIRST(&ifp_list
[ifp_on
]->if_addrhead
); 
1857                                 /* Find the source IP address */ 
1858                                 ifnet_lock_shared(ifp_list
[ifp_on
]); 
1859                                 TAILQ_FOREACH(source_ip
, &ifp_list
[ifp_on
]->if_addrhead
, 
1861                                         if (source_ip
->ifa_addr 
&& 
1862                                                 source_ip
->ifa_addr
->sa_family 
== AF_INET
) { 
1867                                 /* No IP Source, don't arp */ 
1868                                 if (source_ip 
== NULL
) { 
1869                                         ifnet_lock_done(ifp_list
[ifp_on
]); 
1873                                 /* Copy the source IP address */ 
1874                                 source_ip_copy 
= *(struct sockaddr_in
*)source_ip
->ifa_addr
; 
1876                                 ifnet_lock_done(ifp_list
[ifp_on
]); 
1879                                 new_result 
= dlil_send_arp_internal(ifp_list
[ifp_on
], arpop
, 
1880                                                                         (struct sockaddr_dl
*)source_hw
->ifa_addr
, 
1881                                                                         (struct sockaddr
*)&source_ip_copy
, NULL
, 
1884                                 if (result 
== ENOTSUP
) { 
1885                                         result 
= new_result
; 
1890                 ifnet_list_free(ifp_list
); 
1893                 result 
= dlil_send_arp_internal(ifp
, arpop
, sender_hw
, sender_proto
, 
1894                                                                                 target_hw
, target_proto
); 
1900 __private_extern__ 
int 
1909                 old_value 
= ifp
->if_usecnt
; 
1910                 if (old_value 
== 0 && handle_zero 
== kIfNetUseCount_MustNotBeZero
) { 
1911                         retval 
= ENXIO
; // ifp is invalid 
1914         } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)old_value 
+ 1, (UInt32
*)&ifp
->if_usecnt
)); 
1919 /* ifp_unuse is broken into two pieces. 
1921  * ifp_use and ifp_unuse must be called between when the caller calls 
1922  * dlil_write_begin and dlil_write_end. ifp_unuse needs to perform some 
1923  * operations after dlil_write_end has been called. For this reason, 
1924  * anyone calling ifp_unuse must call ifp_use_reached_zero if ifp_unuse 
1925  * returns a non-zero value. The caller must call ifp_use_reached_zero 
1926  * after the caller has called dlil_write_end. 
1928 __private_extern__ 
void 
1929 ifp_use_reached_zero( 
1932         ifnet_detached_func     free_func
; 
1936         if (ifp
->if_usecnt 
!= 0) 
1937                 panic("ifp_use_reached_zero: ifp->if_usecnt != 0"); 
1939         ifnet_head_lock_exclusive(); 
1940         ifnet_lock_exclusive(ifp
); 
1942         /* Remove ourselves from the list */ 
1943         TAILQ_REMOVE(&ifnet_head
, ifp
, if_link
); 
1944         ifnet_addrs
[ifp
->if_index 
- 1] = NULL
; 
1946         /* ifp should be removed from the interface list */ 
1947         while (ifp
->if_multiaddrs
.lh_first
) { 
1948                 struct ifmultiaddr 
*ifma 
= ifp
->if_multiaddrs
.lh_first
; 
1951                  * When the interface is gone, we will no longer 
1952                  * be listening on these multicasts. Various bits 
1953                  * of the stack may be referencing these multicasts, 
1954                  * release only our reference. 
1956                 LIST_REMOVE(ifma
, ifma_link
); 
1957                 ifma
->ifma_ifp 
= NULL
; 
1962         ifp
->if_eflags 
&= ~IFEF_DETACHING
; // clear the detaching flag 
1963         ifnet_lock_done(ifp
); 
1965         free_func 
= ifp
->if_free
; 
1967         dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHED
, NULL
, 0); 
1973 __private_extern__ 
int 
1978         oldval 
= OSDecrementAtomic((SInt32
*)&ifp
->if_usecnt
); 
1980                 panic("ifp_unuse: ifp(%s%d)->if_usecnt was zero\n", ifp
->if_name
, ifp
->if_unit
); 
1985         if ((ifp
->if_eflags 
& IFEF_DETACHING
) == 0) 
1986                 panic("ifp_unuse: use count reached zero but detching flag is not set!"); 
1988         return 1; /* caller must call ifp_use_reached_zero */ 
1991 extern lck_mtx_t        
*domain_proto_mtx
; 
1994 dlil_attach_protocol_internal( 
1995         struct if_proto 
*proto
, 
1996         const struct ifnet_demux_desc 
*demux_list
, 
1997         u_int32_t       demux_count
) 
1999         struct kev_dl_proto_data        ev_pr_data
; 
2000         struct ifnet 
*ifp 
= proto
->ifp
; 
2002         u_long hash_value 
= proto_hash_value(proto
->protocol_family
); 
2004     /* setup some of the common values */ 
2007                 lck_mtx_lock(domain_proto_mtx
); 
2009                 while (dp 
&& (protocol_family_t
)dp
->dom_family 
!= proto
->protocol_family
) 
2011                 proto
->dl_domain 
= dp
; 
2012                 lck_mtx_unlock(domain_proto_mtx
); 
2016          * Take the write lock to protect readers and exclude other writers. 
2018         if ((retval 
= dlil_write_begin()) != 0) { 
2019                 printf("dlil_attach_protocol_internal - dlil_write_begin returned %d\n", retval
); 
2023         /* Check that the interface isn't currently detaching */ 
2024         ifnet_lock_shared(ifp
); 
2025         if ((ifp
->if_eflags 
& IFEF_DETACHING
) != 0) { 
2026                 ifnet_lock_done(ifp
); 
2030         ifnet_lock_done(ifp
); 
2032         if (find_attached_proto(ifp
, proto
->protocol_family
) != NULL
) { 
2038          * Call family module add_proto routine so it can refine the 
2039          * demux descriptors as it wishes. 
2041         retval 
= ifp
->if_add_proto(ifp
, proto
->protocol_family
, demux_list
, demux_count
); 
2048          * We can't fail from this point on. 
2049          * Increment the number of uses (protocol attachments + interface attached). 
2051         ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
); 
2054          * Insert the protocol in the hash 
2057                 struct if_proto
*        prev_proto 
= SLIST_FIRST(&ifp
->if_proto_hash
[hash_value
]); 
2058                 while (prev_proto 
&& SLIST_NEXT(prev_proto
, next_hash
) != NULL
) 
2059                         prev_proto 
= SLIST_NEXT(prev_proto
, next_hash
); 
2061                         SLIST_INSERT_AFTER(prev_proto
, proto
, next_hash
); 
2063                         SLIST_INSERT_HEAD(&ifp
->if_proto_hash
[hash_value
], proto
, next_hash
); 
2067          * Add to if_proto list for this interface 
2069         if_proto_ref(proto
); 
2072         /* the reserved field carries the number of protocol still attached (subject to change) */ 
2073         ev_pr_data
.proto_family 
= proto
->protocol_family
; 
2074         ev_pr_data
.proto_remaining_count 
= dlil_ifp_proto_count(ifp
); 
2075         dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_ATTACHED
,  
2076                                   (struct net_event_data 
*)&ev_pr_data
,  
2077                                   sizeof(struct kev_dl_proto_data
)); 
2079         DLIL_PRINTF("dlil. Attached protocol %d to %s%d - %d\n", proto
->protocol_family
, 
2080                          ifp
->if_name
, ifp
->if_unit
, retval
); 
2086 ifnet_attach_protocol(ifnet_t ifp
, protocol_family_t protocol
, 
2087         const struct ifnet_attach_proto_param 
*proto_details
) 
2090         struct if_proto  
*ifproto 
= NULL
; 
2092         if (ifp 
== NULL 
|| protocol 
== 0 || proto_details 
== NULL
) 
2095         ifproto 
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
); 
2097                 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n"); 
2101         bzero(ifproto
, sizeof(*ifproto
)); 
2104         ifproto
->protocol_family 
= protocol
; 
2105         ifproto
->proto_kpi 
= kProtoKPI_v1
; 
2106         ifproto
->kpi
.v1
.input 
= proto_details
->input
; 
2107         ifproto
->kpi
.v1
.pre_output 
= proto_details
->pre_output
; 
2108         ifproto
->kpi
.v1
.event 
= proto_details
->event
; 
2109         ifproto
->kpi
.v1
.ioctl 
= proto_details
->ioctl
; 
2110         ifproto
->kpi
.v1
.detached 
= proto_details
->detached
; 
2111         ifproto
->kpi
.v1
.resolve_multi 
= proto_details
->resolve
; 
2112         ifproto
->kpi
.v1
.send_arp 
= proto_details
->send_arp
; 
2114         retval 
= dlil_attach_protocol_internal(ifproto
, 
2115                                 proto_details
->demux_list
, proto_details
->demux_count
); 
2118         if (retval 
&& ifproto
) 
2119                 FREE(ifproto
, M_IFADDR
); 
2124 ifnet_attach_protocol_v2(ifnet_t ifp
, protocol_family_t protocol
, 
2125         const struct ifnet_attach_proto_param_v2 
*proto_details
) 
2128         struct if_proto  
*ifproto 
= NULL
; 
2130         if (ifp 
== NULL 
|| protocol 
== 0 || proto_details 
== NULL
) 
2133         ifproto 
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
); 
2135                 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n"); 
2139         bzero(ifproto
, sizeof(*ifproto
)); 
2142         ifproto
->protocol_family 
= protocol
; 
2143         ifproto
->proto_kpi 
= kProtoKPI_v2
; 
2144         ifproto
->kpi
.v2
.input 
= proto_details
->input
; 
2145         ifproto
->kpi
.v2
.pre_output 
= proto_details
->pre_output
; 
2146         ifproto
->kpi
.v2
.event 
= proto_details
->event
; 
2147         ifproto
->kpi
.v2
.ioctl 
= proto_details
->ioctl
; 
2148         ifproto
->kpi
.v2
.detached 
= proto_details
->detached
; 
2149         ifproto
->kpi
.v2
.resolve_multi 
= proto_details
->resolve
; 
2150         ifproto
->kpi
.v2
.send_arp 
= proto_details
->send_arp
; 
2152         retval 
= dlil_attach_protocol_internal(ifproto
, 
2153                                 proto_details
->demux_list
, proto_details
->demux_count
); 
2156         if (retval 
&& ifproto
) 
2157                 FREE(ifproto
, M_IFADDR
); 
2161 extern void if_rtproto_del(struct ifnet 
*ifp
, int protocol
); 
2164 dlil_detach_protocol_internal( 
2165         struct if_proto 
*proto
) 
2167         struct ifnet 
*ifp 
= proto
->ifp
; 
2168         u_long proto_family 
= proto
->protocol_family
; 
2169         struct kev_dl_proto_data        ev_pr_data
; 
2171         if (proto
->proto_kpi 
== kProtoKPI_v1
) { 
2172                 if (proto
->kpi
.v1
.detached
) 
2173                         proto
->kpi
.v1
.detached(ifp
, proto
->protocol_family
); 
2175         if (proto
->proto_kpi 
== kProtoKPI_v2
) { 
2176                 if (proto
->kpi
.v2
.detached
) 
2177                         proto
->kpi
.v2
.detached(ifp
, proto
->protocol_family
); 
2179         if_proto_free(proto
); 
2182          * Cleanup routes that may still be in the routing table for that interface/protocol pair. 
2185         if_rtproto_del(ifp
, proto_family
); 
2187         /* the reserved field carries the number of protocol still attached (subject to change) */ 
2188         ev_pr_data
.proto_family   
= proto_family
; 
2189         ev_pr_data
.proto_remaining_count 
= dlil_ifp_proto_count(ifp
); 
2190         dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_DETACHED
,  
2191                                   (struct net_event_data 
*)&ev_pr_data
,  
2192                                   sizeof(struct kev_dl_proto_data
)); 
2197 ifnet_detach_protocol(ifnet_t ifp
, protocol_family_t proto_family
) 
2199         struct if_proto 
*proto 
= NULL
; 
2201         int use_reached_zero 
= 0; 
2203         if (ifp 
== NULL 
|| proto_family 
== 0) return EINVAL
; 
2205         if ((retval 
= dlil_write_begin()) != 0) { 
2206                 if (retval 
== EDEADLK
) { 
2209                         proto 
= find_attached_proto(ifp
, proto_family
); 
2214                                 proto
->detaching 
= 1; 
2215                                 dlil_detach_waiting 
= 1; 
2216                                 wakeup(&dlil_detach_waiting
); 
2223         proto 
= find_attached_proto(ifp
, proto_family
); 
2225         if (proto 
== NULL
) { 
2232          * Call family module del_proto 
2235         if (ifp
->if_del_proto
) 
2236                 ifp
->if_del_proto(ifp
, proto
->protocol_family
); 
2238         SLIST_REMOVE(&ifp
->if_proto_hash
[proto_hash_value(proto_family
)], proto
, if_proto
, next_hash
); 
2241          * We can do the rest of the work outside of the write lock. 
2243         use_reached_zero 
= ifp_unuse(ifp
); 
2246         dlil_detach_protocol_internal(proto
); 
2249          * Only handle the case where the interface will go away after 
2250          * we've sent the message. This way post message can send the 
2251          * message to the interface safely. 
2254         if (use_reached_zero
) 
2255                 ifp_use_reached_zero(ifp
); 
2262  * dlil_delayed_detach_thread is responsible for detaching 
2263  * protocols, protocol filters, and interface filters after 
2264  * an attempt was made to detach one of those items while 
2265  * it was not safe to do so (i.e. called dlil_read_begin). 
2267  * This function will take the dlil write lock and walk 
2268  * through each of the interfaces looking for items with 
2269  * the detaching flag set. When an item is found, it is 
2270  * detached from the interface and placed on a local list. 
2271  * After all of the items have been collected, we drop the 
2272  * write lock and performed the post detach. This is done 
2273  * so we only have to take the write lock once. 
2275  * When detaching a protocol filter, if we find that we 
2276  * have detached the very last protocol and we need to call 
2277  * ifp_use_reached_zero, we have to break out of our work 
2278  * to drop the write lock so we can call ifp_use_reached_zero. 
2282 dlil_delayed_detach_thread(__unused 
void* foo
, __unused wait_result_t wait
) 
2284         thread_t self 
= current_thread(); 
2287         ml_thread_policy(self
, MACHINE_GROUP
, 
2288                                          (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
)); 
2292                 if (dlil_detach_waiting 
!= 0 && dlil_write_begin() == 0) { 
2294                         struct proto_hash_entry detached_protos
; 
2295                         struct ifnet_filter_head detached_filters
; 
2296                         struct if_proto 
*proto
; 
2297                         struct if_proto 
*next_proto
; 
2298                         struct ifnet_filter 
*filt
; 
2299                         struct ifnet_filter 
*next_filt
; 
2304                         /* Clear the detach waiting flag */ 
2305                         dlil_detach_waiting 
= 0; 
2306                         TAILQ_INIT(&detached_filters
); 
2307                         SLIST_INIT(&detached_protos
); 
2309                         ifnet_head_lock_shared(); 
2310                         TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) { 
2313                                 // Look for protocols and protocol filters 
2314                                 for (i 
= 0; i 
< PROTO_HASH_SLOTS 
&& !reached_zero
; i
++) { 
2315                                         struct if_proto 
**prev_nextptr 
= &SLIST_FIRST(&ifp
->if_proto_hash
[i
]); 
2316                                         for (proto 
= *prev_nextptr
; proto
; proto 
= *prev_nextptr
) { 
2318                                                 // Detach this protocol 
2319                                                 if (proto
->detaching
) { 
2320                                                         if (ifp
->if_del_proto
) 
2321                                                                 ifp
->if_del_proto(ifp
, proto
->protocol_family
); 
2322                                                         *prev_nextptr 
= SLIST_NEXT(proto
, next_hash
); 
2323                                                         SLIST_INSERT_HEAD(&detached_protos
, proto
, next_hash
); 
2324                                                         reached_zero 
= ifp_unuse(ifp
); 
2330                                                         // Update prev_nextptr to point to our next ptr 
2331                                                         prev_nextptr 
= &SLIST_NEXT(proto
, next_hash
); 
2336                                 // look for interface filters that need to be detached 
2337                                 for (filt 
= TAILQ_FIRST(&ifp
->if_flt_head
); filt
; filt 
= next_filt
) { 
2338                                         next_filt 
= TAILQ_NEXT(filt
, filt_next
); 
2339                                         if (filt
->filt_detaching 
!= 0) { 
2340                                                 // take this interface filter off the interface filter list 
2341                                                 TAILQ_REMOVE(&ifp
->if_flt_head
, filt
, filt_next
); 
2343                                                 // put this interface filter on the detached filters list 
2344                                                 TAILQ_INSERT_TAIL(&detached_filters
, filt
, filt_next
); 
2348                                 if (ifp
->if_delayed_detach
) { 
2349                                         ifp
->if_delayed_detach 
= 0; 
2350                                         reached_zero 
= ifp_unuse(ifp
); 
2359                         for (filt 
= TAILQ_FIRST(&detached_filters
); filt
; filt 
= next_filt
) { 
2360                                 next_filt 
= TAILQ_NEXT(filt
, filt_next
); 
2362                                  * dlil_detach_filter_internal won't remove an item from 
2363                                  * the list if it is already detached (second parameter). 
2364                                  * The item will be freed though. 
2366                                 dlil_detach_filter_internal(filt
, 1); 
2369                         for (proto 
= SLIST_FIRST(&detached_protos
); proto
; proto 
= next_proto
) { 
2370                                 next_proto 
= SLIST_NEXT(proto
, next_hash
); 
2371                                 dlil_detach_protocol_internal(proto
); 
2375                                 ifp_use_reached_zero(ifp
); 
2376                                 dlil_detach_waiting 
= 1; // we may have missed something 
2380                 if (!asserted 
&& dlil_detach_waiting 
== 0) { 
2382                         assert_wait(&dlil_detach_waiting
, THREAD_UNINT
); 
2385                 if (dlil_detach_waiting 
== 0) { 
2387                         thread_block(dlil_delayed_detach_thread
); 
2393 dlil_call_delayed_detach_thread(void) { 
2394         dlil_delayed_detach_thread(NULL
, THREAD_RESTART
); 
2397 extern int if_next_index(void); 
2402         const struct sockaddr_dl        
*ll_addr
) 
2404         u_long              interface_family
; 
2405         struct ifnet 
*tmp_if
; 
2406         struct proto_hash_entry 
*new_proto_list 
= NULL
; 
2409         if (ifp 
== NULL
) return EINVAL
; 
2410         if (ll_addr 
&& ifp
->if_addrlen 
== 0) { 
2411                 ifp
->if_addrlen 
= ll_addr
->sdl_alen
; 
2413         else if (ll_addr 
&& ll_addr
->sdl_alen 
!= ifp
->if_addrlen
) { 
2417         interface_family 
= ifp
->if_family
; 
2419         ifnet_head_lock_shared(); 
2421         /* Verify we aren't already on the list */ 
2422         TAILQ_FOREACH(tmp_if
, &ifnet_head
, if_link
) { 
2423                 if (tmp_if 
== ifp
) { 
2431         if ((ifp
->if_eflags 
& IFEF_REUSE
) == 0 || ifp
->if_lock 
== 0) 
2433                 ifp
->if_lock 
= lck_rw_alloc_init(ifnet_lock_group
, ifnet_lock_attr
); 
2435                 ifp
->if_lock 
= lck_mtx_alloc_init(ifnet_lock_group
, ifnet_lock_attr
); 
2438         if (ifp
->if_lock 
== 0) { 
2443          * Allow interfaces withouth protocol families to attach 
2444          * only if they have the necessary fields filled out. 
2447         if (ifp
->if_add_proto 
== 0 || ifp
->if_del_proto 
== 0) { 
2448                 DLIL_PRINTF("dlil Attempt to attach interface without family module - %ld\n",  
2453         if ((ifp
->if_eflags 
& IFEF_REUSE
) == 0 || ifp
->if_proto_hash 
== NULL
) { 
2454                 MALLOC(new_proto_list
, struct proto_hash_entry
*, sizeof(struct proto_hash_entry
) * PROTO_HASH_SLOTS
, 
2457                 if (new_proto_list 
== 0) { 
2465         TAILQ_INIT(&ifp
->if_flt_head
); 
2468         if (new_proto_list
) { 
2469                 bzero(new_proto_list
, (PROTO_HASH_SLOTS 
* sizeof(struct proto_hash_entry
))); 
2470                 ifp
->if_proto_hash 
= new_proto_list
; 
2471                 new_proto_list 
= NULL
; 
2477                 int namelen
, masklen
, socksize
, ifasize
; 
2478                 struct ifaddr 
*ifa 
= NULL
; 
2480                 if (ifp
->if_snd
.ifq_maxlen 
== 0) 
2481                         ifp
->if_snd
.ifq_maxlen 
= ifqmaxlen
; 
2482                 TAILQ_INIT(&ifp
->if_prefixhead
); 
2483                 LIST_INIT(&ifp
->if_multiaddrs
); 
2484                 ifnet_touch_lastchange(ifp
); 
2486                 /* usecount to track attachment to the ifnet list */ 
2487                 ifp_use(ifp
, kIfNetUseCount_MayBeZero
); 
2489                 /* Lock the list of interfaces */ 
2490                 ifnet_head_lock_exclusive(); 
2491                 ifnet_lock_exclusive(ifp
); 
2493                 if ((ifp
->if_eflags 
& IFEF_REUSE
) == 0 || ifp
->if_index 
== 0) 
2494                         ifp
->if_index 
= if_next_index(); 
2496                         ifa 
= TAILQ_FIRST(&ifp
->if_addrhead
); 
2498                 namelen 
= snprintf(workbuf
, sizeof(workbuf
), "%s%d", ifp
->if_name
, ifp
->if_unit
); 
2499 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m)) 
2500                 masklen 
= _offsetof(struct sockaddr_dl
, sdl_data
[0]) + namelen
; 
2501                 socksize 
= masklen 
+ ifp
->if_addrlen
; 
2502 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) 
2503                 if ((u_long
)socksize 
< sizeof(struct sockaddr_dl
)) 
2504                         socksize 
= sizeof(struct sockaddr_dl
); 
2505                 socksize 
= ROUNDUP(socksize
); 
2506                 ifasize 
= sizeof(struct ifaddr
) + 2 * socksize
; 
2509                  * Allocate a new ifa if we don't have one 
2510                  * or the old one is too small. 
2512                 if (ifa 
== NULL 
|| socksize 
> ifa
->ifa_addr
->sa_len
) { 
2514                                 if_detach_ifa(ifp
, ifa
); 
2515                         ifa 
= (struct ifaddr
*)_MALLOC(ifasize
, M_IFADDR
, M_WAITOK
); 
2519                         struct sockaddr_dl 
*sdl 
= (struct sockaddr_dl 
*)(ifa 
+ 1); 
2520                         ifnet_addrs
[ifp
->if_index 
- 1] = ifa
; 
2521                         bzero(ifa
, ifasize
); 
2522                         sdl
->sdl_len 
= socksize
; 
2523                         sdl
->sdl_family 
= AF_LINK
; 
2524                         bcopy(workbuf
, sdl
->sdl_data
, namelen
); 
2525                         sdl
->sdl_nlen 
= namelen
; 
2526                         sdl
->sdl_index 
= ifp
->if_index
; 
2527                         sdl
->sdl_type 
= ifp
->if_type
; 
2529                                 sdl
->sdl_alen 
= ll_addr
->sdl_alen
; 
2530                                 if (ll_addr
->sdl_alen 
!= ifp
->if_addrlen
) 
2531                                         panic("ifnet_attach - ll_addr->sdl_alen != ifp->if_addrlen"); 
2532                                 bcopy(CONST_LLADDR(ll_addr
), LLADDR(sdl
), sdl
->sdl_alen
); 
2535                         ifa
->ifa_rtrequest 
= link_rtrequest
; 
2536                         ifa
->ifa_addr 
= (struct sockaddr
*)sdl
; 
2537                         sdl 
= (struct sockaddr_dl
*)(socksize 
+ (caddr_t
)sdl
); 
2538                         ifa
->ifa_netmask 
= (struct sockaddr
*)sdl
; 
2539                         sdl
->sdl_len 
= masklen
; 
2540                         while (namelen 
!= 0) 
2541                                 sdl
->sdl_data
[--namelen
] = 0xff; 
2544                 TAILQ_INIT(&ifp
->if_addrhead
); 
2545                 ifa 
= ifnet_addrs
[ifp
->if_index 
- 1]; 
2549                          * We don't use if_attach_ifa because we want 
2550                          * this address to be first on the list. 
2553                         ifa
->ifa_debug 
|= IFA_ATTACHED
; 
2554                         TAILQ_INSERT_HEAD(&ifp
->if_addrhead
, ifa
, ifa_link
); 
2557                 mac_ifnet_label_associate(ifp
); 
2560                 TAILQ_INSERT_TAIL(&ifnet_head
, ifp
, if_link
); 
2561                 ifindex2ifnet
[ifp
->if_index
] = ifp
; 
2567          * A specific dlil input thread is created per Ethernet interface. 
2568          * pseudo interfaces or other types of interfaces use the main ("loopback") thread. 
2569          * If the sysctl "net.link.generic.system.multi_threaded_input" is set to zero, all packets will 
2570          * be handled by the main loopback thread, reverting to 10.4.x behaviour. 
2574         if (ifp
->if_type 
== IFT_ETHER
) { 
2577                 if (dlil_multithreaded_input 
> 0) { 
2578                         ifp
->if_input_thread 
= _MALLOC(sizeof(struct dlil_threading_info
), M_NKE
, M_WAITOK
); 
2579                         if (ifp
->if_input_thread 
== NULL
) 
2580                                 panic("ifnet_attach ifp=%p couldn't alloc threading\n", ifp
); 
2581                         if ((err 
= dlil_create_input_thread(ifp
, ifp
->if_input_thread
)) != 0) 
2582                                 panic("ifnet_attach ifp=%p couldn't get a thread. err=%x\n", ifp
, err
); 
2584                         printf("ifnet_attach: dlil thread for ifp=%p if_index=%x\n", ifp
, ifp
->if_index
); 
2589         ifnet_lock_done(ifp
); 
2591         dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_ATTACHED
, NULL
, 0); 
2600         struct ifnet_filter 
*filter
; 
2601         struct ifnet_filter     
*filter_next
; 
2604         struct ifnet_filter_head fhead
; 
2605         struct dlil_threading_info 
*inputthread
; 
2607         if (ifp 
== NULL
) return EINVAL
; 
2609         ifnet_lock_exclusive(ifp
); 
2611         if ((ifp
->if_eflags 
& IFEF_DETACHING
) != 0) { 
2612                 /* Interface has already been detached */ 
2613                 ifnet_lock_done(ifp
); 
2618          * Indicate this interface is being detached. 
2620          * This should prevent protocols from attaching 
2621          * from this point on. Interface will remain on 
2622          * the list until all of the protocols are detached. 
2624         ifp
->if_eflags 
|= IFEF_DETACHING
; 
2625         ifnet_lock_done(ifp
); 
2627         dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHING
, NULL
, 0); 
2629         /* Let BPF know we're detaching */ 
2632         if ((retval 
= dlil_write_begin()) != 0) { 
2633                 if (retval 
== EDEADLK
) { 
2636                         /* We need to perform a delayed detach */ 
2637                         ifp
->if_delayed_detach 
= 1; 
2638                         dlil_detach_waiting 
= 1; 
2639                         wakeup(&dlil_detach_waiting
); 
2644         /* Steal the list of interface filters */ 
2645         fhead 
= ifp
->if_flt_head
; 
2646         TAILQ_INIT(&ifp
->if_flt_head
); 
2648         /* unuse the interface */ 
2649         zeroed 
= ifp_unuse(ifp
); 
2652          * If thread affinity was set for the workloop thread, we will need 
2653          * to tear down the affinity and release the extra reference count 
2654          * taken at attach time; 
2656         if ((inputthread 
= ifp
->if_input_thread
) != NULL
) { 
2657                 if (inputthread
->net_affinity
) { 
2660                         if (inputthread 
== dlil_lo_thread_ptr
) 
2661                                 panic("Thread affinity should not be enabled " 
2662                                     "on the loopback dlil input thread\n"); 
2664                         lck_mtx_lock(inputthread
->input_lck
); 
2665                         tp 
= inputthread
->workloop_thread
; 
2666                         inputthread
->workloop_thread 
= NULL
; 
2667                         inputthread
->tag 
= 0; 
2668                         inputthread
->net_affinity 
= FALSE
; 
2669                         lck_mtx_unlock(inputthread
->input_lck
); 
2671                         /* Tear down workloop thread affinity */ 
2673                                 (void) dlil_affinity_set(tp
, 
2674                                     THREAD_AFFINITY_TAG_NULL
); 
2675                                 thread_deallocate(tp
); 
2678                         /* Tear down dlil input thread affinity */ 
2679                         tp 
= inputthread
->input_thread
; 
2680                         (void) dlil_affinity_set(tp
, THREAD_AFFINITY_TAG_NULL
); 
2681                         thread_deallocate(tp
); 
2684                 /* cleanup ifp dlil input thread, if any */ 
2685                 ifp
->if_input_thread 
= NULL
; 
2687                 if (inputthread 
!= dlil_lo_thread_ptr
) { 
2689                         printf("ifnet_detach: wakeup thread threadinfo: %p " 
2690                             "input_thread=%p threads: cur=%d max=%d\n", 
2691                             inputthread
, inputthread
->input_thread
, 
2692                             dlil_multithreaded_input
, cur_dlil_input_threads
); 
2694                         lck_mtx_lock(inputthread
->input_lck
); 
2696                         inputthread
->input_waiting 
|= DLIL_INPUT_TERMINATE
; 
2697                         if ((inputthread
->input_waiting 
& DLIL_INPUT_RUNNING
) == 0) { 
2698                                 wakeup((caddr_t
)&inputthread
->input_waiting
); 
2700                         lck_mtx_unlock(inputthread
->input_lck
); 
2705         for (filter 
= TAILQ_FIRST(&fhead
); filter
; filter 
= filter_next
) { 
2706                 filter_next 
= TAILQ_NEXT(filter
, filt_next
); 
2707                 dlil_detach_filter_internal(filter
, 1); 
2711                 ifp_use_reached_zero(ifp
); 
2719         __unused ifnet_t ifnet_ptr
, 
2720         __unused u_int32_t ioctl_code
, 
2721         __unused 
void *ioctl_arg
) 
2727 dlil_recycle_output( 
2728         __unused 
struct ifnet 
*ifnet_ptr
, 
2737         __unused ifnet_t ifnet_ptr
) 
2742 dlil_recycle_set_bpf_tap( 
2743         __unused ifnet_t ifp
, 
2744         __unused bpf_tap_mode mode
, 
2745         __unused bpf_packet_func callback
) 
2747     /* XXX not sure what to do here */ 
2752 int dlil_if_acquire( 
2754         const void *uniqueid
, 
2755         size_t uniqueid_len
,  
2758     struct ifnet        
*ifp1 
= NULL
; 
2759     struct dlil_ifnet   
*dlifp1 
= NULL
; 
2762     lck_mtx_lock(dlil_ifnet_mutex
); 
2763     TAILQ_FOREACH(dlifp1
, &dlil_ifnet_head
, dl_if_link
) { 
2765         ifp1 
= (struct ifnet 
*)dlifp1
; 
2767                 if (ifp1
->if_family 
== family
)  { 
2769             /* same uniqueid and same len or no unique id specified */ 
2770             if ((uniqueid_len 
== dlifp1
->if_uniqueid_len
) 
2771                 && !bcmp(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
)) { 
2773                                 /* check for matching interface in use */ 
2774                                 if (ifp1
->if_eflags 
& IFEF_INUSE
) { 
2782                                                 panic("ifp's lock is gone\n"); 
2783                                         ifnet_lock_exclusive(ifp1
); 
2784                                         ifp1
->if_eflags 
|= (IFEF_INUSE 
| IFEF_REUSE
); 
2785                                         ifnet_lock_done(ifp1
); 
2793     /* no interface found, allocate a new one */ 
2794     MALLOC(dlifp1
, struct dlil_ifnet 
*, sizeof(*dlifp1
), M_NKE
, M_WAITOK
); 
2800     bzero(dlifp1
, sizeof(*dlifp1
)); 
2803         MALLOC(dlifp1
->if_uniqueid
, void *, uniqueid_len
, M_NKE
, M_WAITOK
); 
2804         if (dlifp1
->if_uniqueid 
== 0) { 
2805             FREE(dlifp1
, M_NKE
); 
2809         bcopy(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
); 
2810         dlifp1
->if_uniqueid_len 
= uniqueid_len
; 
2813     ifp1 
= (struct ifnet 
*)dlifp1
; 
2814     ifp1
->if_eflags 
|= IFEF_INUSE
; 
2815     ifp1
->if_name 
= dlifp1
->if_namestorage
; 
2817     mac_ifnet_label_init(ifp1
); 
2820     TAILQ_INSERT_TAIL(&dlil_ifnet_head
, dlifp1
, dl_if_link
); 
2825         lck_mtx_unlock(dlil_ifnet_mutex
); 
2830 __private_extern__ 
void 
2834     struct dlil_ifnet   
*dlifp 
= (struct dlil_ifnet 
*)ifp
; 
2836     /* Interface does not have a lock until it is attached - radar 3713951 */ 
2838                 ifnet_lock_exclusive(ifp
); 
2839     ifp
->if_eflags 
&= ~IFEF_INUSE
; 
2840     ifp
->if_ioctl 
= dlil_recycle_ioctl
; 
2841     ifp
->if_output 
= dlil_recycle_output
; 
2842     ifp
->if_free 
= dlil_recycle_free
; 
2843     ifp
->if_set_bpf_tap 
= dlil_recycle_set_bpf_tap
; 
2845     strncpy(dlifp
->if_namestorage
, ifp
->if_name
, IFNAMSIZ
); 
2846     ifp
->if_name 
= dlifp
->if_namestorage
; 
2849      * We can either recycle the MAC label here or in dlil_if_acquire(). 
2850      * It seems logical to do it here but this means that anything that 
2851      * still has a handle on ifp will now see it as unlabeled. 
2852      * Since the interface is "dead" that may be OK.  Revisit later. 
2854     mac_ifnet_label_recycle(ifp
); 
2857                 ifnet_lock_done(ifp
); 
2861 __private_extern__ 
void 
2862 dlil_proto_unplumb_all(struct ifnet 
*ifp
) 
2865          * if_proto_hash[0-3] are for PF_INET, PF_INET6, PF_APPLETALK 
2866          * and PF_VLAN, where each bucket contains exactly one entry; 
2867          * PF_VLAN does not need an explicit unplumb. 
2869          * if_proto_hash[4] is for other protocols; we expect anything 
2870          * in this bucket to respond to the DETACHING event (which would 
2871          * have happened by now) and do the unplumb then. 
2873         (void) proto_unplumb(PF_INET
, ifp
); 
2875         (void) proto_unplumb(PF_INET6
, ifp
); 
2878         (void) proto_unplumb(PF_APPLETALK
, ifp
);