1/* 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1980, 1986, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)if.c 8.3 (Berkeley) 1/4/94 61 * $FreeBSD: src/sys/net/if.c,v 1.85.2.9 2001/07/24 19:10:17 brooks Exp $ 62 */ 63/* 64 * NOTICE: This file was modified by SPARTA, Inc. in 2006 to introduce 65 * support for mandatory and extensible security protections. This notice 66 * is included in support of clause 2.2 (b) of the Apple Public License, 67 * Version 2.0. 68 */ 69 70#include <kern/locks.h> 71 72#include <sys/param.h> 73#include <sys/malloc.h> 74#include <sys/mbuf.h> 75#include <sys/systm.h> 76#include <sys/proc.h> 77#include <sys/socket.h> 78#include <sys/socketvar.h> 79#include <sys/protosw.h> 80#include <sys/kernel.h> 81#include <sys/sockio.h> 82#include <sys/syslog.h> 83#include <sys/sysctl.h> 84 85#include <net/if.h> 86#include <net/if_arp.h> 87#include <net/if_dl.h> 88#include <net/if_types.h> 89#include <net/if_var.h> 90#include <net/net_osdep.h> 91#include <net/ethernet.h> 92 93#include <net/radix.h> 94#include <net/route.h> 95#ifdef __APPLE__ 96#include <net/dlil.h> 97//#include <string.h> 98#include <sys/domain.h> 99#include <libkern/OSAtomic.h> 100#endif 101 102#if INET || INET6 103/*XXX*/ 104#include <netinet/in.h> 105#include <netinet/in_var.h> 106#include <netinet/ip_var.h> 107#if INET6 108#include <netinet6/in6_var.h> 109#include <netinet6/in6_ifattach.h> 110#endif 111#endif 112 113extern u_long route_generation; 114extern int use_routegenid; 115extern int dlil_multithreaded_input; 116extern struct dlil_threading_info *dlil_lo_thread_ptr; 117 118#if CONFIG_MACF_NET 119#include <security/mac_framework.h> 120#endif 121 122/* 123 * System initialization 124 */ 125 126static int ifconf(u_long cmd, user_addr_t ifrp, int * ret_space); 127static void if_qflush(struct ifqueue *); 128__private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *); 129void if_rtproto_del(struct ifnet *ifp, int protocol); 130 131static int if_rtmtu(struct radix_node *, void *); 132static void if_rtmtu_update(struct ifnet *); 133 134static struct if_clone *if_clone_lookup(const char *, int *); 135#ifdef IF_CLONE_LIST 136static int if_clone_list(int count, int * total, user_addr_t dst); 137#endif 138 139MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); 140MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); 141 142int ifqmaxlen = IFQ_MAXLEN; 143struct ifnethead ifnet_head = TAILQ_HEAD_INITIALIZER(ifnet_head); 144 145static int if_cloners_count; 146LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 147 148static struct ifaddr *ifa_ifwithnet_common(const struct sockaddr *, 149 unsigned int); 150 151#if INET6 152/* 153 * XXX: declare here to avoid to include many inet6 related files.. 154 * should be more generalized? 155 */ 156extern void nd6_setmtu(struct ifnet *); 157#endif 158 159#define M_CLONE M_IFADDR 160 161/* 162 * Network interface utility routines. 163 * 164 * Routines with ifa_ifwith* names take sockaddr *'s as 165 * parameters. 166 */ 167 168int if_index; 169struct ifaddr **ifnet_addrs; 170struct ifnet **ifindex2ifnet; 171 172__private_extern__ void 173if_attach_ifa( 174 struct ifnet *ifp, 175 struct ifaddr *ifa) 176{ 177 ifnet_lock_assert(ifp, LCK_MTX_ASSERT_OWNED); 178 if (ifa->ifa_debug & IFA_ATTACHED) { 179 panic("if_attach_ifa: Attempted to attach address that's already attached!\n"); 180 } 181 ifaref(ifa); 182 ifa->ifa_debug |= IFA_ATTACHED; 183 TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); 184} 185 186__private_extern__ void 187if_detach_ifa( 188 struct ifnet *ifp, 189 struct ifaddr *ifa) 190{ 191 ifnet_lock_assert(ifp, LCK_MTX_ASSERT_OWNED); 192#if 1 193 /* Debugging code */ 194 if ((ifa->ifa_debug & IFA_ATTACHED) == 0) { 195 printf("if_detach_ifa: ifa is not attached to any interface! flags=%lu\n", ifa->ifa_debug); 196 return; 197 } 198 else { 199 struct ifaddr *ifa2; 200 TAILQ_FOREACH(ifa2, &ifp->if_addrhead, ifa_link) { 201 if (ifa2 == ifa) 202 break; 203 } 204 if (ifa2 != ifa) { 205 printf("if_detach_ifa: Attempted to detach IFA that was not attached!\n"); 206 } 207 } 208#endif 209 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); 210 ifa->ifa_debug &= ~IFA_ATTACHED; 211 ifafree(ifa); 212} 213 214#define INITIAL_IF_INDEXLIM 8 215 216/* 217 * Function: if_next_index 218 * Purpose: 219 * Return the next available interface index. 220 * Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the 221 * added entry when necessary. 222 * 223 * Note: 224 * ifnet_addrs[] is indexed by (if_index - 1), whereas 225 * ifindex2ifnet[] is indexed by ifp->if_index. That requires us to 226 * always allocate one extra element to hold ifindex2ifnet[0], which 227 * is unused. 228 */ 229int if_next_index(void); 230 231__private_extern__ int 232if_next_index(void) 233{ 234 static int if_indexlim = 0; 235 int new_index; 236 237 new_index = ++if_index; 238 if (if_index > if_indexlim) { 239 unsigned n; 240 int new_if_indexlim; 241 caddr_t new_ifnet_addrs; 242 caddr_t new_ifindex2ifnet; 243 caddr_t old_ifnet_addrs; 244 245 old_ifnet_addrs = (caddr_t)ifnet_addrs; 246 if (ifnet_addrs == NULL) { 247 new_if_indexlim = INITIAL_IF_INDEXLIM; 248 } else { 249 new_if_indexlim = if_indexlim << 1; 250 } 251 252 /* allocate space for the larger arrays */ 253 n = (2 * new_if_indexlim + 1) * sizeof(caddr_t); 254 new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK); 255 new_ifindex2ifnet = new_ifnet_addrs 256 + new_if_indexlim * sizeof(caddr_t); 257 bzero(new_ifnet_addrs, n); 258 if (ifnet_addrs != NULL) { 259 /* copy the existing data */ 260 bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs, 261 if_indexlim * sizeof(caddr_t)); 262 bcopy((caddr_t)ifindex2ifnet, 263 new_ifindex2ifnet, 264 (if_indexlim + 1) * sizeof(caddr_t)); 265 } 266 267 /* switch to the new tables and size */ 268 ifnet_addrs = (struct ifaddr **)new_ifnet_addrs; 269 ifindex2ifnet = (struct ifnet **)new_ifindex2ifnet; 270 if_indexlim = new_if_indexlim; 271 272 /* release the old data */ 273 if (old_ifnet_addrs != NULL) { 274 _FREE((caddr_t)old_ifnet_addrs, M_IFADDR); 275 } 276 } 277 return (new_index); 278} 279 280/* 281 * Create a clone network interface. 282 */ 283static int 284if_clone_create(char *name, int len) 285{ 286 struct if_clone *ifc; 287 char *dp; 288 int wildcard, bytoff, bitoff; 289 int unit; 290 int err; 291 292 ifc = if_clone_lookup(name, &unit); 293 if (ifc == NULL) 294 return (EINVAL); 295 296 if (ifunit(name) != NULL) 297 return (EEXIST); 298 299 bytoff = bitoff = 0; 300 wildcard = (unit < 0); 301 /* 302 * Find a free unit if none was given. 303 */ 304 if (wildcard) { 305 while ((bytoff < ifc->ifc_bmlen) 306 && (ifc->ifc_units[bytoff] == 0xff)) 307 bytoff++; 308 if (bytoff >= ifc->ifc_bmlen) 309 return (ENOSPC); 310 while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0) 311 bitoff++; 312 unit = (bytoff << 3) + bitoff; 313 } 314 315 if (unit > ifc->ifc_maxunit) 316 return (ENXIO); 317 318 err = (*ifc->ifc_create)(ifc, unit); 319 if (err != 0) 320 return (err); 321 322 if (!wildcard) { 323 bytoff = unit >> 3; 324 bitoff = unit - (bytoff << 3); 325 } 326 327 /* 328 * Allocate the unit in the bitmap. 329 */ 330 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0, 331 ("%s: bit is already set", __func__)); 332 ifc->ifc_units[bytoff] |= (1 << bitoff); 333 334 /* In the wildcard case, we need to update the name. */ 335 if (wildcard) { 336 for (dp = name; *dp != '\0'; dp++); 337 if (snprintf(dp, len - (dp-name), "%d", unit) > 338 len - (dp-name) - 1) { 339 /* 340 * This can only be a programmer error and 341 * there's no straightforward way to recover if 342 * it happens. 343 */ 344 panic("if_clone_create(): interface name too long"); 345 } 346 347 } 348 349 return (0); 350} 351 352/* 353 * Destroy a clone network interface. 354 */ 355static int 356if_clone_destroy(const char *name) 357{ 358 struct if_clone *ifc; 359 struct ifnet *ifp; 360 int bytoff, bitoff; 361 int unit; 362 363 ifc = if_clone_lookup(name, &unit); 364 if (ifc == NULL) 365 return (EINVAL); 366 367 if (unit < ifc->ifc_minifs) 368 return (EINVAL); 369 370 ifp = ifunit(name); 371 if (ifp == NULL) 372 return (ENXIO); 373 374 if (ifc->ifc_destroy == NULL) 375 return (EOPNOTSUPP); 376 377 (*ifc->ifc_destroy)(ifp); 378 379 /* 380 * Compute offset in the bitmap and deallocate the unit. 381 */ 382 bytoff = unit >> 3; 383 bitoff = unit - (bytoff << 3); 384 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0, 385 ("%s: bit is already cleared", __func__)); 386 ifc->ifc_units[bytoff] &= ~(1 << bitoff); 387 return (0); 388} 389 390/* 391 * Look up a network interface cloner. 392 */ 393 394static struct if_clone * 395if_clone_lookup(const char *name, int *unitp) 396{ 397 struct if_clone *ifc; 398 const char *cp; 399 size_t i; 400 401 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) { 402 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) { 403 if (ifc->ifc_name[i] != *cp) 404 goto next_ifc; 405 } 406 goto found_name; 407 next_ifc: 408 ifc = LIST_NEXT(ifc, ifc_list); 409 } 410 411 /* No match. */ 412 return ((struct if_clone *)NULL); 413 414 found_name: 415 if (*cp == '\0') { 416 i = -1; 417 } else { 418 for (i = 0; *cp != '\0'; cp++) { 419 if (*cp < '0' || *cp > '9') { 420 /* Bogus unit number. */ 421 return (NULL); 422 } 423 i = (i * 10) + (*cp - '0'); 424 } 425 } 426 427 if (unitp != NULL) 428 *unitp = i; 429 return (ifc); 430} 431 432/* 433 * Register a network interface cloner. 434 */ 435void 436if_clone_attach(struct if_clone *ifc) 437{ 438 int bytoff, bitoff; 439 int err; 440 int len, maxclone; 441 int unit; 442 443 KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit, 444 ("%s: %s requested more units then allowed (%d > %d)", 445 __func__, ifc->ifc_name, ifc->ifc_minifs, 446 ifc->ifc_maxunit + 1)); 447 /* 448 * Compute bitmap size and allocate it. 449 */ 450 maxclone = ifc->ifc_maxunit + 1; 451 len = maxclone >> 3; 452 if ((len << 3) < maxclone) 453 len++; 454 ifc->ifc_units = _MALLOC(len, M_CLONE, M_WAITOK | M_ZERO); 455 bzero(ifc->ifc_units, len); 456 ifc->ifc_bmlen = len; 457 458 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 459 if_cloners_count++; 460 461 for (unit = 0; unit < ifc->ifc_minifs; unit++) { 462 err = (*ifc->ifc_create)(ifc, unit); 463 KASSERT(err == 0, 464 ("%s: failed to create required interface %s%d", 465 __func__, ifc->ifc_name, unit)); 466 467 /* Allocate the unit in the bitmap. */ 468 bytoff = unit >> 3; 469 bitoff = unit - (bytoff << 3); 470 ifc->ifc_units[bytoff] |= (1 << bitoff); 471 } 472} 473 474/* 475 * Unregister a network interface cloner. 476 */ 477void 478if_clone_detach(struct if_clone *ifc) 479{ 480 481 LIST_REMOVE(ifc, ifc_list); 482 FREE(ifc->ifc_units, M_CLONE); 483 if_cloners_count--; 484} 485 486#ifdef IF_CLONE_LIST 487/* 488 * Provide list of interface cloners to userspace. 489 */ 490static int 491if_clone_list(int count, int * total, user_addr_t dst) 492{ 493 char outbuf[IFNAMSIZ]; 494 struct if_clone *ifc; 495 int error = 0; 496 497 *total = if_cloners_count; 498 if (dst == USER_ADDR_NULL) { 499 /* Just asking how many there are. */ 500 return (0); 501 } 502 503 if (count < 0) 504 return (EINVAL); 505 506 count = (if_cloners_count < count) ? if_cloners_count : count; 507 508 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 509 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 510 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ); 511 error = copyout(outbuf, dst, IFNAMSIZ); 512 if (error) 513 break; 514 } 515 516 return (error); 517} 518#endif IF_CLONE_LIST 519 520__private_extern__ int 521ifa_foraddr( 522 unsigned int addr) 523{ 524 struct ifnet *ifp; 525 struct ifaddr *ifa; 526 unsigned int addr2; 527 int result = 0; 528 529 ifnet_head_lock_shared(); 530 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) { 531 ifnet_lock_shared(ifp); 532 for (ifa = ifp->if_addrhead.tqh_first; ifa; 533 ifa = ifa->ifa_link.tqe_next) { 534 if (ifa->ifa_addr->sa_family != AF_INET) 535 continue; 536 addr2 = IA_SIN(ifa)->sin_addr.s_addr; 537 538 if (addr == addr2) { 539 result = 1; 540 break; 541 } 542 } 543 ifnet_lock_done(ifp); 544 } 545 ifnet_head_done(); 546 547 return result; 548} 549 550/* 551 * Return the first (primary) address of a given family on an interface. 552 */ 553__private_extern__ struct ifaddr * 554ifa_ifpgetprimary(struct ifnet *ifp, int family) 555{ 556 struct ifaddr *ifa0 = NULL, *ifa; 557 558 ifnet_lock_shared(ifp); 559 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 560 if (ifa->ifa_addr->sa_family == family && ifa0 == NULL) { 561 ifa0 = ifa; 562 break; 563 } 564 } 565 if (ifa0 != NULL) 566 ifaref(ifa0); 567 ifnet_lock_done(ifp); 568 569 return (ifa0); 570} 571 572/* 573 * Locate an interface based on a complete address. 574 */ 575/*ARGSUSED*/ 576struct ifaddr * 577ifa_ifwithaddr( 578 const struct sockaddr *addr) 579{ 580 struct ifnet *ifp; 581 struct ifaddr *ifa; 582 struct ifaddr *result = NULL; 583 584#define equal(a1, a2) \ 585 (bcmp((const void*)(a1), (const void*)(a2), ((const struct sockaddr *)(a1))->sa_len) == 0) 586 587 ifnet_head_lock_shared(); 588 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) { 589 ifnet_lock_shared(ifp); 590 for (ifa = ifp->if_addrhead.tqh_first; ifa; 591 ifa = ifa->ifa_link.tqe_next) { 592 if (ifa->ifa_addr->sa_family != addr->sa_family) 593 continue; 594 if (equal(addr, ifa->ifa_addr)) { 595 result = ifa; 596 break; 597 } 598 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr && 599 /* IP6 doesn't have broadcast */ 600 ifa->ifa_broadaddr->sa_len != 0 && 601 equal(ifa->ifa_broadaddr, addr)) { 602 result = ifa; 603 break; 604 } 605 } 606 if (result) 607 ifaref(result); 608 ifnet_lock_done(ifp); 609 } 610 ifnet_head_done(); 611 612 return result; 613} 614/* 615 * Locate the point to point interface with a given destination address. 616 */ 617/*ARGSUSED*/ 618struct ifaddr * 619ifa_ifwithdstaddr( 620 const struct sockaddr *addr) 621{ 622 struct ifnet *ifp; 623 struct ifaddr *ifa; 624 struct ifaddr *result = NULL; 625 626 ifnet_head_lock_shared(); 627 for (ifp = ifnet_head.tqh_first; ifp && !result; ifp = ifp->if_link.tqe_next) { 628 if (ifp->if_flags & IFF_POINTOPOINT) { 629 ifnet_lock_shared(ifp); 630 for (ifa = ifp->if_addrhead.tqh_first; ifa; 631 ifa = ifa->ifa_link.tqe_next) { 632 if (ifa->ifa_addr->sa_family != addr->sa_family) 633 continue; 634 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) { 635 result = ifa; 636 break; 637 } 638 } 639 if (result) 640 ifaref(result); 641 ifnet_lock_done(ifp); 642 } 643 } 644 ifnet_head_done(); 645 return result; 646} 647 648/* 649 * Locate the source address of an interface based on a complete address. 650 */ 651struct ifaddr * 652ifa_ifwithaddr_scoped(const struct sockaddr *addr, unsigned int ifscope) 653{ 654 struct ifaddr *result = NULL; 655 struct ifnet *ifp; 656 657 if (ifscope == IFSCOPE_NONE) 658 return (ifa_ifwithaddr(addr)); 659 660 ifnet_head_lock_shared(); 661 if (ifscope > (unsigned int)if_index) { 662 ifnet_head_done(); 663 return (NULL); 664 } 665 666 ifp = ifindex2ifnet[ifscope]; 667 if (ifp != NULL) { 668 struct ifaddr *ifa = NULL; 669 670 /* 671 * This is suboptimal; there should be a better way 672 * to search for a given address of an interface. 673 */ 674 ifnet_lock_shared(ifp); 675 for (ifa = ifp->if_addrhead.tqh_first; ifa != NULL; 676 ifa = ifa->ifa_link.tqe_next) { 677 if (ifa->ifa_addr->sa_family != addr->sa_family) 678 continue; 679 if (equal(addr, ifa->ifa_addr)) { 680 result = ifa; 681 break; 682 } 683 if ((ifp->if_flags & IFF_BROADCAST) && 684 ifa->ifa_broadaddr != NULL && 685 /* IP6 doesn't have broadcast */ 686 ifa->ifa_broadaddr->sa_len != 0 && 687 equal(ifa->ifa_broadaddr, addr)) { 688 result = ifa; 689 break; 690 } 691 } 692 if (result != NULL) 693 ifaref(result); 694 ifnet_lock_done(ifp); 695 } 696 ifnet_head_done(); 697 698 return (result); 699} 700 701struct ifaddr * 702ifa_ifwithnet(const struct sockaddr *addr) 703{ 704 return (ifa_ifwithnet_common(addr, IFSCOPE_NONE)); 705} 706 707struct ifaddr * 708ifa_ifwithnet_scoped(const struct sockaddr *addr, unsigned int ifscope) 709{ 710 return (ifa_ifwithnet_common(addr, ifscope)); 711} 712 713/* 714 * Find an interface on a specific network. If many, choice 715 * is most specific found. 716 */ 717static struct ifaddr * 718ifa_ifwithnet_common(const struct sockaddr *addr, unsigned int ifscope) 719{ 720 struct ifnet *ifp; 721 struct ifaddr *ifa = NULL; 722 struct ifaddr *ifa_maybe = (struct ifaddr *) 0; 723 u_int af = addr->sa_family; 724 const char *addr_data = addr->sa_data, *cplim; 725 726 if (!ip_doscopedroute || addr->sa_family != AF_INET) 727 ifscope = IFSCOPE_NONE; 728 729 ifnet_head_lock_shared(); 730 /* 731 * AF_LINK addresses can be looked up directly by their index number, 732 * so do that if we can. 733 */ 734 if (af == AF_LINK) { 735 const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)addr; 736 if (sdl->sdl_index && sdl->sdl_index <= if_index) { 737 ifa = ifnet_addrs[sdl->sdl_index - 1]; 738 739 if (ifa) 740 ifaref(ifa); 741 742 ifnet_head_done(); 743 return ifa; 744 } 745 } 746 747 /* 748 * Scan though each interface, looking for ones that have 749 * addresses in this address family. 750 */ 751 for (ifp = ifnet_head.tqh_first; ifp; ifp = ifp->if_link.tqe_next) { 752 ifnet_lock_shared(ifp); 753 for (ifa = ifp->if_addrhead.tqh_first; ifa; 754 ifa = ifa->ifa_link.tqe_next) { 755 const char *cp, *cp2, *cp3; 756 757 if (ifa->ifa_addr->sa_family != af) 758next: continue; 759#ifndef __APPLE__ 760/* This breaks tunneling application trying to install a route with 761 * a specific subnet and the local address as the destination 762 * It's breaks binary compatibility with previous version of MacOS X 763 */ 764 if ( 765 766#if INET6 /* XXX: for maching gif tunnel dst as routing entry gateway */ 767 addr->sa_family != AF_INET6 && 768#endif 769 ifp->if_flags & IFF_POINTOPOINT) { 770 /* 771 * This is a bit broken as it doesn't 772 * take into account that the remote end may 773 * be a single node in the network we are 774 * looking for. 775 * The trouble is that we don't know the 776 * netmask for the remote end. 777 */ 778 if (ifa->ifa_dstaddr != 0 779 && equal(addr, ifa->ifa_dstaddr)) { 780 break; 781 } 782 } else 783#endif /* __APPLE__*/ 784 { 785 /* 786 * If we're looking up with a scope, 787 * find using a matching interface. 788 */ 789 if (ifscope != IFSCOPE_NONE && 790 ifp->if_index != ifscope) 791 continue; 792 793 /* 794 * if we have a special address handler, 795 * then use it instead of the generic one. 796 */ 797 if (ifa->ifa_claim_addr) { 798 if (ifa->ifa_claim_addr(ifa, addr)) { 799 break; 800 } else { 801 continue; 802 } 803 } 804 805 /* 806 * Scan all the bits in the ifa's address. 807 * If a bit dissagrees with what we are 808 * looking for, mask it with the netmask 809 * to see if it really matters. 810 * (A byte at a time) 811 */ 812 if (ifa->ifa_netmask == 0) 813 continue; 814 cp = addr_data; 815 cp2 = ifa->ifa_addr->sa_data; 816 cp3 = ifa->ifa_netmask->sa_data; 817 cplim = ifa->ifa_netmask->sa_len 818 + (char *)ifa->ifa_netmask; 819 while (cp3 < cplim) 820 if ((*cp++ ^ *cp2++) & *cp3++) 821 goto next; /* next address! */ 822 /* 823 * If the netmask of what we just found 824 * is more specific than what we had before 825 * (if we had one) then remember the new one 826 * before continuing to search 827 * for an even better one. 828 */ 829 if (ifa_maybe == 0 || 830 rn_refines((caddr_t)ifa->ifa_netmask, 831 (caddr_t)ifa_maybe->ifa_netmask)) { 832 ifaref(ifa); 833 if (ifa_maybe) 834 ifafree(ifa_maybe); 835 ifa_maybe = ifa; 836 } 837 } 838 } 839 840 if (ifa) { 841 ifaref(ifa); 842 } 843 844 /* 845 * ifa is set if we found an exact match. 846 * take a reference to the ifa before 847 * releasing the ifp lock 848 */ 849 ifnet_lock_done(ifp); 850 851 if (ifa) { 852 break; 853 } 854 } 855 ifnet_head_done(); 856 if (!ifa) 857 ifa = ifa_maybe; 858 else if (ifa_maybe) { 859 ifafree(ifa_maybe); 860 ifa_maybe = NULL; 861 } 862 return ifa; 863} 864 865/* 866 * Find an interface address specific to an interface best matching 867 * a given address. 868 */ 869struct ifaddr * 870ifaof_ifpforaddr( 871 const struct sockaddr *addr, 872 struct ifnet *ifp) 873{ 874 struct ifaddr *ifa = NULL; 875 const char *cp, *cp2, *cp3; 876 char *cplim; 877 struct ifaddr *ifa_maybe = NULL; 878 struct ifaddr *better_ifa_maybe = NULL; 879 u_int af = addr->sa_family; 880 881 if (af >= AF_MAX) 882 return (NULL); 883 884 ifnet_lock_shared(ifp); 885 for (ifa = ifp->if_addrhead.tqh_first; ifa; 886 ifa = ifa->ifa_link.tqe_next) { 887 if (ifa->ifa_addr->sa_family != af) 888 continue; 889 if (ifa_maybe == 0) 890 ifa_maybe = ifa; 891 if (ifa->ifa_netmask == 0) { 892 if (equal(addr, ifa->ifa_addr) || 893 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) 894 break; 895 continue; 896 } 897 if (ifp->if_flags & IFF_POINTOPOINT) { 898 if (equal(addr, ifa->ifa_dstaddr)) 899 break; 900 } else { 901 if (equal(addr, ifa->ifa_addr)) { 902 /* exact match */ 903 break; 904 } 905 cp = addr->sa_data; 906 cp2 = ifa->ifa_addr->sa_data; 907 cp3 = ifa->ifa_netmask->sa_data; 908 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 909 for (; cp3 < cplim; cp3++) 910 if ((*cp++ ^ *cp2++) & *cp3) 911 break; 912 if (cp3 == cplim) { 913 /* subnet match */ 914 if (better_ifa_maybe == NULL) { 915 better_ifa_maybe = ifa; 916 } 917 } 918 } 919 } 920 921 if (ifa == NULL) { 922 if (better_ifa_maybe != NULL) { 923 ifa = better_ifa_maybe; 924 } else { 925 ifa = ifa_maybe; 926 } 927 } 928 if (ifa) ifaref(ifa); 929 930 ifnet_lock_done(ifp); 931 return ifa; 932} 933 934#include <net/route.h> 935 936/* 937 * Default action when installing a route with a Link Level gateway. 938 * Lookup an appropriate real ifa to point to. 939 * This should be moved to /sys/net/link.c eventually. 940 */ 941void 942link_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa) 943{ 944 struct ifaddr *ifa; 945 struct sockaddr *dst; 946 struct ifnet *ifp; 947 948 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 949 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 950 return; 951 ifa = ifaof_ifpforaddr(dst, ifp); 952 if (ifa) { 953 rtsetifa(rt, ifa); 954 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 955 ifa->ifa_rtrequest(cmd, rt, sa); 956 ifafree(ifa); 957 } 958} 959 960/* 961 * if_updown will set the interface up or down. It will 962 * prevent other up/down events from occurring until this 963 * up/down event has completed. 964 * 965 * Caller must lock ifnet. This function will drop the 966 * lock. This allows ifnet_set_flags to set the rest of 967 * the flags after we change the up/down state without 968 * dropping the interface lock between setting the 969 * up/down state and updating the rest of the flags. 970 */ 971__private_extern__ void 972if_updown( 973 struct ifnet *ifp, 974 int up) 975{ 976 int i; 977 struct ifaddr **ifa; 978 struct timespec tv; 979 980 /* Wait until no one else is changing the up/down state */ 981 while ((ifp->if_eflags & IFEF_UPDOWNCHANGE) != 0) { 982 tv.tv_sec = 0; 983 tv.tv_nsec = NSEC_PER_SEC / 10; 984 ifnet_lock_done(ifp); 985 msleep(&ifp->if_eflags, NULL, 0, "if_updown", &tv); 986 ifnet_lock_exclusive(ifp); 987 } 988 989 /* Verify that the interface isn't already in the right state */ 990 if ((!up && (ifp->if_flags & IFF_UP) == 0) || 991 (up && (ifp->if_flags & IFF_UP) == IFF_UP)) { 992 return; 993 } 994 995 /* Indicate that the up/down state is changing */ 996 ifp->if_eflags |= IFEF_UPDOWNCHANGE; 997 998 /* Mark interface up or down */ 999 if (up) { 1000 ifp->if_flags |= IFF_UP; 1001 } 1002 else { 1003 ifp->if_flags &= ~IFF_UP; 1004 } 1005 1006 ifnet_touch_lastchange(ifp); 1007 1008 /* Drop the lock to notify addresses and route */ 1009 ifnet_lock_done(ifp); 1010 if (ifnet_get_address_list(ifp, &ifa) == 0) { 1011 for (i = 0; ifa[i] != 0; i++) { 1012 pfctlinput(up ? PRC_IFUP : PRC_IFDOWN, ifa[i]->ifa_addr); 1013 } 1014 ifnet_free_address_list(ifa); 1015 } 1016 rt_ifmsg(ifp); 1017 1018 /* Aquire the lock to clear the changing flag and flush the send queue */ 1019 ifnet_lock_exclusive(ifp); 1020 if (!up) 1021 if_qflush(&ifp->if_snd); 1022 ifp->if_eflags &= ~IFEF_UPDOWNCHANGE; 1023 wakeup(&ifp->if_eflags); 1024 1025 return; 1026} 1027 1028/* 1029 * Mark an interface down and notify protocols of 1030 * the transition. 1031 */ 1032void 1033if_down( 1034 struct ifnet *ifp) 1035{ 1036 ifnet_lock_exclusive(ifp); 1037 if_updown(ifp, 0); 1038 ifnet_lock_done(ifp); 1039} 1040 1041/* 1042 * Mark an interface up and notify protocols of 1043 * the transition. 1044 */ 1045void 1046if_up( 1047 struct ifnet *ifp) 1048{ 1049 ifnet_lock_exclusive(ifp); 1050 if_updown(ifp, 1); 1051 ifnet_lock_done(ifp); 1052} 1053 1054/* 1055 * Flush an interface queue. 1056 */ 1057static void 1058if_qflush(struct ifqueue *ifq) 1059{ 1060 struct mbuf *m, *n; 1061 1062 n = ifq->ifq_head; 1063 while ((m = n) != 0) { 1064 n = m->m_act; 1065 m_freem(m); 1066 } 1067 ifq->ifq_head = NULL; 1068 ifq->ifq_tail = NULL; 1069 ifq->ifq_len = 0; 1070} 1071 1072/* 1073 * Map interface name to 1074 * interface structure pointer. 1075 */ 1076struct ifnet * 1077ifunit(const char *name) 1078{ 1079 char namebuf[IFNAMSIZ + 1]; 1080 const char *cp; 1081 struct ifnet *ifp; 1082 int unit; 1083 unsigned len, m; 1084 char c; 1085 1086 len = strlen(name); 1087 if (len < 2 || len > IFNAMSIZ) 1088 return NULL; 1089 cp = name + len - 1; 1090 c = *cp; 1091 if (c < '0' || c > '9') 1092 return NULL; /* trailing garbage */ 1093 unit = 0; 1094 m = 1; 1095 do { 1096 if (cp == name) 1097 return NULL; /* no interface name */ 1098 unit += (c - '0') * m; 1099 if (unit > 1000000) 1100 return NULL; /* number is unreasonable */ 1101 m *= 10; 1102 c = *--cp; 1103 } while (c >= '0' && c <= '9'); 1104 len = cp - name + 1; 1105 bcopy(name, namebuf, len); 1106 namebuf[len] = '\0'; 1107 /* 1108 * Now search all the interfaces for this name/number 1109 */ 1110 ifnet_head_lock_shared(); 1111 TAILQ_FOREACH(ifp, &ifnet_head, if_link) { 1112 if (strncmp(ifp->if_name, namebuf, len)) 1113 continue; 1114 if (unit == ifp->if_unit) 1115 break; 1116 } 1117 ifnet_head_done(); 1118 return (ifp); 1119} 1120 1121 1122/* 1123 * Map interface name in a sockaddr_dl to 1124 * interface structure pointer. 1125 */ 1126struct ifnet * 1127if_withname(struct sockaddr *sa) 1128{ 1129 char ifname[IFNAMSIZ+1]; 1130 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; 1131 1132 if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) || 1133 (sdl->sdl_nlen > IFNAMSIZ) ) 1134 return NULL; 1135 1136 /* 1137 * ifunit wants a null-terminated name. It may not be null-terminated 1138 * in the sockaddr. We don't want to change the caller's sockaddr, 1139 * and there might not be room to put the trailing null anyway, so we 1140 * make a local copy that we know we can null terminate safely. 1141 */ 1142 1143 bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen); 1144 ifname[sdl->sdl_nlen] = '\0'; 1145 return ifunit(ifname); 1146} 1147 1148 1149/* 1150 * Interface ioctls. 1151 */ 1152int 1153ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) 1154{ 1155 struct ifnet *ifp; 1156 struct ifreq *ifr; 1157 struct ifstat *ifs; 1158 int error = 0; 1159 short oif_flags; 1160 struct kev_msg ev_msg; 1161 struct net_event_data ev_data; 1162 1163 switch (cmd) { 1164 case SIOCGIFCONF: 1165 case OSIOCGIFCONF: 1166 case SIOCGIFCONF64: 1167 { 1168 struct ifconf64 * ifc = (struct ifconf64 *)data; 1169 user_addr_t user_addr; 1170 1171 user_addr = proc_is64bit(p) 1172 ? ifc->ifc_req64 : CAST_USER_ADDR_T(ifc->ifc_req); 1173 return (ifconf(cmd, user_addr, &ifc->ifc_len)); 1174 } 1175 break; 1176 } 1177 ifr = (struct ifreq *)data; 1178 switch (cmd) { 1179 case SIOCIFCREATE: 1180 case SIOCIFDESTROY: 1181 error = proc_suser(p); 1182 if (error) 1183 return (error); 1184 return ((cmd == SIOCIFCREATE) ? 1185 if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) : 1186 if_clone_destroy(ifr->ifr_name)); 1187#if IF_CLONE_LIST 1188 case SIOCIFGCLONERS: 1189 case SIOCIFGCLONERS64: 1190 { 1191 struct if_clonereq64 * ifcr = (struct if_clonereq64 *)data; 1192 user_addr = proc_is64bit(p) 1193 ? ifcr->ifcr_ifcru.ifcru_buffer64 1194 : CAST_USER_ADDR_T(ifcr->ifcr_ifcru.ifcru_buffer32); 1195 return (if_clone_list(ifcr->ifcr_count, &ifcr->ifcr_total, 1196 user_data)); 1197 } 1198#endif IF_CLONE_LIST 1199 } 1200 1201 ifp = ifunit(ifr->ifr_name); 1202 if (ifp == 0) 1203 return (ENXIO); 1204 switch (cmd) { 1205 1206 case SIOCGIFFLAGS: 1207 ifnet_lock_shared(ifp); 1208 ifr->ifr_flags = ifp->if_flags; 1209 ifnet_lock_done(ifp); 1210 break; 1211 1212#if CONFIG_MACF_NET 1213 case SIOCGIFMAC: 1214 error = mac_ifnet_label_get(kauth_cred_get(), ifr, ifp); 1215 if (error) 1216 return (error); 1217 break; 1218#endif 1219 case SIOCGIFMETRIC: 1220 ifnet_lock_shared(ifp); 1221 ifr->ifr_metric = ifp->if_metric; 1222 ifnet_lock_done(ifp); 1223 break; 1224 1225 case SIOCGIFMTU: 1226 ifnet_lock_shared(ifp); 1227 ifr->ifr_mtu = ifp->if_mtu; 1228 ifnet_lock_done(ifp); 1229 break; 1230 1231 case SIOCGIFPHYS: 1232 ifnet_lock_shared(ifp); 1233 ifr->ifr_phys = ifp->if_physical; 1234 ifnet_lock_done(ifp); 1235 break; 1236 1237 case SIOCSIFFLAGS: 1238 error = proc_suser(p); 1239 if (error) 1240 return (error); 1241 1242 ifnet_set_flags(ifp, ifr->ifr_flags, (u_int16_t)~IFF_CANTCHANGE); 1243 1244 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1245 cmd, data); 1246 1247 if (error == 0) { 1248 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1249 ev_msg.kev_class = KEV_NETWORK_CLASS; 1250 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 1251 1252 ev_msg.event_code = KEV_DL_SIFFLAGS; 1253 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 1254 ev_data.if_family = ifp->if_family; 1255 ev_data.if_unit = (unsigned long) ifp->if_unit; 1256 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 1257 ev_msg.dv[0].data_ptr = &ev_data; 1258 ev_msg.dv[1].data_length = 0; 1259 kev_post_msg(&ev_msg); 1260 } 1261 ifnet_touch_lastchange(ifp); 1262 break; 1263 1264#if CONFIG_MACF_NET 1265 case SIOCSIFMAC: 1266 error = mac_ifnet_label_set(kauth_cred_get(), ifr, ifp); 1267 if (error) 1268 return (error); 1269 break; 1270#endif 1271 case SIOCSIFMETRIC: 1272 error = proc_suser(p); 1273 if (error) 1274 return (error); 1275 ifp->if_metric = ifr->ifr_metric; 1276 1277 1278 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1279 ev_msg.kev_class = KEV_NETWORK_CLASS; 1280 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 1281 1282 ev_msg.event_code = KEV_DL_SIFMETRICS; 1283 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 1284 ev_data.if_family = ifp->if_family; 1285 ev_data.if_unit = (unsigned long) ifp->if_unit; 1286 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 1287 ev_msg.dv[0].data_ptr = &ev_data; 1288 1289 ev_msg.dv[1].data_length = 0; 1290 kev_post_msg(&ev_msg); 1291 1292 ifnet_touch_lastchange(ifp); 1293 break; 1294 1295 case SIOCSIFPHYS: 1296 error = proc_suser(p); 1297 if (error) 1298 return error; 1299 1300 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1301 cmd, data); 1302 1303 if (error == 0) { 1304 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1305 ev_msg.kev_class = KEV_NETWORK_CLASS; 1306 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 1307 1308 ev_msg.event_code = KEV_DL_SIFPHYS; 1309 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 1310 ev_data.if_family = ifp->if_family; 1311 ev_data.if_unit = (unsigned long) ifp->if_unit; 1312 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 1313 ev_msg.dv[0].data_ptr = &ev_data; 1314 ev_msg.dv[1].data_length = 0; 1315 kev_post_msg(&ev_msg); 1316 1317 ifnet_touch_lastchange(ifp); 1318 } 1319 return(error); 1320 1321 case SIOCSIFMTU: 1322 { 1323 u_long oldmtu = ifp->if_mtu; 1324 1325 error = proc_suser(p); 1326 if (error) 1327 return (error); 1328 if (ifp->if_ioctl == NULL) 1329 return (EOPNOTSUPP); 1330 if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU) 1331 return (EINVAL); 1332 1333 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1334 cmd, data); 1335 1336 if (error == 0) { 1337 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1338 ev_msg.kev_class = KEV_NETWORK_CLASS; 1339 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 1340 1341 ev_msg.event_code = KEV_DL_SIFMTU; 1342 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 1343 ev_data.if_family = ifp->if_family; 1344 ev_data.if_unit = (unsigned long) ifp->if_unit; 1345 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 1346 ev_msg.dv[0].data_ptr = &ev_data; 1347 ev_msg.dv[1].data_length = 0; 1348 kev_post_msg(&ev_msg); 1349 1350 ifnet_touch_lastchange(ifp); 1351 rt_ifmsg(ifp); 1352 } 1353 /* 1354 * If the link MTU changed, do network layer specific procedure 1355 * and update all route entries associated with the interface, 1356 * so that their MTU metric gets updated. 1357 */ 1358 if (error == 0 && ifp->if_mtu != oldmtu) { 1359 if_rtmtu_update(ifp); 1360#if INET6 1361 nd6_setmtu(ifp); 1362#endif 1363 } 1364 return (error); 1365 } 1366 1367 case SIOCADDMULTI: 1368 case SIOCDELMULTI: 1369 error = proc_suser(p); 1370 if (error) 1371 return (error); 1372 1373 /* Don't allow group membership on non-multicast interfaces. */ 1374 if ((ifp->if_flags & IFF_MULTICAST) == 0) 1375 return EOPNOTSUPP; 1376 1377#ifndef __APPLE__ 1378 /* Don't let users screw up protocols' entries. */ 1379 if (ifr->ifr_addr.sa_family != AF_LINK) 1380 return EINVAL; 1381#endif 1382 1383 if (cmd == SIOCADDMULTI) { 1384 error = if_addmulti(ifp, &ifr->ifr_addr, NULL); 1385 ev_msg.event_code = KEV_DL_ADDMULTI; 1386 } else { 1387 error = if_delmulti(ifp, &ifr->ifr_addr); 1388 ev_msg.event_code = KEV_DL_DELMULTI; 1389 } 1390 if (error == 0) { 1391 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1392 ev_msg.kev_class = KEV_NETWORK_CLASS; 1393 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 1394 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 1395 1396 ev_data.if_family = ifp->if_family; 1397 ev_data.if_unit = (unsigned long) ifp->if_unit; 1398 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 1399 ev_msg.dv[0].data_ptr = &ev_data; 1400 ev_msg.dv[1].data_length = 0; 1401 kev_post_msg(&ev_msg); 1402 1403 ifnet_touch_lastchange(ifp); 1404 } 1405 return error; 1406 1407 case SIOCSIFPHYADDR: 1408 case SIOCDIFPHYADDR: 1409#if INET6 1410 case SIOCSIFPHYADDR_IN6: 1411#endif 1412 case SIOCSLIFPHYADDR: 1413 case SIOCSIFMEDIA: 1414 case SIOCSIFGENERIC: 1415 case SIOCSIFLLADDR: 1416 case SIOCSIFALTMTU: 1417 case SIOCSIFVLAN: 1418 case SIOCSIFBOND: 1419 error = proc_suser(p); 1420 if (error) 1421 return (error); 1422 1423 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1424 cmd, data); 1425 1426 if (error == 0) 1427 ifnet_touch_lastchange(ifp); 1428 return error; 1429 1430 case SIOCGIFSTATUS: 1431 ifs = (struct ifstat *)data; 1432 ifs->ascii[0] = '\0'; 1433 1434 case SIOCGIFPSRCADDR: 1435 case SIOCGIFPDSTADDR: 1436 case SIOCGLIFPHYADDR: 1437 case SIOCGIFMEDIA: 1438 case SIOCGIFGENERIC: 1439 case SIOCGIFDEVMTU: 1440 return ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1441 cmd, data); 1442 case SIOCGIFVLAN: 1443 case SIOCGIFBOND: 1444 return ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1445 cmd, data); 1446 1447 default: 1448 oif_flags = ifp->if_flags; 1449 if (so->so_proto == 0) 1450 return (EOPNOTSUPP); 1451 { 1452 int ocmd = cmd; 1453 1454 switch (cmd) { 1455 1456 case SIOCSIFDSTADDR: 1457 case SIOCSIFADDR: 1458 case SIOCSIFBRDADDR: 1459 case SIOCSIFNETMASK: 1460#if BYTE_ORDER != BIG_ENDIAN 1461 if (ifr->ifr_addr.sa_family == 0 && 1462 ifr->ifr_addr.sa_len < 16) { 1463 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 1464 ifr->ifr_addr.sa_len = 16; 1465 } 1466#else 1467 if (ifr->ifr_addr.sa_len == 0) 1468 ifr->ifr_addr.sa_len = 16; 1469#endif 1470 break; 1471 1472 case OSIOCGIFADDR: 1473 cmd = SIOCGIFADDR; 1474 break; 1475 1476 case OSIOCGIFDSTADDR: 1477 cmd = SIOCGIFDSTADDR; 1478 break; 1479 1480 case OSIOCGIFBRDADDR: 1481 cmd = SIOCGIFBRDADDR; 1482 break; 1483 1484 case OSIOCGIFNETMASK: 1485 cmd = SIOCGIFNETMASK; 1486 } 1487 socket_lock(so, 1); 1488 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, 1489 data, ifp, p)); 1490 socket_unlock(so, 1); 1491 switch (ocmd) { 1492 1493 case OSIOCGIFADDR: 1494 case OSIOCGIFDSTADDR: 1495 case OSIOCGIFBRDADDR: 1496 case OSIOCGIFNETMASK: 1497 *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 1498 1499 } 1500 } 1501 if (cmd == SIOCSIFKPI) { 1502 int temperr = proc_suser(p); 1503 if (temperr != 0) 1504 error = temperr; 1505 } 1506 1507 if (error == EOPNOTSUPP || error == ENOTSUP) 1508 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1509 cmd, data); 1510 1511 return (error); 1512 } 1513 return (0); 1514} 1515 1516int 1517ifioctllocked(struct socket *so, u_long cmd, caddr_t data, struct proc *p) 1518{ 1519 int error; 1520 1521 socket_unlock(so, 0); 1522 error = ifioctl(so, cmd, data, p); 1523 socket_lock(so, 0); 1524 return(error); 1525} 1526 1527/* 1528 * Set/clear promiscuous mode on interface ifp based on the truth value 1529 * of pswitch. The calls are reference counted so that only the first 1530 * "on" request actually has an effect, as does the final "off" request. 1531 * Results are undefined if the "off" and "on" requests are not matched. 1532 */ 1533errno_t 1534ifnet_set_promiscuous( 1535 ifnet_t ifp, 1536 int pswitch) 1537{ 1538 struct ifreq ifr; 1539 int error = 0; 1540 int oldflags; 1541 int locked = 0; 1542 int changed = 0; 1543 1544 ifnet_lock_exclusive(ifp); 1545 locked = 1; 1546 oldflags = ifp->if_flags; 1547 if (pswitch) { 1548 /* 1549 * If the device is not configured up, we cannot put it in 1550 * promiscuous mode. 1551 */ 1552 if ((ifp->if_flags & IFF_UP) == 0) { 1553 error = ENETDOWN; 1554 goto done; 1555 } 1556 if (ifp->if_pcount++ != 0) { 1557 goto done; 1558 } 1559 ifp->if_flags |= IFF_PROMISC; 1560 } else { 1561 if (--ifp->if_pcount > 0) 1562 goto done; 1563 ifp->if_flags &= ~IFF_PROMISC; 1564 } 1565 ifr.ifr_flags = ifp->if_flags; 1566 locked = 0; 1567 ifnet_lock_done(ifp); 1568 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, &ifr); 1569 if (error == 0) 1570 rt_ifmsg(ifp); 1571 else 1572 ifp->if_flags = oldflags; 1573done: 1574 if (locked) ifnet_lock_done(ifp); 1575 if (changed) { 1576 log(LOG_INFO, "%s%d: promiscuous mode %s\n", 1577 ifp->if_name, ifp->if_unit, 1578 pswitch != 0 ? "enabled" : "disabled"); 1579 } 1580 return error; 1581} 1582 1583/* 1584 * Return interface configuration 1585 * of system. List may be used 1586 * in later ioctl's (above) to get 1587 * other information. 1588 */ 1589/*ARGSUSED*/ 1590static int 1591ifconf(u_long cmd, user_addr_t ifrp, int * ret_space) 1592{ 1593 struct ifnet *ifp = NULL; 1594 struct ifaddr *ifa; 1595 struct ifreq ifr; 1596 int error = 0; 1597 size_t space; 1598 1599 /* 1600 * Zero the ifr buffer to make sure we don't 1601 * disclose the contents of the stack. 1602 */ 1603 bzero(&ifr, sizeof(struct ifreq)); 1604 1605 space = *ret_space; 1606 ifnet_head_lock_shared(); 1607 for (ifp = ifnet_head.tqh_first; space > sizeof(ifr) && ifp; ifp = ifp->if_link.tqe_next) { 1608 char workbuf[64]; 1609 size_t ifnlen, addrs; 1610 1611 ifnlen = snprintf(workbuf, sizeof(workbuf), 1612 "%s%d", ifp->if_name, ifp->if_unit); 1613 if(ifnlen + 1 > sizeof ifr.ifr_name) { 1614 error = ENAMETOOLONG; 1615 break; 1616 } else { 1617 strlcpy(ifr.ifr_name, workbuf, IFNAMSIZ); 1618 } 1619 1620 ifnet_lock_shared(ifp); 1621 1622 addrs = 0; 1623 ifa = ifp->if_addrhead.tqh_first; 1624 for ( ; space > sizeof (ifr) && ifa; 1625 ifa = ifa->ifa_link.tqe_next) { 1626 struct sockaddr *sa = ifa->ifa_addr; 1627#ifndef __APPLE__ 1628 if (curproc->p_prison && prison_if(curproc, sa)) 1629 continue; 1630#endif 1631 addrs++; 1632 if (cmd == OSIOCGIFCONF) { 1633 struct osockaddr *osa = 1634 (struct osockaddr *)&ifr.ifr_addr; 1635 ifr.ifr_addr = *sa; 1636 osa->sa_family = sa->sa_family; 1637 error = copyout((caddr_t)&ifr, ifrp, sizeof(ifr)); 1638 ifrp += sizeof(struct ifreq); 1639 } else if (sa->sa_len <= sizeof(*sa)) { 1640 ifr.ifr_addr = *sa; 1641 error = copyout((caddr_t)&ifr, ifrp, sizeof(ifr)); 1642 ifrp += sizeof(struct ifreq); 1643 } else { 1644 if (space < sizeof (ifr) + sa->sa_len - sizeof(*sa)) 1645 break; 1646 space -= sa->sa_len - sizeof(*sa); 1647 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr.ifr_name)); 1648 if (error == 0) { 1649 error = copyout((caddr_t)sa, 1650 (ifrp + offsetof(struct ifreq, ifr_addr)), 1651 sa->sa_len); 1652 } 1653 ifrp += (sa->sa_len + offsetof(struct ifreq, ifr_addr)); 1654 } 1655 if (error) 1656 break; 1657 space -= sizeof (ifr); 1658 } 1659 ifnet_lock_done(ifp); 1660 1661 if (error) 1662 break; 1663 if (!addrs) { 1664 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 1665 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr)); 1666 if (error) 1667 break; 1668 space -= sizeof (ifr); 1669 ifrp += sizeof(struct ifreq); 1670 } 1671 } 1672 ifnet_head_done(); 1673 *ret_space -= space; 1674 return (error); 1675} 1676 1677/* 1678 * Just like if_promisc(), but for all-multicast-reception mode. 1679 */ 1680int 1681if_allmulti(struct ifnet *ifp, int onswitch) 1682{ 1683 int error = 0; 1684 int modified = 0; 1685 1686 ifnet_lock_exclusive(ifp); 1687 1688 if (onswitch) { 1689 if (ifp->if_amcount++ == 0) { 1690 ifp->if_flags |= IFF_ALLMULTI; 1691 modified = 1; 1692 } 1693 } else { 1694 if (ifp->if_amcount > 1) { 1695 ifp->if_amcount--; 1696 } else { 1697 ifp->if_amcount = 0; 1698 ifp->if_flags &= ~IFF_ALLMULTI; 1699 modified = 1; 1700 } 1701 } 1702 ifnet_lock_done(ifp); 1703 1704 if (modified) 1705 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL); 1706 1707 if (error == 0) 1708 rt_ifmsg(ifp); 1709 return error; 1710} 1711 1712void 1713ifma_reference( 1714 struct ifmultiaddr *ifma) 1715{ 1716 if (OSIncrementAtomic((SInt32 *)&ifma->ifma_refcount) <= 0) 1717 panic("ifma_reference: ifma already released or invalid\n"); 1718} 1719 1720void 1721ifma_release( 1722 struct ifmultiaddr *ifma) 1723{ 1724 while (ifma) { 1725 struct ifmultiaddr *next; 1726 int32_t prevValue = OSDecrementAtomic((SInt32 *)&ifma->ifma_refcount); 1727 if (prevValue < 1) 1728 panic("ifma_release: ifma already released or invalid\n"); 1729 if (prevValue != 1) 1730 break; 1731 1732 /* Allow the allocator of the protospec to free it */ 1733 if (ifma->ifma_protospec && ifma->ifma_free) { 1734 ifma->ifma_free(ifma->ifma_protospec); 1735 } 1736 1737 next = ifma->ifma_ll; 1738 FREE(ifma->ifma_addr, M_IFMADDR); 1739 FREE(ifma, M_IFMADDR); 1740 ifma = next; 1741 } 1742} 1743 1744 /* 1745 * Find an ifmultiaddr that matches a socket address on an interface. 1746 * 1747 * Caller is responsible for holding the ifnet_lock while calling 1748 * this function. 1749 */ 1750static int 1751if_addmulti_doesexist( 1752 struct ifnet *ifp, 1753 const struct sockaddr *sa, 1754 struct ifmultiaddr **retifma) 1755{ 1756 struct ifmultiaddr *ifma; 1757 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 1758 ifma = ifma->ifma_link.le_next) { 1759 if (equal(sa, ifma->ifma_addr)) { 1760 ifma->ifma_usecount++; 1761 if (retifma) { 1762 *retifma = ifma; 1763 ifma_reference(*retifma); 1764 } 1765 return 0; 1766 } 1767 } 1768 1769 return ENOENT; 1770} 1771 1772/* 1773 * Radar 3642395, make sure all multicasts are in a standard format. 1774 */ 1775static struct sockaddr* 1776copy_and_normalize( 1777 const struct sockaddr *original) 1778{ 1779 int alen = 0; 1780 const u_char *aptr = NULL; 1781 struct sockaddr *copy = NULL; 1782 struct sockaddr_dl *sdl_new = NULL; 1783 int len = 0; 1784 1785 if (original->sa_family != AF_LINK && 1786 original->sa_family != AF_UNSPEC) { 1787 /* Just make a copy */ 1788 MALLOC(copy, struct sockaddr*, original->sa_len, M_IFADDR, M_WAITOK); 1789 if (copy != NULL) 1790 bcopy(original, copy, original->sa_len); 1791 return copy; 1792 } 1793 1794 switch (original->sa_family) { 1795 case AF_LINK: { 1796 const struct sockaddr_dl *sdl_original = 1797 (const struct sockaddr_dl*)original; 1798 1799 if (sdl_original->sdl_nlen + sdl_original->sdl_alen + sdl_original->sdl_slen + 1800 offsetof(struct sockaddr_dl, sdl_data) > sdl_original->sdl_len) 1801 return NULL; 1802 1803 alen = sdl_original->sdl_alen; 1804 aptr = CONST_LLADDR(sdl_original); 1805 } 1806 break; 1807 1808 case AF_UNSPEC: { 1809 if (original->sa_len < ETHER_ADDR_LEN + 1810 offsetof(struct sockaddr, sa_data)) { 1811 return NULL; 1812 } 1813 1814 alen = ETHER_ADDR_LEN; 1815 aptr = (const u_char*)original->sa_data; 1816 } 1817 break; 1818 } 1819 1820 if (alen == 0 || aptr == NULL) 1821 return NULL; 1822 1823 len = alen + offsetof(struct sockaddr_dl, sdl_data); 1824 MALLOC(sdl_new, struct sockaddr_dl*, len, M_IFADDR, M_WAITOK); 1825 1826 if (sdl_new != NULL) { 1827 bzero(sdl_new, len); 1828 sdl_new->sdl_len = len; 1829 sdl_new->sdl_family = AF_LINK; 1830 sdl_new->sdl_alen = alen; 1831 bcopy(aptr, LLADDR(sdl_new), alen); 1832 } 1833 1834 return (struct sockaddr*)sdl_new; 1835} 1836 1837/* 1838 * Add a multicast listenership to the interface in question. 1839 * The link layer provides a routine which converts 1840 */ 1841int 1842if_addmulti( 1843 struct ifnet *ifp, /* interface to manipulate */ 1844 const struct sockaddr *sa, /* address to add */ 1845 struct ifmultiaddr **retifma) 1846{ 1847 struct sockaddr_storage storage; 1848 struct sockaddr *llsa = NULL; 1849 struct sockaddr *dupsa = NULL; 1850 int error = 0; 1851 struct ifmultiaddr *ifma = NULL; 1852 struct ifmultiaddr *llifma = NULL; 1853 1854 /* If sa is a AF_LINK or AF_UNSPEC, duplicate and normalize it */ 1855 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) { 1856 dupsa = copy_and_normalize(sa); 1857 if (dupsa == NULL) { 1858 return ENOMEM; 1859 } 1860 sa = dupsa; 1861 } 1862 1863 ifnet_lock_exclusive(ifp); 1864 error = if_addmulti_doesexist(ifp, sa, retifma); 1865 ifnet_lock_done(ifp); 1866 1867 if (error == 0) { 1868 goto cleanup; 1869 } 1870 1871 /* 1872 * Give the link layer a chance to accept/reject it, and also 1873 * find out which AF_LINK address this maps to, if it isn't one 1874 * already. 1875 */ 1876 error = dlil_resolve_multi(ifp, sa, (struct sockaddr*)&storage, 1877 sizeof(storage)); 1878 if (error == 0 && storage.ss_len != 0) { 1879 llsa = copy_and_normalize((struct sockaddr*)&storage); 1880 if (llsa == NULL) { 1881 error = ENOMEM; 1882 goto cleanup; 1883 } 1884 1885 MALLOC(llifma, struct ifmultiaddr *, sizeof *llifma, M_IFMADDR, M_WAITOK); 1886 if (llifma == NULL) { 1887 error = ENOMEM; 1888 goto cleanup; 1889 } 1890 } 1891 1892 /* to be similar to FreeBSD */ 1893 if (error == EOPNOTSUPP) { 1894 error = 0; 1895 } 1896 else if (error) { 1897 goto cleanup; 1898 } 1899 1900 /* Allocate while we aren't holding any locks */ 1901 if (dupsa == NULL) { 1902 dupsa = copy_and_normalize(sa); 1903 if (dupsa == NULL) { 1904 error = ENOMEM; 1905 goto cleanup; 1906 } 1907 } 1908 MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, M_IFMADDR, M_WAITOK); 1909 if (ifma == NULL) { 1910 error = ENOMEM; 1911 goto cleanup; 1912 } 1913 1914 ifnet_lock_exclusive(ifp); 1915 /* 1916 * Check again for the matching multicast. 1917 */ 1918 if ((error = if_addmulti_doesexist(ifp, sa, retifma)) == 0) { 1919 ifnet_lock_done(ifp); 1920 goto cleanup; 1921 } 1922 1923 bzero(ifma, sizeof(*ifma)); 1924 ifma->ifma_addr = dupsa; 1925 ifma->ifma_ifp = ifp; 1926 ifma->ifma_usecount = 1; 1927 ifma->ifma_refcount = 1; 1928 1929 if (llifma != 0) { 1930 if (if_addmulti_doesexist(ifp, llsa, &ifma->ifma_ll) == 0) { 1931 FREE(llsa, M_IFMADDR); 1932 FREE(llifma, M_IFMADDR); 1933 } else { 1934 bzero(llifma, sizeof(*llifma)); 1935 llifma->ifma_addr = llsa; 1936 llifma->ifma_ifp = ifp; 1937 llifma->ifma_usecount = 1; 1938 llifma->ifma_refcount = 1; 1939 LIST_INSERT_HEAD(&ifp->if_multiaddrs, llifma, ifma_link); 1940 1941 ifma->ifma_ll = llifma; 1942 ifma_reference(ifma->ifma_ll); 1943 } 1944 } 1945 1946 LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link); 1947 1948 if (retifma) { 1949 *retifma = ifma; 1950 ifma_reference(*retifma); 1951 } 1952 1953 ifnet_lock_done(ifp); 1954 1955 if (llsa != 0) 1956 rt_newmaddrmsg(RTM_NEWMADDR, ifma); 1957 1958 /* 1959 * We are certain we have added something, so call down to the 1960 * interface to let them know about it. 1961 */ 1962 ifnet_ioctl(ifp, 0, SIOCADDMULTI, NULL); 1963 1964 return 0; 1965 1966cleanup: 1967 if (ifma) 1968 FREE(ifma, M_IFADDR); 1969 if (dupsa) 1970 FREE(dupsa, M_IFADDR); 1971 if (llifma) 1972 FREE(llifma, M_IFADDR); 1973 if (llsa) 1974 FREE(llsa, M_IFADDR); 1975 1976 return error; 1977} 1978 1979int 1980if_delmultiaddr( 1981 struct ifmultiaddr *ifma, 1982 int locked) 1983{ 1984 struct ifnet *ifp; 1985 int do_del_multi = 0; 1986 1987 ifp = ifma->ifma_ifp; 1988 1989 if (!locked && ifp) { 1990 ifnet_lock_exclusive(ifp); 1991 } 1992 1993 while (ifma != NULL) { 1994 struct ifmultiaddr *ll_ifma; 1995 1996 if (ifma->ifma_usecount > 1) { 1997 ifma->ifma_usecount--; 1998 break; 1999 } 2000 2001 if (ifp) 2002 LIST_REMOVE(ifma, ifma_link); 2003 2004 ll_ifma = ifma->ifma_ll; 2005 2006 if (ll_ifma) { /* send a routing msg for network addresses only */ 2007 if (ifp) 2008 ifnet_lock_done(ifp); 2009 rt_newmaddrmsg(RTM_DELMADDR, ifma); 2010 if (ifp) 2011 ifnet_lock_exclusive(ifp); 2012 } 2013 2014 /* 2015 * Make sure the interface driver is notified 2016 * in the case of a link layer mcast group being left. 2017 */ 2018 if (ll_ifma == 0) { 2019 if (ifp && ifma->ifma_addr->sa_family == AF_LINK) 2020 do_del_multi = 1; 2021 break; 2022 } 2023 2024 if (ifp) 2025 ifma_release(ifma); 2026 2027 ifma = ll_ifma; 2028 } 2029 2030 if (!locked && ifp) { 2031 /* This wasn't initially locked, we should unlock it */ 2032 ifnet_lock_done(ifp); 2033 } 2034 2035 if (do_del_multi) { 2036 if (locked) 2037 ifnet_lock_done(ifp); 2038 ifnet_ioctl(ifp, 0, SIOCDELMULTI, NULL); 2039 if (locked) 2040 ifnet_lock_exclusive(ifp); 2041 } 2042 2043 return 0; 2044} 2045 2046/* 2047 * Remove a reference to a multicast address on this interface. Yell 2048 * if the request does not match an existing membership. 2049 */ 2050int 2051if_delmulti( 2052 struct ifnet *ifp, 2053 const struct sockaddr *sa) 2054{ 2055 struct ifmultiaddr *ifma; 2056 struct sockaddr *dupsa = NULL; 2057 int retval = 0; 2058 2059 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) { 2060 dupsa = copy_and_normalize(sa); 2061 if (dupsa == NULL) { 2062 return ENOMEM; 2063 } 2064 sa = dupsa; 2065 } 2066 2067 ifnet_lock_exclusive(ifp); 2068 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 2069 ifma = ifma->ifma_link.le_next) 2070 if (equal(sa, ifma->ifma_addr)) 2071 break; 2072 if (ifma == 0) { 2073 ifnet_lock_done(ifp); 2074 if (dupsa) 2075 FREE(dupsa, M_IFADDR); 2076 return ENOENT; 2077 } 2078 2079 retval = if_delmultiaddr(ifma, 1); 2080 ifnet_lock_done(ifp); 2081 if (dupsa) 2082 FREE(dupsa, M_IFADDR); 2083 2084 return retval; 2085} 2086 2087 2088/* 2089 * We don't use if_setlladdr, our interfaces are responsible for 2090 * handling the SIOCSIFLLADDR ioctl. 2091 */ 2092#ifndef __APPLE__ 2093int 2094if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len) 2095{ 2096 ... 2097} 2098#endif 2099 2100struct ifmultiaddr * 2101ifmaof_ifpforaddr(const struct sockaddr *sa, struct ifnet *ifp) 2102{ 2103 struct ifmultiaddr *ifma; 2104 2105 ifnet_lock_shared(ifp); 2106 for (ifma = ifp->if_multiaddrs.lh_first; ifma; 2107 ifma = ifma->ifma_link.le_next) 2108 if (equal(ifma->ifma_addr, sa)) 2109 break; 2110 ifnet_lock_done(ifp); 2111 2112 return ifma; 2113} 2114 2115SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Link layers"); 2116SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Generic link-management"); 2117 2118 2119/* 2120 * Shutdown all network activity. Used boot() when halting 2121 * system. 2122 */ 2123int 2124if_down_all(void) 2125{ 2126 struct ifnet **ifp; 2127 u_int32_t count; 2128 u_int32_t i; 2129 2130 if (ifnet_list_get_all(IFNET_FAMILY_ANY, &ifp, &count) == 0) { 2131 for (i = 0; i < count; i++) { 2132 if_down(ifp[i]); 2133 dlil_proto_unplumb_all(ifp[i]); 2134 } 2135 ifnet_list_free(ifp); 2136 } 2137 2138 return 0; 2139} 2140 2141/* 2142 * Delete Routes for a Network Interface 2143 * 2144 * Called for each routing entry via the rnh->rnh_walktree() call above 2145 * to delete all route entries referencing a detaching network interface. 2146 * 2147 * Arguments: 2148 * rn pointer to node in the routing table 2149 * arg argument passed to rnh->rnh_walktree() - detaching interface 2150 * 2151 * Returns: 2152 * 0 successful 2153 * errno failed - reason indicated 2154 * 2155 */ 2156static int 2157if_rtdel( 2158 struct radix_node *rn, 2159 void *arg) 2160{ 2161 struct rtentry *rt = (struct rtentry *)rn; 2162 struct ifnet *ifp = arg; 2163 int err; 2164 2165 if (rt != NULL && rt->rt_ifp == ifp) { 2166 2167 /* 2168 * Protect (sorta) against walktree recursion problems 2169 * with cloned routes 2170 */ 2171 if ((rt->rt_flags & RTF_UP) == 0) 2172 return (0); 2173 2174 err = rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway, 2175 rt_mask(rt), rt->rt_flags, 2176 (struct rtentry **) NULL); 2177 if (err) { 2178 log(LOG_WARNING, "if_rtdel: error %d\n", err); 2179 } 2180 } 2181 2182 return (0); 2183} 2184 2185/* 2186 * Removes routing table reference to a given interfacei 2187 * for a given protocol family 2188 */ 2189void if_rtproto_del(struct ifnet *ifp, int protocol) 2190{ 2191 struct radix_node_head *rnh; 2192 if (use_routegenid) 2193 route_generation++; 2194 if ((protocol <= AF_MAX) && (protocol >= 0) && 2195 ((rnh = rt_tables[protocol]) != NULL) && (ifp != NULL)) { 2196 lck_mtx_lock(rt_mtx); 2197 (void) rnh->rnh_walktree(rnh, if_rtdel, ifp); 2198 lck_mtx_unlock(rt_mtx); 2199 } 2200} 2201 2202static int 2203if_rtmtu(struct radix_node *rn, void *arg) 2204{ 2205 struct rtentry *rt = (struct rtentry *)rn; 2206 struct ifnet *ifp = arg; 2207 2208 if (rt->rt_ifp == ifp) { 2209 /* 2210 * Update the MTU of this entry only if the MTU 2211 * has not been locked (RTV_MTU is not set) and 2212 * if it was non-zero to begin with. 2213 */ 2214 if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu) 2215 rt->rt_rmx.rmx_mtu = ifp->if_mtu; 2216 } 2217 2218 return (0); 2219} 2220 2221/* 2222 * Update the MTU metric of all route entries in all protocol tables 2223 * associated with a particular interface; this is called when the 2224 * MTU of that interface has changed. 2225 */ 2226static 2227void if_rtmtu_update(struct ifnet *ifp) 2228{ 2229 struct radix_node_head *rnh; 2230 int p; 2231 2232 for (p = 0; p < AF_MAX + 1; p++) { 2233 if ((rnh = rt_tables[p]) == NULL) 2234 continue; 2235 2236 lck_mtx_lock(rt_mtx); 2237 (void) rnh->rnh_walktree(rnh, if_rtmtu, ifp); 2238 lck_mtx_unlock(rt_mtx); 2239 } 2240 2241 if (use_routegenid) 2242 route_generation++; 2243} 2244 2245__private_extern__ void 2246if_data_internal_to_if_data( 2247 struct ifnet *ifp, 2248 const struct if_data_internal *if_data_int, 2249 struct if_data *if_data) 2250{ 2251 struct dlil_threading_info *thread; 2252 if ((thread = ifp->if_input_thread) == NULL || (dlil_multithreaded_input == 0)) 2253 thread = dlil_lo_thread_ptr; 2254 2255#define COPYFIELD(fld) if_data->fld = if_data_int->fld 2256#define COPYFIELD32(fld) if_data->fld = (u_int32_t)(if_data_int->fld) 2257 COPYFIELD(ifi_type); 2258 COPYFIELD(ifi_typelen); 2259 COPYFIELD(ifi_physical); 2260 COPYFIELD(ifi_addrlen); 2261 COPYFIELD(ifi_hdrlen); 2262 COPYFIELD(ifi_recvquota); 2263 COPYFIELD(ifi_xmitquota); 2264 if_data->ifi_unused1 = 0; 2265 COPYFIELD(ifi_mtu); 2266 COPYFIELD(ifi_metric); 2267 if (if_data_int->ifi_baudrate & 0xFFFFFFFF00000000LL) { 2268 if_data->ifi_baudrate = 0xFFFFFFFF; 2269 } 2270 else { 2271 COPYFIELD32(ifi_baudrate); 2272 } 2273 2274 lck_mtx_lock(thread->input_lck); 2275 COPYFIELD32(ifi_ipackets); 2276 COPYFIELD32(ifi_ierrors); 2277 COPYFIELD32(ifi_opackets); 2278 COPYFIELD32(ifi_oerrors); 2279 COPYFIELD32(ifi_collisions); 2280 COPYFIELD32(ifi_ibytes); 2281 COPYFIELD32(ifi_obytes); 2282 COPYFIELD32(ifi_imcasts); 2283 COPYFIELD32(ifi_omcasts); 2284 COPYFIELD32(ifi_iqdrops); 2285 COPYFIELD32(ifi_noproto); 2286 COPYFIELD32(ifi_recvtiming); 2287 COPYFIELD32(ifi_xmittiming); 2288 COPYFIELD(ifi_lastchange); 2289 lck_mtx_unlock(thread->input_lck); 2290 2291#if IF_LASTCHANGEUPTIME 2292 if_data->ifi_lastchange.tv_sec += boottime_sec(); 2293#endif 2294 2295 if_data->ifi_unused2 = 0; 2296 COPYFIELD(ifi_hwassist); 2297 if_data->ifi_reserved1 = 0; 2298 if_data->ifi_reserved2 = 0; 2299#undef COPYFIELD32 2300#undef COPYFIELD 2301} 2302 2303__private_extern__ void 2304if_data_internal_to_if_data64( 2305 struct ifnet *ifp, 2306 const struct if_data_internal *if_data_int, 2307 struct if_data64 *if_data64) 2308{ 2309 struct dlil_threading_info *thread; 2310 if ((thread = ifp->if_input_thread) == NULL || (dlil_multithreaded_input == 0)) 2311 thread = dlil_lo_thread_ptr; 2312 2313#define COPYFIELD(fld) if_data64->fld = if_data_int->fld 2314 COPYFIELD(ifi_type); 2315 COPYFIELD(ifi_typelen); 2316 COPYFIELD(ifi_physical); 2317 COPYFIELD(ifi_addrlen); 2318 COPYFIELD(ifi_hdrlen); 2319 COPYFIELD(ifi_recvquota); 2320 COPYFIELD(ifi_xmitquota); 2321 if_data64->ifi_unused1 = 0; 2322 COPYFIELD(ifi_mtu); 2323 COPYFIELD(ifi_metric); 2324 COPYFIELD(ifi_baudrate); 2325 2326 lck_mtx_lock(thread->input_lck); 2327 COPYFIELD(ifi_ipackets); 2328 COPYFIELD(ifi_ierrors); 2329 COPYFIELD(ifi_opackets); 2330 COPYFIELD(ifi_oerrors); 2331 COPYFIELD(ifi_collisions); 2332 COPYFIELD(ifi_ibytes); 2333 COPYFIELD(ifi_obytes); 2334 COPYFIELD(ifi_imcasts); 2335 COPYFIELD(ifi_omcasts); 2336 COPYFIELD(ifi_iqdrops); 2337 COPYFIELD(ifi_noproto); 2338 COPYFIELD(ifi_recvtiming); 2339 COPYFIELD(ifi_xmittiming); 2340 COPYFIELD(ifi_lastchange); 2341 lck_mtx_unlock(thread->input_lck); 2342 2343#if IF_LASTCHANGEUPTIME 2344 if_data64->ifi_lastchange.tv_sec += boottime_sec(); 2345#endif 2346 2347#undef COPYFIELD 2348} 2349