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