1 /* $NetBSD: if.c,v 1.99 2001/11/12 23:49:34 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by William Studnemund and Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. Neither the name of the project nor the names of its contributors 52 * may be used to endorse or promote products derived from this software 53 * without specific prior written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 */ 67 68 /* 69 * Copyright (c) 1980, 1986, 1993 70 * The Regents of the University of California. All rights reserved. 71 * 72 * Redistribution and use in source and binary forms, with or without 73 * modification, are permitted provided that the following conditions 74 * are met: 75 * 1. Redistributions of source code must retain the above copyright 76 * notice, this list of conditions and the following disclaimer. 77 * 2. Redistributions in binary form must reproduce the above copyright 78 * notice, this list of conditions and the following disclaimer in the 79 * documentation and/or other materials provided with the distribution. 80 * 3. All advertising materials mentioning features or use of this software 81 * must display the following acknowledgement: 82 * This product includes software developed by the University of 83 * California, Berkeley and its contributors. 84 * 4. Neither the name of the University nor the names of its contributors 85 * may be used to endorse or promote products derived from this software 86 * without specific prior written permission. 87 * 88 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 89 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 91 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 94 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 98 * SUCH DAMAGE. 99 * 100 * @(#)if.c 8.5 (Berkeley) 1/9/95 101 */ 102 103 #include <sys/cdefs.h> 104 __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.99 2001/11/12 23:49:34 lukem Exp $"); 105 106 #include "opt_inet.h" 107 108 #include "opt_compat_linux.h" 109 #include "opt_compat_svr4.h" 110 #include "opt_compat_43.h" 111 #include "opt_atalk.h" 112 #include "opt_pfil_hooks.h" 113 114 #include <sys/param.h> 115 #include <sys/mbuf.h> 116 #include <sys/systm.h> 117 #include <sys/callout.h> 118 #include <sys/proc.h> 119 #include <sys/socket.h> 120 #include <sys/socketvar.h> 121 #include <sys/domain.h> 122 #include <sys/protosw.h> 123 #include <sys/kernel.h> 124 #include <sys/ioctl.h> 125 126 #include <net/if.h> 127 #include <net/if_dl.h> 128 #include <net/if_ether.h> 129 #include <net/if_ieee80211.h> 130 #include <net/if_types.h> 131 #include <net/radix.h> 132 #include <net/route.h> 133 #include <net/netisr.h> 134 #ifdef NETATALK 135 #include <netatalk/at_extern.h> 136 #include <netatalk/at.h> 137 #endif 138 139 #ifdef INET6 140 /*XXX*/ 141 #include <netinet/in.h> 142 #include <netinet6/in6_var.h> 143 #endif 144 145 int ifqmaxlen = IFQ_MAXLEN; 146 struct callout if_slowtimo_ch; 147 148 #ifdef INET6 149 /* 150 * XXX: declare here to avoid to include many inet6 related files.. 151 * should be more generalized? 152 */ 153 extern void nd6_setmtu __P((struct ifnet *)); 154 #endif 155 156 int if_rt_walktree __P((struct radix_node *, void *)); 157 158 struct if_clone *if_clone_lookup __P((const char *, int *)); 159 int if_clone_list __P((struct if_clonereq *)); 160 161 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 162 int if_cloners_count; 163 164 static void if_detach_queues __P((struct ifnet *, struct ifqueue *)); 165 166 /* 167 * Network interface utility routines. 168 * 169 * Routines with ifa_ifwith* names take sockaddr *'s as 170 * parameters. 171 */ 172 void 173 ifinit() 174 { 175 176 callout_init(&if_slowtimo_ch); 177 if_slowtimo(NULL); 178 } 179 180 /* 181 * Null routines used while an interface is going away. These routines 182 * just return an error. 183 */ 184 185 int 186 if_nulloutput(ifp, m, so, rt) 187 struct ifnet *ifp; 188 struct mbuf *m; 189 struct sockaddr *so; 190 struct rtentry *rt; 191 { 192 193 return (ENXIO); 194 } 195 196 void 197 if_nullinput(ifp, m) 198 struct ifnet *ifp; 199 struct mbuf *m; 200 { 201 202 /* Nothing. */ 203 } 204 205 void 206 if_nullstart(ifp) 207 struct ifnet *ifp; 208 { 209 210 /* Nothing. */ 211 } 212 213 int 214 if_nullioctl(ifp, cmd, data) 215 struct ifnet *ifp; 216 u_long cmd; 217 caddr_t data; 218 { 219 220 return (ENXIO); 221 } 222 223 int 224 if_nullinit(ifp) 225 struct ifnet *ifp; 226 { 227 228 return (ENXIO); 229 } 230 231 void 232 if_nullstop(ifp, disable) 233 struct ifnet *ifp; 234 int disable; 235 { 236 237 /* Nothing. */ 238 } 239 240 void 241 if_nullwatchdog(ifp) 242 struct ifnet *ifp; 243 { 244 245 /* Nothing. */ 246 } 247 248 void 249 if_nulldrain(ifp) 250 struct ifnet *ifp; 251 { 252 253 /* Nothing. */ 254 } 255 256 int if_index = 0; 257 struct ifaddr **ifnet_addrs = NULL; 258 struct ifnet **ifindex2ifnet = NULL; 259 260 /* 261 * Allocate the link level name for the specified interface. This 262 * is an attachment helper. It must be called after ifp->if_addrlen 263 * is initialized, which may not be the case when if_attach() is 264 * called. 265 */ 266 void 267 if_alloc_sadl(struct ifnet *ifp) 268 { 269 unsigned socksize, ifasize; 270 int namelen, masklen; 271 struct sockaddr_dl *sdl; 272 struct ifaddr *ifa; 273 274 /* 275 * If the interface already has a link name, release it 276 * now. This is useful for interfaces that can change 277 * link types, and thus switch link names often. 278 */ 279 if (ifp->if_sadl != NULL) 280 if_free_sadl(ifp); 281 282 namelen = strlen(ifp->if_xname); 283 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; 284 socksize = masklen + ifp->if_addrlen; 285 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) 286 if (socksize < sizeof(*sdl)) 287 socksize = sizeof(*sdl); 288 socksize = ROUNDUP(socksize); 289 ifasize = sizeof(*ifa) + 2 * socksize; 290 ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK); 291 memset((caddr_t)ifa, 0, ifasize); 292 sdl = (struct sockaddr_dl *)(ifa + 1); 293 sdl->sdl_len = socksize; 294 sdl->sdl_family = AF_LINK; 295 bcopy(ifp->if_xname, sdl->sdl_data, namelen); 296 sdl->sdl_nlen = namelen; 297 sdl->sdl_alen = ifp->if_addrlen; 298 sdl->sdl_index = ifp->if_index; 299 sdl->sdl_type = ifp->if_type; 300 ifnet_addrs[ifp->if_index] = ifa; 301 IFAREF(ifa); 302 ifa->ifa_ifp = ifp; 303 ifa->ifa_rtrequest = link_rtrequest; 304 TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list); 305 IFAREF(ifa); 306 ifa->ifa_addr = (struct sockaddr *)sdl; 307 ifp->if_sadl = sdl; 308 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); 309 ifa->ifa_netmask = (struct sockaddr *)sdl; 310 sdl->sdl_len = masklen; 311 while (namelen != 0) 312 sdl->sdl_data[--namelen] = 0xff; 313 } 314 315 /* 316 * Free the link level name for the specified interface. This is 317 * a detach helper. This is called from if_detach() or from 318 * link layer type specific detach functions. 319 */ 320 void 321 if_free_sadl(struct ifnet *ifp) 322 { 323 struct ifaddr *ifa; 324 int s; 325 326 ifa = ifnet_addrs[ifp->if_index]; 327 if (ifa == NULL) { 328 KASSERT(ifp->if_sadl == NULL); 329 return; 330 } 331 332 KASSERT(ifp->if_sadl != NULL); 333 334 s = splnet(); 335 rtinit(ifa, RTM_DELETE, 0); 336 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 337 IFAFREE(ifa); 338 339 ifp->if_sadl = NULL; 340 341 ifnet_addrs[ifp->if_index] = NULL; 342 IFAFREE(ifa); 343 splx(s); 344 } 345 346 /* 347 * Attach an interface to the 348 * list of "active" interfaces. 349 */ 350 void 351 if_attach(ifp) 352 struct ifnet *ifp; 353 { 354 static size_t if_indexlim = 8; 355 356 if (if_index == 0) 357 TAILQ_INIT(&ifnet); 358 TAILQ_INIT(&ifp->if_addrlist); 359 TAILQ_INSERT_TAIL(&ifnet, ifp, if_list); 360 ifp->if_index = ++if_index; 361 362 /* 363 * We have some arrays that should be indexed by if_index. 364 * since if_index will grow dynamically, they should grow too. 365 * struct ifadd **ifnet_addrs 366 * struct ifnet **ifindex2ifnet 367 */ 368 if (ifnet_addrs == 0 || ifindex2ifnet == 0 || 369 ifp->if_index >= if_indexlim) { 370 size_t n; 371 caddr_t q; 372 373 while (ifp->if_index >= if_indexlim) 374 if_indexlim <<= 1; 375 376 /* grow ifnet_addrs */ 377 n = if_indexlim * sizeof(struct ifaddr *); 378 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); 379 memset(q, 0, n); 380 if (ifnet_addrs) { 381 bcopy((caddr_t)ifnet_addrs, q, n/2); 382 free((caddr_t)ifnet_addrs, M_IFADDR); 383 } 384 ifnet_addrs = (struct ifaddr **)q; 385 386 /* grow ifindex2ifnet */ 387 n = if_indexlim * sizeof(struct ifnet *); 388 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); 389 memset(q, 0, n); 390 if (ifindex2ifnet) { 391 bcopy((caddr_t)ifindex2ifnet, q, n/2); 392 free((caddr_t)ifindex2ifnet, M_IFADDR); 393 } 394 ifindex2ifnet = (struct ifnet **)q; 395 } 396 397 ifindex2ifnet[ifp->if_index] = ifp; 398 399 /* 400 * Link level name is allocated later by a separate call to 401 * if_alloc_sadl(). 402 */ 403 404 if (ifp->if_snd.ifq_maxlen == 0) 405 ifp->if_snd.ifq_maxlen = ifqmaxlen; 406 ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ 407 408 ifp->if_link_state = LINK_STATE_UNKNOWN; 409 410 ifp->if_capenable = 0; 411 ifp->if_csum_flags_tx = 0; 412 ifp->if_csum_flags_rx = 0; 413 414 #ifdef ALTQ 415 ifp->if_snd.altq_type = 0; 416 ifp->if_snd.altq_disc = NULL; 417 ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE; 418 ifp->if_snd.altq_tbr = NULL; 419 ifp->if_snd.altq_ifp = ifp; 420 #endif 421 422 #ifdef PFIL_HOOKS 423 ifp->if_pfil.ph_type = PFIL_TYPE_IFNET; 424 ifp->if_pfil.ph_ifnet = ifp; 425 if (pfil_head_register(&ifp->if_pfil) != 0) 426 printf("%s: WARNING: unable to register pfil hook\n", 427 ifp->if_xname); 428 #endif 429 430 /* Announce the interface. */ 431 rt_ifannouncemsg(ifp, IFAN_ARRIVAL); 432 } 433 434 /* 435 * Deactivate an interface. This points all of the procedure 436 * handles at error stubs. May be called from interrupt context. 437 */ 438 void 439 if_deactivate(ifp) 440 struct ifnet *ifp; 441 { 442 int s; 443 444 s = splnet(); 445 446 ifp->if_output = if_nulloutput; 447 ifp->if_input = if_nullinput; 448 ifp->if_start = if_nullstart; 449 ifp->if_ioctl = if_nullioctl; 450 ifp->if_init = if_nullinit; 451 ifp->if_stop = if_nullstop; 452 ifp->if_watchdog = if_nullwatchdog; 453 ifp->if_drain = if_nulldrain; 454 455 /* No more packets may be enqueued. */ 456 ifp->if_snd.ifq_maxlen = 0; 457 458 splx(s); 459 } 460 461 /* 462 * Detach an interface from the list of "active" interfaces, 463 * freeing any resources as we go along. 464 * 465 * NOTE: This routine must be called with a valid thread context, 466 * as it may block. 467 */ 468 void 469 if_detach(ifp) 470 struct ifnet *ifp; 471 { 472 struct socket so; 473 struct ifaddr *ifa; 474 #ifdef IFAREF_DEBUG 475 struct ifaddr *last_ifa = NULL; 476 #endif 477 struct domain *dp; 478 struct protosw *pr; 479 struct radix_node_head *rnh; 480 int s, i, family, purged; 481 482 /* 483 * XXX It's kind of lame that we have to have the 484 * XXX socket structure... 485 */ 486 memset(&so, 0, sizeof(so)); 487 488 s = splnet(); 489 490 /* 491 * Do an if_down() to give protocols a chance to do something. 492 */ 493 if_down(ifp); 494 495 #ifdef ALTQ 496 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 497 altq_disable(&ifp->if_snd); 498 if (ALTQ_IS_ATTACHED(&ifp->if_snd)) 499 altq_detach(&ifp->if_snd); 500 #endif 501 502 #ifdef PFIL_HOOKS 503 (void) pfil_head_unregister(&ifp->if_pfil); 504 #endif 505 506 if_free_sadl(ifp); 507 508 /* 509 * Rip all the addresses off the interface. This should make 510 * all of the routes go away. 511 */ 512 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) { 513 family = ifa->ifa_addr->sa_family; 514 #ifdef IFAREF_DEBUG 515 printf("if_detach: ifaddr %p, family %d, refcnt %d\n", 516 ifa, family, ifa->ifa_refcnt); 517 if (last_ifa != NULL && ifa == last_ifa) 518 panic("if_detach: loop detected"); 519 last_ifa = ifa; 520 #endif 521 if (family == AF_LINK) { 522 /* 523 * XXX This case may now be obsolete by 524 * XXX the call to if_free_sadl(). 525 */ 526 rtinit(ifa, RTM_DELETE, 0); 527 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 528 IFAFREE(ifa); 529 } else { 530 dp = pffinddomain(family); 531 #ifdef DIAGNOSTIC 532 if (dp == NULL) 533 panic("if_detach: no domain for AF %d\n", 534 family); 535 #endif 536 purged = 0; 537 for (pr = dp->dom_protosw; 538 pr < dp->dom_protoswNPROTOSW; pr++) { 539 so.so_proto = pr; 540 if (pr->pr_usrreq != NULL) { 541 (void) (*pr->pr_usrreq)(&so, 542 PRU_PURGEIF, NULL, NULL, 543 (struct mbuf *) ifp, curproc); 544 purged = 1; 545 } 546 } 547 if (purged == 0) { 548 /* 549 * XXX What's really the best thing to do 550 * XXX here? --thorpej@netbsd.org 551 */ 552 printf("if_detach: WARNING: AF %d not purged\n", 553 family); 554 } 555 } 556 } 557 558 /* Walk the routing table looking for straglers. */ 559 for (i = 0; i <= AF_MAX; i++) { 560 if ((rnh = rt_tables[i]) != NULL) 561 (void) (*rnh->rnh_walktree)(rnh, if_rt_walktree, ifp); 562 } 563 564 /* Announce that the interface is gone. */ 565 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 566 567 ifindex2ifnet[ifp->if_index] = NULL; 568 569 TAILQ_REMOVE(&ifnet, ifp, if_list); 570 571 /* 572 * remove packets came from ifp, from software interrupt queues. 573 * net/netisr_dispatch.h is not usable, as some of them use 574 * strange queue names. 575 */ 576 #define IF_DETACH_QUEUES(x) \ 577 do { \ 578 extern struct ifqueue x; \ 579 if_detach_queues(ifp, & x); \ 580 } while (0) 581 #ifdef INET 582 #if NARP > 0 583 IF_DETACH_QUEUES(arpintrq); 584 #endif 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 NS 595 IF_DETACH_QUEUES(nsintrq); 596 #endif 597 #ifdef ISO 598 IF_DETACH_QUEUES(clnlintrq); 599 #endif 600 #ifdef CCITT 601 IF_DETACH_QUEUES(llcintrq); 602 IF_DETACH_QUEUES(hdintrq); 603 #endif 604 #ifdef NATM 605 IF_DETACH_QUEUES(natmintrq); 606 #endif 607 #undef IF_DETACH_QUEUES 608 609 splx(s); 610 } 611 612 static void 613 if_detach_queues(ifp, q) 614 struct ifnet *ifp; 615 struct ifqueue *q; 616 { 617 struct mbuf *m, *prev, *next; 618 619 prev = NULL; 620 for (m = q->ifq_head; m; m = next) { 621 next = m->m_nextpkt; 622 #ifdef DIAGNOSTIC 623 if ((m->m_flags & M_PKTHDR) == 0) { 624 prev = m; 625 continue; 626 } 627 #endif 628 if (m->m_pkthdr.rcvif != ifp) { 629 prev = m; 630 continue; 631 } 632 633 if (prev) 634 prev->m_nextpkt = m->m_nextpkt; 635 else 636 q->ifq_head = m->m_nextpkt; 637 if (q->ifq_tail == m) 638 q->ifq_tail = prev; 639 q->ifq_len--; 640 641 m->m_nextpkt = NULL; 642 m_freem(m); 643 IF_DROP(q); 644 } 645 } 646 647 /* 648 * Callback for a radix tree walk to delete all references to an 649 * ifnet. 650 */ 651 int 652 if_rt_walktree(rn, v) 653 struct radix_node *rn; 654 void *v; 655 { 656 struct ifnet *ifp = (struct ifnet *)v; 657 struct rtentry *rt = (struct rtentry *)rn; 658 int error; 659 660 if (rt->rt_ifp == ifp) { 661 /* Delete the entry. */ 662 error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, 663 rt_mask(rt), rt->rt_flags, NULL); 664 if (error) 665 printf("%s: warning: unable to delete rtentry @ %p, " 666 "error = %d\n", ifp->if_xname, rt, error); 667 } 668 return (0); 669 } 670 671 /* 672 * Create a clone network interface. 673 */ 674 int 675 if_clone_create(name) 676 const char *name; 677 { 678 struct if_clone *ifc; 679 int unit; 680 681 ifc = if_clone_lookup(name, &unit); 682 if (ifc == NULL) 683 return (EINVAL); 684 685 if (ifunit(name) != NULL) 686 return (EEXIST); 687 688 return ((*ifc->ifc_create)(ifc, unit)); 689 } 690 691 /* 692 * Destroy a clone network interface. 693 */ 694 int 695 if_clone_destroy(name) 696 const char *name; 697 { 698 struct if_clone *ifc; 699 struct ifnet *ifp; 700 701 ifc = if_clone_lookup(name, NULL); 702 if (ifc == NULL) 703 return (EINVAL); 704 705 ifp = ifunit(name); 706 if (ifp == NULL) 707 return (ENXIO); 708 709 if (ifc->ifc_destroy == NULL) 710 return (EOPNOTSUPP); 711 712 (*ifc->ifc_destroy)(ifp); 713 return (0); 714 } 715 716 /* 717 * Look up a network interface cloner. 718 */ 719 struct if_clone * 720 if_clone_lookup(name, unitp) 721 const char *name; 722 int *unitp; 723 { 724 struct if_clone *ifc; 725 const char *cp; 726 int i; 727 728 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) { 729 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) { 730 if (ifc->ifc_name[i] != *cp) 731 goto next_ifc; 732 } 733 goto found_name; 734 next_ifc: 735 ifc = LIST_NEXT(ifc, ifc_list); 736 } 737 738 /* No match. */ 739 return (NULL); 740 741 found_name: 742 for (i = 0; *cp != '\0'; cp++) { 743 if (*cp < '0' || *cp > '9') { 744 /* Bogus unit number. */ 745 return (NULL); 746 } 747 i = (i * 10) + (*cp - '0'); 748 } 749 750 if (unitp != NULL) 751 *unitp = i; 752 return (ifc); 753 } 754 755 /* 756 * Register a network interface cloner. 757 */ 758 void 759 if_clone_attach(ifc) 760 struct if_clone *ifc; 761 { 762 763 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 764 if_cloners_count++; 765 } 766 767 /* 768 * Unregister a network interface cloner. 769 */ 770 void 771 if_clone_detach(ifc) 772 struct if_clone *ifc; 773 { 774 775 LIST_REMOVE(ifc, ifc_list); 776 if_cloners_count--; 777 } 778 779 /* 780 * Provide list of interface cloners to userspace. 781 */ 782 int 783 if_clone_list(ifcr) 784 struct if_clonereq *ifcr; 785 { 786 char outbuf[IFNAMSIZ], *dst; 787 struct if_clone *ifc; 788 int count, error = 0; 789 790 ifcr->ifcr_total = if_cloners_count; 791 if ((dst = ifcr->ifcr_buffer) == NULL) { 792 /* Just asking how many there are. */ 793 return (0); 794 } 795 796 if (ifcr->ifcr_count < 0) 797 return (EINVAL); 798 799 count = (if_cloners_count < ifcr->ifcr_count) ? 800 if_cloners_count : ifcr->ifcr_count; 801 802 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 803 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 804 strncpy(outbuf, ifc->ifc_name, IFNAMSIZ); 805 outbuf[IFNAMSIZ - 1] = '\0'; /* sanity */ 806 error = copyout(outbuf, dst, IFNAMSIZ); 807 if (error) 808 break; 809 } 810 811 return (error); 812 } 813 814 /* 815 * Locate an interface based on a complete address. 816 */ 817 /*ARGSUSED*/ 818 struct ifaddr * 819 ifa_ifwithaddr(addr) 820 struct sockaddr *addr; 821 { 822 struct ifnet *ifp; 823 struct ifaddr *ifa; 824 825 #define equal(a1, a2) \ 826 (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0) 827 828 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 829 ifp = TAILQ_NEXT(ifp, if_list)) { 830 if (ifp->if_output == if_nulloutput) 831 continue; 832 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 833 ifa = TAILQ_NEXT(ifa, ifa_list)) { 834 if (ifa->ifa_addr->sa_family != addr->sa_family) 835 continue; 836 if (equal(addr, ifa->ifa_addr)) 837 return (ifa); 838 if ((ifp->if_flags & IFF_BROADCAST) && 839 ifa->ifa_broadaddr && 840 /* IP6 doesn't have broadcast */ 841 ifa->ifa_broadaddr->sa_len != 0 && 842 equal(ifa->ifa_broadaddr, addr)) 843 return (ifa); 844 } 845 } 846 return (NULL); 847 } 848 849 /* 850 * Locate the point to point interface with a given destination address. 851 */ 852 /*ARGSUSED*/ 853 struct ifaddr * 854 ifa_ifwithdstaddr(addr) 855 struct sockaddr *addr; 856 { 857 struct ifnet *ifp; 858 struct ifaddr *ifa; 859 860 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 861 ifp = TAILQ_NEXT(ifp, if_list)) { 862 if (ifp->if_output == if_nulloutput) 863 continue; 864 if (ifp->if_flags & IFF_POINTOPOINT) { 865 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 866 ifa = TAILQ_NEXT(ifa, ifa_list)) { 867 if (ifa->ifa_addr->sa_family != 868 addr->sa_family || 869 ifa->ifa_dstaddr == NULL) 870 continue; 871 if (equal(addr, ifa->ifa_dstaddr)) 872 return (ifa); 873 } 874 } 875 } 876 return (NULL); 877 } 878 879 /* 880 * Find an interface on a specific network. If many, choice 881 * is most specific found. 882 */ 883 struct ifaddr * 884 ifa_ifwithnet(addr) 885 struct sockaddr *addr; 886 { 887 struct ifnet *ifp; 888 struct ifaddr *ifa; 889 struct sockaddr_dl *sdl; 890 struct ifaddr *ifa_maybe = 0; 891 u_int af = addr->sa_family; 892 char *addr_data = addr->sa_data, *cplim; 893 894 if (af == AF_LINK) { 895 sdl = (struct sockaddr_dl *)addr; 896 if (sdl->sdl_index && sdl->sdl_index <= if_index && 897 ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput) 898 return (ifnet_addrs[sdl->sdl_index]); 899 } 900 #ifdef NETATALK 901 if (af == AF_APPLETALK) { 902 struct sockaddr_at *sat, *sat2; 903 sat = (struct sockaddr_at *)addr; 904 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 905 ifp = TAILQ_NEXT(ifp, if_list)) { 906 if (ifp->if_output == if_nulloutput) 907 continue; 908 ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp); 909 if (ifa == NULL) 910 continue; 911 sat2 = (struct sockaddr_at *)ifa->ifa_addr; 912 if (sat2->sat_addr.s_net == sat->sat_addr.s_net) 913 return (ifa); /* exact match */ 914 if (ifa_maybe == NULL) { 915 /* else keep the if with the rigth range */ 916 ifa_maybe = ifa; 917 } 918 } 919 return (ifa_maybe); 920 } 921 #endif 922 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 923 ifp = TAILQ_NEXT(ifp, if_list)) { 924 if (ifp->if_output == if_nulloutput) 925 continue; 926 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 927 ifa = TAILQ_NEXT(ifa, ifa_list)) { 928 char *cp, *cp2, *cp3; 929 930 if (ifa->ifa_addr->sa_family != af || 931 ifa->ifa_netmask == 0) 932 next: continue; 933 cp = addr_data; 934 cp2 = ifa->ifa_addr->sa_data; 935 cp3 = ifa->ifa_netmask->sa_data; 936 cplim = (char *)ifa->ifa_netmask + 937 ifa->ifa_netmask->sa_len; 938 while (cp3 < cplim) { 939 if ((*cp++ ^ *cp2++) & *cp3++) { 940 /* want to continue for() loop */ 941 goto next; 942 } 943 } 944 if (ifa_maybe == 0 || 945 rn_refines((caddr_t)ifa->ifa_netmask, 946 (caddr_t)ifa_maybe->ifa_netmask)) 947 ifa_maybe = ifa; 948 } 949 } 950 return (ifa_maybe); 951 } 952 953 /* 954 * Find the interface of the addresss. 955 */ 956 struct ifaddr * 957 ifa_ifwithladdr(addr) 958 struct sockaddr *addr; 959 { 960 struct ifaddr *ia; 961 962 if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) || 963 (ia = ifa_ifwithnet(addr))) 964 return (ia); 965 return (NULL); 966 } 967 968 /* 969 * Find an interface using a specific address family 970 */ 971 struct ifaddr * 972 ifa_ifwithaf(af) 973 int af; 974 { 975 struct ifnet *ifp; 976 struct ifaddr *ifa; 977 978 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 979 ifp = TAILQ_NEXT(ifp, if_list)) { 980 if (ifp->if_output == if_nulloutput) 981 continue; 982 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 983 ifa = TAILQ_NEXT(ifa, ifa_list)) { 984 if (ifa->ifa_addr->sa_family == af) 985 return (ifa); 986 } 987 } 988 return (NULL); 989 } 990 991 /* 992 * Find an interface address specific to an interface best matching 993 * a given address. 994 */ 995 struct ifaddr * 996 ifaof_ifpforaddr(addr, ifp) 997 struct sockaddr *addr; 998 struct ifnet *ifp; 999 { 1000 struct ifaddr *ifa; 1001 char *cp, *cp2, *cp3; 1002 char *cplim; 1003 struct ifaddr *ifa_maybe = 0; 1004 u_int af = addr->sa_family; 1005 1006 if (ifp->if_output == if_nulloutput) 1007 return (NULL); 1008 1009 if (af >= AF_MAX) 1010 return (NULL); 1011 1012 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1013 ifa = TAILQ_NEXT(ifa, ifa_list)) { 1014 if (ifa->ifa_addr->sa_family != af) 1015 continue; 1016 ifa_maybe = ifa; 1017 if (ifa->ifa_netmask == 0) { 1018 if (equal(addr, ifa->ifa_addr) || 1019 (ifa->ifa_dstaddr && 1020 equal(addr, ifa->ifa_dstaddr))) 1021 return (ifa); 1022 continue; 1023 } 1024 cp = addr->sa_data; 1025 cp2 = ifa->ifa_addr->sa_data; 1026 cp3 = ifa->ifa_netmask->sa_data; 1027 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 1028 for (; cp3 < cplim; cp3++) { 1029 if ((*cp++ ^ *cp2++) & *cp3) 1030 break; 1031 } 1032 if (cp3 == cplim) 1033 return (ifa); 1034 } 1035 return (ifa_maybe); 1036 } 1037 1038 /* 1039 * Default action when installing a route with a Link Level gateway. 1040 * Lookup an appropriate real ifa to point to. 1041 * This should be moved to /sys/net/link.c eventually. 1042 */ 1043 void 1044 link_rtrequest(cmd, rt, info) 1045 int cmd; 1046 struct rtentry *rt; 1047 struct rt_addrinfo *info; 1048 { 1049 struct ifaddr *ifa; 1050 struct sockaddr *dst; 1051 struct ifnet *ifp; 1052 1053 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 1054 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 1055 return; 1056 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { 1057 IFAFREE(rt->rt_ifa); 1058 rt->rt_ifa = ifa; 1059 IFAREF(ifa); 1060 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 1061 ifa->ifa_rtrequest(cmd, rt, info); 1062 } 1063 } 1064 1065 /* 1066 * Mark an interface down and notify protocols of 1067 * the transition. 1068 * NOTE: must be called at splsoftnet or equivalent. 1069 */ 1070 void 1071 if_down(ifp) 1072 struct ifnet *ifp; 1073 { 1074 struct ifaddr *ifa; 1075 1076 ifp->if_flags &= ~IFF_UP; 1077 microtime(&ifp->if_lastchange); 1078 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1079 ifa = TAILQ_NEXT(ifa, ifa_list)) 1080 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 1081 IFQ_PURGE(&ifp->if_snd); 1082 rt_ifmsg(ifp); 1083 } 1084 1085 /* 1086 * Mark an interface up and notify protocols of 1087 * the transition. 1088 * NOTE: must be called at splsoftnet or equivalent. 1089 */ 1090 void 1091 if_up(ifp) 1092 struct ifnet *ifp; 1093 { 1094 #ifdef notyet 1095 struct ifaddr *ifa; 1096 #endif 1097 1098 ifp->if_flags |= IFF_UP; 1099 microtime(&ifp->if_lastchange); 1100 #ifdef notyet 1101 /* this has no effect on IP, and will kill all ISO connections XXX */ 1102 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1103 ifa = TAILQ_NEXT(ifa, ifa_list)) 1104 pfctlinput(PRC_IFUP, ifa->ifa_addr); 1105 #endif 1106 rt_ifmsg(ifp); 1107 #ifdef INET6 1108 in6_if_up(ifp); 1109 #endif 1110 } 1111 1112 /* 1113 * Handle interface watchdog timer routines. Called 1114 * from softclock, we decrement timers (if set) and 1115 * call the appropriate interface routine on expiration. 1116 */ 1117 void 1118 if_slowtimo(arg) 1119 void *arg; 1120 { 1121 struct ifnet *ifp; 1122 int s = splnet(); 1123 1124 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 1125 ifp = TAILQ_NEXT(ifp, if_list)) { 1126 if (ifp->if_timer == 0 || --ifp->if_timer) 1127 continue; 1128 if (ifp->if_watchdog) 1129 (*ifp->if_watchdog)(ifp); 1130 } 1131 splx(s); 1132 callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ, 1133 if_slowtimo, NULL); 1134 } 1135 1136 /* 1137 * Set/clear promiscuous mode on interface ifp based on the truth value 1138 * of pswitch. The calls are reference counted so that only the first 1139 * "on" request actually has an effect, as does the final "off" request. 1140 * Results are undefined if the "off" and "on" requests are not matched. 1141 */ 1142 int 1143 ifpromisc(ifp, pswitch) 1144 struct ifnet *ifp; 1145 int pswitch; 1146 { 1147 int pcount, ret; 1148 short flags; 1149 struct ifreq ifr; 1150 1151 pcount = ifp->if_pcount; 1152 flags = ifp->if_flags; 1153 if (pswitch) { 1154 /* 1155 * Allow the device to be "placed" into promiscuous 1156 * mode even if it is not configured up. It will 1157 * consult IFF_PROMISC when it is is brought up. 1158 */ 1159 if (ifp->if_pcount++ != 0) 1160 return (0); 1161 ifp->if_flags |= IFF_PROMISC; 1162 if ((ifp->if_flags & IFF_UP) == 0) 1163 return (0); 1164 } else { 1165 if (--ifp->if_pcount > 0) 1166 return (0); 1167 ifp->if_flags &= ~IFF_PROMISC; 1168 /* 1169 * If the device is not configured up, we should not need to 1170 * turn off promiscuous mode (device should have turned it 1171 * off when interface went down; and will look at IFF_PROMISC 1172 * again next time interface comes up). 1173 */ 1174 if ((ifp->if_flags & IFF_UP) == 0) 1175 return (0); 1176 } 1177 memset(&ifr, 0, sizeof(ifr)); 1178 ifr.ifr_flags = ifp->if_flags; 1179 ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t) &ifr); 1180 /* Restore interface state if not successful. */ 1181 if (ret != 0) { 1182 ifp->if_pcount = pcount; 1183 ifp->if_flags = flags; 1184 } 1185 return (ret); 1186 } 1187 1188 /* 1189 * Map interface name to 1190 * interface structure pointer. 1191 */ 1192 struct ifnet * 1193 ifunit(name) 1194 const char *name; 1195 { 1196 struct ifnet *ifp; 1197 1198 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 1199 ifp = TAILQ_NEXT(ifp, if_list)) { 1200 if (ifp->if_output == if_nulloutput) 1201 continue; 1202 if (strcmp(ifp->if_xname, name) == 0) 1203 return (ifp); 1204 } 1205 return (NULL); 1206 } 1207 1208 /* 1209 * Interface ioctls. 1210 */ 1211 int 1212 ifioctl(so, cmd, data, p) 1213 struct socket *so; 1214 u_long cmd; 1215 caddr_t data; 1216 struct proc *p; 1217 { 1218 struct ifnet *ifp; 1219 struct ifreq *ifr; 1220 struct ifcapreq *ifcr; 1221 int s, error = 0; 1222 short oif_flags; 1223 1224 switch (cmd) { 1225 1226 case SIOCGIFCONF: 1227 case OSIOCGIFCONF: 1228 return (ifconf(cmd, data)); 1229 } 1230 ifr = (struct ifreq *)data; 1231 ifcr = (struct ifcapreq *)data; 1232 1233 switch (cmd) { 1234 case SIOCIFCREATE: 1235 case SIOCIFDESTROY: 1236 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1237 return (error); 1238 return ((cmd == SIOCIFCREATE) ? 1239 if_clone_create(ifr->ifr_name) : 1240 if_clone_destroy(ifr->ifr_name)); 1241 1242 case SIOCIFGCLONERS: 1243 return (if_clone_list((struct if_clonereq *)data)); 1244 } 1245 1246 ifp = ifunit(ifr->ifr_name); 1247 if (ifp == 0) 1248 return (ENXIO); 1249 oif_flags = ifp->if_flags; 1250 switch (cmd) { 1251 1252 case SIOCGIFFLAGS: 1253 ifr->ifr_flags = ifp->if_flags; 1254 break; 1255 1256 case SIOCGIFMETRIC: 1257 ifr->ifr_metric = ifp->if_metric; 1258 break; 1259 1260 case SIOCGIFMTU: 1261 ifr->ifr_mtu = ifp->if_mtu; 1262 break; 1263 1264 case SIOCGIFDLT: 1265 ifr->ifr_dlt = ifp->if_dlt; 1266 break; 1267 1268 case SIOCSIFFLAGS: 1269 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1270 return (error); 1271 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 1272 s = splnet(); 1273 if_down(ifp); 1274 splx(s); 1275 } 1276 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 1277 s = splnet(); 1278 if_up(ifp); 1279 splx(s); 1280 } 1281 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 1282 (ifr->ifr_flags &~ IFF_CANTCHANGE); 1283 if (ifp->if_ioctl) 1284 (void) (*ifp->if_ioctl)(ifp, cmd, data); 1285 break; 1286 1287 case SIOCGIFCAP: 1288 ifcr->ifcr_capabilities = ifp->if_capabilities; 1289 ifcr->ifcr_capenable = ifp->if_capenable; 1290 break; 1291 1292 case SIOCSIFCAP: 1293 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1294 return (error); 1295 if ((ifcr->ifcr_capenable & ~ifp->if_capabilities) != 0) 1296 return (EINVAL); 1297 if (ifp->if_ioctl == NULL) 1298 return (EOPNOTSUPP); 1299 1300 /* Must prevent race with packet reception here. */ 1301 s = splnet(); 1302 if (ifcr->ifcr_capenable != ifp->if_capenable) { 1303 struct ifreq ifrq; 1304 1305 ifrq.ifr_flags = ifp->if_flags; 1306 ifp->if_capenable = ifcr->ifcr_capenable; 1307 1308 /* Pre-compute the checksum flags mask. */ 1309 ifp->if_csum_flags_tx = 0; 1310 ifp->if_csum_flags_rx = 0; 1311 if (ifp->if_capenable & IFCAP_CSUM_IPv4) { 1312 ifp->if_csum_flags_tx |= M_CSUM_IPv4; 1313 ifp->if_csum_flags_rx |= M_CSUM_IPv4; 1314 } 1315 1316 if (ifp->if_capenable & IFCAP_CSUM_TCPv4) { 1317 ifp->if_csum_flags_tx |= M_CSUM_TCPv4; 1318 ifp->if_csum_flags_rx |= M_CSUM_TCPv4; 1319 } else if (ifp->if_capenable & IFCAP_CSUM_TCPv4_Rx) 1320 ifp->if_csum_flags_rx |= M_CSUM_TCPv4; 1321 1322 if (ifp->if_capenable & IFCAP_CSUM_UDPv4) { 1323 ifp->if_csum_flags_tx |= M_CSUM_UDPv4; 1324 ifp->if_csum_flags_rx |= M_CSUM_UDPv4; 1325 } else if (ifp->if_capenable & IFCAP_CSUM_UDPv4_Rx) 1326 ifp->if_csum_flags_rx |= M_CSUM_UDPv4; 1327 1328 if (ifp->if_capenable & IFCAP_CSUM_TCPv6) { 1329 ifp->if_csum_flags_tx |= M_CSUM_TCPv6; 1330 ifp->if_csum_flags_rx |= M_CSUM_TCPv6; 1331 } 1332 1333 if (ifp->if_capenable & IFCAP_CSUM_UDPv6) { 1334 ifp->if_csum_flags_tx |= M_CSUM_UDPv6; 1335 ifp->if_csum_flags_rx |= M_CSUM_UDPv6; 1336 } 1337 1338 /* 1339 * Only kick the interface if it's up. If it's 1340 * not up now, it will notice the cap enables 1341 * when it is brought up later. 1342 */ 1343 if (ifp->if_flags & IFF_UP) 1344 (void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, 1345 (caddr_t) &ifrq); 1346 } 1347 splx(s); 1348 break; 1349 1350 case SIOCSIFMETRIC: 1351 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1352 return (error); 1353 ifp->if_metric = ifr->ifr_metric; 1354 break; 1355 1356 case SIOCSIFMTU: 1357 { 1358 u_long oldmtu = ifp->if_mtu; 1359 1360 error = suser(p->p_ucred, &p->p_acflag); 1361 if (error) 1362 return (error); 1363 if (ifp->if_ioctl == NULL) 1364 return (EOPNOTSUPP); 1365 error = (*ifp->if_ioctl)(ifp, cmd, data); 1366 1367 /* 1368 * If the link MTU changed, do network layer specific procedure. 1369 */ 1370 if (ifp->if_mtu != oldmtu) { 1371 #ifdef INET6 1372 nd6_setmtu(ifp); 1373 #endif 1374 } 1375 break; 1376 } 1377 case SIOCSIFPHYADDR: 1378 case SIOCDIFPHYADDR: 1379 #ifdef INET6 1380 case SIOCSIFPHYADDR_IN6: 1381 #endif 1382 case SIOCSLIFPHYADDR: 1383 case SIOCADDMULTI: 1384 case SIOCDELMULTI: 1385 case SIOCSIFMEDIA: 1386 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1387 return (error); 1388 /* FALLTHROUGH */ 1389 case SIOCGIFPSRCADDR: 1390 case SIOCGIFPDSTADDR: 1391 case SIOCGLIFPHYADDR: 1392 case SIOCGIFMEDIA: 1393 if (ifp->if_ioctl == 0) 1394 return (EOPNOTSUPP); 1395 error = (*ifp->if_ioctl)(ifp, cmd, data); 1396 break; 1397 1398 case SIOCSDRVSPEC: 1399 case SIOCS80211NWID: 1400 case SIOCS80211NWKEY: 1401 case SIOCS80211POWER: 1402 /* XXX: need to pass proc pointer through to driver... */ 1403 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1404 return (error); 1405 /* FALLTHROUGH */ 1406 default: 1407 if (so->so_proto == 0) 1408 return (EOPNOTSUPP); 1409 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4) && !defined(LKM) 1410 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1411 (struct mbuf *)cmd, (struct mbuf *)data, 1412 (struct mbuf *)ifp, p)); 1413 #else 1414 { 1415 int ocmd = cmd; 1416 1417 switch (cmd) { 1418 1419 case SIOCSIFADDR: 1420 case SIOCSIFDSTADDR: 1421 case SIOCSIFBRDADDR: 1422 case SIOCSIFNETMASK: 1423 #if BYTE_ORDER != BIG_ENDIAN 1424 if (ifr->ifr_addr.sa_family == 0 && 1425 ifr->ifr_addr.sa_len < 16) { 1426 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 1427 ifr->ifr_addr.sa_len = 16; 1428 } 1429 #else 1430 if (ifr->ifr_addr.sa_len == 0) 1431 ifr->ifr_addr.sa_len = 16; 1432 #endif 1433 break; 1434 1435 case OSIOCGIFADDR: 1436 cmd = SIOCGIFADDR; 1437 break; 1438 1439 case OSIOCGIFDSTADDR: 1440 cmd = SIOCGIFDSTADDR; 1441 break; 1442 1443 case OSIOCGIFBRDADDR: 1444 cmd = SIOCGIFBRDADDR; 1445 break; 1446 1447 case OSIOCGIFNETMASK: 1448 cmd = SIOCGIFNETMASK; 1449 } 1450 1451 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1452 (struct mbuf *)cmd, (struct mbuf *)data, 1453 (struct mbuf *)ifp, p)); 1454 1455 switch (ocmd) { 1456 case OSIOCGIFADDR: 1457 case OSIOCGIFDSTADDR: 1458 case OSIOCGIFBRDADDR: 1459 case OSIOCGIFNETMASK: 1460 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 1461 } 1462 } 1463 #endif /* COMPAT_43 */ 1464 break; 1465 } 1466 1467 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) { 1468 #ifdef INET6 1469 if ((ifp->if_flags & IFF_UP) != 0) { 1470 s = splnet(); 1471 in6_if_up(ifp); 1472 splx(s); 1473 } 1474 #endif 1475 } 1476 1477 return (error); 1478 } 1479 1480 /* 1481 * Return interface configuration 1482 * of system. List may be used 1483 * in later ioctl's (above) to get 1484 * other information. 1485 */ 1486 /*ARGSUSED*/ 1487 int 1488 ifconf(cmd, data) 1489 u_long cmd; 1490 caddr_t data; 1491 { 1492 struct ifconf *ifc = (struct ifconf *)data; 1493 struct ifnet *ifp; 1494 struct ifaddr *ifa; 1495 struct ifreq ifr, *ifrp; 1496 int space = ifc->ifc_len, error = 0; 1497 1498 ifrp = ifc->ifc_req; 1499 TAILQ_FOREACH(ifp, &ifnet, if_list) { 1500 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ); 1501 if ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) == 0) { 1502 memset((caddr_t)&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); 1503 if (space >= (int)sizeof (ifr)) { 1504 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1505 sizeof(ifr)); 1506 if (error) 1507 break; 1508 } 1509 space -= sizeof (ifr), ifrp++; 1510 } else 1511 for (; ifa != 0; ifa = TAILQ_NEXT(ifa, ifa_list)) { 1512 struct sockaddr *sa = ifa->ifa_addr; 1513 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1514 if (cmd == OSIOCGIFCONF) { 1515 struct osockaddr *osa = 1516 (struct osockaddr *)&ifr.ifr_addr; 1517 ifr.ifr_addr = *sa; 1518 osa->sa_family = sa->sa_family; 1519 if (space >= (int)sizeof (ifr)) { 1520 error = copyout((caddr_t)&ifr, 1521 (caddr_t)ifrp, 1522 sizeof (ifr)); 1523 ifrp++; 1524 } 1525 } else 1526 #endif 1527 if (sa->sa_len <= sizeof(*sa)) { 1528 ifr.ifr_addr = *sa; 1529 if (space >= (int)sizeof (ifr)) { 1530 error = copyout((caddr_t)&ifr, 1531 (caddr_t)ifrp, 1532 sizeof (ifr)); 1533 ifrp++; 1534 } 1535 } else { 1536 space -= sa->sa_len - sizeof(*sa); 1537 if (space >= (int)sizeof (ifr)) { 1538 error = copyout((caddr_t)&ifr, 1539 (caddr_t)ifrp, 1540 sizeof (ifr.ifr_name)); 1541 if (error == 0) { 1542 error = copyout((caddr_t)sa, 1543 (caddr_t)&ifrp->ifr_addr, 1544 sa->sa_len); 1545 } 1546 ifrp = (struct ifreq *) 1547 (sa->sa_len + 1548 (caddr_t)&ifrp->ifr_addr); 1549 } 1550 } 1551 if (error) 1552 break; 1553 space -= sizeof (ifr); 1554 } 1555 } 1556 ifc->ifc_len -= space; 1557 return (error); 1558 } 1559