2 * Copyright (c) 1999-2009 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>
78 #include <net/pfvar.h>
81 #define DBG_LAYER_BEG DLILDBG_CODE(DBG_DLIL_STATIC, 0)
82 #define DBG_LAYER_END DLILDBG_CODE(DBG_DLIL_STATIC, 2)
83 #define DBG_FNC_DLIL_INPUT DLILDBG_CODE(DBG_DLIL_STATIC, (1 << 8))
84 #define DBG_FNC_DLIL_OUTPUT DLILDBG_CODE(DBG_DLIL_STATIC, (2 << 8))
85 #define DBG_FNC_DLIL_IFOUT DLILDBG_CODE(DBG_DLIL_STATIC, (3 << 8))
88 #define MAX_FRAME_TYPE_SIZE 4 /* LONGWORDS */
89 #define MAX_LINKADDR 4 /* LONGWORDS */
90 #define M_NKE M_IFADDR
93 #define DLIL_PRINTF printf
95 #define DLIL_PRINTF kprintf
105 SLIST_ENTRY(if_proto
) next_hash
;
109 struct domain
*dl_domain
;
110 protocol_family_t protocol_family
;
114 proto_media_input input
;
115 proto_media_preout pre_output
;
116 proto_media_event event
;
117 proto_media_ioctl ioctl
;
118 proto_media_detached detached
;
119 proto_media_resolve_multi resolve_multi
;
120 proto_media_send_arp send_arp
;
123 proto_media_input_v2 input
;
124 proto_media_preout pre_output
;
125 proto_media_event event
;
126 proto_media_ioctl ioctl
;
127 proto_media_detached detached
;
128 proto_media_resolve_multi resolve_multi
;
129 proto_media_send_arp send_arp
;
134 SLIST_HEAD(proto_hash_entry
, if_proto
);
138 /* ifnet and drvr_ext are used by the stack and drivers
139 drvr_ext extends the public ifnet and must follow dl_if */
140 struct ifnet dl_if
; /* public ifnet */
142 /* dlil private fields */
143 TAILQ_ENTRY(dlil_ifnet
) dl_if_link
; /* dlil_ifnet are link together */
144 /* it is not the ifnet list */
145 void *if_uniqueid
; /* unique id identifying the interface */
146 size_t if_uniqueid_len
;/* length of the unique id */
147 char if_namestorage
[IFNAMSIZ
]; /* interface name storage */
150 struct ifnet_filter
{
151 TAILQ_ENTRY(ifnet_filter
) filt_next
;
155 const char *filt_name
;
157 protocol_family_t filt_protocol
;
158 iff_input_func filt_input
;
159 iff_output_func filt_output
;
160 iff_event_func filt_event
;
161 iff_ioctl_func filt_ioctl
;
162 iff_detached_func filt_detached
;
165 struct proto_input_entry
;
167 static TAILQ_HEAD(, dlil_ifnet
) dlil_ifnet_head
;
168 static lck_grp_t
*dlil_lock_group
;
169 static lck_grp_t
*ifnet_lock_group
;
170 static lck_grp_t
*ifnet_head_lock_group
;
171 static lck_attr_t
*ifnet_lock_attr
;
172 static lck_rw_t
*ifnet_head_mutex
;
173 static lck_mtx_t
*dlil_ifnet_mutex
;
174 static lck_mtx_t
*dlil_mutex
;
175 static u_int32_t dlil_read_count
= 0;
176 static u_int32_t dlil_detach_waiting
= 0;
177 u_int32_t dlil_filter_count
= 0;
178 extern u_int32_t ipv4_ll_arp_aware
;
180 static struct dlil_threading_info dlil_lo_thread
;
181 __private_extern__
struct dlil_threading_info
*dlil_lo_thread_ptr
= &dlil_lo_thread
;
183 static struct mbuf
*dlil_lo_input_mbuf_head
= NULL
;
184 static struct mbuf
*dlil_lo_input_mbuf_tail
= NULL
;
186 #if IFNET_INPUT_SANITY_CHK
187 static int dlil_lo_input_mbuf_count
= 0;
188 int dlil_input_sanity_check
= 0; /* sanity checking of input packet lists received */
190 int dlil_multithreaded_input
= 1;
191 static int cur_dlil_input_threads
= 0;
193 static int dlil_event_internal(struct ifnet
*ifp
, struct kev_msg
*msg
);
194 static int dlil_detach_filter_internal(interface_filter_t filter
, int detached
);
195 static void dlil_call_delayed_detach_thread(void);
197 static void dlil_read_begin(void);
198 static __inline__
void dlil_read_end(void);
199 static int dlil_write_begin(void);
200 static void dlil_write_end(void);
203 __private_extern__
int dlil_verbose
= 1;
205 __private_extern__
int dlil_verbose
= 0;
208 unsigned int net_affinity
= 1;
209 static kern_return_t
dlil_affinity_set(struct thread
*, u_int32_t
);
211 extern void bpfdetach(struct ifnet
*);
212 extern void proto_input_run(void); // new run_netisr
214 void dlil_input_packet_list(struct ifnet
*ifp
, struct mbuf
*m
);
215 static void dlil_input_thread_func(struct dlil_threading_info
*inpthread
);
216 __private_extern__
int dlil_create_input_thread(
217 ifnet_t
, struct dlil_threading_info
*);
218 __private_extern__
void dlil_terminate_input_thread(
219 struct dlil_threading_info
*);
221 __private_extern__
void link_rtrequest(int, struct rtentry
*, struct sockaddr
*);
225 extern u_int32_t inject_buckets
;
227 static const u_int32_t dlil_writer_waiting
= 0x80000000;
228 static lck_grp_attr_t
*dlil_grp_attributes
= NULL
;
229 static lck_attr_t
*dlil_lck_attributes
= NULL
;
230 static lck_grp_t
*dlil_input_lock_grp
= NULL
;
233 _cast_non_const(const void * ptr
) {
243 /* Should these be inline? */
245 dlil_read_begin(void)
249 struct uthread
*uth
= get_bsdthread_info(current_thread());
251 if (uth
->dlil_incremented_read
== dlil_writer_waiting
)
252 panic("dlil_read_begin - thread is already a writer");
256 old_value
= dlil_read_count
;
258 if ((old_value
& dlil_writer_waiting
) != 0 && uth
->dlil_incremented_read
== 0)
260 tsleep(&dlil_read_count
, PRIBIO
, "dlil_read_count", 1);
264 new_value
= old_value
+ 1;
265 } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)new_value
, (UInt32
*)&dlil_read_count
));
267 uth
->dlil_incremented_read
++;
273 struct uthread
*uth
= get_bsdthread_info(current_thread());
275 OSDecrementAtomic(&dlil_read_count
);
276 uth
->dlil_incremented_read
--;
277 if (dlil_read_count
== dlil_writer_waiting
)
278 wakeup(_cast_non_const(&dlil_writer_waiting
));
282 dlil_write_begin(void)
284 struct uthread
*uth
= get_bsdthread_info(current_thread());
286 if (uth
->dlil_incremented_read
!= 0) {
289 lck_mtx_lock(dlil_mutex
);
290 OSBitOrAtomic((UInt32
)dlil_writer_waiting
, &dlil_read_count
);
292 if (dlil_read_count
== dlil_writer_waiting
) {
293 uth
->dlil_incremented_read
= dlil_writer_waiting
;
297 tsleep(_cast_non_const(&dlil_writer_waiting
), PRIBIO
, "dlil_writer_waiting", 1);
305 struct uthread
*uth
= get_bsdthread_info(current_thread());
307 if (uth
->dlil_incremented_read
!= dlil_writer_waiting
)
308 panic("dlil_write_end - thread is not a writer");
309 OSBitAndAtomic((UInt32
)~dlil_writer_waiting
, &dlil_read_count
);
310 lck_mtx_unlock(dlil_mutex
);
311 uth
->dlil_incremented_read
= 0;
312 wakeup(&dlil_read_count
);
315 #define PROTO_HASH_SLOTS 0x5
318 * Internal functions.
322 proto_hash_value(u_int32_t protocol_family
)
325 * dlil_proto_unplumb_all() depends on the mapping between
326 * the hash bucket index and the protocol family defined
327 * here; future changes must be applied there as well.
329 switch(protocol_family
) {
343 static struct if_proto
*
344 find_attached_proto(struct ifnet
*ifp
, u_int32_t protocol_family
)
346 struct if_proto
*proto
= NULL
;
347 u_int32_t i
= proto_hash_value(protocol_family
);
348 if (ifp
->if_proto_hash
) {
349 proto
= SLIST_FIRST(&ifp
->if_proto_hash
[i
]);
352 while(proto
&& proto
->protocol_family
!= protocol_family
) {
353 proto
= SLIST_NEXT(proto
, next_hash
);
360 if_proto_ref(struct if_proto
*proto
)
362 OSAddAtomic(1, &proto
->refcount
);
366 if_proto_free(struct if_proto
*proto
)
368 int oldval
= OSAddAtomic(-1, &proto
->refcount
);
370 if (oldval
== 1) { /* This was the last reference */
371 FREE(proto
, M_IFADDR
);
375 __private_extern__
void
377 __unused
struct ifnet
*ifp
,
382 * Not implemented for rw locks.
384 * Function exists so when/if we use mutex we can
388 lck_mtx_assert(ifp
->if_lock
, what
);
392 __private_extern__
void
397 lck_rw_lock_shared(ifp
->if_lock
);
399 lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_NOTOWNED
);
400 lck_mtx_lock(ifp
->if_lock
);
404 __private_extern__
void
405 ifnet_lock_exclusive(
409 lck_rw_lock_exclusive(ifp
->if_lock
);
411 lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_NOTOWNED
);
412 lck_mtx_lock(ifp
->if_lock
);
416 __private_extern__
void
421 lck_rw_done(ifp
->if_lock
);
423 lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_OWNED
);
424 lck_mtx_unlock(ifp
->if_lock
);
428 __private_extern__
void
429 ifnet_head_lock_shared(void)
431 lck_rw_lock_shared(ifnet_head_mutex
);
434 __private_extern__
void
435 ifnet_head_lock_exclusive(void)
437 lck_rw_lock_exclusive(ifnet_head_mutex
);
440 __private_extern__
void
441 ifnet_head_done(void)
443 lck_rw_done(ifnet_head_mutex
);
446 static int dlil_ifp_proto_count(struct ifnet
* ifp
)
451 if (ifp
->if_proto_hash
!= NULL
) {
452 for (i
= 0; i
< PROTO_HASH_SLOTS
; i
++) {
453 struct if_proto
*proto
;
454 SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) {
463 __private_extern__
void
464 dlil_post_msg(struct ifnet
*ifp
, u_int32_t event_subclass
, u_int32_t event_code
,
465 struct net_event_data
*event_data
, u_int32_t event_data_len
)
467 struct net_event_data ev_data
;
468 struct kev_msg ev_msg
;
471 * a net event always starts with a net_event_data structure
472 * but the caller can generate a simple net event or
473 * provide a longer event structure to post
476 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
477 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
478 ev_msg
.kev_subclass
= event_subclass
;
479 ev_msg
.event_code
= event_code
;
481 if (event_data
== 0) {
482 event_data
= &ev_data
;
483 event_data_len
= sizeof(struct net_event_data
);
486 strncpy(&event_data
->if_name
[0], ifp
->if_name
, IFNAMSIZ
);
487 event_data
->if_family
= ifp
->if_family
;
488 event_data
->if_unit
= (u_int32_t
) ifp
->if_unit
;
490 ev_msg
.dv
[0].data_length
= event_data_len
;
491 ev_msg
.dv
[0].data_ptr
= event_data
;
492 ev_msg
.dv
[1].data_length
= 0;
494 dlil_event_internal(ifp
, &ev_msg
);
497 __private_extern__
int
498 dlil_create_input_thread(
499 ifnet_t ifp
, struct dlil_threading_info
*inputthread
)
503 bzero(inputthread
, sizeof(*inputthread
));
504 // loopback ifp may not be configured at dlil_init time.
506 strlcat(inputthread
->input_name
, "dlil_input_main_thread_mtx", 32);
508 snprintf(inputthread
->input_name
, 32, "dlil_input_%s%d_mtx", ifp
->if_name
, ifp
->if_unit
);
510 inputthread
->lck_grp
= lck_grp_alloc_init(inputthread
->input_name
, dlil_grp_attributes
);
511 inputthread
->input_lck
= lck_mtx_alloc_init(inputthread
->lck_grp
, dlil_lck_attributes
);
513 error
= kernel_thread_start((thread_continue_t
)dlil_input_thread_func
, inputthread
, &inputthread
->input_thread
);
515 ml_thread_policy(inputthread
->input_thread
, MACHINE_GROUP
,
516 (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
));
518 * Except for the loopback dlil input thread, we create
519 * an affinity set so that the matching workloop thread
520 * can be scheduled on the same processor set.
522 if (net_affinity
&& inputthread
!= dlil_lo_thread_ptr
) {
523 struct thread
*tp
= inputthread
->input_thread
;
526 * Randomize to reduce the probability
527 * of affinity tag namespace collision.
529 read_random(&tag
, sizeof (tag
));
530 if (dlil_affinity_set(tp
, tag
) == KERN_SUCCESS
) {
531 thread_reference(tp
);
532 inputthread
->tag
= tag
;
533 inputthread
->net_affinity
= TRUE
;
537 panic("dlil_create_input_thread: couldn't create thread\n");
539 OSAddAtomic(1, &cur_dlil_input_threads
);
541 printf("dlil_create_input_thread: threadinfo: %p input_thread=%p threads: cur=%d max=%d\n",
542 inputthread
, inputthread
->input_thread
, dlil_multithreaded_input
, cur_dlil_input_threads
);
546 __private_extern__
void
547 dlil_terminate_input_thread(
548 struct dlil_threading_info
*inputthread
)
550 OSAddAtomic(-1, &cur_dlil_input_threads
);
552 lck_mtx_unlock(inputthread
->input_lck
);
553 lck_mtx_free(inputthread
->input_lck
, inputthread
->lck_grp
);
554 lck_grp_free(inputthread
->lck_grp
);
556 FREE(inputthread
, M_NKE
);
558 /* For the extra reference count from kernel_thread_start() */
559 thread_deallocate(current_thread());
561 thread_terminate(current_thread());
565 dlil_affinity_set(struct thread
*tp
, u_int32_t tag
)
567 thread_affinity_policy_data_t policy
;
569 bzero(&policy
, sizeof (policy
));
570 policy
.affinity_tag
= tag
;
571 return (thread_policy_set(tp
, THREAD_AFFINITY_POLICY
,
572 (thread_policy_t
)&policy
, THREAD_AFFINITY_POLICY_COUNT
));
578 thread_t thread
= THREAD_NULL
;
580 PE_parse_boot_argn("net_affinity", &net_affinity
, sizeof (net_affinity
));
582 TAILQ_INIT(&dlil_ifnet_head
);
583 TAILQ_INIT(&ifnet_head
);
585 /* Setup the lock groups we will use */
586 dlil_grp_attributes
= lck_grp_attr_alloc_init();
588 dlil_lock_group
= lck_grp_alloc_init("dlil internal locks", dlil_grp_attributes
);
589 ifnet_lock_group
= lck_grp_alloc_init("ifnet locks", dlil_grp_attributes
);
590 ifnet_head_lock_group
= lck_grp_alloc_init("ifnet head lock", dlil_grp_attributes
);
591 dlil_input_lock_grp
= lck_grp_alloc_init("dlil input lock", dlil_grp_attributes
);
593 /* Setup the lock attributes we will use */
594 dlil_lck_attributes
= lck_attr_alloc_init();
596 ifnet_lock_attr
= lck_attr_alloc_init();
599 ifnet_head_mutex
= lck_rw_alloc_init(ifnet_head_lock_group
, dlil_lck_attributes
);
600 dlil_ifnet_mutex
= lck_mtx_alloc_init(dlil_lock_group
, dlil_lck_attributes
);
601 dlil_mutex
= lck_mtx_alloc_init(dlil_lock_group
, dlil_lck_attributes
);
603 lck_attr_free(dlil_lck_attributes
);
604 dlil_lck_attributes
= NULL
;
607 * Create and start up the first dlil input thread once everything is initialized
609 dlil_create_input_thread(0, dlil_lo_thread_ptr
);
611 (void) kernel_thread_start((thread_continue_t
)dlil_call_delayed_detach_thread
, NULL
, &thread
);
612 thread_deallocate(thread
);
614 /* Initialize the packet filter */
619 __private_extern__
int
622 const struct iff_filter
*if_filter
,
623 interface_filter_t
*filter_ref
)
626 struct ifnet_filter
*filter
;
628 MALLOC(filter
, struct ifnet_filter
*, sizeof(*filter
), M_NKE
, M_WAITOK
);
631 bzero(filter
, sizeof(*filter
));
634 filter
->filt_ifp
= ifp
;
635 filter
->filt_cookie
= if_filter
->iff_cookie
;
636 filter
->filt_name
= if_filter
->iff_name
;
637 filter
->filt_protocol
= if_filter
->iff_protocol
;
638 filter
->filt_input
= if_filter
->iff_input
;
639 filter
->filt_output
= if_filter
->iff_output
;
640 filter
->filt_event
= if_filter
->iff_event
;
641 filter
->filt_ioctl
= if_filter
->iff_ioctl
;
642 filter
->filt_detached
= if_filter
->iff_detached
;
644 if ((retval
= dlil_write_begin()) != 0) {
645 /* Failed to acquire the write lock */
649 TAILQ_INSERT_TAIL(&ifp
->if_flt_head
, filter
, filt_next
);
651 *filter_ref
= filter
;
654 * Bump filter count and route_generation ID to let TCP
655 * know it shouldn't do TSO on this connection
657 OSAddAtomic(1, &dlil_filter_count
);
665 dlil_detach_filter_internal(
666 interface_filter_t filter
,
673 interface_filter_t entry
= NULL
;
675 /* Take the write lock */
676 retval
= dlil_write_begin();
677 if (retval
!= 0 && retval
!= EDEADLK
)
681 * At this point either we have the write lock (retval == 0)
682 * or we couldn't get it (retval == EDEADLK) because someone
683 * else up the stack is holding the read lock. It is safe to
684 * read, either the read or write is held. Verify the filter
685 * parameter before proceeding.
687 ifnet_head_lock_shared();
688 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
689 TAILQ_FOREACH(entry
, &ifp
->if_flt_head
, filt_next
) {
698 if (entry
!= filter
) {
699 /* filter parameter is not a valid filter ref */
706 if (retval
== EDEADLK
) {
707 /* Perform a delayed detach */
708 filter
->filt_detaching
= 1;
709 dlil_detach_waiting
= 1;
710 wakeup(&dlil_detach_waiting
);
714 /* Remove the filter from the list */
715 TAILQ_REMOVE(&ifp
->if_flt_head
, filter
, filt_next
);
719 /* Call the detached funciton if there is one */
720 if (filter
->filt_detached
)
721 filter
->filt_detached(filter
->filt_cookie
, filter
->filt_ifp
);
723 /* Free the filter */
727 * Decrease filter count and route_generation ID to let TCP
728 * know it should reevalute doing TSO or not
730 OSAddAtomic(-1, &dlil_filter_count
);
737 __private_extern__
void
738 dlil_detach_filter(interface_filter_t filter
)
742 dlil_detach_filter_internal(filter
, 0);
746 dlil_input_thread_func(
747 struct dlil_threading_info
*inputthread
)
750 struct mbuf
*m
= NULL
, *m_loop
= NULL
;
751 #if IFNET_INPUT_SANITY_CHK
752 int loop_cnt
= 0, mbuf_cnt
;
755 #endif /* IFNET_INPUT_SANITY_CHK */
757 lck_mtx_lock(inputthread
->input_lck
);
759 /* Wait until there is work to be done */
760 while ((inputthread
->input_waiting
& ~DLIL_INPUT_RUNNING
) == 0) {
761 inputthread
->input_waiting
&= ~DLIL_INPUT_RUNNING
;
762 msleep(&inputthread
->input_waiting
, inputthread
->input_lck
, 0, inputthread
->input_name
, 0);
766 lck_mtx_assert(inputthread
->input_lck
, LCK_MTX_ASSERT_OWNED
);
768 m
= inputthread
->mbuf_head
;
769 inputthread
->mbuf_head
= NULL
;
770 inputthread
->mbuf_tail
= NULL
;
772 if (inputthread
->input_waiting
& DLIL_INPUT_TERMINATE
) {
775 /* this is the end */
776 dlil_terminate_input_thread(inputthread
);
780 inputthread
->input_waiting
|= DLIL_INPUT_RUNNING
;
781 inputthread
->input_waiting
&= ~DLIL_INPUT_WAITING
;
783 if (inputthread
== dlil_lo_thread_ptr
) {
784 m_loop
= dlil_lo_input_mbuf_head
;
785 dlil_lo_input_mbuf_head
= NULL
;
786 dlil_lo_input_mbuf_tail
= NULL
;
789 #if IFNET_INPUT_SANITY_CHK
790 if (dlil_input_sanity_check
!= 0) {
791 mbuf_cnt
= inputthread
->mbuf_count
;
792 inputthread
->mbuf_count
= 0;
793 if (inputthread
== dlil_lo_thread_ptr
) {
794 loop_cnt
= dlil_lo_input_mbuf_count
;
795 dlil_lo_input_mbuf_count
= 0;
798 lck_mtx_unlock(inputthread
->input_lck
);
800 for (m1
= m
, count
= 0; m1
; m1
= mbuf_nextpkt(m1
)) {
803 if (count
!= mbuf_cnt
) {
804 panic("dlil_input_func - thread=%p reg. loop queue has %d packets, should have %d\n",
805 inputthread
, count
, mbuf_cnt
);
808 if (inputthread
== dlil_lo_thread_ptr
) {
809 for (m1
= m_loop
, count
= 0; m1
; m1
= mbuf_nextpkt(m1
)) {
812 if (count
!= loop_cnt
) {
813 panic("dlil_input_func - thread=%p loop queue has %d packets, should have %d\n",
814 inputthread
, count
, loop_cnt
);
818 #endif /* IFNET_INPUT_SANITY_CHK */
820 lck_mtx_unlock(inputthread
->input_lck
);
825 * NOTE warning %%% attention !!!!
826 * We should think about putting some thread starvation safeguards if
827 * we deal with long chains of packets.
830 if (inputthread
== dlil_lo_thread_ptr
)
831 dlil_input_packet_list(lo_ifp
, m_loop
);
832 #if IFNET_INPUT_SANITY_CHK
834 panic("dlil_input_func - thread=%p loop queue has %d packets, should have none!\n",
835 inputthread
, loop_cnt
);
836 #endif /* IFNET_INPUT_SANITY_CHK */
841 dlil_input_packet_list(0, m
);
844 lck_mtx_lock(inputthread
->input_lck
);
846 if ((inputthread
->input_waiting
& (DLIL_PROTO_WAITING
| DLIL_PROTO_REGISTER
)) != 0) {
847 lck_mtx_unlock(inputthread
->input_lck
);
851 lck_mtx_unlock(inputthread
->input_lck
);
859 const struct ifnet_stat_increment_param
*stats
)
861 struct thread
*tp
= current_thread();
863 struct dlil_threading_info
*inp
;
864 #if IFNET_INPUT_SANITY_CHK
865 u_int32_t pkt_count
= 0;
866 #endif /* IFNET_INPUT_SANITY_CHK */
868 if (ifp
== NULL
|| m_head
== NULL
) {
870 mbuf_freem_list(m_head
);
876 #if IFNET_INPUT_SANITY_CHK
877 if (dlil_input_sanity_check
!= 0) {
880 rcvif
= mbuf_pkthdr_rcvif(m_tail
);
884 (ifp
->if_type
!= IFT_LOOP
&& rcvif
!= ifp
) ||
885 (mbuf_flags(m_head
) & MBUF_PKTHDR
) == 0) {
886 panic("ifnet_input - invalid mbuf %p\n", m_tail
);
889 #endif /* IFNET_INPUT_SANITY_CHK */
890 if (mbuf_nextpkt(m_tail
) == NULL
)
892 m_tail
= mbuf_nextpkt(m_tail
);
895 inp
= ifp
->if_input_thread
;
897 if (dlil_multithreaded_input
== 0 || inp
== NULL
)
898 inp
= dlil_lo_thread_ptr
;
901 * If there is a matching dlil input thread associated with an
902 * affinity set, associate this workloop thread with the same set.
903 * We will only do this once.
905 lck_mtx_lock(inp
->input_lck
);
906 if (inp
->net_affinity
&& inp
->workloop_thread
== NULL
) {
907 u_int32_t tag
= inp
->tag
;
908 inp
->workloop_thread
= tp
;
909 lck_mtx_unlock(inp
->input_lck
);
911 /* Associated the current thread with the new affinity tag */
912 (void) dlil_affinity_set(tp
, tag
);
915 * Take a reference on the workloop (current) thread; during
916 * detach, we will need to refer to it in order ot tear down
919 thread_reference(tp
);
920 lck_mtx_lock(inp
->input_lck
);
924 * Because of loopbacked multicast we cannot stuff the ifp in
925 * the rcvif of the packet header: loopback has its own dlil
929 if (inp
== dlil_lo_thread_ptr
&& ifp
->if_type
== IFT_LOOP
) {
930 if (dlil_lo_input_mbuf_head
== NULL
)
931 dlil_lo_input_mbuf_head
= m_head
;
932 else if (dlil_lo_input_mbuf_tail
!= NULL
)
933 dlil_lo_input_mbuf_tail
->m_nextpkt
= m_head
;
934 dlil_lo_input_mbuf_tail
= m_tail
;
935 #if IFNET_INPUT_SANITY_CHK
936 if (dlil_input_sanity_check
!= 0) {
937 dlil_lo_input_mbuf_count
+= pkt_count
;
938 inp
->input_mbuf_cnt
+= pkt_count
;
939 inp
->input_wake_cnt
++;
941 lck_mtx_assert(inp
->input_lck
, LCK_MTX_ASSERT_OWNED
);
946 if (inp
->mbuf_head
== NULL
)
947 inp
->mbuf_head
= m_head
;
948 else if (inp
->mbuf_tail
!= NULL
)
949 inp
->mbuf_tail
->m_nextpkt
= m_head
;
950 inp
->mbuf_tail
= m_tail
;
951 #if IFNET_INPUT_SANITY_CHK
952 if (dlil_input_sanity_check
!= 0) {
953 inp
->mbuf_count
+= pkt_count
;
954 inp
->input_mbuf_cnt
+= pkt_count
;
955 inp
->input_wake_cnt
++;
957 lck_mtx_assert(inp
->input_lck
, LCK_MTX_ASSERT_OWNED
);
963 inp
->input_waiting
|= DLIL_INPUT_WAITING
;
964 if ((inp
->input_waiting
& DLIL_INPUT_RUNNING
) == 0) {
965 wakeup((caddr_t
)&inp
->input_waiting
);
968 ifp
->if_data
.ifi_ipackets
+= stats
->packets_in
;
969 ifp
->if_data
.ifi_ibytes
+= stats
->bytes_in
;
970 ifp
->if_data
.ifi_ierrors
+= stats
->errors_in
;
972 ifp
->if_data
.ifi_opackets
+= stats
->packets_out
;
973 ifp
->if_data
.ifi_obytes
+= stats
->bytes_out
;
974 ifp
->if_data
.ifi_oerrors
+= stats
->errors_out
;
976 ifp
->if_data
.ifi_collisions
+= stats
->collisions
;
977 ifp
->if_data
.ifi_iqdrops
+= stats
->dropped
;
980 lck_mtx_unlock(inp
->input_lck
);
986 dlil_interface_filters_input(struct ifnet
* ifp
, struct mbuf
* * m_p
,
987 char * * frame_header_p
,
988 protocol_family_t protocol_family
)
990 struct ifnet_filter
* filter
;
992 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
995 if (filter
->filt_input
996 && (filter
->filt_protocol
== 0
997 || filter
->filt_protocol
== protocol_family
)) {
998 result
= (*filter
->filt_input
)(filter
->filt_cookie
,
999 ifp
, protocol_family
,
1000 m_p
, frame_header_p
);
1008 * Strip away M_PROTO1 bit prior to sending packet up the stack as
1009 * it is meant to be local to a subsystem -- if_bridge for M_PROTO1
1012 (*m_p
)->m_flags
&= ~M_PROTO1
;
1018 dlil_ifproto_input(struct if_proto
* ifproto
, mbuf_t m
)
1022 if (ifproto
->proto_kpi
== kProtoKPI_v1
) {
1023 /* Version 1 protocols get one packet at a time */
1025 char * frame_header
;
1028 next_packet
= m
->m_nextpkt
;
1029 m
->m_nextpkt
= NULL
;
1030 frame_header
= m
->m_pkthdr
.header
;
1031 m
->m_pkthdr
.header
= NULL
;
1032 error
= (*ifproto
->kpi
.v1
.input
)(ifproto
->ifp
,
1033 ifproto
->protocol_family
,
1035 if (error
!= 0 && error
!= EJUSTRETURN
)
1040 else if (ifproto
->proto_kpi
== kProtoKPI_v2
) {
1041 /* Version 2 protocols support packet lists */
1042 error
= (*ifproto
->kpi
.v2
.input
)(ifproto
->ifp
,
1043 ifproto
->protocol_family
,
1045 if (error
!= 0 && error
!= EJUSTRETURN
)
1051 __private_extern__
void
1052 dlil_input_packet_list(struct ifnet
* ifp_param
, struct mbuf
*m
)
1056 protocol_family_t protocol_family
;
1058 ifnet_t ifp
= ifp_param
;
1059 char * frame_header
;
1060 struct if_proto
* last_ifproto
= NULL
;
1061 mbuf_t pkt_first
= NULL
;
1062 mbuf_t
* pkt_next
= NULL
;
1064 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT
| DBG_FUNC_START
,0,0,0,0,0);
1067 struct if_proto
* ifproto
= NULL
;
1069 next_packet
= m
->m_nextpkt
;
1070 m
->m_nextpkt
= NULL
;
1071 if (ifp_param
== NULL
)
1072 ifp
= m
->m_pkthdr
.rcvif
;
1073 frame_header
= m
->m_pkthdr
.header
;
1074 m
->m_pkthdr
.header
= NULL
;
1077 /* dlil lock protects the demux and interface filters */
1081 /* find which protocol family this packet is for */
1082 error
= (*ifp
->if_demux
)(ifp
, m
, frame_header
,
1085 if (error
== EJUSTRETURN
) {
1088 protocol_family
= 0;
1092 if (m
->m_flags
& (M_BCAST
|M_MCAST
))
1095 /* run interface filters, exclude VLAN packets PR-3586856 */
1096 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1099 filter_result
= dlil_interface_filters_input(ifp
, &m
,
1102 if (filter_result
!= 0) {
1103 if (filter_result
!= EJUSTRETURN
) {
1109 if (error
!= 0 || ((m
->m_flags
& M_PROMISC
) != 0) ) {
1114 /* Lookup the protocol attachment to this interface */
1115 if (protocol_family
== 0) {
1118 else if (last_ifproto
!= NULL
1119 && last_ifproto
->ifp
== ifp
1120 && (last_ifproto
->protocol_family
1121 == protocol_family
)) {
1122 ifproto
= last_ifproto
;
1125 ifproto
= find_attached_proto(ifp
, protocol_family
);
1127 if (ifproto
== NULL
) {
1128 /* no protocol for this packet, discard */
1132 if (ifproto
!= last_ifproto
) {
1133 /* make sure ifproto can't go away during input */
1134 if_proto_ref(ifproto
);
1135 if (last_ifproto
!= NULL
) {
1136 /* pass up the list for the previous protocol */
1139 dlil_ifproto_input(last_ifproto
, pkt_first
);
1141 if_proto_free(last_ifproto
);
1144 last_ifproto
= ifproto
;
1146 /* extend the list */
1147 m
->m_pkthdr
.header
= frame_header
;
1148 if (pkt_first
== NULL
) {
1153 pkt_next
= &m
->m_nextpkt
;
1156 if (next_packet
== NULL
&& last_ifproto
!= NULL
) {
1157 /* pass up the last list of packets */
1160 dlil_ifproto_input(last_ifproto
, pkt_first
);
1161 if_proto_free(last_ifproto
);
1170 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT
| DBG_FUNC_END
,0,0,0,0,0);
1175 dlil_event_internal(struct ifnet
*ifp
, struct kev_msg
*event
)
1177 struct ifnet_filter
*filter
;
1179 if (ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
) == 0) {
1182 /* Pass the event to the interface filters */
1183 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1184 if (filter
->filt_event
)
1185 filter
->filt_event(filter
->filt_cookie
, ifp
, filter
->filt_protocol
, event
);
1188 if (ifp
->if_proto_hash
) {
1191 for (i
= 0; i
< PROTO_HASH_SLOTS
; i
++) {
1192 struct if_proto
*proto
;
1194 SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) {
1195 proto_media_event eventp
= proto
->proto_kpi
== kProtoKPI_v1
1196 ? proto
->kpi
.v1
.event
: proto
->kpi
.v2
.event
;
1199 eventp(ifp
, proto
->protocol_family
, event
);
1206 /* Pass the event to the interface */
1208 ifp
->if_event(ifp
, event
);
1211 ifp_use_reached_zero(ifp
);
1214 return kev_post_msg(event
);
1220 struct kern_event_msg
*event
)
1222 struct kev_msg kev_msg
;
1225 if (ifp
== NULL
|| event
== NULL
) return EINVAL
;
1227 kev_msg
.vendor_code
= event
->vendor_code
;
1228 kev_msg
.kev_class
= event
->kev_class
;
1229 kev_msg
.kev_subclass
= event
->kev_subclass
;
1230 kev_msg
.event_code
= event
->event_code
;
1231 kev_msg
.dv
[0].data_ptr
= &event
->event_data
[0];
1232 kev_msg
.dv
[0].data_length
= event
->total_size
- KEV_MSG_HEADER_SIZE
;
1233 kev_msg
.dv
[1].data_length
= 0;
1235 result
= dlil_event_internal(ifp
, &kev_msg
);
1241 #include <netinet/ip6.h>
1242 #include <netinet/ip.h>
1243 static int dlil_get_socket_type(struct mbuf
**mp
, int family
, int raw
)
1247 struct ip6_hdr
*ip6
;
1248 int type
= SOCK_RAW
;
1253 m
= m_pullup(*mp
, sizeof(struct ip
));
1257 ip
= mtod(m
, struct ip
*);
1258 if (ip
->ip_p
== IPPROTO_TCP
)
1260 else if (ip
->ip_p
== IPPROTO_UDP
)
1264 m
= m_pullup(*mp
, sizeof(struct ip6_hdr
));
1268 ip6
= mtod(m
, struct ip6_hdr
*);
1269 if (ip6
->ip6_nxt
== IPPROTO_TCP
)
1271 else if (ip6
->ip6_nxt
== IPPROTO_UDP
)
1285 u_long proto_family
,
1286 struct mbuf
*packetlist
,
1288 const struct sockaddr
*dest
,
1291 char *frame_type
= NULL
;
1292 char *dst_linkaddr
= NULL
;
1294 char frame_type_buffer
[MAX_FRAME_TYPE_SIZE
* 4];
1295 char dst_linkaddr_buffer
[MAX_LINKADDR
* 4];
1296 struct ifnet_filter
*filter
;
1297 struct if_proto
*proto
= 0;
1299 mbuf_t send_head
= NULL
;
1300 mbuf_t
*send_tail
= &send_head
;
1302 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_START
,0,0,0,0,0);
1306 frame_type
= frame_type_buffer
;
1307 dst_linkaddr
= dst_linkaddr_buffer
;
1310 proto
= find_attached_proto(ifp
, proto_family
);
1311 if (proto
== NULL
) {
1318 if (packetlist
== NULL
)
1321 packetlist
= packetlist
->m_nextpkt
;
1322 m
->m_nextpkt
= NULL
;
1325 proto_media_preout preoutp
= proto
->proto_kpi
== kProtoKPI_v1
1326 ? proto
->kpi
.v1
.pre_output
: proto
->kpi
.v2
.pre_output
;
1329 retval
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
);
1332 if (retval
== EJUSTRETURN
) {
1343 retval
= mac_ifnet_check_transmit(ifp
, m
, proto_family
,
1344 dlil_get_socket_type(&m
, proto_family
, raw
));
1351 if (raw
== 0 && ifp
->if_framer
) {
1352 retval
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);
1354 if (retval
!= EJUSTRETURN
) {
1362 * Let interface filters (if any) do their thing ...
1364 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1365 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1366 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1367 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_family
)) &&
1368 filter
->filt_output
) {
1369 retval
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
);
1371 if (retval
!= EJUSTRETURN
)
1379 * Strip away M_PROTO1 bit prior to sending packet to the driver
1380 * as this field may be used by the driver
1382 m
->m_flags
&= ~M_PROTO1
;
1385 * Finally, call the driver.
1388 if ((ifp
->if_eflags
& IFEF_SENDLIST
) != 0) {
1390 send_tail
= &m
->m_nextpkt
;
1393 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1394 retval
= ifp
->if_output(ifp
, m
);
1395 if (retval
&& dlil_verbose
) {
1396 printf("dlil_output: output error on %s%d retval = %d\n",
1397 ifp
->if_name
, ifp
->if_unit
, retval
);
1399 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1401 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1406 packetlist
= packetlist
->m_nextpkt
;
1407 m
->m_nextpkt
= NULL
;
1412 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1413 retval
= ifp
->if_output(ifp
, send_head
);
1414 if (retval
&& dlil_verbose
) {
1415 printf("dlil_output: output error on %s%d retval = %d\n",
1416 ifp
->if_name
, ifp
->if_unit
, retval
);
1418 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1421 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_END
,0,0,0,0,0);
1425 if (packetlist
) /* if any packet left, clean up */
1426 mbuf_freem_list(packetlist
);
1427 if (retval
== EJUSTRETURN
)
1436 * Caller should have a lock on the protocol domain if the protocol
1437 * doesn't support finer grained locking. In most cases, the lock
1438 * will be held from the socket layer and won't be released until
1439 * we return back to the socket layer.
1441 * This does mean that we must take a protocol lock before we take
1442 * an interface lock if we're going to take both. This makes sense
1443 * because a protocol is likely to interact with an ifp while it
1444 * is under the protocol lock.
1446 __private_extern__ errno_t
1449 protocol_family_t proto_family
,
1452 const struct sockaddr
*dest
,
1455 char *frame_type
= NULL
;
1456 char *dst_linkaddr
= NULL
;
1458 char frame_type_buffer
[MAX_FRAME_TYPE_SIZE
* 4];
1459 char dst_linkaddr_buffer
[MAX_LINKADDR
* 4];
1460 struct ifnet_filter
*filter
;
1461 struct if_proto
*proto
= 0;
1463 mbuf_t send_head
= NULL
;
1464 mbuf_t
*send_tail
= &send_head
;
1466 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_START
,0,0,0,0,0);
1470 frame_type
= frame_type_buffer
;
1471 dst_linkaddr
= dst_linkaddr_buffer
;
1474 proto
= find_attached_proto(ifp
, proto_family
);
1475 if (proto
== NULL
) {
1482 if (packetlist
== NULL
)
1485 packetlist
= packetlist
->m_nextpkt
;
1486 m
->m_nextpkt
= NULL
;
1489 proto_media_preout preoutp
= proto
->proto_kpi
== kProtoKPI_v1
1490 ? proto
->kpi
.v1
.pre_output
: proto
->kpi
.v2
.pre_output
;
1493 retval
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
);
1496 if (retval
== EJUSTRETURN
) {
1506 retval
= mac_ifnet_check_transmit(ifp
, m
, proto_family
,
1507 dlil_get_socket_type(&m
, proto_family
, raw
));
1515 if (raw
== 0 && ifp
->if_framer
) {
1519 * If this is a broadcast packet that needs to be
1520 * looped back into the system, set the inbound ifp
1521 * to that of the outbound ifp. This will allow
1522 * us to determine that it is a legitimate packet
1523 * for the system. Only set the ifp if it's not
1524 * already set, just to be safe.
1526 if ((m
->m_flags
& (M_BCAST
| M_LOOP
)) &&
1527 m
->m_pkthdr
.rcvif
== NULL
) {
1528 m
->m_pkthdr
.rcvif
= ifp
;
1532 retval
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);
1534 if (retval
!= EJUSTRETURN
) {
1541 * Clear the ifp if it was set above, and to be
1542 * safe, only if it is still the same as the
1543 * outbound ifp we have in context. If it was
1544 * looped back, then a copy of it was sent to the
1545 * loopback interface with the rcvif set, and we
1546 * are clearing the one that will go down to the
1549 if (rcvif_set
&& m
->m_pkthdr
.rcvif
== ifp
)
1550 m
->m_pkthdr
.rcvif
= NULL
;
1554 * Let interface filters (if any) do their thing ...
1556 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1557 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1558 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1559 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_family
)) &&
1560 filter
->filt_output
) {
1561 retval
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
);
1563 if (retval
!= EJUSTRETURN
)
1572 * Strip away M_PROTO1 bit prior to sending packet to the driver
1573 * as this field may be used by the driver
1575 m
->m_flags
&= ~M_PROTO1
;
1578 * If the underlying interface is not capable of handling a
1579 * packet whose data portion spans across physically disjoint
1580 * pages, we need to "normalize" the packet so that we pass
1581 * down a chain of mbufs where each mbuf points to a span that
1582 * resides in the system page boundary. If the packet does
1583 * not cross page(s), the following is a no-op.
1585 if (!(ifp
->if_hwassist
& IFNET_MULTIPAGES
)) {
1586 if ((m
= m_normalize(m
)) == NULL
)
1591 * If this is a TSO packet, make sure the interface still advertise TSO capability
1594 if ((m
->m_pkthdr
.csum_flags
& CSUM_TSO_IPV4
) && !(ifp
->if_hwassist
& IFNET_TSO_IPV4
)) {
1600 if ((m
->m_pkthdr
.csum_flags
& CSUM_TSO_IPV6
) && !(ifp
->if_hwassist
& IFNET_TSO_IPV6
)) {
1606 * Finally, call the driver.
1609 if ((ifp
->if_eflags
& IFEF_SENDLIST
) != 0) {
1611 send_tail
= &m
->m_nextpkt
;
1614 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1615 retval
= ifp
->if_output(ifp
, m
);
1616 if (retval
&& dlil_verbose
) {
1617 printf("dlil_output: output error on %s%d retval = %d\n",
1618 ifp
->if_name
, ifp
->if_unit
, retval
);
1620 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1622 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1627 packetlist
= packetlist
->m_nextpkt
;
1628 m
->m_nextpkt
= NULL
;
1633 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1634 retval
= ifp
->if_output(ifp
, send_head
);
1635 if (retval
&& dlil_verbose
) {
1636 printf("dlil_output: output error on %s%d retval = %d\n",
1637 ifp
->if_name
, ifp
->if_unit
, retval
);
1639 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1642 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_END
,0,0,0,0,0);
1646 if (packetlist
) /* if any packet left, clean up */
1647 mbuf_freem_list(packetlist
);
1648 if (retval
== EJUSTRETURN
)
1656 protocol_family_t proto_fam
,
1660 struct ifnet_filter
*filter
;
1661 int retval
= EOPNOTSUPP
;
1663 int holding_read
= 0;
1665 if (ifp
== NULL
|| ioctl_code
== 0)
1668 /* Attempt to increment the use count. If it's zero, bail out, the ifp is invalid */
1669 result
= ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
);
1676 /* Run the interface filters first.
1677 * We want to run all filters before calling the protocol,
1678 * interface family, or interface.
1680 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1681 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_fam
)) &&
1682 filter
->filt_ioctl
!= NULL
) {
1683 result
= filter
->filt_ioctl(filter
->filt_cookie
, ifp
, proto_fam
, ioctl_code
, ioctl_arg
);
1684 /* Only update retval if no one has handled the ioctl */
1685 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1686 if (result
== ENOTSUP
)
1687 result
= EOPNOTSUPP
;
1689 if (retval
&& retval
!= EOPNOTSUPP
) {
1696 /* Allow the protocol to handle the ioctl */
1698 struct if_proto
*proto
= find_attached_proto(ifp
, proto_fam
);
1701 proto_media_ioctl ioctlp
= proto
->proto_kpi
== kProtoKPI_v1
1702 ? proto
->kpi
.v1
.ioctl
: proto
->kpi
.v2
.ioctl
;
1703 result
= EOPNOTSUPP
;
1705 result
= ioctlp(ifp
, proto_fam
, ioctl_code
, ioctl_arg
);
1707 /* Only update retval if no one has handled the ioctl */
1708 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1709 if (result
== ENOTSUP
)
1710 result
= EOPNOTSUPP
;
1712 if (retval
&& retval
!= EOPNOTSUPP
) {
1720 * Since we have incremented the use count on the ifp, we are guaranteed
1721 * that the ifp will not go away (the function pointers may not be changed).
1722 * We release the dlil read lock so the interface ioctl may trigger a
1723 * protocol attach. This happens with vlan and may occur with other virtual
1729 /* retval is either 0 or EOPNOTSUPP */
1732 * Let the interface handle this ioctl.
1733 * If it returns EOPNOTSUPP, ignore that, we may have
1734 * already handled this in the protocol or family.
1737 result
= (*ifp
->if_ioctl
)(ifp
, ioctl_code
, ioctl_arg
);
1739 /* Only update retval if no one has handled the ioctl */
1740 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1741 if (result
== ENOTSUP
)
1742 result
= EOPNOTSUPP
;
1744 if (retval
&& retval
!= EOPNOTSUPP
) {
1753 ifp_use_reached_zero(ifp
);
1755 if (retval
== EJUSTRETURN
)
1760 __private_extern__ errno_t
1764 bpf_packet_func callback
)
1769 if (ifp
->if_set_bpf_tap
)
1770 error
= ifp
->if_set_bpf_tap(ifp
, mode
, callback
);
1779 const struct sockaddr
*proto_addr
,
1780 struct sockaddr
*ll_addr
,
1783 errno_t result
= EOPNOTSUPP
;
1784 struct if_proto
*proto
;
1785 const struct sockaddr
*verify
;
1786 proto_media_resolve_multi resolvep
;
1790 bzero(ll_addr
, ll_len
);
1792 /* Call the protocol first */
1793 proto
= find_attached_proto(ifp
, proto_addr
->sa_family
);
1794 if (proto
!= NULL
) {
1795 resolvep
= proto
->proto_kpi
== kProtoKPI_v1
1796 ? proto
->kpi
.v1
.resolve_multi
: proto
->kpi
.v2
.resolve_multi
;
1797 if (resolvep
!= NULL
)
1798 result
= resolvep(ifp
, proto_addr
,(struct sockaddr_dl
*)ll_addr
,
1802 /* Let the interface verify the multicast address */
1803 if ((result
== EOPNOTSUPP
|| result
== 0) && ifp
->if_check_multi
) {
1807 verify
= proto_addr
;
1808 result
= ifp
->if_check_multi(ifp
, verify
);
1816 __private_extern__ errno_t
1817 dlil_send_arp_internal(
1820 const struct sockaddr_dl
* sender_hw
,
1821 const struct sockaddr
* sender_proto
,
1822 const struct sockaddr_dl
* target_hw
,
1823 const struct sockaddr
* target_proto
)
1825 struct if_proto
*proto
;
1830 proto
= find_attached_proto(ifp
, target_proto
->sa_family
);
1831 if (proto
== NULL
) {
1835 proto_media_send_arp arpp
;
1836 arpp
= proto
->proto_kpi
== kProtoKPI_v1
1837 ? proto
->kpi
.v1
.send_arp
: proto
->kpi
.v2
.send_arp
;
1841 result
= arpp(ifp
, arpop
, sender_hw
, sender_proto
, target_hw
,
1850 static __inline__
int
1851 _is_announcement(const struct sockaddr_in
* sender_sin
,
1852 const struct sockaddr_in
* target_sin
)
1854 if (sender_sin
== NULL
) {
1857 return (sender_sin
->sin_addr
.s_addr
== target_sin
->sin_addr
.s_addr
);
1860 __private_extern__ errno_t
1864 const struct sockaddr_dl
* sender_hw
,
1865 const struct sockaddr
* sender_proto
,
1866 const struct sockaddr_dl
* target_hw
,
1867 const struct sockaddr
* target_proto
)
1870 const struct sockaddr_in
* sender_sin
;
1871 const struct sockaddr_in
* target_sin
;
1873 if (target_proto
== NULL
|| (sender_proto
&&
1874 sender_proto
->sa_family
!= target_proto
->sa_family
))
1878 * If this is an ARP request and the target IP is IPv4LL,
1879 * send the request on all interfaces. The exception is
1880 * an announcement, which must only appear on the specific
1883 sender_sin
= (const struct sockaddr_in
*)sender_proto
;
1884 target_sin
= (const struct sockaddr_in
*)target_proto
;
1885 if (target_proto
->sa_family
== AF_INET
1886 && IN_LINKLOCAL(ntohl(target_sin
->sin_addr
.s_addr
))
1887 && ipv4_ll_arp_aware
!= 0
1888 && arpop
== ARPOP_REQUEST
1889 && !_is_announcement(target_sin
, sender_sin
)) {
1896 if (ifnet_list_get(IFNET_FAMILY_ANY
, &ifp_list
, &count
) == 0) {
1897 for (ifp_on
= 0; ifp_on
< count
; ifp_on
++) {
1899 ifaddr_t source_hw
= NULL
;
1900 ifaddr_t source_ip
= NULL
;
1901 struct sockaddr_in source_ip_copy
;
1904 * Only arp on interfaces marked for IPv4LL ARPing. This may
1905 * mean that we don't ARP on the interface the subnet route
1908 if ((ifp_list
[ifp_on
]->if_eflags
& IFEF_ARPLL
) == 0) {
1912 /* Find the source IP address */
1913 ifnet_lock_shared(ifp_list
[ifp_on
]);
1914 source_hw
= TAILQ_FIRST(&ifp_list
[ifp_on
]->if_addrhead
);
1915 TAILQ_FOREACH(source_ip
, &ifp_list
[ifp_on
]->if_addrhead
,
1917 if (source_ip
->ifa_addr
&&
1918 source_ip
->ifa_addr
->sa_family
== AF_INET
) {
1923 /* No IP Source, don't arp */
1924 if (source_ip
== NULL
) {
1925 ifnet_lock_done(ifp_list
[ifp_on
]);
1929 /* Copy the source IP address */
1930 source_ip_copy
= *(struct sockaddr_in
*)source_ip
->ifa_addr
;
1932 ifnet_lock_done(ifp_list
[ifp_on
]);
1935 new_result
= dlil_send_arp_internal(ifp_list
[ifp_on
], arpop
,
1936 (struct sockaddr_dl
*)source_hw
->ifa_addr
,
1937 (struct sockaddr
*)&source_ip_copy
, NULL
,
1941 if (result
== ENOTSUP
) {
1942 result
= new_result
;
1947 ifnet_list_free(ifp_list
);
1950 result
= dlil_send_arp_internal(ifp
, arpop
, sender_hw
, sender_proto
,
1951 target_hw
, target_proto
);
1957 __private_extern__
int
1966 old_value
= ifp
->if_usecnt
;
1967 if (old_value
== 0 && handle_zero
== kIfNetUseCount_MustNotBeZero
) {
1968 retval
= ENXIO
; // ifp is invalid
1971 } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)old_value
+ 1, (UInt32
*)&ifp
->if_usecnt
));
1976 /* ifp_unuse is broken into two pieces.
1978 * ifp_use and ifp_unuse must be called between when the caller calls
1979 * dlil_write_begin and dlil_write_end. ifp_unuse needs to perform some
1980 * operations after dlil_write_end has been called. For this reason,
1981 * anyone calling ifp_unuse must call ifp_use_reached_zero if ifp_unuse
1982 * returns a non-zero value. The caller must call ifp_use_reached_zero
1983 * after the caller has called dlil_write_end.
1985 __private_extern__
void
1986 ifp_use_reached_zero(
1989 ifnet_detached_func free_func
;
1993 if (ifp
->if_usecnt
!= 0)
1994 panic("ifp_use_reached_zero: ifp->if_usecnt != 0");
1996 ifnet_head_lock_exclusive();
1997 ifnet_lock_exclusive(ifp
);
1999 /* Remove ourselves from the list */
2000 TAILQ_REMOVE(&ifnet_head
, ifp
, if_link
);
2001 ifnet_addrs
[ifp
->if_index
- 1] = NULL
;
2003 /* ifp should be removed from the interface list */
2004 while (ifp
->if_multiaddrs
.lh_first
) {
2005 struct ifmultiaddr
*ifma
= ifp
->if_multiaddrs
.lh_first
;
2008 * When the interface is gone, we will no longer
2009 * be listening on these multicasts. Various bits
2010 * of the stack may be referencing these multicasts,
2011 * release only our reference.
2013 LIST_REMOVE(ifma
, ifma_link
);
2014 ifma
->ifma_ifp
= NULL
;
2018 ifp
->if_eflags
&= ~IFEF_DETACHING
; // clear the detaching flag
2019 ifnet_lock_done(ifp
);
2022 free_func
= ifp
->if_free
;
2024 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHED
, NULL
, 0);
2030 __private_extern__
int
2035 oldval
= OSDecrementAtomic(&ifp
->if_usecnt
);
2037 panic("ifp_unuse: ifp(%s%d)->if_usecnt was zero\n", ifp
->if_name
, ifp
->if_unit
);
2042 if ((ifp
->if_eflags
& IFEF_DETACHING
) == 0)
2043 panic("ifp_unuse: use count reached zero but detching flag is not set!");
2045 return 1; /* caller must call ifp_use_reached_zero */
2048 extern lck_mtx_t
*domain_proto_mtx
;
2051 dlil_attach_protocol_internal(
2052 struct if_proto
*proto
,
2053 const struct ifnet_demux_desc
*demux_list
,
2054 u_int32_t demux_count
)
2056 struct kev_dl_proto_data ev_pr_data
;
2057 struct ifnet
*ifp
= proto
->ifp
;
2059 u_int32_t hash_value
= proto_hash_value(proto
->protocol_family
);
2061 /* setup some of the common values */
2064 lck_mtx_lock(domain_proto_mtx
);
2066 while (dp
&& (protocol_family_t
)dp
->dom_family
!= proto
->protocol_family
)
2068 proto
->dl_domain
= dp
;
2069 lck_mtx_unlock(domain_proto_mtx
);
2073 * Take the write lock to protect readers and exclude other writers.
2075 if ((retval
= dlil_write_begin()) != 0) {
2076 printf("dlil_attach_protocol_internal - dlil_write_begin returned %d\n", retval
);
2080 /* Check that the interface isn't currently detaching */
2081 ifnet_lock_shared(ifp
);
2082 if ((ifp
->if_eflags
& IFEF_DETACHING
) != 0) {
2083 ifnet_lock_done(ifp
);
2087 ifnet_lock_done(ifp
);
2089 if (find_attached_proto(ifp
, proto
->protocol_family
) != NULL
) {
2095 * Call family module add_proto routine so it can refine the
2096 * demux descriptors as it wishes.
2098 retval
= ifp
->if_add_proto(ifp
, proto
->protocol_family
, demux_list
, demux_count
);
2105 * We can't fail from this point on.
2106 * Increment the number of uses (protocol attachments + interface attached).
2108 ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
);
2111 * Insert the protocol in the hash
2114 struct if_proto
* prev_proto
= SLIST_FIRST(&ifp
->if_proto_hash
[hash_value
]);
2115 while (prev_proto
&& SLIST_NEXT(prev_proto
, next_hash
) != NULL
)
2116 prev_proto
= SLIST_NEXT(prev_proto
, next_hash
);
2118 SLIST_INSERT_AFTER(prev_proto
, proto
, next_hash
);
2120 SLIST_INSERT_HEAD(&ifp
->if_proto_hash
[hash_value
], proto
, next_hash
);
2124 * Add to if_proto list for this interface
2126 if_proto_ref(proto
);
2129 /* the reserved field carries the number of protocol still attached (subject to change) */
2130 ev_pr_data
.proto_family
= proto
->protocol_family
;
2131 ev_pr_data
.proto_remaining_count
= dlil_ifp_proto_count(ifp
);
2132 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_ATTACHED
,
2133 (struct net_event_data
*)&ev_pr_data
,
2134 sizeof(struct kev_dl_proto_data
));
2136 DLIL_PRINTF("dlil. Attached protocol %d to %s%d - %d\n", proto
->protocol_family
,
2137 ifp
->if_name
, ifp
->if_unit
, retval
);
2143 ifnet_attach_protocol(ifnet_t ifp
, protocol_family_t protocol
,
2144 const struct ifnet_attach_proto_param
*proto_details
)
2147 struct if_proto
*ifproto
= NULL
;
2149 if (ifp
== NULL
|| protocol
== 0 || proto_details
== NULL
)
2152 ifproto
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
);
2154 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n");
2158 bzero(ifproto
, sizeof(*ifproto
));
2161 ifproto
->protocol_family
= protocol
;
2162 ifproto
->proto_kpi
= kProtoKPI_v1
;
2163 ifproto
->kpi
.v1
.input
= proto_details
->input
;
2164 ifproto
->kpi
.v1
.pre_output
= proto_details
->pre_output
;
2165 ifproto
->kpi
.v1
.event
= proto_details
->event
;
2166 ifproto
->kpi
.v1
.ioctl
= proto_details
->ioctl
;
2167 ifproto
->kpi
.v1
.detached
= proto_details
->detached
;
2168 ifproto
->kpi
.v1
.resolve_multi
= proto_details
->resolve
;
2169 ifproto
->kpi
.v1
.send_arp
= proto_details
->send_arp
;
2171 retval
= dlil_attach_protocol_internal(ifproto
,
2172 proto_details
->demux_list
, proto_details
->demux_count
);
2175 if (retval
&& ifproto
)
2176 FREE(ifproto
, M_IFADDR
);
2181 ifnet_attach_protocol_v2(ifnet_t ifp
, protocol_family_t protocol
,
2182 const struct ifnet_attach_proto_param_v2
*proto_details
)
2185 struct if_proto
*ifproto
= NULL
;
2187 if (ifp
== NULL
|| protocol
== 0 || proto_details
== NULL
)
2190 ifproto
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
);
2192 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n");
2196 bzero(ifproto
, sizeof(*ifproto
));
2199 ifproto
->protocol_family
= protocol
;
2200 ifproto
->proto_kpi
= kProtoKPI_v2
;
2201 ifproto
->kpi
.v2
.input
= proto_details
->input
;
2202 ifproto
->kpi
.v2
.pre_output
= proto_details
->pre_output
;
2203 ifproto
->kpi
.v2
.event
= proto_details
->event
;
2204 ifproto
->kpi
.v2
.ioctl
= proto_details
->ioctl
;
2205 ifproto
->kpi
.v2
.detached
= proto_details
->detached
;
2206 ifproto
->kpi
.v2
.resolve_multi
= proto_details
->resolve
;
2207 ifproto
->kpi
.v2
.send_arp
= proto_details
->send_arp
;
2209 retval
= dlil_attach_protocol_internal(ifproto
,
2210 proto_details
->demux_list
, proto_details
->demux_count
);
2213 if (retval
&& ifproto
)
2214 FREE(ifproto
, M_IFADDR
);
2218 extern void if_rtproto_del(struct ifnet
*ifp
, int protocol
);
2221 dlil_detach_protocol_internal(
2222 struct if_proto
*proto
)
2224 struct ifnet
*ifp
= proto
->ifp
;
2225 u_int32_t proto_family
= proto
->protocol_family
;
2226 struct kev_dl_proto_data ev_pr_data
;
2228 if (proto
->proto_kpi
== kProtoKPI_v1
) {
2229 if (proto
->kpi
.v1
.detached
)
2230 proto
->kpi
.v1
.detached(ifp
, proto
->protocol_family
);
2232 if (proto
->proto_kpi
== kProtoKPI_v2
) {
2233 if (proto
->kpi
.v2
.detached
)
2234 proto
->kpi
.v2
.detached(ifp
, proto
->protocol_family
);
2236 if_proto_free(proto
);
2239 * Cleanup routes that may still be in the routing table for that interface/protocol pair.
2242 if_rtproto_del(ifp
, proto_family
);
2244 /* the reserved field carries the number of protocol still attached (subject to change) */
2245 ev_pr_data
.proto_family
= proto_family
;
2246 ev_pr_data
.proto_remaining_count
= dlil_ifp_proto_count(ifp
);
2247 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_DETACHED
,
2248 (struct net_event_data
*)&ev_pr_data
,
2249 sizeof(struct kev_dl_proto_data
));
2254 ifnet_detach_protocol(ifnet_t ifp
, protocol_family_t proto_family
)
2256 struct if_proto
*proto
= NULL
;
2258 int use_reached_zero
= 0;
2260 if (ifp
== NULL
|| proto_family
== 0) return EINVAL
;
2262 if ((retval
= dlil_write_begin()) != 0) {
2263 if (retval
== EDEADLK
) {
2266 proto
= find_attached_proto(ifp
, proto_family
);
2271 proto
->detaching
= 1;
2272 dlil_detach_waiting
= 1;
2273 wakeup(&dlil_detach_waiting
);
2280 proto
= find_attached_proto(ifp
, proto_family
);
2282 if (proto
== NULL
) {
2289 * Call family module del_proto
2292 if (ifp
->if_del_proto
)
2293 ifp
->if_del_proto(ifp
, proto
->protocol_family
);
2295 SLIST_REMOVE(&ifp
->if_proto_hash
[proto_hash_value(proto_family
)], proto
, if_proto
, next_hash
);
2298 * We can do the rest of the work outside of the write lock.
2300 use_reached_zero
= ifp_unuse(ifp
);
2303 dlil_detach_protocol_internal(proto
);
2306 * Only handle the case where the interface will go away after
2307 * we've sent the message. This way post message can send the
2308 * message to the interface safely.
2311 if (use_reached_zero
)
2312 ifp_use_reached_zero(ifp
);
2319 * dlil_delayed_detach_thread is responsible for detaching
2320 * protocols, protocol filters, and interface filters after
2321 * an attempt was made to detach one of those items while
2322 * it was not safe to do so (i.e. called dlil_read_begin).
2324 * This function will take the dlil write lock and walk
2325 * through each of the interfaces looking for items with
2326 * the detaching flag set. When an item is found, it is
2327 * detached from the interface and placed on a local list.
2328 * After all of the items have been collected, we drop the
2329 * write lock and performed the post detach. This is done
2330 * so we only have to take the write lock once.
2332 * When detaching a protocol filter, if we find that we
2333 * have detached the very last protocol and we need to call
2334 * ifp_use_reached_zero, we have to break out of our work
2335 * to drop the write lock so we can call ifp_use_reached_zero.
2339 dlil_delayed_detach_thread(__unused
void* foo
, __unused wait_result_t wait
)
2341 thread_t self
= current_thread();
2344 ml_thread_policy(self
, MACHINE_GROUP
,
2345 (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
));
2349 if (dlil_detach_waiting
!= 0 && dlil_write_begin() == 0) {
2351 struct proto_hash_entry detached_protos
;
2352 struct ifnet_filter_head detached_filters
;
2353 struct if_proto
*proto
;
2354 struct if_proto
*next_proto
;
2355 struct ifnet_filter
*filt
;
2356 struct ifnet_filter
*next_filt
;
2361 /* Clear the detach waiting flag */
2362 dlil_detach_waiting
= 0;
2363 TAILQ_INIT(&detached_filters
);
2364 SLIST_INIT(&detached_protos
);
2366 ifnet_head_lock_shared();
2367 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2370 // Look for protocols and protocol filters
2371 for (i
= 0; i
< PROTO_HASH_SLOTS
&& !reached_zero
; i
++) {
2372 struct if_proto
**prev_nextptr
= &SLIST_FIRST(&ifp
->if_proto_hash
[i
]);
2373 for (proto
= *prev_nextptr
; proto
; proto
= *prev_nextptr
) {
2375 // Detach this protocol
2376 if (proto
->detaching
) {
2377 if (ifp
->if_del_proto
)
2378 ifp
->if_del_proto(ifp
, proto
->protocol_family
);
2379 *prev_nextptr
= SLIST_NEXT(proto
, next_hash
);
2380 SLIST_INSERT_HEAD(&detached_protos
, proto
, next_hash
);
2381 reached_zero
= ifp_unuse(ifp
);
2387 // Update prev_nextptr to point to our next ptr
2388 prev_nextptr
= &SLIST_NEXT(proto
, next_hash
);
2393 // look for interface filters that need to be detached
2394 for (filt
= TAILQ_FIRST(&ifp
->if_flt_head
); filt
; filt
= next_filt
) {
2395 next_filt
= TAILQ_NEXT(filt
, filt_next
);
2396 if (filt
->filt_detaching
!= 0) {
2397 // take this interface filter off the interface filter list
2398 TAILQ_REMOVE(&ifp
->if_flt_head
, filt
, filt_next
);
2400 // put this interface filter on the detached filters list
2401 TAILQ_INSERT_TAIL(&detached_filters
, filt
, filt_next
);
2405 if (ifp
->if_delayed_detach
) {
2406 ifp
->if_delayed_detach
= 0;
2407 reached_zero
= ifp_unuse(ifp
);
2416 for (filt
= TAILQ_FIRST(&detached_filters
); filt
; filt
= next_filt
) {
2417 next_filt
= TAILQ_NEXT(filt
, filt_next
);
2419 * dlil_detach_filter_internal won't remove an item from
2420 * the list if it is already detached (second parameter).
2421 * The item will be freed though.
2423 dlil_detach_filter_internal(filt
, 1);
2426 for (proto
= SLIST_FIRST(&detached_protos
); proto
; proto
= next_proto
) {
2427 next_proto
= SLIST_NEXT(proto
, next_hash
);
2428 dlil_detach_protocol_internal(proto
);
2432 ifp_use_reached_zero(ifp
);
2433 dlil_detach_waiting
= 1; // we may have missed something
2437 if (!asserted
&& dlil_detach_waiting
== 0) {
2439 assert_wait(&dlil_detach_waiting
, THREAD_UNINT
);
2442 if (dlil_detach_waiting
== 0) {
2444 thread_block(dlil_delayed_detach_thread
);
2450 dlil_call_delayed_detach_thread(void) {
2451 dlil_delayed_detach_thread(NULL
, THREAD_RESTART
);
2454 extern int if_next_index(void);
2459 const struct sockaddr_dl
*ll_addr
)
2461 u_int32_t interface_family
;
2462 struct ifnet
*tmp_if
;
2463 struct proto_hash_entry
*new_proto_list
= NULL
;
2466 if (ifp
== NULL
) return EINVAL
;
2467 if (ll_addr
&& ifp
->if_addrlen
== 0) {
2468 ifp
->if_addrlen
= ll_addr
->sdl_alen
;
2470 else if (ll_addr
&& ll_addr
->sdl_alen
!= ifp
->if_addrlen
) {
2474 interface_family
= ifp
->if_family
;
2476 ifnet_head_lock_shared();
2478 /* Verify we aren't already on the list */
2479 TAILQ_FOREACH(tmp_if
, &ifnet_head
, if_link
) {
2480 if (tmp_if
== ifp
) {
2488 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_lock
== 0)
2490 ifp
->if_lock
= lck_rw_alloc_init(ifnet_lock_group
, ifnet_lock_attr
);
2492 ifp
->if_lock
= lck_mtx_alloc_init(ifnet_lock_group
, ifnet_lock_attr
);
2495 if (ifp
->if_lock
== 0) {
2499 if (!(ifp
->if_eflags
& IFEF_REUSE
) || ifp
->if_fwd_route_lock
== NULL
) {
2500 if (ifp
->if_fwd_route_lock
== NULL
)
2501 ifp
->if_fwd_route_lock
= lck_mtx_alloc_init(
2502 ifnet_lock_group
, ifnet_lock_attr
);
2504 if (ifp
->if_fwd_route_lock
== NULL
) {
2506 lck_rw_free(ifp
->if_lock
, ifnet_lock_group
);
2508 lck_mtx_free(ifp
->if_lock
, ifnet_lock_group
);
2510 ifp
->if_lock
= NULL
;
2516 * Allow interfaces without protocol families to attach
2517 * only if they have the necessary fields filled out.
2520 if (ifp
->if_add_proto
== 0 || ifp
->if_del_proto
== 0) {
2521 DLIL_PRINTF("dlil Attempt to attach interface without family module - %d\n",
2526 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_proto_hash
== NULL
) {
2527 MALLOC(new_proto_list
, struct proto_hash_entry
*, sizeof(struct proto_hash_entry
) * PROTO_HASH_SLOTS
,
2530 if (new_proto_list
== 0) {
2538 TAILQ_INIT(&ifp
->if_flt_head
);
2541 if (new_proto_list
) {
2542 bzero(new_proto_list
, (PROTO_HASH_SLOTS
* sizeof(struct proto_hash_entry
)));
2543 ifp
->if_proto_hash
= new_proto_list
;
2544 new_proto_list
= NULL
;
2550 int namelen
, masklen
, socksize
, ifasize
;
2551 struct ifaddr
*ifa
= NULL
;
2553 if (ifp
->if_snd
.ifq_maxlen
== 0)
2554 ifp
->if_snd
.ifq_maxlen
= ifqmaxlen
;
2555 TAILQ_INIT(&ifp
->if_prefixhead
);
2556 LIST_INIT(&ifp
->if_multiaddrs
);
2557 ifnet_touch_lastchange(ifp
);
2559 /* usecount to track attachment to the ifnet list */
2560 ifp_use(ifp
, kIfNetUseCount_MayBeZero
);
2562 /* Lock the list of interfaces */
2563 ifnet_head_lock_exclusive();
2564 ifnet_lock_exclusive(ifp
);
2566 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_index
== 0) {
2567 int idx
= if_next_index();
2570 ifnet_lock_done(ifp
);
2577 ifp
->if_index
= idx
;
2579 ifa
= TAILQ_FIRST(&ifp
->if_addrhead
);
2581 namelen
= snprintf(workbuf
, sizeof(workbuf
), "%s%d", ifp
->if_name
, ifp
->if_unit
);
2582 #define _offsetof(t, m) ((uintptr_t)((caddr_t)&((t *)0)->m))
2583 masklen
= _offsetof(struct sockaddr_dl
, sdl_data
[0]) + namelen
;
2584 socksize
= masklen
+ ifp
->if_addrlen
;
2585 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(u_int32_t) - 1)))
2586 if ((u_int32_t
)socksize
< sizeof(struct sockaddr_dl
))
2587 socksize
= sizeof(struct sockaddr_dl
);
2588 socksize
= ROUNDUP(socksize
);
2589 ifasize
= sizeof(struct ifaddr
) + 2 * socksize
;
2592 * Allocate a new ifa if we don't have one
2593 * or the old one is too small.
2595 if (ifa
== NULL
|| socksize
> ifa
->ifa_addr
->sa_len
) {
2597 if_detach_ifa(ifp
, ifa
);
2598 ifa
= (struct ifaddr
*)_MALLOC(ifasize
, M_IFADDR
, M_WAITOK
);
2602 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)(ifa
+ 1);
2603 ifnet_addrs
[ifp
->if_index
- 1] = ifa
;
2604 bzero(ifa
, ifasize
);
2605 ifa
->ifa_debug
|= IFD_ALLOC
;
2606 sdl
->sdl_len
= socksize
;
2607 sdl
->sdl_family
= AF_LINK
;
2608 bcopy(workbuf
, sdl
->sdl_data
, namelen
);
2609 sdl
->sdl_nlen
= namelen
;
2610 sdl
->sdl_index
= ifp
->if_index
;
2611 sdl
->sdl_type
= ifp
->if_type
;
2613 sdl
->sdl_alen
= ll_addr
->sdl_alen
;
2614 if (ll_addr
->sdl_alen
!= ifp
->if_addrlen
)
2615 panic("ifnet_attach - ll_addr->sdl_alen != ifp->if_addrlen");
2616 bcopy(CONST_LLADDR(ll_addr
), LLADDR(sdl
), sdl
->sdl_alen
);
2619 ifa
->ifa_rtrequest
= link_rtrequest
;
2620 ifa
->ifa_addr
= (struct sockaddr
*)sdl
;
2621 sdl
= (struct sockaddr_dl
*)(socksize
+ (caddr_t
)sdl
);
2622 ifa
->ifa_netmask
= (struct sockaddr
*)sdl
;
2623 sdl
->sdl_len
= masklen
;
2624 while (namelen
!= 0)
2625 sdl
->sdl_data
[--namelen
] = 0xff;
2628 TAILQ_INIT(&ifp
->if_addrhead
);
2629 ifa
= ifnet_addrs
[ifp
->if_index
- 1];
2633 * We don't use if_attach_ifa because we want
2634 * this address to be first on the list.
2637 ifa
->ifa_debug
|= IFD_ATTACHED
;
2638 TAILQ_INSERT_HEAD(&ifp
->if_addrhead
, ifa
, ifa_link
);
2641 mac_ifnet_label_associate(ifp
);
2644 TAILQ_INSERT_TAIL(&ifnet_head
, ifp
, if_link
);
2645 ifindex2ifnet
[ifp
->if_index
] = ifp
;
2649 * A specific dlil input thread is created per Ethernet/PDP interface.
2650 * pseudo interfaces or other types of interfaces use the main ("loopback") thread.
2651 * If the sysctl "net.link.generic.system.multi_threaded_input" is set to zero, all packets will
2652 * be handled by the main loopback thread, reverting to 10.4.x behaviour.
2656 if (ifp
->if_type
== IFT_ETHER
|| ifp
->if_type
== IFT_PDP
) {
2659 if (dlil_multithreaded_input
> 0) {
2660 ifp
->if_input_thread
= _MALLOC(sizeof(struct dlil_threading_info
), M_NKE
, M_WAITOK
);
2661 if (ifp
->if_input_thread
== NULL
)
2662 panic("ifnet_attach ifp=%p couldn't alloc threading\n", ifp
);
2663 if ((err
= dlil_create_input_thread(ifp
, ifp
->if_input_thread
)) != 0)
2664 panic("ifnet_attach ifp=%p couldn't get a thread. err=%d\n", ifp
, err
);
2666 printf("ifnet_attach: dlil thread for ifp=%p if_index=%d\n", ifp
, ifp
->if_index
);
2670 ifnet_lock_done(ifp
);
2674 * Attach packet filter to this interface, if enaled.
2676 pf_ifnet_hook(ifp
, 1);
2680 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_ATTACHED
, NULL
, 0);
2689 struct ifnet_filter
*filter
;
2690 struct ifnet_filter
*filter_next
;
2693 struct ifnet_filter_head fhead
;
2694 struct dlil_threading_info
*inputthread
;
2696 if (ifp
== NULL
) return EINVAL
;
2698 ifnet_lock_exclusive(ifp
);
2700 if ((ifp
->if_eflags
& IFEF_DETACHING
) != 0) {
2701 /* Interface has already been detached */
2702 ifnet_lock_done(ifp
);
2707 * Indicate this interface is being detached.
2709 * This should prevent protocols from attaching
2710 * from this point on. Interface will remain on
2711 * the list until all of the protocols are detached.
2713 ifp
->if_eflags
|= IFEF_DETACHING
;
2714 ifnet_lock_done(ifp
);
2716 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHING
, NULL
, 0);
2718 /* Let BPF know we're detaching */
2721 if ((retval
= dlil_write_begin()) != 0) {
2722 if (retval
== EDEADLK
) {
2725 /* We need to perform a delayed detach */
2726 ifp
->if_delayed_detach
= 1;
2727 dlil_detach_waiting
= 1;
2728 wakeup(&dlil_detach_waiting
);
2735 * Detach this interface from packet filter, if enabled.
2737 pf_ifnet_hook(ifp
, 0);
2740 /* Steal the list of interface filters */
2741 fhead
= ifp
->if_flt_head
;
2742 TAILQ_INIT(&ifp
->if_flt_head
);
2744 /* unuse the interface */
2745 zeroed
= ifp_unuse(ifp
);
2748 * If thread affinity was set for the workloop thread, we will need
2749 * to tear down the affinity and release the extra reference count
2750 * taken at attach time;
2752 if ((inputthread
= ifp
->if_input_thread
) != NULL
) {
2753 if (inputthread
->net_affinity
) {
2756 if (inputthread
== dlil_lo_thread_ptr
)
2757 panic("Thread affinity should not be enabled "
2758 "on the loopback dlil input thread\n");
2760 lck_mtx_lock(inputthread
->input_lck
);
2761 tp
= inputthread
->workloop_thread
;
2762 inputthread
->workloop_thread
= NULL
;
2763 inputthread
->tag
= 0;
2764 inputthread
->net_affinity
= FALSE
;
2765 lck_mtx_unlock(inputthread
->input_lck
);
2767 /* Tear down workloop thread affinity */
2769 (void) dlil_affinity_set(tp
,
2770 THREAD_AFFINITY_TAG_NULL
);
2771 thread_deallocate(tp
);
2774 /* Tear down dlil input thread affinity */
2775 tp
= inputthread
->input_thread
;
2776 (void) dlil_affinity_set(tp
, THREAD_AFFINITY_TAG_NULL
);
2777 thread_deallocate(tp
);
2780 /* cleanup ifp dlil input thread, if any */
2781 ifp
->if_input_thread
= NULL
;
2783 if (inputthread
!= dlil_lo_thread_ptr
) {
2785 printf("ifnet_detach: wakeup thread threadinfo: %p "
2786 "input_thread=%p threads: cur=%d max=%d\n",
2787 inputthread
, inputthread
->input_thread
,
2788 dlil_multithreaded_input
, cur_dlil_input_threads
);
2790 lck_mtx_lock(inputthread
->input_lck
);
2792 inputthread
->input_waiting
|= DLIL_INPUT_TERMINATE
;
2793 if ((inputthread
->input_waiting
& DLIL_INPUT_RUNNING
) == 0) {
2794 wakeup((caddr_t
)&inputthread
->input_waiting
);
2796 lck_mtx_unlock(inputthread
->input_lck
);
2799 /* last chance to clean up IPv4 forwarding cached route */
2800 lck_mtx_lock(ifp
->if_fwd_route_lock
);
2801 if (ifp
->if_fwd_route
.ro_rt
!= NULL
) {
2802 rtfree(ifp
->if_fwd_route
.ro_rt
);
2803 ifp
->if_fwd_route
.ro_rt
= NULL
;
2805 lck_mtx_unlock(ifp
->if_fwd_route_lock
);
2808 for (filter
= TAILQ_FIRST(&fhead
); filter
; filter
= filter_next
) {
2809 filter_next
= TAILQ_NEXT(filter
, filt_next
);
2810 dlil_detach_filter_internal(filter
, 1);
2814 ifp_use_reached_zero(ifp
);
2822 __unused ifnet_t ifnet_ptr
,
2823 __unused u_long ioctl_code
,
2824 __unused
void *ioctl_arg
)
2830 dlil_recycle_output(
2831 __unused
struct ifnet
*ifnet_ptr
,
2840 __unused ifnet_t ifnet_ptr
)
2845 dlil_recycle_set_bpf_tap(
2846 __unused ifnet_t ifp
,
2847 __unused bpf_tap_mode mode
,
2848 __unused bpf_packet_func callback
)
2850 /* XXX not sure what to do here */
2855 int dlil_if_acquire(
2857 const void *uniqueid
,
2858 size_t uniqueid_len
,
2861 struct ifnet
*ifp1
= NULL
;
2862 struct dlil_ifnet
*dlifp1
= NULL
;
2865 lck_mtx_lock(dlil_ifnet_mutex
);
2866 TAILQ_FOREACH(dlifp1
, &dlil_ifnet_head
, dl_if_link
) {
2868 ifp1
= (struct ifnet
*)dlifp1
;
2870 if (ifp1
->if_family
== family
) {
2872 /* same uniqueid and same len or no unique id specified */
2873 if ((uniqueid_len
== dlifp1
->if_uniqueid_len
)
2874 && !bcmp(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
)) {
2876 /* check for matching interface in use */
2877 if (ifp1
->if_eflags
& IFEF_INUSE
) {
2885 panic("ifp's lock is gone\n");
2886 ifnet_lock_exclusive(ifp1
);
2887 ifp1
->if_eflags
|= (IFEF_INUSE
| IFEF_REUSE
);
2888 ifnet_lock_done(ifp1
);
2896 /* no interface found, allocate a new one */
2897 MALLOC(dlifp1
, struct dlil_ifnet
*, sizeof(*dlifp1
), M_NKE
, M_WAITOK
);
2903 bzero(dlifp1
, sizeof(*dlifp1
));
2906 MALLOC(dlifp1
->if_uniqueid
, void *, uniqueid_len
, M_NKE
, M_WAITOK
);
2907 if (dlifp1
->if_uniqueid
== 0) {
2908 FREE(dlifp1
, M_NKE
);
2912 bcopy(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
);
2913 dlifp1
->if_uniqueid_len
= uniqueid_len
;
2916 ifp1
= (struct ifnet
*)dlifp1
;
2917 ifp1
->if_eflags
|= IFEF_INUSE
;
2918 ifp1
->if_name
= dlifp1
->if_namestorage
;
2920 mac_ifnet_label_init(ifp1
);
2923 TAILQ_INSERT_TAIL(&dlil_ifnet_head
, dlifp1
, dl_if_link
);
2928 lck_mtx_unlock(dlil_ifnet_mutex
);
2933 __private_extern__
void
2937 struct dlil_ifnet
*dlifp
= (struct dlil_ifnet
*)ifp
;
2939 /* Interface does not have a lock until it is attached - radar 3713951 */
2941 ifnet_lock_exclusive(ifp
);
2942 ifp
->if_eflags
&= ~IFEF_INUSE
;
2943 ifp
->if_ioctl
= dlil_recycle_ioctl
;
2944 ifp
->if_output
= dlil_recycle_output
;
2945 ifp
->if_free
= dlil_recycle_free
;
2946 ifp
->if_set_bpf_tap
= dlil_recycle_set_bpf_tap
;
2948 strncpy(dlifp
->if_namestorage
, ifp
->if_name
, IFNAMSIZ
);
2949 ifp
->if_name
= dlifp
->if_namestorage
;
2952 * We can either recycle the MAC label here or in dlil_if_acquire().
2953 * It seems logical to do it here but this means that anything that
2954 * still has a handle on ifp will now see it as unlabeled.
2955 * Since the interface is "dead" that may be OK. Revisit later.
2957 mac_ifnet_label_recycle(ifp
);
2960 ifnet_lock_done(ifp
);
2964 __private_extern__
void
2965 dlil_proto_unplumb_all(struct ifnet
*ifp
)
2968 * if_proto_hash[0-3] are for PF_INET, PF_INET6, PF_APPLETALK
2969 * and PF_VLAN, where each bucket contains exactly one entry;
2970 * PF_VLAN does not need an explicit unplumb.
2972 * if_proto_hash[4] is for other protocols; we expect anything
2973 * in this bucket to respond to the DETACHING event (which would
2974 * have happened by now) and do the unplumb then.
2976 (void) proto_unplumb(PF_INET
, ifp
);
2978 (void) proto_unplumb(PF_INET6
, ifp
);
2981 (void) proto_unplumb(PF_APPLETALK
, ifp
);