FreeBSD/Linux Kernel Cross Reference
sys/net/if.c
1 /*-
2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 4. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)if.c 8.5 (Berkeley) 1/9/95
30 * $FreeBSD: src/sys/net/if.c,v 1.290 2008/11/06 15:26:09 bz Exp $
31 */
32
33 #include "opt_compat.h"
34 #include "opt_inet6.h"
35 #include "opt_inet.h"
36 #include "opt_mac.h"
37 #include "opt_carp.h"
38
39 #include <sys/param.h>
40 #include <sys/types.h>
41 #include <sys/conf.h>
42 #include <sys/malloc.h>
43 #include <sys/sbuf.h>
44 #include <sys/bus.h>
45 #include <sys/mbuf.h>
46 #include <sys/systm.h>
47 #include <sys/priv.h>
48 #include <sys/proc.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/protosw.h>
52 #include <sys/kernel.h>
53 #include <sys/sockio.h>
54 #include <sys/syslog.h>
55 #include <sys/sysctl.h>
56 #include <sys/taskqueue.h>
57 #include <sys/domain.h>
58 #include <sys/jail.h>
59 #include <sys/vimage.h>
60 #include <machine/stdarg.h>
61
62 #include <net/if.h>
63 #include <net/if_arp.h>
64 #include <net/if_clone.h>
65 #include <net/if_dl.h>
66 #include <net/if_types.h>
67 #include <net/if_var.h>
68 #include <net/radix.h>
69 #include <net/route.h>
70
71 #if defined(INET) || defined(INET6)
72 /*XXX*/
73 #include <netinet/in.h>
74 #include <netinet/in_var.h>
75 #ifdef INET6
76 #include <netinet6/in6_var.h>
77 #include <netinet6/in6_ifattach.h>
78 #endif
79 #endif
80 #ifdef INET
81 #include <netinet/if_ether.h>
82 #endif
83 #ifdef DEV_CARP
84 #include <netinet/ip_carp.h>
85 #endif
86
87 #include <security/mac/mac_framework.h>
88
89 SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
90 SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
91
92 /* Log link state change events */
93 static int log_link_state_change = 1;
94
95 SYSCTL_INT(_net_link, OID_AUTO, log_link_state_change, CTLFLAG_RW,
96 &log_link_state_change, 0,
97 "log interface link state change events");
98
99 void (*bstp_linkstate_p)(struct ifnet *ifp, int state);
100 void (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
101 void (*lagg_linkstate_p)(struct ifnet *ifp, int state);
102
103 struct mbuf *(*tbr_dequeue_ptr)(struct ifaltq *, int) = NULL;
104
105 /*
106 * XXX: Style; these should be sorted alphabetically, and unprototyped
107 * static functions should be prototyped. Currently they are sorted by
108 * declaration order.
109 */
110 static void if_attachdomain(void *);
111 static void if_attachdomain1(struct ifnet *);
112 static int ifconf(u_long, caddr_t);
113 static void if_freemulti(struct ifmultiaddr *);
114 static void if_grow(void);
115 static void if_init(void *);
116 static void if_qflush(struct ifaltq *);
117 static void if_route(struct ifnet *, int flag, int fam);
118 static int if_setflag(struct ifnet *, int, int, int *, int);
119 static void if_slowtimo(void *);
120 static void if_unroute(struct ifnet *, int flag, int fam);
121 static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
122 static int if_rtdel(struct radix_node *, void *);
123 static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
124 static int if_delmulti_locked(struct ifnet *, struct ifmultiaddr *, int);
125 static void if_start_deferred(void *context, int pending);
126 static void do_link_state_change(void *, int);
127 static int if_getgroup(struct ifgroupreq *, struct ifnet *);
128 static int if_getgroupmembers(struct ifgroupreq *);
129 #ifdef INET6
130 /*
131 * XXX: declare here to avoid to include many inet6 related files..
132 * should be more generalized?
133 */
134 extern void nd6_setmtu(struct ifnet *);
135 #endif
136
137 int if_index = 0;
138 int ifqmaxlen = IFQ_MAXLEN;
139 struct ifnethead ifnet; /* depend on static init XXX */
140 struct ifgrouphead ifg_head;
141 struct mtx ifnet_lock;
142 static if_com_alloc_t *if_com_alloc[256];
143 static if_com_free_t *if_com_free[256];
144
145 static int if_indexlim = 8;
146 static struct knlist ifklist;
147
148 /*
149 * Table of ifnet/cdev by index. Locked with ifnet_lock.
150 */
151 static struct ifindex_entry *ifindex_table = NULL;
152
153 static void filt_netdetach(struct knote *kn);
154 static int filt_netdev(struct knote *kn, long hint);
155
156 static struct filterops netdev_filtops =
157 { 1, NULL, filt_netdetach, filt_netdev };
158
159 /*
160 * System initialization
161 */
162 SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL);
163 SYSINIT(interface_check, SI_SUB_PROTO_IF, SI_ORDER_FIRST, if_slowtimo, NULL);
164
165 MALLOC_DEFINE(M_IFNET, "ifnet", "interface internals");
166 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
167 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
168
169 struct ifnet *
170 ifnet_byindex(u_short idx)
171 {
172 INIT_VNET_NET(curvnet);
173 struct ifnet *ifp;
174
175 IFNET_RLOCK();
176 ifp = V_ifindex_table[idx].ife_ifnet;
177 IFNET_RUNLOCK();
178 return (ifp);
179 }
180
181 static void
182 ifnet_setbyindex(u_short idx, struct ifnet *ifp)
183 {
184 INIT_VNET_NET(curvnet);
185
186 IFNET_WLOCK_ASSERT();
187
188 V_ifindex_table[idx].ife_ifnet = ifp;
189 }
190
191 struct ifaddr *
192 ifaddr_byindex(u_short idx)
193 {
194 INIT_VNET_NET(curvnet);
195 struct ifaddr *ifa;
196
197 IFNET_RLOCK();
198 ifa = ifnet_byindex(idx)->if_addr;
199 IFNET_RUNLOCK();
200 return (ifa);
201 }
202
203 struct cdev *
204 ifdev_byindex(u_short idx)
205 {
206 INIT_VNET_NET(curvnet);
207 struct cdev *cdev;
208
209 IFNET_RLOCK();
210 cdev = V_ifindex_table[idx].ife_dev;
211 IFNET_RUNLOCK();
212 return (cdev);
213 }
214
215 static void
216 ifdev_setbyindex(u_short idx, struct cdev *cdev)
217 {
218 INIT_VNET_NET(curvnet);
219
220 IFNET_WLOCK();
221 V_ifindex_table[idx].ife_dev = cdev;
222 IFNET_WUNLOCK();
223 }
224
225 static d_open_t netopen;
226 static d_close_t netclose;
227 static d_ioctl_t netioctl;
228 static d_kqfilter_t netkqfilter;
229
230 static struct cdevsw net_cdevsw = {
231 .d_version = D_VERSION,
232 .d_flags = D_NEEDGIANT,
233 .d_open = netopen,
234 .d_close = netclose,
235 .d_ioctl = netioctl,
236 .d_name = "net",
237 .d_kqfilter = netkqfilter,
238 };
239
240 static int
241 netopen(struct cdev *dev, int flag, int mode, struct thread *td)
242 {
243 return (0);
244 }
245
246 static int
247 netclose(struct cdev *dev, int flags, int fmt, struct thread *td)
248 {
249 return (0);
250 }
251
252 static int
253 netioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
254 {
255 struct ifnet *ifp;
256 int error, idx;
257
258 /* only support interface specific ioctls */
259 if (IOCGROUP(cmd) != 'i')
260 return (EOPNOTSUPP);
261 idx = dev2unit(dev);
262 if (idx == 0) {
263 /*
264 * special network device, not interface.
265 */
266 if (cmd == SIOCGIFCONF)
267 return (ifconf(cmd, data)); /* XXX remove cmd */
268 #ifdef __amd64__
269 if (cmd == SIOCGIFCONF32)
270 return (ifconf(cmd, data)); /* XXX remove cmd */
271 #endif
272 return (EOPNOTSUPP);
273 }
274
275 ifp = ifnet_byindex(idx);
276 if (ifp == NULL)
277 return (ENXIO);
278
279 error = ifhwioctl(cmd, ifp, data, td);
280 if (error == ENOIOCTL)
281 error = EOPNOTSUPP;
282 return (error);
283 }
284
285 static int
286 netkqfilter(struct cdev *dev, struct knote *kn)
287 {
288 INIT_VNET_NET(curvnet);
289 struct knlist *klist;
290 struct ifnet *ifp;
291 int idx;
292
293 switch (kn->kn_filter) {
294 case EVFILT_NETDEV:
295 kn->kn_fop = &netdev_filtops;
296 break;
297 default:
298 return (EINVAL);
299 }
300
301 idx = dev2unit(dev);
302 if (idx == 0) {
303 klist = &V_ifklist;
304 } else {
305 ifp = ifnet_byindex(idx);
306 if (ifp == NULL)
307 return (1);
308 klist = &ifp->if_klist;
309 }
310
311 kn->kn_hook = (caddr_t)klist;
312
313 knlist_add(klist, kn, 0);
314
315 return (0);
316 }
317
318 static void
319 filt_netdetach(struct knote *kn)
320 {
321 struct knlist *klist = (struct knlist *)kn->kn_hook;
322
323 knlist_remove(klist, kn, 0);
324 }
325
326 static int
327 filt_netdev(struct knote *kn, long hint)
328 {
329 struct knlist *klist = (struct knlist *)kn->kn_hook;
330
331 /*
332 * Currently NOTE_EXIT is abused to indicate device detach.
333 */
334 if (hint == NOTE_EXIT) {
335 kn->kn_data = NOTE_LINKINV;
336 kn->kn_flags |= (EV_EOF | EV_ONESHOT);
337 knlist_remove_inevent(klist, kn);
338 return (1);
339 }
340 if (hint != 0)
341 kn->kn_data = hint; /* current status */
342 if (kn->kn_sfflags & hint)
343 kn->kn_fflags |= hint;
344 return (kn->kn_fflags != 0);
345 }
346
347 /*
348 * Network interface utility routines.
349 *
350 * Routines with ifa_ifwith* names take sockaddr *'s as
351 * parameters.
352 */
353
354 /* ARGSUSED*/
355 static void
356 if_init(void *dummy __unused)
357 {
358 INIT_VNET_NET(curvnet);
359
360 IFNET_LOCK_INIT();
361 TAILQ_INIT(&V_ifnet);
362 TAILQ_INIT(&V_ifg_head);
363 knlist_init(&V_ifklist, NULL, NULL, NULL, NULL);
364 if_grow(); /* create initial table */
365 ifdev_setbyindex(0, make_dev(&net_cdevsw, 0, UID_ROOT, GID_WHEEL,
366 0600, "network"));
367 if_clone_init();
368 }
369
370 static void
371 if_grow(void)
372 {
373 INIT_VNET_NET(curvnet);
374 u_int n;
375 struct ifindex_entry *e;
376
377 V_if_indexlim <<= 1;
378 n = V_if_indexlim * sizeof(*e);
379 e = malloc(n, M_IFNET, M_WAITOK | M_ZERO);
380 if (V_ifindex_table != NULL) {
381 memcpy((caddr_t)e, (caddr_t)V_ifindex_table, n/2);
382 free((caddr_t)V_ifindex_table, M_IFNET);
383 }
384 V_ifindex_table = e;
385 }
386
387 /*
388 * Allocate a struct ifnet and an index for an interface. A layer 2
389 * common structure will also be allocated if an allocation routine is
390 * registered for the passed type.
391 */
392 struct ifnet*
393 if_alloc(u_char type)
394 {
395 INIT_VNET_NET(curvnet);
396 struct ifnet *ifp;
397
398 ifp = malloc(sizeof(struct ifnet), M_IFNET, M_WAITOK|M_ZERO);
399
400 /*
401 * Try to find an empty slot below if_index. If we fail, take
402 * the next slot.
403 *
404 * XXX: should be locked!
405 */
406 for (ifp->if_index = 1; ifp->if_index <= V_if_index; ifp->if_index++) {
407 if (ifnet_byindex(ifp->if_index) == NULL)
408 break;
409 }
410 /* Catch if_index overflow. */
411 if (ifp->if_index < 1) {
412 free(ifp, M_IFNET);
413 return (NULL);
414 }
415 if (ifp->if_index > V_if_index)
416 V_if_index = ifp->if_index;
417 if (V_if_index >= V_if_indexlim)
418 if_grow();
419
420 ifp->if_type = type;
421
422 if (if_com_alloc[type] != NULL) {
423 ifp->if_l2com = if_com_alloc[type](type, ifp);
424 if (ifp->if_l2com == NULL) {
425 free(ifp, M_IFNET);
426 return (NULL);
427 }
428 }
429 IFNET_WLOCK();
430 ifnet_setbyindex(ifp->if_index, ifp);
431 IFNET_WUNLOCK();
432 IF_ADDR_LOCK_INIT(ifp);
433
434 return (ifp);
435 }
436
437 /*
438 * Free the struct ifnet, the associated index, and the layer 2 common
439 * structure if needed. All the work is done in if_free_type().
440 *
441 * Do not add code to this function! Add it to if_free_type().
442 */
443 void
444 if_free(struct ifnet *ifp)
445 {
446
447 if_free_type(ifp, ifp->if_type);
448 }
449
450 /*
451 * Do the actual work of freeing a struct ifnet, associated index, and
452 * layer 2 common structure. This version should only be called by
453 * intefaces that switch their type after calling if_alloc().
454 */
455 void
456 if_free_type(struct ifnet *ifp, u_char type)
457 {
458 INIT_VNET_NET(curvnet); /* ifp->if_vnet can be NULL here ! */
459
460 if (ifp != ifnet_byindex(ifp->if_index)) {
461 if_printf(ifp, "%s: value was not if_alloced, skipping\n",
462 __func__);
463 return;
464 }
465
466 IFNET_WLOCK();
467 ifnet_setbyindex(ifp->if_index, NULL);
468
469 /* XXX: should be locked with if_findindex() */
470 while (V_if_index > 0 && ifnet_byindex(V_if_index) == NULL)
471 V_if_index--;
472 IFNET_WUNLOCK();
473
474 if (if_com_free[type] != NULL)
475 if_com_free[type](ifp->if_l2com, type);
476
477 IF_ADDR_LOCK_DESTROY(ifp);
478 free(ifp, M_IFNET);
479 };
480
481 /*
482 * Perform generic interface initalization tasks and attach the interface
483 * to the list of "active" interfaces.
484 *
485 * XXX:
486 * - The decision to return void and thus require this function to
487 * succeed is questionable.
488 * - We do more initialization here then is probably a good idea.
489 * Some of this should probably move to if_alloc().
490 * - We should probably do more sanity checking. For instance we don't
491 * do anything to insure if_xname is unique or non-empty.
492 */
493 void
494 if_attach(struct ifnet *ifp)
495 {
496 INIT_VNET_NET(curvnet);
497 unsigned socksize, ifasize;
498 int namelen, masklen;
499 struct sockaddr_dl *sdl;
500 struct ifaddr *ifa;
501
502 if (ifp->if_index == 0 || ifp != ifnet_byindex(ifp->if_index))
503 panic ("%s: BUG: if_attach called without if_alloc'd input()\n",
504 ifp->if_xname);
505
506 TASK_INIT(&ifp->if_starttask, 0, if_start_deferred, ifp);
507 TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp);
508 IF_AFDATA_LOCK_INIT(ifp);
509 ifp->if_afdata_initialized = 0;
510
511 TAILQ_INIT(&ifp->if_addrhead);
512 TAILQ_INIT(&ifp->if_prefixhead);
513 TAILQ_INIT(&ifp->if_multiaddrs);
514 TAILQ_INIT(&ifp->if_groups);
515
516 if_addgroup(ifp, IFG_ALL);
517
518 knlist_init(&ifp->if_klist, NULL, NULL, NULL, NULL);
519 getmicrotime(&ifp->if_lastchange);
520 ifp->if_data.ifi_epoch = time_uptime;
521 ifp->if_data.ifi_datalen = sizeof(struct if_data);
522
523 #ifdef MAC
524 mac_ifnet_init(ifp);
525 mac_ifnet_create(ifp);
526 #endif
527
528 ifdev_setbyindex(ifp->if_index, make_dev(&net_cdevsw,
529 ifp->if_index, UID_ROOT, GID_WHEEL, 0600, "%s/%s",
530 net_cdevsw.d_name, ifp->if_xname));
531 make_dev_alias(ifdev_byindex(ifp->if_index), "%s%d",
532 net_cdevsw.d_name, ifp->if_index);
533
534 mtx_init(&ifp->if_snd.ifq_mtx, ifp->if_xname, "if send queue", MTX_DEF);
535
536 /*
537 * create a Link Level name for this device
538 */
539 namelen = strlen(ifp->if_xname);
540 /*
541 * Always save enough space for any possiable name so we can do
542 * a rename in place later.
543 */
544 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + IFNAMSIZ;
545 socksize = masklen + ifp->if_addrlen;
546 if (socksize < sizeof(*sdl))
547 socksize = sizeof(*sdl);
548 socksize = roundup2(socksize, sizeof(long));
549 ifasize = sizeof(*ifa) + 2 * socksize;
550 ifa = malloc(ifasize, M_IFADDR, M_WAITOK | M_ZERO);
551 IFA_LOCK_INIT(ifa);
552 sdl = (struct sockaddr_dl *)(ifa + 1);
553 sdl->sdl_len = socksize;
554 sdl->sdl_family = AF_LINK;
555 bcopy(ifp->if_xname, sdl->sdl_data, namelen);
556 sdl->sdl_nlen = namelen;
557 sdl->sdl_index = ifp->if_index;
558 sdl->sdl_type = ifp->if_type;
559 ifp->if_addr = ifa;
560 ifa->ifa_ifp = ifp;
561 ifa->ifa_rtrequest = link_rtrequest;
562 ifa->ifa_addr = (struct sockaddr *)sdl;
563 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
564 ifa->ifa_netmask = (struct sockaddr *)sdl;
565 sdl->sdl_len = masklen;
566 while (namelen != 0)
567 sdl->sdl_data[--namelen] = 0xff;
568 ifa->ifa_refcnt = 1;
569 TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
570 ifp->if_broadcastaddr = NULL; /* reliably crash if used uninitialized */
571
572 /*
573 * XXX: why do we warn about this? We're correcting it and most
574 * drivers just set the value the way we do.
575 */
576 if (ifp->if_snd.ifq_maxlen == 0) {
577 if_printf(ifp, "XXX: driver didn't set ifq_maxlen\n");
578 ifp->if_snd.ifq_maxlen = ifqmaxlen;
579 }
580 ifp->if_snd.altq_type = 0;
581 ifp->if_snd.altq_disc = NULL;
582 ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
583 ifp->if_snd.altq_tbr = NULL;
584 ifp->if_snd.altq_ifp = ifp;
585
586 IFNET_WLOCK();
587 TAILQ_INSERT_TAIL(&V_ifnet, ifp, if_link);
588 IFNET_WUNLOCK();
589
590 if (domain_init_status >= 2)
591 if_attachdomain1(ifp);
592
593 EVENTHANDLER_INVOKE(ifnet_arrival_event, ifp);
594 devctl_notify("IFNET", ifp->if_xname, "ATTACH", NULL);
595
596 /* Announce the interface. */
597 rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
598
599 if (ifp->if_watchdog != NULL)
600 if_printf(ifp,
601 "WARNING: using obsoleted if_watchdog interface\n");
602 if (ifp->if_flags & IFF_NEEDSGIANT)
603 if_printf(ifp,
604 "WARNING: using obsoleted IFF_NEEDSGIANT flag\n");
605 }
606
607 static void
608 if_attachdomain(void *dummy)
609 {
610 INIT_VNET_NET(curvnet);
611 struct ifnet *ifp;
612 int s;
613
614 s = splnet();
615 TAILQ_FOREACH(ifp, &V_ifnet, if_link)
616 if_attachdomain1(ifp);
617 splx(s);
618 }
619 SYSINIT(domainifattach, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_SECOND,
620 if_attachdomain, NULL);
621
622 static void
623 if_attachdomain1(struct ifnet *ifp)
624 {
625 struct domain *dp;
626 int s;
627
628 s = splnet();
629
630 /*
631 * Since dp->dom_ifattach calls malloc() with M_WAITOK, we
632 * cannot lock ifp->if_afdata initialization, entirely.
633 */
634 if (IF_AFDATA_TRYLOCK(ifp) == 0) {
635 splx(s);
636 return;
637 }
638 if (ifp->if_afdata_initialized >= domain_init_status) {
639 IF_AFDATA_UNLOCK(ifp);
640 splx(s);
641 printf("if_attachdomain called more than once on %s\n",
642 ifp->if_xname);
643 return;
644 }
645 ifp->if_afdata_initialized = domain_init_status;
646 IF_AFDATA_UNLOCK(ifp);
647
648 /* address family dependent data region */
649 bzero(ifp->if_afdata, sizeof(ifp->if_afdata));
650 for (dp = domains; dp; dp = dp->dom_next) {
651 if (dp->dom_ifattach)
652 ifp->if_afdata[dp->dom_family] =
653 (*dp->dom_ifattach)(ifp);
654 }
655
656 splx(s);
657 }
658
659 /*
660 * Remove any unicast or broadcast network addresses from an interface.
661 */
662 void
663 if_purgeaddrs(struct ifnet *ifp)
664 {
665 struct ifaddr *ifa, *next;
666
667 TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) {
668 if (ifa->ifa_addr->sa_family == AF_LINK)
669 continue;
670 #ifdef INET
671 /* XXX: Ugly!! ad hoc just for INET */
672 if (ifa->ifa_addr->sa_family == AF_INET) {
673 struct ifaliasreq ifr;
674
675 bzero(&ifr, sizeof(ifr));
676 ifr.ifra_addr = *ifa->ifa_addr;
677 if (ifa->ifa_dstaddr)
678 ifr.ifra_broadaddr = *ifa->ifa_dstaddr;
679 if (in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp,
680 NULL) == 0)
681 continue;
682 }
683 #endif /* INET */
684 #ifdef INET6
685 if (ifa->ifa_addr->sa_family == AF_INET6) {
686 in6_purgeaddr(ifa);
687 /* ifp_addrhead is already updated */
688 continue;
689 }
690 #endif /* INET6 */
691 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
692 IFAFREE(ifa);
693 }
694 }
695
696 /*
697 * Remove any multicast network addresses from an interface.
698 */
699 void
700 if_purgemaddrs(struct ifnet *ifp)
701 {
702 struct ifmultiaddr *ifma;
703 struct ifmultiaddr *next;
704
705 IF_ADDR_LOCK(ifp);
706 TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
707 if_delmulti_locked(ifp, ifma, 1);
708 IF_ADDR_UNLOCK(ifp);
709 }
710
711 /*
712 * Detach an interface, removing it from the
713 * list of "active" interfaces.
714 *
715 * XXXRW: There are some significant questions about event ordering, and
716 * how to prevent things from starting to use the interface during detach.
717 */
718 void
719 if_detach(struct ifnet *ifp)
720 {
721 INIT_VNET_NET(ifp->if_vnet);
722 struct ifaddr *ifa;
723 struct radix_node_head *rnh;
724 int s;
725 int i;
726 struct domain *dp;
727 struct ifnet *iter;
728 int found = 0;
729
730 IFNET_WLOCK();
731 TAILQ_FOREACH(iter, &V_ifnet, if_link)
732 if (iter == ifp) {
733 TAILQ_REMOVE(&V_ifnet, ifp, if_link);
734 found = 1;
735 break;
736 }
737 IFNET_WUNLOCK();
738 if (!found)
739 return;
740
741 /*
742 * Remove/wait for pending events.
743 */
744 taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
745
746 /*
747 * Remove routes and flush queues.
748 */
749 s = splnet();
750 if_down(ifp);
751 #ifdef ALTQ
752 if (ALTQ_IS_ENABLED(&ifp->if_snd))
753 altq_disable(&ifp->if_snd);
754 if (ALTQ_IS_ATTACHED(&ifp->if_snd))
755 altq_detach(&ifp->if_snd);
756 #endif
757
758 if_purgeaddrs(ifp);
759
760 #ifdef INET
761 in_ifdetach(ifp);
762 #endif
763
764 #ifdef INET6
765 /*
766 * Remove all IPv6 kernel structs related to ifp. This should be done
767 * before removing routing entries below, since IPv6 interface direct
768 * routes are expected to be removed by the IPv6-specific kernel API.
769 * Otherwise, the kernel will detect some inconsistency and bark it.
770 */
771 in6_ifdetach(ifp);
772 #endif
773 if_purgemaddrs(ifp);
774
775 /*
776 * Remove link ifaddr pointer and maybe decrement if_index.
777 * Clean up all addresses.
778 */
779 ifp->if_addr = NULL;
780 destroy_dev(ifdev_byindex(ifp->if_index));
781 ifdev_setbyindex(ifp->if_index, NULL);
782
783 /* We can now free link ifaddr. */
784 if (!TAILQ_EMPTY(&ifp->if_addrhead)) {
785 ifa = TAILQ_FIRST(&ifp->if_addrhead);
786 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
787 IFAFREE(ifa);
788 }
789
790 /*
791 * Delete all remaining routes using this interface
792 * Unfortuneatly the only way to do this is to slog through
793 * the entire routing table looking for routes which point
794 * to this interface...oh well...
795 */
796 for (i = 1; i <= AF_MAX; i++) {
797 int j;
798 for (j = 0; j < rt_numfibs; j++) {
799 if ((rnh = V_rt_tables[j][i]) == NULL)
800 continue;
801 RADIX_NODE_HEAD_LOCK(rnh);
802 (void) rnh->rnh_walktree(rnh, if_rtdel, ifp);
803 RADIX_NODE_HEAD_UNLOCK(rnh);
804 }
805 }
806
807 /* Announce that the interface is gone. */
808 rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
809 EVENTHANDLER_INVOKE(ifnet_departure_event, ifp);
810 devctl_notify("IFNET", ifp->if_xname, "DETACH", NULL);
811
812 IF_AFDATA_LOCK(ifp);
813 for (dp = domains; dp; dp = dp->dom_next) {
814 if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
815 (*dp->dom_ifdetach)(ifp,
816 ifp->if_afdata[dp->dom_family]);
817 }
818 IF_AFDATA_UNLOCK(ifp);
819
820 #ifdef MAC
821 mac_ifnet_destroy(ifp);
822 #endif /* MAC */
823 KNOTE_UNLOCKED(&ifp->if_klist, NOTE_EXIT);
824 knlist_clear(&ifp->if_klist, 0);
825 knlist_destroy(&ifp->if_klist);
826 mtx_destroy(&ifp->if_snd.ifq_mtx);
827 IF_AFDATA_DESTROY(ifp);
828 splx(s);
829 }
830
831 /*
832 * Add a group to an interface
833 */
834 int
835 if_addgroup(struct ifnet *ifp, const char *groupname)
836 {
837 INIT_VNET_NET(ifp->if_vnet);
838 struct ifg_list *ifgl;
839 struct ifg_group *ifg = NULL;
840 struct ifg_member *ifgm;
841
842 if (groupname[0] && groupname[strlen(groupname) - 1] >= '' &&
843 groupname[strlen(groupname) - 1] <= '9')
844 return (EINVAL);
845
846 IFNET_WLOCK();
847 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
848 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) {
849 IFNET_WUNLOCK();
850 return (EEXIST);
851 }
852
853 if ((ifgl = (struct ifg_list *)malloc(sizeof(struct ifg_list), M_TEMP,
854 M_NOWAIT)) == NULL) {
855 IFNET_WUNLOCK();
856 return (ENOMEM);
857 }
858
859 if ((ifgm = (struct ifg_member *)malloc(sizeof(struct ifg_member),
860 M_TEMP, M_NOWAIT)) == NULL) {
861 free(ifgl, M_TEMP);
862 IFNET_WUNLOCK();
863 return (ENOMEM);
864 }
865
866 TAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
867 if (!strcmp(ifg->ifg_group, groupname))
868 break;
869
870 if (ifg == NULL) {
871 if ((ifg = (struct ifg_group *)malloc(sizeof(struct ifg_group),
872 M_TEMP, M_NOWAIT)) == NULL) {
873 free(ifgl, M_TEMP);
874 free(ifgm, M_TEMP);
875 IFNET_WUNLOCK();
876 return (ENOMEM);
877 }
878 strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
879 ifg->ifg_refcnt = 0;
880 TAILQ_INIT(&ifg->ifg_members);
881 EVENTHANDLER_INVOKE(group_attach_event, ifg);
882 TAILQ_INSERT_TAIL(&V_ifg_head, ifg, ifg_next);
883 }
884
885 ifg->ifg_refcnt++;
886 ifgl->ifgl_group = ifg;
887 ifgm->ifgm_ifp = ifp;
888
889 IF_ADDR_LOCK(ifp);
890 TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next);
891 TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next);
892 IF_ADDR_UNLOCK(ifp);
893
894 IFNET_WUNLOCK();
895
896 EVENTHANDLER_INVOKE(group_change_event, groupname);
897
898 return (0);
899 }
900
901 /*
902 * Remove a group from an interface
903 */
904 int
905 if_delgroup(struct ifnet *ifp, const char *groupname)
906 {
907 INIT_VNET_NET(ifp->if_vnet);
908 struct ifg_list *ifgl;
909 struct ifg_member *ifgm;
910
911 IFNET_WLOCK();
912 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
913 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
914 break;
915 if (ifgl == NULL) {
916 IFNET_WUNLOCK();
917 return (ENOENT);
918 }
919
920 IF_ADDR_LOCK(ifp);
921 TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
922 IF_ADDR_UNLOCK(ifp);
923
924 TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
925 if (ifgm->ifgm_ifp == ifp)
926 break;
927
928 if (ifgm != NULL) {
929 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next);
930 free(ifgm, M_TEMP);
931 }
932
933 if (--ifgl->ifgl_group->ifg_refcnt == 0) {
934 TAILQ_REMOVE(&V_ifg_head, ifgl->ifgl_group, ifg_next);
935 EVENTHANDLER_INVOKE(group_detach_event, ifgl->ifgl_group);
936 free(ifgl->ifgl_group, M_TEMP);
937 }
938 IFNET_WUNLOCK();
939
940 free(ifgl, M_TEMP);
941
942 EVENTHANDLER_INVOKE(group_change_event, groupname);
943
944 return (0);
945 }
946
947 /*
948 * Stores all groups from an interface in memory pointed
949 * to by data
950 */
951 static int
952 if_getgroup(struct ifgroupreq *data, struct ifnet *ifp)
953 {
954 int len, error;
955 struct ifg_list *ifgl;
956 struct ifg_req ifgrq, *ifgp;
957 struct ifgroupreq *ifgr = data;
958
959 if (ifgr->ifgr_len == 0) {
960 IF_ADDR_LOCK(ifp);
961 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
962 ifgr->ifgr_len += sizeof(struct ifg_req);
963 IF_ADDR_UNLOCK(ifp);
964 return (0);
965 }
966
967 len = ifgr->ifgr_len;
968 ifgp = ifgr->ifgr_groups;
969 /* XXX: wire */
970 IF_ADDR_LOCK(ifp);
971 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
972 if (len < sizeof(ifgrq)) {
973 IF_ADDR_UNLOCK(ifp);
974 return (EINVAL);
975 }
976 bzero(&ifgrq, sizeof ifgrq);
977 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
978 sizeof(ifgrq.ifgrq_group));
979 if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) {
980 IF_ADDR_UNLOCK(ifp);
981 return (error);
982 }
983 len -= sizeof(ifgrq);
984 ifgp++;
985 }
986 IF_ADDR_UNLOCK(ifp);
987
988 return (0);
989 }
990
991 /*
992 * Stores all members of a group in memory pointed to by data
993 */
994 static int
995 if_getgroupmembers(struct ifgroupreq *data)
996 {
997 INIT_VNET_NET(curvnet);
998 struct ifgroupreq *ifgr = data;
999 struct ifg_group *ifg;
1000 struct ifg_member *ifgm;
1001 struct ifg_req ifgrq, *ifgp;
1002 int len, error;
1003
1004 IFNET_RLOCK();
1005 TAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
1006 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
1007 break;
1008 if (ifg == NULL) {
1009 IFNET_RUNLOCK();
1010 return (ENOENT);
1011 }
1012
1013 if (ifgr->ifgr_len == 0) {
1014 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
1015 ifgr->ifgr_len += sizeof(ifgrq);
1016 IFNET_RUNLOCK();
1017 return (0);
1018 }
1019
1020 len = ifgr->ifgr_len;
1021 ifgp = ifgr->ifgr_groups;
1022 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
1023 if (len < sizeof(ifgrq)) {
1024 IFNET_RUNLOCK();
1025 return (EINVAL);
1026 }
1027 bzero(&ifgrq, sizeof ifgrq);
1028 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
1029 sizeof(ifgrq.ifgrq_member));
1030 if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) {
1031 IFNET_RUNLOCK();
1032 return (error);
1033 }
1034 len -= sizeof(ifgrq);
1035 ifgp++;
1036 }
1037 IFNET_RUNLOCK();
1038
1039 return (0);
1040 }
1041
1042 /*
1043 * Delete Routes for a Network Interface
1044 *
1045 * Called for each routing entry via the rnh->rnh_walktree() call above
1046 * to delete all route entries referencing a detaching network interface.
1047 *
1048 * Arguments:
1049 * rn pointer to node in the routing table
1050 * arg argument passed to rnh->rnh_walktree() - detaching interface
1051 *
1052 * Returns:
1053 * 0 successful
1054 * errno failed - reason indicated
1055 *
1056 */
1057 static int
1058 if_rtdel(struct radix_node *rn, void *arg)
1059 {
1060 struct rtentry *rt = (struct rtentry *)rn;
1061 struct ifnet *ifp = arg;
1062 int err;
1063
1064 if (rt->rt_ifp == ifp) {
1065
1066 /*
1067 * Protect (sorta) against walktree recursion problems
1068 * with cloned routes
1069 */
1070 if ((rt->rt_flags & RTF_UP) == 0)
1071 return (0);
1072
1073 err = rtrequest_fib(RTM_DELETE, rt_key(rt), rt->rt_gateway,
1074 rt_mask(rt), rt->rt_flags,
1075 (struct rtentry **) NULL, rt->rt_fibnum);
1076 if (err) {
1077 log(LOG_WARNING, "if_rtdel: error %d\n", err);
1078 }
1079 }
1080
1081 return (0);
1082 }
1083
1084 /*
1085 * XXX: Because sockaddr_dl has deeper structure than the sockaddr
1086 * structs used to represent other address families, it is necessary
1087 * to perform a different comparison.
1088 */
1089
1090 #define sa_equal(a1, a2) \
1091 (bcmp((a1), (a2), ((a1))->sa_len) == 0)
1092
1093 #define sa_dl_equal(a1, a2) \
1094 ((((struct sockaddr_dl *)(a1))->sdl_len == \
1095 ((struct sockaddr_dl *)(a2))->sdl_len) && \
1096 (bcmp(LLADDR((struct sockaddr_dl *)(a1)), \
1097 LLADDR((struct sockaddr_dl *)(a2)), \
1098 ((struct sockaddr_dl *)(a1))->sdl_alen) == 0))
1099
1100 /*
1101 * Locate an interface based on a complete address.
1102 */
1103 /*ARGSUSED*/
1104 struct ifaddr *
1105 ifa_ifwithaddr(struct sockaddr *addr)
1106 {
1107 INIT_VNET_NET(curvnet);
1108 struct ifnet *ifp;
1109 struct ifaddr *ifa;
1110
1111 IFNET_RLOCK();
1112 TAILQ_FOREACH(ifp, &V_ifnet, if_link)
1113 |