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
113extern u_long route_generation;
114extern int use_routegenid;
115extern int dlil_multithreaded_input;
116extern 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
126static int ifconf(u_long cmd, user_addr_t ifrp, int * ret_space);
127static void if_qflush(struct ifqueue *);
128__private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *);
129void if_rtproto_del(struct ifnet *ifp, int protocol);
130
131static int if_rtmtu(struct radix_node *, void *);
132static void if_rtmtu_update(struct ifnet *);
133
134static struct	if_clone *if_clone_lookup(const char *, int *);
135#ifdef IF_CLONE_LIST
136static int	if_clone_list(int count, int * total, user_addr_t dst);
137#endif
138
139MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
140MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
141
142int	ifqmaxlen = IFQ_MAXLEN;
143struct	ifnethead ifnet_head = TAILQ_HEAD_INITIALIZER(ifnet_head);
144
145static int	if_cloners_count;
146LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
147
148static 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 */
156extern 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
168int if_index;
169struct ifaddr **ifnet_addrs;
170struct ifnet **ifindex2ifnet;
171
172__private_extern__ void
173if_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
187if_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 */
229int if_next_index(void);
230
231__private_extern__ int
232if_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 */
283static int
284if_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 */
355static int
356if_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
394static struct if_clone *
395if_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 */
435void
436if_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 */
477void
478if_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 */
490static int
491if_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
521ifa_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 *
554ifa_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*/
576struct ifaddr *
577ifa_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*/
618struct ifaddr *
619ifa_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 */
651struct ifaddr *
652ifa_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
701struct ifaddr *
702ifa_ifwithnet(const struct sockaddr *addr)
703{
704	return (ifa_ifwithnet_common(addr, IFSCOPE_NONE));
705}
706
707struct ifaddr *
708ifa_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 */
717static struct ifaddr *
718ifa_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)
758next:				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 */
869struct ifaddr *
870ifaof_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 */
941void
942link_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
972if_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 */
1032void
1033if_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 */
1045void
1046if_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 */
1057static void
1058if_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 */
1076struct ifnet *
1077ifunit(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 */
1126struct ifnet *
1127if_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 */
1152int
1153ifioctl(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
1516int
1517ifioctllocked(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 */
1533errno_t
1534ifnet_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;
1573done:
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*/
1590static int
1591ifconf(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 */
1680int
1681if_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
1712void
1713ifma_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
1720void
1721ifma_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  */
1750static int
1751if_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 */
1775static struct sockaddr*
1776copy_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 */
1841int
1842if_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
1966cleanup:
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
1979int
1980if_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 */
2050int
2051if_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__
2093int
2094if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
2095{
2096	...
2097}
2098#endif
2099
2100struct ifmultiaddr *
2101ifmaof_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
2115SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Link layers");
2116SYSCTL_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 */
2123int
2124if_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 */
2156static int
2157if_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 */
2189void 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
2202static int
2203if_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 */
2226static
2227void 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
2246if_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
2304if_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}
2349