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