]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/if.c
xnu-1228.15.4.tar.gz
[apple/xnu.git] / bsd / net / if.c
1 /*
2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (c) 1980, 1986, 1993
30 * The Regents of the University of California. All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)if.c 8.3 (Berkeley) 1/4/94
61 * $FreeBSD: src/sys/net/if.c,v 1.85.2.9 2001/07/24 19:10:17 brooks Exp $
62 */
63 /*
64 * NOTICE: This file was modified by SPARTA, Inc. in 2006 to introduce
65 * support for mandatory and extensible security protections. This notice
66 * is included in support of clause 2.2 (b) of the Apple Public License,
67 * Version 2.0.
68 */
69
70 #include <kern/locks.h>
71
72 #include <sys/param.h>
73 #include <sys/malloc.h>
74 #include <sys/mbuf.h>
75 #include <sys/systm.h>
76 #include <sys/proc.h>
77 #include <sys/socket.h>
78 #include <sys/socketvar.h>
79 #include <sys/protosw.h>
80 #include <sys/kernel.h>
81 #include <sys/sockio.h>
82 #include <sys/syslog.h>
83 #include <sys/sysctl.h>
84
85 #include <net/if.h>
86 #include <net/if_arp.h>
87 #include <net/if_dl.h>
88 #include <net/if_types.h>
89 #include <net/if_var.h>
90 #include <net/net_osdep.h>
91 #include <net/ethernet.h>
92
93 #include <net/radix.h>
94 #include <net/route.h>
95 #ifdef __APPLE__
96 #include <net/dlil.h>
97 //#include <string.h>
98 #include <sys/domain.h>
99 #include <libkern/OSAtomic.h>
100 #endif
101
102 #if INET || INET6
103 /*XXX*/
104 #include <netinet/in.h>
105 #include <netinet/in_var.h>
106 #include <netinet/ip_var.h>
107 #if INET6
108 #include <netinet6/in6_var.h>
109 #include <netinet6/in6_ifattach.h>
110 #endif
111 #endif
112
113 extern u_long route_generation;
114 extern int use_routegenid;
115 extern int dlil_multithreaded_input;
116 extern struct dlil_threading_info *dlil_lo_thread_ptr;
117
118 #if CONFIG_MACF_NET
119 #include <security/mac_framework.h>
120 #endif
121
122 /*
123 * System initialization
124 */
125
126 static int ifconf(u_long cmd, user_addr_t ifrp, int * ret_space);
127 static void if_qflush(struct ifqueue *);
128 __private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *);
129 void if_rtproto_del(struct ifnet *ifp, int protocol);
130
131 static int if_rtmtu(struct radix_node *, void *);
132 static void if_rtmtu_update(struct ifnet *);
133
134 static struct if_clone *if_clone_lookup(const char *, int *);
135 #ifdef IF_CLONE_LIST
136 static int if_clone_list(int count, int * total, user_addr_t dst);
137 #endif
138
139 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
140 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
141
142 int ifqmaxlen = IFQ_MAXLEN;
143 struct ifnethead ifnet_head = TAILQ_HEAD_INITIALIZER(ifnet_head);
144
145 static int if_cloners_count;
146 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
147
148 static struct ifaddr *ifa_ifwithnet_common(const struct sockaddr *,
149 unsigned int);
150
151 #if INET6
152 /*
153 * XXX: declare here to avoid to include many inet6 related files..
154 * should be more generalized?
155 */
156 extern void nd6_setmtu(struct ifnet *);
157 #endif
158
159 #define M_CLONE M_IFADDR
160
161 /*
162 * Network interface utility routines.
163 *
164 * Routines with ifa_ifwith* names take sockaddr *'s as
165 * parameters.
166 */
167
168 int if_index;
169 struct ifaddr **ifnet_addrs;
170 struct ifnet **ifindex2ifnet;
171
172 __private_extern__ void
173 if_attach_ifa(
174 struct ifnet *ifp,
175 struct ifaddr *ifa)
176 {
177 ifnet_lock_assert(ifp, LCK_MTX_ASSERT_OWNED);
178 if (ifa->ifa_debug & IFA_ATTACHED) {
179 panic("if_attach_ifa: Attempted to attach address that's already attached!\n");
180 }
181 ifaref(ifa);
182 ifa->ifa_debug |= IFA_ATTACHED;
183 TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
184 }
185
186 __private_extern__ void
187 if_detach_ifa(
188 struct ifnet *ifp,
189 struct ifaddr *ifa)
190 {
191 ifnet_lock_assert(ifp, LCK_MTX_ASSERT_OWNED);
192 #if 1
193 /* Debugging code */
194 if ((ifa->ifa_debug & IFA_ATTACHED) == 0) {
195 printf("if_detach_ifa: ifa is not attached to any interface! flags=%lu\n", ifa->ifa_debug);
196 return;
197 }
198 else {
199 struct ifaddr *ifa2;
200 TAILQ_FOREACH(ifa2, &ifp->if_addrhead, ifa_link) {
201 if (ifa2 == ifa)
202 break;
203 }
204 if (ifa2 != ifa) {
205 printf("if_detach_ifa: Attempted to detach IFA that was not attached!\n");
206 }
207 }
208 #endif
209 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
210 ifa->ifa_debug &= ~IFA_ATTACHED;
211 ifafree(ifa);
212 }
213
214 #define INITIAL_IF_INDEXLIM 8
215
216 /*
217 * Function: if_next_index
218 * Purpose:
219 * Return the next available interface index.
220 * Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the
221 * added entry when necessary.
222 *
223 * Note:
224 * ifnet_addrs[] is indexed by (if_index - 1), whereas
225 * ifindex2ifnet[] is indexed by ifp->if_index. That requires us to
226 * always allocate one extra element to hold ifindex2ifnet[0], which
227 * is unused.
228 */
229 int if_next_index(void);
230
231 __private_extern__ int
232 if_next_index(void)
233 {
234 static int if_indexlim = 0;
235 int new_index;
236
237 new_index = ++if_index;
238 if (if_index > if_indexlim) {
239 unsigned n;
240 int new_if_indexlim;
241 caddr_t new_ifnet_addrs;
242 caddr_t new_ifindex2ifnet;
243 caddr_t old_ifnet_addrs;
244
245 old_ifnet_addrs = (caddr_t)ifnet_addrs;
246 if (ifnet_addrs == NULL) {
247 new_if_indexlim = INITIAL_IF_INDEXLIM;
248 } else {
249 new_if_indexlim = if_indexlim << 1;
250 }
251
252 /* allocate space for the larger arrays */
253 n = (2 * new_if_indexlim + 1) * sizeof(caddr_t);
254 new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK);
255 new_ifindex2ifnet = new_ifnet_addrs
256 + new_if_indexlim * sizeof(caddr_t);
257 bzero(new_ifnet_addrs, n);
258 if (ifnet_addrs != NULL) {
259 /* copy the existing data */
260 bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs,
261 if_indexlim * sizeof(caddr_t));
262 bcopy((caddr_t)ifindex2ifnet,
263 new_ifindex2ifnet,
264 (if_indexlim + 1) * sizeof(caddr_t));
265 }
266
267 /* switch to the new tables and size */
268 ifnet_addrs = (struct ifaddr **)new_ifnet_addrs;
269 ifindex2ifnet = (struct ifnet **)new_ifindex2ifnet;
270 if_indexlim = new_if_indexlim;
271
272 /* release the old data */
273 if (old_ifnet_addrs != NULL) {
274 _FREE((caddr_t)old_ifnet_addrs, M_IFADDR);
275 }
276 }
277 return (new_index);
278 }
279
280 /*
281 * Create a clone network interface.
282 */
283 static int
284 if_clone_create(char *name, int len)
285 {
286 struct if_clone *ifc;
287 char *dp;
288 int wildcard, bytoff, bitoff;
289 int unit;
290 int err;
291
292 ifc = if_clone_lookup(name, &unit);
293 if (ifc == NULL)
294 return (EINVAL);
295
296 if (ifunit(name) != NULL)
297 return (EEXIST);
298
299 bytoff = bitoff = 0;
300 wildcard = (unit < 0);
301 /*
302 * Find a free unit if none was given.
303 */
304 if (wildcard) {
305 while ((bytoff < ifc->ifc_bmlen)
306 && (ifc->ifc_units[bytoff] == 0xff))
307 bytoff++;
308 if (bytoff >= ifc->ifc_bmlen)
309 return (ENOSPC);
310 while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
311 bitoff++;
312 unit = (bytoff << 3) + bitoff;
313 }
314
315 if (unit > ifc->ifc_maxunit)
316 return (ENXIO);
317
318 err = (*ifc->ifc_create)(ifc, unit);
319 if (err != 0)
320 return (err);
321
322 if (!wildcard) {
323 bytoff = unit >> 3;
324 bitoff = unit - (bytoff << 3);
325 }
326
327 /*
328 * Allocate the unit in the bitmap.
329 */
330 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0,
331 ("%s: bit is already set", __func__));
332 ifc->ifc_units[bytoff] |= (1 << bitoff);
333
334 /* In the wildcard case, we need to update the name. */
335 if (wildcard) {
336 for (dp = name; *dp != '\0'; dp++);
337 if (snprintf(dp, len - (dp-name), "%d", unit) >
338 len - (dp-name) - 1) {
339 /*
340 * This can only be a programmer error and
341 * there's no straightforward way to recover if
342 * it happens.
343 */
344 panic("if_clone_create(): interface name too long");
345 }
346
347 }
348
349 return (0);
350 }
351
352 /*
353 * Destroy a clone network interface.
354 */
355 static int
356 if_clone_destroy(const char *name)
357 {
358 struct if_clone *ifc;
359 struct ifnet *ifp;
360 int bytoff, bitoff;
361 int unit;
362
363 ifc = if_clone_lookup(name, &unit);
364 if (ifc == NULL)
365 return (EINVAL);
366
367 if (unit < ifc->ifc_minifs)
368 return (EINVAL);
369
370 ifp = ifunit(name);
371 if (ifp == NULL)
372 return (ENXIO);
373
374 if (ifc->ifc_destroy == NULL)
375 return (EOPNOTSUPP);
376
377 (*ifc->ifc_destroy)(ifp);
378
379 /*
380 * Compute offset in the bitmap and deallocate the unit.
381 */
382 bytoff = unit >> 3;
383 bitoff = unit - (bytoff << 3);
384 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
385 ("%s: bit is already cleared", __func__));
386 ifc->ifc_units[bytoff] &= ~(1 << bitoff);
387 return (0);
388 }
389
390 /*
391 * Look up a network interface cloner.
392 */
393
394 static struct if_clone *
395 if_clone_lookup(const char *name, int *unitp)
396 {
397 struct if_clone *ifc;
398 const char *cp;
399 size_t i;
400
401 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) {
402 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) {
403 if (ifc->ifc_name[i] != *cp)
404 goto next_ifc;
405 }
406 goto found_name;
407 next_ifc:
408 ifc = LIST_NEXT(ifc, ifc_list);
409 }
410
411 /* No match. */
412 return ((struct if_clone *)NULL);
413
414 found_name:
415 if (*cp == '\0') {
416 i = -1;
417 } else {
418 for (i = 0; *cp != '\0'; cp++) {
419 if (*cp < '0' || *cp > '9') {
420 /* Bogus unit number. */
421 return (NULL);
422 }
423 i = (i * 10) + (*cp - '0');
424 }
425 }
426
427 if (unitp != NULL)
428 *unitp = i;
429 return (ifc);
430 }
431
432 /*
433 * Register a network interface cloner.
434 */
435 void
436 if_clone_attach(struct if_clone *ifc)
437 {
438 int bytoff, bitoff;
439 int err;
440 int len, maxclone;
441 int unit;
442
443 KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit,
444 ("%s: %s requested more units then allowed (%d > %d)",
445 __func__, ifc->ifc_name, ifc->ifc_minifs,
446 ifc->ifc_maxunit + 1));
447 /*
448 * Compute bitmap size and allocate it.
449 */
450 maxclone = ifc->ifc_maxunit + 1;
451 len = maxclone >> 3;
452 if ((len << 3) < maxclone)
453 len++;
454 ifc->ifc_units = _MALLOC(len, M_CLONE, M_WAITOK | M_ZERO);
455 bzero(ifc->ifc_units, len);
456 ifc->ifc_bmlen = len;
457
458 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
459 if_cloners_count++;
460
461 for (unit = 0; unit < ifc->ifc_minifs; unit++) {
462 err = (*ifc->ifc_create)(ifc, unit);
463 KASSERT(err == 0,
464 ("%s: failed to create required interface %s%d",
465 __func__, ifc->ifc_name, unit));
466
467 /* Allocate the unit in the bitmap. */
468 bytoff = unit >> 3;
469 bitoff = unit - (bytoff << 3);
470 ifc->ifc_units[bytoff] |= (1 << bitoff);
471 }
472 }
473
474 /*
475 * Unregister a network interface cloner.
476 */
477 void
478 if_clone_detach(struct if_clone *ifc)
479 {
480
481 LIST_REMOVE(ifc, ifc_list);
482 FREE(ifc->ifc_units, M_CLONE);
483 if_cloners_count--;
484 }
485
486 #ifdef IF_CLONE_LIST
487 /*
488 * Provide list of interface cloners to userspace.
489 */
490 static int
491 if_clone_list(int count, int * total, user_addr_t dst)
492 {
493 char outbuf[IFNAMSIZ];
494 struct if_clone *ifc;
495 int error = 0;
496
497 *total = if_cloners_count;
498 if (dst == USER_ADDR_NULL) {
499 /* Just asking how many there are. */
500 return (0);
501 }
502
503 if (count < 0)
504 return (EINVAL);
505
506 count = (if_cloners_count < count) ? if_cloners_count : count;
507
508 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
509 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
510 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
511 error = copyout(outbuf, dst, IFNAMSIZ);
512 if (error)
513 break;
514 }
515
516 return (error);
517 }
518 #endif IF_CLONE_LIST
519
520 __private_extern__ int
521 ifa_foraddr(
522 unsigned int addr)
523 {
524 struct ifnet *ifp;
525 struct ifaddr *ifa;
526 unsigned int addr2;
527 int result = 0;
528
529 ifnet_head_lock_shared();
530 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) {
531 ifnet_lock_shared(ifp);
532 for (ifa = ifp->if_addrhead.tqh_first; ifa;
533 ifa = ifa->ifa_link.tqe_next) {
534 if (ifa->ifa_addr->sa_family != AF_INET)
535 continue;
536 addr2 = IA_SIN(ifa)->sin_addr.s_addr;
537
538 if (addr == addr2) {
539 result = 1;
540 break;
541 }
542 }
543 ifnet_lock_done(ifp);
544 }
545 ifnet_head_done();
546
547 return result;
548 }
549
550 /*
551 * Return the first (primary) address of a given family on an interface.
552 */
553 __private_extern__ struct ifaddr *
554 ifa_ifpgetprimary(struct ifnet *ifp, int family)
555 {
556 struct ifaddr *ifa0 = NULL, *ifa;
557
558 ifnet_lock_shared(ifp);
559 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
560 if (ifa->ifa_addr->sa_family == family && ifa0 == NULL) {
561 ifa0 = ifa;
562 break;
563 }
564 }
565 if (ifa0 != NULL)
566 ifaref(ifa0);
567 ifnet_lock_done(ifp);
568
569 return (ifa0);
570 }
571
572 /*
573 * Locate an interface based on a complete address.
574 */
575 /*ARGSUSED*/
576 struct ifaddr *
577 ifa_ifwithaddr(
578 const struct sockaddr *addr)
579 {
580 struct ifnet *ifp;
581 struct ifaddr *ifa;
582 struct ifaddr *result = NULL;
583
584 #define equal(a1, a2) \
585 (bcmp((const void*)(a1), (const void*)(a2), ((const struct sockaddr *)(a1))->sa_len) == 0)
586
587 ifnet_head_lock_shared();
588 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) {
589 ifnet_lock_shared(ifp);
590 for (ifa = ifp->if_addrhead.tqh_first; ifa;
591 ifa = ifa->ifa_link.tqe_next) {
592 if (ifa->ifa_addr->sa_family != addr->sa_family)
593 continue;
594 if (equal(addr, ifa->ifa_addr)) {
595 result = ifa;
596 break;
597 }
598 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
599 /* IP6 doesn't have broadcast */
600 ifa->ifa_broadaddr->sa_len != 0 &&
601 equal(ifa->ifa_broadaddr, addr)) {
602 result = ifa;
603 break;
604 }
605 }
606 if (result)
607 ifaref(result);
608 ifnet_lock_done(ifp);
609 }
610 ifnet_head_done();
611
612 return result;
613 }
614 /*
615 * Locate the point to point interface with a given destination address.
616 */
617 /*ARGSUSED*/
618 struct ifaddr *
619 ifa_ifwithdstaddr(
620 const struct sockaddr *addr)
621 {
622 struct ifnet *ifp;
623 struct ifaddr *ifa;
624 struct ifaddr *result = NULL;
625
626 ifnet_head_lock_shared();
627 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) {
628 if (ifp->if_flags & IFF_POINTOPOINT) {
629 ifnet_lock_shared(ifp);
630 for (ifa = ifp->if_addrhead.tqh_first; ifa;
631 ifa = ifa->ifa_link.tqe_next) {
632 if (ifa->ifa_addr->sa_family != addr->sa_family)
633 continue;
634 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) {
635 result = ifa;
636 break;
637 }
638 }
639 if (result)
640 ifaref(result);
641 ifnet_lock_done(ifp);
642 }
643 }
644 ifnet_head_done();
645 return result;
646 }
647
648 /*
649 * Locate the source address of an interface based on a complete address.
650 */
651 struct ifaddr *
652 ifa_ifwithaddr_scoped(const struct sockaddr *addr, unsigned int ifscope)
653 {
654 struct ifaddr *result = NULL;
655 struct ifnet *ifp;
656
657 if (ifscope == IFSCOPE_NONE)
658 return (ifa_ifwithaddr(addr));
659
660 ifnet_head_lock_shared();
661 if (ifscope > (unsigned int)if_index) {
662 ifnet_head_done();
663 return (NULL);
664 }
665
666 ifp = ifindex2ifnet[ifscope];
667 if (ifp != NULL) {
668 struct ifaddr *ifa = NULL;
669
670 /*
671 * This is suboptimal; there should be a better way
672 * to search for a given address of an interface.
673 */
674 ifnet_lock_shared(ifp);
675 for (ifa = ifp->if_addrhead.tqh_first; ifa != NULL;
676 ifa = ifa->ifa_link.tqe_next) {
677 if (ifa->ifa_addr->sa_family != addr->sa_family)
678 continue;
679 if (equal(addr, ifa->ifa_addr)) {
680 result = ifa;
681 break;
682 }
683 if ((ifp->if_flags & IFF_BROADCAST) &&
684 ifa->ifa_broadaddr != NULL &&
685 /* IP6 doesn't have broadcast */
686 ifa->ifa_broadaddr->sa_len != 0 &&
687 equal(ifa->ifa_broadaddr, addr)) {
688 result = ifa;
689 break;
690 }
691 }
692 if (result != NULL)
693 ifaref(result);
694 ifnet_lock_done(ifp);
695 }
696 ifnet_head_done();
697
698 return (result);
699 }
700
701 struct ifaddr *
702 ifa_ifwithnet(const struct sockaddr *addr)
703 {
704 return (ifa_ifwithnet_common(addr, IFSCOPE_NONE));
705 }
706
707 struct ifaddr *
708 ifa_ifwithnet_scoped(const struct sockaddr *addr, unsigned int ifscope)
709 {
710 return (ifa_ifwithnet_common(addr, ifscope));
711 }
712
713 /*
714 * Find an interface on a specific network. If many, choice
715 * is most specific found.
716 */
717 static struct ifaddr *
718 ifa_ifwithnet_common(const struct sockaddr *addr, unsigned int ifscope)
719 {
720 struct ifnet *ifp;
721 struct ifaddr *ifa = NULL;
722 struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
723 u_int af = addr->sa_family;
724 const char *addr_data = addr->sa_data, *cplim;
725
726 if (!ip_doscopedroute || addr->sa_family != AF_INET)
727 ifscope = IFSCOPE_NONE;
728
729 ifnet_head_lock_shared();
730 /*
731 * AF_LINK addresses can be looked up directly by their index number,
732 * so do that if we can.
733 */
734 if (af == AF_LINK) {
735 const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)addr;
736 if (sdl->sdl_index && sdl->sdl_index <= if_index) {
737 ifa = ifnet_addrs[sdl->sdl_index - 1];
738
739 if (ifa)
740 ifaref(ifa);
741
742 ifnet_head_done();
743 return ifa;
744 }
745 }
746
747 /*
748 * Scan though each interface, looking for ones that have
749 * addresses in this address family.
750 */
751 for (ifp = ifnet_head.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
752 ifnet_lock_shared(ifp);
753 for (ifa = ifp->if_addrhead.tqh_first; ifa;
754 ifa = ifa->ifa_link.tqe_next) {
755 const char *cp, *cp2, *cp3;
756
757 if (ifa->ifa_addr->sa_family != af)
758 next: continue;
759 #ifndef __APPLE__
760 /* This breaks tunneling application trying to install a route with
761 * a specific subnet and the local address as the destination
762 * It's breaks binary compatibility with previous version of MacOS X
763 */
764 if (
765
766 #if INET6 /* XXX: for maching gif tunnel dst as routing entry gateway */
767 addr->sa_family != AF_INET6 &&
768 #endif
769 ifp->if_flags & IFF_POINTOPOINT) {
770 /*
771 * This is a bit broken as it doesn't
772 * take into account that the remote end may
773 * be a single node in the network we are
774 * looking for.
775 * The trouble is that we don't know the
776 * netmask for the remote end.
777 */
778 if (ifa->ifa_dstaddr != 0
779 && equal(addr, ifa->ifa_dstaddr)) {
780 break;
781 }
782 } else
783 #endif /* __APPLE__*/
784 {
785 /*
786 * If we're looking up with a scope,
787 * find using a matching interface.
788 */
789 if (ifscope != IFSCOPE_NONE &&
790 ifp->if_index != ifscope)
791 continue;
792
793 /*
794 * if we have a special address handler,
795 * then use it instead of the generic one.
796 */
797 if (ifa->ifa_claim_addr) {
798 if (ifa->ifa_claim_addr(ifa, addr)) {
799 break;
800 } else {
801 continue;
802 }
803 }
804
805 /*
806 * Scan all the bits in the ifa's address.
807 * If a bit dissagrees with what we are
808 * looking for, mask it with the netmask
809 * to see if it really matters.
810 * (A byte at a time)
811 */
812 if (ifa->ifa_netmask == 0)
813 continue;
814 cp = addr_data;
815 cp2 = ifa->ifa_addr->sa_data;
816 cp3 = ifa->ifa_netmask->sa_data;
817 cplim = ifa->ifa_netmask->sa_len
818 + (char *)ifa->ifa_netmask;
819 while (cp3 < cplim)
820 if ((*cp++ ^ *cp2++) & *cp3++)
821 goto next; /* next address! */
822 /*
823 * If the netmask of what we just found
824 * is more specific than what we had before
825 * (if we had one) then remember the new one
826 * before continuing to search
827 * for an even better one.
828 */
829 if (ifa_maybe == 0 ||
830 rn_refines((caddr_t)ifa->ifa_netmask,
831 (caddr_t)ifa_maybe->ifa_netmask)) {
832 ifaref(ifa);
833 if (ifa_maybe)
834 ifafree(ifa_maybe);
835 ifa_maybe = ifa;
836 }
837 }
838 }
839
840 if (ifa) {
841 ifaref(ifa);
842 }
843
844 /*
845 * ifa is set if we found an exact match.
846 * take a reference to the ifa before
847 * releasing the ifp lock
848 */
849 ifnet_lock_done(ifp);
850
851 if (ifa) {
852 break;
853 }
854 }
855 ifnet_head_done();
856 if (!ifa)
857 ifa = ifa_maybe;
858 else if (ifa_maybe) {
859 ifafree(ifa_maybe);
860 ifa_maybe = NULL;
861 }
862 return ifa;
863 }
864
865 /*
866 * Find an interface address specific to an interface best matching
867 * a given address.
868 */
869 struct ifaddr *
870 ifaof_ifpforaddr(
871 const struct sockaddr *addr,
872 struct ifnet *ifp)
873 {
874 struct ifaddr *ifa = NULL;
875 const char *cp, *cp2, *cp3;
876 char *cplim;
877 struct ifaddr *ifa_maybe = NULL;
878 struct ifaddr *better_ifa_maybe = NULL;
879 u_int af = addr->sa_family;
880
881 if (af >= AF_MAX)
882 return (NULL);
883
884 ifnet_lock_shared(ifp);
885 for (ifa = ifp->if_addrhead.tqh_first; ifa;
886 ifa = ifa->ifa_link.tqe_next) {
887 if (ifa->ifa_addr->sa_family != af)
888 continue;
889 if (ifa_maybe == 0)
890 ifa_maybe = ifa;
891 if (ifa->ifa_netmask == 0) {
892 if (equal(addr, ifa->ifa_addr) ||
893 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
894 break;
895 continue;
896 }
897 if (ifp->if_flags & IFF_POINTOPOINT) {
898 if (equal(addr, ifa->ifa_dstaddr))
899 break;
900 } else {
901 if (equal(addr, ifa->ifa_addr)) {
902 /* exact match */
903 break;
904 }
905 cp = addr->sa_data;
906 cp2 = ifa->ifa_addr->sa_data;
907 cp3 = ifa->ifa_netmask->sa_data;
908 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
909 for (; cp3 < cplim; cp3++)
910 if ((*cp++ ^ *cp2++) & *cp3)
911 break;
912 if (cp3 == cplim) {
913 /* subnet match */
914 if (better_ifa_maybe == NULL) {
915 better_ifa_maybe = ifa;
916 }
917 }
918 }
919 }
920
921 if (ifa == NULL) {
922 if (better_ifa_maybe != NULL) {
923 ifa = better_ifa_maybe;
924 } else {
925 ifa = ifa_maybe;
926 }
927 }
928 if (ifa) ifaref(ifa);
929
930 ifnet_lock_done(ifp);
931 return ifa;
932 }
933
934 #include <net/route.h>
935
936 /*
937 * Default action when installing a route with a Link Level gateway.
938 * Lookup an appropriate real ifa to point to.
939 * This should be moved to /sys/net/link.c eventually.
940 */
941 void
942 link_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa)
943 {
944 struct ifaddr *ifa;
945 struct sockaddr *dst;
946 struct ifnet *ifp;
947
948 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
949 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
950 return;
951 ifa = ifaof_ifpforaddr(dst, ifp);
952 if (ifa) {
953 rtsetifa(rt, ifa);
954 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
955 ifa->ifa_rtrequest(cmd, rt, sa);
956 ifafree(ifa);
957 }
958 }
959
960 /*
961 * if_updown will set the interface up or down. It will
962 * prevent other up/down events from occurring until this
963 * up/down event has completed.
964 *
965 * Caller must lock ifnet. This function will drop the
966 * lock. This allows ifnet_set_flags to set the rest of
967 * the flags after we change the up/down state without
968 * dropping the interface lock between setting the
969 * up/down state and updating the rest of the flags.
970 */
971 __private_extern__ void
972 if_updown(
973 struct ifnet *ifp,
974 int up)
975 {
976 int i;
977 struct ifaddr **ifa;
978 struct timespec tv;
979
980 /* Wait until no one else is changing the up/down state */
981 while ((ifp->if_eflags & IFEF_UPDOWNCHANGE) != 0) {
982 tv.tv_sec = 0;
983 tv.tv_nsec = NSEC_PER_SEC / 10;
984 ifnet_lock_done(ifp);
985 msleep(&ifp->if_eflags, NULL, 0, "if_updown", &tv);
986 ifnet_lock_exclusive(ifp);
987 }
988
989 /* Verify that the interface isn't already in the right state */
990 if ((!up && (ifp->if_flags & IFF_UP) == 0) ||
991 (up && (ifp->if_flags & IFF_UP) == IFF_UP)) {
992 return;
993 }
994
995 /* Indicate that the up/down state is changing */
996 ifp->if_eflags |= IFEF_UPDOWNCHANGE;
997
998 /* Mark interface up or down */
999 if (up) {
1000 ifp->if_flags |= IFF_UP;
1001 }
1002 else {
1003 ifp->if_flags &= ~IFF_UP;
1004 }
1005
1006 ifnet_touch_lastchange(ifp);
1007
1008 /* Drop the lock to notify addresses and route */
1009 ifnet_lock_done(ifp);
1010 if (ifnet_get_address_list(ifp, &ifa) == 0) {
1011 for (i = 0; ifa[i] != 0; i++) {
1012 pfctlinput(up ? PRC_IFUP : PRC_IFDOWN, ifa[i]->ifa_addr);
1013 }
1014 ifnet_free_address_list(ifa);
1015 }
1016 rt_ifmsg(ifp);
1017
1018 /* Aquire the lock to clear the changing flag and flush the send queue */
1019 ifnet_lock_exclusive(ifp);
1020 if (!up)
1021 if_qflush(&ifp->if_snd);
1022 ifp->if_eflags &= ~IFEF_UPDOWNCHANGE;
1023 wakeup(&ifp->if_eflags);
1024
1025 return;
1026 }
1027
1028 /*
1029 * Mark an interface down and notify protocols of
1030 * the transition.
1031 */
1032 void
1033 if_down(
1034 struct ifnet *ifp)
1035 {
1036 ifnet_lock_exclusive(ifp);
1037 if_updown(ifp, 0);
1038 ifnet_lock_done(ifp);
1039 }
1040
1041 /*
1042 * Mark an interface up and notify protocols of
1043 * the transition.
1044 */
1045 void
1046 if_up(
1047 struct ifnet *ifp)
1048 {
1049 ifnet_lock_exclusive(ifp);
1050 if_updown(ifp, 1);
1051 ifnet_lock_done(ifp);
1052 }
1053
1054 /*
1055 * Flush an interface queue.
1056 */
1057 static void
1058 if_qflush(struct ifqueue *ifq)
1059 {
1060 struct mbuf *m, *n;
1061
1062 n = ifq->ifq_head;
1063 while ((m = n) != 0) {
1064 n = m->m_act;
1065 m_freem(m);
1066 }
1067 ifq->ifq_head = NULL;
1068 ifq->ifq_tail = NULL;
1069 ifq->ifq_len = 0;
1070 }
1071
1072 /*
1073 * Map interface name to
1074 * interface structure pointer.
1075 */
1076 struct ifnet *
1077 ifunit(const char *name)
1078 {
1079 char namebuf[IFNAMSIZ + 1];
1080 const char *cp;
1081 struct ifnet *ifp;
1082 int unit;
1083 unsigned len, m;
1084 char c;
1085
1086 len = strlen(name);
1087 if (len < 2 || len > IFNAMSIZ)
1088 return NULL;
1089 cp = name + len - 1;
1090 c = *cp;
1091 if (c < '0' || c > '9')
1092 return NULL; /* trailing garbage */
1093 unit = 0;
1094 m = 1;
1095 do {
1096 if (cp == name)
1097 return NULL; /* no interface name */
1098 unit += (c - '0') * m;
1099 if (unit > 1000000)
1100 return NULL; /* number is unreasonable */
1101 m *= 10;
1102 c = *--cp;
1103 } while (c >= '0' && c <= '9');
1104 len = cp - name + 1;
1105 bcopy(name, namebuf, len);
1106 namebuf[len] = '\0';
1107 /*
1108 * Now search all the interfaces for this name/number
1109 */
1110 ifnet_head_lock_shared();
1111 TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
1112 if (strncmp(ifp->if_name, namebuf, len))
1113 continue;
1114 if (unit == ifp->if_unit)
1115 break;
1116 }
1117 ifnet_head_done();
1118 return (ifp);
1119 }
1120
1121
1122 /*
1123 * Map interface name in a sockaddr_dl to
1124 * interface structure pointer.
1125 */
1126 struct ifnet *
1127 if_withname(struct sockaddr *sa)
1128 {
1129 char ifname[IFNAMSIZ+1];
1130 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
1131
1132 if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
1133 (sdl->sdl_nlen > IFNAMSIZ) )
1134 return NULL;
1135
1136 /*
1137 * ifunit wants a null-terminated name. It may not be null-terminated
1138 * in the sockaddr. We don't want to change the caller's sockaddr,
1139 * and there might not be room to put the trailing null anyway, so we
1140 * make a local copy that we know we can null terminate safely.
1141 */
1142
1143 bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
1144 ifname[sdl->sdl_nlen] = '\0';
1145 return ifunit(ifname);
1146 }
1147
1148
1149 /*
1150 * Interface ioctls.
1151 */
1152 int
1153 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1154 {
1155 struct ifnet *ifp;
1156 struct ifreq *ifr;
1157 struct ifstat *ifs;
1158 int error = 0;
1159 short oif_flags;
1160 struct kev_msg ev_msg;
1161 struct net_event_data ev_data;
1162
1163 switch (cmd) {
1164 case SIOCGIFCONF:
1165 case OSIOCGIFCONF:
1166 case SIOCGIFCONF64:
1167 {
1168 struct ifconf64 * ifc = (struct ifconf64 *)data;
1169 user_addr_t user_addr;
1170
1171 user_addr = proc_is64bit(p)
1172 ? ifc->ifc_req64 : CAST_USER_ADDR_T(ifc->ifc_req);
1173 return (ifconf(cmd, user_addr, &ifc->ifc_len));
1174 }
1175 break;
1176 }
1177 ifr = (struct ifreq *)data;
1178 switch (cmd) {
1179 case SIOCIFCREATE:
1180 case SIOCIFDESTROY:
1181 error = proc_suser(p);
1182 if (error)
1183 return (error);
1184 return ((cmd == SIOCIFCREATE) ?
1185 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
1186 if_clone_destroy(ifr->ifr_name));
1187 #if IF_CLONE_LIST
1188 case SIOCIFGCLONERS:
1189 case SIOCIFGCLONERS64:
1190 {
1191 struct if_clonereq64 * ifcr = (struct if_clonereq64 *)data;
1192 user_addr = proc_is64bit(p)
1193 ? ifcr->ifcr_ifcru.ifcru_buffer64
1194 : CAST_USER_ADDR_T(ifcr->ifcr_ifcru.ifcru_buffer32);
1195 return (if_clone_list(ifcr->ifcr_count, &ifcr->ifcr_total,
1196 user_data));
1197 }
1198 #endif IF_CLONE_LIST
1199 }
1200
1201 ifp = ifunit(ifr->ifr_name);
1202 if (ifp == 0)
1203 return (ENXIO);
1204 switch (cmd) {
1205
1206 case SIOCGIFFLAGS:
1207 ifnet_lock_shared(ifp);
1208 ifr->ifr_flags = ifp->if_flags;
1209 ifnet_lock_done(ifp);
1210 break;
1211
1212 #if CONFIG_MACF_NET
1213 case SIOCGIFMAC:
1214 error = mac_ifnet_label_get(kauth_cred_get(), ifr, ifp);
1215 if (error)
1216 return (error);
1217 break;
1218 #endif
1219 case SIOCGIFMETRIC:
1220 ifnet_lock_shared(ifp);
1221 ifr->ifr_metric = ifp->if_metric;
1222 ifnet_lock_done(ifp);
1223 break;
1224
1225 case SIOCGIFMTU:
1226 ifnet_lock_shared(ifp);
1227 ifr->ifr_mtu = ifp->if_mtu;
1228 ifnet_lock_done(ifp);
1229 break;
1230
1231 case SIOCGIFPHYS:
1232 ifnet_lock_shared(ifp);
1233 ifr->ifr_phys = ifp->if_physical;
1234 ifnet_lock_done(ifp);
1235 break;
1236
1237 case SIOCSIFFLAGS:
1238 error = proc_suser(p);
1239 if (error)
1240 return (error);
1241
1242 ifnet_set_flags(ifp, ifr->ifr_flags, (u_int16_t)~IFF_CANTCHANGE);
1243
1244 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1245 cmd, data);
1246
1247 if (error == 0) {
1248 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1249 ev_msg.kev_class = KEV_NETWORK_CLASS;
1250 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1251
1252 ev_msg.event_code = KEV_DL_SIFFLAGS;
1253 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1254 ev_data.if_family = ifp->if_family;
1255 ev_data.if_unit = (unsigned long) ifp->if_unit;
1256 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1257 ev_msg.dv[0].data_ptr = &ev_data;
1258 ev_msg.dv[1].data_length = 0;
1259 kev_post_msg(&ev_msg);
1260 }
1261 ifnet_touch_lastchange(ifp);
1262 break;
1263
1264 #if CONFIG_MACF_NET
1265 case SIOCSIFMAC:
1266 error = mac_ifnet_label_set(kauth_cred_get(), ifr, ifp);
1267 if (error)
1268 return (error);
1269 break;
1270 #endif
1271 case SIOCSIFMETRIC:
1272 error = proc_suser(p);
1273 if (error)
1274 return (error);
1275 ifp->if_metric = ifr->ifr_metric;
1276
1277
1278 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1279 ev_msg.kev_class = KEV_NETWORK_CLASS;
1280 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1281
1282 ev_msg.event_code = KEV_DL_SIFMETRICS;
1283 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1284 ev_data.if_family = ifp->if_family;
1285 ev_data.if_unit = (unsigned long) ifp->if_unit;
1286 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1287 ev_msg.dv[0].data_ptr = &ev_data;
1288
1289 ev_msg.dv[1].data_length = 0;
1290 kev_post_msg(&ev_msg);
1291
1292 ifnet_touch_lastchange(ifp);
1293 break;
1294
1295 case SIOCSIFPHYS:
1296 error = proc_suser(p);
1297 if (error)
1298 return error;
1299
1300 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1301 cmd, data);
1302
1303 if (error == 0) {
1304 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1305 ev_msg.kev_class = KEV_NETWORK_CLASS;
1306 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1307
1308 ev_msg.event_code = KEV_DL_SIFPHYS;
1309 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1310 ev_data.if_family = ifp->if_family;
1311 ev_data.if_unit = (unsigned long) ifp->if_unit;
1312 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1313 ev_msg.dv[0].data_ptr = &ev_data;
1314 ev_msg.dv[1].data_length = 0;
1315 kev_post_msg(&ev_msg);
1316
1317 ifnet_touch_lastchange(ifp);
1318 }
1319 return(error);
1320
1321 case SIOCSIFMTU:
1322 {
1323 u_long oldmtu = ifp->if_mtu;
1324
1325 error = proc_suser(p);
1326 if (error)
1327 return (error);
1328 if (ifp->if_ioctl == NULL)
1329 return (EOPNOTSUPP);
1330 if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU)
1331 return (EINVAL);
1332
1333 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1334 cmd, data);
1335
1336 if (error == 0) {
1337 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1338 ev_msg.kev_class = KEV_NETWORK_CLASS;
1339 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1340
1341 ev_msg.event_code = KEV_DL_SIFMTU;
1342 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1343 ev_data.if_family = ifp->if_family;
1344 ev_data.if_unit = (unsigned long) ifp->if_unit;
1345 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1346 ev_msg.dv[0].data_ptr = &ev_data;
1347 ev_msg.dv[1].data_length = 0;
1348 kev_post_msg(&ev_msg);
1349
1350 ifnet_touch_lastchange(ifp);
1351 rt_ifmsg(ifp);
1352 }
1353 /*
1354 * If the link MTU changed, do network layer specific procedure
1355 * and update all route entries associated with the interface,
1356 * so that their MTU metric gets updated.
1357 */
1358 if (error == 0 && ifp->if_mtu != oldmtu) {
1359 if_rtmtu_update(ifp);
1360 #if INET6
1361 nd6_setmtu(ifp);
1362 #endif
1363 }
1364 return (error);
1365 }
1366
1367 case SIOCADDMULTI:
1368 case SIOCDELMULTI:
1369 error = proc_suser(p);
1370 if (error)
1371 return (error);
1372
1373 /* Don't allow group membership on non-multicast interfaces. */
1374 if ((ifp->if_flags & IFF_MULTICAST) == 0)
1375 return EOPNOTSUPP;
1376
1377 #ifndef __APPLE__
1378 /* Don't let users screw up protocols' entries. */
1379 if (ifr->ifr_addr.sa_family != AF_LINK)
1380 return EINVAL;
1381 #endif
1382
1383 if (cmd == SIOCADDMULTI) {
1384 error = if_addmulti(ifp, &ifr->ifr_addr, NULL);
1385 ev_msg.event_code = KEV_DL_ADDMULTI;
1386 } else {
1387 error = if_delmulti(ifp, &ifr->ifr_addr);
1388 ev_msg.event_code = KEV_DL_DELMULTI;
1389 }
1390 if (error == 0) {
1391 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1392 ev_msg.kev_class = KEV_NETWORK_CLASS;
1393 ev_msg.kev_subclass = KEV_DL_SUBCLASS;
1394 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
1395
1396 ev_data.if_family = ifp->if_family;
1397 ev_data.if_unit = (unsigned long) ifp->if_unit;
1398 ev_msg.dv[0].data_length = sizeof(struct net_event_data);
1399 ev_msg.dv[0].data_ptr = &ev_data;
1400 ev_msg.dv[1].data_length = 0;
1401 kev_post_msg(&ev_msg);
1402
1403 ifnet_touch_lastchange(ifp);
1404 }
1405 return error;
1406
1407 case SIOCSIFPHYADDR:
1408 case SIOCDIFPHYADDR:
1409 #if INET6
1410 case SIOCSIFPHYADDR_IN6:
1411 #endif
1412 case SIOCSLIFPHYADDR:
1413 case SIOCSIFMEDIA:
1414 case SIOCSIFGENERIC:
1415 case SIOCSIFLLADDR:
1416 case SIOCSIFALTMTU:
1417 case SIOCSIFVLAN:
1418 case SIOCSIFBOND:
1419 error = proc_suser(p);
1420 if (error)
1421 return (error);
1422
1423 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1424 cmd, data);
1425
1426 if (error == 0)
1427 ifnet_touch_lastchange(ifp);
1428 return error;
1429
1430 case SIOCGIFSTATUS:
1431 ifs = (struct ifstat *)data;
1432 ifs->ascii[0] = '\0';
1433
1434 case SIOCGIFPSRCADDR:
1435 case SIOCGIFPDSTADDR:
1436 case SIOCGLIFPHYADDR:
1437 case SIOCGIFMEDIA:
1438 case SIOCGIFGENERIC:
1439 case SIOCGIFDEVMTU:
1440 return ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1441 cmd, data);
1442 case SIOCGIFVLAN:
1443 case SIOCGIFBOND:
1444 return ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1445 cmd, data);
1446
1447 default:
1448 oif_flags = ifp->if_flags;
1449 if (so->so_proto == 0)
1450 return (EOPNOTSUPP);
1451 {
1452 int ocmd = cmd;
1453
1454 switch (cmd) {
1455
1456 case SIOCSIFDSTADDR:
1457 case SIOCSIFADDR:
1458 case SIOCSIFBRDADDR:
1459 case SIOCSIFNETMASK:
1460 #if BYTE_ORDER != BIG_ENDIAN
1461 if (ifr->ifr_addr.sa_family == 0 &&
1462 ifr->ifr_addr.sa_len < 16) {
1463 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1464 ifr->ifr_addr.sa_len = 16;
1465 }
1466 #else
1467 if (ifr->ifr_addr.sa_len == 0)
1468 ifr->ifr_addr.sa_len = 16;
1469 #endif
1470 break;
1471
1472 case OSIOCGIFADDR:
1473 cmd = SIOCGIFADDR;
1474 break;
1475
1476 case OSIOCGIFDSTADDR:
1477 cmd = SIOCGIFDSTADDR;
1478 break;
1479
1480 case OSIOCGIFBRDADDR:
1481 cmd = SIOCGIFBRDADDR;
1482 break;
1483
1484 case OSIOCGIFNETMASK:
1485 cmd = SIOCGIFNETMASK;
1486 }
1487 socket_lock(so, 1);
1488 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
1489 data, ifp, p));
1490 socket_unlock(so, 1);
1491 switch (ocmd) {
1492
1493 case OSIOCGIFADDR:
1494 case OSIOCGIFDSTADDR:
1495 case OSIOCGIFBRDADDR:
1496 case OSIOCGIFNETMASK:
1497 *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1498
1499 }
1500 }
1501 if (cmd == SIOCSIFKPI) {
1502 int temperr = proc_suser(p);
1503 if (temperr != 0)
1504 error = temperr;
1505 }
1506
1507 if (error == EOPNOTSUPP || error == ENOTSUP)
1508 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family,
1509 cmd, data);
1510
1511 return (error);
1512 }
1513 return (0);
1514 }
1515
1516 int
1517 ifioctllocked(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1518 {
1519 int error;
1520
1521 socket_unlock(so, 0);
1522 error = ifioctl(so, cmd, data, p);
1523 socket_lock(so, 0);
1524 return(error);
1525 }
1526
1527 /*
1528 * Set/clear promiscuous mode on interface ifp based on the truth value
1529 * of pswitch. The calls are reference counted so that only the first
1530 * "on" request actually has an effect, as does the final "off" request.
1531 * Results are undefined if the "off" and "on" requests are not matched.
1532 */
1533 errno_t
1534 ifnet_set_promiscuous(
1535 ifnet_t ifp,
1536 int pswitch)
1537 {
1538 struct ifreq ifr;
1539 int error = 0;
1540 int oldflags;
1541 int locked = 0;
1542 int changed = 0;
1543
1544 ifnet_lock_exclusive(ifp);
1545 locked = 1;
1546 oldflags = ifp->if_flags;
1547 if (pswitch) {
1548 /*
1549 * If the device is not configured up, we cannot put it in
1550 * promiscuous mode.
1551 */
1552 if ((ifp->if_flags & IFF_UP) == 0) {
1553 error = ENETDOWN;
1554 goto done;
1555 }
1556 if (ifp->if_pcount++ != 0) {
1557 goto done;
1558 }
1559 ifp->if_flags |= IFF_PROMISC;
1560 } else {
1561 if (--ifp->if_pcount > 0)
1562 goto done;
1563 ifp->if_flags &= ~IFF_PROMISC;
1564 }
1565 ifr.ifr_flags = ifp->if_flags;
1566 locked = 0;
1567 ifnet_lock_done(ifp);
1568 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, &ifr);
1569 if (error == 0)
1570 rt_ifmsg(ifp);
1571 else
1572 ifp->if_flags = oldflags;
1573 done:
1574 if (locked) ifnet_lock_done(ifp);
1575 if (changed) {
1576 log(LOG_INFO, "%s%d: promiscuous mode %s\n",
1577 ifp->if_name, ifp->if_unit,
1578 pswitch != 0 ? "enabled" : "disabled");
1579 }
1580 return error;
1581 }
1582
1583 /*
1584 * Return interface configuration
1585 * of system. List may be used
1586 * in later ioctl's (above) to get
1587 * other information.
1588 */
1589 /*ARGSUSED*/
1590 static int
1591 ifconf(u_long cmd, user_addr_t ifrp, int * ret_space)
1592 {
1593 struct ifnet *ifp = NULL;
1594 struct ifaddr *ifa;
1595 struct ifreq ifr;
1596 int error = 0;
1597 size_t space;
1598
1599 /*
1600 * Zero the ifr buffer to make sure we don't
1601 * disclose the contents of the stack.
1602 */
1603 bzero(&ifr, sizeof(struct ifreq));
1604
1605 space = *ret_space;
1606 ifnet_head_lock_shared();
1607 for (ifp = ifnet_head.tqh_first; space > sizeof(ifr) && ifp; ifp = ifp->if_link.tqe_next) {
1608 char workbuf[64];
1609 size_t ifnlen, addrs;
1610
1611 ifnlen = snprintf(workbuf, sizeof(workbuf),
1612 "%s%d", ifp->if_name, ifp->if_unit);
1613 if(ifnlen + 1 > sizeof ifr.ifr_name) {
1614 error = ENAMETOOLONG;
1615 break;
1616 } else {
1617 strlcpy(ifr.ifr_name, workbuf, IFNAMSIZ);
1618 }
1619
1620 ifnet_lock_shared(ifp);
1621
1622 addrs = 0;
1623 ifa = ifp->if_addrhead.tqh_first;
1624 for ( ; space > sizeof (ifr) && ifa;
1625 ifa = ifa->ifa_link.tqe_next) {
1626 struct sockaddr *sa = ifa->ifa_addr;
1627 #ifndef __APPLE__
1628 if (curproc->p_prison && prison_if(curproc, sa))
1629 continue;
1630 #endif
1631 addrs++;
1632 if (cmd == OSIOCGIFCONF) {
1633 struct osockaddr *osa =
1634 (struct osockaddr *)&ifr.ifr_addr;
1635 ifr.ifr_addr = *sa;
1636 osa->sa_family = sa->sa_family;
1637 error = copyout((caddr_t)&ifr, ifrp, sizeof(ifr));
1638 ifrp += sizeof(struct ifreq);
1639 } else if (sa->sa_len <= sizeof(*sa)) {
1640 ifr.ifr_addr = *sa;
1641 error = copyout((caddr_t)&ifr, ifrp, sizeof(ifr));
1642 ifrp += sizeof(struct ifreq);
1643 } else {
1644 if (space < sizeof (ifr) + sa->sa_len - sizeof(*sa))
1645 break;
1646 space -= sa->sa_len - sizeof(*sa);
1647 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr.ifr_name));
1648 if (error == 0) {
1649 error = copyout((caddr_t)sa,
1650 (ifrp + offsetof(struct ifreq, ifr_addr)),
1651 sa->sa_len);
1652 }
1653 ifrp += (sa->sa_len + offsetof(struct ifreq, ifr_addr));
1654 }
1655 if (error)
1656 break;
1657 space -= sizeof (ifr);
1658 }
1659 ifnet_lock_done(ifp);
1660
1661 if (error)
1662 break;
1663 if (!addrs) {
1664 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1665 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr));
1666 if (error)
1667 break;
1668 space -= sizeof (ifr);
1669 ifrp += sizeof(struct ifreq);
1670 }
1671 }
1672 ifnet_head_done();
1673 *ret_space -= space;
1674 return (error);
1675 }
1676
1677 /*
1678 * Just like if_promisc(), but for all-multicast-reception mode.
1679 */
1680 int
1681 if_allmulti(struct ifnet *ifp, int onswitch)
1682 {
1683 int error = 0;
1684 int modified = 0;
1685
1686 ifnet_lock_exclusive(ifp);
1687
1688 if (onswitch) {
1689 if (ifp->if_amcount++ == 0) {
1690 ifp->if_flags |= IFF_ALLMULTI;
1691 modified = 1;
1692 }
1693 } else {
1694 if (ifp->if_amcount > 1) {
1695 ifp->if_amcount--;
1696 } else {
1697 ifp->if_amcount = 0;
1698 ifp->if_flags &= ~IFF_ALLMULTI;
1699 modified = 1;
1700 }
1701 }
1702 ifnet_lock_done(ifp);
1703
1704 if (modified)
1705 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
1706
1707 if (error == 0)
1708 rt_ifmsg(ifp);
1709 return error;
1710 }
1711
1712 void
1713 ifma_reference(
1714 struct ifmultiaddr *ifma)
1715 {
1716 if (OSIncrementAtomic((SInt32 *)&ifma->ifma_refcount) <= 0)
1717 panic("ifma_reference: ifma already released or invalid\n");
1718 }
1719
1720 void
1721 ifma_release(
1722 struct ifmultiaddr *ifma)
1723 {
1724 while (ifma) {
1725 struct ifmultiaddr *next;
1726 int32_t prevValue = OSDecrementAtomic((SInt32 *)&ifma->ifma_refcount);
1727 if (prevValue < 1)
1728 panic("ifma_release: ifma already released or invalid\n");
1729 if (prevValue != 1)
1730 break;
1731
1732 /* Allow the allocator of the protospec to free it */
1733 if (ifma->ifma_protospec && ifma->ifma_free) {
1734 ifma->ifma_free(ifma->ifma_protospec);
1735 }
1736
1737 next = ifma->ifma_ll;
1738 FREE(ifma->ifma_addr, M_IFMADDR);
1739 FREE(ifma, M_IFMADDR);
1740 ifma = next;
1741 }
1742 }
1743
1744 /*
1745 * Find an ifmultiaddr that matches a socket address on an interface.
1746 *
1747 * Caller is responsible for holding the ifnet_lock while calling
1748 * this function.
1749 */
1750 static int
1751 if_addmulti_doesexist(
1752 struct ifnet *ifp,
1753 const struct sockaddr *sa,
1754 struct ifmultiaddr **retifma)
1755 {
1756 struct ifmultiaddr *ifma;
1757 for (ifma = ifp->if_multiaddrs.lh_first; ifma;
1758 ifma = ifma->ifma_link.le_next) {
1759 if (equal(sa, ifma->ifma_addr)) {
1760 ifma->ifma_usecount++;
1761 if (retifma) {
1762 *retifma = ifma;
1763 ifma_reference(*retifma);
1764 }
1765 return 0;
1766 }
1767 }
1768
1769 return ENOENT;
1770 }
1771
1772 /*
1773 * Radar 3642395, make sure all multicasts are in a standard format.
1774 */
1775 static struct sockaddr*
1776 copy_and_normalize(
1777 const struct sockaddr *original)
1778 {
1779 int alen = 0;
1780 const u_char *aptr = NULL;
1781 struct sockaddr *copy = NULL;
1782 struct sockaddr_dl *sdl_new = NULL;
1783 int len = 0;
1784
1785 if (original->sa_family != AF_LINK &&
1786 original->sa_family != AF_UNSPEC) {
1787 /* Just make a copy */
1788 MALLOC(copy, struct sockaddr*, original->sa_len, M_IFADDR, M_WAITOK);
1789 if (copy != NULL)
1790 bcopy(original, copy, original->sa_len);
1791 return copy;
1792 }
1793
1794 switch (original->sa_family) {
1795 case AF_LINK: {
1796 const struct sockaddr_dl *sdl_original =
1797 (const struct sockaddr_dl*)original;
1798
1799 if (sdl_original->sdl_nlen + sdl_original->sdl_alen + sdl_original->sdl_slen +
1800 offsetof(struct sockaddr_dl, sdl_data) > sdl_original->sdl_len)
1801 return NULL;
1802
1803 alen = sdl_original->sdl_alen;
1804 aptr = CONST_LLADDR(sdl_original);
1805 }
1806 break;
1807
1808 case AF_UNSPEC: {
1809 if (original->sa_len < ETHER_ADDR_LEN +
1810 offsetof(struct sockaddr, sa_data)) {
1811 return NULL;
1812 }
1813
1814 alen = ETHER_ADDR_LEN;
1815 aptr = (const u_char*)original->sa_data;
1816 }
1817 break;
1818 }
1819
1820 if (alen == 0 || aptr == NULL)
1821 return NULL;
1822
1823 len = alen + offsetof(struct sockaddr_dl, sdl_data);
1824 MALLOC(sdl_new, struct sockaddr_dl*, len, M_IFADDR, M_WAITOK);
1825
1826 if (sdl_new != NULL) {
1827 bzero(sdl_new, len);
1828 sdl_new->sdl_len = len;
1829 sdl_new->sdl_family = AF_LINK;
1830 sdl_new->sdl_alen = alen;
1831 bcopy(aptr, LLADDR(sdl_new), alen);
1832 }
1833
1834 return (struct sockaddr*)sdl_new;
1835 }
1836
1837 /*
1838 * Add a multicast listenership to the interface in question.
1839 * The link layer provides a routine which converts
1840 */
1841 int
1842 if_addmulti(
1843 struct ifnet *ifp, /* interface to manipulate */
1844 const struct sockaddr *sa, /* address to add */
1845 struct ifmultiaddr **retifma)
1846 {
1847 struct sockaddr_storage storage;
1848 struct sockaddr *llsa = NULL;
1849 struct sockaddr *dupsa = NULL;
1850 int error = 0;
1851 struct ifmultiaddr *ifma = NULL;
1852 struct ifmultiaddr *llifma = NULL;
1853
1854 /* If sa is a AF_LINK or AF_UNSPEC, duplicate and normalize it */
1855 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) {
1856 dupsa = copy_and_normalize(sa);
1857 if (dupsa == NULL) {
1858 return ENOMEM;
1859 }
1860 sa = dupsa;
1861 }
1862
1863 ifnet_lock_exclusive(ifp);
1864 error = if_addmulti_doesexist(ifp, sa, retifma);
1865 ifnet_lock_done(ifp);
1866
1867 if (error == 0) {
1868 goto cleanup;
1869 }
1870
1871 /*
1872 * Give the link layer a chance to accept/reject it, and also
1873 * find out which AF_LINK address this maps to, if it isn't one
1874 * already.
1875 */
1876 error = dlil_resolve_multi(ifp, sa, (struct sockaddr*)&storage,
1877 sizeof(storage));
1878 if (error == 0 && storage.ss_len != 0) {
1879 llsa = copy_and_normalize((struct sockaddr*)&storage);
1880 if (llsa == NULL) {
1881 error = ENOMEM;
1882 goto cleanup;
1883 }
1884
1885 MALLOC(llifma, struct ifmultiaddr *, sizeof *llifma, M_IFMADDR, M_WAITOK);
1886 if (llifma == NULL) {
1887 error = ENOMEM;
1888 goto cleanup;
1889 }
1890 }
1891
1892 /* to be similar to FreeBSD */
1893 if (error == EOPNOTSUPP) {
1894 error = 0;
1895 }
1896 else if (error) {
1897 goto cleanup;
1898 }
1899
1900 /* Allocate while we aren't holding any locks */
1901 if (dupsa == NULL) {
1902 dupsa = copy_and_normalize(sa);
1903 if (dupsa == NULL) {
1904 error = ENOMEM;
1905 goto cleanup;
1906 }
1907 }
1908 MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, M_IFMADDR, M_WAITOK);
1909 if (ifma == NULL) {
1910 error = ENOMEM;
1911 goto cleanup;
1912 }
1913
1914 ifnet_lock_exclusive(ifp);
1915 /*
1916 * Check again for the matching multicast.
1917 */
1918 if ((error = if_addmulti_doesexist(ifp, sa, retifma)) == 0) {
1919 ifnet_lock_done(ifp);
1920 goto cleanup;
1921 }
1922
1923 bzero(ifma, sizeof(*ifma));
1924 ifma->ifma_addr = dupsa;
1925 ifma->ifma_ifp = ifp;
1926 ifma->ifma_usecount = 1;
1927 ifma->ifma_refcount = 1;
1928
1929 if (llifma != 0) {
1930 if (if_addmulti_doesexist(ifp, llsa, &ifma->ifma_ll) == 0) {
1931 FREE(llsa, M_IFMADDR);
1932 FREE(llifma, M_IFMADDR);
1933 } else {
1934 bzero(llifma, sizeof(*llifma));
1935 llifma->ifma_addr = llsa;
1936 llifma->ifma_ifp = ifp;
1937 llifma->ifma_usecount = 1;
1938 llifma->ifma_refcount = 1;
1939 LIST_INSERT_HEAD(&ifp->if_multiaddrs, llifma, ifma_link);
1940
1941 ifma->ifma_ll = llifma;
1942 ifma_reference(ifma->ifma_ll);
1943 }
1944 }
1945
1946 LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
1947
1948 if (retifma) {
1949 *retifma = ifma;
1950 ifma_reference(*retifma);
1951 }
1952
1953 ifnet_lock_done(ifp);
1954
1955 if (llsa != 0)
1956 rt_newmaddrmsg(RTM_NEWMADDR, ifma);
1957
1958 /*
1959 * We are certain we have added something, so call down to the
1960 * interface to let them know about it.
1961 */
1962 ifnet_ioctl(ifp, 0, SIOCADDMULTI, NULL);
1963
1964 return 0;
1965
1966 cleanup:
1967 if (ifma)
1968 FREE(ifma, M_IFADDR);
1969 if (dupsa)
1970 FREE(dupsa, M_IFADDR);
1971 if (llifma)
1972 FREE(llifma, M_IFADDR);
1973 if (llsa)
1974 FREE(llsa, M_IFADDR);
1975
1976 return error;
1977 }
1978
1979 int
1980 if_delmultiaddr(
1981 struct ifmultiaddr *ifma,
1982 int locked)
1983 {
1984 struct ifnet *ifp;
1985 int do_del_multi = 0;
1986
1987 ifp = ifma->ifma_ifp;
1988
1989 if (!locked && ifp) {
1990 ifnet_lock_exclusive(ifp);
1991 }
1992
1993 while (ifma != NULL) {
1994 struct ifmultiaddr *ll_ifma;
1995
1996 if (ifma->ifma_usecount > 1) {
1997 ifma->ifma_usecount--;
1998 break;
1999 }
2000
2001 if (ifp)
2002 LIST_REMOVE(ifma, ifma_link);
2003
2004 ll_ifma = ifma->ifma_ll;
2005
2006 if (ll_ifma) { /* send a routing msg for network addresses only */
2007 if (ifp)
2008 ifnet_lock_done(ifp);
2009 rt_newmaddrmsg(RTM_DELMADDR, ifma);
2010 if (ifp)
2011 ifnet_lock_exclusive(ifp);
2012 }
2013
2014 /*
2015 * Make sure the interface driver is notified
2016 * in the case of a link layer mcast group being left.
2017 */
2018 if (ll_ifma == 0) {
2019 if (ifp && ifma->ifma_addr->sa_family == AF_LINK)
2020 do_del_multi = 1;
2021 break;
2022 }
2023
2024 if (ifp)
2025 ifma_release(ifma);
2026
2027 ifma = ll_ifma;
2028 }
2029
2030 if (!locked && ifp) {
2031 /* This wasn't initially locked, we should unlock it */
2032 ifnet_lock_done(ifp);
2033 }
2034
2035 if (do_del_multi) {
2036 if (locked)
2037 ifnet_lock_done(ifp);
2038 ifnet_ioctl(ifp, 0, SIOCDELMULTI, NULL);
2039 if (locked)
2040 ifnet_lock_exclusive(ifp);
2041 }
2042
2043 return 0;
2044 }
2045
2046 /*
2047 * Remove a reference to a multicast address on this interface. Yell
2048 * if the request does not match an existing membership.
2049 */
2050 int
2051 if_delmulti(
2052 struct ifnet *ifp,
2053 const struct sockaddr *sa)
2054 {
2055 struct ifmultiaddr *ifma;
2056 struct sockaddr *dupsa = NULL;
2057 int retval = 0;
2058
2059 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) {
2060 dupsa = copy_and_normalize(sa);
2061 if (dupsa == NULL) {
2062 return ENOMEM;
2063 }
2064 sa = dupsa;
2065 }
2066
2067 ifnet_lock_exclusive(ifp);
2068 for (ifma = ifp->if_multiaddrs.lh_first; ifma;
2069 ifma = ifma->ifma_link.le_next)
2070 if (equal(sa, ifma->ifma_addr))
2071 break;
2072 if (ifma == 0) {
2073 ifnet_lock_done(ifp);
2074 if (dupsa)
2075 FREE(dupsa, M_IFADDR);
2076 return ENOENT;
2077 }
2078
2079 retval = if_delmultiaddr(ifma, 1);
2080 ifnet_lock_done(ifp);
2081 if (dupsa)
2082 FREE(dupsa, M_IFADDR);
2083
2084 return retval;
2085 }
2086
2087
2088 /*
2089 * We don't use if_setlladdr, our interfaces are responsible for
2090 * handling the SIOCSIFLLADDR ioctl.
2091 */
2092 #ifndef __APPLE__
2093 int
2094 if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
2095 {
2096 ...
2097 }
2098 #endif
2099
2100 struct ifmultiaddr *
2101 ifmaof_ifpforaddr(const struct sockaddr *sa, struct ifnet *ifp)
2102 {
2103 struct ifmultiaddr *ifma;
2104
2105 ifnet_lock_shared(ifp);
2106 for (ifma = ifp->if_multiaddrs.lh_first; ifma;
2107 ifma = ifma->ifma_link.le_next)
2108 if (equal(ifma->ifma_addr, sa))
2109 break;
2110 ifnet_lock_done(ifp);
2111
2112 return ifma;
2113 }
2114
2115 SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Link layers");
2116 SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Generic link-management");
2117
2118
2119 /*
2120 * Shutdown all network activity. Used boot() when halting
2121 * system.
2122 */
2123 int
2124 if_down_all(void)
2125 {
2126 struct ifnet **ifp;
2127 u_int32_t count;
2128 u_int32_t i;
2129
2130 if (ifnet_list_get_all(IFNET_FAMILY_ANY, &ifp, &count) == 0) {
2131 for (i = 0; i < count; i++) {
2132 if_down(ifp[i]);
2133 dlil_proto_unplumb_all(ifp[i]);
2134 }
2135 ifnet_list_free(ifp);
2136 }
2137
2138 return 0;
2139 }
2140
2141 /*
2142 * Delete Routes for a Network Interface
2143 *
2144 * Called for each routing entry via the rnh->rnh_walktree() call above
2145 * to delete all route entries referencing a detaching network interface.
2146 *
2147 * Arguments:
2148 * rn pointer to node in the routing table
2149 * arg argument passed to rnh->rnh_walktree() - detaching interface
2150 *
2151 * Returns:
2152 * 0 successful
2153 * errno failed - reason indicated
2154 *
2155 */
2156 static int
2157 if_rtdel(
2158 struct radix_node *rn,
2159 void *arg)
2160 {
2161 struct rtentry *rt = (struct rtentry *)rn;
2162 struct ifnet *ifp = arg;
2163 int err;
2164
2165 if (rt != NULL && rt->rt_ifp == ifp) {
2166
2167 /*
2168 * Protect (sorta) against walktree recursion problems
2169 * with cloned routes
2170 */
2171 if ((rt->rt_flags & RTF_UP) == 0)
2172 return (0);
2173
2174 err = rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway,
2175 rt_mask(rt), rt->rt_flags,
2176 (struct rtentry **) NULL);
2177 if (err) {
2178 log(LOG_WARNING, "if_rtdel: error %d\n", err);
2179 }
2180 }
2181
2182 return (0);
2183 }
2184
2185 /*
2186 * Removes routing table reference to a given interfacei
2187 * for a given protocol family
2188 */
2189 void if_rtproto_del(struct ifnet *ifp, int protocol)
2190 {
2191 struct radix_node_head *rnh;
2192 if (use_routegenid)
2193 route_generation++;
2194 if ((protocol <= AF_MAX) && (protocol >= 0) &&
2195 ((rnh = rt_tables[protocol]) != NULL) && (ifp != NULL)) {
2196 lck_mtx_lock(rt_mtx);
2197 (void) rnh->rnh_walktree(rnh, if_rtdel, ifp);
2198 lck_mtx_unlock(rt_mtx);
2199 }
2200 }
2201
2202 static int
2203 if_rtmtu(struct radix_node *rn, void *arg)
2204 {
2205 struct rtentry *rt = (struct rtentry *)rn;
2206 struct ifnet *ifp = arg;
2207
2208 if (rt->rt_ifp == ifp) {
2209 /*
2210 * Update the MTU of this entry only if the MTU
2211 * has not been locked (RTV_MTU is not set) and
2212 * if it was non-zero to begin with.
2213 */
2214 if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu)
2215 rt->rt_rmx.rmx_mtu = ifp->if_mtu;
2216 }
2217
2218 return (0);
2219 }
2220
2221 /*
2222 * Update the MTU metric of all route entries in all protocol tables
2223 * associated with a particular interface; this is called when the
2224 * MTU of that interface has changed.
2225 */
2226 static
2227 void if_rtmtu_update(struct ifnet *ifp)
2228 {
2229 struct radix_node_head *rnh;
2230 int p;
2231
2232 for (p = 0; p < AF_MAX + 1; p++) {
2233 if ((rnh = rt_tables[p]) == NULL)
2234 continue;
2235
2236 lck_mtx_lock(rt_mtx);
2237 (void) rnh->rnh_walktree(rnh, if_rtmtu, ifp);
2238 lck_mtx_unlock(rt_mtx);
2239 }
2240
2241 if (use_routegenid)
2242 route_generation++;
2243 }
2244
2245 __private_extern__ void
2246 if_data_internal_to_if_data(
2247 struct ifnet *ifp,
2248 const struct if_data_internal *if_data_int,
2249 struct if_data *if_data)
2250 {
2251 struct dlil_threading_info *thread;
2252 if ((thread = ifp->if_input_thread) == NULL || (dlil_multithreaded_input == 0))
2253 thread = dlil_lo_thread_ptr;
2254
2255 #define COPYFIELD(fld) if_data->fld = if_data_int->fld
2256 #define COPYFIELD32(fld) if_data->fld = (u_int32_t)(if_data_int->fld)
2257 COPYFIELD(ifi_type);
2258 COPYFIELD(ifi_typelen);
2259 COPYFIELD(ifi_physical);
2260 COPYFIELD(ifi_addrlen);
2261 COPYFIELD(ifi_hdrlen);
2262 COPYFIELD(ifi_recvquota);
2263 COPYFIELD(ifi_xmitquota);
2264 if_data->ifi_unused1 = 0;
2265 COPYFIELD(ifi_mtu);
2266 COPYFIELD(ifi_metric);
2267 if (if_data_int->ifi_baudrate & 0xFFFFFFFF00000000LL) {
2268 if_data->ifi_baudrate = 0xFFFFFFFF;
2269 }
2270 else {
2271 COPYFIELD32(ifi_baudrate);
2272 }
2273
2274 lck_mtx_lock(thread->input_lck);
2275 COPYFIELD32(ifi_ipackets);
2276 COPYFIELD32(ifi_ierrors);
2277 COPYFIELD32(ifi_opackets);
2278 COPYFIELD32(ifi_oerrors);
2279 COPYFIELD32(ifi_collisions);
2280 COPYFIELD32(ifi_ibytes);
2281 COPYFIELD32(ifi_obytes);
2282 COPYFIELD32(ifi_imcasts);
2283 COPYFIELD32(ifi_omcasts);
2284 COPYFIELD32(ifi_iqdrops);
2285 COPYFIELD32(ifi_noproto);
2286 COPYFIELD32(ifi_recvtiming);
2287 COPYFIELD32(ifi_xmittiming);
2288 COPYFIELD(ifi_lastchange);
2289 lck_mtx_unlock(thread->input_lck);
2290
2291 #if IF_LASTCHANGEUPTIME
2292 if_data->ifi_lastchange.tv_sec += boottime_sec();
2293 #endif
2294
2295 if_data->ifi_unused2 = 0;
2296 COPYFIELD(ifi_hwassist);
2297 if_data->ifi_reserved1 = 0;
2298 if_data->ifi_reserved2 = 0;
2299 #undef COPYFIELD32
2300 #undef COPYFIELD
2301 }
2302
2303 __private_extern__ void
2304 if_data_internal_to_if_data64(
2305 struct ifnet *ifp,
2306 const struct if_data_internal *if_data_int,
2307 struct if_data64 *if_data64)
2308 {
2309 struct dlil_threading_info *thread;
2310 if ((thread = ifp->if_input_thread) == NULL || (dlil_multithreaded_input == 0))
2311 thread = dlil_lo_thread_ptr;
2312
2313 #define COPYFIELD(fld) if_data64->fld = if_data_int->fld
2314 COPYFIELD(ifi_type);
2315 COPYFIELD(ifi_typelen);
2316 COPYFIELD(ifi_physical);
2317 COPYFIELD(ifi_addrlen);
2318 COPYFIELD(ifi_hdrlen);
2319 COPYFIELD(ifi_recvquota);
2320 COPYFIELD(ifi_xmitquota);
2321 if_data64->ifi_unused1 = 0;
2322 COPYFIELD(ifi_mtu);
2323 COPYFIELD(ifi_metric);
2324 COPYFIELD(ifi_baudrate);
2325
2326 lck_mtx_lock(thread->input_lck);
2327 COPYFIELD(ifi_ipackets);
2328 COPYFIELD(ifi_ierrors);
2329 COPYFIELD(ifi_opackets);
2330 COPYFIELD(ifi_oerrors);
2331 COPYFIELD(ifi_collisions);
2332 COPYFIELD(ifi_ibytes);
2333 COPYFIELD(ifi_obytes);
2334 COPYFIELD(ifi_imcasts);
2335 COPYFIELD(ifi_omcasts);
2336 COPYFIELD(ifi_iqdrops);
2337 COPYFIELD(ifi_noproto);
2338 COPYFIELD(ifi_recvtiming);
2339 COPYFIELD(ifi_xmittiming);
2340 COPYFIELD(ifi_lastchange);
2341 lck_mtx_unlock(thread->input_lck);
2342
2343 #if IF_LASTCHANGEUPTIME
2344 if_data64->ifi_lastchange.tv_sec += boottime_sec();
2345 #endif
2346
2347 #undef COPYFIELD
2348 }