1/* 2 * Copyright (c) 2000-2012 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#include <sys/mcache.h> 85#include <kern/zalloc.h> 86 87#include <machine/endian.h> 88 89#include <pexpert/pexpert.h> 90 91#include <net/if.h> 92#include <net/if_arp.h> 93#include <net/if_dl.h> 94#include <net/if_types.h> 95#include <net/if_var.h> 96#include <net/net_osdep.h> 97#include <net/ethernet.h> 98 99#include <net/radix.h> 100#include <net/route.h> 101#ifdef __APPLE__ 102#include <net/dlil.h> 103//#include <string.h> 104#include <sys/domain.h> 105#include <libkern/OSAtomic.h> 106#endif 107 108#if INET || INET6 109/*XXX*/ 110#include <netinet/in.h> 111#include <netinet/in_var.h> 112#include <netinet/ip_var.h> 113#include <netinet/ip6.h> 114#include <netinet/ip_var.h> 115#include <netinet/tcp.h> 116#include <netinet/tcp_var.h> 117#include <netinet/udp.h> 118#include <netinet/udp_var.h> 119#if INET6 120#include <netinet6/in6_var.h> 121#include <netinet6/in6_ifattach.h> 122#include <netinet6/ip6_var.h> 123#endif 124#endif 125 126#if CONFIG_MACF_NET 127#include <security/mac_framework.h> 128#endif 129 130#if PF_ALTQ 131#include <net/altq/if_altq.h> 132#endif /* !PF_ALTQ */ 133 134/* 135 * System initialization 136 */ 137 138/* Lock group and attribute for ifaddr lock */ 139lck_attr_t *ifa_mtx_attr; 140lck_grp_t *ifa_mtx_grp; 141static lck_grp_attr_t *ifa_mtx_grp_attr; 142 143static int ifioctl_ifreq(struct socket *, u_long, struct ifreq *, 144 struct proc *); 145static int ifconf(u_long cmd, user_addr_t ifrp, int * ret_space); 146__private_extern__ void link_rtrequest(int, struct rtentry *, struct sockaddr *); 147void if_rtproto_del(struct ifnet *ifp, int protocol); 148 149static int if_addmulti_common(struct ifnet *, const struct sockaddr *, 150 struct ifmultiaddr **, int); 151static int if_delmulti_common(struct ifmultiaddr *, struct ifnet *, 152 const struct sockaddr *, int); 153 154static int if_rtmtu(struct radix_node *, void *); 155static void if_rtmtu_update(struct ifnet *); 156 157#if IF_CLONE_LIST 158static int if_clone_list(int count, int * total, user_addr_t dst); 159#endif /* IF_CLONE_LIST */ 160 161MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); 162 163struct ifnethead ifnet_head = TAILQ_HEAD_INITIALIZER(ifnet_head); 164 165static int if_cloners_count; 166LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 167 168static struct ifaddr *ifa_ifwithnet_common(const struct sockaddr *, 169 unsigned int); 170static void if_attach_ifa_common(struct ifnet *, struct ifaddr *, int); 171static void if_detach_ifa_common(struct ifnet *, struct ifaddr *, int); 172 173static void if_attach_ifma(struct ifnet *, struct ifmultiaddr *, int); 174static int if_detach_ifma(struct ifnet *, struct ifmultiaddr *, int); 175 176static struct ifmultiaddr *ifma_alloc(int); 177static void ifma_free(struct ifmultiaddr *); 178static void ifma_trace(struct ifmultiaddr *, int); 179 180#if DEBUG 181static unsigned int ifma_debug = 1; /* debugging (enabled) */ 182#else 183static unsigned int ifma_debug; /* debugging (disabled) */ 184#endif /* !DEBUG */ 185static unsigned int ifma_size; /* size of zone element */ 186static struct zone *ifma_zone; /* zone for ifmultiaddr */ 187 188#define IFMA_TRACE_HIST_SIZE 32 /* size of trace history */ 189 190/* For gdb */ 191__private_extern__ unsigned int ifma_trace_hist_size = IFMA_TRACE_HIST_SIZE; 192 193struct ifmultiaddr_dbg { 194 struct ifmultiaddr ifma; /* ifmultiaddr */ 195 u_int16_t ifma_refhold_cnt; /* # of ref */ 196 u_int16_t ifma_refrele_cnt; /* # of rele */ 197 /* 198 * Circular lists of IFA_ADDREF and IFA_REMREF callers. 199 */ 200 ctrace_t ifma_refhold[IFMA_TRACE_HIST_SIZE]; 201 ctrace_t ifma_refrele[IFMA_TRACE_HIST_SIZE]; 202 /* 203 * Trash list linkage 204 */ 205 TAILQ_ENTRY(ifmultiaddr_dbg) ifma_trash_link; 206}; 207 208/* List of trash ifmultiaddr entries protected by ifma_trash_lock */ 209static TAILQ_HEAD(, ifmultiaddr_dbg) ifma_trash_head; 210static decl_lck_mtx_data(, ifma_trash_lock); 211 212#define IFMA_ZONE_MAX 64 /* maximum elements in zone */ 213#define IFMA_ZONE_NAME "ifmultiaddr" /* zone name */ 214 215#if INET6 216/* 217 * XXX: declare here to avoid to include many inet6 related files.. 218 * should be more generalized? 219 */ 220extern void nd6_setmtu(struct ifnet *); 221extern lck_mtx_t *nd6_mutex; 222#endif 223 224 225void 226ifa_init(void) 227{ 228 /* Setup lock group and attribute for ifaddr */ 229 ifa_mtx_grp_attr = lck_grp_attr_alloc_init(); 230 ifa_mtx_grp = lck_grp_alloc_init("ifaddr", ifa_mtx_grp_attr); 231 ifa_mtx_attr = lck_attr_alloc_init(); 232 233 PE_parse_boot_argn("ifa_debug", &ifma_debug, sizeof (ifma_debug)); 234 235 ifma_size = (ifma_debug == 0) ? sizeof (struct ifmultiaddr) : 236 sizeof (struct ifmultiaddr_dbg); 237 238 ifma_zone = zinit(ifma_size, IFMA_ZONE_MAX * ifma_size, 0, 239 IFMA_ZONE_NAME); 240 if (ifma_zone == NULL) { 241 panic("%s: failed allocating %s", __func__, IFMA_ZONE_NAME); 242 /* NOTREACHED */ 243 } 244 zone_change(ifma_zone, Z_EXPAND, TRUE); 245 zone_change(ifma_zone, Z_CALLERACCT, FALSE); 246 247 lck_mtx_init(&ifma_trash_lock, ifa_mtx_grp, ifa_mtx_attr); 248 TAILQ_INIT(&ifma_trash_head); 249} 250 251/* 252 * Network interface utility routines. 253 * 254 * Routines with ifa_ifwith* names take sockaddr *'s as 255 * parameters. 256 */ 257 258int if_index; 259struct ifaddr **ifnet_addrs; 260struct ifnet **ifindex2ifnet; 261 262__private_extern__ void 263if_attach_ifa(struct ifnet *ifp, struct ifaddr *ifa) 264{ 265 if_attach_ifa_common(ifp, ifa, 0); 266} 267 268__private_extern__ void 269if_attach_link_ifa(struct ifnet *ifp, struct ifaddr *ifa) 270{ 271 if_attach_ifa_common(ifp, ifa, 1); 272} 273 274static void 275if_attach_ifa_common(struct ifnet *ifp, struct ifaddr *ifa, int link) 276{ 277 ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE); 278 IFA_LOCK_ASSERT_HELD(ifa); 279 280 if (ifa->ifa_ifp != ifp) { 281 panic("%s: Mismatch ifa_ifp=%p != ifp=%p", __func__, 282 ifa->ifa_ifp, ifp); 283 /* NOTREACHED */ 284 } else if (ifa->ifa_debug & IFD_ATTACHED) { 285 panic("%s: Attempt to attach an already attached ifa=%p", 286 __func__, ifa); 287 /* NOTREACHED */ 288 } else if (link && !(ifa->ifa_debug & IFD_LINK)) { 289 panic("%s: Unexpected non-link address ifa=%p", __func__, ifa); 290 /* NOTREACHED */ 291 } else if (!link && (ifa->ifa_debug & IFD_LINK)) { 292 panic("%s: Unexpected link address ifa=%p", __func__, ifa); 293 /* NOTREACHED */ 294 } 295 IFA_ADDREF_LOCKED(ifa); 296 ifa->ifa_debug |= IFD_ATTACHED; 297 if (link) 298 TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); 299 else 300 TAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link); 301 302 if (ifa->ifa_attached != NULL) 303 (*ifa->ifa_attached)(ifa); 304} 305 306__private_extern__ void 307if_detach_ifa(struct ifnet *ifp, struct ifaddr *ifa) 308{ 309 if_detach_ifa_common(ifp, ifa, 0); 310} 311 312__private_extern__ void 313if_detach_link_ifa(struct ifnet *ifp, struct ifaddr *ifa) 314{ 315 if_detach_ifa_common(ifp, ifa, 1); 316} 317 318static void 319if_detach_ifa_common(struct ifnet *ifp, struct ifaddr *ifa, int link) 320{ 321 ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE); 322 IFA_LOCK_ASSERT_HELD(ifa); 323 324 if (link && !(ifa->ifa_debug & IFD_LINK)) { 325 panic("%s: Unexpected non-link address ifa=%p", __func__, ifa); 326 /* NOTREACHED */ 327 } else if (link && ifa != TAILQ_FIRST(&ifp->if_addrhead)) { 328 panic("%s: Link address ifa=%p not first", __func__, ifa); 329 /* NOTREACHED */ 330 } else if (!link && (ifa->ifa_debug & IFD_LINK)) { 331 panic("%s: Unexpected link address ifa=%p", __func__, ifa); 332 /* NOTREACHED */ 333 } else if (!(ifa->ifa_debug & IFD_ATTACHED)) { 334 panic("%s: Attempt to detach an unattached address ifa=%p", 335 __func__, ifa); 336 /* NOTREACHED */ 337 } else if (ifa->ifa_ifp != ifp) { 338 panic("%s: Mismatch ifa_ifp=%p, ifp=%p", __func__, 339 ifa->ifa_ifp, ifp); 340 /* NOTREACHED */ 341 } else if (ifa->ifa_debug & IFD_DEBUG) { 342 struct ifaddr *ifa2; 343 TAILQ_FOREACH(ifa2, &ifp->if_addrhead, ifa_link) { 344 if (ifa2 == ifa) 345 break; 346 } 347 if (ifa2 != ifa) { 348 panic("%s: Attempt to detach a stray address ifa=%p", 349 __func__, ifa); 350 /* NOTREACHED */ 351 } 352 } 353 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); 354 /* This must not be the last reference to the ifaddr */ 355 if (IFA_REMREF_LOCKED(ifa) == NULL) { 356 panic("%s: unexpected (missing) refcnt ifa=%p", __func__, ifa); 357 /* NOTREACHED */ 358 } 359 ifa->ifa_debug &= ~IFD_ATTACHED; 360 361 if (ifa->ifa_detached != NULL) 362 (*ifa->ifa_detached)(ifa); 363} 364 365#define INITIAL_IF_INDEXLIM 8 366 367/* 368 * Function: if_next_index 369 * Purpose: 370 * Return the next available interface index. 371 * Grow the ifnet_addrs[] and ifindex2ifnet[] arrays to accomodate the 372 * added entry when necessary. 373 * 374 * Note: 375 * ifnet_addrs[] is indexed by (if_index - 1), whereas 376 * ifindex2ifnet[] is indexed by ifp->if_index. That requires us to 377 * always allocate one extra element to hold ifindex2ifnet[0], which 378 * is unused. 379 */ 380int if_next_index(void); 381 382__private_extern__ int 383if_next_index(void) 384{ 385 static int if_indexlim = 0; 386 int new_index; 387 388 new_index = ++if_index; 389 if (if_index > if_indexlim) { 390 unsigned n; 391 int new_if_indexlim; 392 caddr_t new_ifnet_addrs; 393 caddr_t new_ifindex2ifnet; 394 caddr_t old_ifnet_addrs; 395 396 old_ifnet_addrs = (caddr_t)ifnet_addrs; 397 if (ifnet_addrs == NULL) { 398 new_if_indexlim = INITIAL_IF_INDEXLIM; 399 } else { 400 new_if_indexlim = if_indexlim << 1; 401 } 402 403 /* allocate space for the larger arrays */ 404 n = (2 * new_if_indexlim + 1) * sizeof(caddr_t); 405 new_ifnet_addrs = _MALLOC(n, M_IFADDR, M_WAITOK); 406 if (new_ifnet_addrs == NULL) { 407 --if_index; 408 return -1; 409 } 410 411 new_ifindex2ifnet = new_ifnet_addrs 412 + new_if_indexlim * sizeof(caddr_t); 413 bzero(new_ifnet_addrs, n); 414 if (ifnet_addrs != NULL) { 415 /* copy the existing data */ 416 bcopy((caddr_t)ifnet_addrs, new_ifnet_addrs, 417 if_indexlim * sizeof(caddr_t)); 418 bcopy((caddr_t)ifindex2ifnet, 419 new_ifindex2ifnet, 420 (if_indexlim + 1) * sizeof(caddr_t)); 421 } 422 423 /* switch to the new tables and size */ 424 ifnet_addrs = (struct ifaddr **)(void *)new_ifnet_addrs; 425 ifindex2ifnet = (struct ifnet **)(void *)new_ifindex2ifnet; 426 if_indexlim = new_if_indexlim; 427 428 /* release the old data */ 429 if (old_ifnet_addrs != NULL) { 430 _FREE((caddr_t)old_ifnet_addrs, M_IFADDR); 431 } 432 } 433 return (new_index); 434} 435 436/* 437 * Create a clone network interface. 438 */ 439static int 440if_clone_create(char *name, int len, void *params) 441{ 442 struct if_clone *ifc; 443 char *dp; 444 int wildcard; 445 u_int32_t bytoff, bitoff; 446 u_int32_t unit; 447 int err; 448 449 ifc = if_clone_lookup(name, &unit); 450 if (ifc == NULL) 451 return (EINVAL); 452 453 if (ifunit(name) != NULL) 454 return (EEXIST); 455 456 bytoff = bitoff = 0; 457 wildcard = (unit == UINT32_MAX); 458 /* 459 * Find a free unit if none was given. 460 */ 461 if (wildcard) { 462 while ((bytoff < ifc->ifc_bmlen) 463 && (ifc->ifc_units[bytoff] == 0xff)) 464 bytoff++; 465 if (bytoff >= ifc->ifc_bmlen) 466 return (ENOSPC); 467 while ((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0) 468 bitoff++; 469 unit = (bytoff << 3) + bitoff; 470 } 471 472 if (unit > ifc->ifc_maxunit) 473 return (ENXIO); 474 475 err = (*ifc->ifc_create)(ifc, unit, params); 476 if (err != 0) 477 return (err); 478 479 if (!wildcard) { 480 bytoff = unit >> 3; 481 bitoff = unit - (bytoff << 3); 482 } 483 484 /* 485 * Allocate the unit in the bitmap. 486 */ 487 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) == 0, 488 ("%s: bit is already set", __func__)); 489 ifc->ifc_units[bytoff] |= (1 << bitoff); 490 491 /* In the wildcard case, we need to update the name. */ 492 if (wildcard) { 493 for (dp = name; *dp != '\0'; dp++); 494 if (snprintf(dp, len - (dp-name), "%d", unit) > 495 len - (dp-name) - 1) { 496 /* 497 * This can only be a programmer error and 498 * there's no straightforward way to recover if 499 * it happens. 500 */ 501 panic("%s: interface name too long", __func__); 502 /* NOTREACHED */ 503 } 504 505 } 506 507 return (0); 508} 509 510/* 511 * Destroy a clone network interface. 512 */ 513static int 514if_clone_destroy(const char *name) 515{ 516 struct if_clone *ifc; 517 struct ifnet *ifp; 518 int bytoff, bitoff; 519 u_int32_t unit; 520 521 ifc = if_clone_lookup(name, &unit); 522 if (ifc == NULL) 523 return (EINVAL); 524 525 if (unit < ifc->ifc_minifs) 526 return (EINVAL); 527 528 ifp = ifunit(name); 529 if (ifp == NULL) 530 return (ENXIO); 531 532 if (ifc->ifc_destroy == NULL) 533 return (EOPNOTSUPP); 534 535 (*ifc->ifc_destroy)(ifp); 536 537 /* 538 * Compute offset in the bitmap and deallocate the unit. 539 */ 540 bytoff = unit >> 3; 541 bitoff = unit - (bytoff << 3); 542 KASSERT((ifc->ifc_units[bytoff] & (1 << bitoff)) != 0, 543 ("%s: bit is already cleared", __func__)); 544 ifc->ifc_units[bytoff] &= ~(1 << bitoff); 545 return (0); 546} 547 548/* 549 * Look up a network interface cloner. 550 */ 551 552__private_extern__ struct if_clone * 553if_clone_lookup(const char *name, u_int32_t *unitp) 554{ 555 struct if_clone *ifc; 556 const char *cp; 557 size_t i; 558 559 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) { 560 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) { 561 if (ifc->ifc_name[i] != *cp) 562 goto next_ifc; 563 } 564 goto found_name; 565 next_ifc: 566 ifc = LIST_NEXT(ifc, ifc_list); 567 } 568 569 /* No match. */ 570 return ((struct if_clone *)NULL); 571 572 found_name: 573 if (*cp == '\0') { 574 i = 0xffff; 575 } else { 576 for (i = 0; *cp != '\0'; cp++) { 577 if (*cp < '0' || *cp > '9') { 578 /* Bogus unit number. */ 579 return (NULL); 580 } 581 i = (i * 10) + (*cp - '0'); 582 } 583 } 584 585 if (unitp != NULL) 586 *unitp = i; 587 return (ifc); 588} 589 590/* 591 * Register a network interface cloner. 592 */ 593int 594if_clone_attach(struct if_clone *ifc) 595{ 596 int bytoff, bitoff; 597 int err; 598 int len, maxclone; 599 u_int32_t unit; 600 601 KASSERT(ifc->ifc_minifs - 1 <= ifc->ifc_maxunit, 602 ("%s: %s requested more units then allowed (%d > %d)", 603 __func__, ifc->ifc_name, ifc->ifc_minifs, 604 ifc->ifc_maxunit + 1)); 605 /* 606 * Compute bitmap size and allocate it. 607 */ 608 maxclone = ifc->ifc_maxunit + 1; 609 len = maxclone >> 3; 610 if ((len << 3) < maxclone) 611 len++; 612 ifc->ifc_units = _MALLOC(len, M_CLONE, M_WAITOK | M_ZERO); 613 if (ifc->ifc_units == NULL) 614 return ENOBUFS; 615 bzero(ifc->ifc_units, len); 616 ifc->ifc_bmlen = len; 617 618 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 619 if_cloners_count++; 620 621 for (unit = 0; unit < ifc->ifc_minifs; unit++) { 622 err = (*ifc->ifc_create)(ifc, unit, NULL); 623 KASSERT(err == 0, 624 ("%s: failed to create required interface %s%d", 625 __func__, ifc->ifc_name, unit)); 626 627 /* Allocate the unit in the bitmap. */ 628 bytoff = unit >> 3; 629 bitoff = unit - (bytoff << 3); 630 ifc->ifc_units[bytoff] |= (1 << bitoff); 631 } 632 633 return 0; 634} 635 636/* 637 * Unregister a network interface cloner. 638 */ 639void 640if_clone_detach(struct if_clone *ifc) 641{ 642 643 LIST_REMOVE(ifc, ifc_list); 644 FREE(ifc->ifc_units, M_CLONE); 645 if_cloners_count--; 646} 647 648#if IF_CLONE_LIST 649/* 650 * Provide list of interface cloners to userspace. 651 */ 652static int 653if_clone_list(int count, int * total, user_addr_t dst) 654{ 655 char outbuf[IFNAMSIZ]; 656 struct if_clone *ifc; 657 int error = 0; 658 659 *total = if_cloners_count; 660 if (dst == USER_ADDR_NULL) { 661 /* Just asking how many there are. */ 662 return (0); 663 } 664 665 if (count < 0) 666 return (EINVAL); 667 668 count = (if_cloners_count < count) ? if_cloners_count : count; 669 670 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 671 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 672 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ); 673 error = copyout(outbuf, dst, IFNAMSIZ); 674 if (error) 675 break; 676 } 677 678 return (error); 679} 680#endif /* IF_CLONE_LIST */ 681 682/* 683 * Similar to ifa_ifwithaddr, except that this is IPv4 specific 684 * and that it matches only the local (not broadcast) address. 685 */ 686__private_extern__ struct in_ifaddr * 687ifa_foraddr(unsigned int addr) 688{ 689 return (ifa_foraddr_scoped(addr, IFSCOPE_NONE)); 690} 691 692/* 693 * Similar to ifa_foraddr, except with the added interface scope 694 * constraint (unless the caller passes in IFSCOPE_NONE in which 695 * case there is no scope restriction). 696 */ 697__private_extern__ struct in_ifaddr * 698ifa_foraddr_scoped(unsigned int addr, unsigned int scope) 699{ 700 struct in_ifaddr *ia = NULL; 701 702 lck_rw_lock_shared(in_ifaddr_rwlock); 703 TAILQ_FOREACH(ia, INADDR_HASH(addr), ia_hash) { 704 IFA_LOCK_SPIN(&ia->ia_ifa); 705 if (ia->ia_addr.sin_addr.s_addr == addr && 706 (scope == IFSCOPE_NONE || ia->ia_ifp->if_index == scope)) { 707 IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for caller */ 708 IFA_UNLOCK(&ia->ia_ifa); 709 break; 710 } 711 IFA_UNLOCK(&ia->ia_ifa); 712 } 713 lck_rw_done(in_ifaddr_rwlock); 714 return (ia); 715} 716 717#if INET6 718/* 719 * Similar to ifa_foraddr, except that this for IPv6. 720 */ 721__private_extern__ struct in6_ifaddr * 722ifa_foraddr6(struct in6_addr *addr6) 723{ 724 return (ifa_foraddr6_scoped(addr6, IFSCOPE_NONE)); 725} 726 727__private_extern__ struct in6_ifaddr * 728ifa_foraddr6_scoped(struct in6_addr *addr6, unsigned int scope) 729{ 730 struct in6_ifaddr *ia = NULL; 731 732 lck_rw_lock_shared(&in6_ifaddr_rwlock); 733 for (ia = in6_ifaddrs; ia; ia = ia->ia_next) { 734 IFA_LOCK(&ia->ia_ifa); 735 if (IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, addr6) && 736 (scope == IFSCOPE_NONE || ia->ia_ifp->if_index == scope)) { 737 IFA_ADDREF_LOCKED(&ia->ia_ifa); /* for caller */ 738 IFA_UNLOCK(&ia->ia_ifa); 739 break; 740 } 741 IFA_UNLOCK(&ia->ia_ifa); 742 } 743 lck_rw_done(&in6_ifaddr_rwlock); 744 745 return (ia); 746} 747#endif /* INET6 */ 748 749/* 750 * Return the first (primary) address of a given family on an interface. 751 */ 752__private_extern__ struct ifaddr * 753ifa_ifpgetprimary(struct ifnet *ifp, int family) 754{ 755 struct ifaddr *ifa; 756 757 ifnet_lock_shared(ifp); 758 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 759 IFA_LOCK_SPIN(ifa); 760 if (ifa->ifa_addr->sa_family == family) { 761 IFA_ADDREF_LOCKED(ifa); /* for caller */ 762 IFA_UNLOCK(ifa); 763 break; 764 } 765 IFA_UNLOCK(ifa); 766 } 767 ifnet_lock_done(ifp); 768 769 return (ifa); 770} 771 772/* 773 * Locate an interface based on a complete address. 774 */ 775/*ARGSUSED*/ 776struct ifaddr * 777ifa_ifwithaddr(const struct sockaddr *addr) 778{ 779 struct ifnet *ifp; 780 struct ifaddr *ifa; 781 struct ifaddr *result = NULL; 782 783#define equal(a1, a2) \ 784 (bcmp((const void*)(a1), (const void*)(a2), \ 785 ((const struct sockaddr *)(a1))->sa_len) == 0) 786 787 ifnet_head_lock_shared(); 788 for (ifp = ifnet_head.tqh_first; ifp && !result; 789 ifp = ifp->if_link.tqe_next) { 790 ifnet_lock_shared(ifp); 791 for (ifa = ifp->if_addrhead.tqh_first; ifa; 792 ifa = ifa->ifa_link.tqe_next) { 793 IFA_LOCK_SPIN(ifa); 794 if (ifa->ifa_addr->sa_family != addr->sa_family) { 795 IFA_UNLOCK(ifa); 796 continue; 797 } 798 if (equal(addr, ifa->ifa_addr)) { 799 result = ifa; 800 IFA_ADDREF_LOCKED(ifa); /* for caller */ 801 IFA_UNLOCK(ifa); 802 break; 803 } 804 if ((ifp->if_flags & IFF_BROADCAST) && 805 ifa->ifa_broadaddr != NULL && 806 /* IP6 doesn't have broadcast */ 807 ifa->ifa_broadaddr->sa_len != 0 && 808 equal(ifa->ifa_broadaddr, addr)) { 809 result = ifa; 810 IFA_ADDREF_LOCKED(ifa); /* for caller */ 811 IFA_UNLOCK(ifa); 812 break; 813 } 814 IFA_UNLOCK(ifa); 815 } 816 ifnet_lock_done(ifp); 817 } 818 ifnet_head_done(); 819 820 return (result); 821} 822/* 823 * Locate the point to point interface with a given destination address. 824 */ 825/*ARGSUSED*/ 826struct ifaddr * 827ifa_ifwithdstaddr(const struct sockaddr *addr) 828{ 829 struct ifnet *ifp; 830 struct ifaddr *ifa; 831 struct ifaddr *result = NULL; 832 833 ifnet_head_lock_shared(); 834 for (ifp = ifnet_head.tqh_first; ifp && !result; 835 ifp = ifp->if_link.tqe_next) { 836 if ((ifp->if_flags & IFF_POINTOPOINT)) { 837 ifnet_lock_shared(ifp); 838 for (ifa = ifp->if_addrhead.tqh_first; ifa; 839 ifa = ifa->ifa_link.tqe_next) { 840 IFA_LOCK_SPIN(ifa); 841 if (ifa->ifa_addr->sa_family != 842 addr->sa_family) { 843 IFA_UNLOCK(ifa); 844 continue; 845 } 846 if (ifa->ifa_dstaddr && 847 equal(addr, ifa->ifa_dstaddr)) { 848 result = ifa; 849 IFA_ADDREF_LOCKED(ifa); /* for caller */ 850 IFA_UNLOCK(ifa); 851 break; 852 } 853 IFA_UNLOCK(ifa); 854 } 855 ifnet_lock_done(ifp); 856 } 857 } 858 ifnet_head_done(); 859 return (result); 860} 861 862/* 863 * Locate the source address of an interface based on a complete address. 864 */ 865struct ifaddr * 866ifa_ifwithaddr_scoped(const struct sockaddr *addr, unsigned int ifscope) 867{ 868 struct ifaddr *result = NULL; 869 struct ifnet *ifp; 870 871 if (ifscope == IFSCOPE_NONE) 872 return (ifa_ifwithaddr(addr)); 873 874 ifnet_head_lock_shared(); 875 if (ifscope > (unsigned int)if_index) { 876 ifnet_head_done(); 877 return (NULL); 878 } 879 880 ifp = ifindex2ifnet[ifscope]; 881 if (ifp != NULL) { 882 struct ifaddr *ifa = NULL; 883 884 /* 885 * This is suboptimal; there should be a better way 886 * to search for a given address of an interface 887 * for any given address family. 888 */ 889 ifnet_lock_shared(ifp); 890 for (ifa = ifp->if_addrhead.tqh_first; ifa != NULL; 891 ifa = ifa->ifa_link.tqe_next) { 892 IFA_LOCK_SPIN(ifa); 893 if (ifa->ifa_addr->sa_family != addr->sa_family) { 894 IFA_UNLOCK(ifa); 895 continue; 896 } 897 if (equal(addr, ifa->ifa_addr)) { 898 result = ifa; 899 IFA_ADDREF_LOCKED(ifa); /* for caller */ 900 IFA_UNLOCK(ifa); 901 break; 902 } 903 if ((ifp->if_flags & IFF_BROADCAST) && 904 ifa->ifa_broadaddr != NULL && 905 /* IP6 doesn't have broadcast */ 906 ifa->ifa_broadaddr->sa_len != 0 && 907 equal(ifa->ifa_broadaddr, addr)) { 908 result = ifa; 909 IFA_ADDREF_LOCKED(ifa); /* for caller */ 910 IFA_UNLOCK(ifa); 911 break; 912 } 913 IFA_UNLOCK(ifa); 914 } 915 ifnet_lock_done(ifp); 916 } 917 ifnet_head_done(); 918 919 return (result); 920} 921 922struct ifaddr * 923ifa_ifwithnet(const struct sockaddr *addr) 924{ 925 return (ifa_ifwithnet_common(addr, IFSCOPE_NONE)); 926} 927 928struct ifaddr * 929ifa_ifwithnet_scoped(const struct sockaddr *addr, unsigned int ifscope) 930{ 931 return (ifa_ifwithnet_common(addr, ifscope)); 932} 933 934/* 935 * Find an interface on a specific network. If many, choice 936 * is most specific found. 937 */ 938static struct ifaddr * 939ifa_ifwithnet_common(const struct sockaddr *addr, unsigned int ifscope) 940{ 941 struct ifnet *ifp; 942 struct ifaddr *ifa = NULL; 943 struct ifaddr *ifa_maybe = NULL; 944 u_int af = addr->sa_family; 945 const char *addr_data = addr->sa_data, *cplim; 946 947#if INET6 948 if ((af != AF_INET && af != AF_INET6) || 949 (af == AF_INET && !ip_doscopedroute) || 950 (af == AF_INET6 && !ip6_doscopedroute)) 951#else 952 if (af != AF_INET || !ip_doscopedroute) 953#endif /* !INET6 */ 954 ifscope = IFSCOPE_NONE; 955 956 ifnet_head_lock_shared(); 957 /* 958 * AF_LINK addresses can be looked up directly by their index number, 959 * so do that if we can. 960 */ 961 if (af == AF_LINK) { 962 const struct sockaddr_dl *sdl = 963 (const struct sockaddr_dl *)(uintptr_t)(size_t)addr; 964 if (sdl->sdl_index && sdl->sdl_index <= if_index) { 965 ifa = ifnet_addrs[sdl->sdl_index - 1]; 966 if (ifa != NULL) 967 IFA_ADDREF(ifa); 968 969 ifnet_head_done(); 970 return (ifa); 971 } 972 } 973 974 /* 975 * Scan though each interface, looking for ones that have 976 * addresses in this address family. 977 */ 978 for (ifp = ifnet_head.tqh_first; ifp; ifp = ifp->if_link.tqe_next) { 979 ifnet_lock_shared(ifp); 980 for (ifa = ifp->if_addrhead.tqh_first; ifa; 981 ifa = ifa->ifa_link.tqe_next) { 982 const char *cp, *cp2, *cp3; 983 984 IFA_LOCK(ifa); 985 if (ifa->ifa_addr == NULL || 986 ifa->ifa_addr->sa_family != af) { 987next: 988 IFA_UNLOCK(ifa); 989 continue; 990 } 991#ifndef __APPLE__ 992/* This breaks tunneling application trying to install a route with 993 * a specific subnet and the local address as the destination 994 * It's breaks binary compatibility with previous version of MacOS X 995 */ 996 if ( 997#if INET6 /* XXX: for maching gif tunnel dst as routing entry gateway */ 998 addr->sa_family != AF_INET6 && 999#endif 1000 ifp->if_flags & IFF_POINTOPOINT) { 1001 /* 1002 * This is a bit broken as it doesn't 1003 * take into account that the remote end may 1004 * be a single node in the network we are 1005 * looking for. 1006 * The trouble is that we don't know the 1007 * netmask for the remote end. 1008 */ 1009 if (ifa->ifa_dstaddr != 0 && 1010 equal(addr, ifa->ifa_dstaddr)) { 1011 IFA_ADDREF_LOCKED(ifa); 1012 IFA_UNLOCK(ifa); 1013 break; 1014 } 1015 IFA_UNLOCK(ifa); 1016 } else 1017#endif /* __APPLE__*/ 1018 { 1019 /* 1020 * If we're looking up with a scope, 1021 * find using a matching interface. 1022 */ 1023 if (ifscope != IFSCOPE_NONE && 1024 ifp->if_index != ifscope) { 1025 IFA_UNLOCK(ifa); 1026 continue; 1027 } 1028 1029 /* 1030 * Scan all the bits in the ifa's address. 1031 * If a bit dissagrees with what we are 1032 * looking for, mask it with the netmask 1033 * to see if it really matters. 1034 * (A byte at a time) 1035 */ 1036 if (ifa->ifa_netmask == 0) { 1037 IFA_UNLOCK(ifa); 1038 continue; 1039 } 1040 cp = addr_data; 1041 cp2 = ifa->ifa_addr->sa_data; 1042 cp3 = ifa->ifa_netmask->sa_data; 1043 cplim = ifa->ifa_netmask->sa_len 1044 + (char *)ifa->ifa_netmask; 1045 while (cp3 < cplim) 1046 if ((*cp++ ^ *cp2++) & *cp3++) 1047 goto next; /* next address! */ 1048 /* 1049 * If the netmask of what we just found 1050 * is more specific than what we had before 1051 * (if we had one) then remember the new one 1052 * before continuing to search 1053 * for an even better one. 1054 */ 1055 if (ifa_maybe == NULL || 1056 rn_refines((caddr_t)ifa->ifa_netmask, 1057 (caddr_t)ifa_maybe->ifa_netmask)) { 1058 IFA_ADDREF_LOCKED(ifa); /* ifa_maybe */ 1059 IFA_UNLOCK(ifa); 1060 if (ifa_maybe != NULL) 1061 IFA_REMREF(ifa_maybe); 1062 ifa_maybe = ifa; 1063 } else { 1064 IFA_UNLOCK(ifa); 1065 } 1066 } 1067 IFA_LOCK_ASSERT_NOTHELD(ifa); 1068 } 1069 ifnet_lock_done(ifp); 1070 1071 if (ifa != NULL) 1072 break; 1073 } 1074 ifnet_head_done(); 1075 1076 if (ifa == NULL) 1077 ifa = ifa_maybe; 1078 else if (ifa_maybe != NULL) 1079 IFA_REMREF(ifa_maybe); 1080 1081 return (ifa); 1082} 1083 1084/* 1085 * Find an interface address specific to an interface best matching 1086 * a given address. 1087 */ 1088struct ifaddr * 1089ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp) 1090{ 1091 struct ifaddr *ifa = NULL; 1092 const char *cp, *cp2, *cp3; 1093 char *cplim; 1094 struct ifaddr *ifa_maybe = NULL; 1095 struct ifaddr *better_ifa_maybe = NULL; 1096 u_int af = addr->sa_family; 1097 1098 if (af >= AF_MAX) 1099 return (NULL); 1100 1101 ifnet_lock_shared(ifp); 1102 for (ifa = ifp->if_addrhead.tqh_first; ifa; 1103 ifa = ifa->ifa_link.tqe_next) { 1104 IFA_LOCK(ifa); 1105 if (ifa->ifa_addr->sa_family != af) { 1106 IFA_UNLOCK(ifa); 1107 continue; 1108 } 1109 if (ifa_maybe == NULL) { 1110 IFA_ADDREF_LOCKED(ifa); /* for ifa_maybe */ 1111 ifa_maybe = ifa; 1112 } 1113 if (ifa->ifa_netmask == 0) { 1114 if (equal(addr, ifa->ifa_addr) || (ifa->ifa_dstaddr && 1115 equal(addr, ifa->ifa_dstaddr))) { 1116 IFA_ADDREF_LOCKED(ifa); /* for caller */ 1117 IFA_UNLOCK(ifa); 1118 break; 1119 } 1120 IFA_UNLOCK(ifa); 1121 continue; 1122 } 1123 if (ifp->if_flags & IFF_POINTOPOINT) { 1124 if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) { 1125 IFA_ADDREF_LOCKED(ifa); /* for caller */ 1126 IFA_UNLOCK(ifa); 1127 break; 1128 } 1129 } else { 1130 if (equal(addr, ifa->ifa_addr)) { 1131 /* exact match */ 1132 IFA_ADDREF_LOCKED(ifa); /* for caller */ 1133 IFA_UNLOCK(ifa); 1134 break; 1135 } 1136 cp = addr->sa_data; 1137 cp2 = ifa->ifa_addr->sa_data; 1138 cp3 = ifa->ifa_netmask->sa_data; 1139 cplim = ifa->ifa_netmask->sa_len + 1140 (char *)ifa->ifa_netmask; 1141 for (; cp3 < cplim; cp3++) 1142 if ((*cp++ ^ *cp2++) & *cp3) 1143 break; 1144 if (cp3 == cplim) { 1145 /* subnet match */ 1146 if (better_ifa_maybe == NULL) { 1147 /* for better_ifa_maybe */ 1148 IFA_ADDREF_LOCKED(ifa); 1149 better_ifa_maybe = ifa; 1150 } 1151 } 1152 } 1153 IFA_UNLOCK(ifa); 1154 } 1155 1156 if (ifa == NULL) { 1157 if (better_ifa_maybe != NULL) { 1158 ifa = better_ifa_maybe; 1159 better_ifa_maybe = NULL; 1160 } else { 1161 ifa = ifa_maybe; 1162 ifa_maybe = NULL; 1163 } 1164 } 1165 1166 ifnet_lock_done(ifp); 1167 1168 if (better_ifa_maybe != NULL) 1169 IFA_REMREF(better_ifa_maybe); 1170 if (ifa_maybe != NULL) 1171 IFA_REMREF(ifa_maybe); 1172 1173 return (ifa); 1174} 1175 1176#include <net/route.h> 1177 1178/* 1179 * Default action when installing a route with a Link Level gateway. 1180 * Lookup an appropriate real ifa to point to. 1181 * This should be moved to /sys/net/link.c eventually. 1182 */ 1183void 1184link_rtrequest(int cmd, struct rtentry *rt, struct sockaddr *sa) 1185{ 1186 struct ifaddr *ifa; 1187 struct sockaddr *dst; 1188 struct ifnet *ifp; 1189 void (*ifa_rtrequest)(int, struct rtentry *, struct sockaddr *); 1190 1191 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); 1192 RT_LOCK_ASSERT_HELD(rt); 1193 1194 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 1195 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 1196 return; 1197 1198 /* Become a regular mutex, just in case */ 1199 RT_CONVERT_LOCK(rt); 1200 1201 ifa = ifaof_ifpforaddr(dst, ifp); 1202 if (ifa) { 1203 rtsetifa(rt, ifa); 1204 IFA_LOCK_SPIN(ifa); 1205 ifa_rtrequest = ifa->ifa_rtrequest; 1206 IFA_UNLOCK(ifa); 1207 if (ifa_rtrequest != NULL && ifa_rtrequest != link_rtrequest) 1208 ifa_rtrequest(cmd, rt, sa); 1209 IFA_REMREF(ifa); 1210 } 1211} 1212 1213/* 1214 * if_updown will set the interface up or down. It will 1215 * prevent other up/down events from occurring until this 1216 * up/down event has completed. 1217 * 1218 * Caller must lock ifnet. This function will drop the 1219 * lock. This allows ifnet_set_flags to set the rest of 1220 * the flags after we change the up/down state without 1221 * dropping the interface lock between setting the 1222 * up/down state and updating the rest of the flags. 1223 */ 1224__private_extern__ void 1225if_updown( 1226 struct ifnet *ifp, 1227 int up) 1228{ 1229 int i; 1230 struct ifaddr **ifa; 1231 struct timespec tv; 1232 struct ifclassq *ifq = &ifp->if_snd; 1233 1234 /* Wait until no one else is changing the up/down state */ 1235 while ((ifp->if_eflags & IFEF_UPDOWNCHANGE) != 0) { 1236 tv.tv_sec = 0; 1237 tv.tv_nsec = NSEC_PER_SEC / 10; 1238 ifnet_lock_done(ifp); 1239 msleep(&ifp->if_eflags, NULL, 0, "if_updown", &tv); 1240 ifnet_lock_exclusive(ifp); 1241 } 1242 1243 /* Verify that the interface isn't already in the right state */ 1244 if ((!up && (ifp->if_flags & IFF_UP) == 0) || 1245 (up && (ifp->if_flags & IFF_UP) == IFF_UP)) { 1246 return; 1247 } 1248 1249 /* Indicate that the up/down state is changing */ 1250 ifp->if_eflags |= IFEF_UPDOWNCHANGE; 1251 1252 /* Mark interface up or down */ 1253 if (up) { 1254 ifp->if_flags |= IFF_UP; 1255 } 1256 else { 1257 ifp->if_flags &= ~IFF_UP; 1258 } 1259 1260 ifnet_touch_lastchange(ifp); 1261 1262 /* Drop the lock to notify addresses and route */ 1263 ifnet_lock_done(ifp); 1264 if (ifnet_get_address_list(ifp, &ifa) == 0) { 1265 for (i = 0; ifa[i] != 0; i++) { 1266 pfctlinput(up ? PRC_IFUP : PRC_IFDOWN, ifa[i]->ifa_addr); 1267 } 1268 ifnet_free_address_list(ifa); 1269 } 1270 rt_ifmsg(ifp); 1271 1272 if (!up) 1273 if_qflush(ifp, 0); 1274 1275 /* Inform all transmit queues about the new link state */ 1276 IFCQ_LOCK(ifq); 1277 ifnet_update_sndq(ifq, up ? CLASSQ_EV_LINK_UP : CLASSQ_EV_LINK_DOWN); 1278 IFCQ_UNLOCK(ifq); 1279 1280 /* Aquire the lock to clear the changing flag */ 1281 ifnet_lock_exclusive(ifp); 1282 ifp->if_eflags &= ~IFEF_UPDOWNCHANGE; 1283 wakeup(&ifp->if_eflags); 1284} 1285 1286/* 1287 * Mark an interface down and notify protocols of 1288 * the transition. 1289 */ 1290void 1291if_down( 1292 struct ifnet *ifp) 1293{ 1294 ifnet_lock_exclusive(ifp); 1295 if_updown(ifp, 0); 1296 ifnet_lock_done(ifp); 1297} 1298 1299/* 1300 * Mark an interface up and notify protocols of 1301 * the transition. 1302 */ 1303void 1304if_up( 1305 struct ifnet *ifp) 1306{ 1307 ifnet_lock_exclusive(ifp); 1308 if_updown(ifp, 1); 1309 ifnet_lock_done(ifp); 1310} 1311 1312/* 1313 * Flush an interface queue. 1314 */ 1315void 1316if_qflush(struct ifnet *ifp, int ifq_locked) 1317{ 1318 struct ifclassq *ifq = &ifp->if_snd; 1319 1320 if (!ifq_locked) 1321 IFCQ_LOCK(ifq); 1322 1323 if (IFCQ_IS_ENABLED(ifq)) 1324 IFCQ_PURGE(ifq); 1325#if PF_ALTQ 1326 if (IFCQ_IS_DRAINING(ifq)) 1327 ifq->ifcq_drain = 0; 1328 if (ALTQ_IS_ENABLED(IFCQ_ALTQ(ifq))) 1329 ALTQ_PURGE(IFCQ_ALTQ(ifq)); 1330#endif /* PF_ALTQ */ 1331 1332 VERIFY(IFCQ_IS_EMPTY(ifq)); 1333 1334 if (!ifq_locked) 1335 IFCQ_UNLOCK(ifq); 1336} 1337 1338void 1339if_qflush_sc(struct ifnet *ifp, mbuf_svc_class_t sc, u_int32_t flow, 1340 u_int32_t *packets, u_int32_t *bytes, int ifq_locked) 1341{ 1342 struct ifclassq *ifq = &ifp->if_snd; 1343 u_int32_t cnt = 0, len = 0; 1344 u_int32_t a_cnt = 0, a_len = 0; 1345 1346 VERIFY(sc == MBUF_SC_UNSPEC || MBUF_VALID_SC(sc)); 1347 VERIFY(flow != 0); 1348 1349 if (!ifq_locked) 1350 IFCQ_LOCK(ifq); 1351 1352 if (IFCQ_IS_ENABLED(ifq)) 1353 IFCQ_PURGE_SC(ifq, sc, flow, cnt, len); 1354#if PF_ALTQ 1355 if (IFCQ_IS_DRAINING(ifq)) { 1356 VERIFY((signed)(ifq->ifcq_drain - cnt) >= 0); 1357 ifq->ifcq_drain -= cnt; 1358 } 1359 if (ALTQ_IS_ENABLED(IFCQ_ALTQ(ifq))) 1360 ALTQ_PURGE_SC(IFCQ_ALTQ(ifq), sc, flow, a_cnt, a_len); 1361#endif /* PF_ALTQ */ 1362 1363 if (!ifq_locked) 1364 IFCQ_UNLOCK(ifq); 1365 1366 if (packets != NULL) 1367 *packets = cnt + a_cnt; 1368 if (bytes != NULL) 1369 *bytes = len + a_len; 1370} 1371 1372/* 1373 * Map interface name to 1374 * interface structure pointer. 1375 */ 1376struct ifnet * 1377ifunit(const char *name) 1378{ 1379 char namebuf[IFNAMSIZ + 1]; 1380 const char *cp; 1381 struct ifnet *ifp; 1382 int unit; 1383 unsigned len, m; 1384 char c; 1385 1386 len = strlen(name); 1387 if (len < 2 || len > IFNAMSIZ) 1388 return (NULL); 1389 cp = name + len - 1; 1390 c = *cp; 1391 if (c < '0' || c > '9') 1392 return (NULL); /* trailing garbage */ 1393 unit = 0; 1394 m = 1; 1395 do { 1396 if (cp == name) 1397 return (NULL); /* no interface name */ 1398 unit += (c - '0') * m; 1399 if (unit > 1000000) 1400 return (NULL); /* number is unreasonable */ 1401 m *= 10; 1402 c = *--cp; 1403 } while (c >= '0' && c <= '9'); 1404 len = cp - name + 1; 1405 bcopy(name, namebuf, len); 1406 namebuf[len] = '\0'; 1407 /* 1408 * Now search all the interfaces for this name/number 1409 */ 1410 ifnet_head_lock_shared(); 1411 TAILQ_FOREACH(ifp, &ifnet_head, if_link) { 1412 if (strncmp(ifp->if_name, namebuf, len)) 1413 continue; 1414 if (unit == ifp->if_unit) 1415 break; 1416 } 1417 ifnet_head_done(); 1418 return (ifp); 1419} 1420 1421 1422/* 1423 * Map interface name in a sockaddr_dl to 1424 * interface structure pointer. 1425 */ 1426struct ifnet * 1427if_withname(struct sockaddr *sa) 1428{ 1429 char ifname[IFNAMSIZ+1]; 1430 struct sockaddr_dl *sdl = (struct sockaddr_dl *)(void *)sa; 1431 1432 if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) || 1433 (sdl->sdl_nlen > IFNAMSIZ) ) 1434 return (NULL); 1435 1436 /* 1437 * ifunit wants a null-terminated name. It may not be null-terminated 1438 * in the sockaddr. We don't want to change the caller's sockaddr, 1439 * and there might not be room to put the trailing null anyway, so we 1440 * make a local copy that we know we can null terminate safely. 1441 */ 1442 1443 bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen); 1444 ifname[sdl->sdl_nlen] = '\0'; 1445 return (ifunit(ifname)); 1446} 1447 1448 1449/* 1450 * Interface ioctls. 1451 */ 1452int 1453ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p) 1454{ 1455 char ifname[IFNAMSIZ + 1]; 1456 struct ifnet *ifp = NULL; 1457 struct ifstat *ifs = NULL; 1458 int error = 0; 1459 1460 bzero(ifname, sizeof (ifname)); 1461 1462 /* 1463 * ioctls which don't require ifp, or ifreq ioctls 1464 */ 1465 switch (cmd) { 1466 case OSIOCGIFCONF32: /* struct ifconf32 */ 1467 case SIOCGIFCONF32: { /* struct ifconf32 */ 1468 struct ifconf32 ifc; 1469 bcopy(data, &ifc, sizeof (ifc)); 1470 error = ifconf(cmd, CAST_USER_ADDR_T(ifc.ifc_req), 1471 &ifc.ifc_len); 1472 bcopy(&ifc, data, sizeof (ifc)); 1473 goto done; 1474 } 1475 1476 case SIOCGIFCONF64: /* struct ifconf64 */ 1477 case OSIOCGIFCONF64: { /* struct ifconf64 */ 1478 struct ifconf64 ifc; 1479 bcopy(data, &ifc, sizeof (ifc)); 1480 error = ifconf(cmd, ifc.ifc_req, &ifc.ifc_len); 1481 bcopy(&ifc, data, sizeof (ifc)); 1482 goto done; 1483 } 1484 1485#if IF_CLONE_LIST 1486 case SIOCIFGCLONERS32: { /* struct if_clonereq32 */ 1487 struct if_clonereq32 ifcr; 1488 bcopy(data, &ifcr, sizeof (ifcr)); 1489 error = if_clone_list(ifcr.ifcr_count, &ifcr.ifcr_total, 1490 CAST_USER_ADDR_T(ifcr.ifcru_buffer)); 1491 bcopy(&ifcr, data, sizeof (ifcr)); 1492 goto done; 1493 } 1494 1495 case SIOCIFGCLONERS64: { /* struct if_clonereq64 */ 1496 struct if_clonereq64 ifcr; 1497 bcopy(data, &ifcr, sizeof (ifcr)); 1498 error = if_clone_list(ifcr.ifcr_count, &ifcr.ifcr_total, 1499 ifcr.ifcru_buffer); 1500 bcopy(&ifcr, data, sizeof (ifcr)); 1501 goto done; 1502 } 1503#endif /* IF_CLONE_LIST */ 1504 1505 case SIOCSIFDSTADDR: /* struct ifreq */ 1506 case SIOCSIFADDR: /* struct ifreq */ 1507 case SIOCSIFBRDADDR: /* struct ifreq */ 1508 case SIOCSIFNETMASK: /* struct ifreq */ 1509 case OSIOCGIFADDR: /* struct ifreq */ 1510 case OSIOCGIFDSTADDR: /* struct ifreq */ 1511 case OSIOCGIFBRDADDR: /* struct ifreq */ 1512 case OSIOCGIFNETMASK: /* struct ifreq */ 1513 case SIOCSIFKPI: /* struct ifreq */ 1514 if (so->so_proto == NULL) { 1515 error = EOPNOTSUPP; 1516 goto done; 1517 } 1518 /* FALLTHRU */ 1519 case SIOCIFCREATE: /* struct ifreq */ 1520 case SIOCIFCREATE2: /* struct ifreq */ 1521 case SIOCIFDESTROY: /* struct ifreq */ 1522 case SIOCGIFFLAGS: /* struct ifreq */ 1523 case SIOCGIFEFLAGS: /* struct ifreq */ 1524 case SIOCGIFCAP: /* struct ifreq */ 1525 case SIOCGIFMAC: /* struct ifreq */ 1526 case SIOCGIFMETRIC: /* struct ifreq */ 1527 case SIOCGIFMTU: /* struct ifreq */ 1528 case SIOCGIFPHYS: /* struct ifreq */ 1529 case SIOCSIFFLAGS: /* struct ifreq */ 1530 case SIOCSIFCAP: /* struct ifreq */ 1531 case SIOCSIFPHYS: /* struct ifreq */ 1532 case SIOCSIFMTU: /* struct ifreq */ 1533 case SIOCADDMULTI: /* struct ifreq */ 1534 case SIOCDELMULTI: /* struct ifreq */ 1535 case SIOCDIFPHYADDR: /* struct ifreq */ 1536 case SIOCSIFMEDIA: /* struct ifreq */ 1537 case SIOCSIFGENERIC: /* struct ifreq */ 1538 case SIOCSIFLLADDR: /* struct ifreq */ 1539 case SIOCSIFALTMTU: /* struct ifreq */ 1540 case SIOCSIFVLAN: /* struct ifreq */ 1541 case SIOCSIFBOND: /* struct ifreq */ 1542 case SIOCGIFPSRCADDR: /* struct ifreq */ 1543 case SIOCGIFPDSTADDR: /* struct ifreq */ 1544 case SIOCGIFGENERIC: /* struct ifreq */ 1545 case SIOCGIFDEVMTU: /* struct ifreq */ 1546 case SIOCGIFVLAN: /* struct ifreq */ 1547 case SIOCGIFBOND: /* struct ifreq */ 1548 case SIOCGIFWAKEFLAGS: /* struct ifreq */ 1549 case SIOCGIFGETRTREFCNT: /* struct ifreq */ 1550 case SIOCSIFOPPORTUNISTIC: /* struct ifreq */ 1551 case SIOCGIFOPPORTUNISTIC: /* struct ifreq */ 1552 case SIOCGIFLINKQUALITYMETRIC: { /* struct ifreq */ 1553 struct ifreq ifr; 1554 bcopy(data, &ifr, sizeof (ifr)); 1555 error = ifioctl_ifreq(so, cmd, &ifr, p); 1556 bcopy(&ifr, data, sizeof (ifr)); 1557 goto done; 1558 } 1559 } 1560 1561 /* 1562 * ioctls which require ifp. Note that we acquire dlil_ifnet_lock 1563 * here to ensure that the ifnet, if found, has been fully attached. 1564 */ 1565 dlil_if_lock(); 1566 switch (cmd) { 1567 case SIOCSIFPHYADDR: { /* struct ifaliasreq */ 1568 bcopy(((struct ifaliasreq *)(void *)data)->ifra_name, 1569 ifname, IFNAMSIZ); 1570 ifp = ifunit(ifname); 1571 break; 1572 } 1573 1574#if INET6 1575 case SIOCSIFPHYADDR_IN6_32: { /* struct in6_aliasreq_32 */ 1576 bcopy(((struct in6_aliasreq_32 *)(void *)data)->ifra_name, 1577 ifname, IFNAMSIZ); 1578 ifp = ifunit(ifname); 1579 break; 1580 } 1581 1582 case SIOCSIFPHYADDR_IN6_64: { /* struct in6_aliasreq_64 */ 1583 bcopy(((struct in6_aliasreq_64 *)(void *)data)->ifra_name, 1584 ifname, IFNAMSIZ); 1585 ifp = ifunit(ifname); 1586 break; 1587 } 1588#endif 1589 1590 case SIOCSLIFPHYADDR: /* struct if_laddrreq */ 1591 case SIOCGLIFPHYADDR: { /* struct if_laddrreq */ 1592 bcopy(((struct if_laddrreq *)(void *)data)->iflr_name, 1593 ifname, IFNAMSIZ); 1594 ifp = ifunit(ifname); 1595 break; 1596 } 1597 1598 case SIOCGIFSTATUS: { /* struct ifstat */ 1599 ifs = _MALLOC(sizeof (*ifs), M_DEVBUF, M_WAITOK); 1600 if (ifs == NULL) { 1601 error = ENOMEM; 1602 dlil_if_unlock(); 1603 goto done; 1604 } 1605 bcopy(data, ifs, sizeof (*ifs)); 1606 ifs->ifs_name[IFNAMSIZ - 1] = '\0'; 1607 ifp = ifunit(ifs->ifs_name); 1608 break; 1609 } 1610 1611 case SIOCGIFMEDIA32: { /* struct ifmediareq32 */ 1612 bcopy(((struct ifmediareq32 *)(void *)data)->ifm_name, 1613 ifname, IFNAMSIZ); 1614 ifp = ifunit(ifname); 1615 break; 1616 } 1617 1618 case SIOCGIFMEDIA64: { /* struct ifmediareq64 */ 1619 bcopy(((struct ifmediareq64 *)(void *)data)->ifm_name, 1620 ifname, IFNAMSIZ); 1621 ifp = ifunit(ifname); 1622 break; 1623 } 1624 1625 case SIOCSIFDESC: /* struct if_descreq */ 1626 case SIOCGIFDESC: { /* struct if_descreq */ 1627 bcopy(((struct if_descreq *)(void *)data)->ifdr_name, 1628 ifname, IFNAMSIZ); 1629 ifp = ifunit(ifname); 1630 break; 1631 } 1632 1633 case SIOCSIFLINKPARAMS: /* struct if_linkparamsreq */ 1634 case SIOCGIFLINKPARAMS: { /* struct if_linkparamsreq */ 1635 bcopy(((struct if_linkparamsreq *)(void *)data)->iflpr_name, 1636 ifname, IFNAMSIZ); 1637 ifp = ifunit(ifname); 1638 break; 1639 } 1640 1641 case SIOCGIFQUEUESTATS: { /* struct if_qstatsreq */ 1642 bcopy(((struct if_qstatsreq *)(void *)data)->ifqr_name, 1643 ifname, IFNAMSIZ); 1644 ifp = ifunit(ifname); 1645 break; 1646 } 1647 1648 case SIOCSIFTHROTTLE: /* struct if_throttlereq */ 1649 case SIOCGIFTHROTTLE: { /* struct if_throttlereq */ 1650 bcopy(((struct if_throttlereq *)(void *)data)->ifthr_name, 1651 ifname, IFNAMSIZ); 1652 ifp = ifunit(ifname); 1653 break; 1654 } 1655 1656 default: { 1657 /* 1658 * This is a bad assumption, but the code seems to 1659 * have been doing this in the past; caveat emptor. 1660 */ 1661 bcopy(((struct ifreq *)(void *)data)->ifr_name, 1662 ifname, IFNAMSIZ); 1663 ifp = ifunit(ifname); 1664 break; 1665 } 1666 } 1667 dlil_if_unlock(); 1668 1669 if (ifp == NULL) { 1670 error = ENXIO; 1671 goto done; 1672 } 1673 1674 switch (cmd) { 1675 case SIOCSIFPHYADDR: /* struct ifaliasreq */ 1676#if INET6 1677 case SIOCSIFPHYADDR_IN6_32: /* struct in6_aliasreq_32 */ 1678 case SIOCSIFPHYADDR_IN6_64: /* struct in6_aliasreq_64 */ 1679#endif 1680 case SIOCSLIFPHYADDR: /* struct if_laddrreq */ 1681 error = proc_suser(p); 1682 if (error != 0) 1683 break; 1684 1685 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1686 cmd, data); 1687 if (error != 0) 1688 break; 1689 1690 ifnet_touch_lastchange(ifp); 1691 break; 1692 1693 case SIOCGIFSTATUS: /* struct ifstat */ 1694 VERIFY(ifs != NULL); 1695 ifs->ascii[0] = '\0'; 1696 1697 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1698 cmd, (caddr_t)ifs); 1699 1700 bcopy(ifs, data, sizeof (*ifs)); 1701 break; 1702 1703 case SIOCGLIFPHYADDR: /* struct if_laddrreq */ 1704 case SIOCGIFMEDIA32: /* struct ifmediareq32 */ 1705 case SIOCGIFMEDIA64: /* struct ifmediareq64 */ 1706 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1707 cmd, data); 1708 break; 1709 1710 case SIOCSIFDESC: { /* struct if_descreq */ 1711 struct if_descreq *ifdr = (struct if_descreq *)(void *)data; 1712 u_int32_t ifdr_len; 1713 1714 if ((error = proc_suser(p)) != 0) 1715 break; 1716 1717 ifnet_lock_exclusive(ifp); 1718 bcopy(&ifdr->ifdr_len, &ifdr_len, sizeof (ifdr_len)); 1719 if (ifdr_len > sizeof (ifdr->ifdr_desc) || 1720 ifdr_len > ifp->if_desc.ifd_maxlen) { 1721 error = EINVAL; 1722 ifnet_lock_done(ifp); 1723 break; 1724 } 1725 1726 bzero(ifp->if_desc.ifd_desc, ifp->if_desc.ifd_maxlen); 1727 if ((ifp->if_desc.ifd_len = ifdr_len) > 0) { 1728 bcopy(ifdr->ifdr_desc, ifp->if_desc.ifd_desc, 1729 MIN(ifdr_len, ifp->if_desc.ifd_maxlen)); 1730 } 1731 ifnet_lock_done(ifp); 1732 break; 1733 } 1734 1735 case SIOCGIFDESC: { /* struct if_descreq */ 1736 struct if_descreq *ifdr = (struct if_descreq *)(void *)data; 1737 u_int32_t ifdr_len; 1738 1739 ifnet_lock_shared(ifp); 1740 ifdr_len = MIN(ifp->if_desc.ifd_len, sizeof (ifdr->ifdr_desc)); 1741 bcopy(&ifdr_len, &ifdr->ifdr_len, sizeof (ifdr_len)); 1742 bzero(&ifdr->ifdr_desc, sizeof (ifdr->ifdr_desc)); 1743 if (ifdr_len > 0) { 1744 bcopy(ifp->if_desc.ifd_desc, ifdr->ifdr_desc, ifdr_len); 1745 } 1746 ifnet_lock_done(ifp); 1747 break; 1748 } 1749 1750 case SIOCSIFLINKPARAMS: { /* struct if_linkparamsreq */ 1751 struct if_linkparamsreq *iflpr = 1752 (struct if_linkparamsreq *)(void *)data; 1753 struct ifclassq *ifq = &ifp->if_snd; 1754 struct tb_profile tb = { 0, 0, 0 }; 1755 1756 if ((error = proc_suser(p)) != 0) 1757 break; 1758 1759 IFCQ_LOCK(ifq); 1760 if (!IFCQ_IS_READY(ifq)) { 1761 error = ENXIO; 1762 IFCQ_UNLOCK(ifq); 1763 break; 1764 } 1765 bcopy(&iflpr->iflpr_output_tbr_rate, &tb.rate, 1766 sizeof (tb.rate)); 1767 bcopy(&iflpr->iflpr_output_tbr_percent, &tb.percent, 1768 sizeof (tb.percent)); 1769 error = ifclassq_tbr_set(ifq, &tb, TRUE); 1770 IFCQ_UNLOCK(ifq); 1771 break; 1772 } 1773 1774 case SIOCGIFLINKPARAMS: { /* struct if_linkparamsreq */ 1775 struct if_linkparamsreq *iflpr = 1776 (struct if_linkparamsreq *)(void *)data; 1777 struct ifclassq *ifq = &ifp->if_snd; 1778 u_int32_t sched_type = PKTSCHEDT_NONE, flags = 0; 1779 u_int64_t tbr_bw = 0, tbr_pct = 0; 1780 1781 IFCQ_LOCK(ifq); 1782#if PF_ALTQ 1783 if (ALTQ_IS_ENABLED(IFCQ_ALTQ(ifq))) { 1784 sched_type = IFCQ_ALTQ(ifq)->altq_type; 1785 flags |= IFLPRF_ALTQ; 1786 } else 1787#endif /* PF_ALTQ */ 1788 { 1789 if (IFCQ_IS_ENABLED(ifq)) 1790 sched_type = ifq->ifcq_type; 1791 } 1792 bcopy(&sched_type, &iflpr->iflpr_output_sched, 1793 sizeof (iflpr->iflpr_output_sched)); 1794 1795 if (IFCQ_TBR_IS_ENABLED(ifq)) { 1796 tbr_bw = ifq->ifcq_tbr.tbr_rate_raw; 1797 tbr_pct = ifq->ifcq_tbr.tbr_percent; 1798 } 1799 bcopy(&tbr_bw, &iflpr->iflpr_output_tbr_rate, 1800 sizeof (iflpr->iflpr_output_tbr_rate)); 1801 bcopy(&tbr_pct, &iflpr->iflpr_output_tbr_percent, 1802 sizeof (iflpr->iflpr_output_tbr_percent)); 1803 IFCQ_UNLOCK(ifq); 1804 1805 if (ifp->if_output_sched_model == 1806 IFNET_SCHED_MODEL_DRIVER_MANAGED) 1807 flags |= IFLPRF_DRVMANAGED; 1808 bcopy(&flags, &iflpr->iflpr_flags, sizeof (iflpr->iflpr_flags)); 1809 bcopy(&ifp->if_output_bw, &iflpr->iflpr_output_bw, 1810 sizeof (iflpr->iflpr_output_bw)); 1811 bcopy(&ifp->if_input_bw, &iflpr->iflpr_input_bw, 1812 sizeof (iflpr->iflpr_input_bw)); 1813 break; 1814 } 1815 1816 case SIOCGIFQUEUESTATS: { /* struct if_qstatsreq */ 1817 struct if_qstatsreq *ifqr = (struct if_qstatsreq *)(void *)data; 1818 u_int32_t ifqr_len, ifqr_slot; 1819 1820 bcopy(&ifqr->ifqr_slot, &ifqr_slot, sizeof (ifqr_slot)); 1821 bcopy(&ifqr->ifqr_len, &ifqr_len, sizeof (ifqr_len)); 1822 error = ifclassq_getqstats(&ifp->if_snd, ifqr_slot, 1823 ifqr->ifqr_buf, &ifqr_len); 1824 if (error != 0) 1825 ifqr_len = 0; 1826 bcopy(&ifqr_len, &ifqr->ifqr_len, sizeof (ifqr_len)); 1827 break; 1828 } 1829 1830 case SIOCSIFTHROTTLE: { /* struct if_throttlereq */ 1831 struct if_throttlereq *ifthr = 1832 (struct if_throttlereq *)(void *)data; 1833 u_int32_t ifthr_level; 1834 1835 /* 1836 * XXX: Use priv_check_cred() instead of root check? 1837 */ 1838 if ((error = proc_suser(p)) != 0) 1839 break; 1840 1841 bcopy(&ifthr->ifthr_level, &ifthr_level, sizeof (ifthr_level)); 1842 error = ifnet_set_throttle(ifp, ifthr_level); 1843 if (error == EALREADY) 1844 error = 0; 1845 break; 1846 } 1847 1848 case SIOCGIFTHROTTLE: { /* struct if_throttlereq */ 1849 struct if_throttlereq *ifthr = 1850 (struct if_throttlereq *)(void *)data; 1851 u_int32_t ifthr_level; 1852 1853 if ((error = ifnet_get_throttle(ifp, &ifthr_level)) == 0) { 1854 bcopy(&ifthr_level, &ifthr->ifthr_level, 1855 sizeof (ifthr_level)); 1856 } 1857 break; 1858 } 1859 1860 default: 1861 if (so->so_proto == NULL) { 1862 error = EOPNOTSUPP; 1863 break; 1864 } 1865 1866 socket_lock(so, 1); 1867 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, 1868 data, ifp, p)); 1869 socket_unlock(so, 1); 1870 1871 if (error == EOPNOTSUPP || error == ENOTSUP) { 1872 error = ifnet_ioctl(ifp, 1873 so->so_proto->pr_domain->dom_family, cmd, data); 1874 } 1875 break; 1876 } 1877 1878done: 1879 if (ifs != NULL) 1880 _FREE(ifs, M_DEVBUF); 1881 1882 return (error); 1883} 1884 1885static int 1886ifioctl_ifreq(struct socket *so, u_long cmd, struct ifreq *ifr, struct proc *p) 1887{ 1888 struct ifnet *ifp; 1889 u_long ocmd = cmd; 1890 int error = 0; 1891 struct kev_msg ev_msg; 1892 struct net_event_data ev_data; 1893 1894 bzero(&ev_data, sizeof (struct net_event_data)); 1895 bzero(&ev_msg, sizeof (struct kev_msg)); 1896 1897 ifr->ifr_name[IFNAMSIZ - 1] = '\0'; 1898 1899 switch (cmd) { 1900 case SIOCIFCREATE: 1901 case SIOCIFCREATE2: 1902 error = proc_suser(p); 1903 if (error) 1904 return (error); 1905 return (if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name), 1906 cmd == SIOCIFCREATE2 ? ifr->ifr_data : NULL)); 1907 case SIOCIFDESTROY: 1908 error = proc_suser(p); 1909 if (error) 1910 return (error); 1911 return (if_clone_destroy(ifr->ifr_name)); 1912 } 1913 1914 ifp = ifunit(ifr->ifr_name); 1915 if (ifp == NULL) 1916 return (ENXIO); 1917 1918 switch (cmd) { 1919 case SIOCGIFFLAGS: 1920 ifnet_lock_shared(ifp); 1921 ifr->ifr_flags = ifp->if_flags; 1922 ifnet_lock_done(ifp); 1923 break; 1924 1925 case SIOCGIFEFLAGS: 1926 ifnet_lock_shared(ifp); 1927 ifr->ifr_eflags = ifp->if_eflags; 1928 ifnet_lock_done(ifp); 1929 break; 1930 1931 case SIOCGIFCAP: 1932 ifnet_lock_shared(ifp); 1933 ifr->ifr_reqcap = ifp->if_capabilities; 1934 ifr->ifr_curcap = ifp->if_capenable; 1935 ifnet_lock_done(ifp); 1936 break; 1937 1938#if CONFIG_MACF_NET 1939 case SIOCGIFMAC: 1940 error = mac_ifnet_label_get(kauth_cred_get(), ifr, ifp); 1941 break; 1942#endif 1943 case SIOCGIFMETRIC: 1944 ifnet_lock_shared(ifp); 1945 ifr->ifr_metric = ifp->if_metric; 1946 ifnet_lock_done(ifp); 1947 break; 1948 1949 case SIOCGIFMTU: 1950 ifnet_lock_shared(ifp); 1951 ifr->ifr_mtu = ifp->if_mtu; 1952 ifnet_lock_done(ifp); 1953 break; 1954 1955 case SIOCGIFPHYS: 1956 ifnet_lock_shared(ifp); 1957 ifr->ifr_phys = ifp->if_physical; 1958 ifnet_lock_done(ifp); 1959 break; 1960 1961 case SIOCGIFWAKEFLAGS: 1962 ifnet_lock_shared(ifp); 1963 ifr->ifr_wake_flags = ifnet_get_wake_flags(ifp); 1964 ifnet_lock_done(ifp); 1965 break; 1966 1967 case SIOCGIFGETRTREFCNT: 1968 ifnet_lock_shared(ifp); 1969 ifr->ifr_route_refcnt = ifp->if_route_refcnt; 1970 ifnet_lock_done(ifp); 1971 break; 1972 1973 case SIOCGIFLINKQUALITYMETRIC: 1974 ifnet_lock_shared(ifp); 1975 ifr->ifr_link_quality_metric = ifp->if_lqm; 1976 ifnet_lock_done(ifp); 1977 break; 1978 1979 case SIOCSIFFLAGS: 1980 error = proc_suser(p); 1981 if (error != 0) 1982 break; 1983 1984 (void) ifnet_set_flags(ifp, ifr->ifr_flags, 1985 (u_int16_t)~IFF_CANTCHANGE); 1986 1987 /* 1988 * Note that we intentionally ignore any error from below 1989 * for the SIOCSIFFLAGS case. 1990 */ 1991 (void) ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 1992 cmd, (caddr_t)ifr); 1993 1994 /* 1995 * Send the event even upon error from the driver because 1996 * we changed the flags. 1997 */ 1998 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1999 ev_msg.kev_class = KEV_NETWORK_CLASS; 2000 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 2001 2002 ev_msg.event_code = KEV_DL_SIFFLAGS; 2003 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 2004 ev_data.if_family = ifp->if_family; 2005 ev_data.if_unit = (u_int32_t) ifp->if_unit; 2006 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 2007 ev_msg.dv[0].data_ptr = &ev_data; 2008 ev_msg.dv[1].data_length = 0; 2009 kev_post_msg(&ev_msg); 2010 2011 ifnet_touch_lastchange(ifp); 2012 break; 2013 2014 case SIOCSIFCAP: 2015 error = proc_suser(p); 2016 if (error != 0) 2017 break; 2018 2019 if ((ifr->ifr_reqcap & ~ifp->if_capabilities)) { 2020 error = EINVAL; 2021 break; 2022 } 2023 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 2024 cmd, (caddr_t)ifr); 2025 2026 ifnet_touch_lastchange(ifp); 2027 break; 2028 2029#if CONFIG_MACF_NET 2030 case SIOCSIFMAC: 2031 error = mac_ifnet_label_set(kauth_cred_get(), ifr, ifp); 2032 break; 2033#endif 2034 case SIOCSIFMETRIC: 2035 error = proc_suser(p); 2036 if (error != 0) 2037 break; 2038 2039 ifp->if_metric = ifr->ifr_metric; 2040 2041 ev_msg.vendor_code = KEV_VENDOR_APPLE; 2042 ev_msg.kev_class = KEV_NETWORK_CLASS; 2043 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 2044 2045 ev_msg.event_code = KEV_DL_SIFMETRICS; 2046 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 2047 ev_data.if_family = ifp->if_family; 2048 ev_data.if_unit = (u_int32_t) ifp->if_unit; 2049 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 2050 ev_msg.dv[0].data_ptr = &ev_data; 2051 2052 ev_msg.dv[1].data_length = 0; 2053 kev_post_msg(&ev_msg); 2054 2055 ifnet_touch_lastchange(ifp); 2056 break; 2057 2058 case SIOCSIFPHYS: 2059 error = proc_suser(p); 2060 if (error != 0) 2061 break; 2062 2063 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 2064 cmd, (caddr_t)ifr); 2065 if (error != 0) 2066 break; 2067 2068 ev_msg.vendor_code = KEV_VENDOR_APPLE; 2069 ev_msg.kev_class = KEV_NETWORK_CLASS; 2070 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 2071 2072 ev_msg.event_code = KEV_DL_SIFPHYS; 2073 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 2074 ev_data.if_family = ifp->if_family; 2075 ev_data.if_unit = (u_int32_t) ifp->if_unit; 2076 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 2077 ev_msg.dv[0].data_ptr = &ev_data; 2078 ev_msg.dv[1].data_length = 0; 2079 kev_post_msg(&ev_msg); 2080 2081 ifnet_touch_lastchange(ifp); 2082 break; 2083 2084 case SIOCSIFMTU: { 2085 u_int32_t oldmtu = ifp->if_mtu; 2086 struct ifclassq *ifq = &ifp->if_snd; 2087 2088 error = proc_suser(p); 2089 if (error != 0) 2090 break; 2091 2092 if (ifp->if_ioctl == NULL) { 2093 error = EOPNOTSUPP; 2094 break; 2095 } 2096 if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU) { 2097 error = EINVAL; 2098 break; 2099 } 2100 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 2101 cmd, (caddr_t)ifr); 2102 if (error != 0) 2103 break; 2104 2105 ev_msg.vendor_code = KEV_VENDOR_APPLE; 2106 ev_msg.kev_class = KEV_NETWORK_CLASS; 2107 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 2108 2109 ev_msg.event_code = KEV_DL_SIFMTU; 2110 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 2111 ev_data.if_family = ifp->if_family; 2112 ev_data.if_unit = (u_int32_t) ifp->if_unit; 2113 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 2114 ev_msg.dv[0].data_ptr = &ev_data; 2115 ev_msg.dv[1].data_length = 0; 2116 kev_post_msg(&ev_msg); 2117 2118 ifnet_touch_lastchange(ifp); 2119 rt_ifmsg(ifp); 2120 2121 /* 2122 * If the link MTU changed, do network layer specific procedure 2123 * and update all route entries associated with the interface, 2124 * so that their MTU metric gets updated. 2125 */ 2126 if (ifp->if_mtu != oldmtu) { 2127 if_rtmtu_update(ifp); 2128#if INET6 2129 nd6_setmtu(ifp); 2130#endif 2131 /* Inform all transmit queues about the new MTU */ 2132 IFCQ_LOCK(ifq); 2133 ifnet_update_sndq(ifq, CLASSQ_EV_LINK_MTU); 2134 IFCQ_UNLOCK(ifq); 2135 } 2136 break; 2137 } 2138 2139 case SIOCADDMULTI: 2140 case SIOCDELMULTI: 2141 error = proc_suser(p); 2142 if (error != 0) 2143 break; 2144 2145 /* Don't allow group membership on non-multicast interfaces. */ 2146 if ((ifp->if_flags & IFF_MULTICAST) == 0) { 2147 error = EOPNOTSUPP; 2148 break; 2149 } 2150 2151 /* Don't let users screw up protocols' entries. */ 2152 if (ifr->ifr_addr.sa_family != AF_UNSPEC && 2153 ifr->ifr_addr.sa_family != AF_LINK) { 2154 error = EINVAL; 2155 break; 2156 } 2157 2158 /* 2159 * User is permitted to anonymously join a particular link 2160 * multicast group via SIOCADDMULTI. Subsequent join requested 2161 * for the same record which has an outstanding refcnt from a 2162 * past if_addmulti_anon() will not result in EADDRINUSE error 2163 * (unlike other BSDs.) Anonymously leaving a group is also 2164 * allowed only as long as there is an outstanding refcnt held 2165 * by a previous anonymous request, or else ENOENT (even if the 2166 * link-layer multicast membership exists for a network-layer 2167 * membership.) 2168 */ 2169 if (cmd == SIOCADDMULTI) { 2170 error = if_addmulti_anon(ifp, &ifr->ifr_addr, NULL); 2171 ev_msg.event_code = KEV_DL_ADDMULTI; 2172 } else { 2173 error = if_delmulti_anon(ifp, &ifr->ifr_addr); 2174 ev_msg.event_code = KEV_DL_DELMULTI; 2175 } 2176 if (error != 0) 2177 break; 2178 2179 ev_msg.vendor_code = KEV_VENDOR_APPLE; 2180 ev_msg.kev_class = KEV_NETWORK_CLASS; 2181 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 2182 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 2183 2184 ev_data.if_family = ifp->if_family; 2185 ev_data.if_unit = (u_int32_t) ifp->if_unit; 2186 ev_msg.dv[0].data_length = sizeof(struct net_event_data); 2187 ev_msg.dv[0].data_ptr = &ev_data; 2188 ev_msg.dv[1].data_length = 0; 2189 kev_post_msg(&ev_msg); 2190 2191 ifnet_touch_lastchange(ifp); 2192 break; 2193 2194 case SIOCDIFPHYADDR: 2195 case SIOCSIFMEDIA: 2196 case SIOCSIFGENERIC: 2197 case SIOCSIFLLADDR: 2198 case SIOCSIFALTMTU: 2199 case SIOCSIFVLAN: 2200 case SIOCSIFBOND: 2201 error = proc_suser(p); 2202 if (error != 0) 2203 break; 2204 2205 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 2206 cmd, (caddr_t)ifr); 2207 if (error != 0) 2208 break; 2209 2210 ifnet_touch_lastchange(ifp); 2211 break; 2212 2213 case SIOCGIFPSRCADDR: 2214 case SIOCGIFPDSTADDR: 2215 case SIOCGIFGENERIC: 2216 case SIOCGIFDEVMTU: 2217 case SIOCGIFVLAN: 2218 case SIOCGIFBOND: 2219 error = ifnet_ioctl(ifp, so->so_proto->pr_domain->dom_family, 2220 cmd, (caddr_t)ifr); 2221 break; 2222 2223 case SIOCSIFOPPORTUNISTIC: 2224 case SIOCGIFOPPORTUNISTIC: 2225 error = ifnet_getset_opportunistic(ifp, cmd, ifr, p); 2226 break; 2227 2228 case SIOCSIFDSTADDR: 2229 case SIOCSIFADDR: 2230 case SIOCSIFBRDADDR: 2231 case SIOCSIFNETMASK: 2232 case OSIOCGIFADDR: 2233 case OSIOCGIFDSTADDR: 2234 case OSIOCGIFBRDADDR: 2235 case OSIOCGIFNETMASK: 2236 case SIOCSIFKPI: 2237 VERIFY(so->so_proto != NULL); 2238 2239 if (cmd == SIOCSIFDSTADDR || cmd == SIOCSIFADDR || 2240 cmd == SIOCSIFBRDADDR || cmd == SIOCSIFNETMASK) { 2241#if BYTE_ORDER != BIG_ENDIAN 2242 if (ifr->ifr_addr.sa_family == 0 && 2243 ifr->ifr_addr.sa_len < 16) { 2244 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 2245 ifr->ifr_addr.sa_len = 16; 2246 } 2247#else 2248 if (ifr->ifr_addr.sa_len == 0) 2249 ifr->ifr_addr.sa_len = 16; 2250#endif 2251 } else if (cmd == OSIOCGIFADDR) { 2252 cmd = SIOCGIFADDR; /* struct ifreq */ 2253 } else if (cmd == OSIOCGIFDSTADDR) { 2254 cmd = SIOCGIFDSTADDR; /* struct ifreq */ 2255 } else if (cmd == OSIOCGIFBRDADDR) { 2256 cmd = SIOCGIFBRDADDR; /* struct ifreq */ 2257 } else if (cmd == OSIOCGIFNETMASK) { 2258 cmd = SIOCGIFNETMASK; /* struct ifreq */ 2259 } 2260 2261 socket_lock(so, 1); 2262 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, 2263 (caddr_t)ifr, ifp, p)); 2264 socket_unlock(so, 1); 2265 2266 switch (ocmd) { 2267 case OSIOCGIFADDR: 2268 case OSIOCGIFDSTADDR: 2269 case OSIOCGIFBRDADDR: 2270 case OSIOCGIFNETMASK: 2271 bcopy(&ifr->ifr_addr.sa_family, &ifr->ifr_addr, 2272 sizeof (u_short)); 2273 } 2274 2275 if (cmd == SIOCSIFKPI) { 2276 int temperr = proc_suser(p); 2277 if (temperr != 0) 2278 error = temperr; 2279 } 2280 2281 if (error == EOPNOTSUPP || error == ENOTSUP) { 2282 error = ifnet_ioctl(ifp, 2283 so->so_proto->pr_domain->dom_family, cmd, 2284 (caddr_t)ifr); 2285 } 2286 break; 2287 2288 default: 2289 VERIFY(0); 2290 /* NOTREACHED */ 2291 } 2292 2293 return (error); 2294} 2295 2296int 2297ifioctllocked(struct socket *so, u_long cmd, caddr_t data, struct proc *p) 2298{ 2299 int error; 2300 2301 socket_unlock(so, 0); 2302 error = ifioctl(so, cmd, data, p); 2303 socket_lock(so, 0); 2304 return(error); 2305} 2306 2307/* 2308 * Set/clear promiscuous mode on interface ifp based on the truth value 2309 * of pswitch. The calls are reference counted so that only the first 2310 * "on" request actually has an effect, as does the final "off" request. 2311 * Results are undefined if the "off" and "on" requests are not matched. 2312 */ 2313errno_t 2314ifnet_set_promiscuous( 2315 ifnet_t ifp, 2316 int pswitch) 2317{ 2318 int error = 0; 2319 int oldflags = 0; 2320 int newflags = 0; 2321 2322 ifnet_lock_exclusive(ifp); 2323 oldflags = ifp->if_flags; 2324 ifp->if_pcount += pswitch ? 1 : -1; 2325 2326 if (ifp->if_pcount > 0) 2327 ifp->if_flags |= IFF_PROMISC; 2328 else 2329 ifp->if_flags &= ~IFF_PROMISC; 2330 2331 newflags = ifp->if_flags; 2332 ifnet_lock_done(ifp); 2333 2334 if (newflags != oldflags && (newflags & IFF_UP) != 0) { 2335 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL); 2336 if (error == 0) { 2337 rt_ifmsg(ifp); 2338 } else { 2339 ifnet_lock_exclusive(ifp); 2340 // revert the flags 2341 ifp->if_pcount -= pswitch ? 1 : -1; 2342 if (ifp->if_pcount > 0) 2343 ifp->if_flags |= IFF_PROMISC; 2344 else 2345 ifp->if_flags &= ~IFF_PROMISC; 2346 ifnet_lock_done(ifp); 2347 } 2348 } 2349 2350 if (newflags != oldflags) { 2351 log(LOG_INFO, "%s%d: promiscuous mode %s%s\n", 2352 ifp->if_name, ifp->if_unit, 2353 (newflags & IFF_PROMISC) != 0 ? "enable" : "disable", 2354 error != 0 ? " failed" : " succeeded"); 2355 } 2356 return error; 2357} 2358 2359/* 2360 * Return interface configuration 2361 * of system. List may be used 2362 * in later ioctl's (above) to get 2363 * other information. 2364 */ 2365/*ARGSUSED*/ 2366static int 2367ifconf(u_long cmd, user_addr_t ifrp, int * ret_space) 2368{ 2369 struct ifnet *ifp = NULL; 2370 struct ifaddr *ifa; 2371 struct ifreq ifr; 2372 int error = 0; 2373 size_t space; 2374 2375 /* 2376 * Zero the ifr buffer to make sure we don't 2377 * disclose the contents of the stack. 2378 */ 2379 bzero(&ifr, sizeof(struct ifreq)); 2380 2381 space = *ret_space; 2382 ifnet_head_lock_shared(); 2383 for (ifp = ifnet_head.tqh_first; space > sizeof(ifr) && 2384 ifp; ifp = ifp->if_link.tqe_next) { 2385 char workbuf[64]; 2386 size_t ifnlen, addrs; 2387 2388 ifnlen = snprintf(workbuf, sizeof(workbuf), 2389 "%s%d", ifp->if_name, ifp->if_unit); 2390 if(ifnlen + 1 > sizeof ifr.ifr_name) { 2391 error = ENAMETOOLONG; 2392 break; 2393 } else { 2394 strlcpy(ifr.ifr_name, workbuf, IFNAMSIZ); 2395 } 2396 2397 ifnet_lock_shared(ifp); 2398 2399 addrs = 0; 2400 ifa = ifp->if_addrhead.tqh_first; 2401 for ( ; space > sizeof (ifr) && ifa; 2402 ifa = ifa->ifa_link.tqe_next) { 2403 struct sockaddr *sa; 2404 2405 IFA_LOCK(ifa); 2406 sa = ifa->ifa_addr; 2407#ifndef __APPLE__ 2408 if (curproc->p_prison && prison_if(curproc, sa)) { 2409 IFA_UNLOCK(ifa); 2410 continue; 2411 } 2412#endif 2413 addrs++; 2414 if (cmd == OSIOCGIFCONF32 || cmd == OSIOCGIFCONF64) { 2415 struct osockaddr *osa = 2416 (struct osockaddr *)(void *)&ifr.ifr_addr; 2417 ifr.ifr_addr = *sa; 2418 osa->sa_family = sa->sa_family; 2419 error = copyout((caddr_t)&ifr, ifrp, 2420 sizeof (ifr)); 2421 ifrp += sizeof(struct ifreq); 2422 } else if (sa->sa_len <= sizeof(*sa)) { 2423 ifr.ifr_addr = *sa; 2424 error = copyout((caddr_t)&ifr, ifrp, 2425 sizeof (ifr)); 2426 ifrp += sizeof(struct ifreq); 2427 } else { 2428 if (space < 2429 sizeof (ifr) + sa->sa_len - sizeof(*sa)) { 2430 IFA_UNLOCK(ifa); 2431 break; 2432 } 2433 space -= sa->sa_len - sizeof(*sa); 2434 error = copyout((caddr_t)&ifr, ifrp, 2435 sizeof (ifr.ifr_name)); 2436 if (error == 0) { 2437 error = copyout((caddr_t)sa, (ifrp + 2438 offsetof(struct ifreq, ifr_addr)), 2439 sa->sa_len); 2440 } 2441 ifrp += (sa->sa_len + offsetof(struct ifreq, 2442 ifr_addr)); 2443 } 2444 IFA_UNLOCK(ifa); 2445 if (error) 2446 break; 2447 space -= sizeof (ifr); 2448 } 2449 ifnet_lock_done(ifp); 2450 2451 if (error) 2452 break; 2453 if (!addrs) { 2454 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 2455 error = copyout((caddr_t)&ifr, ifrp, sizeof (ifr)); 2456 if (error) 2457 break; 2458 space -= sizeof (ifr); 2459 ifrp += sizeof(struct ifreq); 2460 } 2461 } 2462 ifnet_head_done(); 2463 *ret_space -= space; 2464 return (error); 2465} 2466 2467/* 2468 * Just like if_promisc(), but for all-multicast-reception mode. 2469 */ 2470int 2471if_allmulti(struct ifnet *ifp, int onswitch) 2472{ 2473 int error = 0; 2474 int modified = 0; 2475 2476 ifnet_lock_exclusive(ifp); 2477 2478 if (onswitch) { 2479 if (ifp->if_amcount++ == 0) { 2480 ifp->if_flags |= IFF_ALLMULTI; 2481 modified = 1; 2482 } 2483 } else { 2484 if (ifp->if_amcount > 1) { 2485 ifp->if_amcount--; 2486 } else { 2487 ifp->if_amcount = 0; 2488 ifp->if_flags &= ~IFF_ALLMULTI; 2489 modified = 1; 2490 } 2491 } 2492 ifnet_lock_done(ifp); 2493 2494 if (modified) 2495 error = ifnet_ioctl(ifp, 0, SIOCSIFFLAGS, NULL); 2496 2497 if (error == 0) 2498 rt_ifmsg(ifp); 2499 return error; 2500} 2501 2502static struct ifmultiaddr * 2503ifma_alloc(int how) 2504{ 2505 struct ifmultiaddr *ifma; 2506 2507 ifma = (how == M_WAITOK) ? zalloc(ifma_zone) : 2508 zalloc_noblock(ifma_zone); 2509 2510 if (ifma != NULL) { 2511 bzero(ifma, ifma_size); 2512 lck_mtx_init(&ifma->ifma_lock, ifa_mtx_grp, ifa_mtx_attr); 2513 ifma->ifma_debug |= IFD_ALLOC; 2514 if (ifma_debug != 0) { 2515 ifma->ifma_debug |= IFD_DEBUG; 2516 ifma->ifma_trace = ifma_trace; 2517 } 2518 } 2519 return (ifma); 2520} 2521 2522static void 2523ifma_free(struct ifmultiaddr *ifma) 2524{ 2525 IFMA_LOCK(ifma); 2526 2527 if (ifma->ifma_protospec != NULL) { 2528 panic("%s: Protospec not NULL for ifma=%p", __func__, ifma); 2529 /* NOTREACHED */ 2530 } else if ((ifma->ifma_flags & IFMAF_ANONYMOUS) || 2531 ifma->ifma_anoncnt != 0) { 2532 panic("%s: Freeing ifma=%p with outstanding anon req", 2533 __func__, ifma); 2534 /* NOTREACHED */ 2535 } else if (ifma->ifma_debug & IFD_ATTACHED) { 2536 panic("%s: ifma=%p attached to ifma_ifp=%p is being freed", 2537 __func__, ifma, ifma->ifma_ifp); 2538 /* NOTREACHED */ 2539 } else if (!(ifma->ifma_debug & IFD_ALLOC)) { 2540 panic("%s: ifma %p cannot be freed", __func__, ifma); 2541 /* NOTREACHED */ 2542 } else if (ifma->ifma_refcount != 0) { 2543 panic("%s: non-zero refcount ifma=%p", __func__, ifma); 2544 /* NOTREACHED */ 2545 } else if (ifma->ifma_reqcnt != 0) { 2546 panic("%s: non-zero reqcnt ifma=%p", __func__, ifma); 2547 /* NOTREACHED */ 2548 } else if (ifma->ifma_ifp != NULL) { 2549 panic("%s: non-NULL ifma_ifp=%p for ifma=%p", __func__, 2550 ifma->ifma_ifp, ifma); 2551 /* NOTREACHED */ 2552 } else if (ifma->ifma_ll != NULL) { 2553 panic("%s: non-NULL ifma_ll=%p for ifma=%p", __func__, 2554 ifma->ifma_ll, ifma); 2555 /* NOTREACHED */ 2556 } 2557 ifma->ifma_debug &= ~IFD_ALLOC; 2558 if ((ifma->ifma_debug & (IFD_DEBUG | IFD_TRASHED)) == 2559 (IFD_DEBUG | IFD_TRASHED)) { 2560 lck_mtx_lock(&ifma_trash_lock); 2561 TAILQ_REMOVE(&ifma_trash_head, (struct ifmultiaddr_dbg *)ifma, 2562 ifma_trash_link); 2563 lck_mtx_unlock(&ifma_trash_lock); 2564 ifma->ifma_debug &= ~IFD_TRASHED; 2565 } 2566 IFMA_UNLOCK(ifma); 2567 2568 if (ifma->ifma_addr != NULL) { 2569 FREE(ifma->ifma_addr, M_IFADDR); 2570 ifma->ifma_addr = NULL; 2571 } 2572 lck_mtx_destroy(&ifma->ifma_lock, ifa_mtx_grp); 2573 zfree(ifma_zone, ifma); 2574} 2575 2576static void 2577ifma_trace(struct ifmultiaddr *ifma, int refhold) 2578{ 2579 struct ifmultiaddr_dbg *ifma_dbg = (struct ifmultiaddr_dbg *)ifma; 2580 ctrace_t *tr; 2581 u_int32_t idx; 2582 u_int16_t *cnt; 2583 2584 if (!(ifma->ifma_debug & IFD_DEBUG)) { 2585 panic("%s: ifma %p has no debug structure", __func__, ifma); 2586 /* NOTREACHED */ 2587 } 2588 if (refhold) { 2589 cnt = &ifma_dbg->ifma_refhold_cnt; 2590 tr = ifma_dbg->ifma_refhold; 2591 } else { 2592 cnt = &ifma_dbg->ifma_refrele_cnt; 2593 tr = ifma_dbg->ifma_refrele; 2594 } 2595 2596 idx = atomic_add_16_ov(cnt, 1) % IFMA_TRACE_HIST_SIZE; 2597 ctrace_record(&tr[idx]); 2598} 2599 2600void 2601ifma_addref(struct ifmultiaddr *ifma, int locked) 2602{ 2603 if (!locked) 2604 IFMA_LOCK(ifma); 2605 else 2606 IFMA_LOCK_ASSERT_HELD(ifma); 2607 2608 if (++ifma->ifma_refcount == 0) { 2609 panic("%s: ifma=%p wraparound refcnt", __func__, ifma); 2610 /* NOTREACHED */ 2611 } else if (ifma->ifma_trace != NULL) { 2612 (*ifma->ifma_trace)(ifma, TRUE); 2613 } 2614 if (!locked) 2615 IFMA_UNLOCK(ifma); 2616} 2617 2618void 2619ifma_remref(struct ifmultiaddr *ifma) 2620{ 2621 struct ifmultiaddr *ll; 2622 2623 IFMA_LOCK(ifma); 2624 2625 if (ifma->ifma_refcount == 0) { 2626 panic("%s: ifma=%p negative refcnt", __func__, ifma); 2627 /* NOTREACHED */ 2628 } else if (ifma->ifma_trace != NULL) { 2629 (*ifma->ifma_trace)(ifma, FALSE); 2630 } 2631 2632 --ifma->ifma_refcount; 2633 if (ifma->ifma_refcount > 0) { 2634 IFMA_UNLOCK(ifma); 2635 return; 2636 } 2637 2638 ll = ifma->ifma_ll; 2639 ifma->ifma_ifp = NULL; 2640 ifma->ifma_ll = NULL; 2641 IFMA_UNLOCK(ifma); 2642 ifma_free(ifma); /* deallocate it */ 2643 2644 if (ll != NULL) 2645 IFMA_REMREF(ll); 2646} 2647 2648static void 2649if_attach_ifma(struct ifnet *ifp, struct ifmultiaddr *ifma, int anon) 2650{ 2651 ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE); 2652 IFMA_LOCK_ASSERT_HELD(ifma); 2653 2654 if (ifma->ifma_ifp != ifp) { 2655 panic("%s: Mismatch ifma_ifp=%p != ifp=%p", __func__, 2656 ifma->ifma_ifp, ifp); 2657 /* NOTREACHED */ 2658 } else if (ifma->ifma_debug & IFD_ATTACHED) { 2659 panic("%s: Attempt to attach an already attached ifma=%p", 2660 __func__, ifma); 2661 /* NOTREACHED */ 2662 } else if (anon && (ifma->ifma_flags & IFMAF_ANONYMOUS)) { 2663 panic("%s: ifma=%p unexpected IFMAF_ANONYMOUS", __func__, ifma); 2664 /* NOTREACHED */ 2665 } else if (ifma->ifma_debug & IFD_TRASHED) { 2666 panic("%s: Attempt to reattach a detached ifma=%p", 2667 __func__, ifma); 2668 /* NOTREACHED */ 2669 } 2670 2671 ifma->ifma_reqcnt++; 2672 VERIFY(ifma->ifma_reqcnt == 1); 2673 IFMA_ADDREF_LOCKED(ifma); 2674 ifma->ifma_debug |= IFD_ATTACHED; 2675 if (anon) { 2676 ifma->ifma_anoncnt++; 2677 VERIFY(ifma->ifma_anoncnt == 1); 2678 ifma->ifma_flags |= IFMAF_ANONYMOUS; 2679 } 2680 2681 LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link); 2682} 2683 2684static int 2685if_detach_ifma(struct ifnet *ifp, struct ifmultiaddr *ifma, int anon) 2686{ 2687 ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE); 2688 IFMA_LOCK_ASSERT_HELD(ifma); 2689 2690 if (ifma->ifma_reqcnt == 0) { 2691 panic("%s: ifma=%p negative reqcnt", __func__, ifma); 2692 /* NOTREACHED */ 2693 } else if (anon && !(ifma->ifma_flags & IFMAF_ANONYMOUS)) { 2694 panic("%s: ifma=%p missing IFMAF_ANONYMOUS", __func__, ifma); 2695 /* NOTREACHED */ 2696 } else if (anon && ifma->ifma_anoncnt == 0) { 2697 panic("%s: ifma=%p negative anonreqcnt", __func__, ifma); 2698 /* NOTREACHED */ 2699 } else if (ifma->ifma_ifp != ifp) { 2700 panic("%s: Mismatch ifma_ifp=%p, ifp=%p", __func__, 2701 ifma->ifma_ifp, ifp); 2702 /* NOTREACHED */ 2703 } 2704 2705 if (anon) { 2706 --ifma->ifma_anoncnt; 2707 if (ifma->ifma_anoncnt > 0) 2708 return (0); 2709 ifma->ifma_flags &= ~IFMAF_ANONYMOUS; 2710 } 2711 2712 --ifma->ifma_reqcnt; 2713 if (ifma->ifma_reqcnt > 0) 2714 return (0); 2715 2716 if (ifma->ifma_protospec != NULL) { 2717 panic("%s: Protospec not NULL for ifma=%p", __func__, ifma); 2718 /* NOTREACHED */ 2719 } else if ((ifma->ifma_flags & IFMAF_ANONYMOUS) || 2720 ifma->ifma_anoncnt != 0) { 2721 panic("%s: Detaching ifma=%p with outstanding anon req", 2722 __func__, ifma); 2723 /* NOTREACHED */ 2724 } else if (!(ifma->ifma_debug & IFD_ATTACHED)) { 2725 panic("%s: Attempt to detach an unattached address ifma=%p", 2726 __func__, ifma); 2727 /* NOTREACHED */ 2728 } else if (ifma->ifma_debug & IFD_TRASHED) { 2729 panic("%s: ifma %p is already in trash list", __func__, ifma); 2730 /* NOTREACHED */ 2731 } 2732 2733 /* 2734 * NOTE: Caller calls IFMA_REMREF 2735 */ 2736 ifma->ifma_debug &= ~IFD_ATTACHED; 2737 LIST_REMOVE(ifma, ifma_link); 2738 if (LIST_EMPTY(&ifp->if_multiaddrs)) 2739 ifp->if_updatemcasts = 0; 2740 2741 if (ifma->ifma_debug & IFD_DEBUG) { 2742 /* Become a regular mutex, just in case */ 2743 IFMA_CONVERT_LOCK(ifma); 2744 lck_mtx_lock(&ifma_trash_lock); 2745 TAILQ_INSERT_TAIL(&ifma_trash_head, 2746 (struct ifmultiaddr_dbg *)ifma, ifma_trash_link); 2747 lck_mtx_unlock(&ifma_trash_lock); 2748 ifma->ifma_debug |= IFD_TRASHED; 2749 } 2750 2751 return (1); 2752} 2753 2754/* 2755 * Find an ifmultiaddr that matches a socket address on an interface. 2756 * 2757 * Caller is responsible for holding the ifnet_lock while calling 2758 * this function. 2759 */ 2760static int 2761if_addmulti_doesexist(struct ifnet *ifp, const struct sockaddr *sa, 2762 struct ifmultiaddr **retifma, int anon) 2763{ 2764 struct ifmultiaddr *ifma; 2765 2766 for (ifma = LIST_FIRST(&ifp->if_multiaddrs); ifma != NULL; 2767 ifma = LIST_NEXT(ifma, ifma_link)) { 2768 IFMA_LOCK_SPIN(ifma); 2769 if (!equal(sa, ifma->ifma_addr)) { 2770 IFMA_UNLOCK(ifma); 2771 continue; 2772 } 2773 if (anon) { 2774 VERIFY(!(ifma->ifma_flags & IFMAF_ANONYMOUS) || 2775 ifma->ifma_anoncnt != 0); 2776 VERIFY((ifma->ifma_flags & IFMAF_ANONYMOUS) || 2777 ifma->ifma_anoncnt == 0); 2778 ifma->ifma_anoncnt++; 2779 if (!(ifma->ifma_flags & IFMAF_ANONYMOUS)) { 2780 VERIFY(ifma->ifma_anoncnt == 1); 2781 ifma->ifma_flags |= IFMAF_ANONYMOUS; 2782 } 2783 } 2784 if (!anon || ifma->ifma_anoncnt == 1) { 2785 ifma->ifma_reqcnt++; 2786 VERIFY(ifma->ifma_reqcnt > 1); 2787 } 2788 if (retifma != NULL) { 2789 *retifma = ifma; 2790 IFMA_ADDREF_LOCKED(ifma); 2791 } 2792 IFMA_UNLOCK(ifma); 2793 return (0); 2794 } 2795 return (ENOENT); 2796} 2797 2798/* 2799 * Radar 3642395, make sure all multicasts are in a standard format. 2800 */ 2801static struct sockaddr* 2802copy_and_normalize(const struct sockaddr *original) 2803{ 2804 int alen = 0; 2805 const u_char *aptr = NULL; 2806 struct sockaddr *copy = NULL; 2807 struct sockaddr_dl *sdl_new = NULL; 2808 int len = 0; 2809 2810 if (original->sa_family != AF_LINK && 2811 original->sa_family != AF_UNSPEC) { 2812 /* Just make a copy */ 2813 MALLOC(copy, struct sockaddr*, original->sa_len, 2814 M_IFADDR, M_WAITOK); 2815 if (copy != NULL) 2816 bcopy(original, copy, original->sa_len); 2817 return (copy); 2818 } 2819 2820 switch (original->sa_family) { 2821 case AF_LINK: { 2822 const struct sockaddr_dl *sdl_original = 2823 (struct sockaddr_dl*)(uintptr_t)(size_t)original; 2824 2825 if (sdl_original->sdl_nlen + sdl_original->sdl_alen + 2826 sdl_original->sdl_slen + 2827 offsetof(struct sockaddr_dl, sdl_data) > 2828 sdl_original->sdl_len) 2829 return (NULL); 2830 2831 alen = sdl_original->sdl_alen; 2832 aptr = CONST_LLADDR(sdl_original); 2833 } 2834 break; 2835 2836 case AF_UNSPEC: { 2837 if (original->sa_len < ETHER_ADDR_LEN + 2838 offsetof(struct sockaddr, sa_data)) { 2839 return (NULL); 2840 } 2841 2842 alen = ETHER_ADDR_LEN; 2843 aptr = (const u_char*)original->sa_data; 2844 } 2845 break; 2846 } 2847 2848 if (alen == 0 || aptr == NULL) 2849 return (NULL); 2850 2851 len = alen + offsetof(struct sockaddr_dl, sdl_data); 2852 MALLOC(sdl_new, struct sockaddr_dl*, len, M_IFADDR, M_WAITOK); 2853 2854 if (sdl_new != NULL) { 2855 bzero(sdl_new, len); 2856 sdl_new->sdl_len = len; 2857 sdl_new->sdl_family = AF_LINK; 2858 sdl_new->sdl_alen = alen; 2859 bcopy(aptr, LLADDR(sdl_new), alen); 2860 } 2861 2862 return ((struct sockaddr*)sdl_new); 2863} 2864 2865/* 2866 * Network-layer protocol domains which hold references to the underlying 2867 * link-layer record must use this routine. 2868 */ 2869int 2870if_addmulti(struct ifnet *ifp, const struct sockaddr *sa, 2871 struct ifmultiaddr **retifma) 2872{ 2873 return (if_addmulti_common(ifp, sa, retifma, 0)); 2874} 2875 2876/* 2877 * Anything other than network-layer protocol domains which hold references 2878 * to the underlying link-layer record must use this routine: SIOCADDMULTI 2879 * ioctl, ifnet_add_multicast(), AppleTalk, if_bond. 2880 */ 2881int 2882if_addmulti_anon(struct ifnet *ifp, const struct sockaddr *sa, 2883 struct ifmultiaddr **retifma) 2884{ 2885 return (if_addmulti_common(ifp, sa, retifma, 1)); 2886} 2887 2888/* 2889 * Register an additional multicast address with a network interface. 2890 * 2891 * - If the address is already present, bump the reference count on the 2892 * address and return. 2893 * - If the address is not link-layer, look up a link layer address. 2894 * - Allocate address structures for one or both addresses, and attach to the 2895 * multicast address list on the interface. If automatically adding a link 2896 * layer address, the protocol address will own a reference to the link 2897 * layer address, to be freed when it is freed. 2898 * - Notify the network device driver of an addition to the multicast address 2899 * list. 2900 * 2901 * 'sa' points to caller-owned memory with the desired multicast address. 2902 * 2903 * 'retifma' will be used to return a pointer to the resulting multicast 2904 * address reference, if desired. 2905 * 2906 * 'anon' indicates a link-layer address with no protocol address reference 2907 * made to it. Anything other than network-layer protocol domain requests 2908 * are considered as anonymous. 2909 */ 2910static int 2911if_addmulti_common(struct ifnet *ifp, const struct sockaddr *sa, 2912 struct ifmultiaddr **retifma, int anon) 2913{ 2914 struct sockaddr_storage storage; 2915 struct sockaddr *llsa = NULL; 2916 struct sockaddr *dupsa = NULL; 2917 int error = 0, ll_firstref = 0, lladdr; 2918 struct ifmultiaddr *ifma = NULL; 2919 struct ifmultiaddr *llifma = NULL; 2920 2921 /* Only AF_UNSPEC/AF_LINK is allowed for an "anonymous" address */ 2922 VERIFY(!anon || sa->sa_family == AF_UNSPEC || 2923 sa->sa_family == AF_LINK); 2924 2925 /* If sa is a AF_LINK or AF_UNSPEC, duplicate and normalize it */ 2926 if (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC) { 2927 dupsa = copy_and_normalize(sa); 2928 if (dupsa == NULL) { 2929 error = ENOMEM; 2930 goto cleanup; 2931 } 2932 sa = dupsa; 2933 } 2934 2935 ifnet_lock_exclusive(ifp); 2936 if (!(ifp->if_flags & IFF_MULTICAST)) { 2937 error = EADDRNOTAVAIL; 2938 ifnet_lock_done(ifp); 2939 goto cleanup; 2940 } 2941 2942 /* If the address is already present, return a new reference to it */ 2943 error = if_addmulti_doesexist(ifp, sa, retifma, anon); 2944 ifnet_lock_done(ifp); 2945 if (error == 0) 2946 goto cleanup; 2947 2948 /* 2949 * The address isn't already present; give the link layer a chance 2950 * to accept/reject it, and also find out which AF_LINK address this 2951 * maps to, if it isn't one already. 2952 */ 2953 error = dlil_resolve_multi(ifp, sa, (struct sockaddr *)&storage, 2954 sizeof (storage)); 2955 if (error == 0 && storage.ss_len != 0) { 2956 llsa = copy_and_normalize((struct sockaddr *)&storage); 2957 if (llsa == NULL) { 2958 error = ENOMEM; 2959 goto cleanup; 2960 } 2961 2962 llifma = ifma_alloc(M_WAITOK); 2963 if (llifma == NULL) { 2964 error = ENOMEM; 2965 goto cleanup; 2966 } 2967 } 2968 2969 /* to be similar to FreeBSD */ 2970 if (error == EOPNOTSUPP) 2971 error = 0; 2972 else if (error != 0) 2973 goto cleanup; 2974 2975 /* Allocate while we aren't holding any locks */ 2976 if (dupsa == NULL) { 2977 dupsa = copy_and_normalize(sa); 2978 if (dupsa == NULL) { 2979 error = ENOMEM; 2980 goto cleanup; 2981 } 2982 } 2983 ifma = ifma_alloc(M_WAITOK); 2984 if (ifma == NULL) { 2985 error = ENOMEM; 2986 goto cleanup; 2987 } 2988 2989 ifnet_lock_exclusive(ifp); 2990 /* 2991 * Check again for the matching multicast. 2992 */ 2993 error = if_addmulti_doesexist(ifp, sa, retifma, anon); 2994 if (error == 0) { 2995 ifnet_lock_done(ifp); 2996 goto cleanup; 2997 } 2998 2999 if (llifma != NULL) { 3000 VERIFY(!anon); /* must not get here if "anonymous" */ 3001 if (if_addmulti_doesexist(ifp, llsa, &ifma->ifma_ll, 0) == 0) { 3002 FREE(llsa, M_IFADDR); 3003 llsa = NULL; 3004 ifma_free(llifma); 3005 llifma = NULL; 3006 VERIFY(ifma->ifma_ll->ifma_ifp == ifp); 3007 } else { 3008 ll_firstref = 1; 3009 llifma->ifma_addr = llsa; 3010 llifma->ifma_ifp = ifp; 3011 IFMA_LOCK(llifma); 3012 if_attach_ifma(ifp, llifma, 0); 3013 /* add extra refcnt for ifma */ 3014 IFMA_ADDREF_LOCKED(llifma); 3015 IFMA_UNLOCK(llifma); 3016 ifma->ifma_ll = llifma; 3017 } 3018 } 3019 3020 /* "anonymous" request should not result in network address */ 3021 VERIFY(!anon || ifma->ifma_ll == NULL); 3022 3023 ifma->ifma_addr = dupsa; 3024 ifma->ifma_ifp = ifp; 3025 IFMA_LOCK(ifma); 3026 if_attach_ifma(ifp, ifma, anon); 3027 IFMA_ADDREF_LOCKED(ifma); /* for this routine */ 3028 if (retifma != NULL) { 3029 *retifma = ifma; 3030 IFMA_ADDREF_LOCKED(*retifma); /* for caller */ 3031 } 3032 lladdr = (ifma->ifma_addr->sa_family == AF_UNSPEC || 3033 ifma->ifma_addr->sa_family == AF_LINK); 3034 IFMA_UNLOCK(ifma); 3035 ifnet_lock_done(ifp); 3036 3037 rt_newmaddrmsg(RTM_NEWMADDR, ifma); 3038 IFMA_REMREF(ifma); /* for this routine */ 3039 3040 /* 3041 * We are certain we have added something, so call down to the 3042 * interface to let them know about it. Do this only for newly- 3043 * added AF_LINK/AF_UNSPEC address in the if_multiaddrs set. 3044 */ 3045 if (lladdr || ll_firstref) 3046 (void) ifnet_ioctl(ifp, 0, SIOCADDMULTI, NULL); 3047 3048 if (ifp->if_updatemcasts > 0) 3049 ifp->if_updatemcasts = 0; 3050 3051 return (0); 3052 3053cleanup: 3054 if (ifma != NULL) 3055 ifma_free(ifma); 3056 if (dupsa != NULL) 3057 FREE(dupsa, M_IFADDR); 3058 if (llifma != NULL) 3059 ifma_free(llifma); 3060 if (llsa != NULL) 3061 FREE(llsa, M_IFADDR); 3062 3063 return (error); 3064} 3065 3066/* 3067 * Delete a multicast group membership by network-layer group address. 3068 * This routine is deprecated. 3069 */ 3070int 3071if_delmulti(struct ifnet *ifp, const struct sockaddr *sa) 3072{ 3073 return (if_delmulti_common(NULL, ifp, sa, 0)); 3074} 3075 3076/* 3077 * Delete a multicast group membership by group membership pointer. 3078 * Network-layer protocol domains must use this routine. 3079 */ 3080int 3081if_delmulti_ifma(struct ifmultiaddr *ifma) 3082{ 3083 return (if_delmulti_common(ifma, NULL, NULL, 0)); 3084} 3085 3086/* 3087 * Anything other than network-layer protocol domains which hold references 3088 * to the underlying link-layer record must use this routine: SIOCDELMULTI 3089 * ioctl, ifnet_remove_multicast(), AppleTalk, if_bond. 3090 */ 3091int 3092if_delmulti_anon(struct ifnet *ifp, const struct sockaddr *sa) 3093{ 3094 return (if_delmulti_common(NULL, ifp, sa, 1)); 3095} 3096 3097/* 3098 * Delete a multicast group membership by network-layer group address. 3099 * 3100 * Returns ENOENT if the entry could not be found. 3101 */ 3102static int 3103if_delmulti_common(struct ifmultiaddr *ifma, struct ifnet *ifp, 3104 const struct sockaddr *sa, int anon) 3105{ 3106 struct sockaddr *dupsa = NULL; 3107 int lastref, ll_lastref = 0, lladdr; 3108 struct ifmultiaddr *ll = NULL; 3109 3110 /* sanity check for callers */ 3111 VERIFY(ifma != NULL || (ifp != NULL && sa != NULL)); 3112 3113 if (ifma != NULL) 3114 ifp = ifma->ifma_ifp; 3115 3116 if (sa != NULL && 3117 (sa->sa_family == AF_LINK || sa->sa_family == AF_UNSPEC)) { 3118 dupsa = copy_and_normalize(sa); 3119 if (dupsa == NULL) 3120 return (ENOMEM); 3121 sa = dupsa; 3122 } 3123 3124 ifnet_lock_exclusive(ifp); 3125 if (ifma == NULL) { 3126 for (ifma = LIST_FIRST(&ifp->if_multiaddrs); ifma != NULL; 3127 ifma = LIST_NEXT(ifma, ifma_link)) { 3128 IFMA_LOCK(ifma); 3129 if (!equal(sa, ifma->ifma_addr) || 3130 (anon && !(ifma->ifma_flags & IFMAF_ANONYMOUS))) { 3131 VERIFY(!(ifma->ifma_flags & IFMAF_ANONYMOUS) || 3132 ifma->ifma_anoncnt != 0); 3133 IFMA_UNLOCK(ifma); 3134 continue; 3135 } 3136 /* found; keep it locked */ 3137 break; 3138 } 3139 if (ifma == NULL) { 3140 if (dupsa != NULL) 3141 FREE(dupsa, M_IFADDR); 3142 ifnet_lock_done(ifp); 3143 return (ENOENT); 3144 } 3145 } else { 3146 IFMA_LOCK(ifma); 3147 } 3148 IFMA_LOCK_ASSERT_HELD(ifma); 3149 IFMA_ADDREF_LOCKED(ifma); /* for this routine */ 3150 lastref = if_detach_ifma(ifp, ifma, anon); 3151 VERIFY(!lastref || (!(ifma->ifma_debug & IFD_ATTACHED) && 3152 ifma->ifma_reqcnt == 0)); 3153 VERIFY(!anon || ifma->ifma_ll == NULL); 3154 ll = ifma->ifma_ll; 3155 lladdr = (ifma->ifma_addr->sa_family == AF_UNSPEC || 3156 ifma->ifma_addr->sa_family == AF_LINK); 3157 IFMA_UNLOCK(ifma); 3158 if (lastref && ll != NULL) { 3159 IFMA_LOCK(ll); 3160 ll_lastref = if_detach_ifma(ifp, ll, 0); 3161 IFMA_UNLOCK(ll); 3162 } 3163 ifnet_lock_done(ifp); 3164 3165 if (lastref) 3166 rt_newmaddrmsg(RTM_DELMADDR, ifma); 3167 3168 if ((ll == NULL && lastref && lladdr) || ll_lastref) { 3169 /* 3170 * Make sure the interface driver is notified in the 3171 * case of a link layer mcast group being left. Do 3172 * this only for a AF_LINK/AF_UNSPEC address that has 3173 * been removed from the if_multiaddrs set. 3174 */ 3175 ifnet_ioctl(ifp, 0, SIOCDELMULTI, NULL); 3176 } 3177 3178 if (lastref) 3179 IFMA_REMREF(ifma); /* for if_multiaddrs list */ 3180 if (ll_lastref) 3181 IFMA_REMREF(ll); /* for if_multiaddrs list */ 3182 3183 IFMA_REMREF(ifma); /* for this routine */ 3184 if (dupsa != NULL) 3185 FREE(dupsa, M_IFADDR); 3186 3187 return (0); 3188} 3189 3190/* 3191 * We don't use if_setlladdr, our interfaces are responsible for 3192 * handling the SIOCSIFLLADDR ioctl. 3193 */ 3194#ifndef __APPLE__ 3195int 3196if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len) 3197{ 3198 ... 3199} 3200#endif 3201 3202SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Link layers"); 3203SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "Generic link-management"); 3204 3205 3206/* 3207 * Shutdown all network activity. Used boot() when halting 3208 * system. 3209 */ 3210int 3211if_down_all(void) 3212{ 3213 struct ifnet **ifp; 3214 u_int32_t count; 3215 u_int32_t i; 3216 3217 if (ifnet_list_get_all(IFNET_FAMILY_ANY, &ifp, &count) == 0) { 3218 for (i = 0; i < count; i++) { 3219 if_down(ifp[i]); 3220 dlil_proto_unplumb_all(ifp[i]); 3221 } 3222 ifnet_list_free(ifp); 3223 } 3224 3225 return 0; 3226} 3227 3228/* 3229 * Delete Routes for a Network Interface 3230 * 3231 * Called for each routing entry via the rnh->rnh_walktree() call above 3232 * to delete all route entries referencing a detaching network interface. 3233 * 3234 * Arguments: 3235 * rn pointer to node in the routing table 3236 * arg argument passed to rnh->rnh_walktree() - detaching interface 3237 * 3238 * Returns: 3239 * 0 successful 3240 * errno failed - reason indicated 3241 * 3242 */ 3243static int 3244if_rtdel(struct radix_node *rn, void *arg) 3245{ 3246 struct rtentry *rt = (struct rtentry *)rn; 3247 struct ifnet *ifp = arg; 3248 int err; 3249 3250 if (rt == NULL) 3251 return (0); 3252 /* 3253 * Checking against RTF_UP protects against walktree 3254 * recursion problems with cloned routes. 3255 */ 3256 RT_LOCK(rt); 3257 if (rt->rt_ifp == ifp && (rt->rt_flags & RTF_UP)) { 3258 /* 3259 * Safe to drop rt_lock and use rt_key, rt_gateway, 3260 * since holding rnh_lock here prevents another thread 3261 * from calling rt_setgate() on this route. 3262 */ 3263 RT_UNLOCK(rt); 3264 err = rtrequest_locked(RTM_DELETE, rt_key(rt), rt->rt_gateway, 3265 rt_mask(rt), rt->rt_flags, NULL); 3266 if (err) { 3267 log(LOG_WARNING, "if_rtdel: error %d\n", err); 3268 } 3269 } else { 3270 RT_UNLOCK(rt); 3271 } 3272 return (0); 3273} 3274 3275/* 3276 * Removes routing table reference to a given interface 3277 * for a given protocol family 3278 */ 3279void 3280if_rtproto_del(struct ifnet *ifp, int protocol) 3281{ 3282 struct radix_node_head *rnh; 3283 3284 if (use_routegenid) 3285 routegenid_update(); 3286 if ((protocol <= AF_MAX) && (protocol >= 0) && 3287 ((rnh = rt_tables[protocol]) != NULL) && (ifp != NULL)) { 3288 lck_mtx_lock(rnh_lock); 3289 (void) rnh->rnh_walktree(rnh, if_rtdel, ifp); 3290 lck_mtx_unlock(rnh_lock); 3291 } 3292} 3293 3294static int 3295if_rtmtu(struct radix_node *rn, void *arg) 3296{ 3297 struct rtentry *rt = (struct rtentry *)rn; 3298 struct ifnet *ifp = arg; 3299 3300 RT_LOCK(rt); 3301 if (rt->rt_ifp == ifp) { 3302 /* 3303 * Update the MTU of this entry only if the MTU 3304 * has not been locked (RTV_MTU is not set) and 3305 * if it was non-zero to begin with. 3306 */ 3307 if (!(rt->rt_rmx.rmx_locks & RTV_MTU) && rt->rt_rmx.rmx_mtu) 3308 rt->rt_rmx.rmx_mtu = ifp->if_mtu; 3309 } 3310 RT_UNLOCK(rt); 3311 3312 return (0); 3313} 3314 3315/* 3316 * Update the MTU metric of all route entries in all protocol tables 3317 * associated with a particular interface; this is called when the 3318 * MTU of that interface has changed. 3319 */ 3320static 3321void if_rtmtu_update(struct ifnet *ifp) 3322{ 3323 struct radix_node_head *rnh; 3324 int p; 3325 3326 for (p = 0; p < AF_MAX + 1; p++) { 3327 if ((rnh = rt_tables[p]) == NULL) 3328 continue; 3329 3330 lck_mtx_lock(rnh_lock); 3331 (void) rnh->rnh_walktree(rnh, if_rtmtu, ifp); 3332 lck_mtx_unlock(rnh_lock); 3333 } 3334 3335 if (use_routegenid) 3336 routegenid_update(); 3337} 3338 3339__private_extern__ void 3340if_data_internal_to_if_data(struct ifnet *ifp, 3341 const struct if_data_internal *if_data_int, struct if_data *if_data) 3342{ 3343#pragma unused(ifp) 3344#define COPYFIELD(fld) if_data->fld = if_data_int->fld 3345#define COPYFIELD32(fld) if_data->fld = (u_int32_t)(if_data_int->fld) 3346/* compiler will cast down to 32-bit */ 3347#define COPYFIELD32_ATOMIC(fld) do { \ 3348 atomic_get_64(if_data->fld, \ 3349 (u_int64_t *)(void *)(uintptr_t)&if_data_int->fld); \ 3350} while (0) 3351 3352 COPYFIELD(ifi_type); 3353 COPYFIELD(ifi_typelen); 3354 COPYFIELD(ifi_physical); 3355 COPYFIELD(ifi_addrlen); 3356 COPYFIELD(ifi_hdrlen); 3357 COPYFIELD(ifi_recvquota); 3358 COPYFIELD(ifi_xmitquota); 3359 if_data->ifi_unused1 = 0; 3360 COPYFIELD(ifi_mtu); 3361 COPYFIELD(ifi_metric); 3362 if (if_data_int->ifi_baudrate & 0xFFFFFFFF00000000LL) { 3363 if_data->ifi_baudrate = 0xFFFFFFFF; 3364 } else { 3365 COPYFIELD32(ifi_baudrate); 3366 } 3367 3368 COPYFIELD32_ATOMIC(ifi_ipackets); 3369 COPYFIELD32_ATOMIC(ifi_ierrors); 3370 COPYFIELD32_ATOMIC(ifi_opackets); 3371 COPYFIELD32_ATOMIC(ifi_oerrors); 3372 COPYFIELD32_ATOMIC(ifi_collisions); 3373 COPYFIELD32_ATOMIC(ifi_ibytes); 3374 COPYFIELD32_ATOMIC(ifi_obytes); 3375 COPYFIELD32_ATOMIC(ifi_imcasts); 3376 COPYFIELD32_ATOMIC(ifi_omcasts); 3377 COPYFIELD32_ATOMIC(ifi_iqdrops); 3378 COPYFIELD32_ATOMIC(ifi_noproto); 3379 3380 COPYFIELD(ifi_recvtiming); 3381 COPYFIELD(ifi_xmittiming); 3382 3383 if_data->ifi_lastchange.tv_sec = if_data_int->ifi_lastchange.tv_sec; 3384 if_data->ifi_lastchange.tv_usec = if_data_int->ifi_lastchange.tv_usec; 3385 3386#if IF_LASTCHANGEUPTIME 3387 if_data->ifi_lastchange.tv_sec += boottime_sec(); 3388#endif 3389 3390 if_data->ifi_unused2 = 0; 3391 COPYFIELD(ifi_hwassist); 3392 if_data->ifi_reserved1 = 0; 3393 if_data->ifi_reserved2 = 0; 3394#undef COPYFIELD32_ATOMIC 3395#undef COPYFIELD32 3396#undef COPYFIELD 3397} 3398 3399__private_extern__ void 3400if_data_internal_to_if_data64(struct ifnet *ifp, 3401 const struct if_data_internal *if_data_int, 3402 struct if_data64 *if_data64) 3403{ 3404#pragma unused(ifp) 3405#define COPYFIELD64(fld) if_data64->fld = if_data_int->fld 3406#define COPYFIELD64_ATOMIC(fld) do { \ 3407 atomic_get_64(if_data64->fld, \ 3408 (u_int64_t *)(void *)(uintptr_t)&if_data_int->fld); \ 3409} while (0) 3410 3411 COPYFIELD64(ifi_type); 3412 COPYFIELD64(ifi_typelen); 3413 COPYFIELD64(ifi_physical); 3414 COPYFIELD64(ifi_addrlen); 3415 COPYFIELD64(ifi_hdrlen); 3416 COPYFIELD64(ifi_recvquota); 3417 COPYFIELD64(ifi_xmitquota); 3418 if_data64->ifi_unused1 = 0; 3419 COPYFIELD64(ifi_mtu); 3420 COPYFIELD64(ifi_metric); 3421 COPYFIELD64(ifi_baudrate); 3422 3423 COPYFIELD64_ATOMIC(ifi_ipackets); 3424 COPYFIELD64_ATOMIC(ifi_ierrors); 3425 COPYFIELD64_ATOMIC(ifi_opackets); 3426 COPYFIELD64_ATOMIC(ifi_oerrors); 3427 COPYFIELD64_ATOMIC(ifi_collisions); 3428 COPYFIELD64_ATOMIC(ifi_ibytes); 3429 COPYFIELD64_ATOMIC(ifi_obytes); 3430 COPYFIELD64_ATOMIC(ifi_imcasts); 3431 COPYFIELD64_ATOMIC(ifi_omcasts); 3432 COPYFIELD64_ATOMIC(ifi_iqdrops); 3433 COPYFIELD64_ATOMIC(ifi_noproto); 3434 3435 /* Note these two fields are actually 32 bit, so doing COPYFIELD64_ATOMIC will 3436 * cause them to be misaligned 3437 */ 3438 COPYFIELD64(ifi_recvtiming); 3439 COPYFIELD64(ifi_xmittiming); 3440 3441 if_data64->ifi_lastchange.tv_sec = if_data_int->ifi_lastchange.tv_sec; 3442 if_data64->ifi_lastchange.tv_usec = if_data_int->ifi_lastchange.tv_usec; 3443 3444#if IF_LASTCHANGEUPTIME 3445 if_data64->ifi_lastchange.tv_sec += boottime_sec(); 3446#endif 3447 3448#undef COPYFIELD64 3449} 3450 3451__private_extern__ void 3452if_copy_traffic_class(struct ifnet *ifp, 3453 struct if_traffic_class *if_tc) 3454{ 3455#define COPY_IF_TC_FIELD64_ATOMIC(fld) do { \ 3456 atomic_get_64(if_tc->fld, \ 3457 (u_int64_t *)(void *)(uintptr_t)&ifp->if_tc.fld); \ 3458} while (0) 3459 3460 bzero(if_tc, sizeof (*if_tc)); 3461 COPY_IF_TC_FIELD64_ATOMIC(ifi_ibepackets); 3462 COPY_IF_TC_FIELD64_ATOMIC(ifi_ibebytes); 3463 COPY_IF_TC_FIELD64_ATOMIC(ifi_obepackets); 3464 COPY_IF_TC_FIELD64_ATOMIC(ifi_obebytes); 3465 COPY_IF_TC_FIELD64_ATOMIC(ifi_ibkpackets); 3466 COPY_IF_TC_FIELD64_ATOMIC(ifi_ibkbytes); 3467 COPY_IF_TC_FIELD64_ATOMIC(ifi_obkpackets); 3468 COPY_IF_TC_FIELD64_ATOMIC(ifi_obkbytes); 3469 COPY_IF_TC_FIELD64_ATOMIC(ifi_ivipackets); 3470 COPY_IF_TC_FIELD64_ATOMIC(ifi_ivibytes); 3471 COPY_IF_TC_FIELD64_ATOMIC(ifi_ovipackets); 3472 COPY_IF_TC_FIELD64_ATOMIC(ifi_ovibytes); 3473 COPY_IF_TC_FIELD64_ATOMIC(ifi_ivopackets); 3474 COPY_IF_TC_FIELD64_ATOMIC(ifi_ivobytes); 3475 COPY_IF_TC_FIELD64_ATOMIC(ifi_ovopackets); 3476 COPY_IF_TC_FIELD64_ATOMIC(ifi_ovobytes); 3477 COPY_IF_TC_FIELD64_ATOMIC(ifi_ipvpackets); 3478 COPY_IF_TC_FIELD64_ATOMIC(ifi_ipvbytes); 3479 COPY_IF_TC_FIELD64_ATOMIC(ifi_opvpackets); 3480 COPY_IF_TC_FIELD64_ATOMIC(ifi_opvbytes); 3481 3482#undef COPY_IF_TC_FIELD64_ATOMIC 3483} 3484 3485void 3486if_copy_data_extended(struct ifnet *ifp, struct if_data_extended *if_de) 3487{ 3488#define COPY_IF_DE_FIELD64_ATOMIC(fld) do { \ 3489 atomic_get_64(if_de->fld, \ 3490 (u_int64_t *)(void *)(uintptr_t)&ifp->if_data.fld); \ 3491} while (0) 3492 3493 bzero(if_de, sizeof (*if_de)); 3494 COPY_IF_DE_FIELD64_ATOMIC(ifi_alignerrs); 3495 3496#undef COPY_IF_DE_FIELD64_ATOMIC 3497} 3498 3499void 3500if_copy_packet_stats(struct ifnet *ifp, struct if_packet_stats *if_ps) 3501{ 3502#define COPY_IF_PS_TCP_FIELD64_ATOMIC(fld) do { \ 3503 atomic_get_64(if_ps->ifi_tcp_##fld, \ 3504 (u_int64_t *)(void *)(uintptr_t)&ifp->if_tcp_stat->fld); \ 3505} while (0) 3506 3507#define COPY_IF_PS_UDP_FIELD64_ATOMIC(fld) do { \ 3508 atomic_get_64(if_ps->ifi_udp_##fld, \ 3509 (u_int64_t *)(void *)(uintptr_t)&ifp->if_udp_stat->fld); \ 3510} while (0) 3511 3512 COPY_IF_PS_TCP_FIELD64_ATOMIC(badformat); 3513 COPY_IF_PS_TCP_FIELD64_ATOMIC(unspecv6); 3514 COPY_IF_PS_TCP_FIELD64_ATOMIC(synfin); 3515 COPY_IF_PS_TCP_FIELD64_ATOMIC(badformatipsec); 3516 COPY_IF_PS_TCP_FIELD64_ATOMIC(noconnnolist); 3517 COPY_IF_PS_TCP_FIELD64_ATOMIC(noconnlist); 3518 COPY_IF_PS_TCP_FIELD64_ATOMIC(listbadsyn); 3519 COPY_IF_PS_TCP_FIELD64_ATOMIC(icmp6unreach); 3520 COPY_IF_PS_TCP_FIELD64_ATOMIC(deprecate6); 3521 COPY_IF_PS_TCP_FIELD64_ATOMIC(ooopacket); 3522 COPY_IF_PS_TCP_FIELD64_ATOMIC(rstinsynrcv); 3523 COPY_IF_PS_TCP_FIELD64_ATOMIC(dospacket); 3524 COPY_IF_PS_TCP_FIELD64_ATOMIC(cleanup); 3525 COPY_IF_PS_TCP_FIELD64_ATOMIC(synwindow); 3526 3527 COPY_IF_PS_UDP_FIELD64_ATOMIC(port_unreach); 3528 COPY_IF_PS_UDP_FIELD64_ATOMIC(faithprefix); 3529 COPY_IF_PS_UDP_FIELD64_ATOMIC(port0); 3530 COPY_IF_PS_UDP_FIELD64_ATOMIC(badlength); 3531 COPY_IF_PS_UDP_FIELD64_ATOMIC(badchksum); 3532 COPY_IF_PS_UDP_FIELD64_ATOMIC(badmcast); 3533 COPY_IF_PS_UDP_FIELD64_ATOMIC(cleanup); 3534 COPY_IF_PS_UDP_FIELD64_ATOMIC(badipsec); 3535 3536#undef COPY_IF_PS_TCP_FIELD64_ATOMIC 3537#undef COPY_IF_PS_UDP_FIELD64_ATOMIC 3538} 3539 3540void 3541if_copy_rxpoll_stats(struct ifnet *ifp, struct if_rxpoll_stats *if_rs) 3542{ 3543 bzero(if_rs, sizeof (*if_rs)); 3544 if (!(ifp->if_eflags & IFEF_RXPOLL) || !ifnet_is_attached(ifp, 1)) 3545 return; 3546 3547 /* by now, ifnet will stay attached so if_inp must be valid */ 3548 VERIFY(ifp->if_inp != NULL); 3549 bcopy(&ifp->if_inp->pstats, if_rs, sizeof (*if_rs)); 3550 3551 /* Release the IO refcnt */ 3552 ifnet_decr_iorefcnt(ifp); 3553} 3554 3555struct ifaddr * 3556ifa_remref(struct ifaddr *ifa, int locked) 3557{ 3558 if (!locked) 3559 IFA_LOCK_SPIN(ifa); 3560 else 3561 IFA_LOCK_ASSERT_HELD(ifa); 3562 3563 if (ifa->ifa_refcnt == 0) 3564 panic("%s: ifa %p negative refcnt\n", __func__, ifa); 3565 else if (ifa->ifa_trace != NULL) 3566 (*ifa->ifa_trace)(ifa, FALSE); 3567 if (--ifa->ifa_refcnt == 0) { 3568 if (ifa->ifa_debug & IFD_ATTACHED) 3569 panic("ifa %p attached to ifp is being freed\n", ifa); 3570 /* 3571 * Some interface addresses are allocated either statically 3572 * or carved out of a larger block; e.g. AppleTalk addresses. 3573 * Only free it if it was allocated via MALLOC or via the 3574 * corresponding per-address family allocator. Otherwise, 3575 * leave it alone. 3576 */ 3577 if (ifa->ifa_debug & IFD_ALLOC) { 3578 if (ifa->ifa_free == NULL) { 3579 IFA_UNLOCK(ifa); 3580 FREE(ifa, M_IFADDR); 3581 } else { 3582 /* Become a regular mutex */ 3583 IFA_CONVERT_LOCK(ifa); 3584 /* callee will unlock */ 3585 (*ifa->ifa_free)(ifa); 3586 } 3587 } else { 3588 IFA_UNLOCK(ifa); 3589 } 3590 ifa = NULL; 3591 } 3592 3593 if (!locked && ifa != NULL) 3594 IFA_UNLOCK(ifa); 3595 3596 return (ifa); 3597} 3598 3599void 3600ifa_addref(struct ifaddr *ifa, int locked) 3601{ 3602 if (!locked) 3603 IFA_LOCK_SPIN(ifa); 3604 else 3605 IFA_LOCK_ASSERT_HELD(ifa); 3606 3607 if (++ifa->ifa_refcnt == 0) { 3608 panic("%s: ifa %p wraparound refcnt\n", __func__, ifa); 3609 /* NOTREACHED */ 3610 } else if (ifa->ifa_trace != NULL) { 3611 (*ifa->ifa_trace)(ifa, TRUE); 3612 } 3613 if (!locked) 3614 IFA_UNLOCK(ifa); 3615} 3616 3617void 3618ifa_lock_init(struct ifaddr *ifa) 3619{ 3620 lck_mtx_init(&ifa->ifa_lock, ifa_mtx_grp, ifa_mtx_attr); 3621} 3622 3623void 3624ifa_lock_destroy(struct ifaddr *ifa) 3625{ 3626 IFA_LOCK_ASSERT_NOTHELD(ifa); 3627 lck_mtx_destroy(&ifa->ifa_lock, ifa_mtx_grp); 3628} 3629