1/*
2 * Copyright (c) 2000-2013 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#include <sys/mcache.h>
85#include <kern/zalloc.h>
86
87#include <machine/endian.h>
88
89#include <pexpert/pexpert.h>
90
91#include <net/if.h>
92#include <net/if_arp.h>
93#include <net/if_dl.h>
94#include <net/if_types.h>
95#include <net/if_var.h>
96#include <net/if_ppp.h>
97#include <net/ethernet.h>
98
99#include <net/radix.h>
100#include <net/route.h>
101#include <net/dlil.h>
102#include <sys/domain.h>
103#include <libkern/OSAtomic.h>
104
105#if INET || INET6
106/*XXX*/
107#include <netinet/in.h>
108#include <netinet/in_var.h>
109#include <netinet/ip_var.h>
110#include <netinet/ip6.h>
111#include <netinet/ip_var.h>
112#include <netinet/tcp.h>
113#include <netinet/tcp_var.h>
114#include <netinet/udp.h>
115#include <netinet/udp_var.h>
116#if INET6
117#include <netinet6/in6_var.h>
118#include <netinet6/in6_ifattach.h>
119#include <netinet6/ip6_var.h>
120#include <netinet6/nd6.h>
121#endif /* INET6 */
122#endif /* INET || INET6 */
123
124#if CONFIG_MACF_NET
125#include <security/mac_framework.h>
126#endif
127
128#if PF_ALTQ
129#include <net/altq/if_altq.h>
130#endif /* !PF_ALTQ */
131
132/*
133 * System initialization
134 */
135
136extern char *proc_name_address(void *);
137
138/* Lock group and attribute for ifaddr lock */
139lck_attr_t	*ifa_mtx_attr;
140lck_grp_t	*ifa_mtx_grp;
141static lck_grp_attr_t	*ifa_mtx_grp_attr;
142
143static int ifioctl_ifreq(struct socket *, u_long, struct ifreq *,
144    struct proc *);
145static int ifioctl_ifconf(u_long, caddr_t);
146static int ifioctl_ifclone(u_long, caddr_t);
147static int ifioctl_ifdesc(struct ifnet *, u_long, caddr_t, struct proc *);
148static int ifioctl_linkparams(struct ifnet *, u_long, caddr_t, struct proc *);
149static int ifioctl_qstats(struct ifnet *, u_long, caddr_t);
150static int ifioctl_throttle(struct ifnet *, u_long, caddr_t, struct proc *);
151static int ifconf(u_long cmd, user_addr_t ifrp, int * ret_space);
152__private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *);
153void if_rtproto_del(struct ifnet *ifp, int protocol);
154
155static int if_addmulti_common(struct ifnet *, const struct sockaddr *,
156    struct ifmultiaddr **, int);
157static int if_delmulti_common(struct ifmultiaddr *, struct ifnet *,
158    const struct sockaddr *, int);
159
160static int if_rtmtu(struct radix_node *, void *);
161static void if_rtmtu_update(struct ifnet *);
162
163static int if_clone_list(int, int *, user_addr_t);
164
165MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
166
167struct	ifnethead ifnet_head = TAILQ_HEAD_INITIALIZER(ifnet_head);
168
169static int	if_cloners_count;
170LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
171
172static struct ifaddr *ifa_ifwithnet_common(const struct sockaddr *,
173    unsigned int);
174static void if_attach_ifa_common(struct ifnet *, struct ifaddr *, int);
175static void if_detach_ifa_common(struct ifnet *, struct ifaddr *, int);
176
177static void if_attach_ifma(struct ifnet *, struct ifmultiaddr *, int);
178static int if_detach_ifma(struct ifnet *, struct ifmultiaddr *, int);
179
180static struct ifmultiaddr *ifma_alloc(int);
181static void ifma_free(struct ifmultiaddr *);
182static void ifma_trace(struct ifmultiaddr *, int);
183
184#if DEBUG
185static unsigned int ifma_debug = 1;	/* debugging (enabled) */
186#else
187static unsigned int ifma_debug;		/* debugging (disabled) */
188#endif /* !DEBUG */
189static unsigned int ifma_size;		/* size of zone element */
190static struct zone *ifma_zone;		/* zone for ifmultiaddr */
191
192#define	IFMA_TRACE_HIST_SIZE	32	/* size of trace history */
193
194/* For gdb */
195__private_extern__ unsigned int ifma_trace_hist_size = IFMA_TRACE_HIST_SIZE;
196
197struct ifmultiaddr_dbg {
198	struct ifmultiaddr	ifma;			/* ifmultiaddr */
199	u_int16_t		ifma_refhold_cnt;	/* # of ref */
200	u_int16_t		ifma_refrele_cnt;	/* # of rele */
201	/*
202	 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
203	 */
204	ctrace_t		ifma_refhold[IFMA_TRACE_HIST_SIZE];
205	ctrace_t		ifma_refrele[IFMA_TRACE_HIST_SIZE];
206	/*
207	 * Trash list linkage
208	 */
209	TAILQ_ENTRY(ifmultiaddr_dbg) ifma_trash_link;
210};
211
212/* List of trash ifmultiaddr entries protected by ifma_trash_lock */
213static TAILQ_HEAD(, ifmultiaddr_dbg) ifma_trash_head;
214static decl_lck_mtx_data(, ifma_trash_lock);
215
216#define	IFMA_ZONE_MAX		64		/* maximum elements in zone */
217#define	IFMA_ZONE_NAME		"ifmultiaddr"	/* zone name */
218
219#if INET6
220/*
221 * XXX: declare here to avoid to include many inet6 related files..
222 * should be more generalized?
223 */
224extern void	nd6_setmtu(struct ifnet *);
225extern lck_mtx_t *nd6_mutex;
226#endif
227
228SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Link layers");
229SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
230	"Generic link-management");
231
232SYSCTL_DECL(_net_link_generic_system);
233
234static uint32_t if_verbose = 0;
235SYSCTL_INT(_net_link_generic_system, OID_AUTO, if_verbose,
236    CTLFLAG_RW | CTLFLAG_LOCKED, &if_verbose, 0, "");
237
238void
239ifa_init(void)
240{
241	/* Setup lock group and attribute for ifaddr */
242	ifa_mtx_grp_attr = lck_grp_attr_alloc_init();
243	ifa_mtx_grp = lck_grp_alloc_init("ifaddr", ifa_mtx_grp_attr);
244	ifa_mtx_attr = lck_attr_alloc_init();
245
246	PE_parse_boot_argn("ifa_debug", &ifma_debug, sizeof (ifma_debug));
247
248	ifma_size = (ifma_debug == 0) ? sizeof (struct ifmultiaddr) :
249	    sizeof (struct ifmultiaddr_dbg);
250
251	ifma_zone = zinit(ifma_size, IFMA_ZONE_MAX * ifma_size, 0,
252	    IFMA_ZONE_NAME);
253	if (ifma_zone == NULL) {
254		panic("%s: failed allocating %s", __func__, IFMA_ZONE_NAME);
255		/* NOTREACHED */
256	}
257	zone_change(ifma_zone, Z_EXPAND, TRUE);
258	zone_change(ifma_zone, Z_CALLERACCT, FALSE);
259
260	lck_mtx_init(&ifma_trash_lock, ifa_mtx_grp, ifa_mtx_attr);
261	TAILQ_INIT(&ifma_trash_head);
262}
263
264/*
265 * Network interface utility routines.
266 *
267 * Routines with ifa_ifwith* names take sockaddr *'s as
268 * parameters.
269 */
270
271int if_index;
272struct ifaddr **ifnet_addrs;
273struct ifnet **ifindex2ifnet;
274
275__private_extern__ void
276if_attach_ifa(struct ifnet *ifp, struct ifaddr *ifa)
277{
278	if_attach_ifa_common(ifp, ifa, 0);
279}
280
281__private_extern__ void
282if_attach_link_ifa(struct ifnet *ifp, struct ifaddr *ifa)
283{
284	if_attach_ifa_common(ifp, ifa, 1);
285}
286
287static void
288if_attach_ifa_common(struct ifnet *ifp, struct ifaddr *ifa, int link)
289{
290	ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE);
291	IFA_LOCK_ASSERT_HELD(ifa);
292
293	if (ifa->ifa_ifp != ifp) {
294		panic("%s: Mismatch ifa_ifp=%p != ifp=%p", __func__,
295		    ifa->ifa_ifp, ifp);
296		/* NOTREACHED */
297	} else if (ifa->ifa_debug & IFD_ATTACHED) {
298		panic("%s: Attempt to attach an already attached ifa=%p",
299		    __func__, ifa);
300		/* NOTREACHED */
301	} else if (link && !(ifa->ifa_debug & IFD_LINK)) {
302		panic("%s: Unexpected non-link address ifa=%p", __func__, ifa);
303		/* NOTREACHED */
304	} else if (!link && (ifa->ifa_debug & IFD_LINK)) {
305		panic("%s: Unexpected link address ifa=%p", __func__, ifa);
306		/* NOTREACHED */
307	}
308	IFA_ADDREF_LOCKED(ifa);
309	ifa->ifa_debug |= IFD_ATTACHED;
310	if (link)
311		TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
312	else
313		TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
314
315	if (ifa->ifa_attached != NULL)
316		(*ifa->ifa_attached)(ifa);
317}
318
319__private_extern__ void
320if_detach_ifa(struct ifnet *ifp, struct ifaddr *ifa)
321{
322	if_detach_ifa_common(ifp, ifa, 0);
323}
324
325__private_extern__ void
326if_detach_link_ifa(struct ifnet *ifp, struct ifaddr *ifa)
327{
328	if_detach_ifa_common(ifp, ifa, 1);
329}
330
331static void
332if_detach_ifa_common(struct ifnet *ifp, struct ifaddr *ifa, int link)
333{
334	ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE);
335	IFA_LOCK_ASSERT_HELD(ifa);
336
337	if (link && !(ifa->ifa_debug & IFD_LINK)) {
338		panic("%s: Unexpected non-link address ifa=%p", __func__, ifa);
339		/* NOTREACHED */
340	} else if (link && ifa != TAILQ_FIRST(&ifp->if_addrhead)) {
341		panic("%s: Link address ifa=%p not first", __func__, ifa);
342		/* NOTREACHED */
343	} else if (!link && (ifa->ifa_debug & IFD_LINK)) {
344		panic("%s: Unexpected link address ifa=%p", __func__, ifa);
345		/* NOTREACHED */
346	} else if (!(ifa->ifa_debug & IFD_ATTACHED)) {
347		panic("%s: Attempt to detach an unattached address ifa=%p",
348		    __func__, ifa);
349		/* NOTREACHED */
350	} else if (ifa->ifa_ifp != ifp) {
351		panic("%s: Mismatch ifa_ifp=%p, ifp=%p", __func__,
352		    ifa->ifa_ifp, ifp);
353		/* NOTREACHED */
354	} else if (ifa->ifa_debug & IFD_DEBUG) {
355		struct ifaddr *ifa2;
356		TAILQ_FOREACH(ifa2, &ifp->if_addrhead, ifa_link) {
357			if (ifa2 == ifa)
358				break;
359		}
360		if (ifa2 != ifa) {
361			panic("%s: Attempt to detach a stray address ifa=%p",
362			    __func__, ifa);
363			/* NOTREACHED */
364		}
365	}
366	TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
367	/* This must not be the last reference to the ifaddr */
368	if (IFA_REMREF_LOCKED(ifa) == NULL) {
369		panic("%s: unexpected (missing) refcnt ifa=%p", __func__, ifa);
370		/* NOTREACHED */
371	}
372	ifa->ifa_debug &= ~IFD_ATTACHED;
373
374	if (ifa->ifa_detached != NULL)
375		(*ifa->ifa_detached)(ifa);
376}
377
378#define INITIAL_IF_INDEXLIM	8
379
380/*
381 * Function: if_next_index
382 * Purpose:
383 *   Return the next available interface index.
384 *   Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the
385 *   added entry when necessary.
386 *
387 * Note:
388 *   ifnet_addrs[] is indexed by (if_index - 1), whereas
389 *   ifindex2ifnet[] is indexed by ifp->if_index.  That requires us to
390 *   always allocate one extra element to hold ifindex2ifnet[0], which
391 *   is unused.
392 */
393int if_next_index(void);
394
395__private_extern__ int
396if_next_index(void)
397{
398	static int 	if_indexlim = 0;
399	int		new_index;
400
401	new_index = ++if_index;
402	if (if_index > if_indexlim) {
403		unsigned 	n;
404		int		new_if_indexlim;
405		caddr_t		new_ifnet_addrs;
406		caddr_t		new_ifindex2ifnet;
407		caddr_t		old_ifnet_addrs;
408
409		old_ifnet_addrs = (caddr_t)ifnet_addrs;
410		if (ifnet_addrs == NULL) {
411			new_if_indexlim = INITIAL_IF_INDEXLIM;
412		} else {
413			new_if_indexlim = if_indexlim << 1;
414		}
415
416		/* allocate space for the larger arrays */
417		n = (2 * new_if_indexlim + 1) * sizeof(caddr_t);
418		new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK);
419		if (new_ifnet_addrs == NULL) {
420			--if_index;
421			return -1;
422		}
423
424		new_ifindex2ifnet = new_ifnet_addrs
425			+ new_if_indexlim * sizeof(caddr_t);
426		bzero(new_ifnet_addrs, n);
427		if (ifnet_addrs != NULL) {
428			/* copy the existing data */
429			bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs,
430			      if_indexlim * sizeof(caddr_t));
431			bcopy((caddr_t)ifindex2ifnet,
432			      new_ifindex2ifnet,
433			      (if_indexlim + 1) * sizeof(caddr_t));
434		}
435
436		/* switch to the new tables and size */
437		ifnet_addrs = (struct ifaddr **)(void *)new_ifnet_addrs;
438		ifindex2ifnet = (struct ifnet **)(void *)new_ifindex2ifnet;
439		if_indexlim = new_if_indexlim;
440
441		/* release the old data */
442		if (old_ifnet_addrs != NULL) {
443			_FREE((caddr_t)old_ifnet_addrs, M_IFADDR);
444		}
445	}
446	return (new_index);
447}
448
449/*
450 * Create a clone network interface.
451 */
452static int
453if_clone_create(char *name, int len, void *params)
454{
455	struct if_clone *ifc;
456	char *dp;
457	int wildcard;
458	u_int32_t bytoff, bitoff;
459	u_int32_t unit;
460	int err;
461
462	ifc = if_clone_lookup(name, &unit);
463	if (ifc == NULL)
464		return (EINVAL);
465
466	if (ifunit(name) != NULL)
467		return (EEXIST);
468
469	bytoff = bitoff = 0;
470	wildcard = (unit == UINT32_MAX);
471	/*
472	 * Find a free unit if none was given.
473	 */
474	if (wildcard) {
475		while ((bytoff < ifc->ifc_bmlen)
476		    && (ifc->ifc_units[bytoff] == 0xff))
477			bytoff++;
478		if (bytoff >= ifc->ifc_bmlen)
479			return (ENOSPC);
480		while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0)
481			bitoff++;
482		unit = (bytoff << 3) + bitoff;
483	}
484
485	if (unit > ifc->ifc_maxunit)
486		return (ENXIO);
487
488	err = (*ifc->ifc_create)(ifc, unit, params);
489	if (err != 0)
490		return (err);
491
492	if (!wildcard) {
493		bytoff = unit >> 3;
494		bitoff = unit - (bytoff << 3);
495	}
496
497	/*
498	 * Allocate the unit in the bitmap.
499	 */
500	KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0,
501	    ("%s: bit is already set", __func__));
502	ifc->ifc_units[bytoff] |= (1 << bitoff);
503
504	/* In the wildcard case, we need to update the name. */
505	if (wildcard) {
506		for (dp = name; *dp != '\0'; dp++);
507		if (snprintf(dp, len - (dp-name), "%d", unit) >
508		    len - (dp-name) - 1) {
509			/*
510			 * This can only be a programmer error and
511			 * there's no straightforward way to recover if
512			 * it happens.
513			 */
514			panic("%s: interface name too long", __func__);
515			/* NOTREACHED */
516		}
517
518	}
519
520	return (0);
521}
522
523/*
524 * Destroy a clone network interface.
525 */
526static int
527if_clone_destroy(const char *name)
528{
529	struct if_clone *ifc;
530	struct ifnet *ifp;
531	int bytoff, bitoff;
532	u_int32_t unit;
533
534	ifc = if_clone_lookup(name, &unit);
535	if (ifc == NULL)
536		return (EINVAL);
537
538	if (unit < ifc->ifc_minifs)
539		return (EINVAL);
540
541	ifp = ifunit(name);
542	if (ifp == NULL)
543		return (ENXIO);
544
545	if (ifc->ifc_destroy == NULL)
546		return (EOPNOTSUPP);
547
548	(*ifc->ifc_destroy)(ifp);
549
550	/*
551	 * Compute offset in the bitmap and deallocate the unit.
552	 */
553	bytoff = unit >> 3;
554	bitoff = unit - (bytoff << 3);
555	KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0,
556	    ("%s: bit is already cleared", __func__));
557	ifc->ifc_units[bytoff] &= ~(1 << bitoff);
558	return (0);
559}
560
561/*
562 * Look up a network interface cloner.
563 */
564
565__private_extern__ struct if_clone *
566if_clone_lookup(const char *name, u_int32_t *unitp)
567{
568	struct if_clone *ifc;
569	const char *cp;
570	u_int32_t i;
571
572	for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) {
573		for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) {
574			if (ifc->ifc_name[i] != *cp)
575				goto next_ifc;
576		}
577		goto found_name;
578 next_ifc:
579		ifc = LIST_NEXT(ifc, ifc_list);
580	}
581
582	/* No match. */
583	return ((struct if_clone *)NULL);
584
585 found_name:
586	if (*cp == '\0') {
587		i = UINT32_MAX;
588	} else {
589		for (i = 0; *cp != '\0'; cp++) {
590			if (*cp < '0' || *cp > '9') {
591				/* Bogus unit number. */
592				return (NULL);
593			}
594			i = (i * 10) + (*cp - '0');
595		}
596	}
597
598	if (unitp != NULL)
599		*unitp = i;
600	return (ifc);
601}
602
603/*
604 * Register a network interface cloner.
605 */
606int
607if_clone_attach(struct if_clone *ifc)
608{
609	int bytoff, bitoff;
610	int err;
611	int len, maxclone;
612	u_int32_t unit;
613
614	KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit,
615	    ("%s: %s requested more units then allowed (%d > %d)",
616	    __func__, ifc->ifc_name, ifc->ifc_minifs,
617	    ifc->ifc_maxunit + 1));
618	/*
619	 * Compute bitmap size and allocate it.
620	 */
621	maxclone = ifc->ifc_maxunit + 1;
622	len = maxclone >> 3;
623	if ((len << 3) < maxclone)
624		len++;
625	ifc->ifc_units = _MALLOC(len, M_CLONE, M_WAITOK | M_ZERO);
626	if (ifc->ifc_units == NULL)
627		return ENOBUFS;
628	bzero(ifc->ifc_units, len);
629	ifc->ifc_bmlen = len;
630
631	LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
632	if_cloners_count++;
633
634	for (unit = 0; unit < ifc->ifc_minifs; unit++) {
635		err = (*ifc->ifc_create)(ifc, unit, NULL);
636		KASSERT(err == 0,
637		    ("%s: failed to create required interface %s%d",
638		    __func__, ifc->ifc_name, unit));
639
640		/* Allocate the unit in the bitmap. */
641		bytoff = unit >> 3;
642		bitoff = unit - (bytoff << 3);
643		ifc->ifc_units[bytoff] |= (1 << bitoff);
644	}
645
646	return 0;
647}
648
649/*
650 * Unregister a network interface cloner.
651 */
652void
653if_clone_detach(struct if_clone *ifc)
654{
655	LIST_REMOVE(ifc, ifc_list);
656	FREE(ifc->ifc_units, M_CLONE);
657	if_cloners_count--;
658}
659
660/*
661 * Provide list of interface cloners to userspace.
662 */
663static int
664if_clone_list(int count, int *ret_total, user_addr_t dst)
665{
666	char outbuf[IFNAMSIZ];
667	struct if_clone *ifc;
668	int error = 0;
669
670	*ret_total = if_cloners_count;
671	if (dst == USER_ADDR_NULL) {
672		/* Just asking how many there are. */
673		return (0);
674	}
675
676	if (count < 0)
677		return (EINVAL);
678
679	count = (if_cloners_count < count) ? if_cloners_count : count;
680
681	for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
682	     ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
683		strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
684		error = copyout(outbuf, dst, IFNAMSIZ);
685		if (error)
686			break;
687	}
688
689	return (error);
690}
691
692/*
693 * Similar to ifa_ifwithaddr, except that this is IPv4 specific
694 * and that it matches only the local (not broadcast) address.
695 */
696__private_extern__ struct in_ifaddr *
697ifa_foraddr(unsigned int addr)
698{
699	return (ifa_foraddr_scoped(addr, IFSCOPE_NONE));
700}
701
702/*
703 * Similar to ifa_foraddr, except with the added interface scope
704 * constraint (unless the caller passes in IFSCOPE_NONE in which
705 * case there is no scope restriction).
706 */
707__private_extern__ struct in_ifaddr *
708ifa_foraddr_scoped(unsigned int addr, unsigned int scope)
709{
710	struct in_ifaddr *ia = NULL;
711
712	lck_rw_lock_shared(in_ifaddr_rwlock);
713	TAILQ_FOREACH(ia, INADDR_HASH(addr), ia_hash) {
714		IFA_LOCK_SPIN(&ia->ia_ifa);
715		if (ia->ia_addr.sin_addr.s_addr == addr &&
716		    (scope == IFSCOPE_NONE || ia->ia_ifp->if_index == scope)) {
717			IFA_ADDREF_LOCKED(&ia->ia_ifa);	/* for caller */
718			IFA_UNLOCK(&ia->ia_ifa);
719			break;
720		}
721		IFA_UNLOCK(&ia->ia_ifa);
722	}
723	lck_rw_done(in_ifaddr_rwlock);
724	return (ia);
725}
726
727#if INET6
728/*
729 * Similar to ifa_foraddr, except that this for IPv6.
730 */
731__private_extern__ struct in6_ifaddr *
732ifa_foraddr6(struct in6_addr *addr6)
733{
734	return (ifa_foraddr6_scoped(addr6, IFSCOPE_NONE));
735}
736
737__private_extern__ struct in6_ifaddr *
738ifa_foraddr6_scoped(struct in6_addr *addr6, unsigned int scope)
739{
740	struct in6_ifaddr *ia = NULL;
741
742	lck_rw_lock_shared(&in6_ifaddr_rwlock);
743	for (ia = in6_ifaddrs; ia; ia = ia->ia_next) {
744		IFA_LOCK(&ia->ia_ifa);
745		if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, addr6) &&
746		    (scope == IFSCOPE_NONE || ia->ia_ifp->if_index == scope)) {
747			IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for caller */
748			IFA_UNLOCK(&ia->ia_ifa);
749			break;
750		}
751		IFA_UNLOCK(&ia->ia_ifa);
752	}
753	lck_rw_done(&in6_ifaddr_rwlock);
754
755	return (ia);
756}
757#endif /* INET6 */
758
759/*
760 * Return the first (primary) address of a given family on an interface.
761 */
762__private_extern__ struct ifaddr *
763ifa_ifpgetprimary(struct ifnet *ifp, int family)
764{
765	struct ifaddr *ifa;
766
767	ifnet_lock_shared(ifp);
768	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
769		IFA_LOCK_SPIN(ifa);
770		if (ifa->ifa_addr->sa_family == family) {
771			IFA_ADDREF_LOCKED(ifa);	/* for caller */
772			IFA_UNLOCK(ifa);
773			break;
774		}
775		IFA_UNLOCK(ifa);
776	}
777	ifnet_lock_done(ifp);
778
779	return (ifa);
780}
781
782/*
783 * Locate an interface based on a complete address.
784 */
785/*ARGSUSED*/
786struct ifaddr *
787ifa_ifwithaddr(const struct sockaddr *addr)
788{
789	struct ifnet *ifp;
790	struct ifaddr *ifa;
791	struct ifaddr *result = NULL;
792
793#define	equal(a1, a2)							\
794	(bcmp((const void*)(a1), (const void*)(a2),			\
795	    ((const struct sockaddr *)(a1))->sa_len) == 0)
796
797	ifnet_head_lock_shared();
798	for (ifp = ifnet_head.tqh_first; ifp && !result;
799	    ifp = ifp->if_link.tqe_next) {
800		ifnet_lock_shared(ifp);
801		for (ifa = ifp->if_addrhead.tqh_first; ifa;
802		    ifa = ifa->ifa_link.tqe_next) {
803			IFA_LOCK_SPIN(ifa);
804			if (ifa->ifa_addr->sa_family != addr->sa_family) {
805				IFA_UNLOCK(ifa);
806				continue;
807			}
808			if (equal(addr, ifa->ifa_addr)) {
809				result = ifa;
810				IFA_ADDREF_LOCKED(ifa);	/* for caller */
811				IFA_UNLOCK(ifa);
812				break;
813			}
814			if ((ifp->if_flags & IFF_BROADCAST) &&
815			    ifa->ifa_broadaddr != NULL &&
816			    /* IP6 doesn't have broadcast */
817			    ifa->ifa_broadaddr->sa_len != 0 &&
818			    equal(ifa->ifa_broadaddr, addr)) {
819				result = ifa;
820				IFA_ADDREF_LOCKED(ifa);	/* for caller */
821				IFA_UNLOCK(ifa);
822				break;
823			}
824			IFA_UNLOCK(ifa);
825		}
826		ifnet_lock_done(ifp);
827	}
828	ifnet_head_done();
829
830	return (result);
831}
832/*
833 * Locate the point to point interface with a given destination address.
834 */
835/*ARGSUSED*/
836struct ifaddr *
837ifa_ifwithdstaddr(const struct sockaddr *addr)
838{
839	struct ifnet *ifp;
840	struct ifaddr *ifa;
841	struct ifaddr *result = NULL;
842
843	ifnet_head_lock_shared();
844	for (ifp = ifnet_head.tqh_first; ifp && !result;
845	    ifp = ifp->if_link.tqe_next) {
846	    if ((ifp->if_flags & IFF_POINTOPOINT)) {
847			ifnet_lock_shared(ifp);
848			for (ifa = ifp->if_addrhead.tqh_first; ifa;
849			    ifa = ifa->ifa_link.tqe_next) {
850				IFA_LOCK_SPIN(ifa);
851				if (ifa->ifa_addr->sa_family !=
852				    addr->sa_family) {
853					IFA_UNLOCK(ifa);
854					continue;
855				}
856				if (ifa->ifa_dstaddr &&
857				    equal(addr, ifa->ifa_dstaddr)) {
858					result = ifa;
859					IFA_ADDREF_LOCKED(ifa);	/* for caller */
860					IFA_UNLOCK(ifa);
861					break;
862				}
863				IFA_UNLOCK(ifa);
864			}
865			ifnet_lock_done(ifp);
866		}
867	}
868	ifnet_head_done();
869	return (result);
870}
871
872/*
873 * Locate the source address of an interface based on a complete address.
874 */
875struct ifaddr *
876ifa_ifwithaddr_scoped(const struct sockaddr *addr, unsigned int ifscope)
877{
878	struct ifaddr *result = NULL;
879	struct ifnet *ifp;
880
881	if (ifscope == IFSCOPE_NONE)
882		return (ifa_ifwithaddr(addr));
883
884	ifnet_head_lock_shared();
885	if (ifscope > (unsigned int)if_index) {
886		ifnet_head_done();
887		return (NULL);
888	}
889
890	ifp = ifindex2ifnet[ifscope];
891	if (ifp != NULL) {
892		struct ifaddr *ifa = NULL;
893
894		/*
895		 * This is suboptimal; there should be a better way
896		 * to search for a given address of an interface
897		 * for any given address family.
898		 */
899		ifnet_lock_shared(ifp);
900		for (ifa = ifp->if_addrhead.tqh_first; ifa != NULL;
901		    ifa = ifa->ifa_link.tqe_next) {
902			IFA_LOCK_SPIN(ifa);
903			if (ifa->ifa_addr->sa_family != addr->sa_family) {
904				IFA_UNLOCK(ifa);
905				continue;
906			}
907			if (equal(addr, ifa->ifa_addr)) {
908				result = ifa;
909				IFA_ADDREF_LOCKED(ifa);	/* for caller */
910				IFA_UNLOCK(ifa);
911				break;
912			}
913			if ((ifp->if_flags & IFF_BROADCAST) &&
914			    ifa->ifa_broadaddr != NULL &&
915			    /* IP6 doesn't have broadcast */
916			    ifa->ifa_broadaddr->sa_len != 0 &&
917			    equal(ifa->ifa_broadaddr, addr)) {
918				result = ifa;
919				IFA_ADDREF_LOCKED(ifa);	/* for caller */
920				IFA_UNLOCK(ifa);
921				break;
922			}
923			IFA_UNLOCK(ifa);
924		}
925		ifnet_lock_done(ifp);
926	}
927	ifnet_head_done();
928
929	return (result);
930}
931
932struct ifaddr *
933ifa_ifwithnet(const struct sockaddr *addr)
934{
935	return (ifa_ifwithnet_common(addr, IFSCOPE_NONE));
936}
937
938struct ifaddr *
939ifa_ifwithnet_scoped(const struct sockaddr *addr, unsigned int ifscope)
940{
941	return (ifa_ifwithnet_common(addr, ifscope));
942}
943
944/*
945 * Find an interface on a specific network.  If many, choice
946 * is most specific found.
947 */
948static struct ifaddr *
949ifa_ifwithnet_common(const struct sockaddr *addr, unsigned int ifscope)
950{
951	struct ifnet *ifp;
952	struct ifaddr *ifa = NULL;
953	struct ifaddr *ifa_maybe = NULL;
954	u_int af = addr->sa_family;
955	const char *addr_data = addr->sa_data, *cplim;
956
957#if INET6
958	if ((af != AF_INET && af != AF_INET6) ||
959	    (af == AF_INET && !ip_doscopedroute) ||
960	    (af == AF_INET6 && !ip6_doscopedroute))
961#else
962	if (af != AF_INET || !ip_doscopedroute)
963#endif /* !INET6 */
964		ifscope = IFSCOPE_NONE;
965
966	ifnet_head_lock_shared();
967	/*
968	 * AF_LINK addresses can be looked up directly by their index number,
969	 * so do that if we can.
970	 */
971	if (af == AF_LINK) {
972		const struct sockaddr_dl *sdl =
973		    (const struct sockaddr_dl *)(uintptr_t)(size_t)addr;
974		if (sdl->sdl_index && sdl->sdl_index <= if_index) {
975			ifa = ifnet_addrs[sdl->sdl_index - 1];
976			if (ifa != NULL)
977				IFA_ADDREF(ifa);
978
979			ifnet_head_done();
980			return (ifa);
981		}
982	}
983
984	/*
985	 * Scan though each interface, looking for ones that have
986	 * addresses in this address family.
987	 */
988	for (ifp = ifnet_head.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
989		ifnet_lock_shared(ifp);
990		for (ifa = ifp->if_addrhead.tqh_first; ifa;
991		     ifa = ifa->ifa_link.tqe_next) {
992			const char *cp, *cp2, *cp3;
993
994			IFA_LOCK(ifa);
995			if (ifa->ifa_addr == NULL ||
996			    ifa->ifa_addr->sa_family != af) {
997next:
998				IFA_UNLOCK(ifa);
999				continue;
1000			}
1001			/*
1002			 * If we're looking up with a scope,
1003			 * find using a matching interface.
1004			 */
1005			if (ifscope != IFSCOPE_NONE &&
1006			    ifp->if_index != ifscope) {
1007				IFA_UNLOCK(ifa);
1008				continue;
1009			}
1010
1011			/*
1012			 * Scan all the bits in the ifa's address.
1013			 * If a bit dissagrees with what we are
1014			 * looking for, mask it with the netmask
1015			 * to see if it really matters.
1016			 * (A byte at a time)
1017			 */
1018			if (ifa->ifa_netmask == 0) {
1019				IFA_UNLOCK(ifa);
1020				continue;
1021			}
1022			cp = addr_data;
1023			cp2 = ifa->ifa_addr->sa_data;
1024			cp3 = ifa->ifa_netmask->sa_data;
1025			cplim = ifa->ifa_netmask->sa_len +
1026			    (char *)ifa->ifa_netmask;
1027			while (cp3 < cplim)
1028				if ((*cp++ ^ *cp2++) & *cp3++)
1029					goto next; /* next address! */
1030			/*
1031			 * If the netmask of what we just found
1032			 * is more specific than what we had before
1033			 * (if we had one) then remember the new one
1034			 * before continuing to search
1035			 * for an even better one.
1036			 */
1037			if (ifa_maybe == NULL ||
1038			    rn_refines((caddr_t)ifa->ifa_netmask,
1039			    (caddr_t)ifa_maybe->ifa_netmask)) {
1040				IFA_ADDREF_LOCKED(ifa);	/* ifa_maybe */
1041				IFA_UNLOCK(ifa);
1042				if (ifa_maybe != NULL)
1043					IFA_REMREF(ifa_maybe);
1044				ifa_maybe = ifa;
1045			} else {
1046				IFA_UNLOCK(ifa);
1047			}
1048			IFA_LOCK_ASSERT_NOTHELD(ifa);
1049		}
1050		ifnet_lock_done(ifp);
1051
1052		if (ifa != NULL)
1053			break;
1054	}
1055	ifnet_head_done();
1056
1057	if (ifa == NULL)
1058		ifa = ifa_maybe;
1059	else if (ifa_maybe != NULL)
1060		IFA_REMREF(ifa_maybe);
1061
1062	return (ifa);
1063}
1064
1065/*
1066 * Find an interface address specific to an interface best matching
1067 * a given address.
1068 */
1069struct ifaddr *
1070ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp)
1071{
1072	struct ifaddr *ifa = NULL;
1073	const char *cp, *cp2, *cp3;
1074	char *cplim;
1075	struct ifaddr *ifa_maybe = NULL;
1076	struct ifaddr *better_ifa_maybe = NULL;
1077	u_int af = addr->sa_family;
1078
1079	if (af >= AF_MAX)
1080		return (NULL);
1081
1082	ifnet_lock_shared(ifp);
1083	for (ifa = ifp->if_addrhead.tqh_first; ifa;
1084	     ifa = ifa->ifa_link.tqe_next) {
1085		IFA_LOCK(ifa);
1086		if (ifa->ifa_addr->sa_family != af) {
1087			IFA_UNLOCK(ifa);
1088			continue;
1089		}
1090		if (ifa_maybe == NULL) {
1091			IFA_ADDREF_LOCKED(ifa);	/* for ifa_maybe */
1092			ifa_maybe = ifa;
1093		}
1094		if (ifa->ifa_netmask == 0) {
1095			if (equal(addr, ifa->ifa_addr) || (ifa->ifa_dstaddr &&
1096			    equal(addr, ifa->ifa_dstaddr))) {
1097				IFA_ADDREF_LOCKED(ifa);	/* for caller */
1098				IFA_UNLOCK(ifa);
1099				break;
1100			}
1101			IFA_UNLOCK(ifa);
1102			continue;
1103		}
1104		if (ifp->if_flags & IFF_POINTOPOINT) {
1105			if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) {
1106				IFA_ADDREF_LOCKED(ifa);	/* for caller */
1107				IFA_UNLOCK(ifa);
1108				break;
1109			}
1110		} else {
1111			if (equal(addr, ifa->ifa_addr)) {
1112				/* exact match */
1113				IFA_ADDREF_LOCKED(ifa);	/* for caller */
1114				IFA_UNLOCK(ifa);
1115				break;
1116			}
1117			cp = addr->sa_data;
1118			cp2 = ifa->ifa_addr->sa_data;
1119			cp3 = ifa->ifa_netmask->sa_data;
1120			cplim = ifa->ifa_netmask->sa_len +
1121			    (char *)ifa->ifa_netmask;
1122			for (; cp3 < cplim; cp3++)
1123				if ((*cp++ ^ *cp2++) & *cp3)
1124					break;
1125			if (cp3 == cplim) {
1126				/* subnet match */
1127				if (better_ifa_maybe == NULL) {
1128					/* for better_ifa_maybe */
1129					IFA_ADDREF_LOCKED(ifa);
1130					better_ifa_maybe = ifa;
1131				}
1132			}
1133		}
1134		IFA_UNLOCK(ifa);
1135	}
1136
1137	if (ifa == NULL) {
1138		if (better_ifa_maybe != NULL) {
1139			ifa = better_ifa_maybe;
1140			better_ifa_maybe = NULL;
1141		} else {
1142			ifa = ifa_maybe;
1143			ifa_maybe = NULL;
1144		}
1145	}
1146
1147	ifnet_lock_done(ifp);
1148
1149	if (better_ifa_maybe != NULL)
1150		IFA_REMREF(better_ifa_maybe);
1151	if (ifa_maybe != NULL)
1152		IFA_REMREF(ifa_maybe);
1153
1154	return (ifa);
1155}
1156
1157#include <net/route.h>
1158
1159/*
1160 * Default action when installing a route with a Link Level gateway.
1161 * Lookup an appropriate real ifa to point to.
1162 * This should be moved to /sys/net/link.c eventually.
1163 */
1164void
1165link_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa)
1166{
1167	struct ifaddr *ifa;
1168	struct sockaddr *dst;
1169	struct ifnet *ifp;
1170	void (*ifa_rtrequest)(int, struct rtentry *, struct sockaddr *);
1171
1172	lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED);
1173	RT_LOCK_ASSERT_HELD(rt);
1174
1175	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
1176	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
1177		return;
1178
1179	/* Become a regular mutex, just in case */
1180	RT_CONVERT_LOCK(rt);
1181
1182	ifa = ifaof_ifpforaddr(dst, ifp);
1183	if (ifa) {
1184		rtsetifa(rt, ifa);
1185		IFA_LOCK_SPIN(ifa);
1186		ifa_rtrequest = ifa->ifa_rtrequest;
1187		IFA_UNLOCK(ifa);
1188		if (ifa_rtrequest != NULL && ifa_rtrequest != link_rtrequest)
1189			ifa_rtrequest(cmd, rt, sa);
1190		IFA_REMREF(ifa);
1191	}
1192}
1193
1194/*
1195 * if_updown will set the interface up or down. It will
1196 * prevent other up/down events from occurring until this
1197 * up/down event has completed.
1198 *
1199 * Caller must lock ifnet. This function will drop the
1200 * lock. This allows ifnet_set_flags to set the rest of
1201 * the flags after we change the up/down state without
1202 * dropping the interface lock between setting the
1203 * up/down state and updating the rest of the flags.
1204 */
1205__private_extern__ void
1206if_updown(
1207	struct ifnet	*ifp,
1208	int				up)
1209{
1210	int i;
1211	struct ifaddr **ifa;
1212	struct timespec	tv;
1213	struct ifclassq *ifq = &ifp->if_snd;
1214
1215	/* Wait until no one else is changing the up/down state */
1216	while ((ifp->if_eflags & IFEF_UPDOWNCHANGE) != 0) {
1217		tv.tv_sec = 0;
1218		tv.tv_nsec = NSEC_PER_SEC / 10;
1219		ifnet_lock_done(ifp);
1220		msleep(&ifp->if_eflags, NULL, 0, "if_updown", &tv);
1221		ifnet_lock_exclusive(ifp);
1222	}
1223
1224	/* Verify that the interface isn't already in the right state */
1225	if ((!up && (ifp->if_flags & IFF_UP) == 0) ||
1226		(up && (ifp->if_flags & IFF_UP) == IFF_UP)) {
1227		return;
1228	}
1229
1230	/* Indicate that the up/down state is changing */
1231	ifp->if_eflags |= IFEF_UPDOWNCHANGE;
1232
1233	/* Mark interface up or down */
1234	if (up) {
1235		ifp->if_flags |= IFF_UP;
1236	}
1237	else {
1238		ifp->if_flags &= ~IFF_UP;
1239	}
1240
1241	ifnet_touch_lastchange(ifp);
1242
1243	/* Drop the lock to notify addresses and route */
1244	ifnet_lock_done(ifp);
1245	if (ifnet_get_address_list(ifp, &ifa) == 0) {
1246		for (i = 0; ifa[i] != 0; i++) {
1247			pfctlinput(up ? PRC_IFUP : PRC_IFDOWN, ifa[i]->ifa_addr);
1248		}
1249		ifnet_free_address_list(ifa);
1250	}
1251	rt_ifmsg(ifp);
1252
1253	if (!up)
1254		if_qflush(ifp, 0);
1255
1256	/* Inform all transmit queues about the new link state */
1257	IFCQ_LOCK(ifq);
1258	ifnet_update_sndq(ifq, up ? CLASSQ_EV_LINK_UP : CLASSQ_EV_LINK_DOWN);
1259	IFCQ_UNLOCK(ifq);
1260
1261	/* Aquire the lock to clear the changing flag */
1262	ifnet_lock_exclusive(ifp);
1263	ifp->if_eflags &= ~IFEF_UPDOWNCHANGE;
1264	wakeup(&ifp->if_eflags);
1265}
1266
1267/*
1268 * Mark an interface down and notify protocols of
1269 * the transition.
1270 */
1271void
1272if_down(
1273	struct ifnet *ifp)
1274{
1275	ifnet_lock_exclusive(ifp);
1276	if_updown(ifp, 0);
1277	ifnet_lock_done(ifp);
1278}
1279
1280/*
1281 * Mark an interface up and notify protocols of
1282 * the transition.
1283 */
1284void
1285if_up(
1286	struct ifnet *ifp)
1287{
1288	ifnet_lock_exclusive(ifp);
1289	if_updown(ifp, 1);
1290	ifnet_lock_done(ifp);
1291}
1292
1293/*
1294 * Flush an interface queue.
1295 */
1296void
1297if_qflush(struct ifnet *ifp, int ifq_locked)
1298{
1299	struct ifclassq *ifq = &ifp->if_snd;
1300
1301	if (!ifq_locked)
1302		IFCQ_LOCK(ifq);
1303
1304	if (IFCQ_IS_ENABLED(ifq))
1305		IFCQ_PURGE(ifq);
1306#if PF_ALTQ
1307	if (IFCQ_IS_DRAINING(ifq))
1308		ifq->ifcq_drain = 0;
1309	if (ALTQ_IS_ENABLED(IFCQ_ALTQ(ifq)))
1310		ALTQ_PURGE(IFCQ_ALTQ(ifq));
1311#endif /* PF_ALTQ */
1312
1313	VERIFY(IFCQ_IS_EMPTY(ifq));
1314
1315	if (!ifq_locked)
1316		IFCQ_UNLOCK(ifq);
1317}
1318
1319void
1320if_qflush_sc(struct ifnet *ifp, mbuf_svc_class_t sc, u_int32_t flow,
1321    u_int32_t *packets, u_int32_t *bytes, int ifq_locked)
1322{
1323	struct ifclassq *ifq = &ifp->if_snd;
1324	u_int32_t cnt = 0, len = 0;
1325	u_int32_t a_cnt = 0, a_len = 0;
1326
1327	VERIFY(sc == MBUF_SC_UNSPEC || MBUF_VALID_SC(sc));
1328	VERIFY(flow != 0);
1329
1330	if (!ifq_locked)
1331		IFCQ_LOCK(ifq);
1332
1333	if (IFCQ_IS_ENABLED(ifq))
1334		IFCQ_PURGE_SC(ifq, sc, flow, cnt, len);
1335#if PF_ALTQ
1336	if (IFCQ_IS_DRAINING(ifq)) {
1337		VERIFY((signed)(ifq->ifcq_drain - cnt) >= 0);
1338		ifq->ifcq_drain -= cnt;
1339	}
1340	if (ALTQ_IS_ENABLED(IFCQ_ALTQ(ifq)))
1341		ALTQ_PURGE_SC(IFCQ_ALTQ(ifq), sc, flow, a_cnt, a_len);
1342#endif /* PF_ALTQ */
1343
1344	if (!ifq_locked)
1345		IFCQ_UNLOCK(ifq);
1346
1347	if (packets != NULL)
1348		*packets = cnt + a_cnt;
1349	if (bytes != NULL)
1350		*bytes = len + a_len;
1351}
1352
1353/*
1354 * Map interface name to
1355 * interface structure pointer.
1356 */
1357struct ifnet *
1358ifunit(const char *name)
1359{
1360	char namebuf[IFNAMSIZ + 1];
1361	const char *cp;
1362	struct ifnet *ifp;
1363	int unit;
1364	unsigned len, m;
1365	char c;
1366
1367	len = strlen(name);
1368	if (len < 2 || len > IFNAMSIZ)
1369		return (NULL);
1370	cp = name + len - 1;
1371	c = *cp;
1372	if (c < '0' || c > '9')
1373		return (NULL);		/* trailing garbage */
1374	unit = 0;
1375	m = 1;
1376	do {
1377		if (cp == name)
1378			return (NULL);	/* no interface name */
1379		unit += (c - '0') * m;
1380		if (unit > 1000000)
1381			return (NULL);	/* number is unreasonable */
1382		m *= 10;
1383		c = *--cp;
1384	} while (c >= '0' && c <= '9');
1385	len = cp - name + 1;
1386	bcopy(name, namebuf, len);
1387	namebuf[len] = '\0';
1388	/*
1389	 * Now search all the interfaces for this name/number
1390	 */
1391	ifnet_head_lock_shared();
1392	TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
1393		if (strncmp(ifp->if_name, namebuf, len))
1394			continue;
1395		if (unit == ifp->if_unit)
1396			break;
1397	}
1398	ifnet_head_done();
1399	return (ifp);
1400}
1401
1402
1403/*
1404 * Map interface name in a sockaddr_dl to
1405 * interface structure pointer.
1406 */
1407struct ifnet *
1408if_withname(struct sockaddr *sa)
1409{
1410	char ifname[IFNAMSIZ+1];
1411	struct sockaddr_dl *sdl = (struct sockaddr_dl *)(void *)sa;
1412
1413	if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
1414	     (sdl->sdl_nlen > IFNAMSIZ) )
1415		return (NULL);
1416
1417	/*
1418	 * ifunit wants a null-terminated name.  It may not be null-terminated
1419	 * in the sockaddr.  We don't want to change the caller's sockaddr,
1420	 * and there might not be room to put the trailing null anyway, so we
1421	 * make a local copy that we know we can null terminate safely.
1422	 */
1423
1424	bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
1425	ifname[sdl->sdl_nlen] = '\0';
1426	return (ifunit(ifname));
1427}
1428
1429static __attribute__((noinline)) int
1430ifioctl_ifconf(u_long cmd, caddr_t data)
1431{
1432	int error = 0;
1433
1434	switch (cmd) {
1435	case OSIOCGIFCONF32:			/* struct ifconf32 */
1436	case SIOCGIFCONF32: {			/* struct ifconf32 */
1437		struct ifconf32 ifc;
1438		bcopy(data, &ifc, sizeof (ifc));
1439		error = ifconf(cmd, CAST_USER_ADDR_T(ifc.ifc_req),
1440		    &ifc.ifc_len);
1441		bcopy(&ifc, data, sizeof (ifc));
1442		break;
1443	}
1444
1445	case SIOCGIFCONF64:			/* struct ifconf64 */
1446	case OSIOCGIFCONF64: {			/* struct ifconf64 */
1447		struct ifconf64 ifc;
1448		bcopy(data, &ifc, sizeof (ifc));
1449		error = ifconf(cmd, ifc.ifc_req, &ifc.ifc_len);
1450		bcopy(&ifc, data, sizeof (ifc));
1451		break;
1452	}
1453
1454	default:
1455		VERIFY(0);
1456		/* NOTREACHED */
1457	}
1458
1459	return (error);
1460}
1461
1462static __attribute__((noinline)) int
1463ifioctl_ifclone(u_long cmd, caddr_t data)
1464{
1465	int error = 0;
1466
1467	switch (cmd) {
1468	case SIOCIFGCLONERS32: {		/* struct if_clonereq32 */
1469		struct if_clonereq32 ifcr;
1470		bcopy(data, &ifcr, sizeof (ifcr));
1471		error = if_clone_list(ifcr.ifcr_count, &ifcr.ifcr_total,
1472		    CAST_USER_ADDR_T(ifcr.ifcru_buffer));
1473		bcopy(&ifcr, data, sizeof (ifcr));
1474		break;
1475	}
1476
1477	case SIOCIFGCLONERS64: {		/* struct if_clonereq64 */
1478		struct if_clonereq64 ifcr;
1479		bcopy(data, &ifcr, sizeof (ifcr));
1480		error = if_clone_list(ifcr.ifcr_count, &ifcr.ifcr_total,
1481		    ifcr.ifcru_buffer);
1482		bcopy(&ifcr, data, sizeof (ifcr));
1483		break;
1484	}
1485
1486	default:
1487		VERIFY(0);
1488		/* NOTREACHED */
1489	}
1490
1491	return (error);
1492}
1493
1494static __attribute__((noinline)) int
1495ifioctl_ifdesc(struct ifnet *ifp, u_long cmd, caddr_t data, struct proc *p)
1496{
1497	struct if_descreq *ifdr = (struct if_descreq *)(void *)data;
1498	u_int32_t ifdr_len;
1499	int error = 0;
1500
1501	VERIFY(ifp != NULL);
1502
1503	switch (cmd) {
1504	case SIOCSIFDESC: {			/* struct if_descreq */
1505		if ((error = proc_suser(p)) != 0)
1506                        break;
1507
1508		ifnet_lock_exclusive(ifp);
1509		bcopy(&ifdr->ifdr_len, &ifdr_len, sizeof (ifdr_len));
1510		if (ifdr_len > sizeof (ifdr->ifdr_desc) ||
1511		    ifdr_len > ifp->if_desc.ifd_maxlen) {
1512			error = EINVAL;
1513			ifnet_lock_done(ifp);
1514			break;
1515		}
1516
1517		bzero(ifp->if_desc.ifd_desc, ifp->if_desc.ifd_maxlen);
1518		if ((ifp->if_desc.ifd_len = ifdr_len) > 0) {
1519			bcopy(ifdr->ifdr_desc, ifp->if_desc.ifd_desc,
1520			    MIN(ifdr_len, ifp->if_desc.ifd_maxlen));
1521		}
1522		ifnet_lock_done(ifp);
1523		break;
1524	}
1525
1526	case SIOCGIFDESC: {			/* struct if_descreq */
1527		ifnet_lock_shared(ifp);
1528		ifdr_len = MIN(ifp->if_desc.ifd_len, sizeof (ifdr->ifdr_desc));
1529		bcopy(&ifdr_len, &ifdr->ifdr_len, sizeof (ifdr_len));
1530		bzero(&ifdr->ifdr_desc, sizeof (ifdr->ifdr_desc));
1531		if (ifdr_len > 0) {
1532			bcopy(ifp->if_desc.ifd_desc, ifdr->ifdr_desc, ifdr_len);
1533		}
1534		ifnet_lock_done(ifp);
1535		break;
1536	}
1537
1538	default:
1539		VERIFY(0);
1540		/* NOTREACHED */
1541	}
1542
1543	return (error);
1544}
1545
1546static __attribute__((noinline)) int
1547ifioctl_linkparams(struct ifnet *ifp, u_long cmd, caddr_t data, struct proc *p)
1548{
1549	struct if_linkparamsreq *iflpr =
1550	    (struct if_linkparamsreq *)(void *)data;
1551	struct ifclassq *ifq;
1552	int error = 0;
1553
1554	VERIFY(ifp != NULL);
1555	ifq = &ifp->if_snd;
1556
1557	switch (cmd) {
1558	case SIOCSIFLINKPARAMS: {		/* struct if_linkparamsreq */
1559		struct tb_profile tb = { 0, 0, 0 };
1560
1561		if ((error = proc_suser(p)) != 0)
1562                        break;
1563
1564		IFCQ_LOCK(ifq);
1565		if (!IFCQ_IS_READY(ifq)) {
1566			error = ENXIO;
1567			IFCQ_UNLOCK(ifq);
1568			break;
1569		}
1570		bcopy(&iflpr->iflpr_output_tbr_rate, &tb.rate,
1571		    sizeof (tb.rate));
1572		bcopy(&iflpr->iflpr_output_tbr_percent, &tb.percent,
1573		    sizeof (tb.percent));
1574		error = ifclassq_tbr_set(ifq, &tb, TRUE);
1575		IFCQ_UNLOCK(ifq);
1576		break;
1577	}
1578
1579	case SIOCGIFLINKPARAMS: {		/* struct if_linkparamsreq */
1580		u_int32_t sched_type = PKTSCHEDT_NONE, flags = 0;
1581		u_int64_t tbr_bw = 0, tbr_pct = 0;
1582
1583		IFCQ_LOCK(ifq);
1584#if PF_ALTQ
1585		if (ALTQ_IS_ENABLED(IFCQ_ALTQ(ifq))) {
1586			sched_type = IFCQ_ALTQ(ifq)->altq_type;
1587			flags |= IFLPRF_ALTQ;
1588		} else
1589#endif /* PF_ALTQ */
1590		{
1591			if (IFCQ_IS_ENABLED(ifq))
1592				sched_type = ifq->ifcq_type;
1593		}
1594		bcopy(&sched_type, &iflpr->iflpr_output_sched,
1595		    sizeof (iflpr->iflpr_output_sched));
1596
1597		if (IFCQ_TBR_IS_ENABLED(ifq)) {
1598			tbr_bw = ifq->ifcq_tbr.tbr_rate_raw;
1599			tbr_pct = ifq->ifcq_tbr.tbr_percent;
1600		}
1601		bcopy(&tbr_bw, &iflpr->iflpr_output_tbr_rate,
1602		    sizeof (iflpr->iflpr_output_tbr_rate));
1603		bcopy(&tbr_pct, &iflpr->iflpr_output_tbr_percent,
1604		    sizeof (iflpr->iflpr_output_tbr_percent));
1605		IFCQ_UNLOCK(ifq);
1606
1607		if (ifp->if_output_sched_model ==
1608		    IFNET_SCHED_MODEL_DRIVER_MANAGED)
1609			flags |= IFLPRF_DRVMANAGED;
1610		bcopy(&flags, &iflpr->iflpr_flags, sizeof (iflpr->iflpr_flags));
1611		bcopy(&ifp->if_output_bw, &iflpr->iflpr_output_bw,
1612		    sizeof (iflpr->iflpr_output_bw));
1613		bcopy(&ifp->if_input_bw, &iflpr->iflpr_input_bw,
1614		    sizeof (iflpr->iflpr_input_bw));
1615		bcopy(&ifp->if_output_lt, &iflpr->iflpr_output_lt,
1616		    sizeof (iflpr->iflpr_output_lt));
1617		bcopy(&ifp->if_input_lt, &iflpr->iflpr_input_lt,
1618		    sizeof (iflpr->iflpr_input_lt));
1619		break;
1620	}
1621
1622	default:
1623		VERIFY(0);
1624		/* NOTREACHED */
1625	}
1626
1627	return (error);
1628}
1629
1630static __attribute__((noinline)) int
1631ifioctl_qstats(struct ifnet *ifp, u_long cmd, caddr_t data)
1632{
1633	struct if_qstatsreq *ifqr = (struct if_qstatsreq *)(void *)data;
1634	u_int32_t ifqr_len, ifqr_slot;
1635	int error = 0;
1636
1637	VERIFY(ifp != NULL);
1638
1639	switch (cmd) {
1640	case SIOCGIFQUEUESTATS: {		/* struct if_qstatsreq */
1641		bcopy(&ifqr->ifqr_slot, &ifqr_slot, sizeof (ifqr_slot));
1642		bcopy(&ifqr->ifqr_len, &ifqr_len, sizeof (ifqr_len));
1643		error = ifclassq_getqstats(&ifp->if_snd, ifqr_slot,
1644		    ifqr->ifqr_buf, &ifqr_len);
1645		if (error != 0)
1646			ifqr_len = 0;
1647		bcopy(&ifqr_len, &ifqr->ifqr_len, sizeof (ifqr_len));
1648		break;
1649	}
1650
1651	default:
1652		VERIFY(0);
1653		/* NOTREACHED */
1654	}
1655
1656	return (error);
1657}
1658
1659static __attribute__((noinline)) int
1660ifioctl_throttle(struct ifnet *ifp, u_long cmd, caddr_t data, struct proc *p)
1661{
1662	struct if_throttlereq *ifthr = (struct if_throttlereq *)(void *)data;
1663	u_int32_t ifthr_level;
1664	int error = 0;
1665
1666	VERIFY(ifp != NULL);
1667
1668	switch (cmd) {
1669	case SIOCSIFTHROTTLE: {			/* struct if_throttlereq */
1670		/*
1671		 * XXX: Use priv_check_cred() instead of root check?
1672		 */
1673		if ((error = proc_suser(p)) != 0)
1674                        break;
1675
1676		bcopy(&ifthr->ifthr_level, &ifthr_level, sizeof (ifthr_level));
1677		error = ifnet_set_throttle(ifp, ifthr_level);
1678		if (error == EALREADY)
1679			error = 0;
1680		break;
1681	}
1682
1683	case SIOCGIFTHROTTLE: {			/* struct if_throttlereq */
1684		if ((error = ifnet_get_throttle(ifp, &ifthr_level)) == 0) {
1685			bcopy(&ifthr_level, &ifthr->ifthr_level,
1686			    sizeof (ifthr_level));
1687		}
1688		break;
1689	}
1690
1691	default:
1692		VERIFY(0);
1693		/* NOTREACHED */
1694	}
1695
1696	return (error);
1697}
1698
1699/*
1700 * Interface ioctls.
1701 *
1702 * Most of the routines called to handle the ioctls would end up being
1703 * tail-call optimized, which unfortunately causes this routine to
1704 * consume too much stack space; this is the reason for the "noinline"
1705 * attribute used on those routines.
1706 */
1707int
1708ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1709{
1710	char ifname[IFNAMSIZ + 1];
1711	struct ifnet *ifp = NULL;
1712	struct ifstat *ifs = NULL;
1713	int error = 0;
1714
1715	bzero(ifname, sizeof (ifname));
1716
1717	/*
1718	 * ioctls which don't require ifp, or ifreq ioctls
1719	 */
1720	switch (cmd) {
1721	case OSIOCGIFCONF32:			/* struct ifconf32 */
1722	case SIOCGIFCONF32:			/* struct ifconf32 */
1723	case SIOCGIFCONF64:			/* struct ifconf64 */
1724	case OSIOCGIFCONF64:			/* struct ifconf64 */
1725		error = ifioctl_ifconf(cmd, data);
1726		goto done;
1727
1728	case SIOCIFGCLONERS32:			/* struct if_clonereq32 */
1729	case SIOCIFGCLONERS64:			/* struct if_clonereq64 */
1730		error = ifioctl_ifclone(cmd, data);
1731		goto done;
1732
1733	case SIOCSIFDSTADDR:			/* struct ifreq */
1734	case SIOCSIFADDR:			/* struct ifreq */
1735	case SIOCSIFBRDADDR:			/* struct ifreq */
1736	case SIOCSIFNETMASK:			/* struct ifreq */
1737	case OSIOCGIFADDR:			/* struct ifreq */
1738	case OSIOCGIFDSTADDR:			/* struct ifreq */
1739	case OSIOCGIFBRDADDR:			/* struct ifreq */
1740	case OSIOCGIFNETMASK:			/* struct ifreq */
1741	case SIOCSIFKPI:			/* struct ifreq */
1742		if (so->so_proto == NULL) {
1743			error = EOPNOTSUPP;
1744			goto done;
1745		}
1746		/* FALLTHRU */
1747	case SIOCIFCREATE:			/* struct ifreq */
1748	case SIOCIFCREATE2:			/* struct ifreq */
1749	case SIOCIFDESTROY:			/* struct ifreq */
1750	case SIOCGIFFLAGS:			/* struct ifreq */
1751	case SIOCGIFEFLAGS:			/* struct ifreq */
1752	case SIOCGIFCAP:			/* struct ifreq */
1753#if CONFIG_MACF_NET
1754	case SIOCGIFMAC:			/* struct ifreq */
1755	case SIOCSIFMAC:			/* struct ifreq */
1756#endif /* CONFIG_MACF_NET */
1757	case SIOCGIFMETRIC:			/* struct ifreq */
1758	case SIOCGIFMTU:			/* struct ifreq */
1759	case SIOCGIFPHYS:			/* struct ifreq */
1760	case SIOCSIFFLAGS:			/* struct ifreq */
1761	case SIOCSIFCAP:			/* struct ifreq */
1762	case SIOCSIFMETRIC:			/* struct ifreq */
1763	case SIOCSIFPHYS:			/* struct ifreq */
1764	case SIOCSIFMTU:			/* struct ifreq */
1765	case SIOCADDMULTI:			/* struct ifreq */
1766	case SIOCDELMULTI:			/* struct ifreq */
1767	case SIOCDIFPHYADDR:			/* struct ifreq */
1768	case SIOCSIFMEDIA:			/* struct ifreq */
1769	case SIOCSIFGENERIC:			/* struct ifreq */
1770	case SIOCSIFLLADDR:			/* struct ifreq */
1771	case SIOCSIFALTMTU:			/* struct ifreq */
1772	case SIOCSIFVLAN:			/* struct ifreq */
1773	case SIOCSIFBOND:			/* struct ifreq */
1774	case SIOCGIFLLADDR:			/* struct ifreq */
1775	case SIOCGIFTYPE:			/* struct ifreq */
1776	case SIOCGIFPSRCADDR:			/* struct ifreq */
1777	case SIOCGIFPDSTADDR:			/* struct ifreq */
1778	case SIOCGIFGENERIC:			/* struct ifreq */
1779	case SIOCGIFDEVMTU:			/* struct ifreq */
1780	case SIOCGIFVLAN:			/* struct ifreq */
1781	case SIOCGIFBOND:			/* struct ifreq */
1782	case SIOCGIFWAKEFLAGS:			/* struct ifreq */
1783	case SIOCGIFGETRTREFCNT:		/* struct ifreq */
1784	case SIOCSIFOPPORTUNISTIC:		/* struct ifreq */
1785	case SIOCGIFOPPORTUNISTIC:		/* struct ifreq */
1786	case SIOCGIFLINKQUALITYMETRIC:		/* struct ifreq */
1787	case SIOCSIFLOG:			/* struct ifreq */
1788	case SIOCGIFLOG:			/* struct ifreq */
1789	case SIOCGIFDELEGATE: {			/* struct ifreq */
1790		struct ifreq ifr;
1791		bcopy(data, &ifr, sizeof (ifr));
1792		ifr.ifr_name[IFNAMSIZ - 1] = '\0';
1793		bcopy(&ifr.ifr_name, ifname, IFNAMSIZ);
1794		error = ifioctl_ifreq(so, cmd, &ifr, p);
1795		bcopy(&ifr, data, sizeof (ifr));
1796		goto done;
1797	}
1798	}
1799
1800	/*
1801	 * ioctls which require ifp.  Note that we acquire dlil_ifnet_lock
1802	 * here to ensure that the ifnet, if found, has been fully attached.
1803	 */
1804	dlil_if_lock();
1805	switch (cmd) {
1806	case SIOCSIFPHYADDR:			/* struct {if,in_}aliasreq */
1807		bcopy(((struct in_aliasreq *)(void *)data)->ifra_name,
1808		    ifname, IFNAMSIZ);
1809		ifp = ifunit(ifname);
1810		break;
1811
1812#if INET6
1813	case SIOCSIFPHYADDR_IN6_32:		/* struct in6_aliasreq_32 */
1814		bcopy(((struct in6_aliasreq_32 *)(void *)data)->ifra_name,
1815		    ifname, IFNAMSIZ);
1816		ifp = ifunit(ifname);
1817		break;
1818
1819	case SIOCSIFPHYADDR_IN6_64:		/* struct in6_aliasreq_64 */
1820		bcopy(((struct in6_aliasreq_64 *)(void *)data)->ifra_name,
1821		    ifname, IFNAMSIZ);
1822		ifp = ifunit(ifname);
1823		break;
1824#endif /* INET6 */
1825
1826	case SIOCSLIFPHYADDR:			/* struct if_laddrreq */
1827	case SIOCGLIFPHYADDR:			/* struct if_laddrreq */
1828		bcopy(((struct if_laddrreq *)(void *)data)->iflr_name,
1829		    ifname, IFNAMSIZ);
1830		ifp = ifunit(ifname);
1831		break;
1832
1833	case SIOCGIFSTATUS:			/* struct ifstat */
1834		ifs = _MALLOC(sizeof (*ifs), M_DEVBUF, M_WAITOK);
1835		if (ifs == NULL) {
1836			error = ENOMEM;
1837			dlil_if_unlock();
1838			goto done;
1839		}
1840		bcopy(data, ifs, sizeof (*ifs));
1841		ifs->ifs_name[IFNAMSIZ - 1] = '\0';
1842		bcopy(ifs->ifs_name, ifname, IFNAMSIZ);
1843		ifp = ifunit(ifname);
1844		break;
1845
1846	case SIOCGIFMEDIA32:			/* struct ifmediareq32 */
1847		bcopy(((struct ifmediareq32 *)(void *)data)->ifm_name,
1848		    ifname, IFNAMSIZ);
1849		ifp = ifunit(ifname);
1850		break;
1851
1852	case SIOCGIFMEDIA64:			/* struct ifmediareq64 */
1853		bcopy(((struct ifmediareq64 *)(void *)data)->ifm_name,
1854		    ifname, IFNAMSIZ);
1855		ifp = ifunit(ifname);
1856		break;
1857
1858	case SIOCSIFDESC:			/* struct if_descreq */
1859	case SIOCGIFDESC:			/* struct if_descreq */
1860		bcopy(((struct if_descreq *)(void *)data)->ifdr_name,
1861		    ifname, IFNAMSIZ);
1862		ifp = ifunit(ifname);
1863		break;
1864
1865	case SIOCSIFLINKPARAMS:			/* struct if_linkparamsreq */
1866	case SIOCGIFLINKPARAMS:			/* struct if_linkparamsreq */
1867		bcopy(((struct if_linkparamsreq *)(void *)data)->iflpr_name,
1868		    ifname, IFNAMSIZ);
1869		ifp = ifunit(ifname);
1870		break;
1871
1872	case SIOCGIFQUEUESTATS:			/* struct if_qstatsreq */
1873		bcopy(((struct if_qstatsreq *)(void *)data)->ifqr_name,
1874		    ifname, IFNAMSIZ);
1875		ifp = ifunit(ifname);
1876		break;
1877
1878	case SIOCSIFTHROTTLE:			/* struct if_throttlereq */
1879	case SIOCGIFTHROTTLE:			/* struct if_throttlereq */
1880		bcopy(((struct if_throttlereq *)(void *)data)->ifthr_name,
1881		    ifname, IFNAMSIZ);
1882		ifp = ifunit(ifname);
1883		break;
1884
1885	default:
1886		/*
1887		 * This is a bad assumption, but the code seems to
1888		 * have been doing this in the past; caveat emptor.
1889		 */
1890		bcopy(((struct ifreq *)(void *)data)->ifr_name,
1891		    ifname, IFNAMSIZ);
1892		ifp = ifunit(ifname);
1893		break;
1894	}
1895	dlil_if_unlock();
1896
1897	if (ifp == NULL) {
1898		error = ENXIO;
1899		goto done;
1900	}
1901
1902	switch (cmd) {
1903	case SIOCSIFPHYADDR:			/* struct {if,in_}aliasreq */
1904#if INET6
1905	case SIOCSIFPHYADDR_IN6_32:		/* struct in6_aliasreq_32 */
1906	case SIOCSIFPHYADDR_IN6_64:		/* struct in6_aliasreq_64 */
1907#endif /* INET6 */
1908	case SIOCSLIFPHYADDR:			/* struct if_laddrreq */
1909		error = proc_suser(p);
1910		if (error != 0)
1911			break;
1912
1913		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, data);
1914		if (error != 0)
1915			break;
1916
1917		ifnet_touch_lastchange(ifp);
1918		break;
1919
1920	case SIOCGIFSTATUS:			/* struct ifstat */
1921		VERIFY(ifs != NULL);
1922		ifs->ascii[0] = '\0';
1923
1924		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifs);
1925
1926		bcopy(ifs, data, sizeof (*ifs));
1927		break;
1928
1929	case SIOCGLIFPHYADDR:			/* struct if_laddrreq */
1930	case SIOCGIFMEDIA32:			/* struct ifmediareq32 */
1931	case SIOCGIFMEDIA64:			/* struct ifmediareq64 */
1932		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, data);
1933		break;
1934
1935	case SIOCSIFDESC:			/* struct if_descreq */
1936	case SIOCGIFDESC:			/* struct if_descreq */
1937		error = ifioctl_ifdesc(ifp, cmd, data, p);
1938		break;
1939
1940	case SIOCSIFLINKPARAMS:			/* struct if_linkparamsreq */
1941	case SIOCGIFLINKPARAMS:			/* struct if_linkparamsreq */
1942		error = ifioctl_linkparams(ifp, cmd, data, p);
1943		break;
1944
1945	case SIOCGIFQUEUESTATS:			/* struct if_qstatsreq */
1946		error = ifioctl_qstats(ifp, cmd, data);
1947		break;
1948
1949	case SIOCSIFTHROTTLE:			/* struct if_throttlereq */
1950	case SIOCGIFTHROTTLE:			/* struct if_throttlereq */
1951		error = ifioctl_throttle(ifp, cmd, data, p);
1952		break;
1953
1954	default:
1955		if (so->so_proto == NULL) {
1956			error = EOPNOTSUPP;
1957			break;
1958		}
1959
1960		socket_lock(so, 1);
1961		error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
1962		    data, ifp, p));
1963		socket_unlock(so, 1);
1964
1965		if (error == EOPNOTSUPP || error == ENOTSUP) {
1966			error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, data);
1967		}
1968		break;
1969	}
1970
1971done:
1972	if (ifs != NULL)
1973		_FREE(ifs, M_DEVBUF);
1974
1975	if (if_verbose) {
1976		if (ifname[0] == '\0')
1977			(void) snprintf(ifname, sizeof (ifname), "%s",
1978			    "NULL");
1979		else if (ifp != NULL)
1980			(void) snprintf(ifname, sizeof (ifname), "%s",
1981			    if_name(ifp));
1982
1983		if (error != 0) {
1984			printf("%s[%s,%d]: ifp %s cmd 0x%08lx (%c%c [%lu] "
1985			    "%c %lu) error %d\n", __func__,
1986			    proc_name_address(p), proc_pid(p),
1987			    ifname, cmd, (cmd & IOC_IN) ? 'I' : ' ',
1988			    (cmd & IOC_OUT) ? 'O' : ' ', IOCPARM_LEN(cmd),
1989			    (char)IOCGROUP(cmd), cmd & 0xff, error);
1990		} else if (if_verbose > 1) {
1991			printf("%s[%s,%d]: ifp %s cmd 0x%08lx (%c%c [%lu] "
1992			    "%c %lu) OK\n", __func__,
1993			    proc_name_address(p), proc_pid(p),
1994			    ifname, cmd, (cmd & IOC_IN) ? 'I' : ' ',
1995			    (cmd & IOC_OUT) ? 'O' : ' ', IOCPARM_LEN(cmd),
1996			    (char)IOCGROUP(cmd), cmd & 0xff);
1997		}
1998	}
1999
2000	return (error);
2001}
2002
2003static __attribute__((noinline)) int
2004ifioctl_ifreq(struct socket *so, u_long cmd, struct ifreq *ifr, struct proc *p)
2005{
2006	struct ifnet *ifp;
2007	u_long ocmd = cmd;
2008	int error = 0;
2009	struct kev_msg ev_msg;
2010	struct net_event_data ev_data;
2011
2012	bzero(&ev_data, sizeof (struct net_event_data));
2013	bzero(&ev_msg, sizeof (struct kev_msg));
2014
2015	switch (cmd) {
2016	case SIOCIFCREATE:
2017	case SIOCIFCREATE2:
2018                error = proc_suser(p);
2019                if (error)
2020                        return (error);
2021                return (if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name),
2022		    cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL));
2023	case SIOCIFDESTROY:
2024		error = proc_suser(p);
2025		if (error)
2026			return (error);
2027		return (if_clone_destroy(ifr->ifr_name));
2028	}
2029
2030	/*
2031	 * ioctls which require ifp.  Note that we acquire dlil_ifnet_lock
2032	 * here to ensure that the ifnet, if found, has been fully attached.
2033	 */
2034	dlil_if_lock();
2035	ifp = ifunit(ifr->ifr_name);
2036	dlil_if_unlock();
2037
2038	if (ifp == NULL)
2039		return (ENXIO);
2040
2041	switch (cmd) {
2042	case SIOCGIFFLAGS:
2043		ifnet_lock_shared(ifp);
2044		ifr->ifr_flags = ifp->if_flags;
2045		ifnet_lock_done(ifp);
2046		break;
2047
2048	case SIOCGIFEFLAGS:
2049		ifnet_lock_shared(ifp);
2050		ifr->ifr_eflags = ifp->if_eflags;
2051		ifnet_lock_done(ifp);
2052		break;
2053
2054	case SIOCGIFCAP:
2055		ifnet_lock_shared(ifp);
2056		ifr->ifr_reqcap = ifp->if_capabilities;
2057		ifr->ifr_curcap = ifp->if_capenable;
2058		ifnet_lock_done(ifp);
2059		break;
2060
2061#if CONFIG_MACF_NET
2062	case SIOCGIFMAC:
2063		error = mac_ifnet_label_get(kauth_cred_get(), ifr, ifp);
2064		break;
2065
2066	case SIOCSIFMAC:
2067		error = mac_ifnet_label_set(kauth_cred_get(), ifr, ifp);
2068		break;
2069#endif /* CONFIG_MACF_NET */
2070
2071	case SIOCGIFMETRIC:
2072		ifnet_lock_shared(ifp);
2073		ifr->ifr_metric = ifp->if_metric;
2074		ifnet_lock_done(ifp);
2075		break;
2076
2077	case SIOCGIFMTU:
2078		ifnet_lock_shared(ifp);
2079		ifr->ifr_mtu = ifp->if_mtu;
2080		ifnet_lock_done(ifp);
2081		break;
2082
2083	case SIOCGIFPHYS:
2084		ifnet_lock_shared(ifp);
2085		ifr->ifr_phys = ifp->if_physical;
2086		ifnet_lock_done(ifp);
2087		break;
2088
2089	case SIOCSIFFLAGS:
2090		error = proc_suser(p);
2091		if (error != 0)
2092			break;
2093
2094		(void) ifnet_set_flags(ifp, ifr->ifr_flags,
2095		    (u_int16_t)~IFF_CANTCHANGE);
2096
2097		/*
2098		 * Note that we intentionally ignore any error from below
2099		 * for the SIOCSIFFLAGS case.
2100		 */
2101		(void) ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
2102
2103		/*
2104		 * Send the event even upon error from the driver because
2105		 * we changed the flags.
2106		 */
2107		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
2108		ev_msg.kev_class      = KEV_NETWORK_CLASS;
2109		ev_msg.kev_subclass   = KEV_DL_SUBCLASS;
2110
2111		ev_msg.event_code = KEV_DL_SIFFLAGS;
2112		strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
2113		ev_data.if_family = ifp->if_family;
2114		ev_data.if_unit   = (u_int32_t) ifp->if_unit;
2115		ev_msg.dv[0].data_length = sizeof(struct net_event_data);
2116		ev_msg.dv[0].data_ptr    = &ev_data;
2117		ev_msg.dv[1].data_length = 0;
2118		kev_post_msg(&ev_msg);
2119
2120		ifnet_touch_lastchange(ifp);
2121		break;
2122
2123	case SIOCSIFCAP:
2124		error = proc_suser(p);
2125		if (error != 0)
2126			break;
2127
2128		if ((ifr->ifr_reqcap & ~ifp->if_capabilities)) {
2129			error = EINVAL;
2130			break;
2131		}
2132		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
2133
2134		ifnet_touch_lastchange(ifp);
2135		break;
2136
2137	case SIOCSIFMETRIC:
2138		error = proc_suser(p);
2139		if (error != 0)
2140			break;
2141
2142		ifp->if_metric = ifr->ifr_metric;
2143
2144		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
2145		ev_msg.kev_class      = KEV_NETWORK_CLASS;
2146		ev_msg.kev_subclass   = KEV_DL_SUBCLASS;
2147
2148		ev_msg.event_code = KEV_DL_SIFMETRICS;
2149		strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
2150		ev_data.if_family = ifp->if_family;
2151		ev_data.if_unit   = (u_int32_t) ifp->if_unit;
2152		ev_msg.dv[0].data_length = sizeof(struct net_event_data);
2153		ev_msg.dv[0].data_ptr    = &ev_data;
2154
2155		ev_msg.dv[1].data_length = 0;
2156		kev_post_msg(&ev_msg);
2157
2158		ifnet_touch_lastchange(ifp);
2159		break;
2160
2161	case SIOCSIFPHYS:
2162		error = proc_suser(p);
2163		if (error != 0)
2164			break;
2165
2166		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
2167		if (error != 0)
2168			break;
2169
2170		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
2171		ev_msg.kev_class      = KEV_NETWORK_CLASS;
2172		ev_msg.kev_subclass   = KEV_DL_SUBCLASS;
2173
2174		ev_msg.event_code = KEV_DL_SIFPHYS;
2175		strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
2176		ev_data.if_family = ifp->if_family;
2177		ev_data.if_unit   = (u_int32_t) ifp->if_unit;
2178		ev_msg.dv[0].data_length = sizeof(struct net_event_data);
2179		ev_msg.dv[0].data_ptr    = &ev_data;
2180		ev_msg.dv[1].data_length = 0;
2181		kev_post_msg(&ev_msg);
2182
2183		ifnet_touch_lastchange(ifp);
2184		break;
2185
2186	case SIOCSIFMTU: {
2187		u_int32_t oldmtu = ifp->if_mtu;
2188		struct ifclassq *ifq = &ifp->if_snd;
2189
2190		error = proc_suser(p);
2191		if (error != 0)
2192			break;
2193
2194		if (ifp->if_ioctl == NULL) {
2195			error = EOPNOTSUPP;
2196			break;
2197		}
2198		if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU) {
2199			error = EINVAL;
2200			break;
2201		}
2202		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
2203		if (error != 0)
2204			break;
2205
2206		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
2207		ev_msg.kev_class      = KEV_NETWORK_CLASS;
2208		ev_msg.kev_subclass   = KEV_DL_SUBCLASS;
2209
2210		ev_msg.event_code = KEV_DL_SIFMTU;
2211		strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
2212		ev_data.if_family = ifp->if_family;
2213		ev_data.if_unit   = (u_int32_t) ifp->if_unit;
2214		ev_msg.dv[0].data_length = sizeof(struct net_event_data);
2215		ev_msg.dv[0].data_ptr    = &ev_data;
2216		ev_msg.dv[1].data_length = 0;
2217		kev_post_msg(&ev_msg);
2218
2219		ifnet_touch_lastchange(ifp);
2220		rt_ifmsg(ifp);
2221
2222		/*
2223		 * If the link MTU changed, do network layer specific procedure
2224		 * and update all route entries associated with the interface,
2225		 * so that their MTU metric gets updated.
2226		 */
2227		if (ifp->if_mtu != oldmtu) {
2228			if_rtmtu_update(ifp);
2229#if INET6
2230			nd6_setmtu(ifp);
2231#endif /* INET6 */
2232			/* Inform all transmit queues about the new MTU */
2233			IFCQ_LOCK(ifq);
2234			ifnet_update_sndq(ifq, CLASSQ_EV_LINK_MTU);
2235			IFCQ_UNLOCK(ifq);
2236		}
2237		break;
2238	}
2239
2240	case SIOCADDMULTI:
2241	case SIOCDELMULTI:
2242		error = proc_suser(p);
2243		if (error != 0)
2244			break;
2245
2246		/* Don't allow group membership on non-multicast interfaces. */
2247		if ((ifp->if_flags & IFF_MULTICAST) == 0) {
2248			error = EOPNOTSUPP;
2249			break;
2250		}
2251
2252		/* Don't let users screw up protocols' entries. */
2253		if (ifr->ifr_addr.sa_family != AF_UNSPEC &&
2254		    ifr->ifr_addr.sa_family != AF_LINK) {
2255			error = EINVAL;
2256			break;
2257		}
2258
2259		/*
2260		 * User is permitted to anonymously join a particular link
2261		 * multicast group via SIOCADDMULTI.  Subsequent join requested
2262		 * for the same record which has an outstanding refcnt from a
2263		 * past if_addmulti_anon() will not result in EADDRINUSE error
2264		 * (unlike other BSDs.)  Anonymously leaving a group is also
2265		 * allowed only as long as there is an outstanding refcnt held
2266		 * by a previous anonymous request, or else ENOENT (even if the
2267		 * link-layer multicast membership exists for a network-layer
2268		 * membership.)
2269		 */
2270		if (cmd == SIOCADDMULTI) {
2271			error = if_addmulti_anon(ifp, &ifr->ifr_addr, NULL);
2272			ev_msg.event_code = KEV_DL_ADDMULTI;
2273		} else {
2274			error = if_delmulti_anon(ifp, &ifr->ifr_addr);
2275			ev_msg.event_code = KEV_DL_DELMULTI;
2276		}
2277		if (error != 0)
2278			break;
2279
2280		ev_msg.vendor_code    = KEV_VENDOR_APPLE;
2281		ev_msg.kev_class      = KEV_NETWORK_CLASS;
2282		ev_msg.kev_subclass   = KEV_DL_SUBCLASS;
2283		strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ);
2284
2285		ev_data.if_family = ifp->if_family;
2286		ev_data.if_unit   = (u_int32_t) ifp->if_unit;
2287		ev_msg.dv[0].data_length = sizeof(struct net_event_data);
2288		ev_msg.dv[0].data_ptr    = &ev_data;
2289		ev_msg.dv[1].data_length = 0;
2290		kev_post_msg(&ev_msg);
2291
2292		ifnet_touch_lastchange(ifp);
2293		break;
2294
2295	case SIOCDIFPHYADDR:
2296	case SIOCSIFMEDIA:
2297	case SIOCSIFGENERIC:
2298	case SIOCSIFLLADDR:
2299	case SIOCSIFALTMTU:
2300	case SIOCSIFVLAN:
2301	case SIOCSIFBOND:
2302		error = proc_suser(p);
2303		if (error != 0)
2304			break;
2305
2306		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
2307		if (error != 0)
2308			break;
2309
2310		ifnet_touch_lastchange(ifp);
2311		break;
2312
2313	case SIOCGIFLLADDR: {
2314		struct sockaddr_dl *sdl = SDL(ifp->if_lladdr->ifa_addr);
2315
2316		if (sdl->sdl_alen == 0) {
2317			error = EADDRNOTAVAIL;
2318			break;
2319		}
2320		/* If larger than 14-bytes we'll need another mechanism */
2321		if (sdl->sdl_alen > sizeof (ifr->ifr_addr.sa_data)) {
2322			error = EMSGSIZE;
2323			break;
2324		}
2325		/* Follow the same convention used by SIOCSIFLLADDR */
2326		bzero(&ifr->ifr_addr, sizeof (ifr->ifr_addr));
2327		ifr->ifr_addr.sa_family = AF_LINK;
2328		ifr->ifr_addr.sa_len = sdl->sdl_alen;
2329		error = ifnet_guarded_lladdr_copy_bytes(ifp,
2330		    &ifr->ifr_addr.sa_data, sdl->sdl_alen);
2331		break;
2332	}
2333
2334	case SIOCGIFTYPE:
2335		ifr->ifr_type.ift_type = ifp->if_type;
2336		ifr->ifr_type.ift_family = ifp->if_family;
2337		ifr->ifr_type.ift_subfamily = ifp->if_subfamily;
2338		break;
2339
2340	case SIOCGIFPSRCADDR:
2341	case SIOCGIFPDSTADDR:
2342	case SIOCGIFGENERIC:
2343	case SIOCGIFDEVMTU:
2344	case SIOCGIFVLAN:
2345	case SIOCGIFBOND:
2346		error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd, (caddr_t)ifr);
2347		break;
2348
2349	case SIOCGIFWAKEFLAGS:
2350		ifnet_lock_shared(ifp);
2351		ifr->ifr_wake_flags = ifnet_get_wake_flags(ifp);
2352		ifnet_lock_done(ifp);
2353		break;
2354
2355	case SIOCGIFGETRTREFCNT:
2356		ifnet_lock_shared(ifp);
2357		ifr->ifr_route_refcnt = ifp->if_route_refcnt;
2358		ifnet_lock_done(ifp);
2359		break;
2360
2361	case SIOCSIFOPPORTUNISTIC:
2362	case SIOCGIFOPPORTUNISTIC:
2363		error = ifnet_getset_opportunistic(ifp, cmd, ifr, p);
2364		break;
2365
2366	case SIOCGIFLINKQUALITYMETRIC:
2367		ifnet_lock_shared(ifp);
2368		ifr->ifr_link_quality_metric = ifp->if_lqm;
2369		ifnet_lock_done(ifp);
2370		break;
2371
2372	case SIOCSIFLOG:
2373	case SIOCGIFLOG:
2374		error = ifnet_getset_log(ifp, cmd, ifr, p);
2375		break;
2376
2377	case SIOCGIFDELEGATE:
2378		ifnet_lock_shared(ifp);
2379		ifr->ifr_delegated = ((ifp->if_delegated.ifp != NULL) ?
2380		    ifp->if_delegated.ifp->if_index : 0);
2381		ifnet_lock_done(ifp);
2382		break;
2383
2384	case SIOCSIFDSTADDR:
2385	case SIOCSIFADDR:
2386	case SIOCSIFBRDADDR:
2387	case SIOCSIFNETMASK:
2388	case OSIOCGIFADDR:
2389	case OSIOCGIFDSTADDR:
2390	case OSIOCGIFBRDADDR:
2391	case OSIOCGIFNETMASK:
2392	case SIOCSIFKPI:
2393		VERIFY(so->so_proto != NULL);
2394
2395		if (cmd == SIOCSIFDSTADDR || cmd == SIOCSIFADDR ||
2396		    cmd == SIOCSIFBRDADDR || cmd == SIOCSIFNETMASK) {
2397#if BYTE_ORDER != BIG_ENDIAN
2398			if (ifr->ifr_addr.sa_family == 0 &&
2399			    ifr->ifr_addr.sa_len < 16) {
2400				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
2401				ifr->ifr_addr.sa_len = 16;
2402			}
2403#else
2404			if (ifr->ifr_addr.sa_len == 0)
2405				ifr->ifr_addr.sa_len = 16;
2406#endif
2407		} else if (cmd == OSIOCGIFADDR) {
2408			cmd = SIOCGIFADDR;	/* struct ifreq */
2409		} else if (cmd == OSIOCGIFDSTADDR) {
2410			cmd = SIOCGIFDSTADDR;	/* struct ifreq */
2411		} else if (cmd == OSIOCGIFBRDADDR) {
2412			cmd = SIOCGIFBRDADDR;	/* struct ifreq */
2413		} else if (cmd == OSIOCGIFNETMASK) {
2414			cmd = SIOCGIFNETMASK;	/* struct ifreq */
2415		}
2416
2417		socket_lock(so, 1);
2418		error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
2419		    (caddr_t)ifr, ifp, p));
2420		socket_unlock(so, 1);
2421
2422		switch (ocmd) {
2423		case OSIOCGIFADDR:
2424		case OSIOCGIFDSTADDR:
2425		case OSIOCGIFBRDADDR:
2426		case OSIOCGIFNETMASK:
2427			bcopy(&ifr->ifr_addr.sa_family, &ifr->ifr_addr,
2428			    sizeof (u_short));
2429		}
2430
2431		if (cmd == SIOCSIFKPI) {
2432			int temperr = proc_suser(p);
2433			if (temperr != 0)
2434				error = temperr;
2435		}
2436
2437		if (error == EOPNOTSUPP || error == ENOTSUP) {
2438			error = ifnet_ioctl(ifp, SOCK_DOM(so), cmd,
2439			    (caddr_t)ifr);
2440		}
2441		break;
2442
2443	default:
2444		VERIFY(0);
2445		/* NOTREACHED */
2446	}
2447
2448	return (error);
2449}
2450
2451int
2452ifioctllocked(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
2453{
2454	int error;
2455
2456	socket_unlock(so, 0);
2457	error = ifioctl(so, cmd, data, p);
2458	socket_lock(so, 0);
2459	return(error);
2460}
2461
2462/*
2463 * Set/clear promiscuous mode on interface ifp based on the truth value
2464 * of pswitch.  The calls are reference counted so that only the first
2465 * "on" request actually has an effect, as does the final "off" request.
2466 * Results are undefined if the "off" and "on" requests are not matched.
2467 */
2468errno_t
2469ifnet_set_promiscuous(
2470	ifnet_t	ifp,
2471	int pswitch)
2472{
2473	int error = 0;
2474	int oldflags = 0;
2475	int newflags = 0;
2476
2477	ifnet_lock_exclusive(ifp);
2478	oldflags = ifp->if_flags;
2479	ifp->if_pcount += pswitch ? 1 : -1;
2480
2481	if (ifp->if_pcount > 0)
2482		ifp->if_flags |= IFF_PROMISC;
2483	else
2484		ifp->if_flags &= ~IFF_PROMISC;
2485
2486	newflags = ifp->if_flags;
2487	ifnet_lock_done(ifp);
2488
2489	if (newflags != oldflags && (newflags & IFF_UP) != 0) {
2490		error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
2491		if (error == 0) {
2492			rt_ifmsg(ifp);
2493		} else {
2494			ifnet_lock_exclusive(ifp);
2495			// revert the flags
2496			ifp->if_pcount -= pswitch ? 1 : -1;
2497			if (ifp->if_pcount > 0)
2498			    ifp->if_flags |= IFF_PROMISC;
2499			else
2500			    ifp->if_flags &= ~IFF_PROMISC;
2501			ifnet_lock_done(ifp);
2502		}
2503	}
2504
2505	if (newflags != oldflags) {
2506		log(LOG_INFO, "%s: promiscuous mode %s%s\n",
2507		    if_name(ifp),
2508		    (newflags & IFF_PROMISC) != 0 ? "enable" : "disable",
2509		    error != 0 ? " failed" : " succeeded");
2510	}
2511	return error;
2512}
2513
2514/*
2515 * Return interface configuration
2516 * of system.  List may be used
2517 * in later ioctl's (above) to get
2518 * other information.
2519 */
2520/*ARGSUSED*/
2521static int
2522ifconf(u_long cmd, user_addr_t ifrp, int *ret_space)
2523{
2524	struct ifnet *ifp = NULL;
2525	struct ifaddr *ifa;
2526	struct ifreq ifr;
2527	int error = 0;
2528	size_t space;
2529	net_thread_marks_t marks;
2530
2531	marks = net_thread_marks_push(NET_THREAD_CKREQ_LLADDR);
2532
2533	/*
2534	 * Zero the ifr buffer to make sure we don't
2535	 * disclose the contents of the stack.
2536	 */
2537	bzero(&ifr, sizeof (struct ifreq));
2538
2539	space = *ret_space;
2540	ifnet_head_lock_shared();
2541	for (ifp = ifnet_head.tqh_first; space > sizeof (ifr) &&
2542	    ifp; ifp = ifp->if_link.tqe_next) {
2543		char workbuf[64];
2544		size_t ifnlen, addrs;
2545
2546		ifnlen = snprintf(workbuf, sizeof (workbuf),
2547		    "%s", if_name(ifp));
2548		if (ifnlen + 1 > sizeof (ifr.ifr_name)) {
2549			error = ENAMETOOLONG;
2550			break;
2551		} else {
2552			strlcpy(ifr.ifr_name, workbuf, IFNAMSIZ);
2553		}
2554
2555		ifnet_lock_shared(ifp);
2556
2557		addrs = 0;
2558		ifa = ifp->if_addrhead.tqh_first;
2559		for (; space > sizeof (ifr) && ifa;
2560		    ifa = ifa->ifa_link.tqe_next) {
2561			struct sockaddr *sa;
2562			union {
2563				struct sockaddr sa;
2564				struct sockaddr_dl sdl;
2565				uint8_t buf[SOCK_MAXADDRLEN + 1];
2566			} u;
2567
2568			/*
2569			 * Make sure to accomodate the largest possible
2570			 * size of SA(if_lladdr)->sa_len.
2571			 */
2572			_CASSERT(sizeof (u) == (SOCK_MAXADDRLEN + 1));
2573
2574			IFA_LOCK(ifa);
2575			sa = ifa->ifa_addr;
2576			addrs++;
2577
2578			if (ifa == ifp->if_lladdr) {
2579				VERIFY(sa->sa_family == AF_LINK);
2580				bcopy(sa, &u, sa->sa_len);
2581				IFA_UNLOCK(ifa);
2582				ifnet_guarded_lladdr_copy_bytes(ifp,
2583				    LLADDR(&u.sdl), u.sdl.sdl_alen);
2584				IFA_LOCK(ifa);
2585				sa = &u.sa;
2586			}
2587
2588			if (cmd == OSIOCGIFCONF32 || cmd == OSIOCGIFCONF64) {
2589				struct osockaddr *osa =
2590				    (struct osockaddr *)(void *)&ifr.ifr_addr;
2591				ifr.ifr_addr = *sa;
2592				osa->sa_family = sa->sa_family;
2593				error = copyout((caddr_t)&ifr, ifrp,
2594				    sizeof (ifr));
2595				ifrp += sizeof (struct ifreq);
2596			} else if (sa->sa_len <= sizeof (*sa)) {
2597				ifr.ifr_addr = *sa;
2598				error = copyout((caddr_t)&ifr, ifrp,
2599				    sizeof (ifr));
2600				ifrp += sizeof (struct ifreq);
2601			} else {
2602				if (space <
2603				    sizeof (ifr) + sa->sa_len - sizeof (*sa)) {
2604					IFA_UNLOCK(ifa);
2605					break;
2606				}
2607				space -= sa->sa_len - sizeof (*sa);
2608				error = copyout((caddr_t)&ifr, ifrp,
2609				    sizeof (ifr.ifr_name));
2610				if (error == 0) {
2611					error = copyout((caddr_t)sa, (ifrp +
2612					    offsetof(struct ifreq, ifr_addr)),
2613					    sa->sa_len);
2614				}
2615				ifrp += (sa->sa_len + offsetof(struct ifreq,
2616				    ifr_addr));
2617			}
2618			IFA_UNLOCK(ifa);
2619			if (error)
2620				break;
2621			space -= sizeof (ifr);
2622		}
2623		ifnet_lock_done(ifp);
2624
2625		if (error)
2626			break;
2627		if (!addrs) {
2628			bzero((caddr_t)&ifr.ifr_addr, sizeof (ifr.ifr_addr));
2629			error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr));
2630			if (error)
2631				break;
2632			space -= sizeof (ifr);
2633			ifrp += sizeof (struct ifreq);
2634		}
2635	}
2636	ifnet_head_done();
2637	*ret_space -= space;
2638	net_thread_marks_pop(marks);
2639	return (error);
2640}
2641
2642/*
2643 * Just like if_promisc(), but for all-multicast-reception mode.
2644 */
2645int
2646if_allmulti(struct ifnet *ifp, int onswitch)
2647{
2648	int error = 0;
2649	int	modified = 0;
2650
2651	ifnet_lock_exclusive(ifp);
2652
2653	if (onswitch) {
2654		if (ifp->if_amcount++ == 0) {
2655			ifp->if_flags |= IFF_ALLMULTI;
2656			modified = 1;
2657		}
2658	} else {
2659		if (ifp->if_amcount > 1) {
2660			ifp->if_amcount--;
2661		} else {
2662			ifp->if_amcount = 0;
2663			ifp->if_flags &= ~IFF_ALLMULTI;
2664			modified = 1;
2665		}
2666	}
2667	ifnet_lock_done(ifp);
2668
2669	if (modified)
2670		error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL);
2671
2672	if (error == 0)
2673		rt_ifmsg(ifp);
2674	return error;
2675}
2676
2677static struct ifmultiaddr *
2678ifma_alloc(int how)
2679{
2680	struct ifmultiaddr *ifma;
2681
2682	ifma = (how == M_WAITOK) ? zalloc(ifma_zone) :
2683	    zalloc_noblock(ifma_zone);
2684
2685	if (ifma != NULL) {
2686		bzero(ifma, ifma_size);
2687		lck_mtx_init(&ifma->ifma_lock, ifa_mtx_grp, ifa_mtx_attr);
2688		ifma->ifma_debug |= IFD_ALLOC;
2689		if (ifma_debug != 0) {
2690			ifma->ifma_debug |= IFD_DEBUG;
2691			ifma->ifma_trace = ifma_trace;
2692		}
2693	}
2694	return (ifma);
2695}
2696
2697static void
2698ifma_free(struct ifmultiaddr *ifma)
2699{
2700	IFMA_LOCK(ifma);
2701
2702	if (ifma->ifma_protospec != NULL) {
2703		panic("%s: Protospec not NULL for ifma=%p", __func__, ifma);
2704		/* NOTREACHED */
2705	} else if ((ifma->ifma_flags & IFMAF_ANONYMOUS) ||
2706	    ifma->ifma_anoncnt != 0) {
2707		panic("%s: Freeing ifma=%p with outstanding anon req",
2708		    __func__, ifma);
2709		/* NOTREACHED */
2710	} else if (ifma->ifma_debug & IFD_ATTACHED) {
2711		panic("%s: ifma=%p attached to ifma_ifp=%p is being freed",
2712		    __func__, ifma, ifma->ifma_ifp);
2713		/* NOTREACHED */
2714	} else if (!(ifma->ifma_debug & IFD_ALLOC)) {
2715		panic("%s: ifma %p cannot be freed", __func__, ifma);
2716		/* NOTREACHED */
2717	} else if (ifma->ifma_refcount != 0) {
2718		panic("%s: non-zero refcount ifma=%p", __func__, ifma);
2719		/* NOTREACHED */
2720	} else if (ifma->ifma_reqcnt != 0) {
2721		panic("%s: non-zero reqcnt ifma=%p", __func__, ifma);
2722		/* NOTREACHED */
2723	} else if (ifma->ifma_ifp != NULL) {
2724		panic("%s: non-NULL ifma_ifp=%p for ifma=%p", __func__,
2725		    ifma->ifma_ifp, ifma);
2726		/* NOTREACHED */
2727	} else if (ifma->ifma_ll != NULL) {
2728		panic("%s: non-NULL ifma_ll=%p for ifma=%p", __func__,
2729		    ifma->ifma_ll, ifma);
2730		/* NOTREACHED */
2731	}
2732	ifma->ifma_debug &= ~IFD_ALLOC;
2733	if ((ifma->ifma_debug & (IFD_DEBUG | IFD_TRASHED)) ==
2734	    (IFD_DEBUG | IFD_TRASHED)) {
2735		lck_mtx_lock(&ifma_trash_lock);
2736		TAILQ_REMOVE(&ifma_trash_head, (struct ifmultiaddr_dbg *)ifma,
2737		    ifma_trash_link);
2738		lck_mtx_unlock(&ifma_trash_lock);
2739		ifma->ifma_debug &= ~IFD_TRASHED;
2740	}
2741	IFMA_UNLOCK(ifma);
2742
2743	if (ifma->ifma_addr != NULL) {
2744		FREE(ifma->ifma_addr, M_IFADDR);
2745		ifma->ifma_addr = NULL;
2746	}
2747	lck_mtx_destroy(&ifma->ifma_lock, ifa_mtx_grp);
2748	zfree(ifma_zone, ifma);
2749}
2750
2751static void
2752ifma_trace(struct ifmultiaddr *ifma, int refhold)
2753{
2754	struct ifmultiaddr_dbg *ifma_dbg = (struct ifmultiaddr_dbg *)ifma;
2755	ctrace_t *tr;
2756	u_int32_t idx;
2757	u_int16_t *cnt;
2758
2759	if (!(ifma->ifma_debug & IFD_DEBUG)) {
2760		panic("%s: ifma %p has no debug structure", __func__, ifma);
2761		/* NOTREACHED */
2762	}
2763	if (refhold) {
2764		cnt = &ifma_dbg->ifma_refhold_cnt;
2765		tr = ifma_dbg->ifma_refhold;
2766	} else {
2767		cnt = &ifma_dbg->ifma_refrele_cnt;
2768		tr = ifma_dbg->ifma_refrele;
2769	}
2770
2771	idx = atomic_add_16_ov(cnt, 1) % IFMA_TRACE_HIST_SIZE;
2772	ctrace_record(&tr[idx]);
2773}
2774
2775void
2776ifma_addref(struct ifmultiaddr *ifma, int locked)
2777{
2778	if (!locked)
2779		IFMA_LOCK(ifma);
2780	else
2781		IFMA_LOCK_ASSERT_HELD(ifma);
2782
2783	if (++ifma->ifma_refcount == 0) {
2784		panic("%s: ifma=%p wraparound refcnt", __func__, ifma);
2785		/* NOTREACHED */
2786	} else if (ifma->ifma_trace != NULL) {
2787		(*ifma->ifma_trace)(ifma, TRUE);
2788	}
2789	if (!locked)
2790		IFMA_UNLOCK(ifma);
2791}
2792
2793void
2794ifma_remref(struct ifmultiaddr *ifma)
2795{
2796	struct ifmultiaddr *ll;
2797
2798	IFMA_LOCK(ifma);
2799
2800	if (ifma->ifma_refcount == 0) {
2801		panic("%s: ifma=%p negative refcnt", __func__, ifma);
2802		/* NOTREACHED */
2803	} else if (ifma->ifma_trace != NULL) {
2804		(*ifma->ifma_trace)(ifma, FALSE);
2805	}
2806
2807	--ifma->ifma_refcount;
2808	if (ifma->ifma_refcount > 0) {
2809		IFMA_UNLOCK(ifma);
2810		return;
2811	}
2812
2813	ll = ifma->ifma_ll;
2814	ifma->ifma_ifp = NULL;
2815	ifma->ifma_ll = NULL;
2816	IFMA_UNLOCK(ifma);
2817	ifma_free(ifma);	/* deallocate it */
2818
2819	if (ll != NULL)
2820		IFMA_REMREF(ll);
2821}
2822
2823static void
2824if_attach_ifma(struct ifnet *ifp, struct ifmultiaddr *ifma, int anon)
2825{
2826	ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE);
2827	IFMA_LOCK_ASSERT_HELD(ifma);
2828
2829	if (ifma->ifma_ifp != ifp) {
2830		panic("%s: Mismatch ifma_ifp=%p != ifp=%p", __func__,
2831		    ifma->ifma_ifp, ifp);
2832		/* NOTREACHED */
2833	} else if (ifma->ifma_debug & IFD_ATTACHED) {
2834		panic("%s: Attempt to attach an already attached ifma=%p",
2835		    __func__, ifma);
2836		/* NOTREACHED */
2837	} else if (anon && (ifma->ifma_flags & IFMAF_ANONYMOUS)) {
2838		panic("%s: ifma=%p unexpected IFMAF_ANONYMOUS", __func__, ifma);
2839		/* NOTREACHED */
2840	} else if (ifma->ifma_debug & IFD_TRASHED) {
2841		panic("%s: Attempt to reattach a detached ifma=%p",
2842		    __func__, ifma);
2843		/* NOTREACHED */
2844	}
2845
2846	ifma->ifma_reqcnt++;
2847	VERIFY(ifma->ifma_reqcnt == 1);
2848	IFMA_ADDREF_LOCKED(ifma);
2849	ifma->ifma_debug |= IFD_ATTACHED;
2850	if (anon) {
2851		ifma->ifma_anoncnt++;
2852		VERIFY(ifma->ifma_anoncnt == 1);
2853		ifma->ifma_flags |= IFMAF_ANONYMOUS;
2854	}
2855
2856	LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
2857}
2858
2859static int
2860if_detach_ifma(struct ifnet *ifp, struct ifmultiaddr *ifma, int anon)
2861{
2862	ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE);
2863	IFMA_LOCK_ASSERT_HELD(ifma);
2864
2865	if (ifma->ifma_reqcnt == 0) {
2866		panic("%s: ifma=%p negative reqcnt", __func__, ifma);
2867		/* NOTREACHED */
2868	} else if (anon && !(ifma->ifma_flags & IFMAF_ANONYMOUS)) {
2869		panic("%s: ifma=%p missing IFMAF_ANONYMOUS", __func__, ifma);
2870		/* NOTREACHED */
2871	} else if (anon && ifma->ifma_anoncnt == 0) {
2872		panic("%s: ifma=%p negative anonreqcnt", __func__, ifma);
2873		/* NOTREACHED */
2874	} else if (ifma->ifma_ifp != ifp) {
2875		panic("%s: Mismatch ifma_ifp=%p, ifp=%p", __func__,
2876		    ifma->ifma_ifp, ifp);
2877		/* NOTREACHED */
2878	}
2879
2880	if (anon) {
2881		--ifma->ifma_anoncnt;
2882		if (ifma->ifma_anoncnt > 0)
2883			return (0);
2884		ifma->ifma_flags &= ~IFMAF_ANONYMOUS;
2885	}
2886
2887	--ifma->ifma_reqcnt;
2888	if (ifma->ifma_reqcnt > 0)
2889		return (0);
2890
2891	if (ifma->ifma_protospec != NULL) {
2892		panic("%s: Protospec not NULL for ifma=%p", __func__, ifma);
2893		/* NOTREACHED */
2894	} else if ((ifma->ifma_flags & IFMAF_ANONYMOUS) ||
2895	    ifma->ifma_anoncnt != 0) {
2896		panic("%s: Detaching ifma=%p with outstanding anon req",
2897		    __func__, ifma);
2898		/* NOTREACHED */
2899	} else if (!(ifma->ifma_debug & IFD_ATTACHED)) {
2900		panic("%s: Attempt to detach an unattached address ifma=%p",
2901		    __func__, ifma);
2902		/* NOTREACHED */
2903	} else if (ifma->ifma_debug & IFD_TRASHED) {
2904		panic("%s: ifma %p is already in trash list", __func__, ifma);
2905		/* NOTREACHED */
2906	}
2907
2908	/*
2909	 * NOTE: Caller calls IFMA_REMREF
2910	 */
2911	ifma->ifma_debug &= ~IFD_ATTACHED;
2912	LIST_REMOVE(ifma, ifma_link);
2913	if (LIST_EMPTY(&ifp->if_multiaddrs))
2914		ifp->if_updatemcasts = 0;
2915
2916	if (ifma->ifma_debug & IFD_DEBUG) {
2917		/* Become a regular mutex, just in case */
2918		IFMA_CONVERT_LOCK(ifma);
2919		lck_mtx_lock(&ifma_trash_lock);
2920		TAILQ_INSERT_TAIL(&ifma_trash_head,
2921		    (struct ifmultiaddr_dbg *)ifma, ifma_trash_link);
2922		lck_mtx_unlock(&ifma_trash_lock);
2923		ifma->ifma_debug |= IFD_TRASHED;
2924	}
2925
2926	return (1);
2927}
2928
2929/*
2930 * Find an ifmultiaddr that matches a socket address on an interface.
2931 *
2932 * Caller is responsible for holding the ifnet_lock while calling
2933 * this function.
2934 */
2935static int
2936if_addmulti_doesexist(struct ifnet *ifp, const struct sockaddr *sa,
2937    struct ifmultiaddr **retifma, int anon)
2938{
2939	struct ifmultiaddr *ifma;
2940
2941	for (ifma = LIST_FIRST(&ifp->if_multiaddrs); ifma != NULL;
2942	     ifma = LIST_NEXT(ifma, ifma_link)) {
2943		IFMA_LOCK_SPIN(ifma);
2944		if (!equal(sa, ifma->ifma_addr)) {
2945			IFMA_UNLOCK(ifma);
2946			continue;
2947		}
2948		if (anon) {
2949			VERIFY(!(ifma->ifma_flags & IFMAF_ANONYMOUS) ||
2950			    ifma->ifma_anoncnt != 0);
2951			VERIFY((ifma->ifma_flags & IFMAF_ANONYMOUS) ||
2952			    ifma->ifma_anoncnt == 0);
2953			ifma->ifma_anoncnt++;
2954			if (!(ifma->ifma_flags & IFMAF_ANONYMOUS)) {
2955				VERIFY(ifma->ifma_anoncnt == 1);
2956				ifma->ifma_flags |= IFMAF_ANONYMOUS;
2957			}
2958		}
2959		if (!anon || ifma->ifma_anoncnt == 1) {
2960			ifma->ifma_reqcnt++;
2961			VERIFY(ifma->ifma_reqcnt > 1);
2962		}
2963		if (retifma != NULL) {
2964			*retifma = ifma;
2965			IFMA_ADDREF_LOCKED(ifma);
2966		}
2967		IFMA_UNLOCK(ifma);
2968		return (0);
2969	}
2970	return (ENOENT);
2971}
2972
2973/*
2974 * Radar 3642395, make sure all multicasts are in a standard format.
2975 */
2976static struct sockaddr*
2977copy_and_normalize(const struct sockaddr *original)
2978{
2979	int			alen = 0;
2980	const u_char		*aptr = NULL;
2981	struct sockaddr		*copy = NULL;
2982	struct sockaddr_dl	*sdl_new = NULL;
2983	int			len = 0;
2984
2985	if (original->sa_family != AF_LINK &&
2986	    original->sa_family != AF_UNSPEC) {
2987		/* Just make a copy */
2988		MALLOC(copy, struct sockaddr*, original->sa_len,
2989		    M_IFADDR, M_WAITOK);
2990		if (copy != NULL)
2991			bcopy(original, copy, original->sa_len);
2992		return (copy);
2993	}
2994
2995	switch (original->sa_family) {
2996		case AF_LINK: {
2997			const struct sockaddr_dl *sdl_original =
2998			    (struct sockaddr_dl*)(uintptr_t)(size_t)original;
2999
3000			if (sdl_original->sdl_nlen + sdl_original->sdl_alen +
3001			    sdl_original->sdl_slen +
3002			    offsetof(struct sockaddr_dl, sdl_data) >
3003			    sdl_original->sdl_len)
3004				return (NULL);
3005
3006			alen = sdl_original->sdl_alen;
3007			aptr = CONST_LLADDR(sdl_original);
3008		}
3009		break;
3010
3011		case AF_UNSPEC: {
3012			if (original->sa_len < ETHER_ADDR_LEN +
3013			    offsetof(struct sockaddr, sa_data)) {
3014				return (NULL);
3015			}
3016
3017			alen = ETHER_ADDR_LEN;
3018			aptr = (const u_char*)original->sa_data;
3019		}
3020		break;
3021	}
3022
3023	if (alen == 0 || aptr == NULL)
3024		return (NULL);
3025
3026	len = alen + offsetof(struct sockaddr_dl, sdl_data);
3027	MALLOC(sdl_new, struct sockaddr_dl*, len, M_IFADDR, M_WAITOK);
3028
3029	if (sdl_new != NULL) {
3030		bzero(sdl_new, len);
3031		sdl_new->sdl_len = len;
3032		sdl_new->sdl_family = AF_LINK;
3033		sdl_new->sdl_alen = alen;
3034		bcopy(aptr, LLADDR(sdl_new), alen);
3035	}
3036
3037	return ((struct sockaddr*)sdl_new);
3038}
3039
3040/*
3041 * Network-layer protocol domains which hold references to the underlying
3042 * link-layer record must use this routine.
3043 */
3044int
3045if_addmulti(struct ifnet *ifp, const struct sockaddr *sa,
3046    struct ifmultiaddr **retifma)
3047{
3048	return (if_addmulti_common(ifp, sa, retifma, 0));
3049}
3050
3051/*
3052 * Anything other than network-layer protocol domains which hold references
3053 * to the underlying link-layer record must use this routine: SIOCADDMULTI
3054 * ioctl, ifnet_add_multicast(), if_bond.
3055 */
3056int
3057if_addmulti_anon(struct ifnet *ifp, const struct sockaddr *sa,
3058    struct ifmultiaddr **retifma)
3059{
3060	return (if_addmulti_common(ifp, sa, retifma, 1));
3061}
3062
3063/*
3064 * Register an additional multicast address with a network interface.
3065 *
3066 * - If the address is already present, bump the reference count on the
3067 *   address and return.
3068 * - If the address is not link-layer, look up a link layer address.
3069 * - Allocate address structures for one or both addresses, and attach to the
3070 *   multicast address list on the interface.  If automatically adding a link
3071 *   layer address, the protocol address will own a reference to the link
3072 *   layer address, to be freed when it is freed.
3073 * - Notify the network device driver of an addition to the multicast address
3074 *   list.
3075 *
3076 * 'sa' points to caller-owned memory with the desired multicast address.
3077 *
3078 * 'retifma' will be used to return a pointer to the resulting multicast
3079 * address reference, if desired.
3080 *
3081 * 'anon' indicates a link-layer address with no protocol address reference
3082 * made to it.  Anything other than network-layer protocol domain requests
3083 * are considered as anonymous.
3084 */
3085static int
3086if_addmulti_common(struct ifnet *ifp, const struct sockaddr *sa,
3087    struct ifmultiaddr **retifma, int anon)
3088{
3089	struct sockaddr_storage storage;
3090	struct sockaddr *llsa = NULL;
3091	struct sockaddr *dupsa = NULL;
3092	int error = 0, ll_firstref = 0, lladdr;
3093	struct ifmultiaddr *ifma = NULL;
3094	struct ifmultiaddr *llifma = NULL;
3095
3096	/* Only AF_UNSPEC/AF_LINK is allowed for an "anonymous" address */
3097	VERIFY(!anon || sa->sa_family == AF_UNSPEC ||
3098	    sa->sa_family == AF_LINK);
3099
3100	/* If sa is a AF_LINK or AF_UNSPEC, duplicate and normalize it */
3101	if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) {
3102		dupsa = copy_and_normalize(sa);
3103		if (dupsa == NULL) {
3104			error = ENOMEM;
3105			goto cleanup;
3106		}
3107		sa = dupsa;
3108	}
3109
3110	ifnet_lock_exclusive(ifp);
3111	if (!(ifp->if_flags & IFF_MULTICAST)) {
3112		error = EADDRNOTAVAIL;
3113		ifnet_lock_done(ifp);
3114		goto cleanup;
3115	}
3116
3117	/* If the address is already present, return a new reference to it */
3118	error = if_addmulti_doesexist(ifp, sa, retifma, anon);
3119	ifnet_lock_done(ifp);
3120	if (error == 0)
3121		goto cleanup;
3122
3123	/*
3124	 * The address isn't already present; give the link layer a chance
3125	 * to accept/reject it, and also find out which AF_LINK address this
3126	 * maps to, if it isn't one already.
3127	 */
3128	error = dlil_resolve_multi(ifp, sa, (struct sockaddr *)&storage,
3129	    sizeof (storage));
3130	if (error == 0 && storage.ss_len != 0) {
3131		llsa = copy_and_normalize((struct sockaddr *)&storage);
3132		if (llsa == NULL) {
3133			error = ENOMEM;
3134			goto cleanup;
3135		}
3136
3137		llifma = ifma_alloc(M_WAITOK);
3138		if (llifma == NULL) {
3139			error = ENOMEM;
3140			goto cleanup;
3141		}
3142	}
3143
3144	/* to be similar to FreeBSD */
3145	if (error == EOPNOTSUPP)
3146		error = 0;
3147	else if (error != 0)
3148		goto cleanup;
3149
3150	/* Allocate while we aren't holding any locks */
3151	if (dupsa == NULL) {
3152		dupsa = copy_and_normalize(sa);
3153		if (dupsa == NULL) {
3154			error = ENOMEM;
3155			goto cleanup;
3156		}
3157	}
3158	ifma = ifma_alloc(M_WAITOK);
3159	if (ifma == NULL) {
3160		error = ENOMEM;
3161		goto cleanup;
3162	}
3163
3164	ifnet_lock_exclusive(ifp);
3165	/*
3166	 * Check again for the matching multicast.
3167	 */
3168	error = if_addmulti_doesexist(ifp, sa, retifma, anon);
3169	if (error == 0) {
3170		ifnet_lock_done(ifp);
3171		goto cleanup;
3172	}
3173
3174	if (llifma != NULL) {
3175		VERIFY(!anon);	/* must not get here if "anonymous" */
3176		if (if_addmulti_doesexist(ifp, llsa, &ifma->ifma_ll, 0) == 0) {
3177			FREE(llsa, M_IFADDR);
3178			llsa = NULL;
3179			ifma_free(llifma);
3180			llifma = NULL;
3181			VERIFY(ifma->ifma_ll->ifma_ifp == ifp);
3182		} else {
3183			ll_firstref = 1;
3184			llifma->ifma_addr = llsa;
3185			llifma->ifma_ifp = ifp;
3186			IFMA_LOCK(llifma);
3187			if_attach_ifma(ifp, llifma, 0);
3188			/* add extra refcnt for ifma */
3189			IFMA_ADDREF_LOCKED(llifma);
3190			IFMA_UNLOCK(llifma);
3191			ifma->ifma_ll = llifma;
3192		}
3193	}
3194
3195	/* "anonymous" request should not result in network address */
3196	VERIFY(!anon || ifma->ifma_ll == NULL);
3197
3198	ifma->ifma_addr = dupsa;
3199	ifma->ifma_ifp = ifp;
3200	IFMA_LOCK(ifma);
3201	if_attach_ifma(ifp, ifma, anon);
3202	IFMA_ADDREF_LOCKED(ifma);		/* for this routine */
3203	if (retifma != NULL) {
3204		*retifma = ifma;
3205		IFMA_ADDREF_LOCKED(*retifma);	/* for caller */
3206	}
3207	lladdr = (ifma->ifma_addr->sa_family == AF_UNSPEC ||
3208	    ifma->ifma_addr->sa_family == AF_LINK);
3209	IFMA_UNLOCK(ifma);
3210	ifnet_lock_done(ifp);
3211
3212	rt_newmaddrmsg(RTM_NEWMADDR, ifma);
3213	IFMA_REMREF(ifma);			/* for this routine */
3214
3215	/*
3216	 * We are certain we have added something, so call down to the
3217	 * interface to let them know about it.  Do this only for newly-
3218	 * added AF_LINK/AF_UNSPEC address in the if_multiaddrs set.
3219	 */
3220	if (lladdr || ll_firstref)
3221		(void) ifnet_ioctl(ifp, 0, SIOCADDMULTI, NULL);
3222
3223	if (ifp->if_updatemcasts > 0)
3224		ifp->if_updatemcasts = 0;
3225
3226	return (0);
3227
3228cleanup:
3229	if (ifma != NULL)
3230		ifma_free(ifma);
3231	if (dupsa != NULL)
3232		FREE(dupsa, M_IFADDR);
3233	if (llifma != NULL)
3234		ifma_free(llifma);
3235	if (llsa != NULL)
3236		FREE(llsa, M_IFADDR);
3237
3238	return (error);
3239}
3240
3241/*
3242 * Delete a multicast group membership by network-layer group address.
3243 * This routine is deprecated.
3244 */
3245int
3246if_delmulti(struct ifnet *ifp, const struct sockaddr *sa)
3247{
3248	return (if_delmulti_common(NULL, ifp, sa, 0));
3249}
3250
3251/*
3252 * Delete a multicast group membership by group membership pointer.
3253 * Network-layer protocol domains must use this routine.
3254 */
3255int
3256if_delmulti_ifma(struct ifmultiaddr *ifma)
3257{
3258	return (if_delmulti_common(ifma, NULL, NULL, 0));
3259}
3260
3261/*
3262 * Anything other than network-layer protocol domains which hold references
3263 * to the underlying link-layer record must use this routine: SIOCDELMULTI
3264 * ioctl, ifnet_remove_multicast(), if_bond.
3265 */
3266int
3267if_delmulti_anon(struct ifnet *ifp, const struct sockaddr *sa)
3268{
3269	return (if_delmulti_common(NULL, ifp, sa, 1));
3270}
3271
3272/*
3273 * Delete a multicast group membership by network-layer group address.
3274 *
3275 * Returns ENOENT if the entry could not be found.
3276 */
3277static int
3278if_delmulti_common(struct ifmultiaddr *ifma, struct ifnet *ifp,
3279    const struct sockaddr *sa, int anon)
3280{
3281	struct sockaddr		*dupsa = NULL;
3282	int			lastref, ll_lastref = 0, lladdr;
3283	struct ifmultiaddr	*ll = NULL;
3284
3285	/* sanity check for callers */
3286	VERIFY(ifma != NULL || (ifp != NULL && sa != NULL));
3287
3288	if (ifma != NULL)
3289		ifp = ifma->ifma_ifp;
3290
3291	if (sa != NULL &&
3292	    (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC)) {
3293		dupsa = copy_and_normalize(sa);
3294		if (dupsa == NULL)
3295			return (ENOMEM);
3296		sa = dupsa;
3297	}
3298
3299	ifnet_lock_exclusive(ifp);
3300	if (ifma == NULL) {
3301		for (ifma = LIST_FIRST(&ifp->if_multiaddrs); ifma != NULL;
3302		     ifma = LIST_NEXT(ifma, ifma_link)) {
3303			IFMA_LOCK(ifma);
3304			if (!equal(sa, ifma->ifma_addr) ||
3305			    (anon && !(ifma->ifma_flags & IFMAF_ANONYMOUS))) {
3306				VERIFY(!(ifma->ifma_flags & IFMAF_ANONYMOUS) ||
3307				    ifma->ifma_anoncnt != 0);
3308				IFMA_UNLOCK(ifma);
3309				continue;
3310			}
3311			/* found; keep it locked */
3312			break;
3313		}
3314		if (ifma == NULL) {
3315			if (dupsa != NULL)
3316				FREE(dupsa, M_IFADDR);
3317			ifnet_lock_done(ifp);
3318			return (ENOENT);
3319		}
3320	} else {
3321		IFMA_LOCK(ifma);
3322	}
3323	IFMA_LOCK_ASSERT_HELD(ifma);
3324	IFMA_ADDREF_LOCKED(ifma);	/* for this routine */
3325	lastref = if_detach_ifma(ifp, ifma, anon);
3326	VERIFY(!lastref || (!(ifma->ifma_debug & IFD_ATTACHED) &&
3327	    ifma->ifma_reqcnt == 0));
3328	VERIFY(!anon || ifma->ifma_ll == NULL);
3329	ll = ifma->ifma_ll;
3330	lladdr = (ifma->ifma_addr->sa_family == AF_UNSPEC ||
3331	    ifma->ifma_addr->sa_family == AF_LINK);
3332	IFMA_UNLOCK(ifma);
3333	if (lastref && ll != NULL) {
3334		IFMA_LOCK(ll);
3335		ll_lastref = if_detach_ifma(ifp, ll, 0);
3336		IFMA_UNLOCK(ll);
3337	}
3338	ifnet_lock_done(ifp);
3339
3340	if (lastref)
3341		rt_newmaddrmsg(RTM_DELMADDR, ifma);
3342
3343	if ((ll == NULL && lastref && lladdr) || ll_lastref) {
3344		/*
3345		 * Make sure the interface driver is notified in the
3346		 * case of a link layer mcast group being left.  Do
3347		 * this only for a AF_LINK/AF_UNSPEC address that has
3348		 * been removed from the if_multiaddrs set.
3349		 */
3350		ifnet_ioctl(ifp, 0, SIOCDELMULTI, NULL);
3351	}
3352
3353	if (lastref)
3354		IFMA_REMREF(ifma);	/* for if_multiaddrs list */
3355	if (ll_lastref)
3356		IFMA_REMREF(ll);	/* for if_multiaddrs list */
3357
3358	IFMA_REMREF(ifma);		/* for this routine */
3359	if (dupsa != NULL)
3360		FREE(dupsa, M_IFADDR);
3361
3362	return (0);
3363}
3364
3365/*
3366 * Shutdown all network activity.  Used boot() when halting
3367 * system.
3368 */
3369int
3370if_down_all(void)
3371{
3372	struct ifnet **ifp;
3373	u_int32_t	count;
3374	u_int32_t	i;
3375
3376	if (ifnet_list_get_all(IFNET_FAMILY_ANY, &ifp, &count) == 0) {
3377		for (i = 0; i < count; i++) {
3378			if_down(ifp[i]);
3379			dlil_proto_unplumb_all(ifp[i]);
3380		}
3381		ifnet_list_free(ifp);
3382	}
3383
3384	return 0;
3385}
3386
3387/*
3388 * Delete Routes for a Network Interface
3389 *
3390 * Called for each routing entry via the rnh->rnh_walktree() call above
3391 * to delete all route entries referencing a detaching network interface.
3392 *
3393 * Arguments:
3394 *	rn	pointer to node in the routing table
3395 *	arg	argument passed to rnh->rnh_walktree() - detaching interface
3396 *
3397 * Returns:
3398 *	0	successful
3399 *	errno	failed - reason indicated
3400 *
3401 */
3402static int
3403if_rtdel(struct radix_node *rn, void *arg)
3404{
3405	struct rtentry	*rt = (struct rtentry *)rn;
3406	struct ifnet	*ifp = arg;
3407	int		err;
3408
3409	if (rt == NULL)
3410		return (0);
3411	/*
3412	 * Checking against RTF_UP protects against walktree
3413	 * recursion problems with cloned routes.
3414	 */
3415	RT_LOCK(rt);
3416	if (rt->rt_ifp == ifp && (rt->rt_flags & RTF_UP)) {
3417		/*
3418		 * Safe to drop rt_lock and use rt_key, rt_gateway,
3419		 * since holding rnh_lock here prevents another thread
3420		 * from calling rt_setgate() on this route.
3421		 */
3422		RT_UNLOCK(rt);
3423		err = rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway,
3424		    rt_mask(rt), rt->rt_flags, NULL);
3425		if (err) {
3426			log(LOG_WARNING, "if_rtdel: error %d\n", err);
3427		}
3428	} else {
3429		RT_UNLOCK(rt);
3430	}
3431	return (0);
3432}
3433
3434/*
3435 * Removes routing table reference to a given interface
3436 * for a given protocol family
3437 */
3438void
3439if_rtproto_del(struct ifnet *ifp, int protocol)
3440{
3441	struct radix_node_head  *rnh;
3442
3443	if ((protocol <= AF_MAX) && (protocol >= 0) &&
3444		((rnh = rt_tables[protocol]) != NULL) && (ifp != NULL)) {
3445		lck_mtx_lock(rnh_lock);
3446		(void) rnh->rnh_walktree(rnh, if_rtdel, ifp);
3447		lck_mtx_unlock(rnh_lock);
3448	}
3449}
3450
3451static int
3452if_rtmtu(struct radix_node *rn, void *arg)
3453{
3454	struct rtentry *rt = (struct rtentry *)rn;
3455	struct ifnet *ifp = arg;
3456
3457	RT_LOCK(rt);
3458	if (rt->rt_ifp == ifp) {
3459		/*
3460		 * Update the MTU of this entry only if the MTU
3461		 * has not been locked (RTV_MTU is not set) and
3462		 * if it was non-zero to begin with.
3463		 */
3464		if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu)
3465			rt->rt_rmx.rmx_mtu = ifp->if_mtu;
3466	}
3467	RT_UNLOCK(rt);
3468
3469	return (0);
3470}
3471
3472/*
3473 * Update the MTU metric of all route entries in all protocol tables
3474 * associated with a particular interface; this is called when the
3475 * MTU of that interface has changed.
3476 */
3477static
3478void if_rtmtu_update(struct ifnet *ifp)
3479{
3480	struct radix_node_head *rnh;
3481	int p;
3482
3483	for (p = 0; p < AF_MAX + 1; p++) {
3484		if ((rnh = rt_tables[p]) == NULL)
3485			continue;
3486
3487		lck_mtx_lock(rnh_lock);
3488		(void) rnh->rnh_walktree(rnh, if_rtmtu, ifp);
3489		lck_mtx_unlock(rnh_lock);
3490	}
3491	routegenid_update();
3492}
3493
3494__private_extern__ void
3495if_data_internal_to_if_data(struct ifnet *ifp,
3496    const struct if_data_internal *if_data_int, struct if_data *if_data)
3497{
3498#pragma unused(ifp)
3499#define COPYFIELD(fld)		if_data->fld = if_data_int->fld
3500#define COPYFIELD32(fld)	if_data->fld = (u_int32_t)(if_data_int->fld)
3501/* compiler will cast down to 32-bit */
3502#define	COPYFIELD32_ATOMIC(fld) do {					\
3503	atomic_get_64(if_data->fld,					\
3504	    (u_int64_t *)(void *)(uintptr_t)&if_data_int->fld);		\
3505} while (0)
3506
3507	COPYFIELD(ifi_type);
3508	COPYFIELD(ifi_typelen);
3509	COPYFIELD(ifi_physical);
3510	COPYFIELD(ifi_addrlen);
3511	COPYFIELD(ifi_hdrlen);
3512	COPYFIELD(ifi_recvquota);
3513	COPYFIELD(ifi_xmitquota);
3514	if_data->ifi_unused1 = 0;
3515	COPYFIELD(ifi_mtu);
3516	COPYFIELD(ifi_metric);
3517	if (if_data_int->ifi_baudrate & 0xFFFFFFFF00000000LL) {
3518		if_data->ifi_baudrate = 0xFFFFFFFF;
3519	} else {
3520		COPYFIELD32(ifi_baudrate);
3521	}
3522
3523	COPYFIELD32_ATOMIC(ifi_ipackets);
3524	COPYFIELD32_ATOMIC(ifi_ierrors);
3525	COPYFIELD32_ATOMIC(ifi_opackets);
3526	COPYFIELD32_ATOMIC(ifi_oerrors);
3527	COPYFIELD32_ATOMIC(ifi_collisions);
3528	COPYFIELD32_ATOMIC(ifi_ibytes);
3529	COPYFIELD32_ATOMIC(ifi_obytes);
3530	COPYFIELD32_ATOMIC(ifi_imcasts);
3531	COPYFIELD32_ATOMIC(ifi_omcasts);
3532	COPYFIELD32_ATOMIC(ifi_iqdrops);
3533	COPYFIELD32_ATOMIC(ifi_noproto);
3534
3535	COPYFIELD(ifi_recvtiming);
3536	COPYFIELD(ifi_xmittiming);
3537
3538	if_data->ifi_lastchange.tv_sec = if_data_int->ifi_lastchange.tv_sec;
3539	if_data->ifi_lastchange.tv_usec = if_data_int->ifi_lastchange.tv_usec;
3540
3541	if_data->ifi_lastchange.tv_sec += boottime_sec();
3542
3543	if_data->ifi_unused2 = 0;
3544	COPYFIELD(ifi_hwassist);
3545	if_data->ifi_reserved1 = 0;
3546	if_data->ifi_reserved2 = 0;
3547#undef COPYFIELD32_ATOMIC
3548#undef COPYFIELD32
3549#undef COPYFIELD
3550}
3551
3552__private_extern__ void
3553if_data_internal_to_if_data64(struct ifnet *ifp,
3554    const struct if_data_internal *if_data_int,
3555    struct if_data64 *if_data64)
3556{
3557#pragma unused(ifp)
3558#define COPYFIELD64(fld)	if_data64->fld = if_data_int->fld
3559#define COPYFIELD64_ATOMIC(fld) do {					\
3560	atomic_get_64(if_data64->fld,					\
3561	    (u_int64_t *)(void *)(uintptr_t)&if_data_int->fld);		\
3562} while (0)
3563
3564	COPYFIELD64(ifi_type);
3565	COPYFIELD64(ifi_typelen);
3566	COPYFIELD64(ifi_physical);
3567	COPYFIELD64(ifi_addrlen);
3568	COPYFIELD64(ifi_hdrlen);
3569	COPYFIELD64(ifi_recvquota);
3570	COPYFIELD64(ifi_xmitquota);
3571	if_data64->ifi_unused1 = 0;
3572	COPYFIELD64(ifi_mtu);
3573	COPYFIELD64(ifi_metric);
3574	COPYFIELD64(ifi_baudrate);
3575
3576	COPYFIELD64_ATOMIC(ifi_ipackets);
3577	COPYFIELD64_ATOMIC(ifi_ierrors);
3578	COPYFIELD64_ATOMIC(ifi_opackets);
3579	COPYFIELD64_ATOMIC(ifi_oerrors);
3580	COPYFIELD64_ATOMIC(ifi_collisions);
3581	COPYFIELD64_ATOMIC(ifi_ibytes);
3582	COPYFIELD64_ATOMIC(ifi_obytes);
3583	COPYFIELD64_ATOMIC(ifi_imcasts);
3584	COPYFIELD64_ATOMIC(ifi_omcasts);
3585	COPYFIELD64_ATOMIC(ifi_iqdrops);
3586	COPYFIELD64_ATOMIC(ifi_noproto);
3587
3588	/* Note these two fields are actually 32 bit, so doing COPYFIELD64_ATOMIC will
3589	 * cause them to be misaligned
3590	 */
3591	COPYFIELD64(ifi_recvtiming);
3592	COPYFIELD64(ifi_xmittiming);
3593
3594	if_data64->ifi_lastchange.tv_sec = if_data_int->ifi_lastchange.tv_sec;
3595	if_data64->ifi_lastchange.tv_usec = if_data_int->ifi_lastchange.tv_usec;
3596
3597	if_data64->ifi_lastchange.tv_sec += boottime_sec();
3598
3599#undef COPYFIELD64
3600}
3601
3602__private_extern__ void
3603if_copy_traffic_class(struct ifnet *ifp,
3604    struct if_traffic_class *if_tc)
3605{
3606#define COPY_IF_TC_FIELD64_ATOMIC(fld) do {			\
3607	atomic_get_64(if_tc->fld,				\
3608	    (u_int64_t *)(void *)(uintptr_t)&ifp->if_tc.fld);	\
3609} while (0)
3610
3611	bzero(if_tc, sizeof (*if_tc));
3612	COPY_IF_TC_FIELD64_ATOMIC(ifi_ibepackets);
3613	COPY_IF_TC_FIELD64_ATOMIC(ifi_ibebytes);
3614	COPY_IF_TC_FIELD64_ATOMIC(ifi_obepackets);
3615	COPY_IF_TC_FIELD64_ATOMIC(ifi_obebytes);
3616	COPY_IF_TC_FIELD64_ATOMIC(ifi_ibkpackets);
3617	COPY_IF_TC_FIELD64_ATOMIC(ifi_ibkbytes);
3618	COPY_IF_TC_FIELD64_ATOMIC(ifi_obkpackets);
3619	COPY_IF_TC_FIELD64_ATOMIC(ifi_obkbytes);
3620	COPY_IF_TC_FIELD64_ATOMIC(ifi_ivipackets);
3621	COPY_IF_TC_FIELD64_ATOMIC(ifi_ivibytes);
3622	COPY_IF_TC_FIELD64_ATOMIC(ifi_ovipackets);
3623	COPY_IF_TC_FIELD64_ATOMIC(ifi_ovibytes);
3624	COPY_IF_TC_FIELD64_ATOMIC(ifi_ivopackets);
3625	COPY_IF_TC_FIELD64_ATOMIC(ifi_ivobytes);
3626	COPY_IF_TC_FIELD64_ATOMIC(ifi_ovopackets);
3627	COPY_IF_TC_FIELD64_ATOMIC(ifi_ovobytes);
3628	COPY_IF_TC_FIELD64_ATOMIC(ifi_ipvpackets);
3629	COPY_IF_TC_FIELD64_ATOMIC(ifi_ipvbytes);
3630	COPY_IF_TC_FIELD64_ATOMIC(ifi_opvpackets);
3631	COPY_IF_TC_FIELD64_ATOMIC(ifi_opvbytes);
3632
3633#undef COPY_IF_TC_FIELD64_ATOMIC
3634}
3635
3636void
3637if_copy_data_extended(struct ifnet *ifp, struct if_data_extended *if_de)
3638{
3639#define COPY_IF_DE_FIELD64_ATOMIC(fld) do {			\
3640	atomic_get_64(if_de->fld,				\
3641	    (u_int64_t *)(void *)(uintptr_t)&ifp->if_data.fld);	\
3642} while (0)
3643
3644	bzero(if_de, sizeof (*if_de));
3645	COPY_IF_DE_FIELD64_ATOMIC(ifi_alignerrs);
3646	COPY_IF_DE_FIELD64_ATOMIC(ifi_dt_bytes);
3647	COPY_IF_DE_FIELD64_ATOMIC(ifi_fpackets);
3648	COPY_IF_DE_FIELD64_ATOMIC(ifi_fbytes);
3649
3650#undef COPY_IF_DE_FIELD64_ATOMIC
3651}
3652
3653void
3654if_copy_packet_stats(struct ifnet *ifp, struct if_packet_stats *if_ps)
3655{
3656#define COPY_IF_PS_TCP_FIELD64_ATOMIC(fld) do {				\
3657	atomic_get_64(if_ps->ifi_tcp_##fld,				\
3658	    (u_int64_t *)(void *)(uintptr_t)&ifp->if_tcp_stat->fld);	\
3659} while (0)
3660
3661#define COPY_IF_PS_UDP_FIELD64_ATOMIC(fld) do {				\
3662	atomic_get_64(if_ps->ifi_udp_##fld,				\
3663	    (u_int64_t *)(void *)(uintptr_t)&ifp->if_udp_stat->fld);	\
3664} while (0)
3665
3666	COPY_IF_PS_TCP_FIELD64_ATOMIC(badformat);
3667	COPY_IF_PS_TCP_FIELD64_ATOMIC(unspecv6);
3668	COPY_IF_PS_TCP_FIELD64_ATOMIC(synfin);
3669	COPY_IF_PS_TCP_FIELD64_ATOMIC(badformatipsec);
3670	COPY_IF_PS_TCP_FIELD64_ATOMIC(noconnnolist);
3671	COPY_IF_PS_TCP_FIELD64_ATOMIC(noconnlist);
3672	COPY_IF_PS_TCP_FIELD64_ATOMIC(listbadsyn);
3673	COPY_IF_PS_TCP_FIELD64_ATOMIC(icmp6unreach);
3674	COPY_IF_PS_TCP_FIELD64_ATOMIC(deprecate6);
3675	COPY_IF_PS_TCP_FIELD64_ATOMIC(ooopacket);
3676	COPY_IF_PS_TCP_FIELD64_ATOMIC(rstinsynrcv);
3677	COPY_IF_PS_TCP_FIELD64_ATOMIC(dospacket);
3678	COPY_IF_PS_TCP_FIELD64_ATOMIC(cleanup);
3679	COPY_IF_PS_TCP_FIELD64_ATOMIC(synwindow);
3680
3681	COPY_IF_PS_UDP_FIELD64_ATOMIC(port_unreach);
3682	COPY_IF_PS_UDP_FIELD64_ATOMIC(faithprefix);
3683	COPY_IF_PS_UDP_FIELD64_ATOMIC(port0);
3684	COPY_IF_PS_UDP_FIELD64_ATOMIC(badlength);
3685	COPY_IF_PS_UDP_FIELD64_ATOMIC(badchksum);
3686	COPY_IF_PS_UDP_FIELD64_ATOMIC(badmcast);
3687	COPY_IF_PS_UDP_FIELD64_ATOMIC(cleanup);
3688	COPY_IF_PS_UDP_FIELD64_ATOMIC(badipsec);
3689
3690#undef COPY_IF_PS_TCP_FIELD64_ATOMIC
3691#undef COPY_IF_PS_UDP_FIELD64_ATOMIC
3692}
3693
3694void
3695if_copy_rxpoll_stats(struct ifnet *ifp, struct if_rxpoll_stats *if_rs)
3696{
3697	bzero(if_rs, sizeof (*if_rs));
3698	if (!(ifp->if_eflags & IFEF_RXPOLL) || !ifnet_is_attached(ifp, 1))
3699		return;
3700
3701	/* by now, ifnet will stay attached so if_inp must be valid */
3702	VERIFY(ifp->if_inp != NULL);
3703	bcopy(&ifp->if_inp->pstats, if_rs, sizeof (*if_rs));
3704
3705	/* Release the IO refcnt */
3706	ifnet_decr_iorefcnt(ifp);
3707}
3708
3709struct ifaddr *
3710ifa_remref(struct ifaddr *ifa, int locked)
3711{
3712	if (!locked)
3713		IFA_LOCK_SPIN(ifa);
3714	else
3715		IFA_LOCK_ASSERT_HELD(ifa);
3716
3717	if (ifa->ifa_refcnt == 0)
3718		panic("%s: ifa %p negative refcnt\n", __func__, ifa);
3719	else if (ifa->ifa_trace != NULL)
3720		(*ifa->ifa_trace)(ifa, FALSE);
3721	if (--ifa->ifa_refcnt == 0) {
3722		if (ifa->ifa_debug & IFD_ATTACHED)
3723			panic("ifa %p attached to ifp is being freed\n", ifa);
3724		/*
3725		 * Some interface addresses are allocated either statically
3726		 * or carved out of a larger block.  Only free it if it was
3727		 * allocated via MALLOC or via the corresponding per-address
3728		 * family allocator.  Otherwise, leave it alone.
3729		 */
3730		if (ifa->ifa_debug & IFD_ALLOC) {
3731			if (ifa->ifa_free == NULL) {
3732				IFA_UNLOCK(ifa);
3733				FREE(ifa, M_IFADDR);
3734			} else {
3735				/* Become a regular mutex */
3736				IFA_CONVERT_LOCK(ifa);
3737				/* callee will unlock */
3738				(*ifa->ifa_free)(ifa);
3739			}
3740		} else {
3741			IFA_UNLOCK(ifa);
3742		}
3743		ifa = NULL;
3744	}
3745
3746	if (!locked && ifa != NULL)
3747		IFA_UNLOCK(ifa);
3748
3749	return (ifa);
3750}
3751
3752void
3753ifa_addref(struct ifaddr *ifa, int locked)
3754{
3755	if (!locked)
3756		IFA_LOCK_SPIN(ifa);
3757	else
3758		IFA_LOCK_ASSERT_HELD(ifa);
3759
3760	if (++ifa->ifa_refcnt == 0) {
3761		panic("%s: ifa %p wraparound refcnt\n", __func__, ifa);
3762		/* NOTREACHED */
3763	} else if (ifa->ifa_trace != NULL) {
3764		(*ifa->ifa_trace)(ifa, TRUE);
3765	}
3766	if (!locked)
3767		IFA_UNLOCK(ifa);
3768}
3769
3770void
3771ifa_lock_init(struct ifaddr *ifa)
3772{
3773	lck_mtx_init(&ifa->ifa_lock, ifa_mtx_grp, ifa_mtx_attr);
3774}
3775
3776void
3777ifa_lock_destroy(struct ifaddr *ifa)
3778{
3779	IFA_LOCK_ASSERT_NOTHELD(ifa);
3780	lck_mtx_destroy(&ifa->ifa_lock, ifa_mtx_grp);
3781}
3782
3783/*
3784 * 'i' group ioctls.
3785 *
3786 * The switch statement below does nothing at runtime, as it serves as a
3787 * compile time check to ensure that all of the socket 'i' ioctls (those
3788 * in the 'i' group going thru soo_ioctl) that are made available by the
3789 * networking stack is unique.  This works as long as this routine gets
3790 * updated each time a new interface ioctl gets added.
3791 *
3792 * Any failures at compile time indicates duplicated ioctl values.
3793 */
3794static __attribute__((unused)) void
3795ifioctl_cassert(void)
3796{
3797	/*
3798	 * This is equivalent to _CASSERT() and the compiler wouldn't
3799	 * generate any instructions, thus for compile time only.
3800	 */
3801	switch ((u_long)0) {
3802	case 0:
3803
3804	/* bsd/net/if_ppp.h */
3805	case SIOCGPPPSTATS:
3806	case SIOCGPPPCSTATS:
3807
3808#if INET6
3809	/* bsd/netinet6/in6_var.h */
3810	case SIOCSIFADDR_IN6:
3811	case SIOCGIFADDR_IN6:
3812	case SIOCSIFDSTADDR_IN6:
3813	case SIOCSIFNETMASK_IN6:
3814	case SIOCGIFDSTADDR_IN6:
3815	case SIOCGIFNETMASK_IN6:
3816	case SIOCDIFADDR_IN6:
3817	case SIOCAIFADDR_IN6_32:
3818	case SIOCAIFADDR_IN6_64:
3819	case SIOCSIFPHYADDR_IN6_32:
3820	case SIOCSIFPHYADDR_IN6_64:
3821	case SIOCGIFPSRCADDR_IN6:
3822	case SIOCGIFPDSTADDR_IN6:
3823	case SIOCGIFAFLAG_IN6:
3824	case SIOCGDRLST_IN6_32:
3825	case SIOCGDRLST_IN6_64:
3826	case SIOCGPRLST_IN6_32:
3827	case SIOCGPRLST_IN6_64:
3828	case OSIOCGIFINFO_IN6:
3829	case SIOCGIFINFO_IN6:
3830	case SIOCSNDFLUSH_IN6:
3831	case SIOCGNBRINFO_IN6_32:
3832	case SIOCGNBRINFO_IN6_64:
3833	case SIOCSPFXFLUSH_IN6:
3834	case SIOCSRTRFLUSH_IN6:
3835	case SIOCGIFALIFETIME_IN6:
3836	case SIOCSIFALIFETIME_IN6:
3837	case SIOCGIFSTAT_IN6:
3838	case SIOCGIFSTAT_ICMP6:
3839	case SIOCSDEFIFACE_IN6_32:
3840	case SIOCSDEFIFACE_IN6_64:
3841	case SIOCGDEFIFACE_IN6_32:
3842	case SIOCGDEFIFACE_IN6_64:
3843	case SIOCSIFINFO_FLAGS:
3844	case SIOCSSCOPE6:
3845	case SIOCGSCOPE6:
3846	case SIOCGSCOPE6DEF:
3847	case SIOCSIFPREFIX_IN6:
3848	case SIOCGIFPREFIX_IN6:
3849	case SIOCDIFPREFIX_IN6:
3850	case SIOCAIFPREFIX_IN6:
3851	case SIOCCIFPREFIX_IN6:
3852	case SIOCSGIFPREFIX_IN6:
3853	case SIOCPROTOATTACH_IN6_32:
3854	case SIOCPROTOATTACH_IN6_64:
3855	case SIOCPROTODETACH_IN6:
3856	case SIOCLL_START_32:
3857	case SIOCLL_START_64:
3858	case SIOCLL_STOP:
3859	case SIOCAUTOCONF_START:
3860	case SIOCAUTOCONF_STOP:
3861	case SIOCSETROUTERMODE_IN6:
3862	case SIOCLL_CGASTART_32:
3863	case SIOCLL_CGASTART_64:
3864#endif /* INET6 */
3865
3866	/* bsd/sys/sockio.h */
3867	case SIOCSIFADDR:
3868	case OSIOCGIFADDR:
3869	case SIOCSIFDSTADDR:
3870	case OSIOCGIFDSTADDR:
3871	case SIOCSIFFLAGS:
3872	case SIOCGIFFLAGS:
3873	case OSIOCGIFBRDADDR:
3874	case SIOCSIFBRDADDR:
3875	case OSIOCGIFCONF32:
3876	case OSIOCGIFCONF64:
3877	case OSIOCGIFNETMASK:
3878	case SIOCSIFNETMASK:
3879	case SIOCGIFMETRIC:
3880	case SIOCSIFMETRIC:
3881	case SIOCDIFADDR:
3882	case SIOCAIFADDR:
3883	case SIOCALIFADDR:
3884	case SIOCGLIFADDR:
3885	case SIOCDLIFADDR:
3886	case SIOCGIFADDR:
3887	case SIOCGIFDSTADDR:
3888	case SIOCGIFBRDADDR:
3889	case SIOCGIFCONF32:
3890	case SIOCGIFCONF64:
3891	case SIOCGIFNETMASK:
3892	case SIOCAUTOADDR:
3893	case SIOCAUTONETMASK:
3894	case SIOCARPIPLL:
3895	case SIOCADDMULTI:
3896	case SIOCDELMULTI:
3897	case SIOCGIFMTU:
3898	case SIOCSIFMTU:
3899	case SIOCGIFPHYS:
3900	case SIOCSIFPHYS:
3901	case SIOCSIFMEDIA:
3902	case SIOCGIFMEDIA32:
3903	case SIOCGIFMEDIA64:
3904	case SIOCSIFGENERIC:
3905	case SIOCGIFGENERIC:
3906	case SIOCRSLVMULTI:
3907	case SIOCSIFLLADDR:
3908	case SIOCGIFSTATUS:
3909	case SIOCSIFPHYADDR:
3910	case SIOCGIFPSRCADDR:
3911	case SIOCGIFPDSTADDR:
3912	case SIOCDIFPHYADDR:
3913	case SIOCSLIFPHYADDR:
3914	case SIOCGLIFPHYADDR:
3915	case SIOCGIFDEVMTU:
3916	case SIOCSIFALTMTU:
3917	case SIOCGIFALTMTU:
3918	case SIOCSIFBOND:
3919	case SIOCGIFBOND:
3920	case SIOCPROTOATTACH:
3921	case SIOCPROTODETACH:
3922	case SIOCSIFCAP:
3923	case SIOCGIFCAP:
3924	case SIOCIFCREATE:
3925	case SIOCIFDESTROY:
3926	case SIOCIFCREATE2:
3927	case SIOCSDRVSPEC32:
3928	case SIOCGDRVSPEC32:
3929	case SIOCSDRVSPEC64:
3930	case SIOCGDRVSPEC64:
3931	case SIOCSIFVLAN:
3932	case SIOCGIFVLAN:
3933	case SIOCIFGCLONERS32:
3934	case SIOCIFGCLONERS64:
3935	case SIOCGIFASYNCMAP:
3936	case SIOCSIFASYNCMAP:
3937#if CONFIG_MACF_NET
3938	case SIOCGIFMAC:
3939	case SIOCSIFMAC:
3940#endif /* CONFIG_MACF_NET */
3941	case SIOCSIFKPI:
3942	case SIOCGIFKPI:
3943	case SIOCGIFWAKEFLAGS:
3944	case SIOCGIFGETRTREFCNT:
3945	case SIOCGIFLINKQUALITYMETRIC:
3946	case SIOCSIFOPPORTUNISTIC:
3947	case SIOCGIFOPPORTUNISTIC:
3948	case SIOCSETROUTERMODE:
3949	case SIOCGIFEFLAGS:
3950	case SIOCSIFDESC:
3951	case SIOCGIFDESC:
3952	case SIOCSIFLINKPARAMS:
3953	case SIOCGIFLINKPARAMS:
3954	case SIOCGIFQUEUESTATS:
3955	case SIOCSIFTHROTTLE:
3956	case SIOCGIFTHROTTLE:
3957	case SIOCSIFLOG:
3958	case SIOCGIFLOG:
3959	case SIOCGIFDELEGATE:
3960	case SIOCGIFLLADDR:
3961	case SIOCGIFTYPE:
3962		;
3963	}
3964}
3965