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