1 /**	$MirOS: src/sys/net/if.c,v 1.8 2010/09/24 19:27:32 tg Exp $ */
2 /*	$OpenBSD: if.c,v 1.136 2005/06/23 14:30:40 mickey Exp $	*/
3 /*	$NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $	*/
4 
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /*
35  * Copyright (c) 1980, 1986, 1993
36  *	The Regents of the University of California.  All rights reserved.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. Neither the name of the University nor the names of its contributors
47  *    may be used to endorse or promote products derived from this software
48  *    without specific prior written permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60  * SUCH DAMAGE.
61  *
62  *	@(#)if.c	8.3 (Berkeley) 1/4/94
63  */
64 
65 #include "bpfilter.h"
66 #include "bridge.h"
67 #include "carp.h"
68 #include "pf.h"
69 
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/mbuf.h>
73 #include <sys/proc.h>
74 #include <sys/socket.h>
75 #include <sys/socketvar.h>
76 #include <sys/protosw.h>
77 #include <sys/kernel.h>
78 #include <sys/ioctl.h>
79 #include <sys/domain.h>
80 #include <sys/sysctl.h>
81 
82 #include <net/if.h>
83 #include <net/if_dl.h>
84 #include <net/if_media.h>
85 #include <net/if_types.h>
86 #include <net/route.h>
87 #include <net/netisr.h>
88 
89 #include <dev/rndvar.h>
90 
91 #ifdef INET
92 #include <netinet/in.h>
93 #include <netinet/in_var.h>
94 #include <netinet/if_ether.h>
95 #include <netinet/igmp.h>
96 #ifdef MROUTING
97 #include <netinet/ip_mroute.h>
98 #endif
99 #endif
100 
101 #ifdef INET6
102 #ifndef INET
103 #include <netinet/in.h>
104 #endif
105 #include <netinet6/in6_ifattach.h>
106 #include <netinet6/nd6.h>
107 #endif
108 
109 #if NBPFILTER > 0
110 #include <net/bpf.h>
111 #endif
112 
113 #if NBRIDGE > 0
114 #include <net/if_bridge.h>
115 #endif
116 
117 #if NCARP > 0
118 #include <netinet/ip_carp.h>
119 #endif
120 
121 #if NPF > 0
122 #include <net/pfvar.h>
123 #endif
124 
125 void	if_attachsetup(struct ifnet *);
126 void	if_attachdomain1(struct ifnet *);
127 int	if_detach_rtdelete(struct radix_node *, void *);
128 
129 int	ifqmaxlen = IFQ_MAXLEN;
130 
131 void	if_detach_queues(struct ifnet *, struct ifqueue *);
132 void	if_detached_start(struct ifnet *);
133 int	if_detached_ioctl(struct ifnet *, u_long, caddr_t);
134 int	if_detached_init(struct ifnet *);
135 void	if_detached_watchdog(struct ifnet *);
136 
137 int	if_clone_list(struct if_clonereq *);
138 struct if_clone	*if_clone_lookup(const char *, int *);
139 
140 void	if_congestion_clear(void *);
141 
142 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
143 int if_cloners_count;
144 
145 /*
146  * Network interface utility routines.
147  *
148  * Routines with ifa_ifwith* names take sockaddr *'s as
149  * parameters.
150  */
151 void
ifinit()152 ifinit()
153 {
154 	static struct timeout if_slowtim;
155 
156 	timeout_set(&if_slowtim, if_slowtimo, &if_slowtim);
157 
158 	if_slowtimo(&if_slowtim);
159 }
160 
161 static int if_index = 0;
162 int if_indexlim = 0;
163 struct ifaddr **ifnet_addrs = NULL;
164 struct ifnet **ifindex2ifnet = NULL;
165 struct ifnet_head ifnet;
166 struct ifnet *lo0ifp;
167 
168 /*
169  * Attach an interface to the
170  * list of "active" interfaces.
171  */
172 void
if_attachsetup(struct ifnet * ifp)173 if_attachsetup(struct ifnet *ifp)
174 {
175 	struct ifaddr *ifa;
176 	int wrapped = 0;
177 
178 	if (ifindex2ifnet == 0)
179 		if_index = 1;
180 	else {
181 		while (if_index < if_indexlim &&
182 		    ifindex2ifnet[if_index] != NULL) {
183 			if_index++;
184 			/*
185 			 * If we hit USHRT_MAX, we skip back to 1 since
186 			 * there are a number of places where the value
187 			 * of ifp->if_index or if_index itself is compared
188 			 * to or stored in an unsigned short.  By
189 			 * jumping back, we won't botch those assignments
190 			 * or comparisons.
191 			 */
192 			if (if_index == USHRT_MAX) {
193 				if_index = 1;
194 				/*
195 				 * However, if we have to jump back to 1
196 				 * *twice* without finding an empty
197 				 * slot in ifindex2ifnet[], then there
198 				 * there are too many (>65535) interfaces.
199 				 */
200 				if (wrapped++)
201 					panic("too many interfaces");
202 			}
203 		}
204 	}
205 	ifp->if_index = if_index;
206 
207 	/*
208 	 * We have some arrays that should be indexed by if_index.
209 	 * since if_index will grow dynamically, they should grow too.
210 	 *	struct ifadd **ifnet_addrs
211 	 *	struct ifnet **ifindex2ifnet
212 	 */
213 	if (ifnet_addrs == 0 || ifindex2ifnet == 0 || if_index >= if_indexlim) {
214 		size_t m, n, oldlim;
215 		caddr_t q;
216 
217 		oldlim = if_indexlim;
218 		if (if_indexlim == 0)
219 			if_indexlim = 8;
220 		while (if_index >= if_indexlim)
221 			if_indexlim <<= 1;
222 
223 		/* grow ifnet_addrs */
224 		m = oldlim * sizeof(ifa);
225 		n = if_indexlim * sizeof(ifa);
226 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
227 		bzero(q, n);
228 		if (ifnet_addrs) {
229 			bcopy((caddr_t)ifnet_addrs, q, m);
230 			free((caddr_t)ifnet_addrs, M_IFADDR);
231 		}
232 		ifnet_addrs = (struct ifaddr **)q;
233 
234 		/* grow ifindex2ifnet */
235 		m = oldlim * sizeof(struct ifnet *);
236 		n = if_indexlim * sizeof(struct ifnet *);
237 		q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK);
238 		bzero(q, n);
239 		if (ifindex2ifnet) {
240 			bcopy((caddr_t)ifindex2ifnet, q, m);
241 			free((caddr_t)ifindex2ifnet, M_IFADDR);
242 		}
243 		ifindex2ifnet = (struct ifnet **)q;
244 	}
245 
246 	ifindex2ifnet[if_index] = ifp;
247 
248 	if (ifp->if_snd.ifq_maxlen == 0)
249 		ifp->if_snd.ifq_maxlen = ifqmaxlen;
250 #ifdef ALTQ
251 	ifp->if_snd.altq_type = 0;
252 	ifp->if_snd.altq_disc = NULL;
253 	ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
254 	ifp->if_snd.altq_tbr  = NULL;
255 	ifp->if_snd.altq_ifp  = ifp;
256 #endif
257 
258 	if (domains)
259 		if_attachdomain1(ifp);
260 #if NPF > 0
261 	pfi_attach_ifnet(ifp);
262 #endif
263 
264 	/* Announce the interface. */
265 	rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
266 }
267 
268 /*
269  * Allocate the link level name for the specified interface.  This
270  * is an attachment helper.  It must be called after ifp->if_addrlen
271  * is initialized, which may not be the case when if_attach() is
272  * called.
273  */
274 void
if_alloc_sadl(struct ifnet * ifp)275 if_alloc_sadl(struct ifnet *ifp)
276 {
277 	unsigned socksize, ifasize;
278 	int namelen, masklen;
279 	struct sockaddr_dl *sdl;
280 	struct ifaddr *ifa;
281 
282 	/*
283 	 * If the interface already has a link name, release it
284 	 * now.  This is useful for interfaces that can change
285 	 * link types, and thus switch link names often.
286 	 */
287 	if (ifp->if_sadl != NULL)
288 		if_free_sadl(ifp);
289 
290 	namelen = strlen(ifp->if_xname);
291 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
292 	masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
293 	socksize = masklen + ifp->if_addrlen;
294 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
295 	if (socksize < sizeof(*sdl))
296 		socksize = sizeof(*sdl);
297 	socksize = ROUNDUP(socksize);
298 	ifasize = sizeof(*ifa) + 2 * socksize;
299 	ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
300 	bzero((caddr_t)ifa, ifasize);
301 	sdl = (struct sockaddr_dl *)(ifa + 1);
302 	sdl->sdl_len = socksize;
303 	sdl->sdl_family = AF_LINK;
304 	bcopy(ifp->if_xname, sdl->sdl_data, namelen);
305 	sdl->sdl_nlen = namelen;
306 	sdl->sdl_alen = ifp->if_addrlen;
307 	sdl->sdl_index = ifp->if_index;
308 	sdl->sdl_type = ifp->if_type;
309 	ifnet_addrs[ifp->if_index] = ifa;
310 	ifa->ifa_ifp = ifp;
311 	ifa->ifa_rtrequest = link_rtrequest;
312 	TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
313 	ifa->ifa_addr = (struct sockaddr *)sdl;
314 	ifp->if_sadl = sdl;
315 	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
316 	ifa->ifa_netmask = (struct sockaddr *)sdl;
317 	sdl->sdl_len = masklen;
318 	while (namelen != 0)
319 		sdl->sdl_data[--namelen] = 0xff;
320 }
321 
322 /*
323  * Free the link level name for the specified interface.  This is
324  * a detach helper.  This is called from if_detach() or from
325  * link layer type specific detach functions.
326  */
327 void
if_free_sadl(struct ifnet * ifp)328 if_free_sadl(struct ifnet *ifp)
329 {
330 	struct ifaddr *ifa;
331 	int s;
332 
333 	ifa = ifnet_addrs[ifp->if_index];
334 	if (ifa == NULL)
335 		return;
336 
337 	s = splnet();
338 	rtinit(ifa, RTM_DELETE, 0);
339 #if 0
340 	TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
341 	ifnet_addrs[ifp->if_index] = NULL;
342 #endif
343 	ifp->if_sadl = NULL;
344 
345 	splx(s);
346 }
347 
348 void
if_attachdomain()349 if_attachdomain()
350 {
351 	struct ifnet *ifp;
352 	int s;
353 
354 	s = splnet();
355 	for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list))
356 		if_attachdomain1(ifp);
357 	splx(s);
358 }
359 
360 void
if_attachdomain1(struct ifnet * ifp)361 if_attachdomain1(struct ifnet *ifp)
362 {
363 	struct domain *dp;
364 	int s;
365 
366 	s = splnet();
367 
368 	/* address family dependent data region */
369 	bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
370 	for (dp = domains; dp; dp = dp->dom_next) {
371 		if (dp->dom_ifattach)
372 			ifp->if_afdata[dp->dom_family] =
373 			    (*dp->dom_ifattach)(ifp);
374 	}
375 
376 	splx(s);
377 }
378 
379 void
if_attachhead(struct ifnet * ifp)380 if_attachhead(struct ifnet *ifp)
381 {
382 	if (if_index == 0) {
383 		TAILQ_INIT(&ifnet);
384 	}
385 	TAILQ_INIT(&ifp->if_addrlist);
386 	ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
387 	    M_TEMP, M_NOWAIT);
388 	if (ifp->if_addrhooks == NULL)
389 		panic("if_attachhead: malloc");
390 	TAILQ_INIT(ifp->if_addrhooks);
391 	ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks),
392 	    M_TEMP, M_NOWAIT);
393 	if (ifp->if_linkstatehooks == NULL)
394 		panic("if_attachhead: malloc");
395 	TAILQ_INIT(ifp->if_linkstatehooks);
396 	TAILQ_INSERT_HEAD(&ifnet, ifp, if_list);
397 	if_attachsetup(ifp);
398 }
399 
400 void
if_attach(struct ifnet * ifp)401 if_attach(struct ifnet *ifp)
402 {
403 #if NCARP > 0
404 	struct ifnet *before = NULL;
405 #endif
406 
407 	if (if_index == 0) {
408 		TAILQ_INIT(&ifnet);
409 	}
410 	TAILQ_INIT(&ifp->if_addrlist);
411 	ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
412 	    M_TEMP, M_NOWAIT);
413 	if (ifp->if_addrhooks == NULL)
414 		panic("if_attach: malloc");
415 	TAILQ_INIT(ifp->if_addrhooks);
416 	ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks),
417 	    M_TEMP, M_NOWAIT);
418 	if (ifp->if_linkstatehooks == NULL)
419 		panic("if_attach: malloc");
420 	TAILQ_INIT(ifp->if_linkstatehooks);
421 
422 #if NCARP > 0
423 	if (ifp->if_type != IFT_CARP)
424 		TAILQ_FOREACH(before, &ifnet, if_list)
425 			if (before->if_type == IFT_CARP)
426 				break;
427 	if (before == NULL)
428 		TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
429 	else
430 		TAILQ_INSERT_BEFORE(before, ifp, if_list);
431 #else
432 	TAILQ_INSERT_TAIL(&ifnet, ifp, if_list);
433 #endif
434 
435 	if_attachsetup(ifp);
436 }
437 
438 /*
439  * Delete a route if it has a specific interface for output.
440  * This function complies to the rn_walktree callback API.
441  *
442  * Note that deleting a RTF_CLONING route can trigger the
443  * deletion of more entries, so we need to cancel the walk
444  * and return EAGAIN.  The caller should restart the walk
445  * as long as EAGAIN is returned.
446  */
447 int
if_detach_rtdelete(struct radix_node * rn,void * vifp)448 if_detach_rtdelete(struct radix_node *rn, void *vifp)
449 {
450 	struct ifnet *ifp = vifp;
451 	struct rtentry *rt = (struct rtentry *)rn;
452 
453 	if (rt->rt_ifp == ifp) {
454 		int cloning = (rt->rt_flags & RTF_CLONING);
455 
456 		if (rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
457 		    rt_mask(rt), 0, NULL) == 0 && cloning)
458 			return (EAGAIN);
459 	}
460 
461 	/*
462 	 * XXX There should be no need to check for rt_ifa belonging to this
463 	 * interface, because then rt_ifp is set, right?
464 	 */
465 
466 	return (0);
467 }
468 
469 /*
470  * Detach an interface from everything in the kernel.  Also deallocate
471  * private resources.
472  * XXX So far only the INET protocol family has been looked over
473  * wrt resource usage that needs to be decoupled.
474  */
475 void
if_detach(struct ifnet * ifp)476 if_detach(struct ifnet *ifp)
477 {
478 	struct ifaddr *ifa;
479 	int i, s = splimp();
480 	struct radix_node_head *rnh;
481 	struct domain *dp;
482 
483 	ifp->if_flags &= ~IFF_OACTIVE;
484 	ifp->if_start = if_detached_start;
485 	ifp->if_ioctl = if_detached_ioctl;
486 	ifp->if_init = if_detached_init;
487 	ifp->if_watchdog = if_detached_watchdog;
488 
489 #if NBRIDGE > 0
490 	/* Remove the interface from any bridge it is part of.  */
491 	if (ifp->if_bridge)
492 		bridge_ifdetach(ifp);
493 #endif
494 
495 #if NCARP > 0
496 	/* Remove the interface from any carp group it is a part of.  */
497 	if (ifp->if_carp && ifp->if_type != IFT_CARP)
498 		carp_ifdetach(ifp);
499 #endif
500 
501 #if NBPFILTER > 0
502 	bpfdetach(ifp);
503 #endif
504 #ifdef ALTQ
505 	if (ALTQ_IS_ENABLED(&ifp->if_snd))
506 		altq_disable(&ifp->if_snd);
507 	if (ALTQ_IS_ATTACHED(&ifp->if_snd))
508 		altq_detach(&ifp->if_snd);
509 #endif
510 
511 	/*
512 	 * Find and remove all routes which is using this interface.
513 	 * XXX Factor out into a route.c function?
514 	 */
515 	for (i = 1; i <= AF_MAX; i++) {
516 		rnh = rt_tables[i];
517 		if (rnh)
518 			while ((*rnh->rnh_walktree)(rnh,
519 			    if_detach_rtdelete, ifp) == EAGAIN)
520 				;
521 	}
522 
523 #ifdef INET
524 	rti_delete(ifp);
525 #if NETHER > 0
526 	myip_ifp = NULL;
527 #endif
528 #ifdef MROUTING
529 	vif_delete(ifp);
530 #endif
531 #endif
532 #ifdef INET6
533 	in6_ifdetach(ifp);
534 #endif
535 
536 #if NPF > 0
537 	pfi_detach_ifnet(ifp);
538 #endif
539 
540 	/*
541 	 * remove packets came from ifp, from software interrupt queues.
542 	 * net/netisr_dispatch.h is not usable, as some of them use
543 	 * strange queue names.
544 	 */
545 #define IF_DETACH_QUEUES(x) \
546 do { \
547 	extern struct ifqueue x; \
548 	if_detach_queues(ifp, & x); \
549 } while (0)
550 #ifdef INET
551 	IF_DETACH_QUEUES(arpintrq);
552 	IF_DETACH_QUEUES(ipintrq);
553 #endif
554 #ifdef INET6
555 	IF_DETACH_QUEUES(ip6intrq);
556 #endif
557 #ifdef IPX
558 	IF_DETACH_QUEUES(ipxintrq);
559 #endif
560 #ifdef NETATALK
561 	IF_DETACH_QUEUES(atintrq1);
562 	IF_DETACH_QUEUES(atintrq2);
563 #endif
564 #ifdef NATM
565 	IF_DETACH_QUEUES(natmintrq);
566 #endif
567 #undef IF_DETACH_QUEUES
568 
569 	/*
570 	 * XXX transient ifp refs?  inpcb.ip_moptions.imo_multicast_ifp?
571 	 * Other network stacks than INET?
572 	 */
573 
574 	/* Remove the interface from the list of all interfaces.  */
575 	TAILQ_REMOVE(&ifnet, ifp, if_list);
576 
577 	/*
578 	 * Deallocate private resources.
579 	 * XXX should consult refcnt and use IFAFREE
580 	 */
581 	for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa;
582 	    ifa = TAILQ_FIRST(&ifp->if_addrlist)) {
583 		TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
584 #ifdef INET
585 		if (ifa->ifa_addr->sa_family == AF_INET)
586 			TAILQ_REMOVE(&in_ifaddr, (struct in_ifaddr *)ifa,
587 			    ia_list);
588 #endif
589 		/* XXX if_free_sadl needs this */
590 		if (ifa == ifnet_addrs[ifp->if_index])
591 			continue;
592 
593 		free(ifa, M_IFADDR);
594 	}
595 	if_free_sadl(ifp);
596 
597 	free(ifnet_addrs[ifp->if_index], M_IFADDR);
598 	ifnet_addrs[ifp->if_index] = NULL;
599 
600 	free(ifp->if_addrhooks, M_TEMP);
601 	free(ifp->if_linkstatehooks, M_TEMP);
602 
603 	for (dp = domains; dp; dp = dp->dom_next) {
604 		if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
605 			(*dp->dom_ifdetach)(ifp,
606 			    ifp->if_afdata[dp->dom_family]);
607 	}
608 
609 	/* Announce that the interface is gone. */
610 	rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
611 
612 	splx(s);
613 }
614 
615 void
if_detach_queues(struct ifnet * ifp,struct ifqueue * q)616 if_detach_queues(struct ifnet *ifp, struct ifqueue *q)
617 {
618 	struct mbuf *m, *prev, *next;
619 
620 	prev = NULL;
621 	for (m = q->ifq_head; m; m = next) {
622 		next = m->m_nextpkt;
623 #ifdef DIAGNOSTIC
624 		if ((m->m_flags & M_PKTHDR) == 0) {
625 			prev = m;
626 			continue;
627 		}
628 #endif
629 		if (m->m_pkthdr.rcvif != ifp) {
630 			prev = m;
631 			continue;
632 		}
633 
634 		if (prev)
635 			prev->m_nextpkt = m->m_nextpkt;
636 		else
637 			q->ifq_head = m->m_nextpkt;
638 		if (q->ifq_tail == m)
639 			q->ifq_tail = prev;
640 		q->ifq_len--;
641 
642 		m->m_nextpkt = NULL;
643 		m_freem(m);
644 		IF_DROP(q);
645 	}
646 }
647 
648 /*
649  * Create a clone network interface.
650  */
651 int
if_clone_create(const char * name)652 if_clone_create(const char *name)
653 {
654 	struct if_clone *ifc;
655 	struct ifnet *ifp;
656 	int unit, ret;
657 
658 	ifc = if_clone_lookup(name, &unit);
659 	if (ifc == NULL)
660 		return (EINVAL);
661 
662 	if (ifunit(name) != NULL)
663 		return (EEXIST);
664 
665 	if ((ret = (*ifc->ifc_create)(ifc, unit)) != -1 &&
666 	    (ifp = ifunit(name)) != NULL)
667 		;
668 
669 	return (ret);
670 }
671 
672 /*
673  * Destroy a clone network interface.
674  */
675 int
if_clone_destroy(const char * name)676 if_clone_destroy(const char *name)
677 {
678 	struct if_clone *ifc;
679 	struct ifnet *ifp;
680 	int s, ret;
681 
682 	ifc = if_clone_lookup(name, NULL);
683 	if (ifc == NULL)
684 		return (EINVAL);
685 
686 	ifp = ifunit(name);
687 	if (ifp == NULL)
688 		return (ENXIO);
689 
690 	if (ifc->ifc_destroy == NULL)
691 		return (EOPNOTSUPP);
692 
693 	if (ifp->if_flags & IFF_UP) {
694 		s = splimp();
695 		if_down(ifp);
696 		splx(s);
697 	}
698 
699 	if ((ret = (*ifc->ifc_destroy)(ifp)) == -1)
700 		;
701 
702 	return (ret);
703 }
704 
705 /*
706  * Look up a network interface cloner.
707  */
708 struct if_clone *
if_clone_lookup(const char * name,int * unitp)709 if_clone_lookup(const char *name, int *unitp)
710 {
711 	struct if_clone *ifc;
712 	const char *cp;
713 	int unit;
714 
715 	/* separate interface name from unit */
716 	for (cp = name;
717 	    cp - name < IFNAMSIZ && *cp && (*cp < '0' || *cp > '9');
718 	    cp++)
719 		continue;
720 
721 	if (cp == name || cp - name == IFNAMSIZ || !*cp)
722 		return (NULL);	/* No name or unit number */
723 
724 	if (cp - name < IFNAMSIZ-1 && *cp == '0' && cp[1] != '\0')
725 		return (NULL);	/* unit number 0 padded */
726 
727 	LIST_FOREACH(ifc, &if_cloners, ifc_list) {
728 		if (strlen(ifc->ifc_name) == cp - name &&
729 		    !strncmp(name, ifc->ifc_name, cp - name))
730 			break;
731 	}
732 
733 	if (ifc == NULL)
734 		return (NULL);
735 
736 	unit = 0;
737 	while (cp - name < IFNAMSIZ && *cp) {
738 		if (*cp < '0' || *cp > '9' ||
739 		    unit > (INT_MAX - (*cp - '0')) / 10) {
740 			/* Bogus unit number. */
741 			return (NULL);
742 		}
743 		unit = (unit * 10) + (*cp++ - '0');
744 	}
745 
746 	if (unitp != NULL)
747 		*unitp = unit;
748 	return (ifc);
749 }
750 
751 /*
752  * Register a network interface cloner.
753  */
754 void
if_clone_attach(struct if_clone * ifc)755 if_clone_attach(struct if_clone *ifc)
756 {
757 	LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
758 	if_cloners_count++;
759 }
760 
761 /*
762  * Unregister a network interface cloner.
763  */
764 void
if_clone_detach(struct if_clone * ifc)765 if_clone_detach(struct if_clone *ifc)
766 {
767 
768 	LIST_REMOVE(ifc, ifc_list);
769 	if_cloners_count--;
770 }
771 
772 /*
773  * Provide list of interface cloners to userspace.
774  */
775 int
if_clone_list(struct if_clonereq * ifcr)776 if_clone_list(struct if_clonereq *ifcr)
777 {
778 	char outbuf[IFNAMSIZ], *dst;
779 	struct if_clone *ifc;
780 	int count, error = 0;
781 
782 	ifcr->ifcr_total = if_cloners_count;
783 	if ((dst = ifcr->ifcr_buffer) == NULL) {
784 		/* Just asking how many there are. */
785 		return (0);
786 	}
787 
788 	if (ifcr->ifcr_count < 0)
789 		return (EINVAL);
790 
791 	count = (if_cloners_count < ifcr->ifcr_count) ?
792 	    if_cloners_count : ifcr->ifcr_count;
793 
794 	for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
795 	     ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
796 		strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
797 		error = copyout(outbuf, dst, IFNAMSIZ);
798 		if (error)
799 			break;
800 	}
801 
802 	return (error);
803 }
804 
805 /*
806  * set queue congestion marker and register timeout to clear it
807  */
808 void
if_congestion(struct ifqueue * ifq)809 if_congestion(struct ifqueue *ifq)
810 {
811 	/* Not currently needed, all callers check this */
812 	if (ifq->ifq_congestion)
813 		return;
814 
815 	ifq->ifq_congestion = malloc(sizeof(struct timeout), M_TEMP, M_NOWAIT);
816 	if (ifq->ifq_congestion == NULL)
817 		return;
818 	timeout_set(ifq->ifq_congestion, if_congestion_clear, ifq);
819 	timeout_add(ifq->ifq_congestion, hz / 100);
820 }
821 
822 /*
823  * clear the congestion flag
824  */
825 void
if_congestion_clear(void * arg)826 if_congestion_clear(void *arg)
827 {
828 	struct ifqueue *ifq = arg;
829 	struct timeout *to = ifq->ifq_congestion;
830 
831 	ifq->ifq_congestion = NULL;
832 	free(to, M_TEMP);
833 }
834 
835 /*
836  * Locate an interface based on a complete address.
837  */
838 /*ARGSUSED*/
839 struct ifaddr *
ifa_ifwithaddr(struct sockaddr * addr)840 ifa_ifwithaddr(struct sockaddr *addr)
841 {
842 	struct ifnet *ifp;
843 	struct ifaddr *ifa;
844 
845 #define	equal(a1, a2)	\
846 	(bcmp((caddr_t)(a1), (caddr_t)(a2),	\
847 	((struct sockaddr *)(a1))->sa_len) == 0)
848 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
849 	    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
850 		if (ifa->ifa_addr->sa_family != addr->sa_family)
851 			continue;
852 		if (equal(addr, ifa->ifa_addr))
853 			return (ifa);
854 		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
855 		    /* IP6 doesn't have broadcast */
856 		    ifa->ifa_broadaddr->sa_len != 0 &&
857 		    equal(ifa->ifa_broadaddr, addr))
858 			return (ifa);
859 	    }
860 	}
861 	return (NULL);
862 }
863 /*
864  * Locate the point to point interface with a given destination address.
865  */
866 /*ARGSUSED*/
867 struct ifaddr *
ifa_ifwithdstaddr(struct sockaddr * addr)868 ifa_ifwithdstaddr(struct sockaddr *addr)
869 {
870 	struct ifnet *ifp;
871 	struct ifaddr *ifa;
872 
873 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
874 	    if (ifp->if_flags & IFF_POINTOPOINT)
875 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
876 			if (ifa->ifa_addr->sa_family != addr->sa_family ||
877 			    ifa->ifa_dstaddr == NULL)
878 				continue;
879 			if (equal(addr, ifa->ifa_dstaddr))
880 				return (ifa);
881 		}
882 	}
883 	return (NULL);
884 }
885 
886 /*
887  * Find an interface on a specific network.  If many, choice
888  * is most specific found.
889  */
890 struct ifaddr *
ifa_ifwithnet(struct sockaddr * addr)891 ifa_ifwithnet(struct sockaddr *addr)
892 {
893 	struct ifnet *ifp;
894 	struct ifaddr *ifa;
895 	struct ifaddr *ifa_maybe = 0;
896 	u_int af = addr->sa_family;
897 	char *addr_data = addr->sa_data, *cplim;
898 
899 	if (af == AF_LINK) {
900 		struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
901 		if (sdl->sdl_index && sdl->sdl_index < if_indexlim &&
902 		    ifindex2ifnet[sdl->sdl_index])
903 			return (ifnet_addrs[sdl->sdl_index]);
904 	}
905 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
906 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
907 			char *cp, *cp2, *cp3;
908 
909 			if (ifa->ifa_addr->sa_family != af ||
910 			    ifa->ifa_netmask == 0)
911 				next: continue;
912 			cp = addr_data;
913 			cp2 = ifa->ifa_addr->sa_data;
914 			cp3 = ifa->ifa_netmask->sa_data;
915 			cplim = (char *)ifa->ifa_netmask +
916 				ifa->ifa_netmask->sa_len;
917 			while (cp3 < cplim)
918 				if ((*cp++ ^ *cp2++) & *cp3++)
919 				    /* want to continue for() loop */
920 					goto next;
921 			if (ifa_maybe == 0 ||
922 			    rn_refines((caddr_t)ifa->ifa_netmask,
923 			    (caddr_t)ifa_maybe->ifa_netmask))
924 				ifa_maybe = ifa;
925 		}
926 	}
927 	return (ifa_maybe);
928 }
929 
930 /*
931  * Find an interface using a specific address family
932  */
933 struct ifaddr *
ifa_ifwithaf(int af)934 ifa_ifwithaf(int af)
935 {
936 	struct ifnet *ifp;
937 	struct ifaddr *ifa;
938 
939 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
940 		TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
941 			if (ifa->ifa_addr->sa_family == af)
942 				return (ifa);
943 		}
944 	}
945 	return (NULL);
946 }
947 
948 /*
949  * Find an interface address specific to an interface best matching
950  * a given address.
951  */
952 struct ifaddr *
ifaof_ifpforaddr(struct sockaddr * addr,struct ifnet * ifp)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
link_rtrequest(int cmd,struct rtentry * rt,struct rt_addrinfo * info)993 link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
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 		IFAFREE(rt->rt_ifa);
1004 		rt->rt_ifa = ifa;
1005 		ifa->ifa_refcnt++;
1006 		if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
1007 			ifa->ifa_rtrequest(cmd, rt, info);
1008 	}
1009 }
1010 
1011 /*
1012  * Mark an interface down and notify protocols of
1013  * the transition.
1014  * NOTE: must be called at splsoftnet or equivalent.
1015  */
1016 void
if_down(struct ifnet * ifp)1017 if_down(struct ifnet *ifp)
1018 {
1019 	struct ifaddr *ifa;
1020 
1021 	splassert(IPL_SOFTNET);
1022 
1023 	ifp->if_flags &= ~IFF_UP;
1024 	microtime(&ifp->if_lastchange);
1025 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1026 		pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
1027 	}
1028 	IFQ_PURGE(&ifp->if_snd);
1029 #if NCARP > 0
1030 	if (ifp->if_carp)
1031 		carp_carpdev_state(ifp);
1032 #endif
1033 	rt_ifmsg(ifp);
1034 }
1035 
1036 /*
1037  * Mark an interface up and notify protocols of
1038  * the transition.
1039  * NOTE: must be called at splsoftnet or equivalent.
1040  */
1041 void
if_up(struct ifnet * ifp)1042 if_up(struct ifnet *ifp)
1043 {
1044 #ifdef notyet
1045 	struct ifaddr *ifa;
1046 #endif
1047 
1048 	splassert(IPL_SOFTNET);
1049 
1050 	ifp->if_flags |= IFF_UP;
1051 	microtime(&ifp->if_lastchange);
1052 #ifdef notyet
1053 	/* this has no effect on IP, and will kill all ISO connections XXX */
1054 	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1055 		pfctlinput(PRC_IFUP, ifa->ifa_addr);
1056 	}
1057 #endif
1058 #if NCARP > 0
1059 	if (ifp->if_carp)
1060 		carp_carpdev_state(ifp);
1061 #endif
1062 	rt_ifmsg(ifp);
1063 #ifdef INET6
1064 	in6_if_up(ifp);
1065 #endif
1066 }
1067 
1068 /*
1069  * Process a link state change.
1070  * NOTE: must be called at splsoftnet or equivalent.
1071  */
1072 void
if_link_state_change(struct ifnet * ifp)1073 if_link_state_change(struct ifnet *ifp)
1074 {
1075 	rt_ifmsg(ifp);
1076 	dohooks(ifp->if_linkstatehooks, 0);
1077 }
1078 
1079 /*
1080  * Flush an interface queue.
1081  */
1082 void
if_qflush(struct ifqueue * ifq)1083 if_qflush(struct ifqueue *ifq)
1084 {
1085 	struct mbuf *m, *n;
1086 
1087 	n = ifq->ifq_head;
1088 	while ((m = n) != NULL) {
1089 		n = m->m_act;
1090 		m_freem(m);
1091 	}
1092 	ifq->ifq_head = 0;
1093 	ifq->ifq_tail = 0;
1094 	ifq->ifq_len = 0;
1095 }
1096 
1097 /*
1098  * Handle interface watchdog timer routines.  Called
1099  * from softclock, we decrement timers (if set) and
1100  * call the appropriate interface routine on expiration.
1101  */
1102 void
if_slowtimo(void * arg)1103 if_slowtimo(void *arg)
1104 {
1105 	struct timeout *to = (struct timeout *)arg;
1106 	struct ifnet *ifp;
1107 	int s = splimp();
1108 
1109 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
1110 		if (ifp->if_timer == 0 || --ifp->if_timer)
1111 			continue;
1112 		if (ifp->if_watchdog)
1113 			(*ifp->if_watchdog)(ifp);
1114 	}
1115 	splx(s);
1116 	timeout_add(to, hz / IFNET_SLOWHZ);
1117 }
1118 
1119 /*
1120  * Map interface name to
1121  * interface structure pointer.
1122  */
1123 struct ifnet *
ifunit(const char * name)1124 ifunit(const char *name)
1125 {
1126 	struct ifnet *ifp;
1127 
1128 	TAILQ_FOREACH(ifp, &ifnet, if_list) {
1129 		if (strcmp(ifp->if_xname, name) == 0)
1130 			return (ifp);
1131 	}
1132 	return (NULL);
1133 }
1134 
1135 /*
1136  * Interface ioctls.
1137  */
1138 int
ifioctl(struct socket * so,u_long cmd,caddr_t data,struct proc * p)1139 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1140 {
1141 	struct ifnet *ifp;
1142 	struct ifreq *ifr;
1143 	int error = 0;
1144 	short oif_flags;
1145 
1146 	switch (cmd) {
1147 
1148 	case SIOCGIFCONF:
1149 	case OSIOCGIFCONF:
1150 		return (ifconf(cmd, data));
1151 	}
1152 	ifr = (struct ifreq *)data;
1153 
1154 	switch (cmd) {
1155 	case SIOCIFCREATE:
1156 	case SIOCIFDESTROY:
1157 		if ((error = suser(p, 0)) != 0)
1158 			return (error);
1159 		return ((cmd == SIOCIFCREATE) ?
1160 		    if_clone_create(ifr->ifr_name) :
1161 		    if_clone_destroy(ifr->ifr_name));
1162 	case SIOCIFGCLONERS:
1163 		return (if_clone_list((struct if_clonereq *)data));
1164 	}
1165 
1166 	ifp = ifunit(ifr->ifr_name);
1167 	if (ifp == 0)
1168 		return (ENXIO);
1169 	oif_flags = ifp->if_flags;
1170 	switch (cmd) {
1171 
1172 	case SIOCGIFFLAGS:
1173 		ifr->ifr_flags = ifp->if_flags;
1174 		break;
1175 
1176 	case SIOCGIFMETRIC:
1177 		ifr->ifr_metric = ifp->if_metric;
1178 		break;
1179 
1180 	case SIOCGIFMTU:
1181 		ifr->ifr_mtu = ifp->if_mtu;
1182 		break;
1183 
1184 	case SIOCGIFDATA:
1185 		error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
1186 		    sizeof(ifp->if_data));
1187 		break;
1188 
1189 	case SIOCSIFFLAGS:
1190 		if ((error = suser(p, 0)) != 0)
1191 			return (error);
1192 		if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
1193 			int s = splimp();
1194 			if_down(ifp);
1195 			splx(s);
1196 		}
1197 		if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
1198 			int s = splimp();
1199 			if_up(ifp);
1200 			splx(s);
1201 		}
1202 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
1203 			(ifr->ifr_flags &~ IFF_CANTCHANGE);
1204 		if (ifp->if_ioctl)
1205 			(void) (*ifp->if_ioctl)(ifp, cmd, data);
1206 		break;
1207 
1208 	case SIOCSIFMETRIC:
1209 		if ((error = suser(p, 0)) != 0)
1210 			return (error);
1211 		ifp->if_metric = ifr->ifr_metric;
1212 		break;
1213 
1214 	case SIOCSIFMTU:
1215 	{
1216 #ifdef INET6
1217 		int oldmtu = ifp->if_mtu;
1218 #endif
1219 
1220 		if ((error = suser(p, 0)) != 0)
1221 			return (error);
1222 		if (ifp->if_ioctl == NULL)
1223 			return (EOPNOTSUPP);
1224 		error = (*ifp->if_ioctl)(ifp, cmd, data);
1225 
1226 		/*
1227 		 * If the link MTU changed, do network layer specific procedure.
1228 		 */
1229 #ifdef INET6
1230 		if (ifp->if_mtu != oldmtu)
1231 			nd6_setmtu(ifp);
1232 #endif
1233 		break;
1234 	}
1235 
1236 	case SIOCSIFPHYADDR:
1237 	case SIOCDIFPHYADDR:
1238 #ifdef INET6
1239 	case SIOCSIFPHYADDR_IN6:
1240 #endif
1241 	case SIOCSLIFPHYADDR:
1242 	case SIOCADDMULTI:
1243 	case SIOCDELMULTI:
1244 	case SIOCSIFMEDIA:
1245 		if ((error = suser(p, 0)) != 0)
1246 			return (error);
1247 		/* FALLTHROUGH */
1248 	case SIOCGIFPSRCADDR:
1249 	case SIOCGIFPDSTADDR:
1250 	case SIOCGLIFPHYADDR:
1251 	case SIOCGIFMEDIA:
1252 		if (ifp->if_ioctl == 0)
1253 			return (EOPNOTSUPP);
1254 		error = (*ifp->if_ioctl)(ifp, cmd, data);
1255 		break;
1256 
1257 	default:
1258 		if (so->so_proto == 0)
1259 			return (EOPNOTSUPP);
1260 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX)
1261 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1262 			(struct mbuf *) cmd, (struct mbuf *) data,
1263 			(struct mbuf *) ifp));
1264 #else
1265 	    {
1266 		u_long ocmd = cmd;
1267 
1268 		switch (cmd) {
1269 
1270 		case SIOCSIFADDR:
1271 		case SIOCSIFDSTADDR:
1272 		case SIOCSIFBRDADDR:
1273 		case SIOCSIFNETMASK:
1274 #if BYTE_ORDER != BIG_ENDIAN
1275 			if (ifr->ifr_addr.sa_family == 0 &&
1276 			    ifr->ifr_addr.sa_len < 16) {
1277 				ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
1278 				ifr->ifr_addr.sa_len = 16;
1279 			}
1280 #else
1281 			if (ifr->ifr_addr.sa_len == 0)
1282 				ifr->ifr_addr.sa_len = 16;
1283 #endif
1284 			break;
1285 
1286 		case OSIOCGIFADDR:
1287 			cmd = SIOCGIFADDR;
1288 			break;
1289 
1290 		case OSIOCGIFDSTADDR:
1291 			cmd = SIOCGIFDSTADDR;
1292 			break;
1293 
1294 		case OSIOCGIFBRDADDR:
1295 			cmd = SIOCGIFBRDADDR;
1296 			break;
1297 
1298 		case OSIOCGIFNETMASK:
1299 			cmd = SIOCGIFNETMASK;
1300 		}
1301 		error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
1302 		    (struct mbuf *) cmd, (struct mbuf *) data,
1303 		    (struct mbuf *) ifp));
1304 		switch (ocmd) {
1305 
1306 		case OSIOCGIFADDR:
1307 		case OSIOCGIFDSTADDR:
1308 		case OSIOCGIFBRDADDR:
1309 		case OSIOCGIFNETMASK:
1310 			*(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
1311 		}
1312 
1313 	    }
1314 #endif
1315 		break;
1316 	}
1317 
1318 	if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) {
1319 #ifdef INET6
1320 		if ((ifp->if_flags & IFF_UP) != 0) {
1321 			int s = splnet();
1322 			in6_if_up(ifp);
1323 			splx(s);
1324 		}
1325 #endif
1326 	}
1327 	return (error);
1328 }
1329 
1330 /*
1331  * Return interface configuration
1332  * of system.  List may be used
1333  * in later ioctl's (above) to get
1334  * other information.
1335  */
1336 /*ARGSUSED*/
1337 int
ifconf(u_long cmd,caddr_t data)1338 ifconf(u_long cmd, caddr_t data)
1339 {
1340 	struct ifconf *ifc = (struct ifconf *)data;
1341 	struct ifnet *ifp;
1342 	struct ifaddr *ifa;
1343 	struct ifreq ifr, *ifrp;
1344 	int space = ifc->ifc_len, error = 0;
1345 
1346 	/* If ifc->ifc_len is 0, fill it in with the needed size and return. */
1347 	if (space == 0) {
1348 		TAILQ_FOREACH(ifp, &ifnet, if_list) {
1349 			struct sockaddr *sa;
1350 
1351 			if (TAILQ_EMPTY(&ifp->if_addrlist))
1352 				space += sizeof (ifr);
1353 			else
1354 				TAILQ_FOREACH(ifa,
1355 				    &ifp->if_addrlist, ifa_list) {
1356 					sa = ifa->ifa_addr;
1357 #if defined(COMPAT_43) || defined(COMPAT_LINUX)
1358 					if (cmd != OSIOCGIFCONF)
1359 #endif
1360 					if (sa->sa_len > sizeof(*sa))
1361 						space += sa->sa_len -
1362 						    sizeof(*sa);
1363 					space += sizeof(ifr);
1364 				}
1365 		}
1366 		ifc->ifc_len = space;
1367 		return (0);
1368 	}
1369 
1370 	ifrp = ifc->ifc_req;
1371 	for (ifp = TAILQ_FIRST(&ifnet); space >= sizeof(ifr) &&
1372 	    ifp != TAILQ_END(&ifnet); ifp = TAILQ_NEXT(ifp, if_list)) {
1373 		bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
1374 		if (TAILQ_EMPTY(&ifp->if_addrlist)) {
1375 			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
1376 			error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
1377 			    sizeof(ifr));
1378 			if (error)
1379 				break;
1380 			space -= sizeof (ifr), ifrp++;
1381 		} else
1382 			for (ifa = TAILQ_FIRST(&ifp->if_addrlist);
1383 			    space >= sizeof (ifr) &&
1384 			    ifa != TAILQ_END(&ifp->if_addrlist);
1385 			    ifa = TAILQ_NEXT(ifa, ifa_list)) {
1386 				struct sockaddr *sa = ifa->ifa_addr;
1387 #if defined(COMPAT_43) || defined(COMPAT_LINUX)
1388 				if (cmd == OSIOCGIFCONF) {
1389 					struct osockaddr *osa =
1390 					    (struct osockaddr *)&ifr.ifr_addr;
1391 					ifr.ifr_addr = *sa;
1392 					osa->sa_family = sa->sa_family;
1393 					error = copyout((caddr_t)&ifr,
1394 					    (caddr_t)ifrp, sizeof (ifr));
1395 					ifrp++;
1396 				} else
1397 #endif
1398 				if (sa->sa_len <= sizeof(*sa)) {
1399 					ifr.ifr_addr = *sa;
1400 					error = copyout((caddr_t)&ifr,
1401 					    (caddr_t)ifrp, sizeof (ifr));
1402 					ifrp++;
1403 				} else {
1404 					space -= sa->sa_len - sizeof(*sa);
1405 					if (space < sizeof (ifr))
1406 						break;
1407 					error = copyout((caddr_t)&ifr,
1408 					    (caddr_t)ifrp,
1409 					    sizeof(ifr.ifr_name));
1410 					if (error == 0)
1411 						error = copyout((caddr_t)sa,
1412 						    (caddr_t)&ifrp->ifr_addr,
1413 						    sa->sa_len);
1414 					ifrp = (struct ifreq *)(sa->sa_len +
1415 					    (caddr_t)&ifrp->ifr_addr);
1416 				}
1417 				if (error)
1418 					break;
1419 				space -= sizeof (ifr);
1420 			}
1421 	}
1422 	ifc->ifc_len -= space;
1423 	return (error);
1424 }
1425 
1426 /*
1427  * Dummy functions replaced in ifnet during detach (if protocols decide to
1428  * fiddle with the if during detach.
1429  */
1430 void
if_detached_start(struct ifnet * ifp)1431 if_detached_start(struct ifnet *ifp)
1432 {
1433 	struct mbuf *m;
1434 
1435 	while (1) {
1436 		IF_DEQUEUE(&ifp->if_snd, m);
1437 
1438 		if (m == NULL)
1439 			return;
1440 		m_freem(m);
1441 	}
1442 }
1443 
1444 int
if_detached_ioctl(struct ifnet * ifp,u_long a,caddr_t b)1445 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
1446 {
1447 	return ENODEV;
1448 }
1449 
1450 int
if_detached_init(struct ifnet * ifp)1451 if_detached_init(struct ifnet *ifp)
1452 {
1453 	return (ENXIO);
1454 }
1455 
1456 void
if_detached_watchdog(struct ifnet * ifp)1457 if_detached_watchdog(struct ifnet *ifp)
1458 {
1459 	/* nothing */
1460 }
1461 
1462 /*
1463  * Set/clear promiscuous mode on interface ifp based on the truth value
1464  * of pswitch.  The calls are reference counted so that only the first
1465  * "on" request actually has an effect, as does the final "off" request.
1466  * Results are undefined if the "off" and "on" requests are not matched.
1467  */
1468 int
ifpromisc(ifp,pswitch)1469 ifpromisc(ifp, pswitch)
1470 	struct ifnet *ifp;
1471 	int pswitch;
1472 {
1473 	struct ifreq ifr;
1474 
1475 	if (pswitch) {
1476 		/*
1477 		 * If the device is not configured up, we cannot put it in
1478 		 * promiscuous mode.
1479 		 */
1480 		if ((ifp->if_flags & IFF_UP) == 0)
1481 			return (ENETDOWN);
1482 		if (ifp->if_pcount++ != 0)
1483 			return (0);
1484 		ifp->if_flags |= IFF_PROMISC;
1485 	} else {
1486 		if (--ifp->if_pcount > 0)
1487 			return (0);
1488 		ifp->if_flags &= ~IFF_PROMISC;
1489 		/*
1490 		 * If the device is not configured up, we should not need to
1491 		 * turn off promiscuous mode (device should have turned it
1492 		 * off when interface went down; and will look at IFF_PROMISC
1493 		 * again next time interface comes up).
1494 		 */
1495 		if ((ifp->if_flags & IFF_UP) == 0)
1496 			return (0);
1497 	}
1498 	ifr.ifr_flags = ifp->if_flags;
1499 	return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
1500 }
1501 
1502 int netrndintr_v;
1503 void
netrndintr(void)1504 netrndintr(void)
1505 {
1506 	add_net_randomness(netrndintr_v);
1507 	netrndintr_v = 0;
1508 }
1509