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