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