1 /* $OpenBSD: if.c,v 1.199 2009/08/12 15:58:20 henning 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/proc.h> 75 #include <sys/socket.h> 76 #include <sys/socketvar.h> 77 #include <sys/protosw.h> 78 #include <sys/kernel.h> 79 #include <sys/ioctl.h> 80 #include <sys/domain.h> 81 #include <sys/sysctl.h> 82 83 #include <net/if.h> 84 #include <net/if_dl.h> 85 #include <net/if_media.h> 86 #include <net/if_types.h> 87 #include <net/route.h> 88 #include <net/netisr.h> 89 90 #ifdef INET 91 #include <netinet/in.h> 92 #include <netinet/in_var.h> 93 #include <netinet/if_ether.h> 94 #include <netinet/igmp.h> 95 #ifdef MROUTING 96 #include <netinet/ip_mroute.h> 97 #endif 98 #endif 99 100 #ifdef INET6 101 #ifndef INET 102 #include <netinet/in.h> 103 #endif 104 #include <netinet6/in6_ifattach.h> 105 #include <netinet6/nd6.h> 106 #endif 107 108 #if NBPFILTER > 0 109 #include <net/bpf.h> 110 #endif 111 112 #if NTRUNK > 0 113 #include <net/if_trunk.h> 114 #endif 115 116 #if NBRIDGE > 0 117 #include <net/if_bridge.h> 118 #endif 119 120 #if NCARP > 0 121 #include <netinet/ip_carp.h> 122 #endif 123 124 #if NPF > 0 125 #include <net/pfvar.h> 126 #endif 127 128 void if_attachsetup(struct ifnet *); 129 void if_attachdomain1(struct ifnet *); 130 void if_attach_common(struct ifnet *); 131 132 int ifqmaxlen = IFQ_MAXLEN; 133 134 void if_detach_queues(struct ifnet *, struct ifqueue *); 135 void if_detached_start(struct ifnet *); 136 int if_detached_ioctl(struct ifnet *, u_long, caddr_t); 137 int if_detached_init(struct ifnet *); 138 void if_detached_watchdog(struct ifnet *); 139 140 int if_getgroup(caddr_t, struct ifnet *); 141 int if_getgroupmembers(caddr_t); 142 int if_getgroupattribs(caddr_t); 143 int if_setgroupattribs(caddr_t); 144 145 int if_clone_list(struct if_clonereq *); 146 struct if_clone *if_clone_lookup(const char *, int *); 147 148 void if_congestion_clear(void *); 149 int if_group_egress_build(void); 150 151 TAILQ_HEAD(, ifg_group) ifg_head; 152 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 153 int if_cloners_count; 154 155 struct timeout m_cltick_tmo; 156 int m_clticks; 157 158 /* 159 * Record when the last timeout has been run. If the delta is 160 * too high, m_cldrop() will notice and decrease the interface 161 * high water marks. 162 */ 163 static void 164 m_cltick(void *arg) 165 { 166 extern int ticks; 167 extern void m_cltick(void *); 168 169 m_clticks = ticks; 170 timeout_add(&m_cltick_tmo, 1); 171 } 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 timeout_set(&if_slowtim, if_slowtimo, &if_slowtim); 185 186 if_slowtimo(&if_slowtim); 187 188 timeout_set(&m_cltick_tmo, m_cltick, NULL); 189 m_cltick(NULL); 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; 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 ifp->if_snd.ifq_maxlen = 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 TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list); 344 ifa->ifa_addr = (struct sockaddr *)sdl; 345 ifp->if_sadl = sdl; 346 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); 347 ifa->ifa_netmask = (struct sockaddr *)sdl; 348 sdl->sdl_len = masklen; 349 while (namelen != 0) 350 sdl->sdl_data[--namelen] = 0xff; 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 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 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 if (if_index == 0) { 450 TAILQ_INIT(&ifnet); 451 TAILQ_INIT(&ifg_head); 452 } 453 TAILQ_INIT(&ifp->if_addrlist); 454 ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks), 455 M_TEMP, M_NOWAIT); 456 if (ifp->if_addrhooks == NULL) 457 panic("if_attach_common: malloc"); 458 TAILQ_INIT(ifp->if_addrhooks); 459 ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks), 460 M_TEMP, M_NOWAIT); 461 if (ifp->if_linkstatehooks == NULL) 462 panic("if_attach_common: malloc"); 463 TAILQ_INIT(ifp->if_linkstatehooks); 464 ifp->if_detachhooks = malloc(sizeof(*ifp->if_detachhooks), 465 M_TEMP, M_NOWAIT); 466 if (ifp->if_detachhooks == NULL) 467 panic("if_attach_common: malloc"); 468 TAILQ_INIT(ifp->if_detachhooks); 469 } 470 471 void 472 if_start(struct ifnet *ifp) 473 { 474 if (ifp->if_snd.ifq_len >= min(8, ifp->if_snd.ifq_maxlen) && 475 !ISSET(ifp->if_flags, IFF_OACTIVE)) { 476 if (ISSET(ifp->if_xflags, IFXF_TXREADY)) { 477 TAILQ_REMOVE(&iftxlist, ifp, if_txlist); 478 CLR(ifp->if_xflags, IFXF_TXREADY); 479 } 480 ifp->if_start(ifp); 481 return; 482 } 483 484 if (!ISSET(ifp->if_xflags, IFXF_TXREADY)) { 485 SET(ifp->if_xflags, IFXF_TXREADY); 486 TAILQ_INSERT_TAIL(&iftxlist, ifp, if_txlist); 487 schednetisr(NETISR_TX); 488 } 489 } 490 491 void 492 nettxintr(void) 493 { 494 struct ifnet *ifp; 495 int s; 496 497 s = splnet(); 498 while ((ifp = TAILQ_FIRST(&iftxlist)) != NULL) { 499 TAILQ_REMOVE(&iftxlist, ifp, if_txlist); 500 CLR(ifp->if_xflags, IFXF_TXREADY); 501 ifp->if_start(ifp); 502 } 503 splx(s); 504 } 505 506 /* 507 * Detach an interface from everything in the kernel. Also deallocate 508 * private resources. 509 * XXX So far only the INET protocol family has been looked over 510 * wrt resource usage that needs to be decoupled. 511 */ 512 void 513 if_detach(struct ifnet *ifp) 514 { 515 struct ifaddr *ifa; 516 struct ifg_list *ifg; 517 int s = splnet(); 518 struct domain *dp; 519 520 ifp->if_flags &= ~IFF_OACTIVE; 521 ifp->if_start = if_detached_start; 522 ifp->if_ioctl = if_detached_ioctl; 523 ifp->if_init = if_detached_init; 524 ifp->if_watchdog = if_detached_watchdog; 525 526 /* Call detach hooks, ie. to remove vlan interfaces */ 527 dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE); 528 529 #if NTRUNK > 0 530 if (ifp->if_type == IFT_IEEE8023ADLAG) 531 trunk_port_ifdetach(ifp); 532 #endif 533 534 #if NBRIDGE > 0 535 /* Remove the interface from any bridge it is part of. */ 536 if (ifp->if_bridge) 537 bridge_ifdetach(ifp); 538 #endif 539 540 #if NCARP > 0 541 /* Remove the interface from any carp group it is a part of. */ 542 if (ifp->if_carp && ifp->if_type != IFT_CARP) 543 carp_ifdetach(ifp); 544 #endif 545 546 #if NBPFILTER > 0 547 bpfdetach(ifp); 548 #endif 549 #ifdef ALTQ 550 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 551 altq_disable(&ifp->if_snd); 552 if (ALTQ_IS_ATTACHED(&ifp->if_snd)) 553 altq_detach(&ifp->if_snd); 554 #endif 555 rt_if_remove(ifp); 556 #ifdef INET 557 rti_delete(ifp); 558 #if NETHER > 0 559 myip_ifp = NULL; 560 #endif 561 #ifdef MROUTING 562 vif_delete(ifp); 563 #endif 564 #endif 565 #ifdef INET6 566 in6_ifdetach(ifp); 567 #endif 568 569 #if NPF > 0 570 pfi_detach_ifnet(ifp); 571 #endif 572 573 /* 574 * remove packets came from ifp, from software interrupt queues. 575 * net/netisr_dispatch.h is not usable, as some of them use 576 * strange queue names. 577 */ 578 #define IF_DETACH_QUEUES(x) \ 579 do { \ 580 extern struct ifqueue x; \ 581 if_detach_queues(ifp, & x); \ 582 } while (0) 583 #ifdef INET 584 IF_DETACH_QUEUES(arpintrq); 585 IF_DETACH_QUEUES(ipintrq); 586 #endif 587 #ifdef INET6 588 IF_DETACH_QUEUES(ip6intrq); 589 #endif 590 #ifdef NETATALK 591 IF_DETACH_QUEUES(atintrq1); 592 IF_DETACH_QUEUES(atintrq2); 593 #endif 594 #ifdef NATM 595 IF_DETACH_QUEUES(natmintrq); 596 #endif 597 #undef IF_DETACH_QUEUES 598 599 /* 600 * XXX transient ifp refs? inpcb.ip_moptions.imo_multicast_ifp? 601 * Other network stacks than INET? 602 */ 603 604 /* Remove the interface from the list of all interfaces. */ 605 TAILQ_REMOVE(&ifnet, ifp, if_list); 606 if (ISSET(ifp->if_xflags, IFXF_TXREADY)) 607 TAILQ_REMOVE(&iftxlist, ifp, if_txlist); 608 609 /* 610 * Deallocate private resources. 611 */ 612 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) { 613 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 614 #ifdef INET 615 if (ifa->ifa_addr->sa_family == AF_INET) 616 TAILQ_REMOVE(&in_ifaddr, (struct in_ifaddr *)ifa, 617 ia_list); 618 #endif 619 /* XXX if_free_sadl needs this */ 620 if (ifa == ifnet_addrs[ifp->if_index]) 621 continue; 622 623 ifa->ifa_ifp = NULL; 624 IFAFREE(ifa); 625 } 626 627 for (ifg = TAILQ_FIRST(&ifp->if_groups); ifg; 628 ifg = TAILQ_FIRST(&ifp->if_groups)) 629 if_delgroup(ifp, ifg->ifgl_group->ifg_group); 630 631 if_free_sadl(ifp); 632 633 ifnet_addrs[ifp->if_index]->ifa_ifp = NULL; 634 IFAFREE(ifnet_addrs[ifp->if_index]); 635 ifnet_addrs[ifp->if_index] = NULL; 636 637 free(ifp->if_addrhooks, M_TEMP); 638 free(ifp->if_linkstatehooks, M_TEMP); 639 free(ifp->if_detachhooks, M_TEMP); 640 641 for (dp = domains; dp; dp = dp->dom_next) { 642 if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family]) 643 (*dp->dom_ifdetach)(ifp, 644 ifp->if_afdata[dp->dom_family]); 645 } 646 647 /* Announce that the interface is gone. */ 648 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 649 650 ifindex2ifnet[ifp->if_index] = NULL; 651 splx(s); 652 } 653 654 void 655 if_detach_queues(struct ifnet *ifp, struct ifqueue *q) 656 { 657 struct mbuf *m, *prev, *next; 658 659 prev = NULL; 660 for (m = q->ifq_head; m; m = next) { 661 next = m->m_nextpkt; 662 #ifdef DIAGNOSTIC 663 if ((m->m_flags & M_PKTHDR) == 0) { 664 prev = m; 665 continue; 666 } 667 #endif 668 if (m->m_pkthdr.rcvif != ifp) { 669 prev = m; 670 continue; 671 } 672 673 if (prev) 674 prev->m_nextpkt = m->m_nextpkt; 675 else 676 q->ifq_head = m->m_nextpkt; 677 if (q->ifq_tail == m) 678 q->ifq_tail = prev; 679 q->ifq_len--; 680 681 m->m_nextpkt = NULL; 682 m_freem(m); 683 IF_DROP(q); 684 } 685 } 686 687 /* 688 * Create a clone network interface. 689 */ 690 int 691 if_clone_create(const char *name) 692 { 693 struct if_clone *ifc; 694 struct ifnet *ifp; 695 int unit, ret; 696 697 ifc = if_clone_lookup(name, &unit); 698 if (ifc == NULL) 699 return (EINVAL); 700 701 if (ifunit(name) != NULL) 702 return (EEXIST); 703 704 if ((ret = (*ifc->ifc_create)(ifc, unit)) == 0 && 705 (ifp = ifunit(name)) != NULL) 706 if_addgroup(ifp, ifc->ifc_name); 707 708 return (ret); 709 } 710 711 /* 712 * Destroy a clone network interface. 713 */ 714 int 715 if_clone_destroy(const char *name) 716 { 717 struct if_clone *ifc; 718 struct ifnet *ifp; 719 int s, ret; 720 721 ifc = if_clone_lookup(name, NULL); 722 if (ifc == NULL) 723 return (EINVAL); 724 725 ifp = ifunit(name); 726 if (ifp == NULL) 727 return (ENXIO); 728 729 if (ifc->ifc_destroy == NULL) 730 return (EOPNOTSUPP); 731 732 if (ifp->if_flags & IFF_UP) { 733 s = splnet(); 734 if_down(ifp); 735 splx(s); 736 } 737 738 if_delgroup(ifp, ifc->ifc_name); 739 740 if ((ret = (*ifc->ifc_destroy)(ifp)) != 0) 741 if_addgroup(ifp, ifc->ifc_name); 742 743 return (ret); 744 } 745 746 /* 747 * Look up a network interface cloner. 748 */ 749 struct if_clone * 750 if_clone_lookup(const char *name, int *unitp) 751 { 752 struct if_clone *ifc; 753 const char *cp; 754 int unit; 755 756 /* separate interface name from unit */ 757 for (cp = name; 758 cp - name < IFNAMSIZ && *cp && (*cp < '0' || *cp > '9'); 759 cp++) 760 continue; 761 762 if (cp == name || cp - name == IFNAMSIZ || !*cp) 763 return (NULL); /* No name or unit number */ 764 765 if (cp - name < IFNAMSIZ-1 && *cp == '0' && cp[1] != '\0') 766 return (NULL); /* unit number 0 padded */ 767 768 LIST_FOREACH(ifc, &if_cloners, ifc_list) { 769 if (strlen(ifc->ifc_name) == cp - name && 770 !strncmp(name, ifc->ifc_name, cp - name)) 771 break; 772 } 773 774 if (ifc == NULL) 775 return (NULL); 776 777 unit = 0; 778 while (cp - name < IFNAMSIZ && *cp) { 779 if (*cp < '0' || *cp > '9' || 780 unit > (INT_MAX - (*cp - '0')) / 10) { 781 /* Bogus unit number. */ 782 return (NULL); 783 } 784 unit = (unit * 10) + (*cp++ - '0'); 785 } 786 787 if (unitp != NULL) 788 *unitp = unit; 789 return (ifc); 790 } 791 792 /* 793 * Register a network interface cloner. 794 */ 795 void 796 if_clone_attach(struct if_clone *ifc) 797 { 798 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 799 if_cloners_count++; 800 } 801 802 /* 803 * Unregister a network interface cloner. 804 */ 805 void 806 if_clone_detach(struct if_clone *ifc) 807 { 808 809 LIST_REMOVE(ifc, ifc_list); 810 if_cloners_count--; 811 } 812 813 /* 814 * Provide list of interface cloners to userspace. 815 */ 816 int 817 if_clone_list(struct if_clonereq *ifcr) 818 { 819 char outbuf[IFNAMSIZ], *dst; 820 struct if_clone *ifc; 821 int count, error = 0; 822 823 ifcr->ifcr_total = if_cloners_count; 824 if ((dst = ifcr->ifcr_buffer) == NULL) { 825 /* Just asking how many there are. */ 826 return (0); 827 } 828 829 if (ifcr->ifcr_count < 0) 830 return (EINVAL); 831 832 count = (if_cloners_count < ifcr->ifcr_count) ? 833 if_cloners_count : ifcr->ifcr_count; 834 835 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 836 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 837 bzero(outbuf, sizeof outbuf); 838 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ); 839 error = copyout(outbuf, dst, IFNAMSIZ); 840 if (error) 841 break; 842 } 843 844 return (error); 845 } 846 847 /* 848 * set queue congestion marker and register timeout to clear it 849 */ 850 void 851 if_congestion(struct ifqueue *ifq) 852 { 853 /* Not currently needed, all callers check this */ 854 if (ifq->ifq_congestion) 855 return; 856 857 ifq->ifq_congestion = malloc(sizeof(struct timeout), M_TEMP, M_NOWAIT); 858 if (ifq->ifq_congestion == NULL) 859 return; 860 timeout_set(ifq->ifq_congestion, if_congestion_clear, ifq); 861 timeout_add(ifq->ifq_congestion, hz / 100); 862 } 863 864 /* 865 * clear the congestion flag 866 */ 867 void 868 if_congestion_clear(void *arg) 869 { 870 struct ifqueue *ifq = arg; 871 struct timeout *to = ifq->ifq_congestion; 872 873 ifq->ifq_congestion = NULL; 874 free(to, M_TEMP); 875 } 876 877 /* 878 * Locate an interface based on a complete address. 879 */ 880 /*ARGSUSED*/ 881 struct ifaddr * 882 ifa_ifwithaddr(struct sockaddr *addr, u_int rdomain) 883 { 884 struct ifnet *ifp; 885 struct ifaddr *ifa; 886 887 #define equal(a1, a2) \ 888 (bcmp((caddr_t)(a1), (caddr_t)(a2), \ 889 ((struct sockaddr *)(a1))->sa_len) == 0) 890 TAILQ_FOREACH(ifp, &ifnet, if_list) { 891 if (ifp->if_rdomain != rdomain) 892 continue; 893 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 894 if (ifa->ifa_addr->sa_family != addr->sa_family) 895 continue; 896 if (equal(addr, ifa->ifa_addr)) 897 return (ifa); 898 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr && 899 /* IP6 doesn't have broadcast */ 900 ifa->ifa_broadaddr->sa_len != 0 && 901 equal(ifa->ifa_broadaddr, addr)) 902 return (ifa); 903 } 904 } 905 return (NULL); 906 } 907 /* 908 * Locate the point to point interface with a given destination address. 909 */ 910 /*ARGSUSED*/ 911 struct ifaddr * 912 ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain) 913 { 914 struct ifnet *ifp; 915 struct ifaddr *ifa; 916 917 TAILQ_FOREACH(ifp, &ifnet, if_list) { 918 if (ifp->if_rdomain != rdomain) 919 continue; 920 if (ifp->if_flags & IFF_POINTOPOINT) 921 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 922 if (ifa->ifa_addr->sa_family != 923 addr->sa_family || ifa->ifa_dstaddr == NULL) 924 continue; 925 if (equal(addr, ifa->ifa_dstaddr)) 926 return (ifa); 927 } 928 } 929 return (NULL); 930 } 931 932 /* 933 * Find an interface on a specific network. If many, choice 934 * is most specific found. 935 */ 936 struct ifaddr * 937 ifa_ifwithnet(struct sockaddr *addr, u_int rdomain) 938 { 939 struct ifnet *ifp; 940 struct ifaddr *ifa; 941 struct ifaddr *ifa_maybe = 0; 942 u_int af = addr->sa_family; 943 char *addr_data = addr->sa_data, *cplim; 944 945 if (af == AF_LINK) { 946 struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; 947 if (sdl->sdl_index && sdl->sdl_index < if_indexlim && 948 ifindex2ifnet[sdl->sdl_index]) 949 return (ifnet_addrs[sdl->sdl_index]); 950 } 951 TAILQ_FOREACH(ifp, &ifnet, if_list) { 952 if (ifp->if_rdomain != rdomain) 953 continue; 954 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 955 char *cp, *cp2, *cp3; 956 957 if (ifa->ifa_addr->sa_family != af || 958 ifa->ifa_netmask == 0) 959 next: continue; 960 cp = addr_data; 961 cp2 = ifa->ifa_addr->sa_data; 962 cp3 = ifa->ifa_netmask->sa_data; 963 cplim = (char *)ifa->ifa_netmask + 964 ifa->ifa_netmask->sa_len; 965 while (cp3 < cplim) 966 if ((*cp++ ^ *cp2++) & *cp3++) 967 /* want to continue for() loop */ 968 goto next; 969 if (ifa_maybe == 0 || 970 rn_refines((caddr_t)ifa->ifa_netmask, 971 (caddr_t)ifa_maybe->ifa_netmask)) 972 ifa_maybe = ifa; 973 } 974 } 975 return (ifa_maybe); 976 } 977 978 /* 979 * Find an interface using a specific address family 980 */ 981 struct ifaddr * 982 ifa_ifwithaf(int af, u_int rdomain) 983 { 984 struct ifnet *ifp; 985 struct ifaddr *ifa; 986 987 TAILQ_FOREACH(ifp, &ifnet, if_list) { 988 if (ifp->if_rdomain != rdomain) 989 continue; 990 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 991 if (ifa->ifa_addr->sa_family == af) 992 return (ifa); 993 } 994 } 995 return (NULL); 996 } 997 998 /* 999 * Find an interface address specific to an interface best matching 1000 * a given address. 1001 */ 1002 struct ifaddr * 1003 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp) 1004 { 1005 struct ifaddr *ifa; 1006 char *cp, *cp2, *cp3; 1007 char *cplim; 1008 struct ifaddr *ifa_maybe = NULL; 1009 u_int af = addr->sa_family; 1010 1011 if (af >= AF_MAX) 1012 return (NULL); 1013 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1014 if (ifa->ifa_addr->sa_family != af) 1015 continue; 1016 if (ifa_maybe == NULL) 1017 ifa_maybe = ifa; 1018 if (ifa->ifa_netmask == 0 || ifp->if_flags & IFF_POINTOPOINT) { 1019 if (equal(addr, ifa->ifa_addr) || 1020 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) 1021 return (ifa); 1022 continue; 1023 } 1024 cp = addr->sa_data; 1025 cp2 = ifa->ifa_addr->sa_data; 1026 cp3 = ifa->ifa_netmask->sa_data; 1027 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 1028 for (; cp3 < cplim; cp3++) 1029 if ((*cp++ ^ *cp2++) & *cp3) 1030 break; 1031 if (cp3 == cplim) 1032 return (ifa); 1033 } 1034 return (ifa_maybe); 1035 } 1036 1037 /* 1038 * Default action when installing a route with a Link Level gateway. 1039 * Lookup an appropriate real ifa to point to. 1040 * This should be moved to /sys/net/link.c eventually. 1041 */ 1042 void 1043 link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) 1044 { 1045 struct ifaddr *ifa; 1046 struct sockaddr *dst; 1047 struct ifnet *ifp; 1048 1049 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 1050 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 1051 return; 1052 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { 1053 ifa->ifa_refcnt++; 1054 IFAFREE(rt->rt_ifa); 1055 rt->rt_ifa = ifa; 1056 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 1057 ifa->ifa_rtrequest(cmd, rt, info); 1058 } 1059 } 1060 1061 /* 1062 * Bring down all interfaces 1063 */ 1064 void 1065 if_downall(void) 1066 { 1067 struct ifreq ifrq; /* XXX only partly built */ 1068 struct ifnet *ifp; 1069 int s; 1070 1071 s = splnet(); 1072 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { 1073 if ((ifp->if_flags & IFF_UP) == 0) 1074 continue; 1075 if_down(ifp); 1076 ifp->if_flags &= ~IFF_UP; 1077 1078 if (ifp->if_ioctl) { 1079 ifrq.ifr_flags = ifp->if_flags; 1080 (void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, 1081 (caddr_t)&ifrq); 1082 } 1083 } 1084 splx(s); 1085 } 1086 1087 /* 1088 * Mark an interface down and notify protocols of 1089 * the transition. 1090 * NOTE: must be called at splsoftnet or equivalent. 1091 */ 1092 void 1093 if_down(struct ifnet *ifp) 1094 { 1095 struct ifaddr *ifa; 1096 1097 splsoftassert(IPL_SOFTNET); 1098 1099 ifp->if_flags &= ~IFF_UP; 1100 microtime(&ifp->if_lastchange); 1101 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1102 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 1103 } 1104 IFQ_PURGE(&ifp->if_snd); 1105 #if NCARP > 0 1106 if (ifp->if_carp) 1107 carp_carpdev_state(ifp); 1108 #endif 1109 #if NBRIDGE > 0 1110 if (ifp->if_bridge) 1111 bstp_ifstate(ifp); 1112 #endif 1113 rt_ifmsg(ifp); 1114 #ifndef SMALL_KERNEL 1115 rt_if_track(ifp); 1116 #endif 1117 } 1118 1119 /* 1120 * Mark an interface up and notify protocols of 1121 * the transition. 1122 * NOTE: must be called at splsoftnet or equivalent. 1123 */ 1124 void 1125 if_up(struct ifnet *ifp) 1126 { 1127 #ifdef notyet 1128 struct ifaddr *ifa; 1129 #endif 1130 1131 splsoftassert(IPL_SOFTNET); 1132 1133 ifp->if_flags |= IFF_UP; 1134 microtime(&ifp->if_lastchange); 1135 #ifdef notyet 1136 /* this has no effect on IP, and will kill all ISO connections XXX */ 1137 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1138 pfctlinput(PRC_IFUP, ifa->ifa_addr); 1139 } 1140 #endif 1141 #if NCARP > 0 1142 if (ifp->if_carp) 1143 carp_carpdev_state(ifp); 1144 #endif 1145 #if NBRIDGE > 0 1146 if (ifp->if_bridge) 1147 bstp_ifstate(ifp); 1148 #endif 1149 rt_ifmsg(ifp); 1150 #ifdef INET6 1151 if (!(ifp->if_xflags & IFXF_NOINET6)) 1152 in6_if_up(ifp); 1153 #endif 1154 1155 #ifndef SMALL_KERNEL 1156 rt_if_track(ifp); 1157 #endif 1158 1159 m_clinitifp(ifp); 1160 } 1161 1162 /* 1163 * Process a link state change. 1164 * NOTE: must be called at splsoftnet or equivalent. 1165 */ 1166 void 1167 if_link_state_change(struct ifnet *ifp) 1168 { 1169 rt_ifmsg(ifp); 1170 #ifndef SMALL_KERNEL 1171 rt_if_track(ifp); 1172 #endif 1173 dohooks(ifp->if_linkstatehooks, 0); 1174 } 1175 1176 /* 1177 * Flush an interface queue. 1178 */ 1179 void 1180 if_qflush(struct ifqueue *ifq) 1181 { 1182 struct mbuf *m, *n; 1183 1184 n = ifq->ifq_head; 1185 while ((m = n) != NULL) { 1186 n = m->m_act; 1187 m_freem(m); 1188 } 1189 ifq->ifq_head = 0; 1190 ifq->ifq_tail = 0; 1191 ifq->ifq_len = 0; 1192 } 1193 1194 /* 1195 * Handle interface watchdog timer routines. Called 1196 * from softclock, we decrement timers (if set) and 1197 * call the appropriate interface routine on expiration. 1198 */ 1199 void 1200 if_slowtimo(void *arg) 1201 { 1202 struct timeout *to = (struct timeout *)arg; 1203 struct ifnet *ifp; 1204 int s = splnet(); 1205 1206 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1207 if (ifp->if_timer == 0 || --ifp->if_timer) 1208 continue; 1209 if (ifp->if_watchdog) 1210 (*ifp->if_watchdog)(ifp); 1211 } 1212 splx(s); 1213 timeout_add(to, hz / IFNET_SLOWHZ); 1214 } 1215 1216 /* 1217 * Map interface name to 1218 * interface structure pointer. 1219 */ 1220 struct ifnet * 1221 ifunit(const char *name) 1222 { 1223 struct ifnet *ifp; 1224 1225 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1226 if (strcmp(ifp->if_xname, name) == 0) 1227 return (ifp); 1228 } 1229 return (NULL); 1230 } 1231 1232 /* 1233 * Interface ioctls. 1234 */ 1235 int 1236 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) 1237 { 1238 struct ifnet *ifp; 1239 struct ifreq *ifr; 1240 struct ifaddr *ifa, *nifa; 1241 struct sockaddr_dl *sdl; 1242 struct ifgroupreq *ifgr; 1243 char ifdescrbuf[IFDESCRSIZE]; 1244 char ifrtlabelbuf[RTLABEL_LEN]; 1245 int error = 0; 1246 size_t bytesdone; 1247 short oif_flags; 1248 const char *label; 1249 1250 switch (cmd) { 1251 1252 case SIOCGIFCONF: 1253 case OSIOCGIFCONF: 1254 return (ifconf(cmd, data)); 1255 } 1256 ifr = (struct ifreq *)data; 1257 1258 switch (cmd) { 1259 case SIOCIFCREATE: 1260 case SIOCIFDESTROY: 1261 if ((error = suser(p, 0)) != 0) 1262 return (error); 1263 return ((cmd == SIOCIFCREATE) ? 1264 if_clone_create(ifr->ifr_name) : 1265 if_clone_destroy(ifr->ifr_name)); 1266 case SIOCIFGCLONERS: 1267 return (if_clone_list((struct if_clonereq *)data)); 1268 case SIOCGIFGMEMB: 1269 return (if_getgroupmembers(data)); 1270 case SIOCGIFGATTR: 1271 return (if_getgroupattribs(data)); 1272 case SIOCSIFGATTR: 1273 if ((error = suser(p, 0)) != 0) 1274 return (error); 1275 return (if_setgroupattribs(data)); 1276 } 1277 1278 ifp = ifunit(ifr->ifr_name); 1279 if (ifp == 0) 1280 return (ENXIO); 1281 oif_flags = ifp->if_flags; 1282 switch (cmd) { 1283 1284 case SIOCGIFFLAGS: 1285 ifr->ifr_flags = ifp->if_flags; 1286 break; 1287 1288 case SIOCGIFXFLAGS: 1289 ifr->ifr_flags = ifp->if_xflags; 1290 break; 1291 1292 case SIOCGIFMETRIC: 1293 ifr->ifr_metric = ifp->if_metric; 1294 break; 1295 1296 case SIOCGIFMTU: 1297 ifr->ifr_mtu = ifp->if_mtu; 1298 break; 1299 1300 case SIOCGIFDATA: 1301 error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data, 1302 sizeof(ifp->if_data)); 1303 break; 1304 1305 case SIOCSIFFLAGS: 1306 if ((error = suser(p, 0)) != 0) 1307 return (error); 1308 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 1309 int s = splnet(); 1310 if_down(ifp); 1311 splx(s); 1312 } 1313 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 1314 int s = splnet(); 1315 if_up(ifp); 1316 splx(s); 1317 } 1318 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 1319 (ifr->ifr_flags &~ IFF_CANTCHANGE); 1320 if (ifp->if_ioctl) 1321 (void) (*ifp->if_ioctl)(ifp, cmd, data); 1322 break; 1323 1324 case SIOCSIFXFLAGS: 1325 if ((error = suser(p, 0)) != 0) 1326 return (error); 1327 1328 #ifdef INET6 1329 /* when IFXF_NOINET6 gets changed, detach/attach */ 1330 if (ifp->if_flags & IFF_UP && ifr->ifr_flags & IFXF_NOINET6 && 1331 !(ifp->if_xflags & IFXF_NOINET6)) 1332 in6_ifdetach(ifp); 1333 if (ifp->if_flags & IFF_UP && ifp->if_xflags & IFXF_NOINET6 && 1334 !(ifr->ifr_flags & IFXF_NOINET6)) { 1335 ifp->if_xflags &= ~IFXF_NOINET6; 1336 in6_if_up(ifp); 1337 } 1338 #endif 1339 1340 ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) | 1341 (ifr->ifr_flags &~ IFXF_CANTCHANGE); 1342 rt_ifmsg(ifp); 1343 break; 1344 1345 case SIOCSIFMETRIC: 1346 if ((error = suser(p, 0)) != 0) 1347 return (error); 1348 ifp->if_metric = ifr->ifr_metric; 1349 break; 1350 1351 case SIOCSIFMTU: 1352 { 1353 #ifdef INET6 1354 int oldmtu = ifp->if_mtu; 1355 #endif 1356 1357 if ((error = suser(p, 0)) != 0) 1358 return (error); 1359 if (ifp->if_ioctl == NULL) 1360 return (EOPNOTSUPP); 1361 error = (*ifp->if_ioctl)(ifp, cmd, data); 1362 1363 /* 1364 * If the link MTU changed, do network layer specific procedure. 1365 */ 1366 #ifdef INET6 1367 if (ifp->if_mtu != oldmtu) 1368 nd6_setmtu(ifp); 1369 #endif 1370 break; 1371 } 1372 1373 case SIOCSIFPHYADDR: 1374 case SIOCDIFPHYADDR: 1375 #ifdef INET6 1376 case SIOCSIFPHYADDR_IN6: 1377 #endif 1378 case SIOCSLIFPHYADDR: 1379 case SIOCADDMULTI: 1380 case SIOCDELMULTI: 1381 case SIOCSIFMEDIA: 1382 if ((error = suser(p, 0)) != 0) 1383 return (error); 1384 /* FALLTHROUGH */ 1385 case SIOCGIFPSRCADDR: 1386 case SIOCGIFPDSTADDR: 1387 case SIOCGLIFPHYADDR: 1388 case SIOCGIFMEDIA: 1389 if (ifp->if_ioctl == 0) 1390 return (EOPNOTSUPP); 1391 error = (*ifp->if_ioctl)(ifp, cmd, data); 1392 break; 1393 1394 case SIOCGIFDESCR: 1395 strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE); 1396 error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE, 1397 &bytesdone); 1398 break; 1399 1400 case SIOCSIFDESCR: 1401 if ((error = suser(p, 0)) != 0) 1402 return (error); 1403 error = copyinstr(ifr->ifr_data, ifdescrbuf, 1404 IFDESCRSIZE, &bytesdone); 1405 if (error == 0) { 1406 (void)memset(ifp->if_description, 0, IFDESCRSIZE); 1407 strlcpy(ifp->if_description, ifdescrbuf, IFDESCRSIZE); 1408 } 1409 break; 1410 1411 case SIOCGIFRTLABEL: 1412 if (ifp->if_rtlabelid && 1413 (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) { 1414 strlcpy(ifrtlabelbuf, label, RTLABEL_LEN); 1415 error = copyoutstr(ifrtlabelbuf, ifr->ifr_data, 1416 RTLABEL_LEN, &bytesdone); 1417 } else 1418 error = ENOENT; 1419 break; 1420 1421 case SIOCSIFRTLABEL: 1422 if ((error = suser(p, 0)) != 0) 1423 return (error); 1424 error = copyinstr(ifr->ifr_data, ifrtlabelbuf, 1425 RTLABEL_LEN, &bytesdone); 1426 if (error == 0) { 1427 rtlabel_unref(ifp->if_rtlabelid); 1428 ifp->if_rtlabelid = rtlabel_name2id(ifrtlabelbuf); 1429 } 1430 break; 1431 1432 case SIOCGIFPRIORITY: 1433 ifr->ifr_metric = ifp->if_priority; 1434 break; 1435 1436 case SIOCSIFPRIORITY: 1437 if ((error = suser(p, 0)) != 0) 1438 return (error); 1439 if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15) 1440 return (EINVAL); 1441 ifp->if_priority = ifr->ifr_metric; 1442 break; 1443 1444 case SIOCGIFRTABLEID: 1445 ifr->ifr_rdomainid = ifp->if_rdomain; 1446 break; 1447 1448 case SIOCSIFRTABLEID: 1449 if ((error = suser(p, 0)) != 0) 1450 return (error); 1451 if (ifr->ifr_rdomainid < 0 || 1452 ifr->ifr_rdomainid > RT_TABLEID_MAX) 1453 return (EINVAL); 1454 /* remove all routing entries when switching domains */ 1455 /* XXX hell this is ugly */ 1456 if (ifr->ifr_rdomainid != ifp->if_rdomain) { 1457 rt_if_remove(ifp); 1458 #ifdef INET 1459 rti_delete(ifp); 1460 #if NETHER > 0 1461 myip_ifp = NULL; 1462 #endif 1463 #ifdef MROUTING 1464 vif_delete(ifp); 1465 #endif 1466 #endif 1467 #ifdef INET6 1468 in6_ifdetach(ifp); 1469 #endif 1470 #ifdef INET 1471 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1472 ifa = nifa) { 1473 nifa = TAILQ_NEXT(ifa, ifa_list); 1474 1475 /* only remove AF_INET */ 1476 if (ifa->ifa_addr->sa_family != AF_INET) 1477 continue; 1478 1479 TAILQ_REMOVE(&in_ifaddr, 1480 (struct in_ifaddr *)ifa, ia_list); 1481 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 1482 ifa->ifa_ifp = NULL; 1483 IFAFREE(ifa); 1484 } 1485 #endif 1486 } 1487 1488 /* make sure that the routing table exists */ 1489 if (!rtable_exists(ifr->ifr_rdomainid)) { 1490 if (rtable_add(ifr->ifr_rdomainid) == -1) 1491 panic("rtinit: rtable_add"); 1492 } 1493 1494 ifp->if_rdomain = ifr->ifr_rdomainid; 1495 break; 1496 1497 case SIOCAIFGROUP: 1498 if ((error = suser(p, 0))) 1499 return (error); 1500 (*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */ 1501 ifgr = (struct ifgroupreq *)data; 1502 if ((error = if_addgroup(ifp, ifgr->ifgr_group))) 1503 return (error); 1504 break; 1505 1506 case SIOCGIFGROUP: 1507 if ((error = if_getgroup(data, ifp))) 1508 return (error); 1509 break; 1510 1511 case SIOCDIFGROUP: 1512 if ((error = suser(p, 0))) 1513 return (error); 1514 (*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */ 1515 ifgr = (struct ifgroupreq *)data; 1516 if ((error = if_delgroup(ifp, ifgr->ifgr_group))) 1517 return (error); 1518 break; 1519 1520 case SIOCSIFLLADDR: 1521 if ((error = suser(p, 0))) 1522 return (error); 1523 ifa = ifnet_addrs[ifp->if_index]; 1524 if (ifa == NULL) 1525 return (EINVAL); 1526 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1527 if (sdl == NULL) 1528 return (EINVAL); 1529 if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) 1530 return (EINVAL); 1531 if (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data)) 1532 return (EINVAL); 1533 switch (ifp->if_type) { 1534 case IFT_ETHER: 1535 case IFT_CARP: 1536 case IFT_FDDI: 1537 case IFT_XETHER: 1538 case IFT_ISO88025: 1539 case IFT_L2VLAN: 1540 bcopy((caddr_t)ifr->ifr_addr.sa_data, 1541 (caddr_t)((struct arpcom *)ifp)->ac_enaddr, 1542 ETHER_ADDR_LEN); 1543 bcopy((caddr_t)ifr->ifr_addr.sa_data, 1544 LLADDR(sdl), ETHER_ADDR_LEN); 1545 break; 1546 default: 1547 return (ENODEV); 1548 } 1549 if (ifp->if_flags & IFF_UP) { 1550 struct ifreq ifrq; 1551 int s = splnet(); 1552 ifp->if_flags &= ~IFF_UP; 1553 ifrq.ifr_flags = ifp->if_flags; 1554 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); 1555 ifp->if_flags |= IFF_UP; 1556 ifrq.ifr_flags = ifp->if_flags; 1557 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); 1558 splx(s); 1559 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1560 if (ifa->ifa_addr != NULL && 1561 ifa->ifa_addr->sa_family == AF_INET) 1562 arp_ifinit((struct arpcom *)ifp, ifa); 1563 } 1564 } 1565 break; 1566 1567 default: 1568 if (so->so_proto == 0) 1569 return (EOPNOTSUPP); 1570 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4) 1571 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1572 (struct mbuf *) cmd, (struct mbuf *) data, 1573 (struct mbuf *) ifp, p)); 1574 #else 1575 { 1576 u_long ocmd = cmd; 1577 1578 switch (cmd) { 1579 1580 case SIOCSIFADDR: 1581 case SIOCSIFDSTADDR: 1582 case SIOCSIFBRDADDR: 1583 case SIOCSIFNETMASK: 1584 #if BYTE_ORDER != BIG_ENDIAN 1585 if (ifr->ifr_addr.sa_family == 0 && 1586 ifr->ifr_addr.sa_len < 16) { 1587 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 1588 ifr->ifr_addr.sa_len = 16; 1589 } 1590 #else 1591 if (ifr->ifr_addr.sa_len == 0) 1592 ifr->ifr_addr.sa_len = 16; 1593 #endif 1594 break; 1595 1596 case OSIOCGIFADDR: 1597 cmd = SIOCGIFADDR; 1598 break; 1599 1600 case OSIOCGIFDSTADDR: 1601 cmd = SIOCGIFDSTADDR; 1602 break; 1603 1604 case OSIOCGIFBRDADDR: 1605 cmd = SIOCGIFBRDADDR; 1606 break; 1607 1608 case OSIOCGIFNETMASK: 1609 cmd = SIOCGIFNETMASK; 1610 } 1611 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1612 (struct mbuf *) cmd, (struct mbuf *) data, 1613 (struct mbuf *) ifp, p)); 1614 switch (ocmd) { 1615 1616 case OSIOCGIFADDR: 1617 case OSIOCGIFDSTADDR: 1618 case OSIOCGIFBRDADDR: 1619 case OSIOCGIFNETMASK: 1620 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 1621 } 1622 1623 } 1624 #endif 1625 break; 1626 } 1627 1628 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) { 1629 microtime(&ifp->if_lastchange); 1630 #ifdef INET6 1631 if (!(ifp->if_xflags & IFXF_NOINET6) && 1632 (ifp->if_flags & IFF_UP) != 0) { 1633 int s = splnet(); 1634 in6_if_up(ifp); 1635 splx(s); 1636 } 1637 #endif 1638 } 1639 return (error); 1640 } 1641 1642 /* 1643 * Return interface configuration 1644 * of system. List may be used 1645 * in later ioctl's (above) to get 1646 * other information. 1647 */ 1648 /*ARGSUSED*/ 1649 int 1650 ifconf(u_long cmd, caddr_t data) 1651 { 1652 struct ifconf *ifc = (struct ifconf *)data; 1653 struct ifnet *ifp; 1654 struct ifaddr *ifa; 1655 struct ifreq ifr, *ifrp; 1656 int space = ifc->ifc_len, error = 0; 1657 1658 /* If ifc->ifc_len is 0, fill it in with the needed size and return. */ 1659 if (space == 0) { 1660 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1661 struct sockaddr *sa; 1662 1663 if (TAILQ_EMPTY(&ifp->if_addrlist)) 1664 space += sizeof (ifr); 1665 else 1666 TAILQ_FOREACH(ifa, 1667 &ifp->if_addrlist, ifa_list) { 1668 sa = ifa->ifa_addr; 1669 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1670 if (cmd != OSIOCGIFCONF) 1671 #endif 1672 if (sa->sa_len > sizeof(*sa)) 1673 space += sa->sa_len - 1674 sizeof(*sa); 1675 space += sizeof(ifr); 1676 } 1677 } 1678 ifc->ifc_len = space; 1679 return (0); 1680 } 1681 1682 ifrp = ifc->ifc_req; 1683 for (ifp = TAILQ_FIRST(&ifnet); space >= sizeof(ifr) && 1684 ifp != TAILQ_END(&ifnet); ifp = TAILQ_NEXT(ifp, if_list)) { 1685 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ); 1686 if (TAILQ_EMPTY(&ifp->if_addrlist)) { 1687 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 1688 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1689 sizeof(ifr)); 1690 if (error) 1691 break; 1692 space -= sizeof (ifr), ifrp++; 1693 } else 1694 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); 1695 space >= sizeof (ifr) && 1696 ifa != TAILQ_END(&ifp->if_addrlist); 1697 ifa = TAILQ_NEXT(ifa, ifa_list)) { 1698 struct sockaddr *sa = ifa->ifa_addr; 1699 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1700 if (cmd == OSIOCGIFCONF) { 1701 struct osockaddr *osa = 1702 (struct osockaddr *)&ifr.ifr_addr; 1703 ifr.ifr_addr = *sa; 1704 osa->sa_family = sa->sa_family; 1705 error = copyout((caddr_t)&ifr, 1706 (caddr_t)ifrp, sizeof (ifr)); 1707 ifrp++; 1708 } else 1709 #endif 1710 if (sa->sa_len <= sizeof(*sa)) { 1711 ifr.ifr_addr = *sa; 1712 error = copyout((caddr_t)&ifr, 1713 (caddr_t)ifrp, sizeof (ifr)); 1714 ifrp++; 1715 } else { 1716 space -= sa->sa_len - sizeof(*sa); 1717 if (space < sizeof (ifr)) 1718 break; 1719 error = copyout((caddr_t)&ifr, 1720 (caddr_t)ifrp, 1721 sizeof(ifr.ifr_name)); 1722 if (error == 0) 1723 error = copyout((caddr_t)sa, 1724 (caddr_t)&ifrp->ifr_addr, 1725 sa->sa_len); 1726 ifrp = (struct ifreq *)(sa->sa_len + 1727 (caddr_t)&ifrp->ifr_addr); 1728 } 1729 if (error) 1730 break; 1731 space -= sizeof (ifr); 1732 } 1733 } 1734 ifc->ifc_len -= space; 1735 return (error); 1736 } 1737 1738 /* 1739 * Dummy functions replaced in ifnet during detach (if protocols decide to 1740 * fiddle with the if during detach. 1741 */ 1742 void 1743 if_detached_start(struct ifnet *ifp) 1744 { 1745 struct mbuf *m; 1746 1747 while (1) { 1748 IF_DEQUEUE(&ifp->if_snd, m); 1749 1750 if (m == NULL) 1751 return; 1752 m_freem(m); 1753 } 1754 } 1755 1756 int 1757 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b) 1758 { 1759 return ENODEV; 1760 } 1761 1762 int 1763 if_detached_init(struct ifnet *ifp) 1764 { 1765 return (ENXIO); 1766 } 1767 1768 void 1769 if_detached_watchdog(struct ifnet *ifp) 1770 { 1771 /* nothing */ 1772 } 1773 1774 /* 1775 * Create interface group without members 1776 */ 1777 struct ifg_group * 1778 if_creategroup(const char *groupname) 1779 { 1780 struct ifg_group *ifg; 1781 1782 if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL) 1783 return (NULL); 1784 1785 strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group)); 1786 ifg->ifg_refcnt = 0; 1787 ifg->ifg_carp_demoted = 0; 1788 TAILQ_INIT(&ifg->ifg_members); 1789 #if NPF > 0 1790 pfi_attach_ifgroup(ifg); 1791 #endif 1792 TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next); 1793 1794 return (ifg); 1795 } 1796 1797 /* 1798 * Add a group to an interface 1799 */ 1800 int 1801 if_addgroup(struct ifnet *ifp, const char *groupname) 1802 { 1803 struct ifg_list *ifgl; 1804 struct ifg_group *ifg = NULL; 1805 struct ifg_member *ifgm; 1806 1807 if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' && 1808 groupname[strlen(groupname) - 1] <= '9') 1809 return (EINVAL); 1810 1811 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 1812 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) 1813 return (EEXIST); 1814 1815 if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL) 1816 return (ENOMEM); 1817 1818 if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) { 1819 free(ifgl, M_TEMP); 1820 return (ENOMEM); 1821 } 1822 1823 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1824 if (!strcmp(ifg->ifg_group, groupname)) 1825 break; 1826 1827 if (ifg == NULL && (ifg = if_creategroup(groupname)) == NULL) { 1828 free(ifgl, M_TEMP); 1829 free(ifgm, M_TEMP); 1830 return (ENOMEM); 1831 } 1832 1833 ifg->ifg_refcnt++; 1834 ifgl->ifgl_group = ifg; 1835 ifgm->ifgm_ifp = ifp; 1836 1837 TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next); 1838 TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next); 1839 1840 #if NPF > 0 1841 pfi_group_change(groupname); 1842 #endif 1843 1844 return (0); 1845 } 1846 1847 /* 1848 * Remove a group from an interface 1849 */ 1850 int 1851 if_delgroup(struct ifnet *ifp, const char *groupname) 1852 { 1853 struct ifg_list *ifgl; 1854 struct ifg_member *ifgm; 1855 1856 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 1857 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) 1858 break; 1859 if (ifgl == NULL) 1860 return (ENOENT); 1861 1862 TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next); 1863 1864 TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) 1865 if (ifgm->ifgm_ifp == ifp) 1866 break; 1867 1868 if (ifgm != NULL) { 1869 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next); 1870 free(ifgm, M_TEMP); 1871 } 1872 1873 if (--ifgl->ifgl_group->ifg_refcnt == 0) { 1874 TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next); 1875 #if NPF > 0 1876 pfi_detach_ifgroup(ifgl->ifgl_group); 1877 #endif 1878 free(ifgl->ifgl_group, M_TEMP); 1879 } 1880 1881 free(ifgl, M_TEMP); 1882 1883 #if NPF > 0 1884 pfi_group_change(groupname); 1885 #endif 1886 1887 return (0); 1888 } 1889 1890 /* 1891 * Stores all groups from an interface in memory pointed 1892 * to by data 1893 */ 1894 int 1895 if_getgroup(caddr_t data, struct ifnet *ifp) 1896 { 1897 int len, error; 1898 struct ifg_list *ifgl; 1899 struct ifg_req ifgrq, *ifgp; 1900 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1901 1902 if (ifgr->ifgr_len == 0) { 1903 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 1904 ifgr->ifgr_len += sizeof(struct ifg_req); 1905 return (0); 1906 } 1907 1908 len = ifgr->ifgr_len; 1909 ifgp = ifgr->ifgr_groups; 1910 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { 1911 if (len < sizeof(ifgrq)) 1912 return (EINVAL); 1913 bzero(&ifgrq, sizeof ifgrq); 1914 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, 1915 sizeof(ifgrq.ifgrq_group)); 1916 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, 1917 sizeof(struct ifg_req)))) 1918 return (error); 1919 len -= sizeof(ifgrq); 1920 ifgp++; 1921 } 1922 1923 return (0); 1924 } 1925 1926 /* 1927 * Stores all members of a group in memory pointed to by data 1928 */ 1929 int 1930 if_getgroupmembers(caddr_t data) 1931 { 1932 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1933 struct ifg_group *ifg; 1934 struct ifg_member *ifgm; 1935 struct ifg_req ifgrq, *ifgp; 1936 int len, error; 1937 1938 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1939 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 1940 break; 1941 if (ifg == NULL) 1942 return (ENOENT); 1943 1944 if (ifgr->ifgr_len == 0) { 1945 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) 1946 ifgr->ifgr_len += sizeof(ifgrq); 1947 return (0); 1948 } 1949 1950 len = ifgr->ifgr_len; 1951 ifgp = ifgr->ifgr_groups; 1952 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) { 1953 if (len < sizeof(ifgrq)) 1954 return (EINVAL); 1955 bzero(&ifgrq, sizeof ifgrq); 1956 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname, 1957 sizeof(ifgrq.ifgrq_member)); 1958 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, 1959 sizeof(struct ifg_req)))) 1960 return (error); 1961 len -= sizeof(ifgrq); 1962 ifgp++; 1963 } 1964 1965 return (0); 1966 } 1967 1968 int 1969 if_getgroupattribs(caddr_t data) 1970 { 1971 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1972 struct ifg_group *ifg; 1973 1974 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1975 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 1976 break; 1977 if (ifg == NULL) 1978 return (ENOENT); 1979 1980 ifgr->ifgr_attrib.ifg_carp_demoted = ifg->ifg_carp_demoted; 1981 1982 return (0); 1983 } 1984 1985 int 1986 if_setgroupattribs(caddr_t data) 1987 { 1988 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1989 struct ifg_group *ifg; 1990 struct ifg_member *ifgm; 1991 int demote; 1992 1993 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1994 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 1995 break; 1996 if (ifg == NULL) 1997 return (ENOENT); 1998 1999 demote = ifgr->ifgr_attrib.ifg_carp_demoted; 2000 if (demote + ifg->ifg_carp_demoted > 0xff || 2001 demote + ifg->ifg_carp_demoted < 0) 2002 return (ERANGE); 2003 2004 ifg->ifg_carp_demoted += demote; 2005 2006 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) 2007 if (ifgm->ifgm_ifp->if_ioctl) 2008 ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, 2009 SIOCSIFGATTR, data); 2010 return (0); 2011 } 2012 2013 void 2014 if_group_routechange(struct sockaddr *dst, struct sockaddr *mask) 2015 { 2016 switch (dst->sa_family) { 2017 case AF_INET: 2018 if (satosin(dst)->sin_addr.s_addr == INADDR_ANY && 2019 mask && (mask->sa_len == 0 || 2020 satosin(mask)->sin_addr.s_addr == INADDR_ANY)) 2021 if_group_egress_build(); 2022 break; 2023 #ifdef INET6 2024 case AF_INET6: 2025 if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr, 2026 &in6addr_any) && mask && (mask->sa_len == 0 || 2027 IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr, 2028 &in6addr_any))) 2029 if_group_egress_build(); 2030 break; 2031 #endif 2032 } 2033 } 2034 2035 int 2036 if_group_egress_build(void) 2037 { 2038 struct ifg_group *ifg; 2039 struct ifg_member *ifgm, *next; 2040 struct sockaddr_in sa_in; 2041 #ifdef INET6 2042 struct sockaddr_in6 sa_in6; 2043 #endif 2044 struct radix_node *rn; 2045 struct rtentry *rt; 2046 2047 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 2048 if (!strcmp(ifg->ifg_group, IFG_EGRESS)) 2049 break; 2050 2051 if (ifg != NULL) 2052 for (ifgm = TAILQ_FIRST(&ifg->ifg_members); ifgm; ifgm = next) { 2053 next = TAILQ_NEXT(ifgm, ifgm_next); 2054 if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS); 2055 } 2056 2057 bzero(&sa_in, sizeof(sa_in)); 2058 sa_in.sin_len = sizeof(sa_in); 2059 sa_in.sin_family = AF_INET; 2060 if ((rn = rt_lookup(sintosa(&sa_in), sintosa(&sa_in), 0)) != NULL) { 2061 do { 2062 rt = (struct rtentry *)rn; 2063 if (rt->rt_ifp) 2064 if_addgroup(rt->rt_ifp, IFG_EGRESS); 2065 #ifndef SMALL_KERNEL 2066 rn = rn_mpath_next(rn, 0); 2067 #else 2068 rn = NULL; 2069 #endif 2070 } while (rn != NULL); 2071 } 2072 2073 #ifdef INET6 2074 bcopy(&sa6_any, &sa_in6, sizeof(sa_in6)); 2075 if ((rn = rt_lookup(sin6tosa(&sa_in6), sin6tosa(&sa_in6), 0)) != NULL) { 2076 do { 2077 rt = (struct rtentry *)rn; 2078 if (rt->rt_ifp) 2079 if_addgroup(rt->rt_ifp, IFG_EGRESS); 2080 #ifndef SMALL_KERNEL 2081 rn = rn_mpath_next(rn, 0); 2082 #else 2083 rn = NULL; 2084 #endif 2085 } while (rn != NULL); 2086 } 2087 #endif 2088 2089 return (0); 2090 } 2091 2092 /* 2093 * Set/clear promiscuous mode on interface ifp based on the truth value 2094 * of pswitch. The calls are reference counted so that only the first 2095 * "on" request actually has an effect, as does the final "off" request. 2096 * Results are undefined if the "off" and "on" requests are not matched. 2097 */ 2098 int 2099 ifpromisc(struct ifnet *ifp, int pswitch) 2100 { 2101 struct ifreq ifr; 2102 2103 if (pswitch) { 2104 /* 2105 * If the device is not configured up, we cannot put it in 2106 * promiscuous mode. 2107 */ 2108 if ((ifp->if_flags & IFF_UP) == 0) 2109 return (ENETDOWN); 2110 if (ifp->if_pcount++ != 0) 2111 return (0); 2112 ifp->if_flags |= IFF_PROMISC; 2113 } else { 2114 if (--ifp->if_pcount > 0) 2115 return (0); 2116 ifp->if_flags &= ~IFF_PROMISC; 2117 /* 2118 * If the device is not configured up, we should not need to 2119 * turn off promiscuous mode (device should have turned it 2120 * off when interface went down; and will look at IFF_PROMISC 2121 * again next time interface comes up). 2122 */ 2123 if ((ifp->if_flags & IFF_UP) == 0) 2124 return (0); 2125 } 2126 ifr.ifr_flags = ifp->if_flags; 2127 return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); 2128 } 2129 2130 int 2131 sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2132 void *newp, size_t newlen, struct ifqueue *ifq) 2133 { 2134 /* All sysctl names at this level are terminal. */ 2135 if (namelen != 1) 2136 return (ENOTDIR); 2137 2138 switch (name[0]) { 2139 case IFQCTL_LEN: 2140 return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_len)); 2141 case IFQCTL_MAXLEN: 2142 return (sysctl_int(oldp, oldlenp, newp, newlen, 2143 &ifq->ifq_maxlen)); 2144 case IFQCTL_DROPS: 2145 return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_drops)); 2146 default: 2147 return (EOPNOTSUPP); 2148 } 2149 /* NOTREACHED */ 2150 } 2151