2 * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Data Link Inteface Layer
33 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
34 * support for mandatory and extensible security protections. This notice
35 * is included in support of clause 2.2 (b) of the Apple Public License,
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/malloc.h>
44 #include <sys/socket.h>
45 #include <sys/domain.h>
47 #include <sys/random.h>
48 #include <net/if_dl.h>
50 #include <net/route.h>
51 #include <net/if_var.h>
53 #include <net/if_arp.h>
54 #include <sys/kern_event.h>
55 #include <sys/kdebug.h>
57 #include <kern/assert.h>
58 #include <kern/task.h>
59 #include <kern/thread.h>
60 #include <kern/sched_prim.h>
61 #include <kern/locks.h>
62 #include <net/kpi_protocol.h>
64 #include <net/if_types.h>
65 #include <net/kpi_interfacefilter.h>
67 #include <libkern/OSAtomic.h>
69 #include <machine/machine_routines.h>
71 #include <mach/thread_act.h>
74 #include <security/mac_framework.h>
77 #define DBG_LAYER_BEG DLILDBG_CODE(DBG_DLIL_STATIC, 0)
78 #define DBG_LAYER_END DLILDBG_CODE(DBG_DLIL_STATIC, 2)
79 #define DBG_FNC_DLIL_INPUT DLILDBG_CODE(DBG_DLIL_STATIC, (1 << 8))
80 #define DBG_FNC_DLIL_OUTPUT DLILDBG_CODE(DBG_DLIL_STATIC, (2 << 8))
81 #define DBG_FNC_DLIL_IFOUT DLILDBG_CODE(DBG_DLIL_STATIC, (3 << 8))
84 #define MAX_FRAME_TYPE_SIZE 4 /* LONGWORDS */
85 #define MAX_LINKADDR 4 /* LONGWORDS */
86 #define M_NKE M_IFADDR
89 #define DLIL_PRINTF printf
91 #define DLIL_PRINTF kprintf
101 SLIST_ENTRY(if_proto
) next_hash
;
105 struct domain
*dl_domain
;
106 protocol_family_t protocol_family
;
110 proto_media_input input
;
111 proto_media_preout pre_output
;
112 proto_media_event event
;
113 proto_media_ioctl ioctl
;
114 proto_media_detached detached
;
115 proto_media_resolve_multi resolve_multi
;
116 proto_media_send_arp send_arp
;
119 proto_media_input_v2 input
;
120 proto_media_preout pre_output
;
121 proto_media_event event
;
122 proto_media_ioctl ioctl
;
123 proto_media_detached detached
;
124 proto_media_resolve_multi resolve_multi
;
125 proto_media_send_arp send_arp
;
130 SLIST_HEAD(proto_hash_entry
, if_proto
);
134 /* ifnet and drvr_ext are used by the stack and drivers
135 drvr_ext extends the public ifnet and must follow dl_if */
136 struct ifnet dl_if
; /* public ifnet */
138 /* dlil private fields */
139 TAILQ_ENTRY(dlil_ifnet
) dl_if_link
; /* dlil_ifnet are link together */
140 /* it is not the ifnet list */
141 void *if_uniqueid
; /* unique id identifying the interface */
142 size_t if_uniqueid_len
;/* length of the unique id */
143 char if_namestorage
[IFNAMSIZ
]; /* interface name storage */
146 struct ifnet_filter
{
147 TAILQ_ENTRY(ifnet_filter
) filt_next
;
151 const char *filt_name
;
153 protocol_family_t filt_protocol
;
154 iff_input_func filt_input
;
155 iff_output_func filt_output
;
156 iff_event_func filt_event
;
157 iff_ioctl_func filt_ioctl
;
158 iff_detached_func filt_detached
;
161 struct proto_input_entry
;
163 static TAILQ_HEAD(, dlil_ifnet
) dlil_ifnet_head
;
164 static lck_grp_t
*dlil_lock_group
;
165 static lck_grp_t
*ifnet_lock_group
;
166 static lck_grp_t
*ifnet_head_lock_group
;
167 static lck_attr_t
*ifnet_lock_attr
;
168 static lck_rw_t
*ifnet_head_mutex
;
169 static lck_mtx_t
*dlil_ifnet_mutex
;
170 static lck_mtx_t
*dlil_mutex
;
171 static unsigned long dlil_read_count
= 0;
172 static unsigned long dlil_detach_waiting
= 0;
173 extern u_int32_t ipv4_ll_arp_aware
;
175 static struct dlil_threading_info dlil_lo_thread
;
176 __private_extern__
struct dlil_threading_info
*dlil_lo_thread_ptr
= &dlil_lo_thread
;
178 static struct mbuf
*dlil_lo_input_mbuf_head
= NULL
;
179 static struct mbuf
*dlil_lo_input_mbuf_tail
= NULL
;
181 #if IFNET_INPUT_SANITY_CHK
182 static int dlil_lo_input_mbuf_count
= 0;
183 int dlil_input_sanity_check
= 0; /* sanity checking of input packet lists received */
185 int dlil_multithreaded_input
= 1;
186 static int cur_dlil_input_threads
= 0;
188 static int dlil_event_internal(struct ifnet
*ifp
, struct kev_msg
*msg
);
189 static int dlil_detach_filter_internal(interface_filter_t filter
, int detached
);
190 static void dlil_call_delayed_detach_thread(void);
192 static void dlil_read_begin(void);
193 static __inline__
void dlil_read_end(void);
194 static int dlil_write_begin(void);
195 static void dlil_write_end(void);
197 unsigned int net_affinity
= 1;
198 static kern_return_t
dlil_affinity_set(struct thread
*, u_int32_t
);
200 extern void bpfdetach(struct ifnet
*);
201 extern void proto_input_run(void); // new run_netisr
203 void dlil_input_packet_list(struct ifnet
*ifp
, struct mbuf
*m
);
204 static void dlil_input_thread_func(struct dlil_threading_info
*inpthread
);
205 __private_extern__
int dlil_create_input_thread(
206 ifnet_t
, struct dlil_threading_info
*);
207 __private_extern__
void dlil_terminate_input_thread(
208 struct dlil_threading_info
*);
210 __private_extern__
void link_rtrequest(int, struct rtentry
*, struct sockaddr
*);
214 extern u_int32_t inject_buckets
;
216 static const u_int32_t dlil_writer_waiting
= 0x80000000;
217 static lck_grp_attr_t
*dlil_grp_attributes
= NULL
;
218 static lck_attr_t
*dlil_lck_attributes
= NULL
;
219 static lck_grp_t
*dlil_input_lock_grp
= NULL
;
222 _cast_non_const(const void * ptr
) {
232 /* Should these be inline? */
234 dlil_read_begin(void)
236 unsigned long new_value
;
237 unsigned long old_value
;
238 struct uthread
*uth
= get_bsdthread_info(current_thread());
240 if (uth
->dlil_incremented_read
== dlil_writer_waiting
)
241 panic("dlil_read_begin - thread is already a writer");
245 old_value
= dlil_read_count
;
247 if ((old_value
& dlil_writer_waiting
) != 0 && uth
->dlil_incremented_read
== 0)
249 tsleep(&dlil_read_count
, PRIBIO
, "dlil_read_count", 1);
253 new_value
= old_value
+ 1;
254 } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)new_value
, (UInt32
*)&dlil_read_count
));
256 uth
->dlil_incremented_read
++;
262 struct uthread
*uth
= get_bsdthread_info(current_thread());
264 OSDecrementAtomic((SInt32
*)&dlil_read_count
);
265 uth
->dlil_incremented_read
--;
266 if (dlil_read_count
== dlil_writer_waiting
)
267 wakeup(_cast_non_const(&dlil_writer_waiting
));
271 dlil_write_begin(void)
273 struct uthread
*uth
= get_bsdthread_info(current_thread());
275 if (uth
->dlil_incremented_read
!= 0) {
278 lck_mtx_lock(dlil_mutex
);
279 OSBitOrAtomic((UInt32
)dlil_writer_waiting
, (UInt32
*)&dlil_read_count
);
281 if (dlil_read_count
== dlil_writer_waiting
) {
282 uth
->dlil_incremented_read
= dlil_writer_waiting
;
286 tsleep(_cast_non_const(&dlil_writer_waiting
), PRIBIO
, "dlil_writer_waiting", 1);
294 struct uthread
*uth
= get_bsdthread_info(current_thread());
296 if (uth
->dlil_incremented_read
!= dlil_writer_waiting
)
297 panic("dlil_write_end - thread is not a writer");
298 OSBitAndAtomic((UInt32
)~dlil_writer_waiting
, (UInt32
*)&dlil_read_count
);
299 lck_mtx_unlock(dlil_mutex
);
300 uth
->dlil_incremented_read
= 0;
301 wakeup(&dlil_read_count
);
304 #define PROTO_HASH_SLOTS 0x5
307 * Internal functions.
311 proto_hash_value(u_long protocol_family
)
313 switch(protocol_family
) {
327 static struct if_proto
*
328 find_attached_proto(struct ifnet
*ifp
, u_long protocol_family
)
330 struct if_proto
*proto
= NULL
;
331 u_long i
= proto_hash_value(protocol_family
);
332 if (ifp
->if_proto_hash
) {
333 proto
= SLIST_FIRST(&ifp
->if_proto_hash
[i
]);
336 while(proto
&& proto
->protocol_family
!= protocol_family
) {
337 proto
= SLIST_NEXT(proto
, next_hash
);
344 if_proto_ref(struct if_proto
*proto
)
346 OSAddAtomic(1, (SInt32
*)&proto
->refcount
);
350 if_proto_free(struct if_proto
*proto
)
352 int oldval
= OSAddAtomic(-1, (SInt32
*)&proto
->refcount
);
354 if (oldval
== 1) { /* This was the last reference */
355 FREE(proto
, M_IFADDR
);
359 __private_extern__
void
361 __unused
struct ifnet
*ifp
,
366 * Not implemented for rw locks.
368 * Function exists so when/if we use mutex we can
372 lck_mtx_assert(ifp
->if_lock
, what
);
376 __private_extern__
void
381 lck_rw_lock_shared(ifp
->if_lock
);
383 lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_NOTOWNED
);
384 lck_mtx_lock(ifp
->if_lock
);
388 __private_extern__
void
389 ifnet_lock_exclusive(
393 lck_rw_lock_exclusive(ifp
->if_lock
);
395 lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_NOTOWNED
);
396 lck_mtx_lock(ifp
->if_lock
);
400 __private_extern__
void
405 lck_rw_done(ifp
->if_lock
);
407 lck_mtx_assert(ifp
->if_lock
, LCK_MTX_ASSERT_OWNED
);
408 lck_mtx_unlock(ifp
->if_lock
);
412 __private_extern__
void
413 ifnet_head_lock_shared(void)
415 lck_rw_lock_shared(ifnet_head_mutex
);
418 __private_extern__
void
419 ifnet_head_lock_exclusive(void)
421 lck_rw_lock_exclusive(ifnet_head_mutex
);
424 __private_extern__
void
425 ifnet_head_done(void)
427 lck_rw_done(ifnet_head_mutex
);
430 static int dlil_ifp_proto_count(struct ifnet
* ifp
)
435 if (ifp
->if_proto_hash
!= NULL
) {
436 for (i
= 0; i
< PROTO_HASH_SLOTS
; i
++) {
437 struct if_proto
*proto
;
438 SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) {
447 __private_extern__
void
448 dlil_post_msg(struct ifnet
*ifp
, u_long event_subclass
, u_long event_code
,
449 struct net_event_data
*event_data
, u_long event_data_len
)
451 struct net_event_data ev_data
;
452 struct kev_msg ev_msg
;
455 * a net event always starts with a net_event_data structure
456 * but the caller can generate a simple net event or
457 * provide a longer event structure to post
460 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
461 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
462 ev_msg
.kev_subclass
= event_subclass
;
463 ev_msg
.event_code
= event_code
;
465 if (event_data
== 0) {
466 event_data
= &ev_data
;
467 event_data_len
= sizeof(struct net_event_data
);
470 strncpy(&event_data
->if_name
[0], ifp
->if_name
, IFNAMSIZ
);
471 event_data
->if_family
= ifp
->if_family
;
472 event_data
->if_unit
= (unsigned long) ifp
->if_unit
;
474 ev_msg
.dv
[0].data_length
= event_data_len
;
475 ev_msg
.dv
[0].data_ptr
= event_data
;
476 ev_msg
.dv
[1].data_length
= 0;
478 dlil_event_internal(ifp
, &ev_msg
);
481 __private_extern__
int
482 dlil_create_input_thread(
483 ifnet_t ifp
, struct dlil_threading_info
*inputthread
)
487 bzero(inputthread
, sizeof(*inputthread
));
488 // loopback ifp may not be configured at dlil_init time.
490 strlcat(inputthread
->input_name
, "dlil_input_main_thread_mtx", 32);
492 snprintf(inputthread
->input_name
, 32, "dlil_input_%s%d_mtx", ifp
->if_name
, ifp
->if_unit
);
494 inputthread
->lck_grp
= lck_grp_alloc_init(inputthread
->input_name
, dlil_grp_attributes
);
495 inputthread
->input_lck
= lck_mtx_alloc_init(inputthread
->lck_grp
, dlil_lck_attributes
);
497 error
= kernel_thread_start((thread_continue_t
)dlil_input_thread_func
, inputthread
, &inputthread
->input_thread
);
499 ml_thread_policy(inputthread
->input_thread
, MACHINE_GROUP
,
500 (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
));
502 * Except for the loopback dlil input thread, we create
503 * an affinity set so that the matching workloop thread
504 * can be scheduled on the same processor set.
506 if (net_affinity
&& inputthread
!= dlil_lo_thread_ptr
) {
507 struct thread
*tp
= inputthread
->input_thread
;
510 * Randomize to reduce the probability
511 * of affinity tag namespace collision.
513 read_random(&tag
, sizeof (tag
));
514 if (dlil_affinity_set(tp
, tag
) == KERN_SUCCESS
) {
515 thread_reference(tp
);
516 inputthread
->tag
= tag
;
517 inputthread
->net_affinity
= TRUE
;
521 panic("dlil_create_input_thread: couldn't create thread\n");
523 OSAddAtomic(1, (SInt32
*)&cur_dlil_input_threads
);
525 printf("dlil_create_input_thread: threadinfo: %p input_thread=%p threads: cur=%d max=%d\n",
526 inputthread
, inputthread
->input_thread
, dlil_multithreaded_input
, cur_dlil_input_threads
);
530 __private_extern__
void
531 dlil_terminate_input_thread(
532 struct dlil_threading_info
*inputthread
)
534 OSAddAtomic(-1, (SInt32
*)&cur_dlil_input_threads
);
536 lck_mtx_unlock(inputthread
->input_lck
);
537 lck_mtx_free(inputthread
->input_lck
, inputthread
->lck_grp
);
538 lck_grp_free(inputthread
->lck_grp
);
540 FREE(inputthread
, M_NKE
);
542 /* For the extra reference count from kernel_thread_start() */
543 thread_deallocate(current_thread());
545 thread_terminate(current_thread());
549 dlil_affinity_set(struct thread
*tp
, u_int32_t tag
)
551 thread_affinity_policy_data_t policy
;
553 bzero(&policy
, sizeof (policy
));
554 policy
.affinity_tag
= tag
;
555 return (thread_policy_set(tp
, THREAD_AFFINITY_POLICY
,
556 (thread_policy_t
)&policy
, THREAD_AFFINITY_POLICY_COUNT
));
562 PE_parse_boot_arg("net_affinity", &net_affinity
);
564 TAILQ_INIT(&dlil_ifnet_head
);
565 TAILQ_INIT(&ifnet_head
);
567 /* Setup the lock groups we will use */
568 dlil_grp_attributes
= lck_grp_attr_alloc_init();
570 dlil_lock_group
= lck_grp_alloc_init("dlil internal locks", dlil_grp_attributes
);
571 ifnet_lock_group
= lck_grp_alloc_init("ifnet locks", dlil_grp_attributes
);
572 ifnet_head_lock_group
= lck_grp_alloc_init("ifnet head lock", dlil_grp_attributes
);
573 dlil_input_lock_grp
= lck_grp_alloc_init("dlil input lock", dlil_grp_attributes
);
575 /* Setup the lock attributes we will use */
576 dlil_lck_attributes
= lck_attr_alloc_init();
578 ifnet_lock_attr
= lck_attr_alloc_init();
581 ifnet_head_mutex
= lck_rw_alloc_init(ifnet_head_lock_group
, dlil_lck_attributes
);
582 dlil_ifnet_mutex
= lck_mtx_alloc_init(dlil_lock_group
, dlil_lck_attributes
);
583 dlil_mutex
= lck_mtx_alloc_init(dlil_lock_group
, dlil_lck_attributes
);
585 lck_attr_free(dlil_lck_attributes
);
586 dlil_lck_attributes
= NULL
;
589 * Create and start up the first dlil input thread once everything is initialized
591 dlil_create_input_thread(0, dlil_lo_thread_ptr
);
593 (void) kernel_thread(kernel_task
, dlil_call_delayed_detach_thread
);
596 __private_extern__
int
599 const struct iff_filter
*if_filter
,
600 interface_filter_t
*filter_ref
)
603 struct ifnet_filter
*filter
;
605 MALLOC(filter
, struct ifnet_filter
*, sizeof(*filter
), M_NKE
, M_WAITOK
);
608 bzero(filter
, sizeof(*filter
));
611 filter
->filt_ifp
= ifp
;
612 filter
->filt_cookie
= if_filter
->iff_cookie
;
613 filter
->filt_name
= if_filter
->iff_name
;
614 filter
->filt_protocol
= if_filter
->iff_protocol
;
615 filter
->filt_input
= if_filter
->iff_input
;
616 filter
->filt_output
= if_filter
->iff_output
;
617 filter
->filt_event
= if_filter
->iff_event
;
618 filter
->filt_ioctl
= if_filter
->iff_ioctl
;
619 filter
->filt_detached
= if_filter
->iff_detached
;
621 if ((retval
= dlil_write_begin()) != 0) {
622 /* Failed to acquire the write lock */
626 TAILQ_INSERT_TAIL(&ifp
->if_flt_head
, filter
, filt_next
);
628 *filter_ref
= filter
;
633 dlil_detach_filter_internal(
634 interface_filter_t filter
,
641 interface_filter_t entry
= NULL
;
643 /* Take the write lock */
644 retval
= dlil_write_begin();
645 if (retval
!= 0 && retval
!= EDEADLK
)
649 * At this point either we have the write lock (retval == 0)
650 * or we couldn't get it (retval == EDEADLK) because someone
651 * else up the stack is holding the read lock. It is safe to
652 * read, either the read or write is held. Verify the filter
653 * parameter before proceeding.
655 ifnet_head_lock_shared();
656 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
657 TAILQ_FOREACH(entry
, &ifp
->if_flt_head
, filt_next
) {
666 if (entry
!= filter
) {
667 /* filter parameter is not a valid filter ref */
674 if (retval
== EDEADLK
) {
675 /* Perform a delayed detach */
676 filter
->filt_detaching
= 1;
677 dlil_detach_waiting
= 1;
678 wakeup(&dlil_detach_waiting
);
682 /* Remove the filter from the list */
683 TAILQ_REMOVE(&ifp
->if_flt_head
, filter
, filt_next
);
687 /* Call the detached funciton if there is one */
688 if (filter
->filt_detached
)
689 filter
->filt_detached(filter
->filt_cookie
, filter
->filt_ifp
);
691 /* Free the filter */
697 __private_extern__
void
698 dlil_detach_filter(interface_filter_t filter
)
702 dlil_detach_filter_internal(filter
, 0);
706 dlil_input_thread_func(
707 struct dlil_threading_info
*inputthread
)
710 struct mbuf
*m
= NULL
, *m_loop
= NULL
;
711 #if IFNET_INPUT_SANITY_CHK
712 int loop_cnt
= 0, mbuf_cnt
;
715 #endif /* IFNET_INPUT_SANITY_CHK */
717 lck_mtx_lock(inputthread
->input_lck
);
719 /* Wait until there is work to be done */
720 while ((inputthread
->input_waiting
& ~DLIL_INPUT_RUNNING
) == 0) {
721 inputthread
->input_waiting
&= ~DLIL_INPUT_RUNNING
;
722 msleep(&inputthread
->input_waiting
, inputthread
->input_lck
, 0, inputthread
->input_name
, 0);
726 lck_mtx_assert(inputthread
->input_lck
, LCK_MTX_ASSERT_OWNED
);
728 m
= inputthread
->mbuf_head
;
729 inputthread
->mbuf_head
= NULL
;
730 inputthread
->mbuf_tail
= NULL
;
732 if (inputthread
->input_waiting
& DLIL_INPUT_TERMINATE
) {
735 /* this is the end */
736 dlil_terminate_input_thread(inputthread
);
740 inputthread
->input_waiting
|= DLIL_INPUT_RUNNING
;
741 inputthread
->input_waiting
&= ~DLIL_INPUT_WAITING
;
743 if (inputthread
== dlil_lo_thread_ptr
) {
744 m_loop
= dlil_lo_input_mbuf_head
;
745 dlil_lo_input_mbuf_head
= NULL
;
746 dlil_lo_input_mbuf_tail
= NULL
;
749 #if IFNET_INPUT_SANITY_CHK
750 if (dlil_input_sanity_check
!= 0) {
751 mbuf_cnt
= inputthread
->mbuf_count
;
752 inputthread
->mbuf_count
= 0;
753 if (inputthread
== dlil_lo_thread_ptr
) {
754 loop_cnt
= dlil_lo_input_mbuf_count
;
755 dlil_lo_input_mbuf_count
= 0;
758 lck_mtx_unlock(inputthread
->input_lck
);
760 for (m1
= m
, count
= 0; m1
; m1
= mbuf_nextpkt(m1
)) {
763 if (count
!= mbuf_cnt
) {
764 panic("dlil_input_func - thread=%p reg. loop queue has %d packets, should have %d\n",
765 inputthread
, count
, mbuf_cnt
);
768 if (inputthread
== dlil_lo_thread_ptr
) {
769 for (m1
= m_loop
, count
= 0; m1
; m1
= mbuf_nextpkt(m1
)) {
772 if (count
!= loop_cnt
) {
773 panic("dlil_input_func - thread=%p loop queue has %d packets, should have %d\n",
774 inputthread
, count
, loop_cnt
);
778 #endif /* IFNET_INPUT_SANITY_CHK */
780 lck_mtx_unlock(inputthread
->input_lck
);
785 * NOTE warning %%% attention !!!!
786 * We should think about putting some thread starvation safeguards if
787 * we deal with long chains of packets.
790 if (inputthread
== dlil_lo_thread_ptr
)
791 dlil_input_packet_list(lo_ifp
, m_loop
);
792 #if IFNET_INPUT_SANITY_CHK
794 panic("dlil_input_func - thread=%p loop queue has %d packets, should have none!\n",
795 inputthread
, loop_cnt
);
796 #endif /* IFNET_INPUT_SANITY_CHK */
801 dlil_input_packet_list(0, m
);
804 lck_mtx_lock(inputthread
->input_lck
);
806 if ((inputthread
->input_waiting
& (DLIL_PROTO_WAITING
| DLIL_PROTO_REGISTER
)) != 0) {
807 lck_mtx_unlock(inputthread
->input_lck
);
811 lck_mtx_unlock(inputthread
->input_lck
);
819 const struct ifnet_stat_increment_param
*stats
)
821 struct thread
*tp
= current_thread();
823 struct dlil_threading_info
*inp
;
824 #if IFNET_INPUT_SANITY_CHK
825 u_int32_t pkt_count
= 0;
826 #endif /* IFNET_INPUT_SANITY_CHK */
828 if (ifp
== NULL
|| m_head
== NULL
) {
830 mbuf_freem_list(m_head
);
836 #if IFNET_INPUT_SANITY_CHK
837 if (dlil_input_sanity_check
!= 0) {
840 rcvif
= mbuf_pkthdr_rcvif(m_tail
);
844 (ifp
->if_type
!= IFT_LOOP
&& rcvif
!= ifp
) ||
845 (mbuf_flags(m_head
) & MBUF_PKTHDR
) == 0) {
846 panic("ifnet_input - invalid mbuf %p\n", m_tail
);
849 #endif /* IFNET_INPUT_SANITY_CHK */
850 if (mbuf_nextpkt(m_tail
) == NULL
)
852 m_tail
= mbuf_nextpkt(m_tail
);
855 inp
= ifp
->if_input_thread
;
857 if (dlil_multithreaded_input
== 0 || inp
== NULL
)
858 inp
= dlil_lo_thread_ptr
;
861 * If there is a matching dlil input thread associated with an
862 * affinity set, associate this workloop thread with the same set.
863 * We will only do this once.
865 lck_mtx_lock(inp
->input_lck
);
866 if (inp
->net_affinity
&& inp
->workloop_thread
== NULL
) {
867 u_int32_t tag
= inp
->tag
;
868 inp
->workloop_thread
= tp
;
869 lck_mtx_unlock(inp
->input_lck
);
871 /* Associated the current thread with the new affinity tag */
872 (void) dlil_affinity_set(tp
, tag
);
875 * Take a reference on the workloop (current) thread; during
876 * detach, we will need to refer to it in order ot tear down
879 thread_reference(tp
);
880 lck_mtx_lock(inp
->input_lck
);
884 * Because of loopbacked multicast we cannot stuff the ifp in
885 * the rcvif of the packet header: loopback has its own dlil
889 if (inp
== dlil_lo_thread_ptr
&& ifp
->if_type
== IFT_LOOP
) {
890 if (dlil_lo_input_mbuf_head
== NULL
)
891 dlil_lo_input_mbuf_head
= m_head
;
892 else if (dlil_lo_input_mbuf_tail
!= NULL
)
893 dlil_lo_input_mbuf_tail
->m_nextpkt
= m_head
;
894 dlil_lo_input_mbuf_tail
= m_tail
;
895 #if IFNET_INPUT_SANITY_CHK
896 if (dlil_input_sanity_check
!= 0) {
897 dlil_lo_input_mbuf_count
+= pkt_count
;
898 inp
->input_mbuf_cnt
+= pkt_count
;
899 inp
->input_wake_cnt
++;
901 lck_mtx_assert(inp
->input_lck
, LCK_MTX_ASSERT_OWNED
);
906 if (inp
->mbuf_head
== NULL
)
907 inp
->mbuf_head
= m_head
;
908 else if (inp
->mbuf_tail
!= NULL
)
909 inp
->mbuf_tail
->m_nextpkt
= m_head
;
910 inp
->mbuf_tail
= m_tail
;
911 #if IFNET_INPUT_SANITY_CHK
912 if (dlil_input_sanity_check
!= 0) {
913 inp
->mbuf_count
+= pkt_count
;
914 inp
->input_mbuf_cnt
+= pkt_count
;
915 inp
->input_wake_cnt
++;
917 lck_mtx_assert(inp
->input_lck
, LCK_MTX_ASSERT_OWNED
);
923 inp
->input_waiting
|= DLIL_INPUT_WAITING
;
924 if ((inp
->input_waiting
& DLIL_INPUT_RUNNING
) == 0) {
925 wakeup((caddr_t
)&inp
->input_waiting
);
928 ifp
->if_data
.ifi_ipackets
+= stats
->packets_in
;
929 ifp
->if_data
.ifi_ibytes
+= stats
->bytes_in
;
930 ifp
->if_data
.ifi_ierrors
+= stats
->errors_in
;
932 ifp
->if_data
.ifi_opackets
+= stats
->packets_out
;
933 ifp
->if_data
.ifi_obytes
+= stats
->bytes_out
;
934 ifp
->if_data
.ifi_oerrors
+= stats
->errors_out
;
936 ifp
->if_data
.ifi_collisions
+= stats
->collisions
;
937 ifp
->if_data
.ifi_iqdrops
+= stats
->dropped
;
940 lck_mtx_unlock(inp
->input_lck
);
946 dlil_interface_filters_input(struct ifnet
* ifp
, struct mbuf
* * m_p
,
947 char * * frame_header_p
,
948 protocol_family_t protocol_family
)
950 struct ifnet_filter
* filter
;
952 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
955 if (filter
->filt_input
956 && (filter
->filt_protocol
== 0
957 || filter
->filt_protocol
== protocol_family
)) {
958 result
= (*filter
->filt_input
)(filter
->filt_cookie
,
959 ifp
, protocol_family
,
960 m_p
, frame_header_p
);
970 dlil_ifproto_input(struct if_proto
* ifproto
, mbuf_t m
)
974 if (ifproto
->proto_kpi
== kProtoKPI_v1
) {
975 /* Version 1 protocols get one packet at a time */
980 next_packet
= m
->m_nextpkt
;
982 frame_header
= m
->m_pkthdr
.header
;
983 m
->m_pkthdr
.header
= NULL
;
984 error
= (*ifproto
->kpi
.v1
.input
)(ifproto
->ifp
,
985 ifproto
->protocol_family
,
987 if (error
!= 0 && error
!= EJUSTRETURN
)
992 else if (ifproto
->proto_kpi
== kProtoKPI_v2
) {
993 /* Version 2 protocols support packet lists */
994 error
= (*ifproto
->kpi
.v2
.input
)(ifproto
->ifp
,
995 ifproto
->protocol_family
,
997 if (error
!= 0 && error
!= EJUSTRETURN
)
1003 __private_extern__
void
1004 dlil_input_packet_list(struct ifnet
* ifp_param
, struct mbuf
*m
)
1008 protocol_family_t protocol_family
;
1010 ifnet_t ifp
= ifp_param
;
1011 char * frame_header
;
1012 struct if_proto
* last_ifproto
= NULL
;
1013 mbuf_t pkt_first
= NULL
;
1014 mbuf_t
* pkt_next
= NULL
;
1016 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT
| DBG_FUNC_START
,0,0,0,0,0);
1019 struct if_proto
* ifproto
= NULL
;
1021 next_packet
= m
->m_nextpkt
;
1022 m
->m_nextpkt
= NULL
;
1023 if (ifp_param
== NULL
)
1024 ifp
= m
->m_pkthdr
.rcvif
;
1025 frame_header
= m
->m_pkthdr
.header
;
1026 m
->m_pkthdr
.header
= NULL
;
1029 /* dlil lock protects the demux and interface filters */
1033 /* find which protocol family this packet is for */
1034 error
= (*ifp
->if_demux
)(ifp
, m
, frame_header
,
1037 if (error
== EJUSTRETURN
) {
1040 protocol_family
= 0;
1044 if (m
->m_flags
& (M_BCAST
|M_MCAST
))
1047 /* run interface filters, exclude VLAN packets PR-3586856 */
1048 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1051 filter_result
= dlil_interface_filters_input(ifp
, &m
,
1054 if (filter_result
!= 0) {
1055 if (filter_result
!= EJUSTRETURN
) {
1061 if (error
!= 0 || ((m
->m_flags
& M_PROMISC
) != 0) ) {
1066 /* Lookup the protocol attachment to this interface */
1067 if (protocol_family
== 0) {
1070 else if (last_ifproto
!= NULL
1071 && last_ifproto
->ifp
== ifp
1072 && (last_ifproto
->protocol_family
1073 == protocol_family
)) {
1074 ifproto
= last_ifproto
;
1077 ifproto
= find_attached_proto(ifp
, protocol_family
);
1079 if (ifproto
== NULL
) {
1080 /* no protocol for this packet, discard */
1084 if (ifproto
!= last_ifproto
) {
1085 /* make sure ifproto can't go away during input */
1086 if_proto_ref(ifproto
);
1087 if (last_ifproto
!= NULL
) {
1088 /* pass up the list for the previous protocol */
1091 dlil_ifproto_input(last_ifproto
, pkt_first
);
1093 if_proto_free(last_ifproto
);
1096 last_ifproto
= ifproto
;
1098 /* extend the list */
1099 m
->m_pkthdr
.header
= frame_header
;
1100 if (pkt_first
== NULL
) {
1105 pkt_next
= &m
->m_nextpkt
;
1108 if (next_packet
== NULL
&& last_ifproto
!= NULL
) {
1109 /* pass up the last list of packets */
1112 dlil_ifproto_input(last_ifproto
, pkt_first
);
1113 if_proto_free(last_ifproto
);
1122 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT
| DBG_FUNC_END
,0,0,0,0,0);
1127 dlil_event_internal(struct ifnet
*ifp
, struct kev_msg
*event
)
1129 struct ifnet_filter
*filter
;
1131 if (ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
) == 0) {
1134 /* Pass the event to the interface filters */
1135 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1136 if (filter
->filt_event
)
1137 filter
->filt_event(filter
->filt_cookie
, ifp
, filter
->filt_protocol
, event
);
1140 if (ifp
->if_proto_hash
) {
1143 for (i
= 0; i
< PROTO_HASH_SLOTS
; i
++) {
1144 struct if_proto
*proto
;
1146 SLIST_FOREACH(proto
, &ifp
->if_proto_hash
[i
], next_hash
) {
1147 proto_media_event eventp
= proto
->proto_kpi
== kProtoKPI_v1
1148 ? proto
->kpi
.v1
.event
: proto
->kpi
.v2
.event
;
1151 eventp(ifp
, proto
->protocol_family
, event
);
1158 /* Pass the event to the interface */
1160 ifp
->if_event(ifp
, event
);
1163 ifp_use_reached_zero(ifp
);
1166 return kev_post_msg(event
);
1172 struct kern_event_msg
*event
)
1174 struct kev_msg kev_msg
;
1177 if (ifp
== NULL
|| event
== NULL
) return EINVAL
;
1179 kev_msg
.vendor_code
= event
->vendor_code
;
1180 kev_msg
.kev_class
= event
->kev_class
;
1181 kev_msg
.kev_subclass
= event
->kev_subclass
;
1182 kev_msg
.event_code
= event
->event_code
;
1183 kev_msg
.dv
[0].data_ptr
= &event
->event_data
[0];
1184 kev_msg
.dv
[0].data_length
= event
->total_size
- KEV_MSG_HEADER_SIZE
;
1185 kev_msg
.dv
[1].data_length
= 0;
1187 result
= dlil_event_internal(ifp
, &kev_msg
);
1193 #include <netinet/ip6.h>
1194 #include <netinet/ip.h>
1195 static int dlil_get_socket_type(struct mbuf
**mp
, int family
, int raw
)
1199 struct ip6_hdr
*ip6
;
1200 int type
= SOCK_RAW
;
1205 m
= m_pullup(*mp
, sizeof(struct ip
));
1209 ip
= mtod(m
, struct ip
*);
1210 if (ip
->ip_p
== IPPROTO_TCP
)
1212 else if (ip
->ip_p
== IPPROTO_UDP
)
1216 m
= m_pullup(*mp
, sizeof(struct ip6_hdr
));
1220 ip6
= mtod(m
, struct ip6_hdr
*);
1221 if (ip6
->ip6_nxt
== IPPROTO_TCP
)
1223 else if (ip6
->ip6_nxt
== IPPROTO_UDP
)
1237 u_long proto_family
,
1238 struct mbuf
*packetlist
,
1240 const struct sockaddr
*dest
,
1243 char *frame_type
= NULL
;
1244 char *dst_linkaddr
= NULL
;
1246 char frame_type_buffer
[MAX_FRAME_TYPE_SIZE
* 4];
1247 char dst_linkaddr_buffer
[MAX_LINKADDR
* 4];
1248 struct ifnet_filter
*filter
;
1249 struct if_proto
*proto
= 0;
1251 mbuf_t send_head
= NULL
;
1252 mbuf_t
*send_tail
= &send_head
;
1254 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_START
,0,0,0,0,0);
1258 frame_type
= frame_type_buffer
;
1259 dst_linkaddr
= dst_linkaddr_buffer
;
1262 proto
= find_attached_proto(ifp
, proto_family
);
1263 if (proto
== NULL
) {
1270 if (packetlist
== NULL
)
1273 packetlist
= packetlist
->m_nextpkt
;
1274 m
->m_nextpkt
= NULL
;
1277 proto_media_preout preoutp
= proto
->proto_kpi
== kProtoKPI_v1
1278 ? proto
->kpi
.v1
.pre_output
: proto
->kpi
.v2
.pre_output
;
1281 retval
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
);
1284 if (retval
== EJUSTRETURN
) {
1295 retval
= mac_ifnet_check_transmit(ifp
, m
, proto_family
,
1296 dlil_get_socket_type(&m
, proto_family
, raw
));
1303 if (raw
== 0 && ifp
->if_framer
) {
1304 retval
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);
1306 if (retval
!= EJUSTRETURN
) {
1316 * Need to consider how to handle this.
1317 * Also note that return should be a goto cleanup
1321 struct mbuf
*m0
= m
;
1322 struct ether_header
*eh
= mtod(m
, struct ether_header
*);
1324 if (m
->m_pkthdr
.rcvif
)
1325 m
->m_pkthdr
.rcvif
= NULL
;
1326 ifp
= bridge_dst_lookup(eh
);
1327 bdg_forward(&m0
, ifp
);
1331 return 0 - should be
goto cleanup
?
1336 * Let interface filters (if any) do their thing ...
1338 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1339 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1340 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1341 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_family
)) &&
1342 filter
->filt_output
) {
1343 retval
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
);
1345 if (retval
!= EJUSTRETURN
)
1354 * Finally, call the driver.
1357 if ((ifp
->if_eflags
& IFEF_SENDLIST
) != 0) {
1359 send_tail
= &m
->m_nextpkt
;
1362 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1363 retval
= ifp
->if_output(ifp
, m
);
1365 printf("dlil_output: output error retval = %x\n", retval
);
1367 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1369 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1374 packetlist
= packetlist
->m_nextpkt
;
1375 m
->m_nextpkt
= NULL
;
1380 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1381 retval
= ifp
->if_output(ifp
, send_head
);
1383 printf("dlil_output: output error retval = %x\n", retval
);
1385 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1388 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_END
,0,0,0,0,0);
1392 if (packetlist
) /* if any packet left, clean up */
1393 mbuf_freem_list(packetlist
);
1394 if (retval
== EJUSTRETURN
)
1403 * Caller should have a lock on the protocol domain if the protocol
1404 * doesn't support finer grained locking. In most cases, the lock
1405 * will be held from the socket layer and won't be released until
1406 * we return back to the socket layer.
1408 * This does mean that we must take a protocol lock before we take
1409 * an interface lock if we're going to take both. This makes sense
1410 * because a protocol is likely to interact with an ifp while it
1411 * is under the protocol lock.
1413 __private_extern__ errno_t
1416 protocol_family_t proto_family
,
1419 const struct sockaddr
*dest
,
1422 char *frame_type
= NULL
;
1423 char *dst_linkaddr
= NULL
;
1425 char frame_type_buffer
[MAX_FRAME_TYPE_SIZE
* 4];
1426 char dst_linkaddr_buffer
[MAX_LINKADDR
* 4];
1427 struct ifnet_filter
*filter
;
1428 struct if_proto
*proto
= 0;
1430 mbuf_t send_head
= NULL
;
1431 mbuf_t
*send_tail
= &send_head
;
1433 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_START
,0,0,0,0,0);
1437 frame_type
= frame_type_buffer
;
1438 dst_linkaddr
= dst_linkaddr_buffer
;
1441 proto
= find_attached_proto(ifp
, proto_family
);
1442 if (proto
== NULL
) {
1449 if (packetlist
== NULL
)
1452 packetlist
= packetlist
->m_nextpkt
;
1453 m
->m_nextpkt
= NULL
;
1456 proto_media_preout preoutp
= proto
->proto_kpi
== kProtoKPI_v1
1457 ? proto
->kpi
.v1
.pre_output
: proto
->kpi
.v2
.pre_output
;
1460 retval
= preoutp(ifp
, proto_family
, &m
, dest
, route
, frame_type
, dst_linkaddr
);
1463 if (retval
== EJUSTRETURN
) {
1473 retval
= mac_ifnet_check_transmit(ifp
, m
, proto_family
,
1474 dlil_get_socket_type(&m
, proto_family
, raw
));
1482 if (raw
== 0 && ifp
->if_framer
) {
1483 retval
= ifp
->if_framer(ifp
, &m
, dest
, dst_linkaddr
, frame_type
);
1485 if (retval
!= EJUSTRETURN
) {
1495 * Need to consider how to handle this.
1496 * Also note that return should be a goto cleanup
1500 struct mbuf
*m0
= m
;
1501 struct ether_header
*eh
= mtod(m
, struct ether_header
*);
1503 if (m
->m_pkthdr
.rcvif
)
1504 m
->m_pkthdr
.rcvif
= NULL
;
1505 ifp
= bridge_dst_lookup(eh
);
1506 bdg_forward(&m0
, ifp
);
1510 return 0 - should be
goto cleanup
?
1515 * Let interface filters (if any) do their thing ...
1517 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1518 if ((m
->m_pkthdr
.csum_flags
& CSUM_VLAN_TAG_VALID
) == 0) {
1519 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1520 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_family
)) &&
1521 filter
->filt_output
) {
1522 retval
= filter
->filt_output(filter
->filt_cookie
, ifp
, proto_family
, &m
);
1524 if (retval
!= EJUSTRETURN
)
1533 * If the underlying interface is not capable of handling a
1534 * packet whose data portion spans across physically disjoint
1535 * pages, we need to "normalize" the packet so that we pass
1536 * down a chain of mbufs where each mbuf points to a span that
1537 * resides in the system page boundary. If the packet does
1538 * not cross page(s), the following is a no-op.
1540 if (!(ifp
->if_hwassist
& IFNET_MULTIPAGES
)) {
1541 if ((m
= m_normalize(m
)) == NULL
)
1546 * Finally, call the driver.
1549 if ((ifp
->if_eflags
& IFEF_SENDLIST
) != 0) {
1551 send_tail
= &m
->m_nextpkt
;
1554 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1555 retval
= ifp
->if_output(ifp
, m
);
1557 printf("dlil_output: output error retval = %x\n", retval
);
1559 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1561 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1566 packetlist
= packetlist
->m_nextpkt
;
1567 m
->m_nextpkt
= NULL
;
1572 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_START
, 0,0,0,0,0);
1573 retval
= ifp
->if_output(ifp
, send_head
);
1575 printf("dlil_output: output error retval = %x\n", retval
);
1577 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT
| DBG_FUNC_END
, 0,0,0,0,0);
1580 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT
| DBG_FUNC_END
,0,0,0,0,0);
1584 if (packetlist
) /* if any packet left, clean up */
1585 mbuf_freem_list(packetlist
);
1586 if (retval
== EJUSTRETURN
)
1594 protocol_family_t proto_fam
,
1595 u_int32_t ioctl_code
,
1598 struct ifnet_filter
*filter
;
1599 int retval
= EOPNOTSUPP
;
1601 int holding_read
= 0;
1603 if (ifp
== NULL
|| ioctl_code
== 0)
1606 /* Attempt to increment the use count. If it's zero, bail out, the ifp is invalid */
1607 result
= ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
);
1614 /* Run the interface filters first.
1615 * We want to run all filters before calling the protocol,
1616 * interface family, or interface.
1618 TAILQ_FOREACH(filter
, &ifp
->if_flt_head
, filt_next
) {
1619 if ((filter
->filt_protocol
== 0 || (filter
->filt_protocol
== proto_fam
)) &&
1620 filter
->filt_ioctl
!= NULL
) {
1621 result
= filter
->filt_ioctl(filter
->filt_cookie
, ifp
, proto_fam
, ioctl_code
, ioctl_arg
);
1622 /* Only update retval if no one has handled the ioctl */
1623 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1624 if (result
== ENOTSUP
)
1625 result
= EOPNOTSUPP
;
1627 if (retval
&& retval
!= EOPNOTSUPP
) {
1634 /* Allow the protocol to handle the ioctl */
1636 struct if_proto
*proto
= find_attached_proto(ifp
, proto_fam
);
1639 proto_media_ioctl ioctlp
= proto
->proto_kpi
== kProtoKPI_v1
1640 ? proto
->kpi
.v1
.ioctl
: proto
->kpi
.v2
.ioctl
;
1641 result
= EOPNOTSUPP
;
1643 result
= ioctlp(ifp
, proto_fam
, ioctl_code
, ioctl_arg
);
1645 /* Only update retval if no one has handled the ioctl */
1646 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1647 if (result
== ENOTSUP
)
1648 result
= EOPNOTSUPP
;
1650 if (retval
&& retval
!= EOPNOTSUPP
) {
1658 * Since we have incremented the use count on the ifp, we are guaranteed
1659 * that the ifp will not go away (the function pointers may not be changed).
1660 * We release the dlil read lock so the interface ioctl may trigger a
1661 * protocol attach. This happens with vlan and may occur with other virtual
1667 /* retval is either 0 or EOPNOTSUPP */
1670 * Let the interface handle this ioctl.
1671 * If it returns EOPNOTSUPP, ignore that, we may have
1672 * already handled this in the protocol or family.
1675 result
= (*ifp
->if_ioctl
)(ifp
, ioctl_code
, ioctl_arg
);
1677 /* Only update retval if no one has handled the ioctl */
1678 if (retval
== EOPNOTSUPP
|| result
== EJUSTRETURN
) {
1679 if (result
== ENOTSUP
)
1680 result
= EOPNOTSUPP
;
1682 if (retval
&& retval
!= EOPNOTSUPP
) {
1691 ifp_use_reached_zero(ifp
);
1693 if (retval
== EJUSTRETURN
)
1698 __private_extern__ errno_t
1702 bpf_packet_func callback
)
1707 if (ifp
->if_set_bpf_tap
)
1708 error
= ifp
->if_set_bpf_tap(ifp
, mode
, callback
);
1717 const struct sockaddr
*proto_addr
,
1718 struct sockaddr
*ll_addr
,
1721 errno_t result
= EOPNOTSUPP
;
1722 struct if_proto
*proto
;
1723 const struct sockaddr
*verify
;
1724 proto_media_resolve_multi resolvep
;
1728 bzero(ll_addr
, ll_len
);
1730 /* Call the protocol first */
1731 proto
= find_attached_proto(ifp
, proto_addr
->sa_family
);
1732 if (proto
!= NULL
) {
1733 resolvep
= proto
->proto_kpi
== kProtoKPI_v1
1734 ? proto
->kpi
.v1
.resolve_multi
: proto
->kpi
.v2
.resolve_multi
;
1735 if (resolvep
!= NULL
)
1736 result
= resolvep(ifp
, proto_addr
,(struct sockaddr_dl
*)ll_addr
,
1740 /* Let the interface verify the multicast address */
1741 if ((result
== EOPNOTSUPP
|| result
== 0) && ifp
->if_check_multi
) {
1745 verify
= proto_addr
;
1746 result
= ifp
->if_check_multi(ifp
, verify
);
1754 __private_extern__ errno_t
1755 dlil_send_arp_internal(
1758 const struct sockaddr_dl
* sender_hw
,
1759 const struct sockaddr
* sender_proto
,
1760 const struct sockaddr_dl
* target_hw
,
1761 const struct sockaddr
* target_proto
)
1763 struct if_proto
*proto
;
1768 proto
= find_attached_proto(ifp
, target_proto
->sa_family
);
1769 if (proto
== NULL
) {
1773 proto_media_send_arp arpp
;
1774 arpp
= proto
->proto_kpi
== kProtoKPI_v1
1775 ? proto
->kpi
.v1
.send_arp
: proto
->kpi
.v2
.send_arp
;
1779 result
= arpp(ifp
, arpop
, sender_hw
, sender_proto
, target_hw
,
1788 static __inline__
int
1789 _is_announcement(const struct sockaddr_in
* sender_sin
,
1790 const struct sockaddr_in
* target_sin
)
1792 if (sender_sin
== NULL
) {
1795 return (sender_sin
->sin_addr
.s_addr
== target_sin
->sin_addr
.s_addr
);
1798 __private_extern__ errno_t
1802 const struct sockaddr_dl
* sender_hw
,
1803 const struct sockaddr
* sender_proto
,
1804 const struct sockaddr_dl
* target_hw
,
1805 const struct sockaddr
* target_proto
)
1808 const struct sockaddr_in
* sender_sin
;
1809 const struct sockaddr_in
* target_sin
;
1811 if (target_proto
== NULL
|| (sender_proto
&&
1812 sender_proto
->sa_family
!= target_proto
->sa_family
))
1816 * If this is an ARP request and the target IP is IPv4LL,
1817 * send the request on all interfaces. The exception is
1818 * an announcement, which must only appear on the specific
1821 sender_sin
= (const struct sockaddr_in
*)sender_proto
;
1822 target_sin
= (const struct sockaddr_in
*)target_proto
;
1823 if (target_proto
->sa_family
== AF_INET
1824 && IN_LINKLOCAL(ntohl(target_sin
->sin_addr
.s_addr
))
1825 && ipv4_ll_arp_aware
!= 0
1826 && arpop
== ARPOP_REQUEST
1827 && !_is_announcement(target_sin
, sender_sin
)) {
1834 if (ifnet_list_get(IFNET_FAMILY_ANY
, &ifp_list
, &count
) == 0) {
1835 for (ifp_on
= 0; ifp_on
< count
; ifp_on
++) {
1837 ifaddr_t source_hw
= NULL
;
1838 ifaddr_t source_ip
= NULL
;
1839 struct sockaddr_in source_ip_copy
;
1842 * Only arp on interfaces marked for IPv4LL ARPing. This may
1843 * mean that we don't ARP on the interface the subnet route
1846 if ((ifp_list
[ifp_on
]->if_eflags
& IFEF_ARPLL
) == 0) {
1850 source_hw
= TAILQ_FIRST(&ifp_list
[ifp_on
]->if_addrhead
);
1852 /* Find the source IP address */
1853 ifnet_lock_shared(ifp_list
[ifp_on
]);
1854 TAILQ_FOREACH(source_ip
, &ifp_list
[ifp_on
]->if_addrhead
,
1856 if (source_ip
->ifa_addr
&&
1857 source_ip
->ifa_addr
->sa_family
== AF_INET
) {
1862 /* No IP Source, don't arp */
1863 if (source_ip
== NULL
) {
1864 ifnet_lock_done(ifp_list
[ifp_on
]);
1868 /* Copy the source IP address */
1869 source_ip_copy
= *(struct sockaddr_in
*)source_ip
->ifa_addr
;
1871 ifnet_lock_done(ifp_list
[ifp_on
]);
1874 new_result
= dlil_send_arp_internal(ifp_list
[ifp_on
], arpop
,
1875 (struct sockaddr_dl
*)source_hw
->ifa_addr
,
1876 (struct sockaddr
*)&source_ip_copy
, NULL
,
1879 if (result
== ENOTSUP
) {
1880 result
= new_result
;
1885 ifnet_list_free(ifp_list
);
1888 result
= dlil_send_arp_internal(ifp
, arpop
, sender_hw
, sender_proto
,
1889 target_hw
, target_proto
);
1895 __private_extern__
int
1904 old_value
= ifp
->if_usecnt
;
1905 if (old_value
== 0 && handle_zero
== kIfNetUseCount_MustNotBeZero
) {
1906 retval
= ENXIO
; // ifp is invalid
1909 } while (!OSCompareAndSwap((UInt32
)old_value
, (UInt32
)old_value
+ 1, (UInt32
*)&ifp
->if_usecnt
));
1914 /* ifp_unuse is broken into two pieces.
1916 * ifp_use and ifp_unuse must be called between when the caller calls
1917 * dlil_write_begin and dlil_write_end. ifp_unuse needs to perform some
1918 * operations after dlil_write_end has been called. For this reason,
1919 * anyone calling ifp_unuse must call ifp_use_reached_zero if ifp_unuse
1920 * returns a non-zero value. The caller must call ifp_use_reached_zero
1921 * after the caller has called dlil_write_end.
1923 __private_extern__
void
1924 ifp_use_reached_zero(
1927 ifnet_detached_func free_func
;
1931 if (ifp
->if_usecnt
!= 0)
1932 panic("ifp_use_reached_zero: ifp->if_usecnt != 0");
1934 ifnet_head_lock_exclusive();
1935 ifnet_lock_exclusive(ifp
);
1937 /* Remove ourselves from the list */
1938 TAILQ_REMOVE(&ifnet_head
, ifp
, if_link
);
1939 ifnet_addrs
[ifp
->if_index
- 1] = NULL
;
1941 /* ifp should be removed from the interface list */
1942 while (ifp
->if_multiaddrs
.lh_first
) {
1943 struct ifmultiaddr
*ifma
= ifp
->if_multiaddrs
.lh_first
;
1946 * When the interface is gone, we will no longer
1947 * be listening on these multicasts. Various bits
1948 * of the stack may be referencing these multicasts,
1949 * release only our reference.
1951 LIST_REMOVE(ifma
, ifma_link
);
1952 ifma
->ifma_ifp
= NULL
;
1957 ifp
->if_eflags
&= ~IFEF_DETACHING
; // clear the detaching flag
1958 ifnet_lock_done(ifp
);
1960 free_func
= ifp
->if_free
;
1962 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHED
, NULL
, 0);
1968 __private_extern__
int
1973 oldval
= OSDecrementAtomic((SInt32
*)&ifp
->if_usecnt
);
1975 panic("ifp_unuse: ifp(%s%d)->if_usecnt was zero\n", ifp
->if_name
, ifp
->if_unit
);
1980 if ((ifp
->if_eflags
& IFEF_DETACHING
) == 0)
1981 panic("ifp_unuse: use count reached zero but detching flag is not set!");
1983 return 1; /* caller must call ifp_use_reached_zero */
1986 extern lck_mtx_t
*domain_proto_mtx
;
1989 dlil_attach_protocol_internal(
1990 struct if_proto
*proto
,
1991 const struct ifnet_demux_desc
*demux_list
,
1992 u_int32_t demux_count
)
1994 struct kev_dl_proto_data ev_pr_data
;
1995 struct ifnet
*ifp
= proto
->ifp
;
1997 u_long hash_value
= proto_hash_value(proto
->protocol_family
);
1999 /* setup some of the common values */
2002 lck_mtx_lock(domain_proto_mtx
);
2004 while (dp
&& (protocol_family_t
)dp
->dom_family
!= proto
->protocol_family
)
2006 proto
->dl_domain
= dp
;
2007 lck_mtx_unlock(domain_proto_mtx
);
2011 * Take the write lock to protect readers and exclude other writers.
2013 if ((retval
= dlil_write_begin()) != 0) {
2014 printf("dlil_attach_protocol_internal - dlil_write_begin returned %d\n", retval
);
2018 /* Check that the interface isn't currently detaching */
2019 ifnet_lock_shared(ifp
);
2020 if ((ifp
->if_eflags
& IFEF_DETACHING
) != 0) {
2021 ifnet_lock_done(ifp
);
2025 ifnet_lock_done(ifp
);
2027 if (find_attached_proto(ifp
, proto
->protocol_family
) != NULL
) {
2033 * Call family module add_proto routine so it can refine the
2034 * demux descriptors as it wishes.
2036 retval
= ifp
->if_add_proto(ifp
, proto
->protocol_family
, demux_list
, demux_count
);
2043 * We can't fail from this point on.
2044 * Increment the number of uses (protocol attachments + interface attached).
2046 ifp_use(ifp
, kIfNetUseCount_MustNotBeZero
);
2049 * Insert the protocol in the hash
2052 struct if_proto
* prev_proto
= SLIST_FIRST(&ifp
->if_proto_hash
[hash_value
]);
2053 while (prev_proto
&& SLIST_NEXT(prev_proto
, next_hash
) != NULL
)
2054 prev_proto
= SLIST_NEXT(prev_proto
, next_hash
);
2056 SLIST_INSERT_AFTER(prev_proto
, proto
, next_hash
);
2058 SLIST_INSERT_HEAD(&ifp
->if_proto_hash
[hash_value
], proto
, next_hash
);
2062 * Add to if_proto list for this interface
2064 if_proto_ref(proto
);
2067 /* the reserved field carries the number of protocol still attached (subject to change) */
2068 ev_pr_data
.proto_family
= proto
->protocol_family
;
2069 ev_pr_data
.proto_remaining_count
= dlil_ifp_proto_count(ifp
);
2070 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_ATTACHED
,
2071 (struct net_event_data
*)&ev_pr_data
,
2072 sizeof(struct kev_dl_proto_data
));
2074 DLIL_PRINTF("dlil. Attached protocol %d to %s%d - %d\n", proto
->protocol_family
,
2075 ifp
->if_name
, ifp
->if_unit
, retval
);
2081 ifnet_attach_protocol(ifnet_t ifp
, protocol_family_t protocol
,
2082 const struct ifnet_attach_proto_param
*proto_details
)
2085 struct if_proto
*ifproto
= NULL
;
2087 if (ifp
== NULL
|| protocol
== 0 || proto_details
== NULL
)
2090 ifproto
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
);
2092 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n");
2096 bzero(ifproto
, sizeof(*ifproto
));
2099 ifproto
->protocol_family
= protocol
;
2100 ifproto
->proto_kpi
= kProtoKPI_v1
;
2101 ifproto
->kpi
.v1
.input
= proto_details
->input
;
2102 ifproto
->kpi
.v1
.pre_output
= proto_details
->pre_output
;
2103 ifproto
->kpi
.v1
.event
= proto_details
->event
;
2104 ifproto
->kpi
.v1
.ioctl
= proto_details
->ioctl
;
2105 ifproto
->kpi
.v1
.detached
= proto_details
->detached
;
2106 ifproto
->kpi
.v1
.resolve_multi
= proto_details
->resolve
;
2107 ifproto
->kpi
.v1
.send_arp
= proto_details
->send_arp
;
2109 retval
= dlil_attach_protocol_internal(ifproto
,
2110 proto_details
->demux_list
, proto_details
->demux_count
);
2113 if (retval
&& ifproto
)
2114 FREE(ifproto
, M_IFADDR
);
2119 ifnet_attach_protocol_v2(ifnet_t ifp
, protocol_family_t protocol
,
2120 const struct ifnet_attach_proto_param_v2
*proto_details
)
2123 struct if_proto
*ifproto
= NULL
;
2125 if (ifp
== NULL
|| protocol
== 0 || proto_details
== NULL
)
2128 ifproto
= _MALLOC(sizeof(struct if_proto
), M_IFADDR
, M_WAITOK
);
2130 DLIL_PRINTF("ERROR - dlil failed if_proto allocation\n");
2134 bzero(ifproto
, sizeof(*ifproto
));
2137 ifproto
->protocol_family
= protocol
;
2138 ifproto
->proto_kpi
= kProtoKPI_v2
;
2139 ifproto
->kpi
.v2
.input
= proto_details
->input
;
2140 ifproto
->kpi
.v2
.pre_output
= proto_details
->pre_output
;
2141 ifproto
->kpi
.v2
.event
= proto_details
->event
;
2142 ifproto
->kpi
.v2
.ioctl
= proto_details
->ioctl
;
2143 ifproto
->kpi
.v2
.detached
= proto_details
->detached
;
2144 ifproto
->kpi
.v2
.resolve_multi
= proto_details
->resolve
;
2145 ifproto
->kpi
.v2
.send_arp
= proto_details
->send_arp
;
2147 retval
= dlil_attach_protocol_internal(ifproto
,
2148 proto_details
->demux_list
, proto_details
->demux_count
);
2151 if (retval
&& ifproto
)
2152 FREE(ifproto
, M_IFADDR
);
2156 extern void if_rtproto_del(struct ifnet
*ifp
, int protocol
);
2159 dlil_detach_protocol_internal(
2160 struct if_proto
*proto
)
2162 struct ifnet
*ifp
= proto
->ifp
;
2163 u_long proto_family
= proto
->protocol_family
;
2164 struct kev_dl_proto_data ev_pr_data
;
2166 if (proto
->proto_kpi
== kProtoKPI_v1
) {
2167 if (proto
->kpi
.v1
.detached
)
2168 proto
->kpi
.v1
.detached(ifp
, proto
->protocol_family
);
2170 if (proto
->proto_kpi
== kProtoKPI_v2
) {
2171 if (proto
->kpi
.v2
.detached
)
2172 proto
->kpi
.v2
.detached(ifp
, proto
->protocol_family
);
2174 if_proto_free(proto
);
2177 * Cleanup routes that may still be in the routing table for that interface/protocol pair.
2180 if_rtproto_del(ifp
, proto_family
);
2182 /* the reserved field carries the number of protocol still attached (subject to change) */
2183 ev_pr_data
.proto_family
= proto_family
;
2184 ev_pr_data
.proto_remaining_count
= dlil_ifp_proto_count(ifp
);
2185 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_PROTO_DETACHED
,
2186 (struct net_event_data
*)&ev_pr_data
,
2187 sizeof(struct kev_dl_proto_data
));
2192 ifnet_detach_protocol(ifnet_t ifp
, protocol_family_t proto_family
)
2194 struct if_proto
*proto
= NULL
;
2196 int use_reached_zero
= 0;
2198 if (ifp
== NULL
|| proto_family
== 0) return EINVAL
;
2200 if ((retval
= dlil_write_begin()) != 0) {
2201 if (retval
== EDEADLK
) {
2204 proto
= find_attached_proto(ifp
, proto_family
);
2209 proto
->detaching
= 1;
2210 dlil_detach_waiting
= 1;
2211 wakeup(&dlil_detach_waiting
);
2218 proto
= find_attached_proto(ifp
, proto_family
);
2220 if (proto
== NULL
) {
2227 * Call family module del_proto
2230 if (ifp
->if_del_proto
)
2231 ifp
->if_del_proto(ifp
, proto
->protocol_family
);
2233 SLIST_REMOVE(&ifp
->if_proto_hash
[proto_hash_value(proto_family
)], proto
, if_proto
, next_hash
);
2236 * We can do the rest of the work outside of the write lock.
2238 use_reached_zero
= ifp_unuse(ifp
);
2241 dlil_detach_protocol_internal(proto
);
2244 * Only handle the case where the interface will go away after
2245 * we've sent the message. This way post message can send the
2246 * message to the interface safely.
2249 if (use_reached_zero
)
2250 ifp_use_reached_zero(ifp
);
2257 * dlil_delayed_detach_thread is responsible for detaching
2258 * protocols, protocol filters, and interface filters after
2259 * an attempt was made to detach one of those items while
2260 * it was not safe to do so (i.e. called dlil_read_begin).
2262 * This function will take the dlil write lock and walk
2263 * through each of the interfaces looking for items with
2264 * the detaching flag set. When an item is found, it is
2265 * detached from the interface and placed on a local list.
2266 * After all of the items have been collected, we drop the
2267 * write lock and performed the post detach. This is done
2268 * so we only have to take the write lock once.
2270 * When detaching a protocol filter, if we find that we
2271 * have detached the very last protocol and we need to call
2272 * ifp_use_reached_zero, we have to break out of our work
2273 * to drop the write lock so we can call ifp_use_reached_zero.
2277 dlil_delayed_detach_thread(__unused
void* foo
, __unused wait_result_t wait
)
2279 thread_t self
= current_thread();
2282 ml_thread_policy(self
, MACHINE_GROUP
,
2283 (MACHINE_NETWORK_GROUP
|MACHINE_NETWORK_NETISR
));
2287 if (dlil_detach_waiting
!= 0 && dlil_write_begin() == 0) {
2289 struct proto_hash_entry detached_protos
;
2290 struct ifnet_filter_head detached_filters
;
2291 struct if_proto
*proto
;
2292 struct if_proto
*next_proto
;
2293 struct ifnet_filter
*filt
;
2294 struct ifnet_filter
*next_filt
;
2299 /* Clear the detach waiting flag */
2300 dlil_detach_waiting
= 0;
2301 TAILQ_INIT(&detached_filters
);
2302 SLIST_INIT(&detached_protos
);
2304 ifnet_head_lock_shared();
2305 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2308 // Look for protocols and protocol filters
2309 for (i
= 0; i
< PROTO_HASH_SLOTS
&& !reached_zero
; i
++) {
2310 struct if_proto
**prev_nextptr
= &SLIST_FIRST(&ifp
->if_proto_hash
[i
]);
2311 for (proto
= *prev_nextptr
; proto
; proto
= *prev_nextptr
) {
2313 // Detach this protocol
2314 if (proto
->detaching
) {
2315 if (ifp
->if_del_proto
)
2316 ifp
->if_del_proto(ifp
, proto
->protocol_family
);
2317 *prev_nextptr
= SLIST_NEXT(proto
, next_hash
);
2318 SLIST_INSERT_HEAD(&detached_protos
, proto
, next_hash
);
2319 reached_zero
= ifp_unuse(ifp
);
2325 // Update prev_nextptr to point to our next ptr
2326 prev_nextptr
= &SLIST_NEXT(proto
, next_hash
);
2331 // look for interface filters that need to be detached
2332 for (filt
= TAILQ_FIRST(&ifp
->if_flt_head
); filt
; filt
= next_filt
) {
2333 next_filt
= TAILQ_NEXT(filt
, filt_next
);
2334 if (filt
->filt_detaching
!= 0) {
2335 // take this interface filter off the interface filter list
2336 TAILQ_REMOVE(&ifp
->if_flt_head
, filt
, filt_next
);
2338 // put this interface filter on the detached filters list
2339 TAILQ_INSERT_TAIL(&detached_filters
, filt
, filt_next
);
2343 if (ifp
->if_delayed_detach
) {
2344 ifp
->if_delayed_detach
= 0;
2345 reached_zero
= ifp_unuse(ifp
);
2354 for (filt
= TAILQ_FIRST(&detached_filters
); filt
; filt
= next_filt
) {
2355 next_filt
= TAILQ_NEXT(filt
, filt_next
);
2357 * dlil_detach_filter_internal won't remove an item from
2358 * the list if it is already detached (second parameter).
2359 * The item will be freed though.
2361 dlil_detach_filter_internal(filt
, 1);
2364 for (proto
= SLIST_FIRST(&detached_protos
); proto
; proto
= next_proto
) {
2365 next_proto
= SLIST_NEXT(proto
, next_hash
);
2366 dlil_detach_protocol_internal(proto
);
2370 ifp_use_reached_zero(ifp
);
2371 dlil_detach_waiting
= 1; // we may have missed something
2375 if (!asserted
&& dlil_detach_waiting
== 0) {
2377 assert_wait(&dlil_detach_waiting
, THREAD_UNINT
);
2380 if (dlil_detach_waiting
== 0) {
2382 thread_block(dlil_delayed_detach_thread
);
2388 dlil_call_delayed_detach_thread(void) {
2389 dlil_delayed_detach_thread(NULL
, THREAD_RESTART
);
2392 extern int if_next_index(void);
2397 const struct sockaddr_dl
*ll_addr
)
2399 u_long interface_family
;
2400 struct ifnet
*tmp_if
;
2401 struct proto_hash_entry
*new_proto_list
= NULL
;
2404 if (ifp
== NULL
) return EINVAL
;
2405 if (ll_addr
&& ifp
->if_addrlen
== 0) {
2406 ifp
->if_addrlen
= ll_addr
->sdl_alen
;
2408 else if (ll_addr
&& ll_addr
->sdl_alen
!= ifp
->if_addrlen
) {
2412 interface_family
= ifp
->if_family
;
2414 ifnet_head_lock_shared();
2416 /* Verify we aren't already on the list */
2417 TAILQ_FOREACH(tmp_if
, &ifnet_head
, if_link
) {
2418 if (tmp_if
== ifp
) {
2426 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_lock
== 0)
2428 ifp
->if_lock
= lck_rw_alloc_init(ifnet_lock_group
, ifnet_lock_attr
);
2430 ifp
->if_lock
= lck_mtx_alloc_init(ifnet_lock_group
, ifnet_lock_attr
);
2433 if (ifp
->if_lock
== 0) {
2438 * Allow interfaces withouth protocol families to attach
2439 * only if they have the necessary fields filled out.
2442 if (ifp
->if_add_proto
== 0 || ifp
->if_del_proto
== 0) {
2443 DLIL_PRINTF("dlil Attempt to attach interface without family module - %ld\n",
2448 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_proto_hash
== NULL
) {
2449 MALLOC(new_proto_list
, struct proto_hash_entry
*, sizeof(struct proto_hash_entry
) * PROTO_HASH_SLOTS
,
2452 if (new_proto_list
== 0) {
2460 TAILQ_INIT(&ifp
->if_flt_head
);
2463 if (new_proto_list
) {
2464 bzero(new_proto_list
, (PROTO_HASH_SLOTS
* sizeof(struct proto_hash_entry
)));
2465 ifp
->if_proto_hash
= new_proto_list
;
2466 new_proto_list
= NULL
;
2472 int namelen
, masklen
, socksize
, ifasize
;
2473 struct ifaddr
*ifa
= NULL
;
2475 if (ifp
->if_snd
.ifq_maxlen
== 0)
2476 ifp
->if_snd
.ifq_maxlen
= ifqmaxlen
;
2477 TAILQ_INIT(&ifp
->if_prefixhead
);
2478 LIST_INIT(&ifp
->if_multiaddrs
);
2479 ifnet_touch_lastchange(ifp
);
2481 /* usecount to track attachment to the ifnet list */
2482 ifp_use(ifp
, kIfNetUseCount_MayBeZero
);
2484 /* Lock the list of interfaces */
2485 ifnet_head_lock_exclusive();
2486 ifnet_lock_exclusive(ifp
);
2488 if ((ifp
->if_eflags
& IFEF_REUSE
) == 0 || ifp
->if_index
== 0)
2489 ifp
->if_index
= if_next_index();
2491 ifa
= TAILQ_FIRST(&ifp
->if_addrhead
);
2493 namelen
= snprintf(workbuf
, sizeof(workbuf
), "%s%d", ifp
->if_name
, ifp
->if_unit
);
2494 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
2495 masklen
= _offsetof(struct sockaddr_dl
, sdl_data
[0]) + namelen
;
2496 socksize
= masklen
+ ifp
->if_addrlen
;
2497 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
2498 if ((u_long
)socksize
< sizeof(struct sockaddr_dl
))
2499 socksize
= sizeof(struct sockaddr_dl
);
2500 socksize
= ROUNDUP(socksize
);
2501 ifasize
= sizeof(struct ifaddr
) + 2 * socksize
;
2504 * Allocate a new ifa if we don't have one
2505 * or the old one is too small.
2507 if (ifa
== NULL
|| socksize
> ifa
->ifa_addr
->sa_len
) {
2509 if_detach_ifa(ifp
, ifa
);
2510 ifa
= (struct ifaddr
*)_MALLOC(ifasize
, M_IFADDR
, M_WAITOK
);
2514 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)(ifa
+ 1);
2515 ifnet_addrs
[ifp
->if_index
- 1] = ifa
;
2516 bzero(ifa
, ifasize
);
2517 sdl
->sdl_len
= socksize
;
2518 sdl
->sdl_family
= AF_LINK
;
2519 bcopy(workbuf
, sdl
->sdl_data
, namelen
);
2520 sdl
->sdl_nlen
= namelen
;
2521 sdl
->sdl_index
= ifp
->if_index
;
2522 sdl
->sdl_type
= ifp
->if_type
;
2524 sdl
->sdl_alen
= ll_addr
->sdl_alen
;
2525 if (ll_addr
->sdl_alen
!= ifp
->if_addrlen
)
2526 panic("ifnet_attach - ll_addr->sdl_alen != ifp->if_addrlen");
2527 bcopy(CONST_LLADDR(ll_addr
), LLADDR(sdl
), sdl
->sdl_alen
);
2530 ifa
->ifa_rtrequest
= link_rtrequest
;
2531 ifa
->ifa_addr
= (struct sockaddr
*)sdl
;
2532 sdl
= (struct sockaddr_dl
*)(socksize
+ (caddr_t
)sdl
);
2533 ifa
->ifa_netmask
= (struct sockaddr
*)sdl
;
2534 sdl
->sdl_len
= masklen
;
2535 while (namelen
!= 0)
2536 sdl
->sdl_data
[--namelen
] = 0xff;
2539 TAILQ_INIT(&ifp
->if_addrhead
);
2540 ifa
= ifnet_addrs
[ifp
->if_index
- 1];
2544 * We don't use if_attach_ifa because we want
2545 * this address to be first on the list.
2548 ifa
->ifa_debug
|= IFA_ATTACHED
;
2549 TAILQ_INSERT_HEAD(&ifp
->if_addrhead
, ifa
, ifa_link
);
2552 mac_ifnet_label_associate(ifp
);
2555 TAILQ_INSERT_TAIL(&ifnet_head
, ifp
, if_link
);
2556 ifindex2ifnet
[ifp
->if_index
] = ifp
;
2562 * A specific dlil input thread is created per Ethernet interface.
2563 * pseudo interfaces or other types of interfaces use the main ("loopback") thread.
2564 * If the sysctl "net.link.generic.system.multi_threaded_input" is set to zero, all packets will
2565 * be handled by the main loopback thread, reverting to 10.4.x behaviour.
2569 if (ifp
->if_type
== IFT_ETHER
) {
2572 if (dlil_multithreaded_input
> 0) {
2573 ifp
->if_input_thread
= _MALLOC(sizeof(struct dlil_threading_info
), M_NKE
, M_WAITOK
);
2574 if (ifp
->if_input_thread
== NULL
)
2575 panic("ifnet_attach ifp=%p couldn't alloc threading\n", ifp
);
2576 if ((err
= dlil_create_input_thread(ifp
, ifp
->if_input_thread
)) != 0)
2577 panic("ifnet_attach ifp=%p couldn't get a thread. err=%x\n", ifp
, err
);
2579 printf("ifnet_attach: dlil thread for ifp=%p if_index=%x\n", ifp
, ifp
->if_index
);
2584 ifnet_lock_done(ifp
);
2586 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_ATTACHED
, NULL
, 0);
2595 struct ifnet_filter
*filter
;
2596 struct ifnet_filter
*filter_next
;
2599 struct ifnet_filter_head fhead
;
2600 struct dlil_threading_info
*inputthread
;
2602 if (ifp
== NULL
) return EINVAL
;
2604 ifnet_lock_exclusive(ifp
);
2606 if ((ifp
->if_eflags
& IFEF_DETACHING
) != 0) {
2607 /* Interface has already been detached */
2608 ifnet_lock_done(ifp
);
2613 * Indicate this interface is being detached.
2615 * This should prevent protocols from attaching
2616 * from this point on. Interface will remain on
2617 * the list until all of the protocols are detached.
2619 ifp
->if_eflags
|= IFEF_DETACHING
;
2620 ifnet_lock_done(ifp
);
2622 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IF_DETACHING
, NULL
, 0);
2624 /* Let BPF know we're detaching */
2627 if ((retval
= dlil_write_begin()) != 0) {
2628 if (retval
== EDEADLK
) {
2631 /* We need to perform a delayed detach */
2632 ifp
->if_delayed_detach
= 1;
2633 dlil_detach_waiting
= 1;
2634 wakeup(&dlil_detach_waiting
);
2639 /* Steal the list of interface filters */
2640 fhead
= ifp
->if_flt_head
;
2641 TAILQ_INIT(&ifp
->if_flt_head
);
2643 /* unuse the interface */
2644 zeroed
= ifp_unuse(ifp
);
2647 * If thread affinity was set for the workloop thread, we will need
2648 * to tear down the affinity and release the extra reference count
2649 * taken at attach time;
2651 if ((inputthread
= ifp
->if_input_thread
) != NULL
) {
2652 if (inputthread
->net_affinity
) {
2655 if (inputthread
== dlil_lo_thread_ptr
)
2656 panic("Thread affinity should not be enabled "
2657 "on the loopback dlil input thread\n");
2659 lck_mtx_lock(inputthread
->input_lck
);
2660 tp
= inputthread
->workloop_thread
;
2661 inputthread
->workloop_thread
= NULL
;
2662 inputthread
->tag
= 0;
2663 inputthread
->net_affinity
= FALSE
;
2664 lck_mtx_unlock(inputthread
->input_lck
);
2666 /* Tear down workloop thread affinity */
2668 (void) dlil_affinity_set(tp
,
2669 THREAD_AFFINITY_TAG_NULL
);
2670 thread_deallocate(tp
);
2673 /* Tear down dlil input thread affinity */
2674 tp
= inputthread
->input_thread
;
2675 (void) dlil_affinity_set(tp
, THREAD_AFFINITY_TAG_NULL
);
2676 thread_deallocate(tp
);
2679 /* cleanup ifp dlil input thread, if any */
2680 ifp
->if_input_thread
= NULL
;
2682 if (inputthread
!= dlil_lo_thread_ptr
) {
2684 printf("ifnet_detach: wakeup thread threadinfo: %p "
2685 "input_thread=%p threads: cur=%d max=%d\n",
2686 inputthread
, inputthread
->input_thread
,
2687 dlil_multithreaded_input
, cur_dlil_input_threads
);
2689 lck_mtx_lock(inputthread
->input_lck
);
2691 inputthread
->input_waiting
|= DLIL_INPUT_TERMINATE
;
2692 if ((inputthread
->input_waiting
& DLIL_INPUT_RUNNING
) == 0) {
2693 wakeup((caddr_t
)&inputthread
->input_waiting
);
2695 lck_mtx_unlock(inputthread
->input_lck
);
2700 for (filter
= TAILQ_FIRST(&fhead
); filter
; filter
= filter_next
) {
2701 filter_next
= TAILQ_NEXT(filter
, filt_next
);
2702 dlil_detach_filter_internal(filter
, 1);
2706 ifp_use_reached_zero(ifp
);
2714 __unused ifnet_t ifnet_ptr
,
2715 __unused u_int32_t ioctl_code
,
2716 __unused
void *ioctl_arg
)
2722 dlil_recycle_output(
2723 __unused
struct ifnet
*ifnet_ptr
,
2732 __unused ifnet_t ifnet_ptr
)
2737 dlil_recycle_set_bpf_tap(
2738 __unused ifnet_t ifp
,
2739 __unused bpf_tap_mode mode
,
2740 __unused bpf_packet_func callback
)
2742 /* XXX not sure what to do here */
2747 int dlil_if_acquire(
2749 const void *uniqueid
,
2750 size_t uniqueid_len
,
2753 struct ifnet
*ifp1
= NULL
;
2754 struct dlil_ifnet
*dlifp1
= NULL
;
2757 lck_mtx_lock(dlil_ifnet_mutex
);
2758 TAILQ_FOREACH(dlifp1
, &dlil_ifnet_head
, dl_if_link
) {
2760 ifp1
= (struct ifnet
*)dlifp1
;
2762 if (ifp1
->if_family
== family
) {
2764 /* same uniqueid and same len or no unique id specified */
2765 if ((uniqueid_len
== dlifp1
->if_uniqueid_len
)
2766 && !bcmp(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
)) {
2768 /* check for matching interface in use */
2769 if (ifp1
->if_eflags
& IFEF_INUSE
) {
2777 panic("ifp's lock is gone\n");
2778 ifnet_lock_exclusive(ifp1
);
2779 ifp1
->if_eflags
|= (IFEF_INUSE
| IFEF_REUSE
);
2780 ifnet_lock_done(ifp1
);
2788 /* no interface found, allocate a new one */
2789 MALLOC(dlifp1
, struct dlil_ifnet
*, sizeof(*dlifp1
), M_NKE
, M_WAITOK
);
2795 bzero(dlifp1
, sizeof(*dlifp1
));
2798 MALLOC(dlifp1
->if_uniqueid
, void *, uniqueid_len
, M_NKE
, M_WAITOK
);
2799 if (dlifp1
->if_uniqueid
== 0) {
2800 FREE(dlifp1
, M_NKE
);
2804 bcopy(uniqueid
, dlifp1
->if_uniqueid
, uniqueid_len
);
2805 dlifp1
->if_uniqueid_len
= uniqueid_len
;
2808 ifp1
= (struct ifnet
*)dlifp1
;
2809 ifp1
->if_eflags
|= IFEF_INUSE
;
2810 ifp1
->if_name
= dlifp1
->if_namestorage
;
2812 mac_ifnet_label_init(ifp1
);
2815 TAILQ_INSERT_TAIL(&dlil_ifnet_head
, dlifp1
, dl_if_link
);
2820 lck_mtx_unlock(dlil_ifnet_mutex
);
2825 __private_extern__
void
2829 struct dlil_ifnet
*dlifp
= (struct dlil_ifnet
*)ifp
;
2831 /* Interface does not have a lock until it is attached - radar 3713951 */
2833 ifnet_lock_exclusive(ifp
);
2834 ifp
->if_eflags
&= ~IFEF_INUSE
;
2835 ifp
->if_ioctl
= dlil_recycle_ioctl
;
2836 ifp
->if_output
= dlil_recycle_output
;
2837 ifp
->if_free
= dlil_recycle_free
;
2838 ifp
->if_set_bpf_tap
= dlil_recycle_set_bpf_tap
;
2840 strncpy(dlifp
->if_namestorage
, ifp
->if_name
, IFNAMSIZ
);
2841 ifp
->if_name
= dlifp
->if_namestorage
;
2844 * We can either recycle the MAC label here or in dlil_if_acquire().
2845 * It seems logical to do it here but this means that anything that
2846 * still has a handle on ifp will now see it as unlabeled.
2847 * Since the interface is "dead" that may be OK. Revisit later.
2849 mac_ifnet_label_recycle(ifp
);
2852 ifnet_lock_done(ifp
);