]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/dlil.c
5f766f6b7af4b45a3771552806493dfe4397fab3
[apple/xnu.git] / bsd / net / dlil.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1999 Apple Computer, Inc.
24 *
25 * Data Link Inteface Layer
26 * Author: Ted Walker
27 */
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/malloc.h>
33 #include <sys/mbuf.h>
34 #include <sys/socket.h>
35 #include <sys/domain.h>
36 #include <sys/user.h>
37 #include <net/if_dl.h>
38 #include <net/if.h>
39 #include <net/route.h>
40 #include <net/if_var.h>
41 #include <net/dlil.h>
42 #include <net/if_arp.h>
43 #include <sys/kern_event.h>
44 #include <sys/kdebug.h>
45
46 #include <kern/assert.h>
47 #include <kern/task.h>
48 #include <kern/thread.h>
49 #include <kern/sched_prim.h>
50 #include <kern/locks.h>
51
52 #include <net/if_types.h>
53 #include <net/kpi_interfacefilter.h>
54
55 #include <libkern/OSAtomic.h>
56
57 #include <machine/machine_routines.h>
58
59 #define DBG_LAYER_BEG DLILDBG_CODE(DBG_DLIL_STATIC, 0)
60 #define DBG_LAYER_END DLILDBG_CODE(DBG_DLIL_STATIC, 2)
61 #define DBG_FNC_DLIL_INPUT DLILDBG_CODE(DBG_DLIL_STATIC, (1 << 8))
62 #define DBG_FNC_DLIL_OUTPUT DLILDBG_CODE(DBG_DLIL_STATIC, (2 << 8))
63 #define DBG_FNC_DLIL_IFOUT DLILDBG_CODE(DBG_DLIL_STATIC, (3 << 8))
64
65
66 #define MAX_DL_TAGS 16
67 #define MAX_DLIL_FILTERS 16
68 #define MAX_FRAME_TYPE_SIZE 4 /* LONGWORDS */
69 #define MAX_LINKADDR 4 /* LONGWORDS */
70 #define M_NKE M_IFADDR
71
72 #define PFILT(x) ((struct dlil_filterq_entry *) (x))->variants.pr_filter
73 #define IFILT(x) ((struct dlil_filterq_entry *) (x))->variants.if_filter
74
75 #if 0
76 #define DLIL_PRINTF printf
77 #else
78 #define DLIL_PRINTF kprintf
79 #endif
80
81 //#define DLIL_ALWAYS_DELAY_DETACH 1
82
83 enum {
84 kProtoKPI_DLIL = 0,
85 kProtoKPI_v1 = 1
86 };
87
88 struct if_proto {
89 SLIST_ENTRY(if_proto) next_hash;
90 int refcount;
91 int detaching;
92 struct ifnet *ifp;
93 struct domain *dl_domain;
94 protocol_family_t protocol_family;
95 int proto_kpi;
96 union {
97 struct {
98 dl_input_func dl_input;
99 dl_pre_output_func dl_pre_output;
100 dl_event_func dl_event;
101 dl_offer_func dl_offer;
102 dl_ioctl_func dl_ioctl;
103 dl_detached_func dl_detached;
104 } dlil;
105 struct {
106 proto_media_input input;
107 proto_media_preout pre_output;
108 proto_media_event event;
109 proto_media_ioctl ioctl;
110 proto_media_detached detached;
111 proto_media_resolve_multi resolve_multi;
112 proto_media_send_arp send_arp;
113 } v1;
114 } kpi;
115 };
116
117 SLIST_HEAD(proto_hash_entry, if_proto);
118
119
120 struct dlil_ifnet {
121 /* ifnet and drvr_ext are used by the stack and drivers
122 drvr_ext extends the public ifnet and must follow dl_if */
123 struct ifnet dl_if; /* public ifnet */
124
125 /* dlil private fields */
126 TAILQ_ENTRY(dlil_ifnet) dl_if_link; /* dlil_ifnet are link together */
127 /* it is not the ifnet list */
128 void *if_uniqueid; /* unique id identifying the interface */
129 size_t if_uniqueid_len;/* length of the unique id */
130 char if_namestorage[IFNAMSIZ]; /* interface name storage */
131 };
132
133 struct ifnet_filter {
134 TAILQ_ENTRY(ifnet_filter) filt_next;
135 ifnet_t filt_ifp;
136 int filt_detaching;
137
138 const char *filt_name;
139 void *filt_cookie;
140 protocol_family_t filt_protocol;
141 iff_input_func filt_input;
142 iff_output_func filt_output;
143 iff_event_func filt_event;
144 iff_ioctl_func filt_ioctl;
145 iff_detached_func filt_detached;
146 };
147
148 struct if_family_str {
149 TAILQ_ENTRY(if_family_str) if_fam_next;
150 u_long if_family;
151 int refcnt;
152 int flags;
153
154 #define DLIL_SHUTDOWN 1
155
156 int (*add_if)(struct ifnet *ifp);
157 int (*del_if)(struct ifnet *ifp);
158 int (*init_if)(struct ifnet *ifp);
159 int (*add_proto)(struct ifnet *ifp, u_long protocol_family, struct ddesc_head_str *demux_desc_head);
160 ifnet_del_proto_func del_proto;
161 ifnet_ioctl_func ifmod_ioctl;
162 int (*shutdown)(void);
163 };
164
165 struct proto_family_str {
166 TAILQ_ENTRY(proto_family_str) proto_fam_next;
167 u_long proto_family;
168 u_long if_family;
169 int usecnt;
170
171 int (*attach_proto)(struct ifnet *ifp, u_long protocol_family);
172 int (*detach_proto)(struct ifnet *ifp, u_long protocol_family);
173 };
174
175 enum {
176 kIfNetUseCount_MayBeZero = 0,
177 kIfNetUseCount_MustNotBeZero = 1
178 };
179
180 static TAILQ_HEAD(, dlil_ifnet) dlil_ifnet_head;
181 static TAILQ_HEAD(, if_family_str) if_family_head;
182 static TAILQ_HEAD(, proto_family_str) proto_family_head;
183 static lck_grp_t *dlil_lock_group;
184 static lck_grp_t *ifnet_lock_group;
185 static lck_grp_t *ifnet_head_lock_group;
186 static lck_attr_t *ifnet_lock_attr;
187 static lck_mtx_t *proto_family_mutex;
188 static lck_rw_t *ifnet_head_mutex;
189 static lck_mtx_t *dlil_ifnet_mutex;
190 static lck_mtx_t *dlil_mutex;
191 static unsigned long dlil_read_count = 0;
192 static unsigned long dlil_detach_waiting = 0;
193 extern u_int32_t ipv4_ll_arp_aware;
194
195 int dlil_initialized = 0;
196 lck_spin_t *dlil_input_lock;
197 __private_extern__ thread_t dlil_input_thread_ptr = 0;
198 int dlil_input_thread_wakeup = 0;
199 __private_extern__ int dlil_output_thread_wakeup = 0;
200 static struct mbuf *dlil_input_mbuf_head = NULL;
201 static struct mbuf *dlil_input_mbuf_tail = NULL;
202 #if NLOOP > 1
203 #error dlil_input() needs to be revised to support more than on loopback interface
204 #endif
205 static struct mbuf *dlil_input_loop_head = NULL;
206 static struct mbuf *dlil_input_loop_tail = NULL;
207
208 static void dlil_input_thread(void);
209 static int dlil_event_internal(struct ifnet *ifp, struct kev_msg *msg);
210 struct ifnet *ifbyfamily(u_long family, short unit);
211 static int dlil_detach_filter_internal(interface_filter_t filter, int detached);
212 static void dlil_call_delayed_detach_thread(void);
213
214 static void dlil_read_begin(void);
215 static void dlil_read_end(void);
216 static int dlil_write_begin(void);
217 static void dlil_write_end(void);
218
219 static int ifp_use(struct ifnet *ifp, int handle_zero);
220 static int ifp_unuse(struct ifnet *ifp);
221 static void ifp_use_reached_zero(struct ifnet *ifp);
222
223 extern void bpfdetach(struct ifnet*);
224 extern void proto_input_run(void); // new run_netisr
225
226
227 int dlil_input_packet(struct ifnet *ifp, struct mbuf *m, char *frame_header);
228
229 __private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *);
230
231 int dlil_expand_mcl;
232
233 extern u_int32_t inject_buckets;
234
235 static const u_int32_t dlil_writer_waiting = 0x80000000;
236
237 static __inline__ void*
238 _cast_non_const(const void * ptr) {
239 union {
240 const void* cval;
241 void* val;
242 } ret;
243
244 ret.cval = ptr;
245 return (ret.val);
246 }
247
248 /* Should these be inline? */
249 static void
250 dlil_read_begin(void)
251 {
252 unsigned long new_value;
253 unsigned long old_value;
254 struct uthread *uth = get_bsdthread_info(current_thread());
255
256 if (uth->dlil_incremented_read == dlil_writer_waiting)
257 panic("dlil_read_begin - thread is already a writer");
258
259 do {
260 again:
261 old_value = dlil_read_count;
262
263 if ((old_value & dlil_writer_waiting) != 0 && uth->dlil_incremented_read == 0)
264 {
265 tsleep(&dlil_read_count, PRIBIO, "dlil_read_count", 1);
266 goto again;
267 }
268
269 new_value = old_value + 1;
270 } while (!OSCompareAndSwap((UInt32)old_value, (UInt32)new_value, (UInt32*)&dlil_read_count));
271
272 uth->dlil_incremented_read++;
273 }
274
275 static void
276 dlil_read_end(void)
277 {
278 struct uthread *uth = get_bsdthread_info(current_thread());
279
280 OSDecrementAtomic((UInt32*)&dlil_read_count);
281 uth->dlil_incremented_read--;
282 if (dlil_read_count == dlil_writer_waiting)
283 wakeup(_cast_non_const(&dlil_writer_waiting));
284 }
285
286 static int
287 dlil_write_begin(void)
288 {
289 struct uthread *uth = get_bsdthread_info(current_thread());
290
291 if (uth->dlil_incremented_read != 0) {
292 return EDEADLK;
293 }
294 lck_mtx_lock(dlil_mutex);
295 OSBitOrAtomic((UInt32)dlil_writer_waiting, (UInt32*)&dlil_read_count);
296 again:
297 if (dlil_read_count == dlil_writer_waiting) {
298 uth->dlil_incremented_read = dlil_writer_waiting;
299 return 0;
300 }
301 else {
302 tsleep(_cast_non_const(&dlil_writer_waiting), PRIBIO, "dlil_writer_waiting", 1);
303 goto again;
304 }
305 }
306
307 static void
308 dlil_write_end(void)
309 {
310 struct uthread *uth = get_bsdthread_info(current_thread());
311
312 if (uth->dlil_incremented_read != dlil_writer_waiting)
313 panic("dlil_write_end - thread is not a writer");
314 OSBitAndAtomic((UInt32)~dlil_writer_waiting, (UInt32*)&dlil_read_count);
315 lck_mtx_unlock(dlil_mutex);
316 uth->dlil_incremented_read = 0;
317 wakeup(&dlil_read_count);
318 }
319
320 #define PROTO_HASH_SLOTS 0x5
321
322 /*
323 * Internal functions.
324 */
325
326 static int
327 proto_hash_value(u_long protocol_family)
328 {
329 switch(protocol_family) {
330 case PF_INET:
331 return 0;
332 case PF_INET6:
333 return 1;
334 case PF_APPLETALK:
335 return 2;
336 case PF_VLAN:
337 return 3;
338 default:
339 return 4;
340 }
341 }
342
343 static
344 struct if_family_str *find_family_module(u_long if_family)
345 {
346 struct if_family_str *mod = NULL;
347
348 TAILQ_FOREACH(mod, &if_family_head, if_fam_next) {
349 if (mod->if_family == (if_family & 0xffff))
350 break;
351 }
352
353 return mod;
354 }
355
356 static
357 struct proto_family_str*
358 find_proto_module(u_long proto_family, u_long if_family)
359 {
360 struct proto_family_str *mod = NULL;
361
362 TAILQ_FOREACH(mod, &proto_family_head, proto_fam_next) {
363 if ((mod->proto_family == (proto_family & 0xffff))
364 && (mod->if_family == (if_family & 0xffff)))
365 break;
366 }
367
368 return mod;
369 }
370
371 static struct if_proto*
372 find_attached_proto(struct ifnet *ifp, u_long protocol_family)
373 {
374 struct if_proto *proto = NULL;
375 u_long i = proto_hash_value(protocol_family);
376 if (ifp->if_proto_hash) {
377 proto = SLIST_FIRST(&ifp->if_proto_hash[i]);
378 }
379
380 while(proto && proto->protocol_family != protocol_family) {
381 proto = SLIST_NEXT(proto, next_hash);
382 }
383
384 return proto;
385 }
386
387 static void
388 if_proto_ref(struct if_proto *proto)
389 {
390 OSAddAtomic(1, (UInt32*)&proto->refcount);
391 }
392
393 static void
394 if_proto_free(struct if_proto *proto)
395 {
396 int oldval = OSAddAtomic(-1, (UInt32*)&proto->refcount);
397
398 if (oldval == 1) { /* This was the last reference */
399 FREE(proto, M_IFADDR);
400 }
401 }
402
403 __private_extern__ void
404 ifnet_lock_assert(
405 __unused struct ifnet *ifp,
406 __unused int what)
407 {
408 #if IFNET_RW_LOCK
409 /*
410 * Not implemented for rw locks.
411 *
412 * Function exists so when/if we use mutex we can
413 * enable this check.
414 */
415 #else
416 lck_mtx_assert(ifp->if_lock, what);
417 #endif
418 }
419
420 __private_extern__ void
421 ifnet_lock_shared(
422 struct ifnet *ifp)
423 {
424 #if IFNET_RW_LOCK
425 lck_rw_lock_shared(ifp->if_lock);
426 #else
427 lck_mtx_assert(ifp->if_lock, LCK_MTX_ASSERT_NOTOWNED);
428 lck_mtx_lock(ifp->if_lock);
429 #endif
430 }
431
432 __private_extern__ void
433 ifnet_lock_exclusive(
434 struct ifnet *ifp)
435 {
436 #if IFNET_RW_LOCK
437 lck_rw_lock_exclusive(ifp->if_lock);
438 #else
439 lck_mtx_assert(ifp->if_lock, LCK_MTX_ASSERT_NOTOWNED);
440 lck_mtx_lock(ifp->if_lock);
441 #endif
442 }
443
444 __private_extern__ void
445 ifnet_lock_done(
446 struct ifnet *ifp)
447 {
448 #if IFNET_RW_LOCK
449 lck_rw_done(ifp->if_lock);
450 #else
451 lck_mtx_assert(ifp->if_lock, LCK_MTX_ASSERT_OWNED);
452 lck_mtx_unlock(ifp->if_lock);
453 #endif
454 }
455
456 __private_extern__ void
457 ifnet_head_lock_shared()
458 {
459 lck_rw_lock_shared(ifnet_head_mutex);
460 }
461
462 __private_extern__ void
463 ifnet_head_lock_exclusive()
464 {
465 lck_rw_lock_exclusive(ifnet_head_mutex);
466 }
467
468 __private_extern__ void
469 ifnet_head_done()
470 {
471 lck_rw_done(ifnet_head_mutex);
472 }
473
474 /*
475 * Public functions.
476 */
477 struct ifnet *ifbyfamily(u_long family, short unit)
478 {
479 struct ifnet *ifp;
480
481 ifnet_head_lock_shared();
482 TAILQ_FOREACH(ifp, &ifnet_head, if_link)
483 if ((family == ifp->if_family) && (ifp->if_unit == unit))
484 break;
485 ifnet_head_done();
486
487 return ifp;
488 }
489
490 static int dlil_ifp_proto_count(struct ifnet * ifp)
491 {
492 int count = 0;
493 int i;
494
495 if (ifp->if_proto_hash != NULL) {
496 for (i = 0; i < PROTO_HASH_SLOTS; i++) {
497 struct if_proto *proto;
498 SLIST_FOREACH(proto, &ifp->if_proto_hash[i], next_hash) {
499 count++;
500 }
501 }
502 }
503
504 return count;
505 }
506
507 __private_extern__ void
508 dlil_post_msg(struct ifnet *ifp, u_long event_subclass, u_long event_code,
509 struct net_event_data *event_data, u_long event_data_len)
510 {
511 struct net_event_data ev_data;
512 struct kev_msg ev_msg;
513
514 /*
515 * a net event always start with a net_event_data structure
516 * but the caller can generate a simple net event or
517 * provide a longer event structure to post
518 */
519
520 ev_msg.vendor_code = KEV_VENDOR_APPLE;
521 ev_msg.kev_class = KEV_NETWORK_CLASS;
522 ev_msg.kev_subclass = event_subclass;
523 ev_msg.event_code = event_code;
524
525 if (event_data == 0) {
526 event_data = &ev_data;
527 event_data_len = sizeof(struct net_event_data);
528 }
529
530 strncpy(&event_data->if_name[0], ifp->if_name, IFNAMSIZ);
531 event_data->if_family = ifp->if_family;
532 event_data->if_unit = (unsigned long) ifp->if_unit;
533
534 ev_msg.dv[0].data_length = event_data_len;
535 ev_msg.dv[0].data_ptr = event_data;
536 ev_msg.dv[1].data_length = 0;
537
538 dlil_event_internal(ifp, &ev_msg);
539 }
540
541 void dlil_init(void);
542 void
543 dlil_init(void)
544 {
545 lck_grp_attr_t *grp_attributes = 0;
546 lck_attr_t *lck_attributes = 0;
547 lck_grp_t *input_lock_grp = 0;
548
549 TAILQ_INIT(&dlil_ifnet_head);
550 TAILQ_INIT(&if_family_head);
551 TAILQ_INIT(&proto_family_head);
552 TAILQ_INIT(&ifnet_head);
553
554 /* Setup the lock groups we will use */
555 grp_attributes = lck_grp_attr_alloc_init();
556 lck_grp_attr_setdefault(grp_attributes);
557
558 dlil_lock_group = lck_grp_alloc_init("dlil internal locks", grp_attributes);
559 #if IFNET_RW_LOCK
560 ifnet_lock_group = lck_grp_alloc_init("ifnet locks", grp_attributes);
561 #else
562 ifnet_lock_group = lck_grp_alloc_init("ifnet locks", grp_attributes);
563 #endif
564 ifnet_head_lock_group = lck_grp_alloc_init("ifnet head lock", grp_attributes);
565 input_lock_grp = lck_grp_alloc_init("dlil input lock", grp_attributes);
566 lck_grp_attr_free(grp_attributes);
567 grp_attributes = 0;
568
569 /* Setup the lock attributes we will use */
570 lck_attributes = lck_attr_alloc_init();
571 lck_attr_setdefault(lck_attributes);
572
573 ifnet_lock_attr = lck_attr_alloc_init();
574 lck_attr_setdefault(ifnet_lock_attr);
575
576 dlil_input_lock = lck_spin_alloc_init(input_lock_grp, lck_attributes);
577 input_lock_grp = 0;
578
579 ifnet_head_mutex = lck_rw_alloc_init(ifnet_head_lock_group, lck_attributes);
580 proto_family_mutex = lck_mtx_alloc_init(dlil_lock_group, lck_attributes);
581 dlil_ifnet_mutex = lck_mtx_alloc_init(dlil_lock_group, lck_attributes);
582 dlil_mutex = lck_mtx_alloc_init(dlil_lock_group, lck_attributes);
583
584 lck_attr_free(lck_attributes);
585 lck_attributes = 0;
586
587 /*
588 * Start up the dlil input thread once everything is initialized
589 */
590 (void) kernel_thread(kernel_task, dlil_input_thread);
591 (void) kernel_thread(kernel_task, dlil_call_delayed_detach_thread);
592 }
593
594 int
595 dlil_attach_filter(
596 struct ifnet *ifp,
597 const struct iff_filter *if_filter,
598 interface_filter_t *filter_ref)
599 {
600 int retval = 0;
601 struct ifnet_filter *filter;
602
603 MALLOC(filter, struct ifnet_filter *, sizeof(*filter), M_NKE, M_WAITOK);
604 if (filter == NULL)
605 return ENOMEM;
606 bzero(filter, sizeof(*filter));
607
608
609 filter->filt_ifp = ifp;
610 filter->filt_cookie = if_filter->iff_cookie;
611 filter->filt_name = if_filter->iff_name;
612 filter->filt_protocol = if_filter->iff_protocol;
613 filter->filt_input = if_filter->iff_input;
614 filter->filt_output = if_filter->iff_output;
615 filter->filt_event = if_filter->iff_event;
616 filter->filt_ioctl = if_filter->iff_ioctl;
617 filter->filt_detached = if_filter->iff_detached;
618
619 if ((retval = dlil_write_begin()) != 0) {
620 /* Failed to acquire the write lock */
621 FREE(filter, M_NKE);
622 return retval;
623 }
624 TAILQ_INSERT_TAIL(&ifp->if_flt_head, filter, filt_next);
625 dlil_write_end();
626 *filter_ref = filter;
627 return retval;
628 }
629
630 static int
631 dlil_detach_filter_internal(interface_filter_t filter, int detached)
632 {
633 int retval = 0;
634
635
636 /* Take the write lock */
637 #if DLIL_ALWAYS_DELAY_DETACH
638 retval = EDEADLK;
639 #else
640 if (detached == 0 && (retval = dlil_write_begin()) != 0)
641 #endif
642 {
643 if (retval == EDEADLK) {
644 /* Perform a delayed detach */
645 filter->filt_detaching = 1;
646 dlil_detach_waiting = 1;
647 wakeup(&dlil_detach_waiting);
648 retval = 0;
649 }
650 return retval;
651 }
652
653 if (detached == 0)
654 TAILQ_REMOVE(&filter->filt_ifp->if_flt_head, filter, filt_next);
655
656 /* release the write lock */
657 if (detached == 0)
658 dlil_write_end();
659
660 if (filter->filt_detached)
661 filter->filt_detached(filter->filt_cookie, filter->filt_ifp);
662
663 FREE(filter, M_NKE);
664
665 return retval;
666 }
667
668 void
669 dlil_detach_filter(interface_filter_t filter)
670 {
671 dlil_detach_filter_internal(filter, 0);
672 }
673
674 static void
675 dlil_input_thread_continue(
676 __unused void* foo,
677 __unused wait_result_t wait)
678 {
679 while (1) {
680 struct mbuf *m, *m_loop;
681
682 lck_spin_lock(dlil_input_lock);
683 m = dlil_input_mbuf_head;
684 dlil_input_mbuf_head = NULL;
685 dlil_input_mbuf_tail = NULL;
686 m_loop = dlil_input_loop_head;
687 dlil_input_loop_head = NULL;
688 dlil_input_loop_tail = NULL;
689 lck_spin_unlock(dlil_input_lock);
690
691 /*
692 * NOTE warning %%% attention !!!!
693 * We should think about putting some thread starvation safeguards if
694 * we deal with long chains of packets.
695 */
696 while (m) {
697 struct mbuf *m0 = m->m_nextpkt;
698 void *header = m->m_pkthdr.header;
699
700 m->m_nextpkt = NULL;
701 m->m_pkthdr.header = NULL;
702 (void) dlil_input_packet(m->m_pkthdr.rcvif, m, header);
703 m = m0;
704 }
705 m = m_loop;
706 while (m) {
707 struct mbuf *m0 = m->m_nextpkt;
708 void *header = m->m_pkthdr.header;
709 struct ifnet *ifp = &loif[0];
710
711 m->m_nextpkt = NULL;
712 m->m_pkthdr.header = NULL;
713 (void) dlil_input_packet(ifp, m, header);
714 m = m0;
715 }
716
717 proto_input_run();
718
719 if (dlil_input_mbuf_head == NULL &&
720 dlil_input_loop_head == NULL && inject_buckets == 0) {
721 assert_wait(&dlil_input_thread_wakeup, THREAD_UNINT);
722 (void) thread_block(dlil_input_thread_continue);
723 /* NOTREACHED */
724 }
725 }
726 }
727
728 void dlil_input_thread(void)
729 {
730 register thread_t self = current_thread();
731
732 ml_thread_policy(self, MACHINE_GROUP,
733 (MACHINE_NETWORK_GROUP|MACHINE_NETWORK_NETISR));
734
735 dlil_initialized = 1;
736 dlil_input_thread_ptr = current_thread();
737 dlil_input_thread_continue(NULL, THREAD_RESTART);
738 }
739
740 int
741 dlil_input_with_stats(
742 struct ifnet *ifp,
743 struct mbuf *m_head,
744 struct mbuf *m_tail,
745 const struct ifnet_stat_increment_param *stats)
746 {
747 /* WARNING
748 * Because of loopbacked multicast we cannot stuff the ifp in
749 * the rcvif of the packet header: loopback has its own dlil
750 * input queue
751 */
752
753 lck_spin_lock(dlil_input_lock);
754 if (ifp->if_type != IFT_LOOP) {
755 if (dlil_input_mbuf_head == NULL)
756 dlil_input_mbuf_head = m_head;
757 else if (dlil_input_mbuf_tail != NULL)
758 dlil_input_mbuf_tail->m_nextpkt = m_head;
759 dlil_input_mbuf_tail = m_tail ? m_tail : m_head;
760 } else {
761 if (dlil_input_loop_head == NULL)
762 dlil_input_loop_head = m_head;
763 else if (dlil_input_loop_tail != NULL)
764 dlil_input_loop_tail->m_nextpkt = m_head;
765 dlil_input_loop_tail = m_tail ? m_tail : m_head;
766 }
767 if (stats) {
768 ifp->if_data.ifi_ipackets += stats->packets_in;
769 ifp->if_data.ifi_ibytes += stats->bytes_in;
770 ifp->if_data.ifi_ierrors += stats->errors_in;
771
772 ifp->if_data.ifi_opackets += stats->packets_out;
773 ifp->if_data.ifi_obytes += stats->bytes_out;
774 ifp->if_data.ifi_oerrors += stats->errors_out;
775
776 ifp->if_data.ifi_collisions += stats->collisions;
777 ifp->if_data.ifi_iqdrops += stats->dropped;
778 }
779 lck_spin_unlock(dlil_input_lock);
780
781 wakeup((caddr_t)&dlil_input_thread_wakeup);
782
783 return 0;
784 }
785
786 int
787 dlil_input(struct ifnet *ifp, struct mbuf *m_head, struct mbuf *m_tail)
788 {
789 return dlil_input_with_stats(ifp, m_head, m_tail, NULL);
790 }
791
792 int
793 dlil_input_packet(struct ifnet *ifp, struct mbuf *m,
794 char *frame_header)
795 {
796 int retval;
797 struct if_proto *ifproto = 0;
798 protocol_family_t protocol_family;
799 struct ifnet_filter *filter;
800
801
802 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT | DBG_FUNC_START,0,0,0,0,0);
803
804 /*
805 * Lock the interface while we run through
806 * the filters and the demux. This lock
807 * protects the filter list and the demux list.
808 */
809 dlil_read_begin();
810
811 /*
812 * Call family demux module. If the demux module finds a match
813 * for the frame it will fill-in the ifproto pointer.
814 */
815
816 retval = ifp->if_demux(ifp, m, frame_header, &protocol_family);
817 if (retval != 0)
818 protocol_family = 0;
819 if (retval == EJUSTRETURN) {
820 dlil_read_end();
821 return 0;
822 }
823
824 /* DANGER!!! */
825 if (m->m_flags & (M_BCAST|M_MCAST))
826 ifp->if_imcasts++;
827
828 /*
829 * Run interface filters
830 */
831
832 /* Do not pass VLAN tagged packets to filters PR-3586856 */
833 if ((m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) == 0) {
834 TAILQ_FOREACH(filter, &ifp->if_flt_head, filt_next) {
835 int filter_result;
836 if (filter->filt_input && (filter->filt_protocol == 0 ||
837 filter->filt_protocol == protocol_family)) {
838 filter_result = filter->filt_input(filter->filt_cookie, ifp, protocol_family, &m, &frame_header);
839
840 if (filter_result) {
841 dlil_read_end();
842 if (filter_result == EJUSTRETURN) {
843 filter_result = 0;
844 }
845 else {
846 m_freem(m);
847 }
848
849 return filter_result;
850 }
851 }
852 }
853 }
854
855 /* Demux is done, interface filters have been processed, unlock the mutex */
856 if (retval || ((m->m_flags & M_PROMISC) != 0) ) {
857 dlil_read_end();
858 if (retval != EJUSTRETURN) {
859 m_freem(m);
860 return retval;
861 }
862 else
863 return 0;
864 }
865
866 ifproto = find_attached_proto(ifp, protocol_family);
867
868 if (ifproto == 0) {
869 dlil_read_end();
870 DLIL_PRINTF("ERROR - dlil_input - if_demux didn't return an if_proto pointer\n");
871 m_freem(m);
872 return 0;
873 }
874
875 /*
876 * Hand the packet off to the protocol.
877 */
878
879 if (ifproto->dl_domain && (ifproto->dl_domain->dom_flags & DOM_REENTRANT) == 0) {
880 lck_mtx_lock(ifproto->dl_domain->dom_mtx);
881 }
882
883 if (ifproto->proto_kpi == kProtoKPI_DLIL)
884 retval = (*ifproto->kpi.dlil.dl_input)(m, frame_header,
885 ifp, ifproto->protocol_family,
886 TRUE);
887 else
888 retval = ifproto->kpi.v1.input(ifp, ifproto->protocol_family, m, frame_header);
889
890 if (ifproto->dl_domain && (ifproto->dl_domain->dom_flags & DOM_REENTRANT) == 0) {
891 lck_mtx_unlock(ifproto->dl_domain->dom_mtx);
892 }
893
894 dlil_read_end();
895
896 if (retval == EJUSTRETURN)
897 retval = 0;
898 else
899 if (retval)
900 m_freem(m);
901
902 KERNEL_DEBUG(DBG_FNC_DLIL_INPUT | DBG_FUNC_END,0,0,0,0,0);
903 return retval;
904 }
905
906 static int
907 dlil_event_internal(struct ifnet *ifp, struct kev_msg *event)
908 {
909 struct ifnet_filter *filter;
910
911 if (ifp_use(ifp, kIfNetUseCount_MustNotBeZero) == 0) {
912 dlil_read_begin();
913
914 /* Pass the event to the interface filters */
915 TAILQ_FOREACH(filter, &ifp->if_flt_head, filt_next) {
916 if (filter->filt_event)
917 filter->filt_event(filter->filt_cookie, ifp, filter->filt_protocol, event);
918 }
919
920 if (ifp->if_proto_hash) {
921 int i;
922
923 for (i = 0; i < PROTO_HASH_SLOTS; i++) {
924 struct if_proto *proto;
925
926 SLIST_FOREACH(proto, &ifp->if_proto_hash[i], next_hash) {
927 /* Pass the event to the protocol */
928 if (proto->proto_kpi == kProtoKPI_DLIL) {
929 if (proto->kpi.dlil.dl_event)
930 proto->kpi.dlil.dl_event(ifp, event);
931 }
932 else {
933 if (proto->kpi.v1.event)
934 proto->kpi.v1.event(ifp, proto->protocol_family, event);
935 }
936 }
937 }
938 }
939
940 dlil_read_end();
941
942 /* Pass the event to the interface */
943 if (ifp->if_event)
944 ifp->if_event(ifp, event);
945
946 if (ifp_unuse(ifp))
947 ifp_use_reached_zero(ifp);
948 }
949
950 return kev_post_msg(event);
951 }
952
953 int
954 dlil_event(struct ifnet *ifp, struct kern_event_msg *event)
955 {
956 int result = 0;
957
958 struct kev_msg kev_msg;
959
960 kev_msg.vendor_code = event->vendor_code;
961 kev_msg.kev_class = event->kev_class;
962 kev_msg.kev_subclass = event->kev_subclass;
963 kev_msg.event_code = event->event_code;
964 kev_msg.dv[0].data_ptr = &event->event_data[0];
965 kev_msg.dv[0].data_length = event->total_size - KEV_MSG_HEADER_SIZE;
966 kev_msg.dv[1].data_length = 0;
967
968
969 result = dlil_event_internal(ifp, &kev_msg);
970
971
972 return result;
973 }
974
975 dlil_output_list(
976 struct ifnet* ifp,
977 u_long proto_family,
978 struct mbuf *packetlist,
979 caddr_t route,
980 const struct sockaddr *dest,
981 int raw)
982 {
983 char *frame_type = 0;
984 char *dst_linkaddr = 0;
985 int error, retval = 0;
986 char frame_type_buffer[MAX_FRAME_TYPE_SIZE * 4];
987 char dst_linkaddr_buffer[MAX_LINKADDR * 4];
988 struct ifnet_filter *filter;
989 struct if_proto *proto = 0;
990 struct mbuf *m;
991
992 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT | DBG_FUNC_START,0,0,0,0,0);
993 #if BRIDGE
994 if ((raw != 0) || proto_family != PF_INET || do_brige) {
995 #else
996 if ((raw != 0) || proto_family != PF_INET) {
997 #endif
998 while (packetlist) {
999 m = packetlist;
1000 packetlist = packetlist->m_nextpkt;
1001 m->m_nextpkt = NULL;
1002 error = dlil_output(ifp, proto_family, m, route, dest, raw);
1003 if (error) {
1004 if (packetlist)
1005 m_freem_list(packetlist);
1006 return (error);
1007 }
1008 }
1009 return (0);
1010 }
1011
1012 dlil_read_begin();
1013
1014 frame_type = frame_type_buffer;
1015 dst_linkaddr = dst_linkaddr_buffer;
1016 m = packetlist;
1017 packetlist = packetlist->m_nextpkt;
1018 m->m_nextpkt = NULL;
1019
1020 proto = find_attached_proto(ifp, proto_family);
1021 if (proto == NULL) {
1022 retval = ENXIO;
1023 goto cleanup;
1024 }
1025
1026 retval = 0;
1027 if (proto->proto_kpi == kProtoKPI_DLIL) {
1028 if (proto->kpi.dlil.dl_pre_output)
1029 retval = proto->kpi.dlil.dl_pre_output(ifp, proto_family, &m, dest, route, frame_type, dst_linkaddr);
1030 }
1031 else {
1032 if (proto->kpi.v1.pre_output)
1033 retval = proto->kpi.v1.pre_output(ifp, proto_family, &m, dest, route, frame_type, dst_linkaddr);
1034 }
1035
1036 if (retval) {
1037 if (retval != EJUSTRETURN) {
1038 m_freem(m);
1039 }
1040 goto cleanup;
1041 }
1042
1043 do {
1044
1045
1046 if (ifp->if_framer) {
1047 retval = ifp->if_framer(ifp, &m, dest, dst_linkaddr, frame_type);
1048 if (retval) {
1049 if (retval != EJUSTRETURN) {
1050 m_freem(m);
1051 }
1052 goto cleanup;
1053 }
1054 }
1055
1056 /*
1057 * Let interface filters (if any) do their thing ...
1058 */
1059 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1060 if ((m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) == 0) {
1061 TAILQ_FOREACH(filter, &ifp->if_flt_head, filt_next) {
1062 if ((filter->filt_protocol == 0 || (filter->filt_protocol == proto_family)) &&
1063 filter->filt_output) {
1064 retval = filter->filt_output(filter->filt_cookie, ifp, proto_family, &m);
1065 if (retval) {
1066 if (retval == EJUSTRETURN)
1067 continue;
1068 else {
1069 m_freem(m);
1070 }
1071 goto cleanup;
1072 }
1073 }
1074 }
1075 }
1076 /*
1077 * Finally, call the driver.
1078 */
1079
1080 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT | DBG_FUNC_START, 0,0,0,0,0);
1081 retval = ifp->if_output(ifp, m);
1082 if (retval) {
1083 printf("dlil_output_list: output error retval = %x\n", retval);
1084 goto cleanup;
1085 }
1086 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT | DBG_FUNC_END, 0,0,0,0,0);
1087
1088 m = packetlist;
1089 if (m) {
1090 packetlist = packetlist->m_nextpkt;
1091 m->m_nextpkt = NULL;
1092 }
1093 } while (m);
1094
1095
1096 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT | DBG_FUNC_END,0,0,0,0,0);
1097
1098 cleanup:
1099 dlil_read_end();
1100 if (packetlist) /* if any packet left, clean up */
1101 m_freem_list(packetlist);
1102 if (retval == EJUSTRETURN)
1103 retval = 0;
1104 return retval;
1105 }
1106
1107 /*
1108 * dlil_output
1109 *
1110 * Caller should have a lock on the protocol domain if the protocol
1111 * doesn't support finer grained locking. In most cases, the lock
1112 * will be held from the socket layer and won't be released until
1113 * we return back to the socket layer.
1114 *
1115 * This does mean that we must take a protocol lock before we take
1116 * an interface lock if we're going to take both. This makes sense
1117 * because a protocol is likely to interact with an ifp while it
1118 * is under the protocol lock.
1119 */
1120 int
1121 dlil_output(
1122 struct ifnet* ifp,
1123 u_long proto_family,
1124 struct mbuf *m,
1125 caddr_t route,
1126 const struct sockaddr *dest,
1127 int raw)
1128 {
1129 char *frame_type = 0;
1130 char *dst_linkaddr = 0;
1131 int retval = 0;
1132 char frame_type_buffer[MAX_FRAME_TYPE_SIZE * 4];
1133 char dst_linkaddr_buffer[MAX_LINKADDR * 4];
1134 struct ifnet_filter *filter;
1135
1136 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT | DBG_FUNC_START,0,0,0,0,0);
1137
1138 dlil_read_begin();
1139
1140 frame_type = frame_type_buffer;
1141 dst_linkaddr = dst_linkaddr_buffer;
1142
1143 if (raw == 0) {
1144 struct if_proto *proto = 0;
1145
1146 proto = find_attached_proto(ifp, proto_family);
1147 if (proto == NULL) {
1148 m_freem(m);
1149 retval = ENXIO;
1150 goto cleanup;
1151 }
1152
1153 retval = 0;
1154 if (proto->proto_kpi == kProtoKPI_DLIL) {
1155 if (proto->kpi.dlil.dl_pre_output)
1156 retval = proto->kpi.dlil.dl_pre_output(ifp, proto_family, &m, dest, route, frame_type, dst_linkaddr);
1157 }
1158 else {
1159 if (proto->kpi.v1.pre_output)
1160 retval = proto->kpi.v1.pre_output(ifp, proto_family, &m, dest, route, frame_type, dst_linkaddr);
1161 }
1162
1163 if (retval) {
1164 if (retval != EJUSTRETURN) {
1165 m_freem(m);
1166 }
1167 goto cleanup;
1168 }
1169 }
1170
1171 /*
1172 * Call framing module
1173 */
1174 if ((raw == 0) && (ifp->if_framer)) {
1175 retval = ifp->if_framer(ifp, &m, dest, dst_linkaddr, frame_type);
1176 if (retval) {
1177 if (retval != EJUSTRETURN) {
1178 m_freem(m);
1179 }
1180 goto cleanup;
1181 }
1182 }
1183
1184 #if BRIDGE
1185 /* !!!LOCKING!!!
1186 *
1187 * Need to consider how to handle this.
1188 */
1189 broken-locking
1190 if (do_bridge) {
1191 struct mbuf *m0 = m;
1192 struct ether_header *eh = mtod(m, struct ether_header *);
1193
1194 if (m->m_pkthdr.rcvif)
1195 m->m_pkthdr.rcvif = NULL;
1196 ifp = bridge_dst_lookup(eh);
1197 bdg_forward(&m0, ifp);
1198 if (m0)
1199 m_freem(m0);
1200
1201 return 0;
1202 }
1203 #endif
1204
1205
1206 /*
1207 * Let interface filters (if any) do their thing ...
1208 */
1209
1210 /* Do not pass VLAN tagged packets to filters PR-3586856 */
1211 if ((m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) == 0) {
1212 TAILQ_FOREACH(filter, &ifp->if_flt_head, filt_next) {
1213 if ((filter->filt_protocol == 0 || (filter->filt_protocol == proto_family)) &&
1214 filter->filt_output) {
1215 retval = filter->filt_output(filter->filt_cookie, ifp, proto_family, &m);
1216 if (retval) {
1217 if (retval != EJUSTRETURN)
1218 m_freem(m);
1219 goto cleanup;
1220 }
1221 }
1222 }
1223 }
1224
1225 /*
1226 * Finally, call the driver.
1227 */
1228
1229 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT | DBG_FUNC_START, 0,0,0,0,0);
1230 retval = ifp->if_output(ifp, m);
1231 KERNEL_DEBUG(DBG_FNC_DLIL_IFOUT | DBG_FUNC_END, 0,0,0,0,0);
1232
1233 KERNEL_DEBUG(DBG_FNC_DLIL_OUTPUT | DBG_FUNC_END,0,0,0,0,0);
1234
1235 cleanup:
1236 dlil_read_end();
1237 if (retval == EJUSTRETURN)
1238 retval = 0;
1239 return retval;
1240 }
1241
1242 int
1243 dlil_ioctl(u_long proto_fam,
1244 struct ifnet *ifp,
1245 u_long ioctl_code,
1246 caddr_t ioctl_arg)
1247 {
1248 struct ifnet_filter *filter;
1249 int retval = EOPNOTSUPP;
1250 int result = 0;
1251 struct if_family_str *if_family;
1252 int holding_read = 0;
1253
1254 /* Attempt to increment the use count. If it's zero, bail out, the ifp is invalid */
1255 result = ifp_use(ifp, kIfNetUseCount_MustNotBeZero);
1256 if (result != 0)
1257 return EOPNOTSUPP;
1258
1259 dlil_read_begin();
1260 holding_read = 1;
1261
1262 /* Run the interface filters first.
1263 * We want to run all filters before calling the protocol,
1264 * interface family, or interface.
1265 */
1266 TAILQ_FOREACH(filter, &ifp->if_flt_head, filt_next) {
1267 if ((filter->filt_protocol == 0 || (filter->filt_protocol == proto_fam)) &&
1268 filter->filt_ioctl != NULL) {
1269 result = filter->filt_ioctl(filter->filt_cookie, ifp, proto_fam, ioctl_code, ioctl_arg);
1270 /* Only update retval if no one has handled the ioctl */
1271 if (retval == EOPNOTSUPP || result == EJUSTRETURN) {
1272 if (result == ENOTSUP)
1273 result = EOPNOTSUPP;
1274 retval = result;
1275 if (retval && retval != EOPNOTSUPP) {
1276 goto cleanup;
1277 }
1278 }
1279 }
1280 }
1281
1282 /* Allow the protocol to handle the ioctl */
1283 if (proto_fam) {
1284 struct if_proto *proto = find_attached_proto(ifp, proto_fam);
1285
1286 if (proto != 0) {
1287 result = EOPNOTSUPP;
1288 if (proto->proto_kpi == kProtoKPI_DLIL) {
1289 if (proto->kpi.dlil.dl_ioctl)
1290 result = proto->kpi.dlil.dl_ioctl(proto_fam, ifp, ioctl_code, ioctl_arg);
1291 }
1292 else {
1293 if (proto->kpi.v1.ioctl)
1294 result = proto->kpi.v1.ioctl(ifp, proto_fam, ioctl_code, ioctl_arg);
1295 }
1296
1297 /* Only update retval if no one has handled the ioctl */
1298 if (retval == EOPNOTSUPP || result == EJUSTRETURN) {
1299 if (result == ENOTSUP)
1300 result = EOPNOTSUPP;
1301 retval = result;
1302 if (retval && retval != EOPNOTSUPP) {
1303 goto cleanup;
1304 }
1305 }
1306 }
1307 }
1308
1309 /*
1310 * Since we have incremented the use count on the ifp, we are guaranteed
1311 * that the ifp will not go away (the function pointers may not be changed).
1312 * We release the dlil read lock so the interface ioctl may trigger a
1313 * protocol attach. This happens with vlan and may occur with other virtual
1314 * interfaces.
1315 */
1316 dlil_read_end();
1317 holding_read = 0;
1318
1319 /* retval is either 0 or EOPNOTSUPP */
1320
1321 /*
1322 * Let the family handle this ioctl.
1323 * If it returns something non-zero and not EOPNOTSUPP, we're done.
1324 * If it returns zero, the ioctl was handled, so set retval to zero.
1325 */
1326 if_family = find_family_module(ifp->if_family);
1327 if ((if_family) && (if_family->ifmod_ioctl)) {
1328 result = (*if_family->ifmod_ioctl)(ifp, ioctl_code, ioctl_arg);
1329
1330 /* Only update retval if no one has handled the ioctl */
1331 if (retval == EOPNOTSUPP || result == EJUSTRETURN) {
1332 if (result == ENOTSUP)
1333 result = EOPNOTSUPP;
1334 retval = result;
1335 if (retval && retval != EOPNOTSUPP) {
1336 goto cleanup;
1337 }
1338 }
1339 }
1340
1341 /*
1342 * Let the interface handle this ioctl.
1343 * If it returns EOPNOTSUPP, ignore that, we may have
1344 * already handled this in the protocol or family.
1345 */
1346 if (ifp->if_ioctl)
1347 result = (*ifp->if_ioctl)(ifp, ioctl_code, ioctl_arg);
1348
1349 /* Only update retval if no one has handled the ioctl */
1350 if (retval == EOPNOTSUPP || result == EJUSTRETURN) {
1351 if (result == ENOTSUP)
1352 result = EOPNOTSUPP;
1353 retval = result;
1354 if (retval && retval != EOPNOTSUPP) {
1355 goto cleanup;
1356 }
1357 }
1358
1359 cleanup:
1360 if (holding_read)
1361 dlil_read_end();
1362 if (ifp_unuse(ifp))
1363 ifp_use_reached_zero(ifp);
1364
1365 if (retval == EJUSTRETURN)
1366 retval = 0;
1367 return retval;
1368 }
1369
1370 __private_extern__ errno_t
1371 dlil_set_bpf_tap(
1372 ifnet_t ifp,
1373 bpf_tap_mode mode,
1374 bpf_packet_func callback)
1375 {
1376 errno_t error = 0;
1377
1378 dlil_read_begin();
1379 if (ifp->if_set_bpf_tap)
1380 error = ifp->if_set_bpf_tap(ifp, mode, callback);
1381 dlil_read_end();
1382
1383 return error;
1384 }
1385
1386 __private_extern__ errno_t
1387 dlil_resolve_multi(
1388 struct ifnet *ifp,
1389 const struct sockaddr *proto_addr,
1390 struct sockaddr *ll_addr,
1391 size_t ll_len)
1392 {
1393 errno_t result = EOPNOTSUPP;
1394 struct if_proto *proto;
1395 const struct sockaddr *verify;
1396
1397 dlil_read_begin();
1398
1399 bzero(ll_addr, ll_len);
1400
1401 /* Call the protocol first */
1402 proto = find_attached_proto(ifp, proto_addr->sa_family);
1403 if (proto != NULL && proto->proto_kpi != kProtoKPI_DLIL &&
1404 proto->kpi.v1.resolve_multi != NULL) {
1405 result = proto->kpi.v1.resolve_multi(ifp, proto_addr,
1406 (struct sockaddr_dl*)ll_addr, ll_len);
1407 }
1408
1409 /* Let the interface verify the multicast address */
1410 if ((result == EOPNOTSUPP || result == 0) && ifp->if_check_multi) {
1411 if (result == 0)
1412 verify = ll_addr;
1413 else
1414 verify = proto_addr;
1415 result = ifp->if_check_multi(ifp, verify);
1416 }
1417
1418 dlil_read_end();
1419
1420 return result;
1421 }
1422
1423 __private_extern__ errno_t
1424 dlil_send_arp_internal(
1425 ifnet_t ifp,
1426 u_short arpop,
1427 const struct sockaddr_dl* sender_hw,
1428 const struct sockaddr* sender_proto,
1429 const struct sockaddr_dl* target_hw,
1430 const struct sockaddr* target_proto)
1431 {
1432 struct if_proto *proto;
1433 errno_t result = 0;
1434
1435 dlil_read_begin();
1436
1437 proto = find_attached_proto(ifp, target_proto->sa_family);
1438 if (proto == NULL || proto->proto_kpi == kProtoKPI_DLIL ||
1439 proto->kpi.v1.send_arp == NULL) {
1440 result = ENOTSUP;
1441 }
1442 else {
1443 result = proto->kpi.v1.send_arp(ifp, arpop, sender_hw, sender_proto,
1444 target_hw, target_proto);
1445 }
1446
1447 dlil_read_end();
1448
1449 return result;
1450 }
1451
1452 __private_extern__ errno_t
1453 dlil_send_arp(
1454 ifnet_t ifp,
1455 u_short arpop,
1456 const struct sockaddr_dl* sender_hw,
1457 const struct sockaddr* sender_proto,
1458 const struct sockaddr_dl* target_hw,
1459 const struct sockaddr* target_proto)
1460 {
1461 errno_t result = 0;
1462
1463 if (target_proto == NULL || (sender_proto &&
1464 sender_proto->sa_family != target_proto->sa_family))
1465 return EINVAL;
1466
1467 /*
1468 * If this is an ARP request and the target IP is IPv4LL,
1469 * send the request on all interfaces.
1470 */
1471 if (IN_LINKLOCAL(((const struct sockaddr_in*)target_proto)->sin_addr.s_addr)
1472 && ipv4_ll_arp_aware != 0 && target_proto->sa_family == AF_INET &&
1473 arpop == ARPOP_REQUEST) {
1474 ifnet_t *ifp_list;
1475 u_int32_t count;
1476 u_int32_t ifp_on;
1477
1478 result = ENOTSUP;
1479
1480 if (ifnet_list_get(IFNET_FAMILY_ANY, &ifp_list, &count) == 0) {
1481 for (ifp_on = 0; ifp_on < count; ifp_on++) {
1482 errno_t new_result;
1483 ifaddr_t source_hw = NULL;
1484 ifaddr_t source_ip = NULL;
1485 struct sockaddr_in source_ip_copy;
1486
1487 /*
1488 * Only arp on interfaces marked for IPv4LL ARPing. This may
1489 * mean that we don't ARP on the interface the subnet route
1490 * points to.
1491 */
1492 if ((ifp_list[ifp_on]->if_eflags & IFEF_ARPLL) == 0) {
1493 continue;
1494 }
1495
1496 source_hw = TAILQ_FIRST(&ifp_list[ifp_on]->if_addrhead);
1497
1498 /* Find the source IP address */
1499 ifnet_lock_shared(ifp_list[ifp_on]);
1500 TAILQ_FOREACH(source_ip, &ifp_list[ifp_on]->if_addrhead,
1501 ifa_link) {
1502 if (source_ip->ifa_addr &&
1503 source_ip->ifa_addr->sa_family == AF_INET) {
1504 break;
1505 }
1506 }
1507
1508 /* No IP Source, don't arp */
1509 if (source_ip == NULL) {
1510 ifnet_lock_done(ifp_list[ifp_on]);
1511 continue;
1512 }
1513
1514 /* Copy the source IP address */
1515 source_ip_copy = *(struct sockaddr_in*)source_ip->ifa_addr;
1516
1517 ifnet_lock_done(ifp_list[ifp_on]);
1518
1519 /* Send the ARP */
1520 new_result = dlil_send_arp_internal(ifp_list[ifp_on], arpop,
1521 (struct sockaddr_dl*)source_hw->ifa_addr,
1522 (struct sockaddr*)&source_ip_copy, NULL,
1523 target_proto);
1524
1525 if (result == ENOTSUP) {
1526 result = new_result;
1527 }
1528 }
1529 }
1530
1531 ifnet_list_free(ifp_list);
1532 }
1533 else {
1534 result = dlil_send_arp_internal(ifp, arpop, sender_hw, sender_proto,
1535 target_hw, target_proto);
1536 }
1537
1538 return result;
1539 }
1540
1541 static int
1542 ifp_use(
1543 struct ifnet *ifp,
1544 int handle_zero)
1545 {
1546 int old_value;
1547 int retval = 0;
1548
1549 do {
1550 old_value = ifp->if_usecnt;
1551 if (old_value == 0 && handle_zero == kIfNetUseCount_MustNotBeZero) {
1552 retval = ENXIO; // ifp is invalid
1553 break;
1554 }
1555 } while (!OSCompareAndSwap((UInt32)old_value, (UInt32)old_value + 1, (UInt32*)&ifp->if_usecnt));
1556
1557 return retval;
1558 }
1559
1560 /* ifp_unuse is broken into two pieces.
1561 *
1562 * ifp_use and ifp_unuse must be called between when the caller calls
1563 * dlil_write_begin and dlil_write_end. ifp_unuse needs to perform some
1564 * operations after dlil_write_end has been called. For this reason,
1565 * anyone calling ifp_unuse must call ifp_use_reached_zero if ifp_unuse
1566 * returns a non-zero value. The caller must call ifp_use_reached_zero
1567 * after the caller has called dlil_write_end.
1568 */
1569 static void
1570 ifp_use_reached_zero(
1571 struct ifnet *ifp)
1572 {
1573 struct if_family_str *if_family;
1574 ifnet_detached_func free_func;
1575
1576 dlil_read_begin();
1577
1578 if (ifp->if_usecnt != 0)
1579 panic("ifp_use_reached_zero: ifp->if_usecnt != 0");
1580
1581 /* Let BPF know we're detaching */
1582 bpfdetach(ifp);
1583
1584 ifnet_head_lock_exclusive();
1585 ifnet_lock_exclusive(ifp);
1586
1587 /* Remove ourselves from the list */
1588 TAILQ_REMOVE(&ifnet_head, ifp, if_link);
1589 ifnet_addrs[ifp->if_index - 1] = 0;
1590
1591 /* ifp should be removed from the interface list */
1592 while (ifp->if_multiaddrs.lh_first) {
1593 struct ifmultiaddr *ifma = ifp->if_multiaddrs.lh_first;
1594
1595 /*
1596 * When the interface is gone, we will no longer
1597 * be listening on these multicasts. Various bits
1598 * of the stack may be referencing these multicasts,
1599 * release only our reference.
1600 */
1601 LIST_REMOVE(ifma, ifma_link);
1602 ifma->ifma_ifp = NULL;
1603 ifma_release(ifma);
1604 }
1605 ifnet_head_done();
1606
1607 ifp->if_eflags &= ~IFEF_DETACHING; // clear the detaching flag
1608 ifnet_lock_done(ifp);
1609
1610 if_family = find_family_module(ifp->if_family);
1611 if (if_family && if_family->del_if)
1612 if_family->del_if(ifp);
1613 #if 0
1614 if (--if_family->if_usecnt == 0) {
1615 if (if_family->shutdown)
1616 (*if_family->shutdown)();
1617
1618 TAILQ_REMOVE(&if_family_head, if_family, if_fam_next);
1619 FREE(if_family, M_IFADDR);
1620 }
1621 #endif
1622
1623 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_IF_DETACHED, 0, 0);
1624 free_func = ifp->if_free;
1625 dlil_read_end();
1626
1627 if (free_func)
1628 free_func(ifp);
1629 }
1630
1631 static int
1632 ifp_unuse(
1633 struct ifnet *ifp)
1634 {
1635 int oldval;
1636 oldval = OSDecrementAtomic((UInt32*)&ifp->if_usecnt);
1637 if (oldval == 0)
1638 panic("ifp_unuse: ifp(%s%n)->if_usecnt was zero\n", ifp->if_name, ifp->if_unit);
1639
1640 if (oldval > 1)
1641 return 0;
1642
1643 if ((ifp->if_eflags & IFEF_DETACHING) == 0)
1644 panic("ifp_unuse: use count reached zero but detching flag is not set!");
1645
1646 return 1; /* caller must call ifp_use_reached_zero */
1647 }
1648
1649 void
1650 ifp_reference(
1651 struct ifnet *ifp)
1652 {
1653 int oldval;
1654 oldval = OSIncrementAtomic(&ifp->if_refcnt);
1655 }
1656
1657 void
1658 ifp_release(
1659 struct ifnet *ifp)
1660 {
1661 int oldval;
1662 oldval = OSDecrementAtomic((UInt32*)&ifp->if_refcnt);
1663 if (oldval == 0)
1664 panic("dlil_if_reference - refcount decremented past zero!");
1665 }
1666
1667 extern lck_mtx_t *domain_proto_mtx;
1668
1669 static int
1670 dlil_attach_protocol_internal(
1671 struct if_proto *proto,
1672 const struct ddesc_head_str *demux,
1673 const struct ifnet_demux_desc *demux_list,
1674 u_int32_t demux_count)
1675 {
1676 struct ddesc_head_str temp_head;
1677 struct kev_dl_proto_data ev_pr_data;
1678 struct ifnet *ifp = proto->ifp;
1679 int retval = 0;
1680 u_long hash_value = proto_hash_value(proto->protocol_family);
1681 int if_using_kpi = (ifp->if_eflags & IFEF_USEKPI) != 0;
1682 void* free_me = NULL;
1683
1684 /* setup some of the common values */
1685
1686 {
1687 lck_mtx_lock(domain_proto_mtx);
1688 struct domain *dp = domains;
1689 while (dp && (protocol_family_t)dp->dom_family != proto->protocol_family)
1690 dp = dp->dom_next;
1691 proto->dl_domain = dp;
1692 lck_mtx_unlock(domain_proto_mtx);
1693 }
1694
1695 /*
1696 * Convert the demux descriptors to a type the interface
1697 * will understand. Checking e_flags should be safe, this
1698 * flag won't change.
1699 */
1700 if (if_using_kpi && demux) {
1701 /* Convert the demux linked list to a demux_list */
1702 struct dlil_demux_desc *demux_entry;
1703 struct ifnet_demux_desc *temp_list = NULL;
1704 u_int32_t i = 0;
1705
1706 TAILQ_FOREACH(demux_entry, demux, next) {
1707 i++;
1708 }
1709
1710 temp_list = _MALLOC(sizeof(struct ifnet_demux_desc) * i, M_TEMP, M_WAITOK);
1711 free_me = temp_list;
1712
1713 if (temp_list == NULL)
1714 return ENOMEM;
1715
1716 i = 0;
1717 TAILQ_FOREACH(demux_entry, demux, next) {
1718 /* dlil_demux_desc types 1, 2, and 3 are obsolete and can not be translated */
1719 if (demux_entry->type == 1 ||
1720 demux_entry->type == 2 ||
1721 demux_entry->type == 3) {
1722 FREE(free_me, M_TEMP);
1723 return ENOTSUP;
1724 }
1725
1726 temp_list[i].type = demux_entry->type;
1727 temp_list[i].data = demux_entry->native_type;
1728 temp_list[i].datalen = demux_entry->variants.native_type_length;
1729 i++;
1730 }
1731 demux_count = i;
1732 demux_list = temp_list;
1733 }
1734 else if (!if_using_kpi && demux_list != NULL) {
1735 struct dlil_demux_desc *demux_entry;
1736 u_int32_t i = 0;
1737
1738 demux_entry = _MALLOC(sizeof(struct dlil_demux_desc) * demux_count, M_TEMP, M_WAITOK);
1739 free_me = demux_entry;
1740 if (demux_entry == NULL)
1741 return ENOMEM;
1742
1743 TAILQ_INIT(&temp_head);
1744
1745 for (i = 0; i < demux_count; i++) {
1746 demux_entry[i].type = demux_list[i].type;
1747 demux_entry[i].native_type = demux_list[i].data;
1748 demux_entry[i].variants.native_type_length = demux_list[i].datalen;
1749 TAILQ_INSERT_TAIL(&temp_head, &demux_entry[i], next);
1750 }
1751 demux = &temp_head;
1752 }
1753
1754 /*
1755 * Take the write lock to protect readers and exclude other writers.
1756 */
1757 dlil_write_begin();
1758
1759 /* Check that the interface isn't currently detaching */
1760 ifnet_lock_shared(ifp);
1761 if ((ifp->if_eflags & IFEF_DETACHING) != 0) {
1762 ifnet_lock_done(ifp);
1763 dlil_write_end();
1764 if (free_me)
1765 FREE(free_me, M_TEMP);
1766 return ENXIO;
1767 }
1768 ifnet_lock_done(ifp);
1769
1770 if (find_attached_proto(ifp, proto->protocol_family) != NULL) {
1771 dlil_write_end();
1772 if (free_me)
1773 FREE(free_me, M_TEMP);
1774 return EEXIST;
1775 }
1776
1777 /*
1778 * Call family module add_proto routine so it can refine the
1779 * demux descriptors as it wishes.
1780 */
1781 if (if_using_kpi)
1782 retval = ifp->if_add_proto_u.kpi(ifp, proto->protocol_family, demux_list, demux_count);
1783 else {
1784 retval = ifp->if_add_proto_u.original(ifp, proto->protocol_family,
1785 _cast_non_const(demux));
1786 }
1787 if (retval) {
1788 dlil_write_end();
1789 if (free_me)
1790 FREE(free_me, M_TEMP);
1791 return retval;
1792 }
1793
1794 /*
1795 * We can't fail from this point on.
1796 * Increment the number of uses (protocol attachments + interface attached).
1797 */
1798 ifp_use(ifp, kIfNetUseCount_MustNotBeZero);
1799
1800 /*
1801 * Insert the protocol in the hash
1802 */
1803 {
1804 struct if_proto* prev_proto = SLIST_FIRST(&ifp->if_proto_hash[hash_value]);
1805 while (prev_proto && SLIST_NEXT(prev_proto, next_hash) != NULL)
1806 prev_proto = SLIST_NEXT(prev_proto, next_hash);
1807 if (prev_proto)
1808 SLIST_INSERT_AFTER(prev_proto, proto, next_hash);
1809 else
1810 SLIST_INSERT_HEAD(&ifp->if_proto_hash[hash_value], proto, next_hash);
1811 }
1812
1813 /*
1814 * Add to if_proto list for this interface
1815 */
1816 if_proto_ref(proto);
1817 if (proto->proto_kpi == kProtoKPI_DLIL && proto->kpi.dlil.dl_offer)
1818 ifp->offercnt++;
1819 dlil_write_end();
1820
1821 /* the reserved field carries the number of protocol still attached (subject to change) */
1822 ev_pr_data.proto_family = proto->protocol_family;
1823 ev_pr_data.proto_remaining_count = dlil_ifp_proto_count(ifp);
1824 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_PROTO_ATTACHED,
1825 (struct net_event_data *)&ev_pr_data,
1826 sizeof(struct kev_dl_proto_data));
1827
1828 DLIL_PRINTF("Attached protocol %d to %s%d - %d\n", proto->protocol_family,
1829 ifp->if_name, ifp->if_unit, retval);
1830 if (free_me)
1831 FREE(free_me, M_TEMP);
1832 return retval;
1833 }
1834
1835 __private_extern__ int
1836 dlil_attach_protocol_kpi(ifnet_t ifp, protocol_family_t protocol,
1837 const struct ifnet_attach_proto_param *proto_details)
1838 {
1839 int retval = 0;
1840 struct if_proto *ifproto = NULL;
1841
1842 ifproto = _MALLOC(sizeof(struct if_proto), M_IFADDR, M_WAITOK);
1843 if (ifproto == 0) {
1844 DLIL_PRINTF("ERROR - DLIL failed if_proto allocation\n");
1845 retval = ENOMEM;
1846 goto end;
1847 }
1848 bzero(ifproto, sizeof(*ifproto));
1849
1850 ifproto->ifp = ifp;
1851 ifproto->protocol_family = protocol;
1852 ifproto->proto_kpi = kProtoKPI_v1;
1853 ifproto->kpi.v1.input = proto_details->input;
1854 ifproto->kpi.v1.pre_output = proto_details->pre_output;
1855 ifproto->kpi.v1.event = proto_details->event;
1856 ifproto->kpi.v1.ioctl = proto_details->ioctl;
1857 ifproto->kpi.v1.detached = proto_details->detached;
1858 ifproto->kpi.v1.resolve_multi = proto_details->resolve;
1859 ifproto->kpi.v1.send_arp = proto_details->send_arp;
1860
1861 retval = dlil_attach_protocol_internal(ifproto, NULL,
1862 proto_details->demux_list, proto_details->demux_count);
1863
1864 end:
1865 if (retval && ifproto)
1866 FREE(ifproto, M_IFADDR);
1867 return retval;
1868 }
1869
1870 int
1871 dlil_attach_protocol(struct dlil_proto_reg_str *proto)
1872 {
1873 struct ifnet *ifp = NULL;
1874 struct if_proto *ifproto = NULL;
1875 int retval = 0;
1876
1877 /*
1878 * Do everything we can before taking the write lock
1879 */
1880
1881 if ((proto->protocol_family == 0) || (proto->interface_family == 0))
1882 return EINVAL;
1883
1884 /*
1885 * Allocate and init a new if_proto structure
1886 */
1887 ifproto = _MALLOC(sizeof(struct if_proto), M_IFADDR, M_WAITOK);
1888 if (!ifproto) {
1889 DLIL_PRINTF("ERROR - DLIL failed if_proto allocation\n");
1890 retval = ENOMEM;
1891 goto end;
1892 }
1893
1894
1895 /* ifbyfamily returns us an ifp with an incremented if_usecnt */
1896 ifp = ifbyfamily(proto->interface_family, proto->unit_number);
1897 if (!ifp) {
1898 DLIL_PRINTF("dlil_attach_protocol -- no such interface %d unit %d\n",
1899 proto->interface_family, proto->unit_number);
1900 retval = ENXIO;
1901 goto end;
1902 }
1903
1904 bzero(ifproto, sizeof(struct if_proto));
1905
1906 ifproto->ifp = ifp;
1907 ifproto->protocol_family = proto->protocol_family;
1908 ifproto->proto_kpi = kProtoKPI_DLIL;
1909 ifproto->kpi.dlil.dl_input = proto->input;
1910 ifproto->kpi.dlil.dl_pre_output = proto->pre_output;
1911 ifproto->kpi.dlil.dl_event = proto->event;
1912 ifproto->kpi.dlil.dl_offer = proto->offer;
1913 ifproto->kpi.dlil.dl_ioctl = proto->ioctl;
1914 ifproto->kpi.dlil.dl_detached = proto->detached;
1915
1916 retval = dlil_attach_protocol_internal(ifproto, &proto->demux_desc_head, NULL, 0);
1917
1918 end:
1919 if (retval && ifproto)
1920 FREE(ifproto, M_IFADDR);
1921 return retval;
1922 }
1923
1924 extern void if_rtproto_del(struct ifnet *ifp, int protocol);
1925
1926 static int
1927 dlil_detach_protocol_internal(
1928 struct if_proto *proto)
1929 {
1930 struct ifnet *ifp = proto->ifp;
1931 u_long proto_family = proto->protocol_family;
1932 struct kev_dl_proto_data ev_pr_data;
1933
1934 if (proto->proto_kpi == kProtoKPI_DLIL) {
1935 if (proto->kpi.dlil.dl_detached)
1936 proto->kpi.dlil.dl_detached(proto->protocol_family, ifp);
1937 }
1938 else {
1939 if (proto->kpi.v1.detached)
1940 proto->kpi.v1.detached(ifp, proto->protocol_family);
1941 }
1942 if_proto_free(proto);
1943
1944 /*
1945 * Cleanup routes that may still be in the routing table for that interface/protocol pair.
1946 */
1947
1948 if_rtproto_del(ifp, proto_family);
1949
1950 /* the reserved field carries the number of protocol still attached (subject to change) */
1951 ev_pr_data.proto_family = proto_family;
1952 ev_pr_data.proto_remaining_count = dlil_ifp_proto_count(ifp);
1953 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_PROTO_DETACHED,
1954 (struct net_event_data *)&ev_pr_data,
1955 sizeof(struct kev_dl_proto_data));
1956 return 0;
1957 }
1958
1959 int
1960 dlil_detach_protocol(struct ifnet *ifp, u_long proto_family)
1961 {
1962 struct if_proto *proto = NULL;
1963 int retval = 0;
1964 int use_reached_zero = 0;
1965
1966
1967 #if DLIL_ALWAYS_DELAY_DETACH
1968 {
1969 retval = EDEADLK;
1970 #else
1971 if ((retval = dlil_write_begin()) != 0) {
1972 #endif
1973 if (retval == EDEADLK) {
1974 retval = 0;
1975 dlil_read_begin();
1976 proto = find_attached_proto(ifp, proto_family);
1977 if (proto == 0) {
1978 retval = ENXIO;
1979 }
1980 else {
1981 proto->detaching = 1;
1982 dlil_detach_waiting = 1;
1983 wakeup(&dlil_detach_waiting);
1984 }
1985 dlil_read_end();
1986 }
1987 goto end;
1988 }
1989
1990 proto = find_attached_proto(ifp, proto_family);
1991
1992 if (proto == NULL) {
1993 retval = ENXIO;
1994 dlil_write_end();
1995 goto end;
1996 }
1997
1998 /*
1999 * Call family module del_proto
2000 */
2001
2002 if (ifp->if_del_proto)
2003 ifp->if_del_proto(ifp, proto->protocol_family);
2004
2005 if (proto->proto_kpi == kProtoKPI_DLIL && proto->kpi.dlil.dl_offer)
2006 ifp->offercnt--;
2007
2008 SLIST_REMOVE(&ifp->if_proto_hash[proto_hash_value(proto_family)], proto, if_proto, next_hash);
2009
2010 /*
2011 * We can do the rest of the work outside of the write lock.
2012 */
2013 use_reached_zero = ifp_unuse(ifp);
2014 dlil_write_end();
2015
2016 dlil_detach_protocol_internal(proto);
2017
2018 /*
2019 * Only handle the case where the interface will go away after
2020 * we've sent the message. This way post message can send the
2021 * message to the interface safely.
2022 */
2023
2024 if (use_reached_zero)
2025 ifp_use_reached_zero(ifp);
2026
2027 end:
2028 return retval;
2029 }
2030
2031 /*
2032 * dlil_delayed_detach_thread is responsible for detaching
2033 * protocols, protocol filters, and interface filters after
2034 * an attempt was made to detach one of those items while
2035 * it was not safe to do so (i.e. called dlil_read_begin).
2036 *
2037 * This function will take the dlil write lock and walk
2038 * through each of the interfaces looking for items with
2039 * the detaching flag set. When an item is found, it is
2040 * detached from the interface and placed on a local list.
2041 * After all of the items have been collected, we drop the
2042 * write lock and performed the post detach. This is done
2043 * so we only have to take the write lock once.
2044 *
2045 * When detaching a protocol filter, if we find that we
2046 * have detached the very last protocol and we need to call
2047 * ifp_use_reached_zero, we have to break out of our work
2048 * to drop the write lock so we can call ifp_use_reached_zero.
2049 */
2050
2051 static void
2052 dlil_delayed_detach_thread(__unused void* foo, __unused wait_result_t wait)
2053 {
2054 thread_t self = current_thread();
2055 int asserted = 0;
2056
2057 ml_thread_policy(self, MACHINE_GROUP,
2058 (MACHINE_NETWORK_GROUP|MACHINE_NETWORK_NETISR));
2059
2060
2061 while (1) {
2062 if (dlil_detach_waiting != 0 && dlil_write_begin() == 0) {
2063 struct ifnet *ifp;
2064 struct proto_hash_entry detached_protos;
2065 struct ifnet_filter_head detached_filters;
2066 struct if_proto *proto;
2067 struct if_proto *next_proto;
2068 struct ifnet_filter *filt;
2069 struct ifnet_filter *next_filt;
2070 int reached_zero;
2071
2072 reached_zero = 0;
2073
2074 /* Clear the detach waiting flag */
2075 dlil_detach_waiting = 0;
2076 TAILQ_INIT(&detached_filters);
2077 SLIST_INIT(&detached_protos);
2078
2079 ifnet_head_lock_shared();
2080 TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
2081 int i;
2082
2083 // Look for protocols and protocol filters
2084 for (i = 0; i < PROTO_HASH_SLOTS && !reached_zero; i++) {
2085 struct if_proto **prev_nextptr = &SLIST_FIRST(&ifp->if_proto_hash[i]);
2086 for (proto = *prev_nextptr; proto; proto = *prev_nextptr) {
2087
2088 // Detach this protocol
2089 if (proto->detaching) {
2090 if (ifp->if_del_proto)
2091 ifp->if_del_proto(ifp, proto->protocol_family);
2092 if (proto->proto_kpi == kProtoKPI_DLIL && proto->kpi.dlil.dl_offer)
2093 ifp->offercnt--;
2094 *prev_nextptr = SLIST_NEXT(proto, next_hash);
2095 SLIST_INSERT_HEAD(&detached_protos, proto, next_hash);
2096 reached_zero = ifp_unuse(ifp);
2097 if (reached_zero) {
2098 break;
2099 }
2100 }
2101 else {
2102 // Update prev_nextptr to point to our next ptr
2103 prev_nextptr = &SLIST_NEXT(proto, next_hash);
2104 }
2105 }
2106 }
2107
2108 // look for interface filters that need to be detached
2109 for (filt = TAILQ_FIRST(&ifp->if_flt_head); filt; filt = next_filt) {
2110 next_filt = TAILQ_NEXT(filt, filt_next);
2111 if (filt->filt_detaching != 0) {
2112 // take this interface filter off the interface filter list
2113 TAILQ_REMOVE(&ifp->if_flt_head, filt, filt_next);
2114
2115 // put this interface filter on the detached filters list
2116 TAILQ_INSERT_TAIL(&detached_filters, filt, filt_next);
2117 }
2118 }
2119
2120 if (ifp->if_delayed_detach) {
2121 ifp->if_delayed_detach = 0;
2122 reached_zero = ifp_unuse(ifp);
2123 }
2124
2125 if (reached_zero)
2126 break;
2127 }
2128 ifnet_head_done();
2129 dlil_write_end();
2130
2131 for (filt = TAILQ_FIRST(&detached_filters); filt; filt = next_filt) {
2132 next_filt = TAILQ_NEXT(filt, filt_next);
2133 /*
2134 * dlil_detach_filter_internal won't remove an item from
2135 * the list if it is already detached (second parameter).
2136 * The item will be freed though.
2137 */
2138 dlil_detach_filter_internal(filt, 1);
2139 }
2140
2141 for (proto = SLIST_FIRST(&detached_protos); proto; proto = next_proto) {
2142 next_proto = SLIST_NEXT(proto, next_hash);
2143 dlil_detach_protocol_internal(proto);
2144 }
2145
2146 if (reached_zero) {
2147 ifp_use_reached_zero(ifp);
2148 dlil_detach_waiting = 1; // we may have missed something
2149 }
2150 }
2151
2152 if (!asserted && dlil_detach_waiting == 0) {
2153 asserted = 1;
2154 assert_wait(&dlil_detach_waiting, THREAD_UNINT);
2155 }
2156
2157 if (dlil_detach_waiting == 0) {
2158 asserted = 0;
2159 thread_block(dlil_delayed_detach_thread);
2160 }
2161 }
2162 }
2163
2164 static void
2165 dlil_call_delayed_detach_thread(void) {
2166 dlil_delayed_detach_thread(NULL, THREAD_RESTART);
2167 }
2168
2169 extern int if_next_index(void);
2170
2171 __private_extern__ int
2172 dlil_if_attach_with_address(
2173 struct ifnet *ifp,
2174 const struct sockaddr_dl *ll_addr)
2175 {
2176 u_long interface_family = ifp->if_family;
2177 struct if_family_str *if_family = NULL;
2178 int stat;
2179 struct ifnet *tmp_if;
2180 struct proto_hash_entry *new_proto_list = NULL;
2181 int locked = 0;
2182
2183
2184 ifnet_head_lock_shared();
2185
2186 /* Verify we aren't already on the list */
2187 TAILQ_FOREACH(tmp_if, &ifnet_head, if_link) {
2188 if (tmp_if == ifp) {
2189 ifnet_head_done();
2190 return EEXIST;
2191 }
2192 }
2193
2194 ifnet_head_done();
2195
2196 if ((ifp->if_eflags & IFEF_REUSE) == 0 || ifp->if_lock == 0)
2197 #if IFNET_RW_LOCK
2198 ifp->if_lock = lck_rw_alloc_init(ifnet_lock_group, ifnet_lock_attr);
2199 #else
2200 ifp->if_lock = lck_mtx_alloc_init(ifnet_lock_group, ifnet_lock_attr);
2201 #endif
2202
2203 if (ifp->if_lock == 0) {
2204 return ENOMEM;
2205 }
2206
2207 // Only use family if this is not a KPI interface
2208 if ((ifp->if_eflags & IFEF_USEKPI) == 0) {
2209 if_family = find_family_module(interface_family);
2210 }
2211
2212 /*
2213 * Allow interfaces withouth protocol families to attach
2214 * only if they have the necessary fields filled out.
2215 */
2216
2217 if ((if_family == 0) &&
2218 (ifp->if_add_proto == 0 || ifp->if_del_proto == 0)) {
2219 DLIL_PRINTF("Attempt to attach interface without family module - %d\n",
2220 interface_family);
2221 return ENODEV;
2222 }
2223
2224 if ((ifp->if_eflags & IFEF_REUSE) == 0 || ifp->if_proto_hash == NULL) {
2225 MALLOC(new_proto_list, struct proto_hash_entry*, sizeof(struct proto_hash_entry) * PROTO_HASH_SLOTS,
2226 M_NKE, M_WAITOK);
2227
2228 if (new_proto_list == 0) {
2229 return ENOBUFS;
2230 }
2231 }
2232
2233 dlil_write_begin();
2234 locked = 1;
2235
2236 /*
2237 * Call the family module to fill in the appropriate fields in the
2238 * ifnet structure.
2239 */
2240
2241 if (if_family) {
2242 stat = if_family->add_if(ifp);
2243 if (stat) {
2244 DLIL_PRINTF("dlil_if_attach -- add_if failed with %d\n", stat);
2245 dlil_write_end();
2246 return stat;
2247 }
2248 ifp->if_add_proto_u.original = if_family->add_proto;
2249 ifp->if_del_proto = if_family->del_proto;
2250 if_family->refcnt++;
2251 }
2252
2253 ifp->offercnt = 0;
2254 TAILQ_INIT(&ifp->if_flt_head);
2255
2256
2257 if (new_proto_list) {
2258 bzero(new_proto_list, (PROTO_HASH_SLOTS * sizeof(struct proto_hash_entry)));
2259 ifp->if_proto_hash = new_proto_list;
2260 new_proto_list = 0;
2261 }
2262
2263 /* old_if_attach */
2264 {
2265 struct ifaddr *ifa = 0;
2266
2267 if (ifp->if_snd.ifq_maxlen == 0)
2268 ifp->if_snd.ifq_maxlen = ifqmaxlen;
2269 TAILQ_INIT(&ifp->if_prefixhead);
2270 LIST_INIT(&ifp->if_multiaddrs);
2271 ifnet_touch_lastchange(ifp);
2272
2273 /* usecount to track attachment to the ifnet list */
2274 ifp_use(ifp, kIfNetUseCount_MayBeZero);
2275
2276 /* Lock the list of interfaces */
2277 ifnet_head_lock_exclusive();
2278 ifnet_lock_exclusive(ifp);
2279
2280 if ((ifp->if_eflags & IFEF_REUSE) == 0 || ifp->if_index == 0) {
2281 char workbuf[64];
2282 int namelen, masklen, socksize, ifasize;
2283
2284 ifp->if_index = if_next_index();
2285
2286 namelen = snprintf(workbuf, sizeof(workbuf), "%s%d", ifp->if_name, ifp->if_unit);
2287 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
2288 masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
2289 socksize = masklen + ifp->if_addrlen;
2290 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
2291 if ((u_long)socksize < sizeof(struct sockaddr_dl))
2292 socksize = sizeof(struct sockaddr_dl);
2293 socksize = ROUNDUP(socksize);
2294 ifasize = sizeof(struct ifaddr) + 2 * socksize;
2295 ifa = (struct ifaddr*)_MALLOC(ifasize, M_IFADDR, M_WAITOK);
2296 if (ifa) {
2297 struct sockaddr_dl *sdl = (struct sockaddr_dl *)(ifa + 1);
2298 ifnet_addrs[ifp->if_index - 1] = ifa;
2299 bzero(ifa, ifasize);
2300 sdl->sdl_len = socksize;
2301 sdl->sdl_family = AF_LINK;
2302 bcopy(workbuf, sdl->sdl_data, namelen);
2303 sdl->sdl_nlen = namelen;
2304 sdl->sdl_index = ifp->if_index;
2305 sdl->sdl_type = ifp->if_type;
2306 if (ll_addr) {
2307 sdl->sdl_alen = ll_addr->sdl_alen;
2308 if (ll_addr->sdl_alen != ifp->if_addrlen)
2309 panic("dlil_if_attach - ll_addr->sdl_alen != ifp->if_addrlen");
2310 bcopy(CONST_LLADDR(ll_addr), LLADDR(sdl), sdl->sdl_alen);
2311 }
2312 ifa->ifa_ifp = ifp;
2313 ifa->ifa_rtrequest = link_rtrequest;
2314 ifa->ifa_addr = (struct sockaddr*)sdl;
2315 sdl = (struct sockaddr_dl*)(socksize + (caddr_t)sdl);
2316 ifa->ifa_netmask = (struct sockaddr*)sdl;
2317 sdl->sdl_len = masklen;
2318 while (namelen != 0)
2319 sdl->sdl_data[--namelen] = 0xff;
2320 }
2321 }
2322 else {
2323 /* preserve the first ifaddr */
2324 ifnet_addrs[ifp->if_index - 1] = TAILQ_FIRST(&ifp->if_addrhead);
2325 }
2326
2327
2328 TAILQ_INIT(&ifp->if_addrhead);
2329 ifa = ifnet_addrs[ifp->if_index - 1];
2330
2331 if (ifa) {
2332 /*
2333 * We don't use if_attach_ifa because we want
2334 * this address to be first on the list.
2335 */
2336 ifaref(ifa);
2337 ifa->ifa_debug |= IFA_ATTACHED;
2338 TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
2339 }
2340
2341 TAILQ_INSERT_TAIL(&ifnet_head, ifp, if_link);
2342 ifindex2ifnet[ifp->if_index] = ifp;
2343
2344 ifnet_head_done();
2345 }
2346 dlil_write_end();
2347
2348 if (if_family && if_family->init_if) {
2349 stat = if_family->init_if(ifp);
2350 if (stat) {
2351 DLIL_PRINTF("dlil_if_attach -- init_if failed with %d\n", stat);
2352 }
2353 }
2354
2355 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_IF_ATTACHED, 0, 0);
2356 ifnet_lock_done(ifp);
2357
2358 return 0;
2359 }
2360
2361 int
2362 dlil_if_attach(struct ifnet *ifp)
2363 {
2364 dlil_if_attach_with_address(ifp, NULL);
2365 }
2366
2367
2368 int
2369 dlil_if_detach(struct ifnet *ifp)
2370 {
2371 struct ifnet_filter *filter;
2372 struct ifnet_filter *filter_next;
2373 int zeroed = 0;
2374 int retval = 0;
2375 struct ifnet_filter_head fhead;
2376
2377
2378 ifnet_lock_exclusive(ifp);
2379
2380 if ((ifp->if_eflags & IFEF_DETACHING) != 0) {
2381 /* Interface has already been detached */
2382 ifnet_lock_done(ifp);
2383 return ENXIO;
2384 }
2385
2386 /*
2387 * Indicate this interface is being detached.
2388 *
2389 * This should prevent protocols from attaching
2390 * from this point on. Interface will remain on
2391 * the list until all of the protocols are detached.
2392 */
2393 ifp->if_eflags |= IFEF_DETACHING;
2394 ifnet_lock_done(ifp);
2395
2396 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_IF_DETACHING, 0, 0);
2397
2398 if ((retval = dlil_write_begin()) != 0) {
2399 if (retval == EDEADLK) {
2400 retval = DLIL_WAIT_FOR_FREE;
2401
2402 /* We need to perform a delayed detach */
2403 ifp->if_delayed_detach = 1;
2404 dlil_detach_waiting = 1;
2405 wakeup(&dlil_detach_waiting);
2406 }
2407 return retval;
2408 }
2409
2410 /* Steal the list of interface filters */
2411 fhead = ifp->if_flt_head;
2412 TAILQ_INIT(&ifp->if_flt_head);
2413
2414 /* unuse the interface */
2415 zeroed = ifp_unuse(ifp);
2416
2417 dlil_write_end();
2418
2419 for (filter = TAILQ_FIRST(&fhead); filter; filter = filter_next) {
2420 filter_next = TAILQ_NEXT(filter, filt_next);
2421 dlil_detach_filter_internal(filter, 1);
2422 }
2423
2424 if (zeroed == 0) {
2425 retval = DLIL_WAIT_FOR_FREE;
2426 }
2427 else
2428 {
2429 ifp_use_reached_zero(ifp);
2430 }
2431
2432 return retval;
2433 }
2434
2435
2436 int
2437 dlil_reg_if_modules(u_long interface_family,
2438 struct dlil_ifmod_reg_str *ifmod)
2439 {
2440 struct if_family_str *if_family;
2441
2442
2443 if (find_family_module(interface_family)) {
2444 DLIL_PRINTF("Attempt to register dlil family module more than once - %d\n",
2445 interface_family);
2446 return EEXIST;
2447 }
2448
2449 if ((!ifmod->add_if) || (!ifmod->del_if) ||
2450 (!ifmod->add_proto) || (!ifmod->del_proto)) {
2451 DLIL_PRINTF("dlil_reg_if_modules passed at least one null pointer\n");
2452 return EINVAL;
2453 }
2454
2455 /*
2456 * The following is a gross hack to keep from breaking
2457 * Vicomsoft's internet gateway on Jaguar. Vicomsoft
2458 * does not zero the reserved fields in dlil_ifmod_reg_str.
2459 * As a result, we have to zero any function that used to
2460 * be reserved fields at the time Vicomsoft built their
2461 * kext. Radar #2974305
2462 */
2463 if (ifmod->reserved[0] != 0 || ifmod->reserved[1] != 0 || ifmod->reserved[2]) {
2464 if (interface_family == 123) { /* Vicom */
2465 ifmod->init_if = 0;
2466 } else {
2467 return EINVAL;
2468 }
2469 }
2470
2471 if_family = (struct if_family_str *) _MALLOC(sizeof(struct if_family_str), M_IFADDR, M_WAITOK);
2472 if (!if_family) {
2473 DLIL_PRINTF("dlil_reg_if_modules failed allocation\n");
2474 return ENOMEM;
2475 }
2476
2477 bzero(if_family, sizeof(struct if_family_str));
2478
2479 if_family->if_family = interface_family & 0xffff;
2480 if_family->shutdown = ifmod->shutdown;
2481 if_family->add_if = ifmod->add_if;
2482 if_family->del_if = ifmod->del_if;
2483 if_family->init_if = ifmod->init_if;
2484 if_family->add_proto = ifmod->add_proto;
2485 if_family->del_proto = ifmod->del_proto;
2486 if_family->ifmod_ioctl = ifmod->ifmod_ioctl;
2487 if_family->refcnt = 1;
2488 if_family->flags = 0;
2489
2490 TAILQ_INSERT_TAIL(&if_family_head, if_family, if_fam_next);
2491 return 0;
2492 }
2493
2494 int dlil_dereg_if_modules(u_long interface_family)
2495 {
2496 struct if_family_str *if_family;
2497 int ret = 0;
2498
2499
2500 if_family = find_family_module(interface_family);
2501 if (if_family == 0) {
2502 return ENXIO;
2503 }
2504
2505 if (--if_family->refcnt == 0) {
2506 if (if_family->shutdown)
2507 (*if_family->shutdown)();
2508
2509 TAILQ_REMOVE(&if_family_head, if_family, if_fam_next);
2510 FREE(if_family, M_IFADDR);
2511 }
2512 else {
2513 if_family->flags |= DLIL_SHUTDOWN;
2514 ret = DLIL_WAIT_FOR_FREE;
2515 }
2516
2517 return ret;
2518 }
2519
2520
2521
2522 int
2523 dlil_reg_proto_module(
2524 u_long protocol_family,
2525 u_long interface_family,
2526 int (*attach)(struct ifnet *ifp, u_long protocol_family),
2527 int (*detach)(struct ifnet *ifp, u_long protocol_family))
2528 {
2529 struct proto_family_str *proto_family;
2530
2531 if (attach == NULL) return EINVAL;
2532
2533 lck_mtx_lock(proto_family_mutex);
2534
2535 TAILQ_FOREACH(proto_family, &proto_family_head, proto_fam_next) {
2536 if (proto_family->proto_family == protocol_family &&
2537 proto_family->if_family == interface_family) {
2538 lck_mtx_unlock(proto_family_mutex);
2539 return EEXIST;
2540 }
2541 }
2542
2543 proto_family = (struct proto_family_str *) _MALLOC(sizeof(struct proto_family_str), M_IFADDR, M_WAITOK);
2544 if (!proto_family) {
2545 lck_mtx_unlock(proto_family_mutex);
2546 return ENOMEM;
2547 }
2548
2549 bzero(proto_family, sizeof(struct proto_family_str));
2550 proto_family->proto_family = protocol_family;
2551 proto_family->if_family = interface_family & 0xffff;
2552 proto_family->attach_proto = attach;
2553 proto_family->detach_proto = detach;
2554
2555 TAILQ_INSERT_TAIL(&proto_family_head, proto_family, proto_fam_next);
2556 lck_mtx_unlock(proto_family_mutex);
2557 return 0;
2558 }
2559
2560 int dlil_dereg_proto_module(u_long protocol_family, u_long interface_family)
2561 {
2562 struct proto_family_str *proto_family;
2563 int ret = 0;
2564
2565 lck_mtx_lock(proto_family_mutex);
2566
2567 proto_family = find_proto_module(protocol_family, interface_family);
2568 if (proto_family == 0) {
2569 lck_mtx_unlock(proto_family_mutex);
2570 return ENXIO;
2571 }
2572
2573 TAILQ_REMOVE(&proto_family_head, proto_family, proto_fam_next);
2574 FREE(proto_family, M_IFADDR);
2575
2576 lck_mtx_unlock(proto_family_mutex);
2577 return ret;
2578 }
2579
2580 int dlil_plumb_protocol(u_long protocol_family, struct ifnet *ifp)
2581 {
2582 struct proto_family_str *proto_family;
2583 int ret = 0;
2584
2585 lck_mtx_lock(proto_family_mutex);
2586 proto_family = find_proto_module(protocol_family, ifp->if_family);
2587 if (proto_family == 0) {
2588 lck_mtx_unlock(proto_family_mutex);
2589 return ENXIO;
2590 }
2591
2592 ret = proto_family->attach_proto(ifp, protocol_family);
2593
2594 lck_mtx_unlock(proto_family_mutex);
2595 return ret;
2596 }
2597
2598
2599 int dlil_unplumb_protocol(u_long protocol_family, struct ifnet *ifp)
2600 {
2601 struct proto_family_str *proto_family;
2602 int ret = 0;
2603
2604 lck_mtx_lock(proto_family_mutex);
2605
2606 proto_family = find_proto_module(protocol_family, ifp->if_family);
2607 if (proto_family && proto_family->detach_proto)
2608 ret = proto_family->detach_proto(ifp, protocol_family);
2609 else
2610 ret = dlil_detach_protocol(ifp, protocol_family);
2611
2612 lck_mtx_unlock(proto_family_mutex);
2613 return ret;
2614 }
2615
2616 static errno_t
2617 dlil_recycle_ioctl(
2618 __unused ifnet_t ifnet_ptr,
2619 __unused u_int32_t ioctl_code,
2620 __unused void *ioctl_arg)
2621 {
2622 return EOPNOTSUPP;
2623 }
2624
2625 static int
2626 dlil_recycle_output(
2627 __unused struct ifnet *ifnet_ptr,
2628 struct mbuf *m)
2629 {
2630 m_freem(m);
2631 return 0;
2632 }
2633
2634 static void
2635 dlil_recycle_free(
2636 __unused ifnet_t ifnet_ptr)
2637 {
2638 }
2639
2640 static errno_t
2641 dlil_recycle_set_bpf_tap(
2642 __unused ifnet_t ifp,
2643 __unused bpf_tap_mode mode,
2644 __unused bpf_packet_func callback)
2645 {
2646 /* XXX not sure what to do here */
2647 return 0;
2648 }
2649
2650 int dlil_if_acquire(
2651 u_long family,
2652 const void *uniqueid,
2653 size_t uniqueid_len,
2654 struct ifnet **ifp)
2655 {
2656 struct ifnet *ifp1 = NULL;
2657 struct dlil_ifnet *dlifp1 = NULL;
2658 int ret = 0;
2659
2660 lck_mtx_lock(dlil_ifnet_mutex);
2661 TAILQ_FOREACH(dlifp1, &dlil_ifnet_head, dl_if_link) {
2662
2663 ifp1 = (struct ifnet *)dlifp1;
2664
2665 if (ifp1->if_family == family) {
2666
2667 /* same uniqueid and same len or no unique id specified */
2668 if ((uniqueid_len == dlifp1->if_uniqueid_len)
2669 && !bcmp(uniqueid, dlifp1->if_uniqueid, uniqueid_len)) {
2670
2671 /* check for matching interface in use */
2672 if (ifp1->if_eflags & IFEF_INUSE) {
2673 if (uniqueid_len) {
2674 ret = EBUSY;
2675 goto end;
2676 }
2677 }
2678 else {
2679 if (!ifp1->if_lock)
2680 panic("ifp's lock is gone\n");
2681 ifnet_lock_exclusive(ifp1);
2682 ifp1->if_eflags |= (IFEF_INUSE | IFEF_REUSE);
2683 ifnet_lock_done(ifp1);
2684 *ifp = ifp1;
2685 goto end;
2686 }
2687 }
2688 }
2689 }
2690
2691 /* no interface found, allocate a new one */
2692 MALLOC(dlifp1, struct dlil_ifnet *, sizeof(*dlifp1), M_NKE, M_WAITOK);
2693 if (dlifp1 == 0) {
2694 ret = ENOMEM;
2695 goto end;
2696 }
2697
2698 bzero(dlifp1, sizeof(*dlifp1));
2699
2700 if (uniqueid_len) {
2701 MALLOC(dlifp1->if_uniqueid, void *, uniqueid_len, M_NKE, M_WAITOK);
2702 if (dlifp1->if_uniqueid == 0) {
2703 FREE(dlifp1, M_NKE);
2704 ret = ENOMEM;
2705 goto end;
2706 }
2707 bcopy(uniqueid, dlifp1->if_uniqueid, uniqueid_len);
2708 dlifp1->if_uniqueid_len = uniqueid_len;
2709 }
2710
2711 ifp1 = (struct ifnet *)dlifp1;
2712 ifp1->if_eflags |= IFEF_INUSE;
2713 ifp1->if_name = dlifp1->if_namestorage;
2714
2715 TAILQ_INSERT_TAIL(&dlil_ifnet_head, dlifp1, dl_if_link);
2716
2717 *ifp = ifp1;
2718
2719 end:
2720 lck_mtx_unlock(dlil_ifnet_mutex);
2721
2722 return ret;
2723 }
2724
2725 void dlil_if_release(struct ifnet *ifp)
2726 {
2727 struct dlil_ifnet *dlifp = (struct dlil_ifnet *)ifp;
2728
2729
2730 /* Interface does not have a lock until it is attached - radar 3713951 */
2731 if (ifp->if_lock)
2732 ifnet_lock_exclusive(ifp);
2733 ifp->if_eflags &= ~IFEF_INUSE;
2734 ifp->if_ioctl = dlil_recycle_ioctl;
2735 ifp->if_output = dlil_recycle_output;
2736 ifp->if_free = dlil_recycle_free;
2737 ifp->if_set_bpf_tap = dlil_recycle_set_bpf_tap;
2738
2739 strncpy(dlifp->if_namestorage, ifp->if_name, IFNAMSIZ);
2740 ifp->if_name = dlifp->if_namestorage;
2741 if (ifp->if_lock)
2742 ifnet_lock_done(ifp);
2743
2744 }