xref: /openbsd/sys/net/if.c (revision 404b540a)
1 /*	$OpenBSD: if.c,v 1.199 2009/08/12 15:58:20 henning Exp $	*/
2 /*	$NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $	*/
3 
4 /*
5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the project nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (c) 1980, 1986, 1993
35  *	The Regents of the University of California.  All rights reserved.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. Neither the name of the University nor the names of its contributors
46  *    may be used to endorse or promote products derived from this software
47  *    without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59  * SUCH DAMAGE.
60  *
61  *	@(#)if.c	8.3 (Berkeley) 1/4/94
62  */
63 
64 #include "bluetooth.h"
65 #include "bpfilter.h"
66 #include "bridge.h"
67 #include "carp.h"
68 #include "pf.h"
69 #include "trunk.h"
70 
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/mbuf.h>
74 #include <sys/proc.h>
75 #include <sys/socket.h>
76 #include <sys/socketvar.h>
77 #include <sys/protosw.h>
78 #include <sys/kernel.h>
79 #include <sys/ioctl.h>
80 #include <sys/domain.h>
81 #include <sys/sysctl.h>
82 
83 #include <net/if.h>
84 #include <net/if_dl.h>
85 #include <net/if_media.h>
86 #include <net/if_types.h>
87 #include <net/route.h>
88 #include <net/netisr.h>
89 
90 #ifdef INET
91 #include <netinet/in.h>
92 #include <netinet/in_var.h>
93 #include <netinet/if_ether.h>
94 #include <netinet/igmp.h>
95 #ifdef MROUTING
96 #include <netinet/ip_mroute.h>
97 #endif
98 #endif
99 
100 #ifdef INET6
101 #ifndef INET
102 #include <netinet/in.h>
103 #endif
104 #include <netinet6/in6_ifattach.h>
105 #include <netinet6/nd6.h>
106 #endif
107 
108 #if NBPFILTER > 0
109 #include <net/bpf.h>
110 #endif
111 
112 #if NTRUNK > 0
113 #include <net/if_trunk.h>
114 #endif
115 
116 #if NBRIDGE > 0
117 #include <net/if_bridge.h>
118 #endif
119 
120 #if NCARP > 0
121 #include <netinet/ip_carp.h>
122 #endif
123 
124 #if NPF > 0
125 #include <net/pfvar.h>
126 #endif
127 
128 void	if_attachsetup(struct ifnet *);
129 void	if_attachdomain1(struct ifnet *);
130 void	if_attach_common(struct ifnet *);
131 
132 int	ifqmaxlen = IFQ_MAXLEN;
133 
134 void	if_detach_queues(struct ifnet *, struct ifqueue *);
135 void	if_detached_start(struct ifnet *);
136 int	if_detached_ioctl(struct ifnet *, u_long, caddr_t);
137 int	if_detached_init(struct ifnet *);
138 void	if_detached_watchdog(struct ifnet *);
139 
140 int	if_getgroup(caddr_t, struct ifnet *);
141 int	if_getgroupmembers(caddr_t);
142 int	if_getgroupattribs(caddr_t);
143 int	if_setgroupattribs(caddr_t);
144 
145 int	if_clone_list(struct if_clonereq *);
146 struct if_clone	*if_clone_lookup(const char *, int *);
147 
148 void	if_congestion_clear(void *);
149 int	if_group_egress_build(void);
150 
151 TAILQ_HEAD(, ifg_group) ifg_head;
152 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
153 int if_cloners_count;
154 
155 struct timeout m_cltick_tmo;
156 int m_clticks;
157 
158 /*
159  * Record when the last timeout has been run.  If the delta is
160  * too high, m_cldrop() will notice and decrease the interface
161  * high water marks.
162  */
163 static void
164 m_cltick(void *arg)
165 {
166 	extern int ticks;
167 	extern void m_cltick(void *);
168 
169 	m_clticks = ticks;
170 	timeout_add(&m_cltick_tmo, 1);
171 }
172 
173 /*
174  * Network interface utility routines.
175  *
176  * Routines with ifa_ifwith* names take sockaddr *'s as
177  * parameters.
178  */
179 void
180 ifinit()
181 {
182 	static struct timeout if_slowtim;
183 
184 	timeout_set(&if_slowtim, if_slowtimo, &if_slowtim);
185 
186 	if_slowtimo(&if_slowtim);
187 
188 	timeout_set(&m_cltick_tmo, m_cltick, NULL);
189 	m_cltick(NULL);
190 }
191 
192 static int if_index = 0;
193 int if_indexlim = 0;
194 struct ifaddr **ifnet_addrs = NULL;
195 struct ifnet **ifindex2ifnet = NULL;
196 struct ifnet_head ifnet;
197 struct ifnet_head iftxlist = TAILQ_HEAD_INITIALIZER(iftxlist);
198 struct ifnet *lo0ifp;
199 
200 /*
201  * Attach an interface to the
202  * list of "active" interfaces.
203  */
204 void
205 if_attachsetup(struct ifnet *ifp)
206 {
207 	int wrapped = 0;
208 
209 	if (ifindex2ifnet == 0)
210 		if_index = 1;
211 	else {
212 		while (if_index < if_indexlim &&
213 		    ifindex2ifnet[if_index] != NULL) {
214 			if_index++;
215 			/*
216 			 * If we hit USHRT_MAX, we skip back to 1 since
217 			 * there are a number of places where the value
218 			 * of ifp->if_index or if_index itself is compared
219 			 * to or stored in an unsigned short.  By
220 			 * jumping back, we won't botch those assignments
221 			 * or comparisons.
222 			 */
223 			if (if_index == USHRT_MAX) {
224 				if_index = 1;
225 				/*
226 				 * However, if we have to jump back to 1
227 				 * *twice* without finding an empty
228 				 * slot in ifindex2ifnet[], then there
229 				 * there are too many (>65535) interfaces.
230 				 */
231 				if (wrapped++)
232 					panic("too many interfaces");
233 			}
234 		}
235 	}
236 	ifp->if_index = if_index;
237 
238 	/*
239 	 * We have some arrays that should be indexed by if_index.
240 	 * since if_index will grow dynamically, they should grow too.
241 	 *	struct ifaddr **ifnet_addrs
242 	 *	struct ifnet **ifindex2ifnet
243 	 */
244 	if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if_index >= if_indexlim) {
245 		size_t m, n, oldlim;
246 		caddr_t q;
247 
248 		oldlim = if_indexlim;
249 		if (if_indexlim == 0)
250 			if_indexlim = 8;
251 		while (if_index >= if_indexlim)
252 			if_indexlim <<= 1;
253 
254 		/* grow ifnet_addrs */
255 		m = oldlim * sizeof(struct ifaddr *);
256 		n = if_indexlim * sizeof(struct ifaddr *);
257 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
258 		if (ifnet_addrs) {
259 			bcopy((caddr_t)ifnet_addrs, q, m);
260 			free((caddr_t)ifnet_addrs, M_IFADDR);
261 		}
262 		ifnet_addrs = (struct ifaddr **)q;
263 
264 		/* grow ifindex2ifnet */
265 		m = oldlim * sizeof(struct ifnet *);
266 		n = if_indexlim * sizeof(struct ifnet *);
267 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
268 		if (ifindex2ifnet) {
269 			bcopy((caddr_t)ifindex2ifnet, q, m);
270 			free((caddr_t)ifindex2ifnet, M_IFADDR);
271 		}
272 		ifindex2ifnet = (struct ifnet **)q;
273 	}
274 
275 	TAILQ_INIT(&ifp->if_groups);
276 
277 	if_addgroup(ifp, IFG_ALL);
278 
279 	ifindex2ifnet[if_index] = ifp;
280 
281 	if (ifp->if_snd.ifq_maxlen == 0)
282 		ifp->if_snd.ifq_maxlen = ifqmaxlen;
283 #ifdef ALTQ
284 	ifp->if_snd.altq_type = 0;
285 	ifp->if_snd.altq_disc = NULL;
286 	ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
287 	ifp->if_snd.altq_tbr  = NULL;
288 	ifp->if_snd.altq_ifp  = ifp;
289 #endif
290 
291 	if (domains)
292 		if_attachdomain1(ifp);
293 #if NPF > 0
294 	pfi_attach_ifnet(ifp);
295 #endif
296 
297 	/* Announce the interface. */
298 	rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
299 }
300 
301 /*
302  * Allocate the link level name for the specified interface.  This
303  * is an attachment helper.  It must be called after ifp->if_addrlen
304  * is initialized, which may not be the case when if_attach() is
305  * called.
306  */
307 void
308 if_alloc_sadl(struct ifnet *ifp)
309 {
310 	unsigned int socksize, ifasize;
311 	int namelen, masklen;
312 	struct sockaddr_dl *sdl;
313 	struct ifaddr *ifa;
314 
315 	/*
316 	 * If the interface already has a link name, release it
317 	 * now.  This is useful for interfaces that can change
318 	 * link types, and thus switch link names often.
319 	 */
320 	if (ifp->if_sadl != NULL)
321 		if_free_sadl(ifp);
322 
323 	namelen = strlen(ifp->if_xname);
324 	masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
325 	socksize = masklen + ifp->if_addrlen;
326 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
327 	if (socksize < sizeof(*sdl))
328 		socksize = sizeof(*sdl);
329 	socksize = ROUNDUP(socksize);
330 	ifasize = sizeof(*ifa) + 2 * socksize;
331 	ifa = malloc(ifasize, M_IFADDR, M_WAITOK|M_ZERO);
332 	sdl = (struct sockaddr_dl *)(ifa + 1);
333 	sdl->sdl_len = socksize;
334 	sdl->sdl_family = AF_LINK;
335 	bcopy(ifp->if_xname, sdl->sdl_data, namelen);
336 	sdl->sdl_nlen = namelen;
337 	sdl->sdl_alen = ifp->if_addrlen;
338 	sdl->sdl_index = ifp->if_index;
339 	sdl->sdl_type = ifp->if_type;
340 	ifnet_addrs[ifp->if_index] = ifa;
341 	ifa->ifa_ifp = ifp;
342 	ifa->ifa_rtrequest = link_rtrequest;
343 	TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
344 	ifa->ifa_addr = (struct sockaddr *)sdl;
345 	ifp->if_sadl = sdl;
346 	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
347 	ifa->ifa_netmask = (struct sockaddr *)sdl;
348 	sdl->sdl_len = masklen;
349 	while (namelen != 0)
350 		sdl->sdl_data[--namelen] = 0xff;
351 }
352 
353 /*
354  * Free the link level name for the specified interface.  This is
355  * a detach helper.  This is called from if_detach() or from
356  * link layer type specific detach functions.
357  */
358 void
359 if_free_sadl(struct ifnet *ifp)
360 {
361 	struct ifaddr *ifa;
362 	int s;
363 
364 	ifa = ifnet_addrs[ifp->if_index];
365 	if (ifa == NULL)
366 		return;
367 
368 	s = splnet();
369 	rtinit(ifa, RTM_DELETE, 0);
370 #if 0
371 	TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
372 	ifnet_addrs[ifp->if_index] = NULL;
373 #endif
374 	ifp->if_sadl = NULL;
375 
376 	splx(s);
377 }
378 
379 void
380 if_attachdomain()
381 {
382 	struct ifnet *ifp;
383 	int s;
384 
385 	s = splnet();
386 	for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
387 		if_attachdomain1(ifp);
388 	splx(s);
389 }
390 
391 void
392 if_attachdomain1(struct ifnet *ifp)
393 {
394 	struct domain *dp;
395 	int s;
396 
397 	s = splnet();
398 
399 	/* address family dependent data region */
400 	bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
401 	for (dp = domains; dp; dp = dp->dom_next) {
402 		if (dp->dom_ifattach)
403 			ifp->if_afdata[dp->dom_family] =
404 			    (*dp->dom_ifattach)(ifp);
405 	}
406 
407 	splx(s);
408 }
409 
410 void
411 if_attachhead(struct ifnet *ifp)
412 {
413 	if_attach_common(ifp);
414 	TAILQ_INSERT_HEAD(&ifnet, ifp, if_list);
415 	if_attachsetup(ifp);
416 }
417 
418 void
419 if_attach(struct ifnet *ifp)
420 {
421 #if NCARP > 0
422 	struct ifnet *before = NULL;
423 #endif
424 
425 	if_attach_common(ifp);
426 
427 #if NCARP > 0
428 	if (ifp->if_type != IFT_CARP)
429 		TAILQ_FOREACH(before, &ifnet, if_list)
430 			if (before->if_type == IFT_CARP)
431 				break;
432 	if (before == NULL)
433 		TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
434 	else
435 		TAILQ_INSERT_BEFORE(before, ifp, if_list);
436 #else
437 	TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
438 #endif
439 
440 	m_clinitifp(ifp);
441 
442 	if_attachsetup(ifp);
443 }
444 
445 void
446 if_attach_common(struct ifnet *ifp)
447 {
448 
449 	if (if_index == 0) {
450 		TAILQ_INIT(&ifnet);
451 		TAILQ_INIT(&ifg_head);
452 	}
453 	TAILQ_INIT(&ifp->if_addrlist);
454 	ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
455 	    M_TEMP, M_NOWAIT);
456 	if (ifp->if_addrhooks == NULL)
457 		panic("if_attach_common: malloc");
458 	TAILQ_INIT(ifp->if_addrhooks);
459 	ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks),
460 	    M_TEMP, M_NOWAIT);
461 	if (ifp->if_linkstatehooks == NULL)
462 		panic("if_attach_common: malloc");
463 	TAILQ_INIT(ifp->if_linkstatehooks);
464 	ifp->if_detachhooks = malloc(sizeof(*ifp->if_detachhooks),
465 	    M_TEMP, M_NOWAIT);
466 	if (ifp->if_detachhooks == NULL)
467 		panic("if_attach_common: malloc");
468 	TAILQ_INIT(ifp->if_detachhooks);
469 }
470 
471 void
472 if_start(struct ifnet *ifp)
473 {
474 	if (ifp->if_snd.ifq_len >= min(8, ifp->if_snd.ifq_maxlen) &&
475 	    !ISSET(ifp->if_flags, IFF_OACTIVE)) {
476 		if (ISSET(ifp->if_xflags, IFXF_TXREADY)) {
477 			TAILQ_REMOVE(&iftxlist, ifp, if_txlist);
478 			CLR(ifp->if_xflags, IFXF_TXREADY);
479 		}
480 		ifp->if_start(ifp);
481 		return;
482 	}
483 
484 	if (!ISSET(ifp->if_xflags, IFXF_TXREADY)) {
485 		SET(ifp->if_xflags, IFXF_TXREADY);
486 		TAILQ_INSERT_TAIL(&iftxlist, ifp, if_txlist);
487 		schednetisr(NETISR_TX);
488 	}
489 }
490 
491 void
492 nettxintr(void)
493 {
494 	struct ifnet *ifp;
495 	int s;
496 
497 	s = splnet();
498 	while ((ifp = TAILQ_FIRST(&iftxlist)) != NULL) {
499 		TAILQ_REMOVE(&iftxlist, ifp, if_txlist);
500 		CLR(ifp->if_xflags, IFXF_TXREADY);
501 		ifp->if_start(ifp);
502 	}
503 	splx(s);
504 }
505 
506 /*
507  * Detach an interface from everything in the kernel.  Also deallocate
508  * private resources.
509  * XXX So far only the INET protocol family has been looked over
510  * wrt resource usage that needs to be decoupled.
511  */
512 void
513 if_detach(struct ifnet *ifp)
514 {
515 	struct ifaddr *ifa;
516 	struct ifg_list *ifg;
517 	int s = splnet();
518 	struct domain *dp;
519 
520 	ifp->if_flags &= ~IFF_OACTIVE;
521 	ifp->if_start = if_detached_start;
522 	ifp->if_ioctl = if_detached_ioctl;
523 	ifp->if_init = if_detached_init;
524 	ifp->if_watchdog = if_detached_watchdog;
525 
526 	/* Call detach hooks, ie. to remove vlan interfaces */
527 	dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE);
528 
529 #if NTRUNK > 0
530 	if (ifp->if_type == IFT_IEEE8023ADLAG)
531 		trunk_port_ifdetach(ifp);
532 #endif
533 
534 #if NBRIDGE > 0
535 	/* Remove the interface from any bridge it is part of.  */
536 	if (ifp->if_bridge)
537 		bridge_ifdetach(ifp);
538 #endif
539 
540 #if NCARP > 0
541 	/* Remove the interface from any carp group it is a part of.  */
542 	if (ifp->if_carp && ifp->if_type != IFT_CARP)
543 		carp_ifdetach(ifp);
544 #endif
545 
546 #if NBPFILTER > 0
547 	bpfdetach(ifp);
548 #endif
549 #ifdef ALTQ
550 	if (ALTQ_IS_ENABLED(&ifp->if_snd))
551 		altq_disable(&ifp->if_snd);
552 	if (ALTQ_IS_ATTACHED(&ifp->if_snd))
553 		altq_detach(&ifp->if_snd);
554 #endif
555 	rt_if_remove(ifp);
556 #ifdef INET
557 	rti_delete(ifp);
558 #if NETHER > 0
559 	myip_ifp = NULL;
560 #endif
561 #ifdef MROUTING
562 	vif_delete(ifp);
563 #endif
564 #endif
565 #ifdef INET6
566 	in6_ifdetach(ifp);
567 #endif
568 
569 #if NPF > 0
570 	pfi_detach_ifnet(ifp);
571 #endif
572 
573 	/*
574 	 * remove packets came from ifp, from software interrupt queues.
575 	 * net/netisr_dispatch.h is not usable, as some of them use
576 	 * strange queue names.
577 	 */
578 #define IF_DETACH_QUEUES(x) \
579 do { \
580 	extern struct ifqueue x; \
581 	if_detach_queues(ifp, & x); \
582 } while (0)
583 #ifdef INET
584 	IF_DETACH_QUEUES(arpintrq);
585 	IF_DETACH_QUEUES(ipintrq);
586 #endif
587 #ifdef INET6
588 	IF_DETACH_QUEUES(ip6intrq);
589 #endif
590 #ifdef NETATALK
591 	IF_DETACH_QUEUES(atintrq1);
592 	IF_DETACH_QUEUES(atintrq2);
593 #endif
594 #ifdef NATM
595 	IF_DETACH_QUEUES(natmintrq);
596 #endif
597 #undef IF_DETACH_QUEUES
598 
599 	/*
600 	 * XXX transient ifp refs?  inpcb.ip_moptions.imo_multicast_ifp?
601 	 * Other network stacks than INET?
602 	 */
603 
604 	/* Remove the interface from the list of all interfaces.  */
605 	TAILQ_REMOVE(&ifnet, ifp, if_list);
606 	if (ISSET(ifp->if_xflags, IFXF_TXREADY))
607 		TAILQ_REMOVE(&iftxlist, ifp, if_txlist);
608 
609 	/*
610 	 * Deallocate private resources.
611 	 */
612 	while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
613 		TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
614 #ifdef INET
615 		if (ifa->ifa_addr->sa_family == AF_INET)
616 			TAILQ_REMOVE(&in_ifaddr, (struct in_ifaddr *)ifa,
617 			    ia_list);
618 #endif
619 		/* XXX if_free_sadl needs this */
620 		if (ifa == ifnet_addrs[ifp->if_index])
621 			continue;
622 
623 		ifa->ifa_ifp = NULL;
624 		IFAFREE(ifa);
625 	}
626 
627 	for (ifg = TAILQ_FIRST(&ifp->if_groups); ifg;
628 	    ifg = TAILQ_FIRST(&ifp->if_groups))
629 		if_delgroup(ifp, ifg->ifgl_group->ifg_group);
630 
631 	if_free_sadl(ifp);
632 
633 	ifnet_addrs[ifp->if_index]->ifa_ifp = NULL;
634 	IFAFREE(ifnet_addrs[ifp->if_index]);
635 	ifnet_addrs[ifp->if_index] = NULL;
636 
637 	free(ifp->if_addrhooks, M_TEMP);
638 	free(ifp->if_linkstatehooks, M_TEMP);
639 	free(ifp->if_detachhooks, M_TEMP);
640 
641 	for (dp = domains; dp; dp = dp->dom_next) {
642 		if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
643 			(*dp->dom_ifdetach)(ifp,
644 			    ifp->if_afdata[dp->dom_family]);
645 	}
646 
647 	/* Announce that the interface is gone. */
648 	rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
649 
650 	ifindex2ifnet[ifp->if_index] = NULL;
651 	splx(s);
652 }
653 
654 void
655 if_detach_queues(struct ifnet *ifp, struct ifqueue *q)
656 {
657 	struct mbuf *m, *prev, *next;
658 
659 	prev = NULL;
660 	for (m = q->ifq_head; m; m = next) {
661 		next = m->m_nextpkt;
662 #ifdef DIAGNOSTIC
663 		if ((m->m_flags & M_PKTHDR) == 0) {
664 			prev = m;
665 			continue;
666 		}
667 #endif
668 		if (m->m_pkthdr.rcvif != ifp) {
669 			prev = m;
670 			continue;
671 		}
672 
673 		if (prev)
674 			prev->m_nextpkt = m->m_nextpkt;
675 		else
676 			q->ifq_head = m->m_nextpkt;
677 		if (q->ifq_tail == m)
678 			q->ifq_tail = prev;
679 		q->ifq_len--;
680 
681 		m->m_nextpkt = NULL;
682 		m_freem(m);
683 		IF_DROP(q);
684 	}
685 }
686 
687 /*
688  * Create a clone network interface.
689  */
690 int
691 if_clone_create(const char *name)
692 {
693 	struct if_clone *ifc;
694 	struct ifnet *ifp;
695 	int unit, ret;
696 
697 	ifc = if_clone_lookup(name, &unit);
698 	if (ifc == NULL)
699 		return (EINVAL);
700 
701 	if (ifunit(name) != NULL)
702 		return (EEXIST);
703 
704 	if ((ret = (*ifc->ifc_create)(ifc, unit)) == 0 &&
705 	    (ifp = ifunit(name)) != NULL)
706 		if_addgroup(ifp, ifc->ifc_name);
707 
708 	return (ret);
709 }
710 
711 /*
712  * Destroy a clone network interface.
713  */
714 int
715 if_clone_destroy(const char *name)
716 {
717 	struct if_clone *ifc;
718 	struct ifnet *ifp;
719 	int s, ret;
720 
721 	ifc = if_clone_lookup(name, NULL);
722 	if (ifc == NULL)
723 		return (EINVAL);
724 
725 	ifp = ifunit(name);
726 	if (ifp == NULL)
727 		return (ENXIO);
728 
729 	if (ifc->ifc_destroy == NULL)
730 		return (EOPNOTSUPP);
731 
732 	if (ifp->if_flags & IFF_UP) {
733 		s = splnet();
734 		if_down(ifp);
735 		splx(s);
736 	}
737 
738 	if_delgroup(ifp, ifc->ifc_name);
739 
740 	if ((ret = (*ifc->ifc_destroy)(ifp)) != 0)
741 		if_addgroup(ifp, ifc->ifc_name);
742 
743 	return (ret);
744 }
745 
746 /*
747  * Look up a network interface cloner.
748  */
749 struct if_clone *
750 if_clone_lookup(const char *name, int *unitp)
751 {
752 	struct if_clone *ifc;
753 	const char *cp;
754 	int unit;
755 
756 	/* separate interface name from unit */
757 	for (cp = name;
758 	    cp - name < IFNAMSIZ && *cp && (*cp < '0' || *cp > '9');
759 	    cp++)
760 		continue;
761 
762 	if (cp == name || cp - name == IFNAMSIZ || !*cp)
763 		return (NULL);	/* No name or unit number */
764 
765 	if (cp - name < IFNAMSIZ-1 && *cp == '0' && cp[1] != '\0')
766 		return (NULL);	/* unit number 0 padded */
767 
768 	LIST_FOREACH(ifc, &if_cloners, ifc_list) {
769 		if (strlen(ifc->ifc_name) == cp - name &&
770 		    !strncmp(name, ifc->ifc_name, cp - name))
771 			break;
772 	}
773 
774 	if (ifc == NULL)
775 		return (NULL);
776 
777 	unit = 0;
778 	while (cp - name < IFNAMSIZ && *cp) {
779 		if (*cp < '0' || *cp > '9' ||
780 		    unit > (INT_MAX - (*cp - '0')) / 10) {
781 			/* Bogus unit number. */
782 			return (NULL);
783 		}
784 		unit = (unit * 10) + (*cp++ - '0');
785 	}
786 
787 	if (unitp != NULL)
788 		*unitp = unit;
789 	return (ifc);
790 }
791 
792 /*
793  * Register a network interface cloner.
794  */
795 void
796 if_clone_attach(struct if_clone *ifc)
797 {
798 	LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
799 	if_cloners_count++;
800 }
801 
802 /*
803  * Unregister a network interface cloner.
804  */
805 void
806 if_clone_detach(struct if_clone *ifc)
807 {
808 
809 	LIST_REMOVE(ifc, ifc_list);
810 	if_cloners_count--;
811 }
812 
813 /*
814  * Provide list of interface cloners to userspace.
815  */
816 int
817 if_clone_list(struct if_clonereq *ifcr)
818 {
819 	char outbuf[IFNAMSIZ], *dst;
820 	struct if_clone *ifc;
821 	int count, error = 0;
822 
823 	ifcr->ifcr_total = if_cloners_count;
824 	if ((dst = ifcr->ifcr_buffer) == NULL) {
825 		/* Just asking how many there are. */
826 		return (0);
827 	}
828 
829 	if (ifcr->ifcr_count < 0)
830 		return (EINVAL);
831 
832 	count = (if_cloners_count < ifcr->ifcr_count) ?
833 	    if_cloners_count : ifcr->ifcr_count;
834 
835 	for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
836 	    ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
837 		bzero(outbuf, sizeof outbuf);
838 		strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
839 		error = copyout(outbuf, dst, IFNAMSIZ);
840 		if (error)
841 			break;
842 	}
843 
844 	return (error);
845 }
846 
847 /*
848  * set queue congestion marker and register timeout to clear it
849  */
850 void
851 if_congestion(struct ifqueue *ifq)
852 {
853 	/* Not currently needed, all callers check this */
854 	if (ifq->ifq_congestion)
855 		return;
856 
857 	ifq->ifq_congestion = malloc(sizeof(struct timeout), M_TEMP, M_NOWAIT);
858 	if (ifq->ifq_congestion == NULL)
859 		return;
860 	timeout_set(ifq->ifq_congestion, if_congestion_clear, ifq);
861 	timeout_add(ifq->ifq_congestion, hz / 100);
862 }
863 
864 /*
865  * clear the congestion flag
866  */
867 void
868 if_congestion_clear(void *arg)
869 {
870 	struct ifqueue *ifq = arg;
871 	struct timeout *to = ifq->ifq_congestion;
872 
873 	ifq->ifq_congestion = NULL;
874 	free(to, M_TEMP);
875 }
876 
877 /*
878  * Locate an interface based on a complete address.
879  */
880 /*ARGSUSED*/
881 struct ifaddr *
882 ifa_ifwithaddr(struct sockaddr *addr, u_int rdomain)
883 {
884 	struct ifnet *ifp;
885 	struct ifaddr *ifa;
886 
887 #define	equal(a1, a2)	\
888 	(bcmp((caddr_t)(a1), (caddr_t)(a2),	\
889 	((struct sockaddr *)(a1))->sa_len) == 0)
890 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
891 	    if (ifp->if_rdomain != rdomain)
892 		continue;
893 	    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
894 		if (ifa->ifa_addr->sa_family != addr->sa_family)
895 			continue;
896 		if (equal(addr, ifa->ifa_addr))
897 			return (ifa);
898 		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
899 		    /* IP6 doesn't have broadcast */
900 		    ifa->ifa_broadaddr->sa_len != 0 &&
901 		    equal(ifa->ifa_broadaddr, addr))
902 			return (ifa);
903 	    }
904 	}
905 	return (NULL);
906 }
907 /*
908  * Locate the point to point interface with a given destination address.
909  */
910 /*ARGSUSED*/
911 struct ifaddr *
912 ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain)
913 {
914 	struct ifnet *ifp;
915 	struct ifaddr *ifa;
916 
917 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
918 		if (ifp->if_rdomain != rdomain)
919 			continue;
920 		if (ifp->if_flags & IFF_POINTOPOINT)
921 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
922 				if (ifa->ifa_addr->sa_family !=
923 				    addr->sa_family || ifa->ifa_dstaddr == NULL)
924 					continue;
925 				if (equal(addr, ifa->ifa_dstaddr))
926 					return (ifa);
927 			}
928 	}
929 	return (NULL);
930 }
931 
932 /*
933  * Find an interface on a specific network.  If many, choice
934  * is most specific found.
935  */
936 struct ifaddr *
937 ifa_ifwithnet(struct sockaddr *addr, u_int rdomain)
938 {
939 	struct ifnet *ifp;
940 	struct ifaddr *ifa;
941 	struct ifaddr *ifa_maybe = 0;
942 	u_int af = addr->sa_family;
943 	char *addr_data = addr->sa_data, *cplim;
944 
945 	if (af == AF_LINK) {
946 		struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
947 		if (sdl->sdl_index && sdl->sdl_index < if_indexlim &&
948 		    ifindex2ifnet[sdl->sdl_index])
949 			return (ifnet_addrs[sdl->sdl_index]);
950 	}
951 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
952 		if (ifp->if_rdomain != rdomain)
953 			continue;
954 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
955 			char *cp, *cp2, *cp3;
956 
957 			if (ifa->ifa_addr->sa_family != af ||
958 			    ifa->ifa_netmask == 0)
959 				next: continue;
960 			cp = addr_data;
961 			cp2 = ifa->ifa_addr->sa_data;
962 			cp3 = ifa->ifa_netmask->sa_data;
963 			cplim = (char *)ifa->ifa_netmask +
964 				ifa->ifa_netmask->sa_len;
965 			while (cp3 < cplim)
966 				if ((*cp++ ^ *cp2++) & *cp3++)
967 				    /* want to continue for() loop */
968 					goto next;
969 			if (ifa_maybe == 0 ||
970 			    rn_refines((caddr_t)ifa->ifa_netmask,
971 			    (caddr_t)ifa_maybe->ifa_netmask))
972 				ifa_maybe = ifa;
973 		}
974 	}
975 	return (ifa_maybe);
976 }
977 
978 /*
979  * Find an interface using a specific address family
980  */
981 struct ifaddr *
982 ifa_ifwithaf(int af, u_int rdomain)
983 {
984 	struct ifnet *ifp;
985 	struct ifaddr *ifa;
986 
987 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
988 		if (ifp->if_rdomain != rdomain)
989 			continue;
990 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
991 			if (ifa->ifa_addr->sa_family == af)
992 				return (ifa);
993 		}
994 	}
995 	return (NULL);
996 }
997 
998 /*
999  * Find an interface address specific to an interface best matching
1000  * a given address.
1001  */
1002 struct ifaddr *
1003 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
1004 {
1005 	struct ifaddr *ifa;
1006 	char *cp, *cp2, *cp3;
1007 	char *cplim;
1008 	struct ifaddr *ifa_maybe = NULL;
1009 	u_int af = addr->sa_family;
1010 
1011 	if (af >= AF_MAX)
1012 		return (NULL);
1013 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1014 		if (ifa->ifa_addr->sa_family != af)
1015 			continue;
1016 		if (ifa_maybe == NULL)
1017 			ifa_maybe = ifa;
1018 		if (ifa->ifa_netmask == 0 || ifp->if_flags & IFF_POINTOPOINT) {
1019 			if (equal(addr, ifa->ifa_addr) ||
1020 			    (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
1021 				return (ifa);
1022 			continue;
1023 		}
1024 		cp = addr->sa_data;
1025 		cp2 = ifa->ifa_addr->sa_data;
1026 		cp3 = ifa->ifa_netmask->sa_data;
1027 		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
1028 		for (; cp3 < cplim; cp3++)
1029 			if ((*cp++ ^ *cp2++) & *cp3)
1030 				break;
1031 		if (cp3 == cplim)
1032 			return (ifa);
1033 	}
1034 	return (ifa_maybe);
1035 }
1036 
1037 /*
1038  * Default action when installing a route with a Link Level gateway.
1039  * Lookup an appropriate real ifa to point to.
1040  * This should be moved to /sys/net/link.c eventually.
1041  */
1042 void
1043 link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
1044 {
1045 	struct ifaddr *ifa;
1046 	struct sockaddr *dst;
1047 	struct ifnet *ifp;
1048 
1049 	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
1050 	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
1051 		return;
1052 	if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
1053 		ifa->ifa_refcnt++;
1054 		IFAFREE(rt->rt_ifa);
1055 		rt->rt_ifa = ifa;
1056 		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
1057 			ifa->ifa_rtrequest(cmd, rt, info);
1058 	}
1059 }
1060 
1061 /*
1062  * Bring down all interfaces
1063  */
1064 void
1065 if_downall(void)
1066 {
1067 	struct ifreq ifrq;	/* XXX only partly built */
1068 	struct ifnet *ifp;
1069 	int s;
1070 
1071 	s = splnet();
1072 	for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
1073 		if ((ifp->if_flags & IFF_UP) == 0)
1074 			continue;
1075 		if_down(ifp);
1076 		ifp->if_flags &= ~IFF_UP;
1077 
1078 		if (ifp->if_ioctl) {
1079 			ifrq.ifr_flags = ifp->if_flags;
1080 			(void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
1081 			    (caddr_t)&ifrq);
1082 		}
1083 	}
1084 	splx(s);
1085 }
1086 
1087 /*
1088  * Mark an interface down and notify protocols of
1089  * the transition.
1090  * NOTE: must be called at splsoftnet or equivalent.
1091  */
1092 void
1093 if_down(struct ifnet *ifp)
1094 {
1095 	struct ifaddr *ifa;
1096 
1097 	splsoftassert(IPL_SOFTNET);
1098 
1099 	ifp->if_flags &= ~IFF_UP;
1100 	microtime(&ifp->if_lastchange);
1101 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1102 		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
1103 	}
1104 	IFQ_PURGE(&ifp->if_snd);
1105 #if NCARP > 0
1106 	if (ifp->if_carp)
1107 		carp_carpdev_state(ifp);
1108 #endif
1109 #if NBRIDGE > 0
1110 	if (ifp->if_bridge)
1111 		bstp_ifstate(ifp);
1112 #endif
1113 	rt_ifmsg(ifp);
1114 #ifndef SMALL_KERNEL
1115 	rt_if_track(ifp);
1116 #endif
1117 }
1118 
1119 /*
1120  * Mark an interface up and notify protocols of
1121  * the transition.
1122  * NOTE: must be called at splsoftnet or equivalent.
1123  */
1124 void
1125 if_up(struct ifnet *ifp)
1126 {
1127 #ifdef notyet
1128 	struct ifaddr *ifa;
1129 #endif
1130 
1131 	splsoftassert(IPL_SOFTNET);
1132 
1133 	ifp->if_flags |= IFF_UP;
1134 	microtime(&ifp->if_lastchange);
1135 #ifdef notyet
1136 	/* this has no effect on IP, and will kill all ISO connections XXX */
1137 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1138 		pfctlinput(PRC_IFUP, ifa->ifa_addr);
1139 	}
1140 #endif
1141 #if NCARP > 0
1142 	if (ifp->if_carp)
1143 		carp_carpdev_state(ifp);
1144 #endif
1145 #if NBRIDGE > 0
1146 	if (ifp->if_bridge)
1147 		bstp_ifstate(ifp);
1148 #endif
1149 	rt_ifmsg(ifp);
1150 #ifdef INET6
1151 	if (!(ifp->if_xflags & IFXF_NOINET6))
1152 		in6_if_up(ifp);
1153 #endif
1154 
1155 #ifndef SMALL_KERNEL
1156 	rt_if_track(ifp);
1157 #endif
1158 
1159 	m_clinitifp(ifp);
1160 }
1161 
1162 /*
1163  * Process a link state change.
1164  * NOTE: must be called at splsoftnet or equivalent.
1165  */
1166 void
1167 if_link_state_change(struct ifnet *ifp)
1168 {
1169 	rt_ifmsg(ifp);
1170 #ifndef SMALL_KERNEL
1171 	rt_if_track(ifp);
1172 #endif
1173 	dohooks(ifp->if_linkstatehooks, 0);
1174 }
1175 
1176 /*
1177  * Flush an interface queue.
1178  */
1179 void
1180 if_qflush(struct ifqueue *ifq)
1181 {
1182 	struct mbuf *m, *n;
1183 
1184 	n = ifq->ifq_head;
1185 	while ((m = n) != NULL) {
1186 		n = m->m_act;
1187 		m_freem(m);
1188 	}
1189 	ifq->ifq_head = 0;
1190 	ifq->ifq_tail = 0;
1191 	ifq->ifq_len = 0;
1192 }
1193 
1194 /*
1195  * Handle interface watchdog timer routines.  Called
1196  * from softclock, we decrement timers (if set) and
1197  * call the appropriate interface routine on expiration.
1198  */
1199 void
1200 if_slowtimo(void *arg)
1201 {
1202 	struct timeout *to = (struct timeout *)arg;
1203 	struct ifnet *ifp;
1204 	int s = splnet();
1205 
1206 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
1207 		if (ifp->if_timer == 0 || --ifp->if_timer)
1208 			continue;
1209 		if (ifp->if_watchdog)
1210 			(*ifp->if_watchdog)(ifp);
1211 	}
1212 	splx(s);
1213 	timeout_add(to, hz / IFNET_SLOWHZ);
1214 }
1215 
1216 /*
1217  * Map interface name to
1218  * interface structure pointer.
1219  */
1220 struct ifnet *
1221 ifunit(const char *name)
1222 {
1223 	struct ifnet *ifp;
1224 
1225 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
1226 		if (strcmp(ifp->if_xname, name) == 0)
1227 			return (ifp);
1228 	}
1229 	return (NULL);
1230 }
1231 
1232 /*
1233  * Interface ioctls.
1234  */
1235 int
1236 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1237 {
1238 	struct ifnet *ifp;
1239 	struct ifreq *ifr;
1240 	struct ifaddr *ifa, *nifa;
1241 	struct sockaddr_dl *sdl;
1242 	struct ifgroupreq *ifgr;
1243 	char ifdescrbuf[IFDESCRSIZE];
1244 	char ifrtlabelbuf[RTLABEL_LEN];
1245 	int error = 0;
1246 	size_t bytesdone;
1247 	short oif_flags;
1248 	const char *label;
1249 
1250 	switch (cmd) {
1251 
1252 	case SIOCGIFCONF:
1253 	case OSIOCGIFCONF:
1254 		return (ifconf(cmd, data));
1255 	}
1256 	ifr = (struct ifreq *)data;
1257 
1258 	switch (cmd) {
1259 	case SIOCIFCREATE:
1260 	case SIOCIFDESTROY:
1261 		if ((error = suser(p, 0)) != 0)
1262 			return (error);
1263 		return ((cmd == SIOCIFCREATE) ?
1264 		    if_clone_create(ifr->ifr_name) :
1265 		    if_clone_destroy(ifr->ifr_name));
1266 	case SIOCIFGCLONERS:
1267 		return (if_clone_list((struct if_clonereq *)data));
1268 	case SIOCGIFGMEMB:
1269 		return (if_getgroupmembers(data));
1270 	case SIOCGIFGATTR:
1271 		return (if_getgroupattribs(data));
1272 	case SIOCSIFGATTR:
1273 		if ((error = suser(p, 0)) != 0)
1274 			return (error);
1275 		return (if_setgroupattribs(data));
1276 	}
1277 
1278 	ifp = ifunit(ifr->ifr_name);
1279 	if (ifp == 0)
1280 		return (ENXIO);
1281 	oif_flags = ifp->if_flags;
1282 	switch (cmd) {
1283 
1284 	case SIOCGIFFLAGS:
1285 		ifr->ifr_flags = ifp->if_flags;
1286 		break;
1287 
1288 	case SIOCGIFXFLAGS:
1289 		ifr->ifr_flags = ifp->if_xflags;
1290 		break;
1291 
1292 	case SIOCGIFMETRIC:
1293 		ifr->ifr_metric = ifp->if_metric;
1294 		break;
1295 
1296 	case SIOCGIFMTU:
1297 		ifr->ifr_mtu = ifp->if_mtu;
1298 		break;
1299 
1300 	case SIOCGIFDATA:
1301 		error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
1302 		    sizeof(ifp->if_data));
1303 		break;
1304 
1305 	case SIOCSIFFLAGS:
1306 		if ((error = suser(p, 0)) != 0)
1307 			return (error);
1308 		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
1309 			int s = splnet();
1310 			if_down(ifp);
1311 			splx(s);
1312 		}
1313 		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
1314 			int s = splnet();
1315 			if_up(ifp);
1316 			splx(s);
1317 		}
1318 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
1319 			(ifr->ifr_flags &~ IFF_CANTCHANGE);
1320 		if (ifp->if_ioctl)
1321 			(void) (*ifp->if_ioctl)(ifp, cmd, data);
1322 		break;
1323 
1324 	case SIOCSIFXFLAGS:
1325 		if ((error = suser(p, 0)) != 0)
1326 			return (error);
1327 
1328 #ifdef INET6
1329 		/* when IFXF_NOINET6 gets changed, detach/attach */
1330 		if (ifp->if_flags & IFF_UP && ifr->ifr_flags & IFXF_NOINET6 &&
1331 		    !(ifp->if_xflags & IFXF_NOINET6))
1332 			in6_ifdetach(ifp);
1333 		if (ifp->if_flags & IFF_UP && ifp->if_xflags & IFXF_NOINET6 &&
1334 		    !(ifr->ifr_flags & IFXF_NOINET6)) {
1335 			ifp->if_xflags &= ~IFXF_NOINET6;
1336 			in6_if_up(ifp);
1337 		}
1338 #endif
1339 
1340 		ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
1341 			(ifr->ifr_flags &~ IFXF_CANTCHANGE);
1342 		rt_ifmsg(ifp);
1343 		break;
1344 
1345 	case SIOCSIFMETRIC:
1346 		if ((error = suser(p, 0)) != 0)
1347 			return (error);
1348 		ifp->if_metric = ifr->ifr_metric;
1349 		break;
1350 
1351 	case SIOCSIFMTU:
1352 	{
1353 #ifdef INET6
1354 		int oldmtu = ifp->if_mtu;
1355 #endif
1356 
1357 		if ((error = suser(p, 0)) != 0)
1358 			return (error);
1359 		if (ifp->if_ioctl == NULL)
1360 			return (EOPNOTSUPP);
1361 		error = (*ifp->if_ioctl)(ifp, cmd, data);
1362 
1363 		/*
1364 		 * If the link MTU changed, do network layer specific procedure.
1365 		 */
1366 #ifdef INET6
1367 		if (ifp->if_mtu != oldmtu)
1368 			nd6_setmtu(ifp);
1369 #endif
1370 		break;
1371 	}
1372 
1373 	case SIOCSIFPHYADDR:
1374 	case SIOCDIFPHYADDR:
1375 #ifdef INET6
1376 	case SIOCSIFPHYADDR_IN6:
1377 #endif
1378 	case SIOCSLIFPHYADDR:
1379 	case SIOCADDMULTI:
1380 	case SIOCDELMULTI:
1381 	case SIOCSIFMEDIA:
1382 		if ((error = suser(p, 0)) != 0)
1383 			return (error);
1384 		/* FALLTHROUGH */
1385 	case SIOCGIFPSRCADDR:
1386 	case SIOCGIFPDSTADDR:
1387 	case SIOCGLIFPHYADDR:
1388 	case SIOCGIFMEDIA:
1389 		if (ifp->if_ioctl == 0)
1390 			return (EOPNOTSUPP);
1391 		error = (*ifp->if_ioctl)(ifp, cmd, data);
1392 		break;
1393 
1394 	case SIOCGIFDESCR:
1395 		strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
1396 		error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
1397 		    &bytesdone);
1398 		break;
1399 
1400 	case SIOCSIFDESCR:
1401 		if ((error = suser(p, 0)) != 0)
1402 			return (error);
1403 		error = copyinstr(ifr->ifr_data, ifdescrbuf,
1404 		    IFDESCRSIZE, &bytesdone);
1405 		if (error == 0) {
1406 			(void)memset(ifp->if_description, 0, IFDESCRSIZE);
1407 			strlcpy(ifp->if_description, ifdescrbuf, IFDESCRSIZE);
1408 		}
1409 		break;
1410 
1411 	case SIOCGIFRTLABEL:
1412 		if (ifp->if_rtlabelid &&
1413 		    (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) {
1414 			strlcpy(ifrtlabelbuf, label, RTLABEL_LEN);
1415 			error = copyoutstr(ifrtlabelbuf, ifr->ifr_data,
1416 			    RTLABEL_LEN, &bytesdone);
1417 		} else
1418 			error = ENOENT;
1419 		break;
1420 
1421 	case SIOCSIFRTLABEL:
1422 		if ((error = suser(p, 0)) != 0)
1423 			return (error);
1424 		error = copyinstr(ifr->ifr_data, ifrtlabelbuf,
1425 		    RTLABEL_LEN, &bytesdone);
1426 		if (error == 0) {
1427 			rtlabel_unref(ifp->if_rtlabelid);
1428 			ifp->if_rtlabelid = rtlabel_name2id(ifrtlabelbuf);
1429 		}
1430 		break;
1431 
1432 	case SIOCGIFPRIORITY:
1433 		ifr->ifr_metric = ifp->if_priority;
1434 		break;
1435 
1436 	case SIOCSIFPRIORITY:
1437 		if ((error = suser(p, 0)) != 0)
1438 			return (error);
1439 		if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15)
1440 			return (EINVAL);
1441 		ifp->if_priority = ifr->ifr_metric;
1442 		break;
1443 
1444 	case SIOCGIFRTABLEID:
1445 		ifr->ifr_rdomainid = ifp->if_rdomain;
1446 		break;
1447 
1448 	case SIOCSIFRTABLEID:
1449 		if ((error = suser(p, 0)) != 0)
1450 			return (error);
1451 		if (ifr->ifr_rdomainid < 0 ||
1452 		    ifr->ifr_rdomainid > RT_TABLEID_MAX)
1453 			return (EINVAL);
1454 		/* remove all routing entries when switching domains */
1455 		/* XXX hell this is ugly */
1456 		if (ifr->ifr_rdomainid != ifp->if_rdomain) {
1457 			rt_if_remove(ifp);
1458 #ifdef INET
1459 			rti_delete(ifp);
1460 #if NETHER > 0
1461 			myip_ifp = NULL;
1462 #endif
1463 #ifdef MROUTING
1464 			vif_delete(ifp);
1465 #endif
1466 #endif
1467 #ifdef INET6
1468 			in6_ifdetach(ifp);
1469 #endif
1470 #ifdef INET
1471 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
1472 			    ifa = nifa) {
1473 				nifa = TAILQ_NEXT(ifa, ifa_list);
1474 
1475 				/* only remove AF_INET */
1476 				if (ifa->ifa_addr->sa_family != AF_INET)
1477 					continue;
1478 
1479 				TAILQ_REMOVE(&in_ifaddr,
1480 				    (struct in_ifaddr *)ifa, ia_list);
1481 				TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
1482 				ifa->ifa_ifp = NULL;
1483 				IFAFREE(ifa);
1484 			}
1485 #endif
1486 		}
1487 
1488 		/* make sure that the routing table exists */
1489 		if (!rtable_exists(ifr->ifr_rdomainid)) {
1490 			if (rtable_add(ifr->ifr_rdomainid) == -1)
1491 				panic("rtinit: rtable_add");
1492 		}
1493 
1494 		ifp->if_rdomain = ifr->ifr_rdomainid;
1495 		break;
1496 
1497 	case SIOCAIFGROUP:
1498 		if ((error = suser(p, 0)))
1499 			return (error);
1500 		(*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */
1501 		ifgr = (struct ifgroupreq *)data;
1502 		if ((error = if_addgroup(ifp, ifgr->ifgr_group)))
1503 			return (error);
1504 		break;
1505 
1506 	case SIOCGIFGROUP:
1507 		if ((error = if_getgroup(data, ifp)))
1508 			return (error);
1509 		break;
1510 
1511 	case SIOCDIFGROUP:
1512 		if ((error = suser(p, 0)))
1513 			return (error);
1514 		(*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */
1515 		ifgr = (struct ifgroupreq *)data;
1516 		if ((error = if_delgroup(ifp, ifgr->ifgr_group)))
1517 			return (error);
1518 		break;
1519 
1520 	case SIOCSIFLLADDR:
1521 		if ((error = suser(p, 0)))
1522 			return (error);
1523 		ifa = ifnet_addrs[ifp->if_index];
1524 		if (ifa == NULL)
1525 			return (EINVAL);
1526 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1527 		if (sdl == NULL)
1528 			return (EINVAL);
1529 		if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN)
1530 			return (EINVAL);
1531 		if (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data))
1532 			return (EINVAL);
1533 		switch (ifp->if_type) {
1534 		case IFT_ETHER:
1535 		case IFT_CARP:
1536 		case IFT_FDDI:
1537 		case IFT_XETHER:
1538 		case IFT_ISO88025:
1539 		case IFT_L2VLAN:
1540 			bcopy((caddr_t)ifr->ifr_addr.sa_data,
1541 			    (caddr_t)((struct arpcom *)ifp)->ac_enaddr,
1542 			    ETHER_ADDR_LEN);
1543 			bcopy((caddr_t)ifr->ifr_addr.sa_data,
1544 			    LLADDR(sdl), ETHER_ADDR_LEN);
1545 			break;
1546 		default:
1547 			return (ENODEV);
1548 		}
1549 		if (ifp->if_flags & IFF_UP) {
1550 			struct ifreq ifrq;
1551 			int s = splnet();
1552 			ifp->if_flags &= ~IFF_UP;
1553 			ifrq.ifr_flags = ifp->if_flags;
1554 			(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
1555 			ifp->if_flags |= IFF_UP;
1556 			ifrq.ifr_flags = ifp->if_flags;
1557 			(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
1558 			splx(s);
1559 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1560 				if (ifa->ifa_addr != NULL &&
1561 				    ifa->ifa_addr->sa_family == AF_INET)
1562 					arp_ifinit((struct arpcom *)ifp, ifa);
1563 			}
1564 		}
1565 		break;
1566 
1567 	default:
1568 		if (so->so_proto == 0)
1569 			return (EOPNOTSUPP);
1570 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
1571 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1572 			(struct mbuf *) cmd, (struct mbuf *) data,
1573 			(struct mbuf *) ifp, p));
1574 #else
1575 	    {
1576 		u_long ocmd = cmd;
1577 
1578 		switch (cmd) {
1579 
1580 		case SIOCSIFADDR:
1581 		case SIOCSIFDSTADDR:
1582 		case SIOCSIFBRDADDR:
1583 		case SIOCSIFNETMASK:
1584 #if BYTE_ORDER != BIG_ENDIAN
1585 			if (ifr->ifr_addr.sa_family == 0 &&
1586 			    ifr->ifr_addr.sa_len < 16) {
1587 				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1588 				ifr->ifr_addr.sa_len = 16;
1589 			}
1590 #else
1591 			if (ifr->ifr_addr.sa_len == 0)
1592 				ifr->ifr_addr.sa_len = 16;
1593 #endif
1594 			break;
1595 
1596 		case OSIOCGIFADDR:
1597 			cmd = SIOCGIFADDR;
1598 			break;
1599 
1600 		case OSIOCGIFDSTADDR:
1601 			cmd = SIOCGIFDSTADDR;
1602 			break;
1603 
1604 		case OSIOCGIFBRDADDR:
1605 			cmd = SIOCGIFBRDADDR;
1606 			break;
1607 
1608 		case OSIOCGIFNETMASK:
1609 			cmd = SIOCGIFNETMASK;
1610 		}
1611 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1612 		    (struct mbuf *) cmd, (struct mbuf *) data,
1613 		    (struct mbuf *) ifp, p));
1614 		switch (ocmd) {
1615 
1616 		case OSIOCGIFADDR:
1617 		case OSIOCGIFDSTADDR:
1618 		case OSIOCGIFBRDADDR:
1619 		case OSIOCGIFNETMASK:
1620 			*(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1621 		}
1622 
1623 	    }
1624 #endif
1625 		break;
1626 	}
1627 
1628 	if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1629 		microtime(&ifp->if_lastchange);
1630 #ifdef INET6
1631 		if (!(ifp->if_xflags & IFXF_NOINET6) &&
1632 		    (ifp->if_flags & IFF_UP) != 0) {
1633 			int s = splnet();
1634 			in6_if_up(ifp);
1635 			splx(s);
1636 		}
1637 #endif
1638 	}
1639 	return (error);
1640 }
1641 
1642 /*
1643  * Return interface configuration
1644  * of system.  List may be used
1645  * in later ioctl's (above) to get
1646  * other information.
1647  */
1648 /*ARGSUSED*/
1649 int
1650 ifconf(u_long cmd, caddr_t data)
1651 {
1652 	struct ifconf *ifc = (struct ifconf *)data;
1653 	struct ifnet *ifp;
1654 	struct ifaddr *ifa;
1655 	struct ifreq ifr, *ifrp;
1656 	int space = ifc->ifc_len, error = 0;
1657 
1658 	/* If ifc->ifc_len is 0, fill it in with the needed size and return. */
1659 	if (space == 0) {
1660 		TAILQ_FOREACH(ifp, &ifnet, if_list) {
1661 			struct sockaddr *sa;
1662 
1663 			if (TAILQ_EMPTY(&ifp->if_addrlist))
1664 				space += sizeof (ifr);
1665 			else
1666 				TAILQ_FOREACH(ifa,
1667 				    &ifp->if_addrlist, ifa_list) {
1668 					sa = ifa->ifa_addr;
1669 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1670 					if (cmd != OSIOCGIFCONF)
1671 #endif
1672 					if (sa->sa_len > sizeof(*sa))
1673 						space += sa->sa_len -
1674 						    sizeof(*sa);
1675 					space += sizeof(ifr);
1676 				}
1677 		}
1678 		ifc->ifc_len = space;
1679 		return (0);
1680 	}
1681 
1682 	ifrp = ifc->ifc_req;
1683 	for (ifp = TAILQ_FIRST(&ifnet); space >= sizeof(ifr) &&
1684 	    ifp != TAILQ_END(&ifnet); ifp = TAILQ_NEXT(ifp, if_list)) {
1685 		bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1686 		if (TAILQ_EMPTY(&ifp->if_addrlist)) {
1687 			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1688 			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1689 			    sizeof(ifr));
1690 			if (error)
1691 				break;
1692 			space -= sizeof (ifr), ifrp++;
1693 		} else
1694 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist);
1695 			    space >= sizeof (ifr) &&
1696 			    ifa != TAILQ_END(&ifp->if_addrlist);
1697 			    ifa = TAILQ_NEXT(ifa, ifa_list)) {
1698 				struct sockaddr *sa = ifa->ifa_addr;
1699 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1700 				if (cmd == OSIOCGIFCONF) {
1701 					struct osockaddr *osa =
1702 					    (struct osockaddr *)&ifr.ifr_addr;
1703 					ifr.ifr_addr = *sa;
1704 					osa->sa_family = sa->sa_family;
1705 					error = copyout((caddr_t)&ifr,
1706 					    (caddr_t)ifrp, sizeof (ifr));
1707 					ifrp++;
1708 				} else
1709 #endif
1710 				if (sa->sa_len <= sizeof(*sa)) {
1711 					ifr.ifr_addr = *sa;
1712 					error = copyout((caddr_t)&ifr,
1713 					    (caddr_t)ifrp, sizeof (ifr));
1714 					ifrp++;
1715 				} else {
1716 					space -= sa->sa_len - sizeof(*sa);
1717 					if (space < sizeof (ifr))
1718 						break;
1719 					error = copyout((caddr_t)&ifr,
1720 					    (caddr_t)ifrp,
1721 					    sizeof(ifr.ifr_name));
1722 					if (error == 0)
1723 						error = copyout((caddr_t)sa,
1724 						    (caddr_t)&ifrp->ifr_addr,
1725 						    sa->sa_len);
1726 					ifrp = (struct ifreq *)(sa->sa_len +
1727 					    (caddr_t)&ifrp->ifr_addr);
1728 				}
1729 				if (error)
1730 					break;
1731 				space -= sizeof (ifr);
1732 			}
1733 	}
1734 	ifc->ifc_len -= space;
1735 	return (error);
1736 }
1737 
1738 /*
1739  * Dummy functions replaced in ifnet during detach (if protocols decide to
1740  * fiddle with the if during detach.
1741  */
1742 void
1743 if_detached_start(struct ifnet *ifp)
1744 {
1745 	struct mbuf *m;
1746 
1747 	while (1) {
1748 		IF_DEQUEUE(&ifp->if_snd, m);
1749 
1750 		if (m == NULL)
1751 			return;
1752 		m_freem(m);
1753 	}
1754 }
1755 
1756 int
1757 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
1758 {
1759 	return ENODEV;
1760 }
1761 
1762 int
1763 if_detached_init(struct ifnet *ifp)
1764 {
1765 	return (ENXIO);
1766 }
1767 
1768 void
1769 if_detached_watchdog(struct ifnet *ifp)
1770 {
1771 	/* nothing */
1772 }
1773 
1774 /*
1775  * Create interface group without members
1776  */
1777 struct ifg_group *
1778 if_creategroup(const char *groupname)
1779 {
1780 	struct ifg_group	*ifg;
1781 
1782 	if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL)
1783 		return (NULL);
1784 
1785 	strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
1786 	ifg->ifg_refcnt = 0;
1787 	ifg->ifg_carp_demoted = 0;
1788 	TAILQ_INIT(&ifg->ifg_members);
1789 #if NPF > 0
1790 	pfi_attach_ifgroup(ifg);
1791 #endif
1792 	TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next);
1793 
1794 	return (ifg);
1795 }
1796 
1797 /*
1798  * Add a group to an interface
1799  */
1800 int
1801 if_addgroup(struct ifnet *ifp, const char *groupname)
1802 {
1803 	struct ifg_list		*ifgl;
1804 	struct ifg_group	*ifg = NULL;
1805 	struct ifg_member	*ifgm;
1806 
1807 	if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' &&
1808 	    groupname[strlen(groupname) - 1] <= '9')
1809 		return (EINVAL);
1810 
1811 	TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
1812 		if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
1813 			return (EEXIST);
1814 
1815 	if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL)
1816 		return (ENOMEM);
1817 
1818 	if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) {
1819 		free(ifgl, M_TEMP);
1820 		return (ENOMEM);
1821 	}
1822 
1823 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1824 		if (!strcmp(ifg->ifg_group, groupname))
1825 			break;
1826 
1827 	if (ifg == NULL && (ifg = if_creategroup(groupname)) == NULL) {
1828 		free(ifgl, M_TEMP);
1829 		free(ifgm, M_TEMP);
1830 		return (ENOMEM);
1831 	}
1832 
1833 	ifg->ifg_refcnt++;
1834 	ifgl->ifgl_group = ifg;
1835 	ifgm->ifgm_ifp = ifp;
1836 
1837 	TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next);
1838 	TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next);
1839 
1840 #if NPF > 0
1841 	pfi_group_change(groupname);
1842 #endif
1843 
1844 	return (0);
1845 }
1846 
1847 /*
1848  * Remove a group from an interface
1849  */
1850 int
1851 if_delgroup(struct ifnet *ifp, const char *groupname)
1852 {
1853 	struct ifg_list		*ifgl;
1854 	struct ifg_member	*ifgm;
1855 
1856 	TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
1857 		if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
1858 			break;
1859 	if (ifgl == NULL)
1860 		return (ENOENT);
1861 
1862 	TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
1863 
1864 	TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
1865 		if (ifgm->ifgm_ifp == ifp)
1866 			break;
1867 
1868 	if (ifgm != NULL) {
1869 		TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next);
1870 		free(ifgm, M_TEMP);
1871 	}
1872 
1873 	if (--ifgl->ifgl_group->ifg_refcnt == 0) {
1874 		TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
1875 #if NPF > 0
1876 		pfi_detach_ifgroup(ifgl->ifgl_group);
1877 #endif
1878 		free(ifgl->ifgl_group, M_TEMP);
1879 	}
1880 
1881 	free(ifgl, M_TEMP);
1882 
1883 #if NPF > 0
1884 	pfi_group_change(groupname);
1885 #endif
1886 
1887 	return (0);
1888 }
1889 
1890 /*
1891  * Stores all groups from an interface in memory pointed
1892  * to by data
1893  */
1894 int
1895 if_getgroup(caddr_t data, struct ifnet *ifp)
1896 {
1897 	int			 len, error;
1898 	struct ifg_list		*ifgl;
1899 	struct ifg_req		 ifgrq, *ifgp;
1900 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1901 
1902 	if (ifgr->ifgr_len == 0) {
1903 		TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
1904 			ifgr->ifgr_len += sizeof(struct ifg_req);
1905 		return (0);
1906 	}
1907 
1908 	len = ifgr->ifgr_len;
1909 	ifgp = ifgr->ifgr_groups;
1910 	TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
1911 		if (len < sizeof(ifgrq))
1912 			return (EINVAL);
1913 		bzero(&ifgrq, sizeof ifgrq);
1914 		strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
1915 		    sizeof(ifgrq.ifgrq_group));
1916 		if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
1917 		    sizeof(struct ifg_req))))
1918 			return (error);
1919 		len -= sizeof(ifgrq);
1920 		ifgp++;
1921 	}
1922 
1923 	return (0);
1924 }
1925 
1926 /*
1927  * Stores all members of a group in memory pointed to by data
1928  */
1929 int
1930 if_getgroupmembers(caddr_t data)
1931 {
1932 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1933 	struct ifg_group	*ifg;
1934 	struct ifg_member	*ifgm;
1935 	struct ifg_req		 ifgrq, *ifgp;
1936 	int			 len, error;
1937 
1938 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1939 		if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
1940 			break;
1941 	if (ifg == NULL)
1942 		return (ENOENT);
1943 
1944 	if (ifgr->ifgr_len == 0) {
1945 		TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
1946 			ifgr->ifgr_len += sizeof(ifgrq);
1947 		return (0);
1948 	}
1949 
1950 	len = ifgr->ifgr_len;
1951 	ifgp = ifgr->ifgr_groups;
1952 	TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
1953 		if (len < sizeof(ifgrq))
1954 			return (EINVAL);
1955 		bzero(&ifgrq, sizeof ifgrq);
1956 		strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
1957 		    sizeof(ifgrq.ifgrq_member));
1958 		if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
1959 		    sizeof(struct ifg_req))))
1960 			return (error);
1961 		len -= sizeof(ifgrq);
1962 		ifgp++;
1963 	}
1964 
1965 	return (0);
1966 }
1967 
1968 int
1969 if_getgroupattribs(caddr_t data)
1970 {
1971 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1972 	struct ifg_group	*ifg;
1973 
1974 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1975 		if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
1976 			break;
1977 	if (ifg == NULL)
1978 		return (ENOENT);
1979 
1980 	ifgr->ifgr_attrib.ifg_carp_demoted = ifg->ifg_carp_demoted;
1981 
1982 	return (0);
1983 }
1984 
1985 int
1986 if_setgroupattribs(caddr_t data)
1987 {
1988 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1989 	struct ifg_group	*ifg;
1990 	struct ifg_member	*ifgm;
1991 	int			 demote;
1992 
1993 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1994 		if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
1995 			break;
1996 	if (ifg == NULL)
1997 		return (ENOENT);
1998 
1999 	demote = ifgr->ifgr_attrib.ifg_carp_demoted;
2000 	if (demote + ifg->ifg_carp_demoted > 0xff ||
2001 	    demote + ifg->ifg_carp_demoted < 0)
2002 		return (ERANGE);
2003 
2004 	ifg->ifg_carp_demoted += demote;
2005 
2006 	TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
2007 		if (ifgm->ifgm_ifp->if_ioctl)
2008 			ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp,
2009 			    SIOCSIFGATTR, data);
2010 	return (0);
2011 }
2012 
2013 void
2014 if_group_routechange(struct sockaddr *dst, struct sockaddr *mask)
2015 {
2016 	switch (dst->sa_family) {
2017 	case AF_INET:
2018 		if (satosin(dst)->sin_addr.s_addr == INADDR_ANY &&
2019 		    mask && (mask->sa_len == 0 ||
2020 		    satosin(mask)->sin_addr.s_addr == INADDR_ANY))
2021 			if_group_egress_build();
2022 		break;
2023 #ifdef INET6
2024 	case AF_INET6:
2025 		if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr,
2026 		    &in6addr_any) && mask && (mask->sa_len == 0 ||
2027 		    IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr,
2028 		    &in6addr_any)))
2029 			if_group_egress_build();
2030 		break;
2031 #endif
2032 	}
2033 }
2034 
2035 int
2036 if_group_egress_build(void)
2037 {
2038 	struct ifg_group	*ifg;
2039 	struct ifg_member	*ifgm, *next;
2040 	struct sockaddr_in	 sa_in;
2041 #ifdef INET6
2042 	struct sockaddr_in6	 sa_in6;
2043 #endif
2044 	struct radix_node	*rn;
2045 	struct rtentry		*rt;
2046 
2047 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2048 		if (!strcmp(ifg->ifg_group, IFG_EGRESS))
2049 			break;
2050 
2051 	if (ifg != NULL)
2052 		for (ifgm = TAILQ_FIRST(&ifg->ifg_members); ifgm; ifgm = next) {
2053 			next = TAILQ_NEXT(ifgm, ifgm_next);
2054 			if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS);
2055 		}
2056 
2057 	bzero(&sa_in, sizeof(sa_in));
2058 	sa_in.sin_len = sizeof(sa_in);
2059 	sa_in.sin_family = AF_INET;
2060 	if ((rn = rt_lookup(sintosa(&sa_in), sintosa(&sa_in), 0)) != NULL) {
2061 		do {
2062 			rt = (struct rtentry *)rn;
2063 			if (rt->rt_ifp)
2064 				if_addgroup(rt->rt_ifp, IFG_EGRESS);
2065 #ifndef SMALL_KERNEL
2066 			rn = rn_mpath_next(rn, 0);
2067 #else
2068 			rn = NULL;
2069 #endif
2070 		} while (rn != NULL);
2071 	}
2072 
2073 #ifdef INET6
2074 	bcopy(&sa6_any, &sa_in6, sizeof(sa_in6));
2075 	if ((rn = rt_lookup(sin6tosa(&sa_in6), sin6tosa(&sa_in6), 0)) != NULL) {
2076 		do {
2077 			rt = (struct rtentry *)rn;
2078 			if (rt->rt_ifp)
2079 				if_addgroup(rt->rt_ifp, IFG_EGRESS);
2080 #ifndef SMALL_KERNEL
2081 			rn = rn_mpath_next(rn, 0);
2082 #else
2083 			rn = NULL;
2084 #endif
2085 		} while (rn != NULL);
2086 	}
2087 #endif
2088 
2089 	return (0);
2090 }
2091 
2092 /*
2093  * Set/clear promiscuous mode on interface ifp based on the truth value
2094  * of pswitch.  The calls are reference counted so that only the first
2095  * "on" request actually has an effect, as does the final "off" request.
2096  * Results are undefined if the "off" and "on" requests are not matched.
2097  */
2098 int
2099 ifpromisc(struct ifnet *ifp, int pswitch)
2100 {
2101 	struct ifreq ifr;
2102 
2103 	if (pswitch) {
2104 		/*
2105 		 * If the device is not configured up, we cannot put it in
2106 		 * promiscuous mode.
2107 		 */
2108 		if ((ifp->if_flags & IFF_UP) == 0)
2109 			return (ENETDOWN);
2110 		if (ifp->if_pcount++ != 0)
2111 			return (0);
2112 		ifp->if_flags |= IFF_PROMISC;
2113 	} else {
2114 		if (--ifp->if_pcount > 0)
2115 			return (0);
2116 		ifp->if_flags &= ~IFF_PROMISC;
2117 		/*
2118 		 * If the device is not configured up, we should not need to
2119 		 * turn off promiscuous mode (device should have turned it
2120 		 * off when interface went down; and will look at IFF_PROMISC
2121 		 * again next time interface comes up).
2122 		 */
2123 		if ((ifp->if_flags & IFF_UP) == 0)
2124 			return (0);
2125 	}
2126 	ifr.ifr_flags = ifp->if_flags;
2127 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
2128 }
2129 
2130 int
2131 sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2132     void *newp, size_t newlen, struct ifqueue *ifq)
2133 {
2134 	/* All sysctl names at this level are terminal. */
2135 	if (namelen != 1)
2136 		return (ENOTDIR);
2137 
2138 	switch (name[0]) {
2139 	case IFQCTL_LEN:
2140 		return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_len));
2141 	case IFQCTL_MAXLEN:
2142 		return (sysctl_int(oldp, oldlenp, newp, newlen,
2143 		    &ifq->ifq_maxlen));
2144 	case IFQCTL_DROPS:
2145 		return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_drops));
2146 	default:
2147 		return (EOPNOTSUPP);
2148 	}
2149 	/* NOTREACHED */
2150 }
2151