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