2 * Copyright (c) 1999-2008 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
);
1010 dlil_ifproto_input(struct if_proto
* ifproto
, mbuf_t m
)
1014 if (ifproto
->proto_kpi
== kProtoKPI_v1
) {
1015 /* Version 1 protocols get one packet at a time */
1017 char * frame_header
;
1020 next_packet
= m
->m_nextpkt
;
1021 m
->m_nextpkt
= NULL
;
1022 frame_header
= m
->m_pkthdr
.header
;
1023 m
->m_pkthdr
.header
= NULL
;
1024 error
= (*ifproto
->kpi
.v1
.input
)(ifproto
->ifp
,
1025 ifproto
->protocol_family
,
1027 if (error
!= 0 && error
!= EJUSTRETURN
)
1032 else if (ifproto
->proto_kpi
== kProtoKPI_v2
) {
1033 /* Version 2 protocols support packet lists */
1034 error
= (*ifproto
->kpi
.v2
.input
)(ifproto
->ifp
,
1035 ifproto
->protocol_family
,
1037 if (error
!= 0 && error
!= EJUSTRETURN
)
1043 __private_extern__
void
1044 dlil_input_packet_list(struct ifnet
* ifp_param
, struct mbuf
*m
)
1048 protocol_family_t protocol_family
;
1050 ifnet_t ifp
= ifp_param
;
1051 char * frame_header
;
1052 struct if_proto
* last_ifproto
= NULL
;
1053 mbuf_t pkt_first
= NULL
;
1054 mbuf_t
* pkt_next
= NULL
;
1056 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT
| DBG_FUNC_START
,0,0,0,0,0);
1059 struct if_proto
* ifproto
= NULL
;
1061 next_packet
= m
->m_nextpkt
;
1062 m
->m_nextpkt
= NULL
;
1063 if (ifp_param
== NULL
)
1064 ifp
= m
->m_pkthdr
.rcvif
;
1065 frame_header
= m
->m_pkthdr
.header
;
1066 m
->m_pkthdr
.header
= NULL
;
1069 /* dlil lock protects the demux and interface filters */
1073 /* find which protocol family this packet is for */
1074 error
= (*ifp
->if_demux
)(ifp
, m
, frame_header
,
1077 if (error
== EJUSTRETURN
) {
1080 protocol_family
= 0;
1084 if (m
->m_flags
& (M_BCAST
|M_MCAST
))
1087 /* run interface filters, exclude VLAN packets PR-3586856 */
1088 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1091 filter_result
= dlil_interface_filters_input(ifp
, &m
,
1094 if (filter_result
!= 0) {
1095 if (filter_result
!= EJUSTRETURN
) {
1101 if (error
!= 0 || ((m
->m_flags
& M_PROMISC
) != 0) ) {
1106 /* Lookup the protocol attachment to this interface */
1107 if (protocol_family
== 0) {
1110 else if (last_ifproto
!= NULL
1111 && last_ifproto
->ifp
== ifp
1112 && (last_ifproto
->protocol_family
1113 == protocol_family
)) {
1114 ifproto
= last_ifproto
;
1117 ifproto
= find_attached_proto(ifp
, protocol_family
);
1119 if (ifproto
== NULL
) {
1120 /* no protocol for this packet, discard */
1124 if (ifproto
!= last_ifproto
) {
1125 /* make sure ifproto can't go away during input */
1126 if_proto_ref(ifproto
);
1127 if (last_ifproto
!= NULL
) {
1128 /* pass up the list for the previous protocol */
1131 dlil_ifproto_input(last_ifproto
, pkt_first
);
1133 if_proto_free(last_ifproto
);
1136 last_ifproto
= ifproto
;
1138 /* extend the list */
1139 m
->m_pkthdr
.header
= frame_header
;
1140 if (pkt_first
== NULL
) {
1145 pkt_next
= &m
->m_nextpkt
;
1148 if (next_packet
== NULL
&& last_ifproto
!= NULL
) {
1149 /* pass up the last list of packets */
1152 dlil_ifproto_input(last_ifproto
, pkt_first
);
1153 if_proto_free(last_ifproto
);
1162 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT
| DBG_FUNC_END
,0,0,0,0,0);
1167 dlil_event_internal(struct ifnet
*ifp
, struct kev_msg
*event
)
1169 struct ifnet_filter
*filter
;
1171 if (ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
) == 0) {
1174 /* Pass the event to the interface filters */
1175 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1176 if (filter
->filt_event
)
1177 filter
->filt_event(filter
->filt_cookie
, ifp
, filter
->filt_protocol
, event
);
1180 if (ifp
->if_proto_hash
) {
1183 for (i
= 0; i
< PROTO_HASH_SLOTS
; i
++) {
1184 struct if_proto
*proto
;
1186 SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) {
1187 proto_media_event eventp
= proto
->proto_kpi
== kProtoKPI_v1
1188 ? proto
->kpi
.v1
.event
: proto
->kpi
.v2
.event
;
1191 eventp(ifp
, proto
->protocol_family
, event
);
1198 /* Pass the event to the interface */
1200 ifp
->if_event(ifp
, event
);
1203 ifp_use_reached_zero(ifp
);
1206 return kev_post_msg(event
);
1212 struct kern_event_msg
*event
)
1214 struct kev_msg kev_msg
;
1217 if (ifp
== NULL
|| event
== NULL
) return EINVAL
;
1219 kev_msg
.vendor_code
= event
->vendor_code
;
1220 kev_msg
.kev_class
= event
->kev_class
;
1221 kev_msg
.kev_subclass
= event
->kev_subclass
;
1222 kev_msg
.event_code
= event
->event_code
;
1223 kev_msg
.dv
[0].data_ptr
= &event
->event_data
[0];
1224 kev_msg
.dv
[0].data_length
= event
->total_size
- KEV_MSG_HEADER_SIZE
;
1225 kev_msg
.dv
[1].data_length
= 0;
1227 result
= dlil_event_internal(ifp
, &kev_msg
);
1233 #include <netinet/ip6.h>
1234 #include <netinet/ip.h>
1235 static int dlil_get_socket_type(struct mbuf
**mp
, int family
, int raw
)
1239 struct ip6_hdr
*ip6
;
1240 int type
= SOCK_RAW
;
1245 m
= m_pullup(*mp
, sizeof(struct ip
));
1249 ip
= mtod(m
, struct ip
*);
1250 if (ip
->ip_p
== IPPROTO_TCP
)
1252 else if (ip
->ip_p
== IPPROTO_UDP
)
1256 m
= m_pullup(*mp
, sizeof(struct ip6_hdr
));
1260 ip6
= mtod(m
, struct ip6_hdr
*);
1261 if (ip6
->ip6_nxt
== IPPROTO_TCP
)
1263 else if (ip6
->ip6_nxt
== IPPROTO_UDP
)
1277 u_long proto_family
,
1278 struct mbuf
*packetlist
,
1280 const struct sockaddr
*dest
,
1283 char *frame_type
= NULL
;
1284 char *dst_linkaddr
= NULL
;
1286 char frame_type_buffer
[MAX_FRAME_TYPE_SIZE
* 4];
1287 char dst_linkaddr_buffer
[MAX_LINKADDR
* 4];
1288 struct ifnet_filter
*filter
;
1289 struct if_proto
*proto
= 0;
1291 mbuf_t send_head
= NULL
;
1292 mbuf_t
*send_tail
= &send_head
;
1294 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_START
,0,0,0,0,0);
1298 frame_type
= frame_type_buffer
;
1299 dst_linkaddr
= dst_linkaddr_buffer
;
1302 proto
= find_attached_proto(ifp
, proto_family
);
1303 if (proto
== NULL
) {
1310 if (packetlist
== NULL
)
1313 packetlist
= packetlist
->m_nextpkt
;
1314 m
->m_nextpkt
= NULL
;
1317 proto_media_preout preoutp
= proto
->proto_kpi
== kProtoKPI_v1
1318 ? proto
->kpi
.v1
.pre_output
: proto
->kpi
.v2
.pre_output
;
1321 retval
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
);
1324 if (retval
== EJUSTRETURN
) {
1335 retval
= mac_ifnet_check_transmit(ifp
, m
, proto_family
,
1336 dlil_get_socket_type(&m
, proto_family
, raw
));
1343 if (raw
== 0 && ifp
->if_framer
) {
1344 retval
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);
1346 if (retval
!= EJUSTRETURN
) {
1356 * Need to consider how to handle this.
1357 * Also note that return should be a goto cleanup
1361 struct mbuf
*m0
= m
;
1362 struct ether_header
*eh
= mtod(m
, struct ether_header
*);
1364 if (m
->m_pkthdr
.rcvif
)
1365 m
->m_pkthdr
.rcvif
= NULL
;
1366 ifp
= bridge_dst_lookup(eh
);
1367 bdg_forward(&m0
, ifp
);
1371 return 0 - should be
goto cleanup
?
1376 * Let interface filters (if any) do their thing ...
1378 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1379 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1380 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1381 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_family
)) &&
1382 filter
->filt_output
) {
1383 retval
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
);
1385 if (retval
!= EJUSTRETURN
)
1394 * Finally, call the driver.
1397 if ((ifp
->if_eflags
& IFEF_SENDLIST
) != 0) {
1399 send_tail
= &m
->m_nextpkt
;
1402 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1403 retval
= ifp
->if_output(ifp
, m
);
1404 if (retval
&& dlil_verbose
) {
1405 printf("dlil_output: output error on %s%d retval = %d\n",
1406 ifp
->if_name
, ifp
->if_unit
, retval
);
1408 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1410 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1415 packetlist
= packetlist
->m_nextpkt
;
1416 m
->m_nextpkt
= NULL
;
1421 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1422 retval
= ifp
->if_output(ifp
, send_head
);
1423 if (retval
&& dlil_verbose
) {
1424 printf("dlil_output: output error on %s%d retval = %d\n",
1425 ifp
->if_name
, ifp
->if_unit
, retval
);
1427 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1430 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_END
,0,0,0,0,0);
1434 if (packetlist
) /* if any packet left, clean up */
1435 mbuf_freem_list(packetlist
);
1436 if (retval
== EJUSTRETURN
)
1445 * Caller should have a lock on the protocol domain if the protocol
1446 * doesn't support finer grained locking. In most cases, the lock
1447 * will be held from the socket layer and won't be released until
1448 * we return back to the socket layer.
1450 * This does mean that we must take a protocol lock before we take
1451 * an interface lock if we're going to take both. This makes sense
1452 * because a protocol is likely to interact with an ifp while it
1453 * is under the protocol lock.
1455 __private_extern__ errno_t
1458 protocol_family_t proto_family
,
1461 const struct sockaddr
*dest
,
1464 char *frame_type
= NULL
;
1465 char *dst_linkaddr
= NULL
;
1467 char frame_type_buffer
[MAX_FRAME_TYPE_SIZE
* 4];
1468 char dst_linkaddr_buffer
[MAX_LINKADDR
* 4];
1469 struct ifnet_filter
*filter
;
1470 struct if_proto
*proto
= 0;
1472 mbuf_t send_head
= NULL
;
1473 mbuf_t
*send_tail
= &send_head
;
1475 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_START
,0,0,0,0,0);
1479 frame_type
= frame_type_buffer
;
1480 dst_linkaddr
= dst_linkaddr_buffer
;
1483 proto
= find_attached_proto(ifp
, proto_family
);
1484 if (proto
== NULL
) {
1491 if (packetlist
== NULL
)
1494 packetlist
= packetlist
->m_nextpkt
;
1495 m
->m_nextpkt
= NULL
;
1498 proto_media_preout preoutp
= proto
->proto_kpi
== kProtoKPI_v1
1499 ? proto
->kpi
.v1
.pre_output
: proto
->kpi
.v2
.pre_output
;
1502 retval
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
);
1505 if (retval
== EJUSTRETURN
) {
1515 retval
= mac_ifnet_check_transmit(ifp
, m
, proto_family
,
1516 dlil_get_socket_type(&m
, proto_family
, raw
));
1524 if (raw
== 0 && ifp
->if_framer
) {
1528 * If this is a broadcast packet that needs to be
1529 * looped back into the system, set the inbound ifp
1530 * to that of the outbound ifp. This will allow
1531 * us to determine that it is a legitimate packet
1532 * for the system. Only set the ifp if it's not
1533 * already set, just to be safe.
1535 if ((m
->m_flags
& (M_BCAST
| M_LOOP
)) &&
1536 m
->m_pkthdr
.rcvif
== NULL
) {
1537 m
->m_pkthdr
.rcvif
= ifp
;
1541 retval
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);
1543 if (retval
!= EJUSTRETURN
) {
1550 * Clear the ifp if it was set above, and to be
1551 * safe, only if it is still the same as the
1552 * outbound ifp we have in context. If it was
1553 * looped back, then a copy of it was sent to the
1554 * loopback interface with the rcvif set, and we
1555 * are clearing the one that will go down to the
1558 if (rcvif_set
&& m
->m_pkthdr
.rcvif
== ifp
)
1559 m
->m_pkthdr
.rcvif
= NULL
;
1565 * Need to consider how to handle this.
1566 * Also note that return should be a goto cleanup
1570 struct mbuf
*m0
= m
;
1571 struct ether_header
*eh
= mtod(m
, struct ether_header
*);
1573 if (m
->m_pkthdr
.rcvif
)
1574 m
->m_pkthdr
.rcvif
= NULL
;
1575 ifp
= bridge_dst_lookup(eh
);
1576 bdg_forward(&m0
, ifp
);
1580 return 0 - should be
goto cleanup
?
1585 * Let interface filters (if any) do their thing ...
1587 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1588 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1589 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1590 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_family
)) &&
1591 filter
->filt_output
) {
1592 retval
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
);
1594 if (retval
!= EJUSTRETURN
)
1603 * If the underlying interface is not capable of handling a
1604 * packet whose data portion spans across physically disjoint
1605 * pages, we need to "normalize" the packet so that we pass
1606 * down a chain of mbufs where each mbuf points to a span that
1607 * resides in the system page boundary. If the packet does
1608 * not cross page(s), the following is a no-op.
1610 if (!(ifp
->if_hwassist
& IFNET_MULTIPAGES
)) {
1611 if ((m
= m_normalize(m
)) == NULL
)
1616 * If this is a TSO packet, make sure the interface still advertise TSO capability
1619 if ((m
->m_pkthdr
.csum_flags
& CSUM_TSO_IPV4
) && !(ifp
->if_hwassist
& IFNET_TSO_IPV4
)) {
1625 if ((m
->m_pkthdr
.csum_flags
& CSUM_TSO_IPV6
) && !(ifp
->if_hwassist
& IFNET_TSO_IPV6
)) {
1631 * Finally, call the driver.
1634 if ((ifp
->if_eflags
& IFEF_SENDLIST
) != 0) {
1636 send_tail
= &m
->m_nextpkt
;
1639 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1640 retval
= ifp
->if_output(ifp
, m
);
1641 if (retval
&& dlil_verbose
) {
1642 printf("dlil_output: output error on %s%d retval = %d\n",
1643 ifp
->if_name
, ifp
->if_unit
, retval
);
1645 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1647 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1652 packetlist
= packetlist
->m_nextpkt
;
1653 m
->m_nextpkt
= NULL
;
1658 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1659 retval
= ifp
->if_output(ifp
, send_head
);
1660 if (retval
&& dlil_verbose
) {
1661 printf("dlil_output: output error on %s%d retval = %d\n",
1662 ifp
->if_name
, ifp
->if_unit
, retval
);
1664 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1667 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_END
,0,0,0,0,0);
1671 if (packetlist
) /* if any packet left, clean up */
1672 mbuf_freem_list(packetlist
);
1673 if (retval
== EJUSTRETURN
)
1681 protocol_family_t proto_fam
,
1685 struct ifnet_filter
*filter
;
1686 int retval
= EOPNOTSUPP
;
1688 int holding_read
= 0;
1690 if (ifp
== NULL
|| ioctl_code
== 0)
1693 /* Attempt to increment the use count. If it's zero, bail out, the ifp is invalid */
1694 result
= ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
);
1701 /* Run the interface filters first.
1702 * We want to run all filters before calling the protocol,
1703 * interface family, or interface.
1705 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1706 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_fam
)) &&
1707 filter
->filt_ioctl
!= NULL
) {
1708 result
= filter
->filt_ioctl(filter
->filt_cookie
, ifp
, proto_fam
, ioctl_code
, ioctl_arg
);
1709 /* Only update retval if no one has handled the ioctl */
1710 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1711 if (result
== ENOTSUP
)
1712 result
= EOPNOTSUPP
;
1714 if (retval
&& retval
!= EOPNOTSUPP
) {
1721 /* Allow the protocol to handle the ioctl */
1723 struct if_proto
*proto
= find_attached_proto(ifp
, proto_fam
);
1726 proto_media_ioctl ioctlp
= proto
->proto_kpi
== kProtoKPI_v1
1727 ? proto
->kpi
.v1
.ioctl
: proto
->kpi
.v2
.ioctl
;
1728 result
= EOPNOTSUPP
;
1730 result
= ioctlp(ifp
, proto_fam
, ioctl_code
, ioctl_arg
);
1732 /* Only update retval if no one has handled the ioctl */
1733 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1734 if (result
== ENOTSUP
)
1735 result
= EOPNOTSUPP
;
1737 if (retval
&& retval
!= EOPNOTSUPP
) {
1745 * Since we have incremented the use count on the ifp, we are guaranteed
1746 * that the ifp will not go away (the function pointers may not be changed).
1747 * We release the dlil read lock so the interface ioctl may trigger a
1748 * protocol attach. This happens with vlan and may occur with other virtual
1754 /* retval is either 0 or EOPNOTSUPP */
1757 * Let the interface handle this ioctl.
1758 * If it returns EOPNOTSUPP, ignore that, we may have
1759 * already handled this in the protocol or family.
1762 result
= (*ifp
->if_ioctl
)(ifp
, ioctl_code
, ioctl_arg
);
1764 /* Only update retval if no one has handled the ioctl */
1765 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1766 if (result
== ENOTSUP
)
1767 result
= EOPNOTSUPP
;
1769 if (retval
&& retval
!= EOPNOTSUPP
) {
1778 ifp_use_reached_zero(ifp
);
1780 if (retval
== EJUSTRETURN
)
1785 __private_extern__ errno_t
1789 bpf_packet_func callback
)
1794 if (ifp
->if_set_bpf_tap
)
1795 error
= ifp
->if_set_bpf_tap(ifp
, mode
, callback
);
1804 const struct sockaddr
*proto_addr
,
1805 struct sockaddr
*ll_addr
,
1808 errno_t result
= EOPNOTSUPP
;
1809 struct if_proto
*proto
;
1810 const struct sockaddr
*verify
;
1811 proto_media_resolve_multi resolvep
;
1815 bzero(ll_addr
, ll_len
);
1817 /* Call the protocol first */
1818 proto
= find_attached_proto(ifp
, proto_addr
->sa_family
);
1819 if (proto
!= NULL
) {
1820 resolvep
= proto
->proto_kpi
== kProtoKPI_v1
1821 ? proto
->kpi
.v1
.resolve_multi
: proto
->kpi
.v2
.resolve_multi
;
1822 if (resolvep
!= NULL
)
1823 result
= resolvep(ifp
, proto_addr
,(struct sockaddr_dl
*)ll_addr
,
1827 /* Let the interface verify the multicast address */
1828 if ((result
== EOPNOTSUPP
|| result
== 0) && ifp
->if_check_multi
) {
1832 verify
= proto_addr
;
1833 result
= ifp
->if_check_multi(ifp
, verify
);
1841 __private_extern__ errno_t
1842 dlil_send_arp_internal(
1845 const struct sockaddr_dl
* sender_hw
,
1846 const struct sockaddr
* sender_proto
,
1847 const struct sockaddr_dl
* target_hw
,
1848 const struct sockaddr
* target_proto
)
1850 struct if_proto
*proto
;
1855 proto
= find_attached_proto(ifp
, target_proto
->sa_family
);
1856 if (proto
== NULL
) {
1860 proto_media_send_arp arpp
;
1861 arpp
= proto
->proto_kpi
== kProtoKPI_v1
1862 ? proto
->kpi
.v1
.send_arp
: proto
->kpi
.v2
.send_arp
;
1866 result
= arpp(ifp
, arpop
, sender_hw
, sender_proto
, target_hw
,
1875 static __inline__
int
1876 _is_announcement(const struct sockaddr_in
* sender_sin
,
1877 const struct sockaddr_in
* target_sin
)
1879 if (sender_sin
== NULL
) {
1882 return (sender_sin
->sin_addr
.s_addr
== target_sin
->sin_addr
.s_addr
);
1885 __private_extern__ errno_t
1889 const struct sockaddr_dl
* sender_hw
,
1890 const struct sockaddr
* sender_proto
,
1891 const struct sockaddr_dl
* target_hw
,
1892 const struct sockaddr
* target_proto
)
1895 const struct sockaddr_in
* sender_sin
;
1896 const struct sockaddr_in
* target_sin
;
1898 if (target_proto
== NULL
|| (sender_proto
&&
1899 sender_proto
->sa_family
!= target_proto
->sa_family
))
1903 * If this is an ARP request and the target IP is IPv4LL,
1904 * send the request on all interfaces. The exception is
1905 * an announcement, which must only appear on the specific
1908 sender_sin
= (const struct sockaddr_in
*)sender_proto
;
1909 target_sin
= (const struct sockaddr_in
*)target_proto
;
1910 if (target_proto
->sa_family
== AF_INET
1911 && IN_LINKLOCAL(ntohl(target_sin
->sin_addr
.s_addr
))
1912 && ipv4_ll_arp_aware
!= 0
1913 && arpop
== ARPOP_REQUEST
1914 && !_is_announcement(target_sin
, sender_sin
)) {
1921 if (ifnet_list_get(IFNET_FAMILY_ANY
, &ifp_list
, &count
) == 0) {
1922 for (ifp_on
= 0; ifp_on
< count
; ifp_on
++) {
1924 ifaddr_t source_hw
= NULL
;
1925 ifaddr_t source_ip
= NULL
;
1926 struct sockaddr_in source_ip_copy
;
1929 * Only arp on interfaces marked for IPv4LL ARPing. This may
1930 * mean that we don't ARP on the interface the subnet route
1933 if ((ifp_list
[ifp_on
]->if_eflags
& IFEF_ARPLL
) == 0) {
1937 /* Find the source IP address */
1938 ifnet_lock_shared(ifp_list
[ifp_on
]);
1939 source_hw
= TAILQ_FIRST(&ifp_list
[ifp_on
]->if_addrhead
);
1940 TAILQ_FOREACH(source_ip
, &ifp_list
[ifp_on
]->if_addrhead
,
1942 if (source_ip
->ifa_addr
&&
1943 source_ip
->ifa_addr
->sa_family
== AF_INET
) {
1948 /* No IP Source, don't arp */
1949 if (source_ip
== NULL
) {
1950 ifnet_lock_done(ifp_list
[ifp_on
]);
1954 /* Copy the source IP address */
1955 source_ip_copy
= *(struct sockaddr_in
*)source_ip
->ifa_addr
;
1957 ifnet_lock_done(ifp_list
[ifp_on
]);
1960 new_result
= dlil_send_arp_internal(ifp_list
[ifp_on
], arpop
,
1961 (struct sockaddr_dl
*)source_hw
->ifa_addr
,
1962 (struct sockaddr
*)&source_ip_copy
, NULL
,
1966 if (result
== ENOTSUP
) {
1967 result
= new_result
;
1972 ifnet_list_free(ifp_list
);
1975 result
= dlil_send_arp_internal(ifp
, arpop
, sender_hw
, sender_proto
,
1976 target_hw
, target_proto
);
1982 __private_extern__
int
1991 old_value
= ifp
->if_usecnt
;
1992 if (old_value
== 0 && handle_zero
== kIfNetUseCount_MustNotBeZero
) {
1993 retval
= ENXIO
; // ifp is invalid
1996 } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)old_value
+ 1, (UInt32
*)&ifp
->if_usecnt
));
2001 /* ifp_unuse is broken into two pieces.
2003 * ifp_use and ifp_unuse must be called between when the caller calls
2004 * dlil_write_begin and dlil_write_end. ifp_unuse needs to perform some
2005 * operations after dlil_write_end has been called. For this reason,
2006 * anyone calling ifp_unuse must call ifp_use_reached_zero if ifp_unuse
2007 * returns a non-zero value. The caller must call ifp_use_reached_zero
2008 * after the caller has called dlil_write_end.
2010 __private_extern__
void
2011 ifp_use_reached_zero(
2014 ifnet_detached_func free_func
;
2018 if (ifp
->if_usecnt
!= 0)
2019 panic("ifp_use_reached_zero: ifp->if_usecnt != 0");
2021 ifnet_head_lock_exclusive();
2022 ifnet_lock_exclusive(ifp
);
2024 /* Remove ourselves from the list */
2025 TAILQ_REMOVE(&ifnet_head
, ifp
, if_link
);
2026 ifnet_addrs
[ifp
->if_index
- 1] = NULL
;
2028 /* ifp should be removed from the interface list */
2029 while (ifp
->if_multiaddrs
.lh_first
) {
2030 struct ifmultiaddr
*ifma
= ifp
->if_multiaddrs
.lh_first
;
2033 * When the interface is gone, we will no longer
2034 * be listening on these multicasts. Various bits
2035 * of the stack may be referencing these multicasts,
2036 * release only our reference.
2038 LIST_REMOVE(ifma
, ifma_link
);
2039 ifma
->ifma_ifp
= NULL
;
2043 ifp
->if_eflags
&= ~IFEF_DETACHING
; // clear the detaching flag
2044 ifnet_lock_done(ifp
);
2047 free_func
= ifp
->if_free
;
2049 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHED
, NULL
, 0);
2055 __private_extern__
int
2060 oldval
= OSDecrementAtomic(&ifp
->if_usecnt
);
2062 panic("ifp_unuse: ifp(%s%d)->if_usecnt was zero\n", ifp
->if_name
, ifp
->if_unit
);
2067 if ((ifp
->if_eflags
& IFEF_DETACHING
) == 0)
2068 panic("ifp_unuse: use count reached zero but detching flag is not set!");
2070 return 1; /* caller must call ifp_use_reached_zero */
2073 extern lck_mtx_t
*domain_proto_mtx
;
2076 dlil_attach_protocol_internal(
2077 struct if_proto
*proto
,
2078 const struct ifnet_demux_desc
*demux_list
,
2079 u_int32_t demux_count
)
2081 struct kev_dl_proto_data ev_pr_data
;
2082 struct ifnet
*ifp
= proto
->ifp
;
2084 u_int32_t hash_value
= proto_hash_value(proto
->protocol_family
);
2086 /* setup some of the common values */
2089 lck_mtx_lock(domain_proto_mtx
);
2091 while (dp
&& (protocol_family_t
)dp
->dom_family
!= proto
->protocol_family
)
2093 proto
->dl_domain
= dp
;
2094 lck_mtx_unlock(domain_proto_mtx
);
2098 * Take the write lock to protect readers and exclude other writers.
2100 if ((retval
= dlil_write_begin()) != 0) {
2101 printf("dlil_attach_protocol_internal - dlil_write_begin returned %d\n", retval
);
2105 /* Check that the interface isn't currently detaching */
2106 ifnet_lock_shared(ifp
);
2107 if ((ifp
->if_eflags
& IFEF_DETACHING
) != 0) {
2108 ifnet_lock_done(ifp
);
2112 ifnet_lock_done(ifp
);
2114 if (find_attached_proto(ifp
, proto
->protocol_family
) != NULL
) {
2120 * Call family module add_proto routine so it can refine the
2121 * demux descriptors as it wishes.
2123 retval
= ifp
->if_add_proto(ifp
, proto
->protocol_family
, demux_list
, demux_count
);
2130 * We can't fail from this point on.
2131 * Increment the number of uses (protocol attachments + interface attached).
2133 ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
);
2136 * Insert the protocol in the hash
2139 struct if_proto
* prev_proto
= SLIST_FIRST(&ifp
->if_proto_hash
[hash_value
]);
2140 while (prev_proto
&& SLIST_NEXT(prev_proto
, next_hash
) != NULL
)
2141 prev_proto
= SLIST_NEXT(prev_proto
, next_hash
);
2143 SLIST_INSERT_AFTER(prev_proto
, proto
, next_hash
);
2145 SLIST_INSERT_HEAD(&ifp
->if_proto_hash
[hash_value
], proto
, next_hash
);
2149 * Add to if_proto list for this interface
2151 if_proto_ref(proto
);
2154 /* the reserved field carries the number of protocol still attached (subject to change) */
2155 ev_pr_data
.proto_family
= proto
->protocol_family
;
2156 ev_pr_data
.proto_remaining_count
= dlil_ifp_proto_count(ifp
);
2157 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_ATTACHED
,
2158 (struct net_event_data
*)&ev_pr_data
,
2159 sizeof(struct kev_dl_proto_data
));
2161 DLIL_PRINTF("dlil. Attached protocol %d to %s%d - %d\n", proto
->protocol_family
,
2162 ifp
->if_name
, ifp
->if_unit
, retval
);
2168 ifnet_attach_protocol(ifnet_t ifp
, protocol_family_t protocol
,
2169 const struct ifnet_attach_proto_param
*proto_details
)
2172 struct if_proto
*ifproto
= NULL
;
2174 if (ifp
== NULL
|| protocol
== 0 || proto_details
== NULL
)
2177 ifproto
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
);
2179 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n");
2183 bzero(ifproto
, sizeof(*ifproto
));
2186 ifproto
->protocol_family
= protocol
;
2187 ifproto
->proto_kpi
= kProtoKPI_v1
;
2188 ifproto
->kpi
.v1
.input
= proto_details
->input
;
2189 ifproto
->kpi
.v1
.pre_output
= proto_details
->pre_output
;
2190 ifproto
->kpi
.v1
.event
= proto_details
->event
;
2191 ifproto
->kpi
.v1
.ioctl
= proto_details
->ioctl
;
2192 ifproto
->kpi
.v1
.detached
= proto_details
->detached
;
2193 ifproto
->kpi
.v1
.resolve_multi
= proto_details
->resolve
;
2194 ifproto
->kpi
.v1
.send_arp
= proto_details
->send_arp
;
2196 retval
= dlil_attach_protocol_internal(ifproto
,
2197 proto_details
->demux_list
, proto_details
->demux_count
);
2200 if (retval
&& ifproto
)
2201 FREE(ifproto
, M_IFADDR
);
2206 ifnet_attach_protocol_v2(ifnet_t ifp
, protocol_family_t protocol
,
2207 const struct ifnet_attach_proto_param_v2
*proto_details
)
2210 struct if_proto
*ifproto
= NULL
;
2212 if (ifp
== NULL
|| protocol
== 0 || proto_details
== NULL
)
2215 ifproto
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
);
2217 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n");
2221 bzero(ifproto
, sizeof(*ifproto
));
2224 ifproto
->protocol_family
= protocol
;
2225 ifproto
->proto_kpi
= kProtoKPI_v2
;
2226 ifproto
->kpi
.v2
.input
= proto_details
->input
;
2227 ifproto
->kpi
.v2
.pre_output
= proto_details
->pre_output
;
2228 ifproto
->kpi
.v2
.event
= proto_details
->event
;
2229 ifproto
->kpi
.v2
.ioctl
= proto_details
->ioctl
;
2230 ifproto
->kpi
.v2
.detached
= proto_details
->detached
;
2231 ifproto
->kpi
.v2
.resolve_multi
= proto_details
->resolve
;
2232 ifproto
->kpi
.v2
.send_arp
= proto_details
->send_arp
;
2234 retval
= dlil_attach_protocol_internal(ifproto
,
2235 proto_details
->demux_list
, proto_details
->demux_count
);
2238 if (retval
&& ifproto
)
2239 FREE(ifproto
, M_IFADDR
);
2243 extern void if_rtproto_del(struct ifnet
*ifp
, int protocol
);
2246 dlil_detach_protocol_internal(
2247 struct if_proto
*proto
)
2249 struct ifnet
*ifp
= proto
->ifp
;
2250 u_int32_t proto_family
= proto
->protocol_family
;
2251 struct kev_dl_proto_data ev_pr_data
;
2253 if (proto
->proto_kpi
== kProtoKPI_v1
) {
2254 if (proto
->kpi
.v1
.detached
)
2255 proto
->kpi
.v1
.detached(ifp
, proto
->protocol_family
);
2257 if (proto
->proto_kpi
== kProtoKPI_v2
) {
2258 if (proto
->kpi
.v2
.detached
)
2259 proto
->kpi
.v2
.detached(ifp
, proto
->protocol_family
);
2261 if_proto_free(proto
);
2264 * Cleanup routes that may still be in the routing table for that interface/protocol pair.
2267 if_rtproto_del(ifp
, proto_family
);
2269 /* the reserved field carries the number of protocol still attached (subject to change) */
2270 ev_pr_data
.proto_family
= proto_family
;
2271 ev_pr_data
.proto_remaining_count
= dlil_ifp_proto_count(ifp
);
2272 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_DETACHED
,
2273 (struct net_event_data
*)&ev_pr_data
,
2274 sizeof(struct kev_dl_proto_data
));
2279 ifnet_detach_protocol(ifnet_t ifp
, protocol_family_t proto_family
)
2281 struct if_proto
*proto
= NULL
;
2283 int use_reached_zero
= 0;
2285 if (ifp
== NULL
|| proto_family
== 0) return EINVAL
;
2287 if ((retval
= dlil_write_begin()) != 0) {
2288 if (retval
== EDEADLK
) {
2291 proto
= find_attached_proto(ifp
, proto_family
);
2296 proto
->detaching
= 1;
2297 dlil_detach_waiting
= 1;
2298 wakeup(&dlil_detach_waiting
);
2305 proto
= find_attached_proto(ifp
, proto_family
);
2307 if (proto
== NULL
) {
2314 * Call family module del_proto
2317 if (ifp
->if_del_proto
)
2318 ifp
->if_del_proto(ifp
, proto
->protocol_family
);
2320 SLIST_REMOVE(&ifp
->if_proto_hash
[proto_hash_value(proto_family
)], proto
, if_proto
, next_hash
);
2323 * We can do the rest of the work outside of the write lock.
2325 use_reached_zero
= ifp_unuse(ifp
);
2328 dlil_detach_protocol_internal(proto
);
2331 * Only handle the case where the interface will go away after
2332 * we've sent the message. This way post message can send the
2333 * message to the interface safely.
2336 if (use_reached_zero
)
2337 ifp_use_reached_zero(ifp
);
2344 * dlil_delayed_detach_thread is responsible for detaching
2345 * protocols, protocol filters, and interface filters after
2346 * an attempt was made to detach one of those items while
2347 * it was not safe to do so (i.e. called dlil_read_begin).
2349 * This function will take the dlil write lock and walk
2350 * through each of the interfaces looking for items with
2351 * the detaching flag set. When an item is found, it is
2352 * detached from the interface and placed on a local list.
2353 * After all of the items have been collected, we drop the
2354 * write lock and performed the post detach. This is done
2355 * so we only have to take the write lock once.
2357 * When detaching a protocol filter, if we find that we
2358 * have detached the very last protocol and we need to call
2359 * ifp_use_reached_zero, we have to break out of our work
2360 * to drop the write lock so we can call ifp_use_reached_zero.
2364 dlil_delayed_detach_thread(__unused
void* foo
, __unused wait_result_t wait
)
2366 thread_t self
= current_thread();
2369 ml_thread_policy(self
, MACHINE_GROUP
,
2370 (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
));
2374 if (dlil_detach_waiting
!= 0 && dlil_write_begin() == 0) {
2376 struct proto_hash_entry detached_protos
;
2377 struct ifnet_filter_head detached_filters
;
2378 struct if_proto
*proto
;
2379 struct if_proto
*next_proto
;
2380 struct ifnet_filter
*filt
;
2381 struct ifnet_filter
*next_filt
;
2386 /* Clear the detach waiting flag */
2387 dlil_detach_waiting
= 0;
2388 TAILQ_INIT(&detached_filters
);
2389 SLIST_INIT(&detached_protos
);
2391 ifnet_head_lock_shared();
2392 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2395 // Look for protocols and protocol filters
2396 for (i
= 0; i
< PROTO_HASH_SLOTS
&& !reached_zero
; i
++) {
2397 struct if_proto
**prev_nextptr
= &SLIST_FIRST(&ifp
->if_proto_hash
[i
]);
2398 for (proto
= *prev_nextptr
; proto
; proto
= *prev_nextptr
) {
2400 // Detach this protocol
2401 if (proto
->detaching
) {
2402 if (ifp
->if_del_proto
)
2403 ifp
->if_del_proto(ifp
, proto
->protocol_family
);
2404 *prev_nextptr
= SLIST_NEXT(proto
, next_hash
);
2405 SLIST_INSERT_HEAD(&detached_protos
, proto
, next_hash
);
2406 reached_zero
= ifp_unuse(ifp
);
2412 // Update prev_nextptr to point to our next ptr
2413 prev_nextptr
= &SLIST_NEXT(proto
, next_hash
);
2418 // look for interface filters that need to be detached
2419 for (filt
= TAILQ_FIRST(&ifp
->if_flt_head
); filt
; filt
= next_filt
) {
2420 next_filt
= TAILQ_NEXT(filt
, filt_next
);
2421 if (filt
->filt_detaching
!= 0) {
2422 // take this interface filter off the interface filter list
2423 TAILQ_REMOVE(&ifp
->if_flt_head
, filt
, filt_next
);
2425 // put this interface filter on the detached filters list
2426 TAILQ_INSERT_TAIL(&detached_filters
, filt
, filt_next
);
2430 if (ifp
->if_delayed_detach
) {
2431 ifp
->if_delayed_detach
= 0;
2432 reached_zero
= ifp_unuse(ifp
);
2441 for (filt
= TAILQ_FIRST(&detached_filters
); filt
; filt
= next_filt
) {
2442 next_filt
= TAILQ_NEXT(filt
, filt_next
);
2444 * dlil_detach_filter_internal won't remove an item from
2445 * the list if it is already detached (second parameter).
2446 * The item will be freed though.
2448 dlil_detach_filter_internal(filt
, 1);
2451 for (proto
= SLIST_FIRST(&detached_protos
); proto
; proto
= next_proto
) {
2452 next_proto
= SLIST_NEXT(proto
, next_hash
);
2453 dlil_detach_protocol_internal(proto
);
2457 ifp_use_reached_zero(ifp
);
2458 dlil_detach_waiting
= 1; // we may have missed something
2462 if (!asserted
&& dlil_detach_waiting
== 0) {
2464 assert_wait(&dlil_detach_waiting
, THREAD_UNINT
);
2467 if (dlil_detach_waiting
== 0) {
2469 thread_block(dlil_delayed_detach_thread
);
2475 dlil_call_delayed_detach_thread(void) {
2476 dlil_delayed_detach_thread(NULL
, THREAD_RESTART
);
2479 extern int if_next_index(void);
2484 const struct sockaddr_dl
*ll_addr
)
2486 u_int32_t interface_family
;
2487 struct ifnet
*tmp_if
;
2488 struct proto_hash_entry
*new_proto_list
= NULL
;
2491 if (ifp
== NULL
) return EINVAL
;
2492 if (ll_addr
&& ifp
->if_addrlen
== 0) {
2493 ifp
->if_addrlen
= ll_addr
->sdl_alen
;
2495 else if (ll_addr
&& ll_addr
->sdl_alen
!= ifp
->if_addrlen
) {
2499 interface_family
= ifp
->if_family
;
2501 ifnet_head_lock_shared();
2503 /* Verify we aren't already on the list */
2504 TAILQ_FOREACH(tmp_if
, &ifnet_head
, if_link
) {
2505 if (tmp_if
== ifp
) {
2513 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_lock
== 0)
2515 ifp
->if_lock
= lck_rw_alloc_init(ifnet_lock_group
, ifnet_lock_attr
);
2517 ifp
->if_lock
= lck_mtx_alloc_init(ifnet_lock_group
, ifnet_lock_attr
);
2520 if (ifp
->if_lock
== 0) {
2524 if (!(ifp
->if_eflags
& IFEF_REUSE
) || ifp
->if_fwd_route_lock
== NULL
) {
2525 if (ifp
->if_fwd_route_lock
== NULL
)
2526 ifp
->if_fwd_route_lock
= lck_mtx_alloc_init(
2527 ifnet_lock_group
, ifnet_lock_attr
);
2529 if (ifp
->if_fwd_route_lock
== NULL
) {
2531 lck_rw_free(ifp
->if_lock
, ifnet_lock_group
);
2533 lck_mtx_free(ifp
->if_lock
, ifnet_lock_group
);
2535 ifp
->if_lock
= NULL
;
2541 * Allow interfaces without protocol families to attach
2542 * only if they have the necessary fields filled out.
2545 if (ifp
->if_add_proto
== 0 || ifp
->if_del_proto
== 0) {
2546 DLIL_PRINTF("dlil Attempt to attach interface without family module - %d\n",
2551 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_proto_hash
== NULL
) {
2552 MALLOC(new_proto_list
, struct proto_hash_entry
*, sizeof(struct proto_hash_entry
) * PROTO_HASH_SLOTS
,
2555 if (new_proto_list
== 0) {
2563 TAILQ_INIT(&ifp
->if_flt_head
);
2566 if (new_proto_list
) {
2567 bzero(new_proto_list
, (PROTO_HASH_SLOTS
* sizeof(struct proto_hash_entry
)));
2568 ifp
->if_proto_hash
= new_proto_list
;
2569 new_proto_list
= NULL
;
2575 int namelen
, masklen
, socksize
, ifasize
;
2576 struct ifaddr
*ifa
= NULL
;
2578 if (ifp
->if_snd
.ifq_maxlen
== 0)
2579 ifp
->if_snd
.ifq_maxlen
= ifqmaxlen
;
2580 TAILQ_INIT(&ifp
->if_prefixhead
);
2581 LIST_INIT(&ifp
->if_multiaddrs
);
2582 ifnet_touch_lastchange(ifp
);
2584 /* usecount to track attachment to the ifnet list */
2585 ifp_use(ifp
, kIfNetUseCount_MayBeZero
);
2587 /* Lock the list of interfaces */
2588 ifnet_head_lock_exclusive();
2589 ifnet_lock_exclusive(ifp
);
2591 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_index
== 0) {
2592 int idx
= if_next_index();
2595 ifnet_lock_done(ifp
);
2602 ifp
->if_index
= idx
;
2604 ifa
= TAILQ_FIRST(&ifp
->if_addrhead
);
2606 namelen
= snprintf(workbuf
, sizeof(workbuf
), "%s%d", ifp
->if_name
, ifp
->if_unit
);
2607 #define _offsetof(t, m) ((uintptr_t)((caddr_t)&((t *)0)->m))
2608 masklen
= _offsetof(struct sockaddr_dl
, sdl_data
[0]) + namelen
;
2609 socksize
= masklen
+ ifp
->if_addrlen
;
2610 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(u_int32_t) - 1)))
2611 if ((u_int32_t
)socksize
< sizeof(struct sockaddr_dl
))
2612 socksize
= sizeof(struct sockaddr_dl
);
2613 socksize
= ROUNDUP(socksize
);
2614 ifasize
= sizeof(struct ifaddr
) + 2 * socksize
;
2617 * Allocate a new ifa if we don't have one
2618 * or the old one is too small.
2620 if (ifa
== NULL
|| socksize
> ifa
->ifa_addr
->sa_len
) {
2622 if_detach_ifa(ifp
, ifa
);
2623 ifa
= (struct ifaddr
*)_MALLOC(ifasize
, M_IFADDR
, M_WAITOK
);
2627 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)(ifa
+ 1);
2628 ifnet_addrs
[ifp
->if_index
- 1] = ifa
;
2629 bzero(ifa
, ifasize
);
2630 ifa
->ifa_debug
|= IFD_ALLOC
;
2631 sdl
->sdl_len
= socksize
;
2632 sdl
->sdl_family
= AF_LINK
;
2633 bcopy(workbuf
, sdl
->sdl_data
, namelen
);
2634 sdl
->sdl_nlen
= namelen
;
2635 sdl
->sdl_index
= ifp
->if_index
;
2636 sdl
->sdl_type
= ifp
->if_type
;
2638 sdl
->sdl_alen
= ll_addr
->sdl_alen
;
2639 if (ll_addr
->sdl_alen
!= ifp
->if_addrlen
)
2640 panic("ifnet_attach - ll_addr->sdl_alen != ifp->if_addrlen");
2641 bcopy(CONST_LLADDR(ll_addr
), LLADDR(sdl
), sdl
->sdl_alen
);
2644 ifa
->ifa_rtrequest
= link_rtrequest
;
2645 ifa
->ifa_addr
= (struct sockaddr
*)sdl
;
2646 sdl
= (struct sockaddr_dl
*)(socksize
+ (caddr_t
)sdl
);
2647 ifa
->ifa_netmask
= (struct sockaddr
*)sdl
;
2648 sdl
->sdl_len
= masklen
;
2649 while (namelen
!= 0)
2650 sdl
->sdl_data
[--namelen
] = 0xff;
2653 TAILQ_INIT(&ifp
->if_addrhead
);
2654 ifa
= ifnet_addrs
[ifp
->if_index
- 1];
2658 * We don't use if_attach_ifa because we want
2659 * this address to be first on the list.
2662 ifa
->ifa_debug
|= IFD_ATTACHED
;
2663 TAILQ_INSERT_HEAD(&ifp
->if_addrhead
, ifa
, ifa_link
);
2666 mac_ifnet_label_associate(ifp
);
2669 TAILQ_INSERT_TAIL(&ifnet_head
, ifp
, if_link
);
2670 ifindex2ifnet
[ifp
->if_index
] = ifp
;
2674 * A specific dlil input thread is created per Ethernet/PDP interface.
2675 * pseudo interfaces or other types of interfaces use the main ("loopback") thread.
2676 * If the sysctl "net.link.generic.system.multi_threaded_input" is set to zero, all packets will
2677 * be handled by the main loopback thread, reverting to 10.4.x behaviour.
2681 if (ifp
->if_type
== IFT_ETHER
|| ifp
->if_type
== IFT_PDP
) {
2684 if (dlil_multithreaded_input
> 0) {
2685 ifp
->if_input_thread
= _MALLOC(sizeof(struct dlil_threading_info
), M_NKE
, M_WAITOK
);
2686 if (ifp
->if_input_thread
== NULL
)
2687 panic("ifnet_attach ifp=%p couldn't alloc threading\n", ifp
);
2688 if ((err
= dlil_create_input_thread(ifp
, ifp
->if_input_thread
)) != 0)
2689 panic("ifnet_attach ifp=%p couldn't get a thread. err=%d\n", ifp
, err
);
2691 printf("ifnet_attach: dlil thread for ifp=%p if_index=%d\n", ifp
, ifp
->if_index
);
2695 ifnet_lock_done(ifp
);
2699 * Attach packet filter to this interface, if enaled.
2701 pf_ifnet_hook(ifp
, 1);
2705 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_ATTACHED
, NULL
, 0);
2714 struct ifnet_filter
*filter
;
2715 struct ifnet_filter
*filter_next
;
2718 struct ifnet_filter_head fhead
;
2719 struct dlil_threading_info
*inputthread
;
2721 if (ifp
== NULL
) return EINVAL
;
2723 ifnet_lock_exclusive(ifp
);
2725 if ((ifp
->if_eflags
& IFEF_DETACHING
) != 0) {
2726 /* Interface has already been detached */
2727 ifnet_lock_done(ifp
);
2732 * Indicate this interface is being detached.
2734 * This should prevent protocols from attaching
2735 * from this point on. Interface will remain on
2736 * the list until all of the protocols are detached.
2738 ifp
->if_eflags
|= IFEF_DETACHING
;
2739 ifnet_lock_done(ifp
);
2741 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHING
, NULL
, 0);
2743 /* Let BPF know we're detaching */
2746 if ((retval
= dlil_write_begin()) != 0) {
2747 if (retval
== EDEADLK
) {
2750 /* We need to perform a delayed detach */
2751 ifp
->if_delayed_detach
= 1;
2752 dlil_detach_waiting
= 1;
2753 wakeup(&dlil_detach_waiting
);
2760 * Detach this interface from packet filter, if enabled.
2762 pf_ifnet_hook(ifp
, 0);
2765 /* Steal the list of interface filters */
2766 fhead
= ifp
->if_flt_head
;
2767 TAILQ_INIT(&ifp
->if_flt_head
);
2769 /* unuse the interface */
2770 zeroed
= ifp_unuse(ifp
);
2773 * If thread affinity was set for the workloop thread, we will need
2774 * to tear down the affinity and release the extra reference count
2775 * taken at attach time;
2777 if ((inputthread
= ifp
->if_input_thread
) != NULL
) {
2778 if (inputthread
->net_affinity
) {
2781 if (inputthread
== dlil_lo_thread_ptr
)
2782 panic("Thread affinity should not be enabled "
2783 "on the loopback dlil input thread\n");
2785 lck_mtx_lock(inputthread
->input_lck
);
2786 tp
= inputthread
->workloop_thread
;
2787 inputthread
->workloop_thread
= NULL
;
2788 inputthread
->tag
= 0;
2789 inputthread
->net_affinity
= FALSE
;
2790 lck_mtx_unlock(inputthread
->input_lck
);
2792 /* Tear down workloop thread affinity */
2794 (void) dlil_affinity_set(tp
,
2795 THREAD_AFFINITY_TAG_NULL
);
2796 thread_deallocate(tp
);
2799 /* Tear down dlil input thread affinity */
2800 tp
= inputthread
->input_thread
;
2801 (void) dlil_affinity_set(tp
, THREAD_AFFINITY_TAG_NULL
);
2802 thread_deallocate(tp
);
2805 /* cleanup ifp dlil input thread, if any */
2806 ifp
->if_input_thread
= NULL
;
2808 if (inputthread
!= dlil_lo_thread_ptr
) {
2810 printf("ifnet_detach: wakeup thread threadinfo: %p "
2811 "input_thread=%p threads: cur=%d max=%d\n",
2812 inputthread
, inputthread
->input_thread
,
2813 dlil_multithreaded_input
, cur_dlil_input_threads
);
2815 lck_mtx_lock(inputthread
->input_lck
);
2817 inputthread
->input_waiting
|= DLIL_INPUT_TERMINATE
;
2818 if ((inputthread
->input_waiting
& DLIL_INPUT_RUNNING
) == 0) {
2819 wakeup((caddr_t
)&inputthread
->input_waiting
);
2821 lck_mtx_unlock(inputthread
->input_lck
);
2824 /* last chance to clean up IPv4 forwarding cached route */
2825 lck_mtx_lock(ifp
->if_fwd_route_lock
);
2826 if (ifp
->if_fwd_route
.ro_rt
!= NULL
) {
2827 rtfree(ifp
->if_fwd_route
.ro_rt
);
2828 ifp
->if_fwd_route
.ro_rt
= NULL
;
2830 lck_mtx_unlock(ifp
->if_fwd_route_lock
);
2833 for (filter
= TAILQ_FIRST(&fhead
); filter
; filter
= filter_next
) {
2834 filter_next
= TAILQ_NEXT(filter
, filt_next
);
2835 dlil_detach_filter_internal(filter
, 1);
2839 ifp_use_reached_zero(ifp
);
2847 __unused ifnet_t ifnet_ptr
,
2848 __unused u_long ioctl_code
,
2849 __unused
void *ioctl_arg
)
2855 dlil_recycle_output(
2856 __unused
struct ifnet
*ifnet_ptr
,
2865 __unused ifnet_t ifnet_ptr
)
2870 dlil_recycle_set_bpf_tap(
2871 __unused ifnet_t ifp
,
2872 __unused bpf_tap_mode mode
,
2873 __unused bpf_packet_func callback
)
2875 /* XXX not sure what to do here */
2880 int dlil_if_acquire(
2882 const void *uniqueid
,
2883 size_t uniqueid_len
,
2886 struct ifnet
*ifp1
= NULL
;
2887 struct dlil_ifnet
*dlifp1
= NULL
;
2890 lck_mtx_lock(dlil_ifnet_mutex
);
2891 TAILQ_FOREACH(dlifp1
, &dlil_ifnet_head
, dl_if_link
) {
2893 ifp1
= (struct ifnet
*)dlifp1
;
2895 if (ifp1
->if_family
== family
) {
2897 /* same uniqueid and same len or no unique id specified */
2898 if ((uniqueid_len
== dlifp1
->if_uniqueid_len
)
2899 && !bcmp(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
)) {
2901 /* check for matching interface in use */
2902 if (ifp1
->if_eflags
& IFEF_INUSE
) {
2910 panic("ifp's lock is gone\n");
2911 ifnet_lock_exclusive(ifp1
);
2912 ifp1
->if_eflags
|= (IFEF_INUSE
| IFEF_REUSE
);
2913 ifnet_lock_done(ifp1
);
2921 /* no interface found, allocate a new one */
2922 MALLOC(dlifp1
, struct dlil_ifnet
*, sizeof(*dlifp1
), M_NKE
, M_WAITOK
);
2928 bzero(dlifp1
, sizeof(*dlifp1
));
2931 MALLOC(dlifp1
->if_uniqueid
, void *, uniqueid_len
, M_NKE
, M_WAITOK
);
2932 if (dlifp1
->if_uniqueid
== 0) {
2933 FREE(dlifp1
, M_NKE
);
2937 bcopy(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
);
2938 dlifp1
->if_uniqueid_len
= uniqueid_len
;
2941 ifp1
= (struct ifnet
*)dlifp1
;
2942 ifp1
->if_eflags
|= IFEF_INUSE
;
2943 ifp1
->if_name
= dlifp1
->if_namestorage
;
2945 mac_ifnet_label_init(ifp1
);
2948 TAILQ_INSERT_TAIL(&dlil_ifnet_head
, dlifp1
, dl_if_link
);
2953 lck_mtx_unlock(dlil_ifnet_mutex
);
2958 __private_extern__
void
2962 struct dlil_ifnet
*dlifp
= (struct dlil_ifnet
*)ifp
;
2964 /* Interface does not have a lock until it is attached - radar 3713951 */
2966 ifnet_lock_exclusive(ifp
);
2967 ifp
->if_eflags
&= ~IFEF_INUSE
;
2968 ifp
->if_ioctl
= dlil_recycle_ioctl
;
2969 ifp
->if_output
= dlil_recycle_output
;
2970 ifp
->if_free
= dlil_recycle_free
;
2971 ifp
->if_set_bpf_tap
= dlil_recycle_set_bpf_tap
;
2973 strncpy(dlifp
->if_namestorage
, ifp
->if_name
, IFNAMSIZ
);
2974 ifp
->if_name
= dlifp
->if_namestorage
;
2977 * We can either recycle the MAC label here or in dlil_if_acquire().
2978 * It seems logical to do it here but this means that anything that
2979 * still has a handle on ifp will now see it as unlabeled.
2980 * Since the interface is "dead" that may be OK. Revisit later.
2982 mac_ifnet_label_recycle(ifp
);
2985 ifnet_lock_done(ifp
);
2989 __private_extern__
void
2990 dlil_proto_unplumb_all(struct ifnet
*ifp
)
2993 * if_proto_hash[0-3] are for PF_INET, PF_INET6, PF_APPLETALK
2994 * and PF_VLAN, where each bucket contains exactly one entry;
2995 * PF_VLAN does not need an explicit unplumb.
2997 * if_proto_hash[4] is for other protocols; we expect anything
2998 * in this bucket to respond to the DETACHING event (which would
2999 * have happened by now) and do the unplumb then.
3001 (void) proto_unplumb(PF_INET
, ifp
);
3003 (void) proto_unplumb(PF_INET6
, ifp
);
3006 (void) proto_unplumb(PF_APPLETALK
, ifp
);