xref: /openbsd-src/sys/net/if.c (revision 8500990981f885cbe5e6a4958549cacc238b5ae6)
1 /*	$OpenBSD: if.c,v 1.73 2003/11/06 21:09:34 mickey 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 "bpfilter.h"
65 #include "bridge.h"
66 #include "carp.h"
67 
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/mbuf.h>
71 #include <sys/proc.h>
72 #include <sys/socket.h>
73 #include <sys/socketvar.h>
74 #include <sys/protosw.h>
75 #include <sys/kernel.h>
76 #include <sys/ioctl.h>
77 #include <sys/domain.h>
78 
79 #include <net/if.h>
80 #include <net/if_dl.h>
81 #include <net/route.h>
82 
83 #ifdef INET
84 #include <netinet/in.h>
85 #include <netinet/in_var.h>
86 #include <netinet/if_ether.h>
87 #include <netinet/igmp.h>
88 #ifdef MROUTING
89 #include <netinet/ip_mroute.h>
90 #endif
91 #endif
92 
93 #ifdef INET6
94 #ifndef INET
95 #include <netinet/in.h>
96 #endif
97 #include <netinet6/in6_ifattach.h>
98 #include <netinet6/nd6.h>
99 #endif
100 
101 #if NBPFILTER > 0
102 #include <net/bpf.h>
103 #endif
104 
105 #if NBRIDGE > 0
106 #include <net/if_bridge.h>
107 #endif
108 
109 #if NCARP > 0
110 #include <netinet/ip_carp.h>
111 #endif
112 
113 void	if_attachsetup(struct ifnet *);
114 void	if_attachdomain1(struct ifnet *);
115 int	if_detach_rtdelete(struct radix_node *, void *);
116 
117 int	ifqmaxlen = IFQ_MAXLEN;
118 
119 void	if_detach_queues(struct ifnet *, struct ifqueue *);
120 void	if_detached_start(struct ifnet *);
121 int	if_detached_ioctl(struct ifnet *, u_long, caddr_t);
122 int	if_detached_init(struct ifnet *);
123 void	if_detached_watchdog(struct ifnet *);
124 
125 /*
126  * Network interface utility routines.
127  *
128  * Routines with ifa_ifwith* names take sockaddr *'s as
129  * parameters.
130  */
131 void
132 ifinit()
133 {
134 	static struct timeout if_slowtim;
135 
136 	timeout_set(&if_slowtim, if_slowtimo, &if_slowtim);
137 
138 	if_slowtimo(&if_slowtim);
139 }
140 
141 int if_index = 0;
142 struct ifaddr **ifnet_addrs = NULL;
143 struct ifnet **ifindex2ifnet = NULL;
144 struct ifnet_head ifnet;
145 struct ifnet *lo0ifp;
146 
147 /*
148  * Attach an interface to the
149  * list of "active" interfaces.
150  */
151 void
152 if_attachsetup(ifp)
153 	struct ifnet *ifp;
154 {
155 	struct ifaddr *ifa;
156 	static int if_indexlim = 8;
157 
158 	ifp->if_index = ++if_index;
159 
160 	/*
161 	 * We have some arrays that should be indexed by if_index.
162 	 * since if_index will grow dynamically, they should grow too.
163 	 *	struct ifadd **ifnet_addrs
164 	 *	struct ifnet **ifindex2ifnet
165 	 */
166 	if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if_index >= if_indexlim) {
167 		size_t m, n, oldlim;
168 		caddr_t q;
169 
170 		oldlim = if_indexlim;
171 		while (if_index >= if_indexlim)
172 			if_indexlim <<= 1;
173 
174 		/* grow ifnet_addrs */
175 		m = oldlim * sizeof(ifa);
176 		n = if_indexlim * sizeof(ifa);
177 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
178 		bzero(q, n);
179 		if (ifnet_addrs) {
180 			bcopy((caddr_t)ifnet_addrs, q, m);
181 			free((caddr_t)ifnet_addrs, M_IFADDR);
182 		}
183 		ifnet_addrs = (struct ifaddr **)q;
184 
185 		/* grow ifindex2ifnet */
186 		m = oldlim * sizeof(struct ifnet *);
187 		n = if_indexlim * sizeof(struct ifnet *);
188 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
189 		bzero(q, n);
190 		if (ifindex2ifnet) {
191 			bcopy((caddr_t)ifindex2ifnet, q, m);
192 			free((caddr_t)ifindex2ifnet, M_IFADDR);
193 		}
194 		ifindex2ifnet = (struct ifnet **)q;
195 	}
196 
197 	ifindex2ifnet[if_index] = ifp;
198 
199 	if (ifp->if_snd.ifq_maxlen == 0)
200 		ifp->if_snd.ifq_maxlen = ifqmaxlen;
201 #ifdef ALTQ
202 	ifp->if_snd.altq_type = 0;
203 	ifp->if_snd.altq_disc = NULL;
204 	ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
205 	ifp->if_snd.altq_tbr  = NULL;
206 	ifp->if_snd.altq_ifp  = ifp;
207 #endif
208 
209 	if (domains)
210 		if_attachdomain1(ifp);
211 }
212 
213 /*
214  * Allocate the link level name for the specified interface.  This
215  * is an attachment helper.  It must be called after ifp->if_addrlen
216  * is initialized, which may not be the case when if_attach() is
217  * called.
218  */
219 void
220 if_alloc_sadl(ifp)
221 	struct ifnet *ifp;
222 {
223 	unsigned socksize, ifasize;
224 	int namelen, masklen;
225 	struct sockaddr_dl *sdl;
226 	struct ifaddr *ifa;
227 
228 	/*
229 	 * If the interface already has a link name, release it
230 	 * now.  This is useful for interfaces that can change
231 	 * link types, and thus switch link names often.
232 	 */
233 	if (ifp->if_sadl != NULL)
234 		if_free_sadl(ifp);
235 
236 	namelen = strlen(ifp->if_xname);
237 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
238 	masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
239 	socksize = masklen + ifp->if_addrlen;
240 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
241 	if (socksize < sizeof(*sdl))
242 		socksize = sizeof(*sdl);
243 	socksize = ROUNDUP(socksize);
244 	ifasize = sizeof(*ifa) + 2 * socksize;
245 	ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
246 	bzero((caddr_t)ifa, ifasize);
247 	sdl = (struct sockaddr_dl *)(ifa + 1);
248 	sdl->sdl_len = socksize;
249 	sdl->sdl_family = AF_LINK;
250 	bcopy(ifp->if_xname, sdl->sdl_data, namelen);
251 	sdl->sdl_nlen = namelen;
252 	sdl->sdl_alen = ifp->if_addrlen;
253 	sdl->sdl_index = ifp->if_index;
254 	sdl->sdl_type = ifp->if_type;
255 	ifnet_addrs[if_index] = ifa;
256 	ifa->ifa_ifp = ifp;
257 	ifa->ifa_rtrequest = link_rtrequest;
258 	TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
259 	ifa->ifa_addr = (struct sockaddr *)sdl;
260 	ifp->if_sadl = sdl;
261 	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
262 	ifa->ifa_netmask = (struct sockaddr *)sdl;
263 	sdl->sdl_len = masklen;
264 	while (namelen != 0)
265 		sdl->sdl_data[--namelen] = 0xff;
266 }
267 
268 /*
269  * Free the link level name for the specified interface.  This is
270  * a detach helper.  This is called from if_detach() or from
271  * link layer type specific detach functions.
272  */
273 void
274 if_free_sadl(ifp)
275 	struct ifnet *ifp;
276 {
277 	struct ifaddr *ifa;
278 	int s;
279 
280 	ifa = ifnet_addrs[ifp->if_index];
281 	if (ifa == NULL)
282 		return;
283 
284 	s = splnet();
285 	rtinit(ifa, RTM_DELETE, 0);
286 	TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
287 
288 	ifp->if_sadl = NULL;
289 
290 	ifnet_addrs[ifp->if_index] = NULL;
291 	splx(s);
292 }
293 
294 void
295 if_attachdomain()
296 {
297 	struct ifnet *ifp;
298 	int s;
299 
300 	s = splnet();
301 	for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
302 		if_attachdomain1(ifp);
303 	splx(s);
304 }
305 
306 void
307 if_attachdomain1(ifp)
308 	struct ifnet *ifp;
309 {
310 	struct domain *dp;
311 	int s;
312 
313 	s = splnet();
314 
315 	/* address family dependent data region */
316 	bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
317 	for (dp = domains; dp; dp = dp->dom_next) {
318 		if (dp->dom_ifattach)
319 			ifp->if_afdata[dp->dom_family] =
320 			    (*dp->dom_ifattach)(ifp);
321 	}
322 
323 	splx(s);
324 }
325 
326 void
327 if_attachhead(ifp)
328 	struct ifnet *ifp;
329 {
330 	if (if_index == 0)
331 		TAILQ_INIT(&ifnet);
332 	TAILQ_INIT(&ifp->if_addrlist);
333 	ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks), M_TEMP, M_NOWAIT);
334 	if (ifp->if_addrhooks == NULL)
335 		panic("if_attachhead: malloc");
336 	TAILQ_INIT(ifp->if_addrhooks);
337 	TAILQ_INSERT_HEAD(&ifnet, ifp, if_list);
338 	if_attachsetup(ifp);
339 }
340 
341 void
342 if_attach(ifp)
343 	struct ifnet *ifp;
344 {
345 	if (if_index == 0)
346 		TAILQ_INIT(&ifnet);
347 	TAILQ_INIT(&ifp->if_addrlist);
348 	ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks), M_TEMP, M_NOWAIT);
349 	if (ifp->if_addrhooks == NULL)
350 		panic("if_attach: malloc");
351 	TAILQ_INIT(ifp->if_addrhooks);
352 	TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
353 	if_attachsetup(ifp);
354 }
355 
356 /*
357  * Delete a route if it has a specific interface for output.
358  * This function complies to the rn_walktree callback API.
359  */
360 int
361 if_detach_rtdelete(rn, vifp)
362 	struct radix_node *rn;
363 	void *vifp;
364 {
365 	struct ifnet *ifp = vifp;
366 	struct rtentry *rt = (struct rtentry *)rn;
367 
368 	if (rt->rt_ifp == ifp)
369 		rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, rt_mask(rt),
370 		    0, NULL);
371 
372 	/*
373 	 * XXX There should be no need to check for rt_ifa belonging to this
374 	 * interface, because then rt_ifp is set, right?
375 	 */
376 
377 	return (0);
378 }
379 
380 /*
381  * Detach an interface from everything in the kernel.  Also deallocate
382  * private resources.
383  * XXX So far only the INET protocol family has been looked over
384  * wrt resource usage that needs to be decoupled.
385  */
386 void
387 if_detach(ifp)
388 	struct ifnet *ifp;
389 {
390 	struct ifaddr *ifa;
391 	int i, s = splimp();
392 	struct radix_node_head *rnh;
393 	struct domain *dp;
394 
395 	ifp->if_flags &= ~IFF_OACTIVE;
396 	ifp->if_start = if_detached_start;
397 	ifp->if_ioctl = if_detached_ioctl;
398 	ifp->if_init = if_detached_init;
399 	ifp->if_watchdog = if_detached_watchdog;
400 
401 #if NBRIDGE > 0
402 	/* Remove the interface from any bridge it is part of.  */
403 	if (ifp->if_bridge)
404 		bridge_ifdetach(ifp);
405 #endif
406 
407 #if NCARP > 0
408 	/* Remove the interface from any carp group it is a part of.  */
409 	if (ifp->if_carp)
410 		carp_ifdetach(ifp);
411 #endif
412 
413 #if NBPFILTER > 0
414 	/* If there is a bpf device attached, detach from it.  */
415 	if (ifp->if_bpf)
416 		bpfdetach(ifp);
417 #endif
418 #ifdef ALTQ
419 	if (ALTQ_IS_ENABLED(&ifp->if_snd))
420 		altq_disable(&ifp->if_snd);
421 	if (ALTQ_IS_ATTACHED(&ifp->if_snd))
422 		altq_detach(&ifp->if_snd);
423 #endif
424 
425 	/*
426 	 * Find and remove all routes which is using this interface.
427 	 * XXX Factor out into a route.c function?
428 	 */
429 	for (i = 1; i <= AF_MAX; i++) {
430 		rnh = rt_tables[i];
431 		if (rnh)
432 			(*rnh->rnh_walktree)(rnh, if_detach_rtdelete, ifp);
433 	}
434 
435 #ifdef INET
436 	rti_delete(ifp);
437 #if NETHER > 0
438 	myip_ifp = NULL;
439 #endif
440 #ifdef MROUTING
441 	vif_delete(ifp);
442 #endif
443 #endif
444 #ifdef INET6
445 	in6_ifdetach(ifp);
446 #endif
447 
448 	/*
449 	 * remove packets came from ifp, from software interrupt queues.
450 	 * net/netisr_dispatch.h is not usable, as some of them use
451 	 * strange queue names.
452 	 */
453 #define IF_DETACH_QUEUES(x) \
454 do { \
455 	extern struct ifqueue x; \
456 	if_detach_queues(ifp, & x); \
457 } while (0)
458 #ifdef INET
459 	IF_DETACH_QUEUES(arpintrq);
460 	IF_DETACH_QUEUES(ipintrq);
461 #endif
462 #ifdef INET6
463 	IF_DETACH_QUEUES(ip6intrq);
464 #endif
465 #ifdef IPX
466 	IF_DETACH_QUEUES(ipxintrq);
467 #endif
468 #ifdef NS
469 	IF_DETACH_QUEUES(nsintrq);
470 #endif
471 #ifdef NETATALK
472 	IF_DETACH_QUEUES(atintrq1);
473 	IF_DETACH_QUEUES(atintrq2);
474 #endif
475 #ifdef ISO
476 	IF_DETACH_QUEUES(clnlintrq);
477 #endif
478 #ifdef CCITT
479 	IF_DETACH_QUEUES(llcintrq);
480 #endif
481 #ifdef NATM
482 	IF_DETACH_QUEUES(natmintrq);
483 #endif
484 #ifdef DECNET
485 	IF_DETACH_QUEUES(decnetintrq);
486 #endif
487 #undef IF_DETACH_QUEUES
488 
489 	/*
490 	 * XXX transient ifp refs?  inpcb.ip_moptions.imo_multicast_ifp?
491 	 * Other network stacks than INET?
492 	 */
493 
494 	/* Remove the interface from the list of all interfaces.  */
495 	TAILQ_REMOVE(&ifnet, ifp, if_list);
496 
497 	/*
498 	 * Deallocate private resources.
499 	 * XXX should consult refcnt and use IFAFREE
500 	 */
501 	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa;
502 	    ifa = TAILQ_FIRST(&ifp->if_addrlist)) {
503 		TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
504 #ifdef INET
505 		if (ifa->ifa_addr->sa_family == AF_INET)
506 			TAILQ_REMOVE(&in_ifaddr, (struct in_ifaddr *)ifa,
507 			    ia_list);
508 #endif
509 		free(ifa, M_IFADDR);
510 	}
511 	ifp->if_sadl = NULL;
512 	ifnet_addrs[ifp->if_index] = NULL;
513 
514 	free(ifp->if_addrhooks, M_TEMP);
515 
516 	for (dp = domains; dp; dp = dp->dom_next) {
517 		if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
518 			(*dp->dom_ifdetach)(ifp,
519 			    ifp->if_afdata[dp->dom_family]);
520 	}
521 
522 	splx(s);
523 }
524 
525 void
526 if_detach_queues(ifp, q)
527 	struct ifnet *ifp;
528 	struct ifqueue *q;
529 {
530 	struct mbuf *m, *prev, *next;
531 
532 	prev = NULL;
533 	for (m = q->ifq_head; m; m = next) {
534 		next = m->m_nextpkt;
535 #ifdef DIAGNOSTIC
536 		if ((m->m_flags & M_PKTHDR) == 0) {
537 			prev = m;
538 			continue;
539 		}
540 #endif
541 		if (m->m_pkthdr.rcvif != ifp) {
542 			prev = m;
543 			continue;
544 		}
545 
546 		if (prev)
547 			prev->m_nextpkt = m->m_nextpkt;
548 		else
549 			q->ifq_head = m->m_nextpkt;
550 		if (q->ifq_tail == m)
551 			q->ifq_tail = prev;
552 		q->ifq_len--;
553 
554 		m->m_nextpkt = NULL;
555 		m_freem(m);
556 		IF_DROP(q);
557 	}
558 }
559 
560 /*
561  * Locate an interface based on a complete address.
562  */
563 /*ARGSUSED*/
564 struct ifaddr *
565 ifa_ifwithaddr(addr)
566 	register struct sockaddr *addr;
567 {
568 	register struct ifnet *ifp;
569 	register struct ifaddr *ifa;
570 
571 #define	equal(a1, a2) \
572   (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
573 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
574 	    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
575 		if (ifa->ifa_addr->sa_family != addr->sa_family)
576 			continue;
577 		if (equal(addr, ifa->ifa_addr))
578 			return (ifa);
579 		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
580 		    /* IP6 doesn't have broadcast */
581 		    ifa->ifa_broadaddr->sa_len != 0 &&
582 		    equal(ifa->ifa_broadaddr, addr))
583 			return (ifa);
584 	    }
585 	}
586 	return (NULL);
587 }
588 /*
589  * Locate the point to point interface with a given destination address.
590  */
591 /*ARGSUSED*/
592 struct ifaddr *
593 ifa_ifwithdstaddr(addr)
594 	register struct sockaddr *addr;
595 {
596 	register struct ifnet *ifp;
597 	register struct ifaddr *ifa;
598 
599 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
600 	    if (ifp->if_flags & IFF_POINTOPOINT)
601 	        TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
602 			if (ifa->ifa_addr->sa_family != addr->sa_family ||
603 			    ifa->ifa_dstaddr == NULL)
604 				continue;
605 			if (equal(addr, ifa->ifa_dstaddr))
606 				return (ifa);
607 		}
608 	}
609 	return (NULL);
610 }
611 
612 /*
613  * Find an interface on a specific network.  If many, choice
614  * is most specific found.
615  */
616 struct ifaddr *
617 ifa_ifwithnet(addr)
618 	struct sockaddr *addr;
619 {
620 	register struct ifnet *ifp;
621 	register struct ifaddr *ifa;
622 	struct ifaddr *ifa_maybe = 0;
623 	u_int af = addr->sa_family;
624 	char *addr_data = addr->sa_data, *cplim;
625 
626 	if (af == AF_LINK) {
627 	    register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
628 	    if (sdl->sdl_index && sdl->sdl_index <= if_index)
629 		return (ifnet_addrs[sdl->sdl_index]);
630 	}
631 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
632 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
633 			register char *cp, *cp2, *cp3;
634 
635 			if (ifa->ifa_addr->sa_family != af ||
636 			    ifa->ifa_netmask == 0)
637 				next: continue;
638 			cp = addr_data;
639 			cp2 = ifa->ifa_addr->sa_data;
640 			cp3 = ifa->ifa_netmask->sa_data;
641 			cplim = (char *)ifa->ifa_netmask +
642 				ifa->ifa_netmask->sa_len;
643 			while (cp3 < cplim)
644 				if ((*cp++ ^ *cp2++) & *cp3++)
645 				    /* want to continue for() loop */
646 					goto next;
647 			if (ifa_maybe == 0 ||
648 			    rn_refines((caddr_t)ifa->ifa_netmask,
649 			    (caddr_t)ifa_maybe->ifa_netmask))
650 				ifa_maybe = ifa;
651 		}
652 	}
653 	return (ifa_maybe);
654 }
655 
656 /*
657  * Find an interface using a specific address family
658  */
659 struct ifaddr *
660 ifa_ifwithaf(af)
661 	register int af;
662 {
663 	register struct ifnet *ifp;
664 	register struct ifaddr *ifa;
665 
666 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
667 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
668 			if (ifa->ifa_addr->sa_family == af)
669 				return (ifa);
670 		}
671 	}
672 	return (NULL);
673 }
674 
675 /*
676  * Find an interface address specific to an interface best matching
677  * a given address.
678  */
679 struct ifaddr *
680 ifaof_ifpforaddr(addr, ifp)
681 	struct sockaddr *addr;
682 	register struct ifnet *ifp;
683 {
684 	register struct ifaddr *ifa;
685 	register char *cp, *cp2, *cp3;
686 	register char *cplim;
687 	struct ifaddr *ifa_maybe = 0;
688 	u_int af = addr->sa_family;
689 
690 	if (af >= AF_MAX)
691 		return (NULL);
692 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
693 		if (ifa->ifa_addr->sa_family != af)
694 			continue;
695 		ifa_maybe = ifa;
696 		if (ifa->ifa_netmask == 0) {
697 			if (equal(addr, ifa->ifa_addr) ||
698 			    (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
699 				return (ifa);
700 			continue;
701 		}
702 		cp = addr->sa_data;
703 		cp2 = ifa->ifa_addr->sa_data;
704 		cp3 = ifa->ifa_netmask->sa_data;
705 		cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
706 		for (; cp3 < cplim; cp3++)
707 			if ((*cp++ ^ *cp2++) & *cp3)
708 				break;
709 		if (cp3 == cplim)
710 			return (ifa);
711 	}
712 	return (ifa_maybe);
713 }
714 
715 /*
716  * Default action when installing a route with a Link Level gateway.
717  * Lookup an appropriate real ifa to point to.
718  * This should be moved to /sys/net/link.c eventually.
719  */
720 void
721 link_rtrequest(cmd, rt, info)
722 	int cmd;
723 	register struct rtentry *rt;
724 	struct rt_addrinfo *info;
725 {
726 	register struct ifaddr *ifa;
727 	struct sockaddr *dst;
728 	struct ifnet *ifp;
729 
730 	if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
731 	    ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
732 		return;
733 	if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) {
734 		IFAFREE(rt->rt_ifa);
735 		rt->rt_ifa = ifa;
736 		ifa->ifa_refcnt++;
737 		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
738 			ifa->ifa_rtrequest(cmd, rt, info);
739 	}
740 }
741 
742 /*
743  * Mark an interface down and notify protocols of
744  * the transition.
745  * NOTE: must be called at splsoftnet or equivalent.
746  */
747 void
748 if_down(struct ifnet *ifp)
749 {
750 	struct ifaddr *ifa;
751 
752 	splassert(IPL_SOFTNET);
753 
754 	ifp->if_flags &= ~IFF_UP;
755 	microtime(&ifp->if_lastchange);
756 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
757 		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
758 	}
759 	IFQ_PURGE(&ifp->if_snd);
760 	rt_ifmsg(ifp);
761 }
762 
763 /*
764  * Mark an interface up and notify protocols of
765  * the transition.
766  * NOTE: must be called at splsoftnet or equivalent.
767  */
768 void
769 if_up(struct ifnet *ifp)
770 {
771 #ifdef notyet
772 	struct ifaddr *ifa;
773 #endif
774 
775 	splassert(IPL_SOFTNET);
776 
777 	ifp->if_flags |= IFF_UP;
778 	microtime(&ifp->if_lastchange);
779 #ifdef notyet
780 	/* this has no effect on IP, and will kill all ISO connections XXX */
781 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
782 		pfctlinput(PRC_IFUP, ifa->ifa_addr);
783 	}
784 #endif
785 	rt_ifmsg(ifp);
786 #ifdef INET6
787 	in6_if_up(ifp);
788 #endif
789 }
790 
791 /*
792  * Flush an interface queue.
793  */
794 void
795 if_qflush(ifq)
796 	register struct ifqueue *ifq;
797 {
798 	register struct mbuf *m, *n;
799 
800 	n = ifq->ifq_head;
801 	while ((m = n) != NULL) {
802 		n = m->m_act;
803 		m_freem(m);
804 	}
805 	ifq->ifq_head = 0;
806 	ifq->ifq_tail = 0;
807 	ifq->ifq_len = 0;
808 }
809 
810 /*
811  * Handle interface watchdog timer routines.  Called
812  * from softclock, we decrement timers (if set) and
813  * call the appropriate interface routine on expiration.
814  */
815 void
816 if_slowtimo(arg)
817 	void *arg;
818 {
819 	struct timeout *to = (struct timeout *)arg;
820 	struct ifnet *ifp;
821 	int s = splimp();
822 
823 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
824 		if (ifp->if_timer == 0 || --ifp->if_timer)
825 			continue;
826 		if (ifp->if_watchdog)
827 			(*ifp->if_watchdog)(ifp);
828 	}
829 	splx(s);
830 	timeout_add(to, hz / IFNET_SLOWHZ);
831 }
832 
833 /*
834  * Map interface name to
835  * interface structure pointer.
836  */
837 struct ifnet *
838 ifunit(name)
839 	register char *name;
840 {
841 	register struct ifnet *ifp;
842 
843 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
844 		if (strcmp(ifp->if_xname, name) == 0)
845 			return (ifp);
846 	}
847 	return (NULL);
848 }
849 
850 /*
851  * Interface ioctls.
852  */
853 int
854 ifioctl(so, cmd, data, p)
855 	struct socket *so;
856 	u_long cmd;
857 	caddr_t data;
858 	struct proc *p;
859 {
860 	register struct ifnet *ifp;
861 	register struct ifreq *ifr;
862 	int error = 0;
863 	short oif_flags;
864 
865 	switch (cmd) {
866 
867 	case SIOCGIFCONF:
868 	case OSIOCGIFCONF:
869 		return (ifconf(cmd, data));
870 	}
871 	ifr = (struct ifreq *)data;
872 	ifp = ifunit(ifr->ifr_name);
873 	if (ifp == 0)
874 		return (ENXIO);
875 	oif_flags = ifp->if_flags;
876 	switch (cmd) {
877 
878 	case SIOCGIFFLAGS:
879 		ifr->ifr_flags = ifp->if_flags;
880 		break;
881 
882 	case SIOCGIFMETRIC:
883 		ifr->ifr_metric = ifp->if_metric;
884 		break;
885 
886 	case SIOCGIFMTU:
887 		ifr->ifr_mtu = ifp->if_mtu;
888 		break;
889 
890 	case SIOCGIFDATA:
891 		error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
892 		    sizeof(ifp->if_data));
893 		break;
894 
895 	case SIOCSIFFLAGS:
896 		if ((error = suser(p, 0)) != 0)
897 			return (error);
898 		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
899 			int s = splimp();
900 			if_down(ifp);
901 			splx(s);
902 		}
903 		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
904 			int s = splimp();
905 			if_up(ifp);
906 			splx(s);
907 		}
908 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
909 			(ifr->ifr_flags &~ IFF_CANTCHANGE);
910 		if (ifp->if_ioctl)
911 			(void) (*ifp->if_ioctl)(ifp, cmd, data);
912 		break;
913 
914 	case SIOCSIFMETRIC:
915 		if ((error = suser(p, 0)) != 0)
916 			return (error);
917 		ifp->if_metric = ifr->ifr_metric;
918 		break;
919 
920 	case SIOCSIFMTU:
921 	{
922 #ifdef INET6
923 		int oldmtu = ifp->if_mtu;
924 #endif
925 
926 		if ((error = suser(p, 0)) != 0)
927 			return (error);
928 		if (ifp->if_ioctl == NULL)
929 			return (EOPNOTSUPP);
930 		error = (*ifp->if_ioctl)(ifp, cmd, data);
931 
932 		/*
933 		 * If the link MTU changed, do network layer specific procedure.
934 		 */
935 #ifdef INET6
936 		if (ifp->if_mtu != oldmtu)
937 			nd6_setmtu(ifp);
938 #endif
939 		break;
940 	}
941 
942 	case SIOCSIFPHYADDR:
943 	case SIOCDIFPHYADDR:
944 #ifdef INET6
945 	case SIOCSIFPHYADDR_IN6:
946 #endif
947 	case SIOCSLIFPHYADDR:
948 	case SIOCADDMULTI:
949 	case SIOCDELMULTI:
950 	case SIOCSIFMEDIA:
951 		if ((error = suser(p, 0)) != 0)
952 			return (error);
953 		/* FALLTHROUGH */
954 	case SIOCGIFPSRCADDR:
955 	case SIOCGIFPDSTADDR:
956 	case SIOCGLIFPHYADDR:
957 	case SIOCGIFMEDIA:
958 		if (ifp->if_ioctl == 0)
959 			return (EOPNOTSUPP);
960 		error = (*ifp->if_ioctl)(ifp, cmd, data);
961 		break;
962 
963 	default:
964 		if (so->so_proto == 0)
965 			return (EOPNOTSUPP);
966 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4)
967 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
968 			(struct mbuf *) cmd, (struct mbuf *) data,
969 			(struct mbuf *) ifp));
970 #else
971 	    {
972 		u_long ocmd = cmd;
973 
974 		switch (cmd) {
975 
976 		case SIOCSIFADDR:
977 		case SIOCSIFDSTADDR:
978 		case SIOCSIFBRDADDR:
979 		case SIOCSIFNETMASK:
980 #if BYTE_ORDER != BIG_ENDIAN
981 			if (ifr->ifr_addr.sa_family == 0 &&
982 			    ifr->ifr_addr.sa_len < 16) {
983 				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
984 				ifr->ifr_addr.sa_len = 16;
985 			}
986 #else
987 			if (ifr->ifr_addr.sa_len == 0)
988 				ifr->ifr_addr.sa_len = 16;
989 #endif
990 			break;
991 
992 		case OSIOCGIFADDR:
993 			cmd = SIOCGIFADDR;
994 			break;
995 
996 		case OSIOCGIFDSTADDR:
997 			cmd = SIOCGIFDSTADDR;
998 			break;
999 
1000 		case OSIOCGIFBRDADDR:
1001 			cmd = SIOCGIFBRDADDR;
1002 			break;
1003 
1004 		case OSIOCGIFNETMASK:
1005 			cmd = SIOCGIFNETMASK;
1006 		}
1007 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1008 		    (struct mbuf *) cmd, (struct mbuf *) data,
1009 		    (struct mbuf *) ifp));
1010 		switch (ocmd) {
1011 
1012 		case OSIOCGIFADDR:
1013 		case OSIOCGIFDSTADDR:
1014 		case OSIOCGIFBRDADDR:
1015 		case OSIOCGIFNETMASK:
1016 			*(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1017 		}
1018 
1019 	    }
1020 #endif
1021 		break;
1022 	}
1023 
1024 	if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1025 #ifdef INET6
1026 		if ((ifp->if_flags & IFF_UP) != 0) {
1027 			int s = splnet();
1028 			in6_if_up(ifp);
1029 			splx(s);
1030 		}
1031 #endif
1032   	}
1033 	return (error);
1034 }
1035 
1036 /*
1037  * Return interface configuration
1038  * of system.  List may be used
1039  * in later ioctl's (above) to get
1040  * other information.
1041  */
1042 /*ARGSUSED*/
1043 int
1044 ifconf(cmd, data)
1045 	u_long cmd;
1046 	caddr_t data;
1047 {
1048 	register struct ifconf *ifc = (struct ifconf *)data;
1049 	register struct ifnet *ifp;
1050 	register struct ifaddr *ifa;
1051 	struct ifreq ifr, *ifrp;
1052 	int space = ifc->ifc_len, error = 0;
1053 
1054 	/* If ifc->ifc_len is 0, fill it in with the needed size and return. */
1055 	if (space == 0) {
1056 		TAILQ_FOREACH(ifp, &ifnet, if_list) {
1057 			register struct sockaddr *sa;
1058 
1059 			if (TAILQ_EMPTY(&ifp->if_addrlist))
1060 				space += sizeof (ifr);
1061 			else
1062 				TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1063 					sa = ifa->ifa_addr;
1064 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1065 					if (cmd != OSIOCGIFCONF)
1066 #endif
1067 					if (sa->sa_len > sizeof(*sa))
1068 						space += sa->sa_len -
1069 						    sizeof (*sa);
1070 					space += sizeof (ifr);
1071 				}
1072 		}
1073 		ifc->ifc_len = space;
1074 		return (0);
1075 	}
1076 
1077 	ifrp = ifc->ifc_req;
1078 	for (ifp = TAILQ_FIRST(&ifnet); space >= sizeof(ifr) &&
1079 	    ifp != TAILQ_END(&ifnet); ifp = TAILQ_NEXT(ifp, if_list)) {
1080 		bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1081 		if (TAILQ_EMPTY(&ifp->if_addrlist)) {
1082 			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1083 			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1084 			    sizeof(ifr));
1085 			if (error)
1086 				break;
1087 			space -= sizeof (ifr), ifrp++;
1088 		} else
1089 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist);
1090 			    space >= sizeof (ifr) &&
1091 			    ifa != TAILQ_END(&ifp->if_addrlist);
1092 			    ifa = TAILQ_NEXT(ifa, ifa_list)) {
1093 				register struct sockaddr *sa = ifa->ifa_addr;
1094 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4)
1095 				if (cmd == OSIOCGIFCONF) {
1096 					struct osockaddr *osa =
1097 					    (struct osockaddr *)&ifr.ifr_addr;
1098 					ifr.ifr_addr = *sa;
1099 					osa->sa_family = sa->sa_family;
1100 					error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1101 					    sizeof (ifr));
1102 					ifrp++;
1103 				} else
1104 #endif
1105 				if (sa->sa_len <= sizeof(*sa)) {
1106 					ifr.ifr_addr = *sa;
1107 					error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1108 					    sizeof (ifr));
1109 					ifrp++;
1110 				} else {
1111 					space -= sa->sa_len - sizeof(*sa);
1112 					if (space < sizeof (ifr))
1113 						break;
1114 					error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1115 					    sizeof (ifr.ifr_name));
1116 					if (error == 0)
1117 						error = copyout((caddr_t)sa,
1118 						    (caddr_t)&ifrp->ifr_addr,
1119 						    sa->sa_len);
1120 					ifrp = (struct ifreq *)(sa->sa_len +
1121 					    (caddr_t)&ifrp->ifr_addr);
1122 				}
1123 				if (error)
1124 					break;
1125 				space -= sizeof (ifr);
1126 			}
1127 	}
1128 	ifc->ifc_len -= space;
1129 	return (error);
1130 }
1131 
1132 /*
1133  * Dummy functions replaced in ifnet during detach (if protocols decide to
1134  * fiddle with the if during detach.
1135  */
1136 void
1137 if_detached_start(struct ifnet *ifp)
1138 {
1139 	struct mbuf *m;
1140 
1141 	while (1) {
1142 		IF_DEQUEUE(&ifp->if_snd, m);
1143 
1144 		if (m == NULL)
1145 			return;
1146 		m_freem(m);
1147 	}
1148 }
1149 
1150 int
1151 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
1152 {
1153 	return ENODEV;
1154 }
1155 
1156 int
1157 if_detached_init(struct ifnet *ifp)
1158 {
1159 	return (ENXIO);
1160 }
1161 
1162 void
1163 if_detached_watchdog(struct ifnet *ifp)
1164 {
1165 	/* nothing */
1166 }
1167 
1168 /*
1169  * Set/clear promiscuous mode on interface ifp based on the truth value
1170  * of pswitch.  The calls are reference counted so that only the first
1171  * "on" request actually has an effect, as does the final "off" request.
1172  * Results are undefined if the "off" and "on" requests are not matched.
1173  */
1174 int
1175 ifpromisc(ifp, pswitch)
1176 	struct ifnet *ifp;
1177 	int pswitch;
1178 {
1179 	struct ifreq ifr;
1180 
1181 	if (pswitch) {
1182 		/*
1183 		 * If the device is not configured up, we cannot put it in
1184 		 * promiscuous mode.
1185 		 */
1186 		if ((ifp->if_flags & IFF_UP) == 0)
1187 			return (ENETDOWN);
1188 		if (ifp->if_pcount++ != 0)
1189 			return (0);
1190 		ifp->if_flags |= IFF_PROMISC;
1191 	} else {
1192 		if (--ifp->if_pcount > 0)
1193 			return (0);
1194 		ifp->if_flags &= ~IFF_PROMISC;
1195 		/*
1196 		 * If the device is not configured up, we should not need to
1197 		 * turn off promiscuous mode (device should have turned it
1198 		 * off when interface went down; and will look at IFF_PROMISC
1199 		 * again next time interface comes up).
1200 		 */
1201 		if ((ifp->if_flags & IFF_UP) == 0)
1202 			return (0);
1203 	}
1204 	ifr.ifr_flags = ifp->if_flags;
1205 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
1206 }
1207