1 /* $OpenBSD: if.c,v 1.200 2009/11/03 10:59:04 claudio 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 891 rdomain = rtable_l2(rdomain); 892 TAILQ_FOREACH(ifp, &ifnet, if_list) { 893 if (ifp->if_rdomain != rdomain) 894 continue; 895 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 896 if (ifa->ifa_addr->sa_family != addr->sa_family) 897 continue; 898 if (equal(addr, ifa->ifa_addr)) 899 return (ifa); 900 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr && 901 /* IP6 doesn't have broadcast */ 902 ifa->ifa_broadaddr->sa_len != 0 && 903 equal(ifa->ifa_broadaddr, addr)) 904 return (ifa); 905 } 906 } 907 return (NULL); 908 } 909 /* 910 * Locate the point to point interface with a given destination address. 911 */ 912 /*ARGSUSED*/ 913 struct ifaddr * 914 ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain) 915 { 916 struct ifnet *ifp; 917 struct ifaddr *ifa; 918 919 rdomain = rtable_l2(rdomain); 920 TAILQ_FOREACH(ifp, &ifnet, if_list) { 921 if (ifp->if_rdomain != rdomain) 922 continue; 923 if (ifp->if_flags & IFF_POINTOPOINT) 924 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 925 if (ifa->ifa_addr->sa_family != 926 addr->sa_family || ifa->ifa_dstaddr == NULL) 927 continue; 928 if (equal(addr, ifa->ifa_dstaddr)) 929 return (ifa); 930 } 931 } 932 return (NULL); 933 } 934 935 /* 936 * Find an interface on a specific network. If many, choice 937 * is most specific found. 938 */ 939 struct ifaddr * 940 ifa_ifwithnet(struct sockaddr *addr, u_int rdomain) 941 { 942 struct ifnet *ifp; 943 struct ifaddr *ifa; 944 struct ifaddr *ifa_maybe = 0; 945 u_int af = addr->sa_family; 946 char *addr_data = addr->sa_data, *cplim; 947 948 rdomain = rtable_l2(rdomain); 949 if (af == AF_LINK) { 950 struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; 951 if (sdl->sdl_index && sdl->sdl_index < if_indexlim && 952 ifindex2ifnet[sdl->sdl_index]) 953 return (ifnet_addrs[sdl->sdl_index]); 954 } 955 TAILQ_FOREACH(ifp, &ifnet, if_list) { 956 if (ifp->if_rdomain != rdomain) 957 continue; 958 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 959 char *cp, *cp2, *cp3; 960 961 if (ifa->ifa_addr->sa_family != af || 962 ifa->ifa_netmask == 0) 963 next: continue; 964 cp = addr_data; 965 cp2 = ifa->ifa_addr->sa_data; 966 cp3 = ifa->ifa_netmask->sa_data; 967 cplim = (char *)ifa->ifa_netmask + 968 ifa->ifa_netmask->sa_len; 969 while (cp3 < cplim) 970 if ((*cp++ ^ *cp2++) & *cp3++) 971 /* want to continue for() loop */ 972 goto next; 973 if (ifa_maybe == 0 || 974 rn_refines((caddr_t)ifa->ifa_netmask, 975 (caddr_t)ifa_maybe->ifa_netmask)) 976 ifa_maybe = ifa; 977 } 978 } 979 return (ifa_maybe); 980 } 981 982 /* 983 * Find an interface using a specific address family 984 */ 985 struct ifaddr * 986 ifa_ifwithaf(int af, u_int rdomain) 987 { 988 struct ifnet *ifp; 989 struct ifaddr *ifa; 990 991 rdomain = rtable_l2(rdomain); 992 TAILQ_FOREACH(ifp, &ifnet, if_list) { 993 if (ifp->if_rdomain != rdomain) 994 continue; 995 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 996 if (ifa->ifa_addr->sa_family == af) 997 return (ifa); 998 } 999 } 1000 return (NULL); 1001 } 1002 1003 /* 1004 * Find an interface address specific to an interface best matching 1005 * a given address. 1006 */ 1007 struct ifaddr * 1008 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp) 1009 { 1010 struct ifaddr *ifa; 1011 char *cp, *cp2, *cp3; 1012 char *cplim; 1013 struct ifaddr *ifa_maybe = NULL; 1014 u_int af = addr->sa_family; 1015 1016 if (af >= AF_MAX) 1017 return (NULL); 1018 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1019 if (ifa->ifa_addr->sa_family != af) 1020 continue; 1021 if (ifa_maybe == NULL) 1022 ifa_maybe = ifa; 1023 if (ifa->ifa_netmask == 0 || ifp->if_flags & IFF_POINTOPOINT) { 1024 if (equal(addr, ifa->ifa_addr) || 1025 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) 1026 return (ifa); 1027 continue; 1028 } 1029 cp = addr->sa_data; 1030 cp2 = ifa->ifa_addr->sa_data; 1031 cp3 = ifa->ifa_netmask->sa_data; 1032 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 1033 for (; cp3 < cplim; cp3++) 1034 if ((*cp++ ^ *cp2++) & *cp3) 1035 break; 1036 if (cp3 == cplim) 1037 return (ifa); 1038 } 1039 return (ifa_maybe); 1040 } 1041 1042 /* 1043 * Default action when installing a route with a Link Level gateway. 1044 * Lookup an appropriate real ifa to point to. 1045 * This should be moved to /sys/net/link.c eventually. 1046 */ 1047 void 1048 link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) 1049 { 1050 struct ifaddr *ifa; 1051 struct sockaddr *dst; 1052 struct ifnet *ifp; 1053 1054 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 1055 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 1056 return; 1057 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { 1058 ifa->ifa_refcnt++; 1059 IFAFREE(rt->rt_ifa); 1060 rt->rt_ifa = ifa; 1061 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 1062 ifa->ifa_rtrequest(cmd, rt, info); 1063 } 1064 } 1065 1066 /* 1067 * Bring down all interfaces 1068 */ 1069 void 1070 if_downall(void) 1071 { 1072 struct ifreq ifrq; /* XXX only partly built */ 1073 struct ifnet *ifp; 1074 int s; 1075 1076 s = splnet(); 1077 for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { 1078 if ((ifp->if_flags & IFF_UP) == 0) 1079 continue; 1080 if_down(ifp); 1081 ifp->if_flags &= ~IFF_UP; 1082 1083 if (ifp->if_ioctl) { 1084 ifrq.ifr_flags = ifp->if_flags; 1085 (void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, 1086 (caddr_t)&ifrq); 1087 } 1088 } 1089 splx(s); 1090 } 1091 1092 /* 1093 * Mark an interface down and notify protocols of 1094 * the transition. 1095 * NOTE: must be called at splsoftnet or equivalent. 1096 */ 1097 void 1098 if_down(struct ifnet *ifp) 1099 { 1100 struct ifaddr *ifa; 1101 1102 splsoftassert(IPL_SOFTNET); 1103 1104 ifp->if_flags &= ~IFF_UP; 1105 microtime(&ifp->if_lastchange); 1106 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1107 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 1108 } 1109 IFQ_PURGE(&ifp->if_snd); 1110 #if NCARP > 0 1111 if (ifp->if_carp) 1112 carp_carpdev_state(ifp); 1113 #endif 1114 #if NBRIDGE > 0 1115 if (ifp->if_bridge) 1116 bstp_ifstate(ifp); 1117 #endif 1118 rt_ifmsg(ifp); 1119 #ifndef SMALL_KERNEL 1120 rt_if_track(ifp); 1121 #endif 1122 } 1123 1124 /* 1125 * Mark an interface up and notify protocols of 1126 * the transition. 1127 * NOTE: must be called at splsoftnet or equivalent. 1128 */ 1129 void 1130 if_up(struct ifnet *ifp) 1131 { 1132 #ifdef notyet 1133 struct ifaddr *ifa; 1134 #endif 1135 1136 splsoftassert(IPL_SOFTNET); 1137 1138 ifp->if_flags |= IFF_UP; 1139 microtime(&ifp->if_lastchange); 1140 #ifdef notyet 1141 /* this has no effect on IP, and will kill all ISO connections XXX */ 1142 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1143 pfctlinput(PRC_IFUP, ifa->ifa_addr); 1144 } 1145 #endif 1146 #if NCARP > 0 1147 if (ifp->if_carp) 1148 carp_carpdev_state(ifp); 1149 #endif 1150 #if NBRIDGE > 0 1151 if (ifp->if_bridge) 1152 bstp_ifstate(ifp); 1153 #endif 1154 rt_ifmsg(ifp); 1155 #ifdef INET6 1156 if (!(ifp->if_xflags & IFXF_NOINET6)) 1157 in6_if_up(ifp); 1158 #endif 1159 1160 #ifndef SMALL_KERNEL 1161 rt_if_track(ifp); 1162 #endif 1163 1164 m_clinitifp(ifp); 1165 } 1166 1167 /* 1168 * Process a link state change. 1169 * NOTE: must be called at splsoftnet or equivalent. 1170 */ 1171 void 1172 if_link_state_change(struct ifnet *ifp) 1173 { 1174 rt_ifmsg(ifp); 1175 #ifndef SMALL_KERNEL 1176 rt_if_track(ifp); 1177 #endif 1178 dohooks(ifp->if_linkstatehooks, 0); 1179 } 1180 1181 /* 1182 * Flush an interface queue. 1183 */ 1184 void 1185 if_qflush(struct ifqueue *ifq) 1186 { 1187 struct mbuf *m, *n; 1188 1189 n = ifq->ifq_head; 1190 while ((m = n) != NULL) { 1191 n = m->m_act; 1192 m_freem(m); 1193 } 1194 ifq->ifq_head = 0; 1195 ifq->ifq_tail = 0; 1196 ifq->ifq_len = 0; 1197 } 1198 1199 /* 1200 * Handle interface watchdog timer routines. Called 1201 * from softclock, we decrement timers (if set) and 1202 * call the appropriate interface routine on expiration. 1203 */ 1204 void 1205 if_slowtimo(void *arg) 1206 { 1207 struct timeout *to = (struct timeout *)arg; 1208 struct ifnet *ifp; 1209 int s = splnet(); 1210 1211 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1212 if (ifp->if_timer == 0 || --ifp->if_timer) 1213 continue; 1214 if (ifp->if_watchdog) 1215 (*ifp->if_watchdog)(ifp); 1216 } 1217 splx(s); 1218 timeout_add(to, hz / IFNET_SLOWHZ); 1219 } 1220 1221 /* 1222 * Map interface name to 1223 * interface structure pointer. 1224 */ 1225 struct ifnet * 1226 ifunit(const char *name) 1227 { 1228 struct ifnet *ifp; 1229 1230 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1231 if (strcmp(ifp->if_xname, name) == 0) 1232 return (ifp); 1233 } 1234 return (NULL); 1235 } 1236 1237 /* 1238 * Interface ioctls. 1239 */ 1240 int 1241 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) 1242 { 1243 struct ifnet *ifp; 1244 struct ifreq *ifr; 1245 struct ifaddr *ifa, *nifa; 1246 struct sockaddr_dl *sdl; 1247 struct ifgroupreq *ifgr; 1248 char ifdescrbuf[IFDESCRSIZE]; 1249 char ifrtlabelbuf[RTLABEL_LEN]; 1250 int error = 0; 1251 size_t bytesdone; 1252 short oif_flags; 1253 const char *label; 1254 1255 switch (cmd) { 1256 1257 case SIOCGIFCONF: 1258 case OSIOCGIFCONF: 1259 return (ifconf(cmd, data)); 1260 } 1261 ifr = (struct ifreq *)data; 1262 1263 switch (cmd) { 1264 case SIOCIFCREATE: 1265 case SIOCIFDESTROY: 1266 if ((error = suser(p, 0)) != 0) 1267 return (error); 1268 return ((cmd == SIOCIFCREATE) ? 1269 if_clone_create(ifr->ifr_name) : 1270 if_clone_destroy(ifr->ifr_name)); 1271 case SIOCIFGCLONERS: 1272 return (if_clone_list((struct if_clonereq *)data)); 1273 case SIOCGIFGMEMB: 1274 return (if_getgroupmembers(data)); 1275 case SIOCGIFGATTR: 1276 return (if_getgroupattribs(data)); 1277 case SIOCSIFGATTR: 1278 if ((error = suser(p, 0)) != 0) 1279 return (error); 1280 return (if_setgroupattribs(data)); 1281 } 1282 1283 ifp = ifunit(ifr->ifr_name); 1284 if (ifp == 0) 1285 return (ENXIO); 1286 oif_flags = ifp->if_flags; 1287 switch (cmd) { 1288 1289 case SIOCGIFFLAGS: 1290 ifr->ifr_flags = ifp->if_flags; 1291 break; 1292 1293 case SIOCGIFXFLAGS: 1294 ifr->ifr_flags = ifp->if_xflags; 1295 break; 1296 1297 case SIOCGIFMETRIC: 1298 ifr->ifr_metric = ifp->if_metric; 1299 break; 1300 1301 case SIOCGIFMTU: 1302 ifr->ifr_mtu = ifp->if_mtu; 1303 break; 1304 1305 case SIOCGIFDATA: 1306 error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data, 1307 sizeof(ifp->if_data)); 1308 break; 1309 1310 case SIOCSIFFLAGS: 1311 if ((error = suser(p, 0)) != 0) 1312 return (error); 1313 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 1314 int s = splnet(); 1315 if_down(ifp); 1316 splx(s); 1317 } 1318 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 1319 int s = splnet(); 1320 if_up(ifp); 1321 splx(s); 1322 } 1323 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 1324 (ifr->ifr_flags &~ IFF_CANTCHANGE); 1325 if (ifp->if_ioctl) 1326 (void) (*ifp->if_ioctl)(ifp, cmd, data); 1327 break; 1328 1329 case SIOCSIFXFLAGS: 1330 if ((error = suser(p, 0)) != 0) 1331 return (error); 1332 1333 #ifdef INET6 1334 /* when IFXF_NOINET6 gets changed, detach/attach */ 1335 if (ifp->if_flags & IFF_UP && ifr->ifr_flags & IFXF_NOINET6 && 1336 !(ifp->if_xflags & IFXF_NOINET6)) 1337 in6_ifdetach(ifp); 1338 if (ifp->if_flags & IFF_UP && ifp->if_xflags & IFXF_NOINET6 && 1339 !(ifr->ifr_flags & IFXF_NOINET6)) { 1340 ifp->if_xflags &= ~IFXF_NOINET6; 1341 in6_if_up(ifp); 1342 } 1343 #endif 1344 1345 ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) | 1346 (ifr->ifr_flags &~ IFXF_CANTCHANGE); 1347 rt_ifmsg(ifp); 1348 break; 1349 1350 case SIOCSIFMETRIC: 1351 if ((error = suser(p, 0)) != 0) 1352 return (error); 1353 ifp->if_metric = ifr->ifr_metric; 1354 break; 1355 1356 case SIOCSIFMTU: 1357 { 1358 #ifdef INET6 1359 int oldmtu = ifp->if_mtu; 1360 #endif 1361 1362 if ((error = suser(p, 0)) != 0) 1363 return (error); 1364 if (ifp->if_ioctl == NULL) 1365 return (EOPNOTSUPP); 1366 error = (*ifp->if_ioctl)(ifp, cmd, data); 1367 1368 /* 1369 * If the link MTU changed, do network layer specific procedure. 1370 */ 1371 #ifdef INET6 1372 if (ifp->if_mtu != oldmtu) 1373 nd6_setmtu(ifp); 1374 #endif 1375 break; 1376 } 1377 1378 case SIOCSIFPHYADDR: 1379 case SIOCDIFPHYADDR: 1380 #ifdef INET6 1381 case SIOCSIFPHYADDR_IN6: 1382 #endif 1383 case SIOCSLIFPHYADDR: 1384 case SIOCADDMULTI: 1385 case SIOCDELMULTI: 1386 case SIOCSIFMEDIA: 1387 if ((error = suser(p, 0)) != 0) 1388 return (error); 1389 /* FALLTHROUGH */ 1390 case SIOCGIFPSRCADDR: 1391 case SIOCGIFPDSTADDR: 1392 case SIOCGLIFPHYADDR: 1393 case SIOCGIFMEDIA: 1394 if (ifp->if_ioctl == 0) 1395 return (EOPNOTSUPP); 1396 error = (*ifp->if_ioctl)(ifp, cmd, data); 1397 break; 1398 1399 case SIOCGIFDESCR: 1400 strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE); 1401 error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE, 1402 &bytesdone); 1403 break; 1404 1405 case SIOCSIFDESCR: 1406 if ((error = suser(p, 0)) != 0) 1407 return (error); 1408 error = copyinstr(ifr->ifr_data, ifdescrbuf, 1409 IFDESCRSIZE, &bytesdone); 1410 if (error == 0) { 1411 (void)memset(ifp->if_description, 0, IFDESCRSIZE); 1412 strlcpy(ifp->if_description, ifdescrbuf, IFDESCRSIZE); 1413 } 1414 break; 1415 1416 case SIOCGIFRTLABEL: 1417 if (ifp->if_rtlabelid && 1418 (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) { 1419 strlcpy(ifrtlabelbuf, label, RTLABEL_LEN); 1420 error = copyoutstr(ifrtlabelbuf, ifr->ifr_data, 1421 RTLABEL_LEN, &bytesdone); 1422 } else 1423 error = ENOENT; 1424 break; 1425 1426 case SIOCSIFRTLABEL: 1427 if ((error = suser(p, 0)) != 0) 1428 return (error); 1429 error = copyinstr(ifr->ifr_data, ifrtlabelbuf, 1430 RTLABEL_LEN, &bytesdone); 1431 if (error == 0) { 1432 rtlabel_unref(ifp->if_rtlabelid); 1433 ifp->if_rtlabelid = rtlabel_name2id(ifrtlabelbuf); 1434 } 1435 break; 1436 1437 case SIOCGIFPRIORITY: 1438 ifr->ifr_metric = ifp->if_priority; 1439 break; 1440 1441 case SIOCSIFPRIORITY: 1442 if ((error = suser(p, 0)) != 0) 1443 return (error); 1444 if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15) 1445 return (EINVAL); 1446 ifp->if_priority = ifr->ifr_metric; 1447 break; 1448 1449 case SIOCGIFRTABLEID: 1450 ifr->ifr_rdomainid = ifp->if_rdomain; 1451 break; 1452 1453 case SIOCSIFRTABLEID: 1454 if ((error = suser(p, 0)) != 0) 1455 return (error); 1456 if (ifr->ifr_rdomainid < 0 || 1457 ifr->ifr_rdomainid > RT_TABLEID_MAX) 1458 return (EINVAL); 1459 /* remove all routing entries when switching domains */ 1460 /* XXX hell this is ugly */ 1461 if (ifr->ifr_rdomainid != ifp->if_rdomain) { 1462 rt_if_remove(ifp); 1463 #ifdef INET 1464 rti_delete(ifp); 1465 #if NETHER > 0 1466 myip_ifp = NULL; 1467 #endif 1468 #ifdef MROUTING 1469 vif_delete(ifp); 1470 #endif 1471 #endif 1472 #ifdef INET6 1473 in6_ifdetach(ifp); 1474 #endif 1475 #ifdef INET 1476 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1477 ifa = nifa) { 1478 nifa = TAILQ_NEXT(ifa, ifa_list); 1479 1480 /* only remove AF_INET */ 1481 if (ifa->ifa_addr->sa_family != AF_INET) 1482 continue; 1483 1484 TAILQ_REMOVE(&in_ifaddr, 1485 (struct in_ifaddr *)ifa, ia_list); 1486 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 1487 ifa->ifa_ifp = NULL; 1488 IFAFREE(ifa); 1489 } 1490 #endif 1491 } 1492 1493 /* make sure that the routing table exists */ 1494 if (!rtable_exists(ifr->ifr_rdomainid)) { 1495 if (rtable_add(ifr->ifr_rdomainid) == -1) 1496 panic("rtinit: rtable_add"); 1497 } 1498 if (ifr->ifr_rdomainid != rtable_l2(ifr->ifr_rdomainid)) { 1499 /* XXX we should probably flush the table */ 1500 rtable_l2set(ifr->ifr_rdomainid, ifr->ifr_rdomainid); 1501 } 1502 1503 ifp->if_rdomain = ifr->ifr_rdomainid; 1504 break; 1505 1506 case SIOCAIFGROUP: 1507 if ((error = suser(p, 0))) 1508 return (error); 1509 (*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */ 1510 ifgr = (struct ifgroupreq *)data; 1511 if ((error = if_addgroup(ifp, ifgr->ifgr_group))) 1512 return (error); 1513 break; 1514 1515 case SIOCGIFGROUP: 1516 if ((error = if_getgroup(data, ifp))) 1517 return (error); 1518 break; 1519 1520 case SIOCDIFGROUP: 1521 if ((error = suser(p, 0))) 1522 return (error); 1523 (*ifp->if_ioctl)(ifp, cmd, data); /* XXX error check */ 1524 ifgr = (struct ifgroupreq *)data; 1525 if ((error = if_delgroup(ifp, ifgr->ifgr_group))) 1526 return (error); 1527 break; 1528 1529 case SIOCSIFLLADDR: 1530 if ((error = suser(p, 0))) 1531 return (error); 1532 ifa = ifnet_addrs[ifp->if_index]; 1533 if (ifa == NULL) 1534 return (EINVAL); 1535 sdl = (struct sockaddr_dl *)ifa->ifa_addr; 1536 if (sdl == NULL) 1537 return (EINVAL); 1538 if (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) 1539 return (EINVAL); 1540 if (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data)) 1541 return (EINVAL); 1542 switch (ifp->if_type) { 1543 case IFT_ETHER: 1544 case IFT_CARP: 1545 case IFT_FDDI: 1546 case IFT_XETHER: 1547 case IFT_ISO88025: 1548 case IFT_L2VLAN: 1549 bcopy((caddr_t)ifr->ifr_addr.sa_data, 1550 (caddr_t)((struct arpcom *)ifp)->ac_enaddr, 1551 ETHER_ADDR_LEN); 1552 bcopy((caddr_t)ifr->ifr_addr.sa_data, 1553 LLADDR(sdl), ETHER_ADDR_LEN); 1554 break; 1555 default: 1556 return (ENODEV); 1557 } 1558 if (ifp->if_flags & IFF_UP) { 1559 struct ifreq ifrq; 1560 int s = splnet(); 1561 ifp->if_flags &= ~IFF_UP; 1562 ifrq.ifr_flags = ifp->if_flags; 1563 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); 1564 ifp->if_flags |= IFF_UP; 1565 ifrq.ifr_flags = ifp->if_flags; 1566 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq); 1567 splx(s); 1568 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 1569 if (ifa->ifa_addr != NULL && 1570 ifa->ifa_addr->sa_family == AF_INET) 1571 arp_ifinit((struct arpcom *)ifp, ifa); 1572 } 1573 } 1574 break; 1575 1576 default: 1577 if (so->so_proto == 0) 1578 return (EOPNOTSUPP); 1579 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4) 1580 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1581 (struct mbuf *) cmd, (struct mbuf *) data, 1582 (struct mbuf *) ifp, p)); 1583 #else 1584 { 1585 u_long ocmd = cmd; 1586 1587 switch (cmd) { 1588 1589 case SIOCSIFADDR: 1590 case SIOCSIFDSTADDR: 1591 case SIOCSIFBRDADDR: 1592 case SIOCSIFNETMASK: 1593 #if BYTE_ORDER != BIG_ENDIAN 1594 if (ifr->ifr_addr.sa_family == 0 && 1595 ifr->ifr_addr.sa_len < 16) { 1596 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 1597 ifr->ifr_addr.sa_len = 16; 1598 } 1599 #else 1600 if (ifr->ifr_addr.sa_len == 0) 1601 ifr->ifr_addr.sa_len = 16; 1602 #endif 1603 break; 1604 1605 case OSIOCGIFADDR: 1606 cmd = SIOCGIFADDR; 1607 break; 1608 1609 case OSIOCGIFDSTADDR: 1610 cmd = SIOCGIFDSTADDR; 1611 break; 1612 1613 case OSIOCGIFBRDADDR: 1614 cmd = SIOCGIFBRDADDR; 1615 break; 1616 1617 case OSIOCGIFNETMASK: 1618 cmd = SIOCGIFNETMASK; 1619 } 1620 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1621 (struct mbuf *) cmd, (struct mbuf *) data, 1622 (struct mbuf *) ifp, p)); 1623 switch (ocmd) { 1624 1625 case OSIOCGIFADDR: 1626 case OSIOCGIFDSTADDR: 1627 case OSIOCGIFBRDADDR: 1628 case OSIOCGIFNETMASK: 1629 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 1630 } 1631 1632 } 1633 #endif 1634 break; 1635 } 1636 1637 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) { 1638 microtime(&ifp->if_lastchange); 1639 #ifdef INET6 1640 if (!(ifp->if_xflags & IFXF_NOINET6) && 1641 (ifp->if_flags & IFF_UP) != 0) { 1642 int s = splnet(); 1643 in6_if_up(ifp); 1644 splx(s); 1645 } 1646 #endif 1647 } 1648 return (error); 1649 } 1650 1651 /* 1652 * Return interface configuration 1653 * of system. List may be used 1654 * in later ioctl's (above) to get 1655 * other information. 1656 */ 1657 /*ARGSUSED*/ 1658 int 1659 ifconf(u_long cmd, caddr_t data) 1660 { 1661 struct ifconf *ifc = (struct ifconf *)data; 1662 struct ifnet *ifp; 1663 struct ifaddr *ifa; 1664 struct ifreq ifr, *ifrp; 1665 int space = ifc->ifc_len, error = 0; 1666 1667 /* If ifc->ifc_len is 0, fill it in with the needed size and return. */ 1668 if (space == 0) { 1669 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1670 struct sockaddr *sa; 1671 1672 if (TAILQ_EMPTY(&ifp->if_addrlist)) 1673 space += sizeof (ifr); 1674 else 1675 TAILQ_FOREACH(ifa, 1676 &ifp->if_addrlist, ifa_list) { 1677 sa = ifa->ifa_addr; 1678 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1679 if (cmd != OSIOCGIFCONF) 1680 #endif 1681 if (sa->sa_len > sizeof(*sa)) 1682 space += sa->sa_len - 1683 sizeof(*sa); 1684 space += sizeof(ifr); 1685 } 1686 } 1687 ifc->ifc_len = space; 1688 return (0); 1689 } 1690 1691 ifrp = ifc->ifc_req; 1692 for (ifp = TAILQ_FIRST(&ifnet); space >= sizeof(ifr) && 1693 ifp != TAILQ_END(&ifnet); ifp = TAILQ_NEXT(ifp, if_list)) { 1694 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ); 1695 if (TAILQ_EMPTY(&ifp->if_addrlist)) { 1696 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 1697 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1698 sizeof(ifr)); 1699 if (error) 1700 break; 1701 space -= sizeof (ifr), ifrp++; 1702 } else 1703 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); 1704 space >= sizeof (ifr) && 1705 ifa != TAILQ_END(&ifp->if_addrlist); 1706 ifa = TAILQ_NEXT(ifa, ifa_list)) { 1707 struct sockaddr *sa = ifa->ifa_addr; 1708 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1709 if (cmd == OSIOCGIFCONF) { 1710 struct osockaddr *osa = 1711 (struct osockaddr *)&ifr.ifr_addr; 1712 ifr.ifr_addr = *sa; 1713 osa->sa_family = sa->sa_family; 1714 error = copyout((caddr_t)&ifr, 1715 (caddr_t)ifrp, sizeof (ifr)); 1716 ifrp++; 1717 } else 1718 #endif 1719 if (sa->sa_len <= sizeof(*sa)) { 1720 ifr.ifr_addr = *sa; 1721 error = copyout((caddr_t)&ifr, 1722 (caddr_t)ifrp, sizeof (ifr)); 1723 ifrp++; 1724 } else { 1725 space -= sa->sa_len - sizeof(*sa); 1726 if (space < sizeof (ifr)) 1727 break; 1728 error = copyout((caddr_t)&ifr, 1729 (caddr_t)ifrp, 1730 sizeof(ifr.ifr_name)); 1731 if (error == 0) 1732 error = copyout((caddr_t)sa, 1733 (caddr_t)&ifrp->ifr_addr, 1734 sa->sa_len); 1735 ifrp = (struct ifreq *)(sa->sa_len + 1736 (caddr_t)&ifrp->ifr_addr); 1737 } 1738 if (error) 1739 break; 1740 space -= sizeof (ifr); 1741 } 1742 } 1743 ifc->ifc_len -= space; 1744 return (error); 1745 } 1746 1747 /* 1748 * Dummy functions replaced in ifnet during detach (if protocols decide to 1749 * fiddle with the if during detach. 1750 */ 1751 void 1752 if_detached_start(struct ifnet *ifp) 1753 { 1754 struct mbuf *m; 1755 1756 while (1) { 1757 IF_DEQUEUE(&ifp->if_snd, m); 1758 1759 if (m == NULL) 1760 return; 1761 m_freem(m); 1762 } 1763 } 1764 1765 int 1766 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b) 1767 { 1768 return ENODEV; 1769 } 1770 1771 int 1772 if_detached_init(struct ifnet *ifp) 1773 { 1774 return (ENXIO); 1775 } 1776 1777 void 1778 if_detached_watchdog(struct ifnet *ifp) 1779 { 1780 /* nothing */ 1781 } 1782 1783 /* 1784 * Create interface group without members 1785 */ 1786 struct ifg_group * 1787 if_creategroup(const char *groupname) 1788 { 1789 struct ifg_group *ifg; 1790 1791 if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL) 1792 return (NULL); 1793 1794 strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group)); 1795 ifg->ifg_refcnt = 0; 1796 ifg->ifg_carp_demoted = 0; 1797 TAILQ_INIT(&ifg->ifg_members); 1798 #if NPF > 0 1799 pfi_attach_ifgroup(ifg); 1800 #endif 1801 TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next); 1802 1803 return (ifg); 1804 } 1805 1806 /* 1807 * Add a group to an interface 1808 */ 1809 int 1810 if_addgroup(struct ifnet *ifp, const char *groupname) 1811 { 1812 struct ifg_list *ifgl; 1813 struct ifg_group *ifg = NULL; 1814 struct ifg_member *ifgm; 1815 1816 if (groupname[0] && groupname[strlen(groupname) - 1] >= '0' && 1817 groupname[strlen(groupname) - 1] <= '9') 1818 return (EINVAL); 1819 1820 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 1821 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) 1822 return (EEXIST); 1823 1824 if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL) 1825 return (ENOMEM); 1826 1827 if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) { 1828 free(ifgl, M_TEMP); 1829 return (ENOMEM); 1830 } 1831 1832 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1833 if (!strcmp(ifg->ifg_group, groupname)) 1834 break; 1835 1836 if (ifg == NULL && (ifg = if_creategroup(groupname)) == NULL) { 1837 free(ifgl, M_TEMP); 1838 free(ifgm, M_TEMP); 1839 return (ENOMEM); 1840 } 1841 1842 ifg->ifg_refcnt++; 1843 ifgl->ifgl_group = ifg; 1844 ifgm->ifgm_ifp = ifp; 1845 1846 TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next); 1847 TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next); 1848 1849 #if NPF > 0 1850 pfi_group_change(groupname); 1851 #endif 1852 1853 return (0); 1854 } 1855 1856 /* 1857 * Remove a group from an interface 1858 */ 1859 int 1860 if_delgroup(struct ifnet *ifp, const char *groupname) 1861 { 1862 struct ifg_list *ifgl; 1863 struct ifg_member *ifgm; 1864 1865 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 1866 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname)) 1867 break; 1868 if (ifgl == NULL) 1869 return (ENOENT); 1870 1871 TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next); 1872 1873 TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next) 1874 if (ifgm->ifgm_ifp == ifp) 1875 break; 1876 1877 if (ifgm != NULL) { 1878 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next); 1879 free(ifgm, M_TEMP); 1880 } 1881 1882 if (--ifgl->ifgl_group->ifg_refcnt == 0) { 1883 TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next); 1884 #if NPF > 0 1885 pfi_detach_ifgroup(ifgl->ifgl_group); 1886 #endif 1887 free(ifgl->ifgl_group, M_TEMP); 1888 } 1889 1890 free(ifgl, M_TEMP); 1891 1892 #if NPF > 0 1893 pfi_group_change(groupname); 1894 #endif 1895 1896 return (0); 1897 } 1898 1899 /* 1900 * Stores all groups from an interface in memory pointed 1901 * to by data 1902 */ 1903 int 1904 if_getgroup(caddr_t data, struct ifnet *ifp) 1905 { 1906 int len, error; 1907 struct ifg_list *ifgl; 1908 struct ifg_req ifgrq, *ifgp; 1909 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1910 1911 if (ifgr->ifgr_len == 0) { 1912 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) 1913 ifgr->ifgr_len += sizeof(struct ifg_req); 1914 return (0); 1915 } 1916 1917 len = ifgr->ifgr_len; 1918 ifgp = ifgr->ifgr_groups; 1919 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { 1920 if (len < sizeof(ifgrq)) 1921 return (EINVAL); 1922 bzero(&ifgrq, sizeof ifgrq); 1923 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group, 1924 sizeof(ifgrq.ifgrq_group)); 1925 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, 1926 sizeof(struct ifg_req)))) 1927 return (error); 1928 len -= sizeof(ifgrq); 1929 ifgp++; 1930 } 1931 1932 return (0); 1933 } 1934 1935 /* 1936 * Stores all members of a group in memory pointed to by data 1937 */ 1938 int 1939 if_getgroupmembers(caddr_t data) 1940 { 1941 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1942 struct ifg_group *ifg; 1943 struct ifg_member *ifgm; 1944 struct ifg_req ifgrq, *ifgp; 1945 int len, error; 1946 1947 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1948 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 1949 break; 1950 if (ifg == NULL) 1951 return (ENOENT); 1952 1953 if (ifgr->ifgr_len == 0) { 1954 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) 1955 ifgr->ifgr_len += sizeof(ifgrq); 1956 return (0); 1957 } 1958 1959 len = ifgr->ifgr_len; 1960 ifgp = ifgr->ifgr_groups; 1961 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) { 1962 if (len < sizeof(ifgrq)) 1963 return (EINVAL); 1964 bzero(&ifgrq, sizeof ifgrq); 1965 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname, 1966 sizeof(ifgrq.ifgrq_member)); 1967 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp, 1968 sizeof(struct ifg_req)))) 1969 return (error); 1970 len -= sizeof(ifgrq); 1971 ifgp++; 1972 } 1973 1974 return (0); 1975 } 1976 1977 int 1978 if_getgroupattribs(caddr_t data) 1979 { 1980 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1981 struct ifg_group *ifg; 1982 1983 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 1984 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 1985 break; 1986 if (ifg == NULL) 1987 return (ENOENT); 1988 1989 ifgr->ifgr_attrib.ifg_carp_demoted = ifg->ifg_carp_demoted; 1990 1991 return (0); 1992 } 1993 1994 int 1995 if_setgroupattribs(caddr_t data) 1996 { 1997 struct ifgroupreq *ifgr = (struct ifgroupreq *)data; 1998 struct ifg_group *ifg; 1999 struct ifg_member *ifgm; 2000 int demote; 2001 2002 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 2003 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name)) 2004 break; 2005 if (ifg == NULL) 2006 return (ENOENT); 2007 2008 demote = ifgr->ifgr_attrib.ifg_carp_demoted; 2009 if (demote + ifg->ifg_carp_demoted > 0xff || 2010 demote + ifg->ifg_carp_demoted < 0) 2011 return (ERANGE); 2012 2013 ifg->ifg_carp_demoted += demote; 2014 2015 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) 2016 if (ifgm->ifgm_ifp->if_ioctl) 2017 ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, 2018 SIOCSIFGATTR, data); 2019 return (0); 2020 } 2021 2022 void 2023 if_group_routechange(struct sockaddr *dst, struct sockaddr *mask) 2024 { 2025 switch (dst->sa_family) { 2026 case AF_INET: 2027 if (satosin(dst)->sin_addr.s_addr == INADDR_ANY && 2028 mask && (mask->sa_len == 0 || 2029 satosin(mask)->sin_addr.s_addr == INADDR_ANY)) 2030 if_group_egress_build(); 2031 break; 2032 #ifdef INET6 2033 case AF_INET6: 2034 if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr, 2035 &in6addr_any) && mask && (mask->sa_len == 0 || 2036 IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr, 2037 &in6addr_any))) 2038 if_group_egress_build(); 2039 break; 2040 #endif 2041 } 2042 } 2043 2044 int 2045 if_group_egress_build(void) 2046 { 2047 struct ifg_group *ifg; 2048 struct ifg_member *ifgm, *next; 2049 struct sockaddr_in sa_in; 2050 #ifdef INET6 2051 struct sockaddr_in6 sa_in6; 2052 #endif 2053 struct radix_node *rn; 2054 struct rtentry *rt; 2055 2056 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) 2057 if (!strcmp(ifg->ifg_group, IFG_EGRESS)) 2058 break; 2059 2060 if (ifg != NULL) 2061 for (ifgm = TAILQ_FIRST(&ifg->ifg_members); ifgm; ifgm = next) { 2062 next = TAILQ_NEXT(ifgm, ifgm_next); 2063 if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS); 2064 } 2065 2066 bzero(&sa_in, sizeof(sa_in)); 2067 sa_in.sin_len = sizeof(sa_in); 2068 sa_in.sin_family = AF_INET; 2069 if ((rn = rt_lookup(sintosa(&sa_in), sintosa(&sa_in), 0)) != NULL) { 2070 do { 2071 rt = (struct rtentry *)rn; 2072 if (rt->rt_ifp) 2073 if_addgroup(rt->rt_ifp, IFG_EGRESS); 2074 #ifndef SMALL_KERNEL 2075 rn = rn_mpath_next(rn, 0); 2076 #else 2077 rn = NULL; 2078 #endif 2079 } while (rn != NULL); 2080 } 2081 2082 #ifdef INET6 2083 bcopy(&sa6_any, &sa_in6, sizeof(sa_in6)); 2084 if ((rn = rt_lookup(sin6tosa(&sa_in6), sin6tosa(&sa_in6), 0)) != NULL) { 2085 do { 2086 rt = (struct rtentry *)rn; 2087 if (rt->rt_ifp) 2088 if_addgroup(rt->rt_ifp, IFG_EGRESS); 2089 #ifndef SMALL_KERNEL 2090 rn = rn_mpath_next(rn, 0); 2091 #else 2092 rn = NULL; 2093 #endif 2094 } while (rn != NULL); 2095 } 2096 #endif 2097 2098 return (0); 2099 } 2100 2101 /* 2102 * Set/clear promiscuous mode on interface ifp based on the truth value 2103 * of pswitch. The calls are reference counted so that only the first 2104 * "on" request actually has an effect, as does the final "off" request. 2105 * Results are undefined if the "off" and "on" requests are not matched. 2106 */ 2107 int 2108 ifpromisc(struct ifnet *ifp, int pswitch) 2109 { 2110 struct ifreq ifr; 2111 2112 if (pswitch) { 2113 /* 2114 * If the device is not configured up, we cannot put it in 2115 * promiscuous mode. 2116 */ 2117 if ((ifp->if_flags & IFF_UP) == 0) 2118 return (ENETDOWN); 2119 if (ifp->if_pcount++ != 0) 2120 return (0); 2121 ifp->if_flags |= IFF_PROMISC; 2122 } else { 2123 if (--ifp->if_pcount > 0) 2124 return (0); 2125 ifp->if_flags &= ~IFF_PROMISC; 2126 /* 2127 * If the device is not configured up, we should not need to 2128 * turn off promiscuous mode (device should have turned it 2129 * off when interface went down; and will look at IFF_PROMISC 2130 * again next time interface comes up). 2131 */ 2132 if ((ifp->if_flags & IFF_UP) == 0) 2133 return (0); 2134 } 2135 ifr.ifr_flags = ifp->if_flags; 2136 return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); 2137 } 2138 2139 int 2140 sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp, 2141 void *newp, size_t newlen, struct ifqueue *ifq) 2142 { 2143 /* All sysctl names at this level are terminal. */ 2144 if (namelen != 1) 2145 return (ENOTDIR); 2146 2147 switch (name[0]) { 2148 case IFQCTL_LEN: 2149 return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_len)); 2150 case IFQCTL_MAXLEN: 2151 return (sysctl_int(oldp, oldlenp, newp, newlen, 2152 &ifq->ifq_maxlen)); 2153 case IFQCTL_DROPS: 2154 return (sysctl_rdint(oldp, oldlenp, newp, ifq->ifq_drops)); 2155 default: 2156 return (EOPNOTSUPP); 2157 } 2158 /* NOTREACHED */ 2159 } 2160