xref: /openbsd-src/sys/net/if.c (revision 5054e3e78af0749a9bb00ba9a024b3ee2d90290f)
1 /*	$OpenBSD: if.c,v 1.200 2009/11/03 10:59:04 claudio 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 
891 	rdomain = rtable_l2(rdomain);
892 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
893 	    if (ifp->if_rdomain != rdomain)
894 		continue;
895 	    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
896 		if (ifa->ifa_addr->sa_family != addr->sa_family)
897 			continue;
898 		if (equal(addr, ifa->ifa_addr))
899 			return (ifa);
900 		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
901 		    /* IP6 doesn't have broadcast */
902 		    ifa->ifa_broadaddr->sa_len != 0 &&
903 		    equal(ifa->ifa_broadaddr, addr))
904 			return (ifa);
905 	    }
906 	}
907 	return (NULL);
908 }
909 /*
910  * Locate the point to point interface with a given destination address.
911  */
912 /*ARGSUSED*/
913 struct ifaddr *
914 ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain)
915 {
916 	struct ifnet *ifp;
917 	struct ifaddr *ifa;
918 
919 	rdomain = rtable_l2(rdomain);
920 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
921 		if (ifp->if_rdomain != rdomain)
922 			continue;
923 		if (ifp->if_flags & IFF_POINTOPOINT)
924 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
925 				if (ifa->ifa_addr->sa_family !=
926 				    addr->sa_family || ifa->ifa_dstaddr == NULL)
927 					continue;
928 				if (equal(addr, ifa->ifa_dstaddr))
929 					return (ifa);
930 			}
931 	}
932 	return (NULL);
933 }
934 
935 /*
936  * Find an interface on a specific network.  If many, choice
937  * is most specific found.
938  */
939 struct ifaddr *
940 ifa_ifwithnet(struct sockaddr *addr, u_int rdomain)
941 {
942 	struct ifnet *ifp;
943 	struct ifaddr *ifa;
944 	struct ifaddr *ifa_maybe = 0;
945 	u_int af = addr->sa_family;
946 	char *addr_data = addr->sa_data, *cplim;
947 
948 	rdomain = rtable_l2(rdomain);
949 	if (af == AF_LINK) {
950 		struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
951 		if (sdl->sdl_index && sdl->sdl_index < if_indexlim &&
952 		    ifindex2ifnet[sdl->sdl_index])
953 			return (ifnet_addrs[sdl->sdl_index]);
954 	}
955 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
956 		if (ifp->if_rdomain != rdomain)
957 			continue;
958 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
959 			char *cp, *cp2, *cp3;
960 
961 			if (ifa->ifa_addr->sa_family != af ||
962 			    ifa->ifa_netmask == 0)
963 				next: continue;
964 			cp = addr_data;
965 			cp2 = ifa->ifa_addr->sa_data;
966 			cp3 = ifa->ifa_netmask->sa_data;
967 			cplim = (char *)ifa->ifa_netmask +
968 				ifa->ifa_netmask->sa_len;
969 			while (cp3 < cplim)
970 				if ((*cp++ ^ *cp2++) & *cp3++)
971 				    /* want to continue for() loop */
972 					goto next;
973 			if (ifa_maybe == 0 ||
974 			    rn_refines((caddr_t)ifa->ifa_netmask,
975 			    (caddr_t)ifa_maybe->ifa_netmask))
976 				ifa_maybe = ifa;
977 		}
978 	}
979 	return (ifa_maybe);
980 }
981 
982 /*
983  * Find an interface using a specific address family
984  */
985 struct ifaddr *
986 ifa_ifwithaf(int af, u_int rdomain)
987 {
988 	struct ifnet *ifp;
989 	struct ifaddr *ifa;
990 
991 	rdomain = rtable_l2(rdomain);
992 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
993 		if (ifp->if_rdomain != rdomain)
994 			continue;
995 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
996 			if (ifa->ifa_addr->sa_family == af)
997 				return (ifa);
998 		}
999 	}
1000 	return (NULL);
1001 }
1002 
1003 /*
1004  * Find an interface address specific to an interface best matching
1005  * a given address.
1006  */
1007 struct ifaddr *
1008 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
1009 {
1010 	struct ifaddr *ifa;
1011 	char *cp, *cp2, *cp3;
1012 	char *cplim;
1013 	struct ifaddr *ifa_maybe = NULL;
1014 	u_int af = addr->sa_family;
1015 
1016 	if (af >= AF_MAX)
1017 		return (NULL);
1018 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1019 		if (ifa->ifa_addr->sa_family != af)
1020 			continue;
1021 		if (ifa_maybe == NULL)
1022 			ifa_maybe = ifa;
1023 		if (ifa->ifa_netmask == 0 || ifp->if_flags & IFF_POINTOPOINT) {
1024 			if (equal(addr, ifa->ifa_addr) ||
1025 			    (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
1026 				return (ifa);
1027 			continue;
1028 		}
1029 		cp = addr->sa_data;
1030 		cp2 = ifa->ifa_addr->sa_data;
1031 		cp3 = ifa->ifa_netmask->sa_data;
1032 		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
1033 		for (; cp3 < cplim; cp3++)
1034 			if ((*cp++ ^ *cp2++) & *cp3)
1035 				break;
1036 		if (cp3 == cplim)
1037 			return (ifa);
1038 	}
1039 	return (ifa_maybe);
1040 }
1041 
1042 /*
1043  * Default action when installing a route with a Link Level gateway.
1044  * Lookup an appropriate real ifa to point to.
1045  * This should be moved to /sys/net/link.c eventually.
1046  */
1047 void
1048 link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
1049 {
1050 	struct ifaddr *ifa;
1051 	struct sockaddr *dst;
1052 	struct ifnet *ifp;
1053 
1054 	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
1055 	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
1056 		return;
1057 	if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
1058 		ifa->ifa_refcnt++;
1059 		IFAFREE(rt->rt_ifa);
1060 		rt->rt_ifa = ifa;
1061 		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
1062 			ifa->ifa_rtrequest(cmd, rt, info);
1063 	}
1064 }
1065 
1066 /*
1067  * Bring down all interfaces
1068  */
1069 void
1070 if_downall(void)
1071 {
1072 	struct ifreq ifrq;	/* XXX only partly built */
1073 	struct ifnet *ifp;
1074 	int s;
1075 
1076 	s = splnet();
1077 	for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) {
1078 		if ((ifp->if_flags & IFF_UP) == 0)
1079 			continue;
1080 		if_down(ifp);
1081 		ifp->if_flags &= ~IFF_UP;
1082 
1083 		if (ifp->if_ioctl) {
1084 			ifrq.ifr_flags = ifp->if_flags;
1085 			(void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
1086 			    (caddr_t)&ifrq);
1087 		}
1088 	}
1089 	splx(s);
1090 }
1091 
1092 /*
1093  * Mark an interface down and notify protocols of
1094  * the transition.
1095  * NOTE: must be called at splsoftnet or equivalent.
1096  */
1097 void
1098 if_down(struct ifnet *ifp)
1099 {
1100 	struct ifaddr *ifa;
1101 
1102 	splsoftassert(IPL_SOFTNET);
1103 
1104 	ifp->if_flags &= ~IFF_UP;
1105 	microtime(&ifp->if_lastchange);
1106 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1107 		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
1108 	}
1109 	IFQ_PURGE(&ifp->if_snd);
1110 #if NCARP > 0
1111 	if (ifp->if_carp)
1112 		carp_carpdev_state(ifp);
1113 #endif
1114 #if NBRIDGE > 0
1115 	if (ifp->if_bridge)
1116 		bstp_ifstate(ifp);
1117 #endif
1118 	rt_ifmsg(ifp);
1119 #ifndef SMALL_KERNEL
1120 	rt_if_track(ifp);
1121 #endif
1122 }
1123 
1124 /*
1125  * Mark an interface up and notify protocols of
1126  * the transition.
1127  * NOTE: must be called at splsoftnet or equivalent.
1128  */
1129 void
1130 if_up(struct ifnet *ifp)
1131 {
1132 #ifdef notyet
1133 	struct ifaddr *ifa;
1134 #endif
1135 
1136 	splsoftassert(IPL_SOFTNET);
1137 
1138 	ifp->if_flags |= IFF_UP;
1139 	microtime(&ifp->if_lastchange);
1140 #ifdef notyet
1141 	/* this has no effect on IP, and will kill all ISO connections XXX */
1142 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1143 		pfctlinput(PRC_IFUP, ifa->ifa_addr);
1144 	}
1145 #endif
1146 #if NCARP > 0
1147 	if (ifp->if_carp)
1148 		carp_carpdev_state(ifp);
1149 #endif
1150 #if NBRIDGE > 0
1151 	if (ifp->if_bridge)
1152 		bstp_ifstate(ifp);
1153 #endif
1154 	rt_ifmsg(ifp);
1155 #ifdef INET6
1156 	if (!(ifp->if_xflags & IFXF_NOINET6))
1157 		in6_if_up(ifp);
1158 #endif
1159 
1160 #ifndef SMALL_KERNEL
1161 	rt_if_track(ifp);
1162 #endif
1163 
1164 	m_clinitifp(ifp);
1165 }
1166 
1167 /*
1168  * Process a link state change.
1169  * NOTE: must be called at splsoftnet or equivalent.
1170  */
1171 void
1172 if_link_state_change(struct ifnet *ifp)
1173 {
1174 	rt_ifmsg(ifp);
1175 #ifndef SMALL_KERNEL
1176 	rt_if_track(ifp);
1177 #endif
1178 	dohooks(ifp->if_linkstatehooks, 0);
1179 }
1180 
1181 /*
1182  * Flush an interface queue.
1183  */
1184 void
1185 if_qflush(struct ifqueue *ifq)
1186 {
1187 	struct mbuf *m, *n;
1188 
1189 	n = ifq->ifq_head;
1190 	while ((m = n) != NULL) {
1191 		n = m->m_act;
1192 		m_freem(m);
1193 	}
1194 	ifq->ifq_head = 0;
1195 	ifq->ifq_tail = 0;
1196 	ifq->ifq_len = 0;
1197 }
1198 
1199 /*
1200  * Handle interface watchdog timer routines.  Called
1201  * from softclock, we decrement timers (if set) and
1202  * call the appropriate interface routine on expiration.
1203  */
1204 void
1205 if_slowtimo(void *arg)
1206 {
1207 	struct timeout *to = (struct timeout *)arg;
1208 	struct ifnet *ifp;
1209 	int s = splnet();
1210 
1211 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
1212 		if (ifp->if_timer == 0 || --ifp->if_timer)
1213 			continue;
1214 		if (ifp->if_watchdog)
1215 			(*ifp->if_watchdog)(ifp);
1216 	}
1217 	splx(s);
1218 	timeout_add(to, hz / IFNET_SLOWHZ);
1219 }
1220 
1221 /*
1222  * Map interface name to
1223  * interface structure pointer.
1224  */
1225 struct ifnet *
1226 ifunit(const char *name)
1227 {
1228 	struct ifnet *ifp;
1229 
1230 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
1231 		if (strcmp(ifp->if_xname, name) == 0)
1232 			return (ifp);
1233 	}
1234 	return (NULL);
1235 }
1236 
1237 /*
1238  * Interface ioctls.
1239  */
1240 int
1241 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1242 {
1243 	struct ifnet *ifp;
1244 	struct ifreq *ifr;
1245 	struct ifaddr *ifa, *nifa;
1246 	struct sockaddr_dl *sdl;
1247 	struct ifgroupreq *ifgr;
1248 	char ifdescrbuf[IFDESCRSIZE];
1249 	char ifrtlabelbuf[RTLABEL_LEN];
1250 	int error = 0;
1251 	size_t bytesdone;
1252 	short oif_flags;
1253 	const char *label;
1254 
1255 	switch (cmd) {
1256 
1257 	case SIOCGIFCONF:
1258 	case OSIOCGIFCONF:
1259 		return (ifconf(cmd, data));
1260 	}
1261 	ifr = (struct ifreq *)data;
1262 
1263 	switch (cmd) {
1264 	case SIOCIFCREATE:
1265 	case SIOCIFDESTROY:
1266 		if ((error = suser(p, 0)) != 0)
1267 			return (error);
1268 		return ((cmd == SIOCIFCREATE) ?
1269 		    if_clone_create(ifr->ifr_name) :
1270 		    if_clone_destroy(ifr->ifr_name));
1271 	case SIOCIFGCLONERS:
1272 		return (if_clone_list((struct if_clonereq *)data));
1273 	case SIOCGIFGMEMB:
1274 		return (if_getgroupmembers(data));
1275 	case SIOCGIFGATTR:
1276 		return (if_getgroupattribs(data));
1277 	case SIOCSIFGATTR:
1278 		if ((error = suser(p, 0)) != 0)
1279 			return (error);
1280 		return (if_setgroupattribs(data));
1281 	}
1282 
1283 	ifp = ifunit(ifr->ifr_name);
1284 	if (ifp == 0)
1285 		return (ENXIO);
1286 	oif_flags = ifp->if_flags;
1287 	switch (cmd) {
1288 
1289 	case SIOCGIFFLAGS:
1290 		ifr->ifr_flags = ifp->if_flags;
1291 		break;
1292 
1293 	case SIOCGIFXFLAGS:
1294 		ifr->ifr_flags = ifp->if_xflags;
1295 		break;
1296 
1297 	case SIOCGIFMETRIC:
1298 		ifr->ifr_metric = ifp->if_metric;
1299 		break;
1300 
1301 	case SIOCGIFMTU:
1302 		ifr->ifr_mtu = ifp->if_mtu;
1303 		break;
1304 
1305 	case SIOCGIFDATA:
1306 		error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
1307 		    sizeof(ifp->if_data));
1308 		break;
1309 
1310 	case SIOCSIFFLAGS:
1311 		if ((error = suser(p, 0)) != 0)
1312 			return (error);
1313 		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
1314 			int s = splnet();
1315 			if_down(ifp);
1316 			splx(s);
1317 		}
1318 		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
1319 			int s = splnet();
1320 			if_up(ifp);
1321 			splx(s);
1322 		}
1323 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
1324 			(ifr->ifr_flags &~ IFF_CANTCHANGE);
1325 		if (ifp->if_ioctl)
1326 			(void) (*ifp->if_ioctl)(ifp, cmd, data);
1327 		break;
1328 
1329 	case SIOCSIFXFLAGS:
1330 		if ((error = suser(p, 0)) != 0)
1331 			return (error);
1332 
1333 #ifdef INET6
1334 		/* when IFXF_NOINET6 gets changed, detach/attach */
1335 		if (ifp->if_flags & IFF_UP && ifr->ifr_flags & IFXF_NOINET6 &&
1336 		    !(ifp->if_xflags & IFXF_NOINET6))
1337 			in6_ifdetach(ifp);
1338 		if (ifp->if_flags & IFF_UP && ifp->if_xflags & IFXF_NOINET6 &&
1339 		    !(ifr->ifr_flags & IFXF_NOINET6)) {
1340 			ifp->if_xflags &= ~IFXF_NOINET6;
1341 			in6_if_up(ifp);
1342 		}
1343 #endif
1344 
1345 		ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
1346 			(ifr->ifr_flags &~ IFXF_CANTCHANGE);
1347 		rt_ifmsg(ifp);
1348 		break;
1349 
1350 	case SIOCSIFMETRIC:
1351 		if ((error = suser(p, 0)) != 0)
1352 			return (error);
1353 		ifp->if_metric = ifr->ifr_metric;
1354 		break;
1355 
1356 	case SIOCSIFMTU:
1357 	{
1358 #ifdef INET6
1359 		int oldmtu = ifp->if_mtu;
1360 #endif
1361 
1362 		if ((error = suser(p, 0)) != 0)
1363 			return (error);
1364 		if (ifp->if_ioctl == NULL)
1365 			return (EOPNOTSUPP);
1366 		error = (*ifp->if_ioctl)(ifp, cmd, data);
1367 
1368 		/*
1369 		 * If the link MTU changed, do network layer specific procedure.
1370 		 */
1371 #ifdef INET6
1372 		if (ifp->if_mtu != oldmtu)
1373 			nd6_setmtu(ifp);
1374 #endif
1375 		break;
1376 	}
1377 
1378 	case SIOCSIFPHYADDR:
1379 	case SIOCDIFPHYADDR:
1380 #ifdef INET6
1381 	case SIOCSIFPHYADDR_IN6:
1382 #endif
1383 	case SIOCSLIFPHYADDR:
1384 	case SIOCADDMULTI:
1385 	case SIOCDELMULTI:
1386 	case SIOCSIFMEDIA:
1387 		if ((error = suser(p, 0)) != 0)
1388 			return (error);
1389 		/* FALLTHROUGH */
1390 	case SIOCGIFPSRCADDR:
1391 	case SIOCGIFPDSTADDR:
1392 	case SIOCGLIFPHYADDR:
1393 	case SIOCGIFMEDIA:
1394 		if (ifp->if_ioctl == 0)
1395 			return (EOPNOTSUPP);
1396 		error = (*ifp->if_ioctl)(ifp, cmd, data);
1397 		break;
1398 
1399 	case SIOCGIFDESCR:
1400 		strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
1401 		error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
1402 		    &bytesdone);
1403 		break;
1404 
1405 	case SIOCSIFDESCR:
1406 		if ((error = suser(p, 0)) != 0)
1407 			return (error);
1408 		error = copyinstr(ifr->ifr_data, ifdescrbuf,
1409 		    IFDESCRSIZE, &bytesdone);
1410 		if (error == 0) {
1411 			(void)memset(ifp->if_description, 0, IFDESCRSIZE);
1412 			strlcpy(ifp->if_description, ifdescrbuf, IFDESCRSIZE);
1413 		}
1414 		break;
1415 
1416 	case SIOCGIFRTLABEL:
1417 		if (ifp->if_rtlabelid &&
1418 		    (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) {
1419 			strlcpy(ifrtlabelbuf, label, RTLABEL_LEN);
1420 			error = copyoutstr(ifrtlabelbuf, ifr->ifr_data,
1421 			    RTLABEL_LEN, &bytesdone);
1422 		} else
1423 			error = ENOENT;
1424 		break;
1425 
1426 	case SIOCSIFRTLABEL:
1427 		if ((error = suser(p, 0)) != 0)
1428 			return (error);
1429 		error = copyinstr(ifr->ifr_data, ifrtlabelbuf,
1430 		    RTLABEL_LEN, &bytesdone);
1431 		if (error == 0) {
1432 			rtlabel_unref(ifp->if_rtlabelid);
1433 			ifp->if_rtlabelid = rtlabel_name2id(ifrtlabelbuf);
1434 		}
1435 		break;
1436 
1437 	case SIOCGIFPRIORITY:
1438 		ifr->ifr_metric = ifp->if_priority;
1439 		break;
1440 
1441 	case SIOCSIFPRIORITY:
1442 		if ((error = suser(p, 0)) != 0)
1443 			return (error);
1444 		if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15)
1445 			return (EINVAL);
1446 		ifp->if_priority = ifr->ifr_metric;
1447 		break;
1448 
1449 	case SIOCGIFRTABLEID:
1450 		ifr->ifr_rdomainid = ifp->if_rdomain;
1451 		break;
1452 
1453 	case SIOCSIFRTABLEID:
1454 		if ((error = suser(p, 0)) != 0)
1455 			return (error);
1456 		if (ifr->ifr_rdomainid < 0 ||
1457 		    ifr->ifr_rdomainid > RT_TABLEID_MAX)
1458 			return (EINVAL);
1459 		/* remove all routing entries when switching domains */
1460 		/* XXX hell this is ugly */
1461 		if (ifr->ifr_rdomainid != ifp->if_rdomain) {
1462 			rt_if_remove(ifp);
1463 #ifdef INET
1464 			rti_delete(ifp);
1465 #if NETHER > 0
1466 			myip_ifp = NULL;
1467 #endif
1468 #ifdef MROUTING
1469 			vif_delete(ifp);
1470 #endif
1471 #endif
1472 #ifdef INET6
1473 			in6_ifdetach(ifp);
1474 #endif
1475 #ifdef INET
1476 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL;
1477 			    ifa = nifa) {
1478 				nifa = TAILQ_NEXT(ifa, ifa_list);
1479 
1480 				/* only remove AF_INET */
1481 				if (ifa->ifa_addr->sa_family != AF_INET)
1482 					continue;
1483 
1484 				TAILQ_REMOVE(&in_ifaddr,
1485 				    (struct in_ifaddr *)ifa, ia_list);
1486 				TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
1487 				ifa->ifa_ifp = NULL;
1488 				IFAFREE(ifa);
1489 			}
1490 #endif
1491 		}
1492 
1493 		/* make sure that the routing table exists */
1494 		if (!rtable_exists(ifr->ifr_rdomainid)) {
1495 			if (rtable_add(ifr->ifr_rdomainid) == -1)
1496 				panic("rtinit: rtable_add");
1497 		}
1498 		if (ifr->ifr_rdomainid != rtable_l2(ifr->ifr_rdomainid)) {
1499 			/* XXX we should probably flush the table */
1500 			rtable_l2set(ifr->ifr_rdomainid, ifr->ifr_rdomainid);
1501 		}
1502 
1503 		ifp->if_rdomain = ifr->ifr_rdomainid;
1504 		break;
1505 
1506 	case SIOCAIFGROUP:
1507 		if ((error = suser(p, 0)))
1508 			return (error);
1509 		(*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */
1510 		ifgr = (struct ifgroupreq *)data;
1511 		if ((error = if_addgroup(ifp, ifgr->ifgr_group)))
1512 			return (error);
1513 		break;
1514 
1515 	case SIOCGIFGROUP:
1516 		if ((error = if_getgroup(data, ifp)))
1517 			return (error);
1518 		break;
1519 
1520 	case SIOCDIFGROUP:
1521 		if ((error = suser(p, 0)))
1522 			return (error);
1523 		(*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */
1524 		ifgr = (struct ifgroupreq *)data;
1525 		if ((error = if_delgroup(ifp, ifgr->ifgr_group)))
1526 			return (error);
1527 		break;
1528 
1529 	case SIOCSIFLLADDR:
1530 		if ((error = suser(p, 0)))
1531 			return (error);
1532 		ifa = ifnet_addrs[ifp->if_index];
1533 		if (ifa == NULL)
1534 			return (EINVAL);
1535 		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1536 		if (sdl == NULL)
1537 			return (EINVAL);
1538 		if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN)
1539 			return (EINVAL);
1540 		if (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data))
1541 			return (EINVAL);
1542 		switch (ifp->if_type) {
1543 		case IFT_ETHER:
1544 		case IFT_CARP:
1545 		case IFT_FDDI:
1546 		case IFT_XETHER:
1547 		case IFT_ISO88025:
1548 		case IFT_L2VLAN:
1549 			bcopy((caddr_t)ifr->ifr_addr.sa_data,
1550 			    (caddr_t)((struct arpcom *)ifp)->ac_enaddr,
1551 			    ETHER_ADDR_LEN);
1552 			bcopy((caddr_t)ifr->ifr_addr.sa_data,
1553 			    LLADDR(sdl), ETHER_ADDR_LEN);
1554 			break;
1555 		default:
1556 			return (ENODEV);
1557 		}
1558 		if (ifp->if_flags & IFF_UP) {
1559 			struct ifreq ifrq;
1560 			int s = splnet();
1561 			ifp->if_flags &= ~IFF_UP;
1562 			ifrq.ifr_flags = ifp->if_flags;
1563 			(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
1564 			ifp->if_flags |= IFF_UP;
1565 			ifrq.ifr_flags = ifp->if_flags;
1566 			(*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
1567 			splx(s);
1568 			TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1569 				if (ifa->ifa_addr != NULL &&
1570 				    ifa->ifa_addr->sa_family == AF_INET)
1571 					arp_ifinit((struct arpcom *)ifp, ifa);
1572 			}
1573 		}
1574 		break;
1575 
1576 	default:
1577 		if (so->so_proto == 0)
1578 			return (EOPNOTSUPP);
1579 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
1580 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1581 			(struct mbuf *) cmd, (struct mbuf *) data,
1582 			(struct mbuf *) ifp, p));
1583 #else
1584 	    {
1585 		u_long ocmd = cmd;
1586 
1587 		switch (cmd) {
1588 
1589 		case SIOCSIFADDR:
1590 		case SIOCSIFDSTADDR:
1591 		case SIOCSIFBRDADDR:
1592 		case SIOCSIFNETMASK:
1593 #if BYTE_ORDER != BIG_ENDIAN
1594 			if (ifr->ifr_addr.sa_family == 0 &&
1595 			    ifr->ifr_addr.sa_len < 16) {
1596 				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1597 				ifr->ifr_addr.sa_len = 16;
1598 			}
1599 #else
1600 			if (ifr->ifr_addr.sa_len == 0)
1601 				ifr->ifr_addr.sa_len = 16;
1602 #endif
1603 			break;
1604 
1605 		case OSIOCGIFADDR:
1606 			cmd = SIOCGIFADDR;
1607 			break;
1608 
1609 		case OSIOCGIFDSTADDR:
1610 			cmd = SIOCGIFDSTADDR;
1611 			break;
1612 
1613 		case OSIOCGIFBRDADDR:
1614 			cmd = SIOCGIFBRDADDR;
1615 			break;
1616 
1617 		case OSIOCGIFNETMASK:
1618 			cmd = SIOCGIFNETMASK;
1619 		}
1620 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1621 		    (struct mbuf *) cmd, (struct mbuf *) data,
1622 		    (struct mbuf *) ifp, p));
1623 		switch (ocmd) {
1624 
1625 		case OSIOCGIFADDR:
1626 		case OSIOCGIFDSTADDR:
1627 		case OSIOCGIFBRDADDR:
1628 		case OSIOCGIFNETMASK:
1629 			*(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1630 		}
1631 
1632 	    }
1633 #endif
1634 		break;
1635 	}
1636 
1637 	if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1638 		microtime(&ifp->if_lastchange);
1639 #ifdef INET6
1640 		if (!(ifp->if_xflags & IFXF_NOINET6) &&
1641 		    (ifp->if_flags & IFF_UP) != 0) {
1642 			int s = splnet();
1643 			in6_if_up(ifp);
1644 			splx(s);
1645 		}
1646 #endif
1647 	}
1648 	return (error);
1649 }
1650 
1651 /*
1652  * Return interface configuration
1653  * of system.  List may be used
1654  * in later ioctl's (above) to get
1655  * other information.
1656  */
1657 /*ARGSUSED*/
1658 int
1659 ifconf(u_long cmd, caddr_t data)
1660 {
1661 	struct ifconf *ifc = (struct ifconf *)data;
1662 	struct ifnet *ifp;
1663 	struct ifaddr *ifa;
1664 	struct ifreq ifr, *ifrp;
1665 	int space = ifc->ifc_len, error = 0;
1666 
1667 	/* If ifc->ifc_len is 0, fill it in with the needed size and return. */
1668 	if (space == 0) {
1669 		TAILQ_FOREACH(ifp, &ifnet, if_list) {
1670 			struct sockaddr *sa;
1671 
1672 			if (TAILQ_EMPTY(&ifp->if_addrlist))
1673 				space += sizeof (ifr);
1674 			else
1675 				TAILQ_FOREACH(ifa,
1676 				    &ifp->if_addrlist, ifa_list) {
1677 					sa = ifa->ifa_addr;
1678 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1679 					if (cmd != OSIOCGIFCONF)
1680 #endif
1681 					if (sa->sa_len > sizeof(*sa))
1682 						space += sa->sa_len -
1683 						    sizeof(*sa);
1684 					space += sizeof(ifr);
1685 				}
1686 		}
1687 		ifc->ifc_len = space;
1688 		return (0);
1689 	}
1690 
1691 	ifrp = ifc->ifc_req;
1692 	for (ifp = TAILQ_FIRST(&ifnet); space >= sizeof(ifr) &&
1693 	    ifp != TAILQ_END(&ifnet); ifp = TAILQ_NEXT(ifp, if_list)) {
1694 		bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1695 		if (TAILQ_EMPTY(&ifp->if_addrlist)) {
1696 			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1697 			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1698 			    sizeof(ifr));
1699 			if (error)
1700 				break;
1701 			space -= sizeof (ifr), ifrp++;
1702 		} else
1703 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist);
1704 			    space >= sizeof (ifr) &&
1705 			    ifa != TAILQ_END(&ifp->if_addrlist);
1706 			    ifa = TAILQ_NEXT(ifa, ifa_list)) {
1707 				struct sockaddr *sa = ifa->ifa_addr;
1708 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1709 				if (cmd == OSIOCGIFCONF) {
1710 					struct osockaddr *osa =
1711 					    (struct osockaddr *)&ifr.ifr_addr;
1712 					ifr.ifr_addr = *sa;
1713 					osa->sa_family = sa->sa_family;
1714 					error = copyout((caddr_t)&ifr,
1715 					    (caddr_t)ifrp, sizeof (ifr));
1716 					ifrp++;
1717 				} else
1718 #endif
1719 				if (sa->sa_len <= sizeof(*sa)) {
1720 					ifr.ifr_addr = *sa;
1721 					error = copyout((caddr_t)&ifr,
1722 					    (caddr_t)ifrp, sizeof (ifr));
1723 					ifrp++;
1724 				} else {
1725 					space -= sa->sa_len - sizeof(*sa);
1726 					if (space < sizeof (ifr))
1727 						break;
1728 					error = copyout((caddr_t)&ifr,
1729 					    (caddr_t)ifrp,
1730 					    sizeof(ifr.ifr_name));
1731 					if (error == 0)
1732 						error = copyout((caddr_t)sa,
1733 						    (caddr_t)&ifrp->ifr_addr,
1734 						    sa->sa_len);
1735 					ifrp = (struct ifreq *)(sa->sa_len +
1736 					    (caddr_t)&ifrp->ifr_addr);
1737 				}
1738 				if (error)
1739 					break;
1740 				space -= sizeof (ifr);
1741 			}
1742 	}
1743 	ifc->ifc_len -= space;
1744 	return (error);
1745 }
1746 
1747 /*
1748  * Dummy functions replaced in ifnet during detach (if protocols decide to
1749  * fiddle with the if during detach.
1750  */
1751 void
1752 if_detached_start(struct ifnet *ifp)
1753 {
1754 	struct mbuf *m;
1755 
1756 	while (1) {
1757 		IF_DEQUEUE(&ifp->if_snd, m);
1758 
1759 		if (m == NULL)
1760 			return;
1761 		m_freem(m);
1762 	}
1763 }
1764 
1765 int
1766 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
1767 {
1768 	return ENODEV;
1769 }
1770 
1771 int
1772 if_detached_init(struct ifnet *ifp)
1773 {
1774 	return (ENXIO);
1775 }
1776 
1777 void
1778 if_detached_watchdog(struct ifnet *ifp)
1779 {
1780 	/* nothing */
1781 }
1782 
1783 /*
1784  * Create interface group without members
1785  */
1786 struct ifg_group *
1787 if_creategroup(const char *groupname)
1788 {
1789 	struct ifg_group	*ifg;
1790 
1791 	if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL)
1792 		return (NULL);
1793 
1794 	strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
1795 	ifg->ifg_refcnt = 0;
1796 	ifg->ifg_carp_demoted = 0;
1797 	TAILQ_INIT(&ifg->ifg_members);
1798 #if NPF > 0
1799 	pfi_attach_ifgroup(ifg);
1800 #endif
1801 	TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next);
1802 
1803 	return (ifg);
1804 }
1805 
1806 /*
1807  * Add a group to an interface
1808  */
1809 int
1810 if_addgroup(struct ifnet *ifp, const char *groupname)
1811 {
1812 	struct ifg_list		*ifgl;
1813 	struct ifg_group	*ifg = NULL;
1814 	struct ifg_member	*ifgm;
1815 
1816 	if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' &&
1817 	    groupname[strlen(groupname) - 1] <= '9')
1818 		return (EINVAL);
1819 
1820 	TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
1821 		if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
1822 			return (EEXIST);
1823 
1824 	if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL)
1825 		return (ENOMEM);
1826 
1827 	if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) {
1828 		free(ifgl, M_TEMP);
1829 		return (ENOMEM);
1830 	}
1831 
1832 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1833 		if (!strcmp(ifg->ifg_group, groupname))
1834 			break;
1835 
1836 	if (ifg == NULL && (ifg = if_creategroup(groupname)) == NULL) {
1837 		free(ifgl, M_TEMP);
1838 		free(ifgm, M_TEMP);
1839 		return (ENOMEM);
1840 	}
1841 
1842 	ifg->ifg_refcnt++;
1843 	ifgl->ifgl_group = ifg;
1844 	ifgm->ifgm_ifp = ifp;
1845 
1846 	TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next);
1847 	TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next);
1848 
1849 #if NPF > 0
1850 	pfi_group_change(groupname);
1851 #endif
1852 
1853 	return (0);
1854 }
1855 
1856 /*
1857  * Remove a group from an interface
1858  */
1859 int
1860 if_delgroup(struct ifnet *ifp, const char *groupname)
1861 {
1862 	struct ifg_list		*ifgl;
1863 	struct ifg_member	*ifgm;
1864 
1865 	TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
1866 		if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
1867 			break;
1868 	if (ifgl == NULL)
1869 		return (ENOENT);
1870 
1871 	TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
1872 
1873 	TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
1874 		if (ifgm->ifgm_ifp == ifp)
1875 			break;
1876 
1877 	if (ifgm != NULL) {
1878 		TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next);
1879 		free(ifgm, M_TEMP);
1880 	}
1881 
1882 	if (--ifgl->ifgl_group->ifg_refcnt == 0) {
1883 		TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
1884 #if NPF > 0
1885 		pfi_detach_ifgroup(ifgl->ifgl_group);
1886 #endif
1887 		free(ifgl->ifgl_group, M_TEMP);
1888 	}
1889 
1890 	free(ifgl, M_TEMP);
1891 
1892 #if NPF > 0
1893 	pfi_group_change(groupname);
1894 #endif
1895 
1896 	return (0);
1897 }
1898 
1899 /*
1900  * Stores all groups from an interface in memory pointed
1901  * to by data
1902  */
1903 int
1904 if_getgroup(caddr_t data, struct ifnet *ifp)
1905 {
1906 	int			 len, error;
1907 	struct ifg_list		*ifgl;
1908 	struct ifg_req		 ifgrq, *ifgp;
1909 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1910 
1911 	if (ifgr->ifgr_len == 0) {
1912 		TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
1913 			ifgr->ifgr_len += sizeof(struct ifg_req);
1914 		return (0);
1915 	}
1916 
1917 	len = ifgr->ifgr_len;
1918 	ifgp = ifgr->ifgr_groups;
1919 	TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
1920 		if (len < sizeof(ifgrq))
1921 			return (EINVAL);
1922 		bzero(&ifgrq, sizeof ifgrq);
1923 		strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
1924 		    sizeof(ifgrq.ifgrq_group));
1925 		if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
1926 		    sizeof(struct ifg_req))))
1927 			return (error);
1928 		len -= sizeof(ifgrq);
1929 		ifgp++;
1930 	}
1931 
1932 	return (0);
1933 }
1934 
1935 /*
1936  * Stores all members of a group in memory pointed to by data
1937  */
1938 int
1939 if_getgroupmembers(caddr_t data)
1940 {
1941 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1942 	struct ifg_group	*ifg;
1943 	struct ifg_member	*ifgm;
1944 	struct ifg_req		 ifgrq, *ifgp;
1945 	int			 len, error;
1946 
1947 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1948 		if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
1949 			break;
1950 	if (ifg == NULL)
1951 		return (ENOENT);
1952 
1953 	if (ifgr->ifgr_len == 0) {
1954 		TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
1955 			ifgr->ifgr_len += sizeof(ifgrq);
1956 		return (0);
1957 	}
1958 
1959 	len = ifgr->ifgr_len;
1960 	ifgp = ifgr->ifgr_groups;
1961 	TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
1962 		if (len < sizeof(ifgrq))
1963 			return (EINVAL);
1964 		bzero(&ifgrq, sizeof ifgrq);
1965 		strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
1966 		    sizeof(ifgrq.ifgrq_member));
1967 		if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
1968 		    sizeof(struct ifg_req))))
1969 			return (error);
1970 		len -= sizeof(ifgrq);
1971 		ifgp++;
1972 	}
1973 
1974 	return (0);
1975 }
1976 
1977 int
1978 if_getgroupattribs(caddr_t data)
1979 {
1980 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1981 	struct ifg_group	*ifg;
1982 
1983 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
1984 		if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
1985 			break;
1986 	if (ifg == NULL)
1987 		return (ENOENT);
1988 
1989 	ifgr->ifgr_attrib.ifg_carp_demoted = ifg->ifg_carp_demoted;
1990 
1991 	return (0);
1992 }
1993 
1994 int
1995 if_setgroupattribs(caddr_t data)
1996 {
1997 	struct ifgroupreq	*ifgr = (struct ifgroupreq *)data;
1998 	struct ifg_group	*ifg;
1999 	struct ifg_member	*ifgm;
2000 	int			 demote;
2001 
2002 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2003 		if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
2004 			break;
2005 	if (ifg == NULL)
2006 		return (ENOENT);
2007 
2008 	demote = ifgr->ifgr_attrib.ifg_carp_demoted;
2009 	if (demote + ifg->ifg_carp_demoted > 0xff ||
2010 	    demote + ifg->ifg_carp_demoted < 0)
2011 		return (ERANGE);
2012 
2013 	ifg->ifg_carp_demoted += demote;
2014 
2015 	TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
2016 		if (ifgm->ifgm_ifp->if_ioctl)
2017 			ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp,
2018 			    SIOCSIFGATTR, data);
2019 	return (0);
2020 }
2021 
2022 void
2023 if_group_routechange(struct sockaddr *dst, struct sockaddr *mask)
2024 {
2025 	switch (dst->sa_family) {
2026 	case AF_INET:
2027 		if (satosin(dst)->sin_addr.s_addr == INADDR_ANY &&
2028 		    mask && (mask->sa_len == 0 ||
2029 		    satosin(mask)->sin_addr.s_addr == INADDR_ANY))
2030 			if_group_egress_build();
2031 		break;
2032 #ifdef INET6
2033 	case AF_INET6:
2034 		if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr,
2035 		    &in6addr_any) && mask && (mask->sa_len == 0 ||
2036 		    IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr,
2037 		    &in6addr_any)))
2038 			if_group_egress_build();
2039 		break;
2040 #endif
2041 	}
2042 }
2043 
2044 int
2045 if_group_egress_build(void)
2046 {
2047 	struct ifg_group	*ifg;
2048 	struct ifg_member	*ifgm, *next;
2049 	struct sockaddr_in	 sa_in;
2050 #ifdef INET6
2051 	struct sockaddr_in6	 sa_in6;
2052 #endif
2053 	struct radix_node	*rn;
2054 	struct rtentry		*rt;
2055 
2056 	TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2057 		if (!strcmp(ifg->ifg_group, IFG_EGRESS))
2058 			break;
2059 
2060 	if (ifg != NULL)
2061 		for (ifgm = TAILQ_FIRST(&ifg->ifg_members); ifgm; ifgm = next) {
2062 			next = TAILQ_NEXT(ifgm, ifgm_next);
2063 			if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS);
2064 		}
2065 
2066 	bzero(&sa_in, sizeof(sa_in));
2067 	sa_in.sin_len = sizeof(sa_in);
2068 	sa_in.sin_family = AF_INET;
2069 	if ((rn = rt_lookup(sintosa(&sa_in), sintosa(&sa_in), 0)) != NULL) {
2070 		do {
2071 			rt = (struct rtentry *)rn;
2072 			if (rt->rt_ifp)
2073 				if_addgroup(rt->rt_ifp, IFG_EGRESS);
2074 #ifndef SMALL_KERNEL
2075 			rn = rn_mpath_next(rn, 0);
2076 #else
2077 			rn = NULL;
2078 #endif
2079 		} while (rn != NULL);
2080 	}
2081 
2082 #ifdef INET6
2083 	bcopy(&sa6_any, &sa_in6, sizeof(sa_in6));
2084 	if ((rn = rt_lookup(sin6tosa(&sa_in6), sin6tosa(&sa_in6), 0)) != NULL) {
2085 		do {
2086 			rt = (struct rtentry *)rn;
2087 			if (rt->rt_ifp)
2088 				if_addgroup(rt->rt_ifp, IFG_EGRESS);
2089 #ifndef SMALL_KERNEL
2090 			rn = rn_mpath_next(rn, 0);
2091 #else
2092 			rn = NULL;
2093 #endif
2094 		} while (rn != NULL);
2095 	}
2096 #endif
2097 
2098 	return (0);
2099 }
2100 
2101 /*
2102  * Set/clear promiscuous mode on interface ifp based on the truth value
2103  * of pswitch.  The calls are reference counted so that only the first
2104  * "on" request actually has an effect, as does the final "off" request.
2105  * Results are undefined if the "off" and "on" requests are not matched.
2106  */
2107 int
2108 ifpromisc(struct ifnet *ifp, int pswitch)
2109 {
2110 	struct ifreq ifr;
2111 
2112 	if (pswitch) {
2113 		/*
2114 		 * If the device is not configured up, we cannot put it in
2115 		 * promiscuous mode.
2116 		 */
2117 		if ((ifp->if_flags & IFF_UP) == 0)
2118 			return (ENETDOWN);
2119 		if (ifp->if_pcount++ != 0)
2120 			return (0);
2121 		ifp->if_flags |= IFF_PROMISC;
2122 	} else {
2123 		if (--ifp->if_pcount > 0)
2124 			return (0);
2125 		ifp->if_flags &= ~IFF_PROMISC;
2126 		/*
2127 		 * If the device is not configured up, we should not need to
2128 		 * turn off promiscuous mode (device should have turned it
2129 		 * off when interface went down; and will look at IFF_PROMISC
2130 		 * again next time interface comes up).
2131 		 */
2132 		if ((ifp->if_flags & IFF_UP) == 0)
2133 			return (0);
2134 	}
2135 	ifr.ifr_flags = ifp->if_flags;
2136 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
2137 }
2138 
2139 int
2140 sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2141     void *newp, size_t newlen, struct ifqueue *ifq)
2142 {
2143 	/* All sysctl names at this level are terminal. */
2144 	if (namelen != 1)
2145 		return (ENOTDIR);
2146 
2147 	switch (name[0]) {
2148 	case IFQCTL_LEN:
2149 		return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_len));
2150 	case IFQCTL_MAXLEN:
2151 		return (sysctl_int(oldp, oldlenp, newp, newlen,
2152 		    &ifq->ifq_maxlen));
2153 	case IFQCTL_DROPS:
2154 		return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_drops));
2155 	default:
2156 		return (EOPNOTSUPP);
2157 	}
2158 	/* NOTREACHED */
2159 }
2160