1/* 2 * Copyright (c) 2004-2013 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#include "kpi_interface.h" 30 31#include <sys/queue.h> 32#include <sys/param.h> /* for definition of NULL */ 33#include <kern/debug.h> /* for panic */ 34#include <sys/errno.h> 35#include <sys/socket.h> 36#include <sys/kern_event.h> 37#include <sys/kernel.h> 38#include <sys/malloc.h> 39#include <sys/kpi_mbuf.h> 40#include <sys/mcache.h> 41#include <sys/protosw.h> 42#include <sys/syslog.h> 43#include <net/if_var.h> 44#include <net/if_dl.h> 45#include <net/dlil.h> 46#include <net/if_types.h> 47#include <net/if_dl.h> 48#include <net/if_arp.h> 49#include <net/if_llreach.h> 50#include <net/if_ether.h> 51#include <net/route.h> 52#include <libkern/libkern.h> 53#include <libkern/OSAtomic.h> 54#include <kern/locks.h> 55#include <kern/clock.h> 56#include <sys/sockio.h> 57#include <sys/proc.h> 58#include <sys/sysctl.h> 59#include <sys/mbuf.h> 60#include <netinet/ip_var.h> 61#include <netinet/udp.h> 62#include <netinet/udp_var.h> 63#include <netinet/tcp.h> 64#include <netinet/tcp_var.h> 65#ifdef INET 66#include <netinet/igmp_var.h> 67#endif 68#ifdef INET6 69#include <netinet6/mld6_var.h> 70#endif 71 72#include "net/net_str_id.h" 73 74#if CONFIG_MACF 75#include <sys/kauth.h> 76#include <security/mac_framework.h> 77#endif 78 79#define TOUCHLASTCHANGE(__if_lastchange) { \ 80 (__if_lastchange)->tv_sec = net_uptime(); \ 81 (__if_lastchange)->tv_usec = 0; \ 82} 83 84static errno_t ifnet_defrouter_llreachinfo(ifnet_t, int, 85 struct ifnet_llreach_info *); 86static void ifnet_kpi_free(ifnet_t); 87static errno_t ifnet_list_get_common(ifnet_family_t, boolean_t, ifnet_t **, 88 u_int32_t *); 89static errno_t ifnet_set_lladdr_internal(ifnet_t, const void *, size_t, 90 u_char, int); 91static errno_t ifnet_awdl_check_eflags(ifnet_t, u_int32_t *, u_int32_t *); 92 93/* 94 * Temporary work around until we have real reference counting 95 * 96 * We keep the bits about calling dlil_if_release (which should be 97 * called recycle) transparent by calling it from our if_free function 98 * pointer. We have to keep the client's original detach function 99 * somewhere so we can call it. 100 */ 101static void 102ifnet_kpi_free(ifnet_t ifp) 103{ 104 ifnet_detached_func detach_func = ifp->if_kpi_storage; 105 106 if (detach_func != NULL) 107 detach_func(ifp); 108 109 if (ifp->if_broadcast.length > sizeof (ifp->if_broadcast.u.buffer)) { 110 FREE(ifp->if_broadcast.u.ptr, M_IFADDR); 111 ifp->if_broadcast.u.ptr = NULL; 112 } 113 114 dlil_if_release(ifp); 115} 116 117errno_t 118ifnet_allocate(const struct ifnet_init_params *init, ifnet_t *interface) 119{ 120 struct ifnet_init_eparams einit; 121 122 bzero(&einit, sizeof (einit)); 123 124 einit.ver = IFNET_INIT_CURRENT_VERSION; 125 einit.len = sizeof (einit); 126 einit.flags = IFNET_INIT_LEGACY; 127 einit.uniqueid = init->uniqueid; 128 einit.uniqueid_len = init->uniqueid_len; 129 einit.name = init->name; 130 einit.unit = init->unit; 131 einit.family = init->family; 132 einit.type = init->type; 133 einit.output = init->output; 134 einit.demux = init->demux; 135 einit.add_proto = init->add_proto; 136 einit.del_proto = init->del_proto; 137 einit.check_multi = init->check_multi; 138 einit.framer = init->framer; 139 einit.softc = init->softc; 140 einit.ioctl = init->ioctl; 141 einit.set_bpf_tap = init->set_bpf_tap; 142 einit.detach = init->detach; 143 einit.event = init->event; 144 einit.broadcast_addr = init->broadcast_addr; 145 einit.broadcast_len = init->broadcast_len; 146 147 return (ifnet_allocate_extended(&einit, interface)); 148} 149 150errno_t 151ifnet_allocate_extended(const struct ifnet_init_eparams *einit0, 152 ifnet_t *interface) 153{ 154 struct ifnet_init_eparams einit; 155 struct ifnet *ifp = NULL; 156 int error; 157 158 einit = *einit0; 159 160 if (einit.ver != IFNET_INIT_CURRENT_VERSION || 161 einit.len < sizeof (einit)) 162 return (EINVAL); 163 164 if (einit.family == 0 || einit.name == NULL || 165 strlen(einit.name) >= IFNAMSIZ || 166 (einit.type & 0xFFFFFF00) != 0 || einit.type == 0) 167 return (EINVAL); 168 169 if (einit.flags & IFNET_INIT_LEGACY) { 170 if (einit.output == NULL || einit.flags != IFNET_INIT_LEGACY) 171 return (EINVAL); 172 173 einit.pre_enqueue = NULL; 174 einit.start = NULL; 175 einit.output_ctl = NULL; 176 einit.output_sched_model = IFNET_SCHED_MODEL_NORMAL; 177 einit.input_poll = NULL; 178 einit.input_ctl = NULL; 179 } else { 180 if (einit.start == NULL) 181 return (EINVAL); 182 183 einit.output = NULL; 184 if (einit.output_sched_model >= IFNET_SCHED_MODEL_MAX) 185 return (EINVAL); 186 187 if (einit.flags & IFNET_INIT_INPUT_POLL) { 188 if (einit.input_poll == NULL || einit.input_ctl == NULL) 189 return (EINVAL); 190 } else { 191 einit.input_poll = NULL; 192 einit.input_ctl = NULL; 193 } 194 } 195 196 error = dlil_if_acquire(einit.family, einit.uniqueid, 197 einit.uniqueid_len, &ifp); 198 199 if (error == 0) { 200 u_int64_t br; 201 202 /* 203 * Cast ifp->if_name as non const. dlil_if_acquire sets it up 204 * to point to storage of at least IFNAMSIZ bytes. It is safe 205 * to write to this. 206 */ 207 strncpy(__DECONST(char *, ifp->if_name), einit.name, IFNAMSIZ); 208 ifp->if_type = einit.type; 209 ifp->if_family = einit.family; 210 ifp->if_subfamily = einit.subfamily; 211 ifp->if_unit = einit.unit; 212 ifp->if_output = einit.output; 213 ifp->if_pre_enqueue = einit.pre_enqueue; 214 ifp->if_start = einit.start; 215 ifp->if_output_ctl = einit.output_ctl; 216 ifp->if_output_sched_model = einit.output_sched_model; 217 ifp->if_output_bw.eff_bw = einit.output_bw; 218 ifp->if_output_bw.max_bw = einit.output_bw_max; 219 ifp->if_output_lt.eff_lt = einit.output_lt; 220 ifp->if_output_lt.max_lt = einit.output_lt_max; 221 ifp->if_input_poll = einit.input_poll; 222 ifp->if_input_ctl = einit.input_ctl; 223 ifp->if_input_bw.eff_bw = einit.input_bw; 224 ifp->if_input_bw.max_bw = einit.input_bw_max; 225 ifp->if_input_lt.eff_lt = einit.input_lt; 226 ifp->if_input_lt.max_lt = einit.input_lt_max; 227 ifp->if_demux = einit.demux; 228 ifp->if_add_proto = einit.add_proto; 229 ifp->if_del_proto = einit.del_proto; 230 ifp->if_check_multi = einit.check_multi; 231 ifp->if_framer_legacy = einit.framer; 232 ifp->if_framer = einit.framer_extended; 233 ifp->if_softc = einit.softc; 234 ifp->if_ioctl = einit.ioctl; 235 ifp->if_set_bpf_tap = einit.set_bpf_tap; 236 ifp->if_free = ifnet_kpi_free; 237 ifp->if_event = einit.event; 238 ifp->if_kpi_storage = einit.detach; 239 240 /* Initialize external name (name + unit) */ 241 snprintf(__DECONST(char *, ifp->if_xname), IFXNAMSIZ, 242 "%s%d", ifp->if_name, ifp->if_unit); 243 244 /* 245 * On embedded, framer() is already in the extended form; 246 * we simply use it as is, unless the caller specifies 247 * framer_extended() which will then override it. 248 * 249 * On non-embedded, framer() has long been exposed as part 250 * of the public KPI, and therefore its signature must 251 * remain the same (without the pre- and postpend length 252 * parameters.) We special case ether_frameout, such that 253 * it gets mapped to its extended variant. All other cases 254 * utilize the stub routine which will simply return zeroes 255 * for those new parameters. 256 * 257 * Internally, DLIL will only use the extended callback 258 * variant which is represented by if_framer. 259 */ 260 if (ifp->if_framer == NULL && ifp->if_framer_legacy != NULL) { 261 if (ifp->if_framer_legacy == ether_frameout) 262 ifp->if_framer = ether_frameout_extended; 263 else 264 ifp->if_framer = ifnet_framer_stub; 265 } 266 267 if (ifp->if_output_bw.eff_bw > ifp->if_output_bw.max_bw) 268 ifp->if_output_bw.max_bw = ifp->if_output_bw.eff_bw; 269 else if (ifp->if_output_bw.eff_bw == 0) 270 ifp->if_output_bw.eff_bw = ifp->if_output_bw.max_bw; 271 272 if (ifp->if_input_bw.eff_bw > ifp->if_input_bw.max_bw) 273 ifp->if_input_bw.max_bw = ifp->if_input_bw.eff_bw; 274 else if (ifp->if_input_bw.eff_bw == 0) 275 ifp->if_input_bw.eff_bw = ifp->if_input_bw.max_bw; 276 277 if (ifp->if_output_bw.max_bw == 0) 278 ifp->if_output_bw = ifp->if_input_bw; 279 else if (ifp->if_input_bw.max_bw == 0) 280 ifp->if_input_bw = ifp->if_output_bw; 281 282 /* Pin if_baudrate to 32 bits */ 283 br = MAX(ifp->if_output_bw.max_bw, ifp->if_input_bw.max_bw); 284 if (br != 0) 285 ifp->if_baudrate = (br > 0xFFFFFFFF) ? 0xFFFFFFFF : br; 286 287 if (ifp->if_output_lt.eff_lt > ifp->if_output_lt.max_lt) 288 ifp->if_output_lt.max_lt = ifp->if_output_lt.eff_lt; 289 else if (ifp->if_output_lt.eff_lt == 0) 290 ifp->if_output_lt.eff_lt = ifp->if_output_lt.max_lt; 291 292 if (ifp->if_input_lt.eff_lt > ifp->if_input_lt.max_lt) 293 ifp->if_input_lt.max_lt = ifp->if_input_lt.eff_lt; 294 else if (ifp->if_input_lt.eff_lt == 0) 295 ifp->if_input_lt.eff_lt = ifp->if_input_lt.max_lt; 296 297 if (ifp->if_output_lt.max_lt == 0) 298 ifp->if_output_lt = ifp->if_input_lt; 299 else if (ifp->if_input_lt.max_lt == 0) 300 ifp->if_input_lt = ifp->if_output_lt; 301 302 if (ifp->if_ioctl == NULL) 303 ifp->if_ioctl = ifp_if_ioctl; 304 305 if (ifp->if_start != NULL) { 306 ifp->if_eflags |= IFEF_TXSTART; 307 if (ifp->if_pre_enqueue == NULL) 308 ifp->if_pre_enqueue = ifnet_enqueue; 309 ifp->if_output = ifp->if_pre_enqueue; 310 } else { 311 ifp->if_eflags &= ~IFEF_TXSTART; 312 } 313 314 if (ifp->if_input_poll != NULL) 315 ifp->if_eflags |= IFEF_RXPOLL; 316 else 317 ifp->if_eflags &= ~IFEF_RXPOLL; 318 319 VERIFY(!(einit.flags & IFNET_INIT_LEGACY) || 320 (ifp->if_pre_enqueue == NULL && ifp->if_start == NULL && 321 ifp->if_output_ctl == NULL && ifp->if_input_poll == NULL && 322 ifp->if_input_ctl == NULL)); 323 VERIFY(!(einit.flags & IFNET_INIT_INPUT_POLL) || 324 (ifp->if_input_poll != NULL && ifp->if_input_ctl != NULL)); 325 326 if (einit.broadcast_len && einit.broadcast_addr) { 327 if (einit.broadcast_len > 328 sizeof (ifp->if_broadcast.u.buffer)) { 329 MALLOC(ifp->if_broadcast.u.ptr, u_char *, 330 einit.broadcast_len, M_IFADDR, M_NOWAIT); 331 if (ifp->if_broadcast.u.ptr == NULL) { 332 error = ENOMEM; 333 } else { 334 bcopy(einit.broadcast_addr, 335 ifp->if_broadcast.u.ptr, 336 einit.broadcast_len); 337 } 338 } else { 339 bcopy(einit.broadcast_addr, 340 ifp->if_broadcast.u.buffer, 341 einit.broadcast_len); 342 } 343 ifp->if_broadcast.length = einit.broadcast_len; 344 } else { 345 bzero(&ifp->if_broadcast, sizeof (ifp->if_broadcast)); 346 } 347 348 IFCQ_MAXLEN(&ifp->if_snd) = einit.sndq_maxlen; 349 350 if (error == 0) { 351 *interface = ifp; 352 // temporary - this should be done in dlil_if_acquire 353 ifnet_reference(ifp); 354 } else { 355 dlil_if_release(ifp); 356 *interface = NULL; 357 } 358 } 359 360 /* 361 * Note: We should do something here to indicate that we haven't been 362 * attached yet. By doing so, we can catch the case in ifnet_release 363 * where the reference count reaches zero and call the recycle 364 * function. If the interface is attached, the interface will be 365 * recycled when the interface's if_free function is called. If the 366 * interface is never attached, the if_free function will never be 367 * called and the interface will never be recycled. 368 */ 369 370 return (error); 371} 372 373errno_t 374ifnet_reference(ifnet_t ifp) 375{ 376 return (dlil_if_ref(ifp)); 377} 378 379errno_t 380ifnet_release(ifnet_t ifp) 381{ 382 return (dlil_if_free(ifp)); 383} 384 385errno_t 386ifnet_interface_family_find(const char *module_string, 387 ifnet_family_t *family_id) 388{ 389 if (module_string == NULL || family_id == NULL) 390 return (EINVAL); 391 392 return (net_str_id_find_internal(module_string, family_id, 393 NSI_IF_FAM_ID, 1)); 394} 395 396void * 397ifnet_softc(ifnet_t interface) 398{ 399 return ((interface == NULL) ? NULL : interface->if_softc); 400} 401 402const char * 403ifnet_name(ifnet_t interface) 404{ 405 return ((interface == NULL) ? NULL : interface->if_name); 406} 407 408ifnet_family_t 409ifnet_family(ifnet_t interface) 410{ 411 return ((interface == NULL) ? 0 : interface->if_family); 412} 413 414ifnet_subfamily_t 415ifnet_subfamily(ifnet_t interface) 416{ 417 return ((interface == NULL) ? 0 : interface->if_subfamily); 418} 419 420u_int32_t 421ifnet_unit(ifnet_t interface) 422{ 423 return ((interface == NULL) ? (u_int32_t)0xffffffff : 424 (u_int32_t)interface->if_unit); 425} 426 427u_int32_t 428ifnet_index(ifnet_t interface) 429{ 430 return ((interface == NULL) ? (u_int32_t)0xffffffff : 431 interface->if_index); 432} 433 434errno_t 435ifnet_set_flags(ifnet_t interface, u_int16_t new_flags, u_int16_t mask) 436{ 437 uint16_t old_flags; 438 439 if (interface == NULL) 440 return (EINVAL); 441 442 ifnet_lock_exclusive(interface); 443 444 /* If we are modifying the up/down state, call if_updown */ 445 if ((mask & IFF_UP) != 0) { 446 if_updown(interface, (new_flags & IFF_UP) == IFF_UP); 447 } 448 449 old_flags = interface->if_flags; 450 interface->if_flags = (new_flags & mask) | (interface->if_flags & ~mask); 451 /* If we are modifying the multicast flag, set/unset the silent flag */ 452 if ((old_flags & IFF_MULTICAST) != 453 (interface->if_flags & IFF_MULTICAST)) { 454#if INET 455 if (IGMP_IFINFO(interface) != NULL) 456 igmp_initsilent(interface, IGMP_IFINFO(interface)); 457#endif /* INET */ 458#if INET6 459 if (MLD_IFINFO(interface) != NULL) 460 mld6_initsilent(interface, MLD_IFINFO(interface)); 461#endif /* INET6 */ 462 } 463 464 ifnet_lock_done(interface); 465 466 return (0); 467} 468 469u_int16_t 470ifnet_flags(ifnet_t interface) 471{ 472 return ((interface == NULL) ? 0 : interface->if_flags); 473} 474 475/* 476 * This routine ensures the following: 477 * 478 * If IFEF_AWDL is set by the caller, also set the rest of flags as 479 * defined in IFEF_AWDL_MASK. 480 * 481 * If IFEF_AWDL has been set on the interface and the caller attempts 482 * to clear one or more of the associated flags in IFEF_AWDL_MASK, 483 * return failure. 484 * 485 * All other flags not associated with AWDL are not affected. 486 * 487 * See <net/if.h> for current definition of IFEF_AWDL_MASK. 488 */ 489static errno_t 490ifnet_awdl_check_eflags(ifnet_t ifp, u_int32_t *new_eflags, u_int32_t *mask) 491{ 492 u_int32_t eflags; 493 494 ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE); 495 496 eflags = (*new_eflags & *mask) | (ifp->if_eflags & ~(*mask)); 497 498 if (ifp->if_eflags & IFEF_AWDL) { 499 if (eflags & IFEF_AWDL) { 500 if ((eflags & IFEF_AWDL_MASK) != IFEF_AWDL_MASK) 501 return (1); 502 } else { 503 *new_eflags &= ~IFEF_AWDL_MASK; 504 *mask |= IFEF_AWDL_MASK; 505 } 506 } else if (eflags & IFEF_AWDL) { 507 *new_eflags |= IFEF_AWDL_MASK; 508 *mask |= IFEF_AWDL_MASK; 509 } 510 511 return (0); 512} 513 514errno_t 515ifnet_set_eflags(ifnet_t interface, u_int32_t new_flags, u_int32_t mask) 516{ 517 if (interface == NULL) 518 return (EINVAL); 519 520 ifnet_lock_exclusive(interface); 521 /* 522 * Sanity checks for IFEF_AWDL and its related flags. 523 */ 524 if (ifnet_awdl_check_eflags(interface, &new_flags, &mask) != 0) { 525 ifnet_lock_done(interface); 526 return (EINVAL); 527 } 528 interface->if_eflags = 529 (new_flags & mask) | (interface->if_eflags & ~mask); 530 ifnet_lock_done(interface); 531 532 return (0); 533} 534 535u_int32_t 536ifnet_eflags(ifnet_t interface) 537{ 538 return ((interface == NULL) ? 0 : interface->if_eflags); 539} 540 541errno_t 542ifnet_set_idle_flags_locked(ifnet_t ifp, u_int32_t new_flags, u_int32_t mask) 543{ 544 int before, after; 545 546 if (ifp == NULL) 547 return (EINVAL); 548 549 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); 550 ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_EXCLUSIVE); 551 552 /* 553 * If this is called prior to ifnet attach, the actual work will 554 * be done at attach time. Otherwise, if it is called after 555 * ifnet detach, then it is a no-op. 556 */ 557 if (!ifnet_is_attached(ifp, 0)) { 558 ifp->if_idle_new_flags = new_flags; 559 ifp->if_idle_new_flags_mask = mask; 560 return (0); 561 } else { 562 ifp->if_idle_new_flags = ifp->if_idle_new_flags_mask = 0; 563 } 564 565 before = ifp->if_idle_flags; 566 ifp->if_idle_flags = (new_flags & mask) | (ifp->if_idle_flags & ~mask); 567 after = ifp->if_idle_flags; 568 569 if ((after - before) < 0 && ifp->if_idle_flags == 0 && 570 ifp->if_want_aggressive_drain != 0) { 571 ifp->if_want_aggressive_drain = 0; 572 if (ifnet_aggressive_drainers == 0) 573 panic("%s: ifp=%p negative aggdrain!", __func__, ifp); 574 } else if ((after - before) > 0 && ifp->if_want_aggressive_drain == 0) { 575 ifp->if_want_aggressive_drain++; 576 if (++ifnet_aggressive_drainers == 0) 577 panic("%s: ifp=%p wraparound aggdrain!", __func__, ifp); 578 } 579 580 return (0); 581} 582 583errno_t 584ifnet_set_idle_flags(ifnet_t ifp, u_int32_t new_flags, u_int32_t mask) 585{ 586 errno_t err; 587 588 lck_mtx_lock(rnh_lock); 589 ifnet_lock_exclusive(ifp); 590 err = ifnet_set_idle_flags_locked(ifp, new_flags, mask); 591 ifnet_lock_done(ifp); 592 lck_mtx_unlock(rnh_lock); 593 594 return (err); 595} 596 597u_int32_t 598ifnet_idle_flags(ifnet_t ifp) 599{ 600 return ((ifp == NULL) ? 0 : ifp->if_idle_flags); 601} 602 603errno_t 604ifnet_set_link_quality(ifnet_t ifp, int quality) 605{ 606 errno_t err = 0; 607 608 if (ifp == NULL || quality < IFNET_LQM_MIN || quality > IFNET_LQM_MAX) { 609 err = EINVAL; 610 goto done; 611 } 612 613 if (!ifnet_is_attached(ifp, 0)) { 614 err = ENXIO; 615 goto done; 616 } 617 618 if_lqm_update(ifp, quality); 619 620done: 621 return (err); 622} 623 624int 625ifnet_link_quality(ifnet_t ifp) 626{ 627 int lqm; 628 629 if (ifp == NULL) 630 return (IFNET_LQM_THRESH_OFF); 631 632 ifnet_lock_shared(ifp); 633 lqm = ifp->if_lqm; 634 ifnet_lock_done(ifp); 635 636 return (lqm); 637} 638 639static errno_t 640ifnet_defrouter_llreachinfo(ifnet_t ifp, int af, 641 struct ifnet_llreach_info *iflri) 642{ 643 if (ifp == NULL || iflri == NULL) 644 return (EINVAL); 645 646 VERIFY(af == AF_INET || af == AF_INET6); 647 648 return (ifnet_llreach_get_defrouter(ifp, af, iflri)); 649} 650 651errno_t 652ifnet_inet_defrouter_llreachinfo(ifnet_t ifp, struct ifnet_llreach_info *iflri) 653{ 654 return (ifnet_defrouter_llreachinfo(ifp, AF_INET, iflri)); 655} 656 657errno_t 658ifnet_inet6_defrouter_llreachinfo(ifnet_t ifp, struct ifnet_llreach_info *iflri) 659{ 660 return (ifnet_defrouter_llreachinfo(ifp, AF_INET6, iflri)); 661} 662 663errno_t 664ifnet_set_capabilities_supported(ifnet_t ifp, u_int32_t new_caps, 665 u_int32_t mask) 666{ 667 errno_t error = 0; 668 int tmp; 669 670 if (ifp == NULL) 671 return (EINVAL); 672 673 ifnet_lock_exclusive(ifp); 674 tmp = (new_caps & mask) | (ifp->if_capabilities & ~mask); 675 if ((tmp & ~IFCAP_VALID)) 676 error = EINVAL; 677 else 678 ifp->if_capabilities = tmp; 679 ifnet_lock_done(ifp); 680 681 return (error); 682} 683 684u_int32_t 685ifnet_capabilities_supported(ifnet_t ifp) 686{ 687 return ((ifp == NULL) ? 0 : ifp->if_capabilities); 688} 689 690 691errno_t 692ifnet_set_capabilities_enabled(ifnet_t ifp, u_int32_t new_caps, 693 u_int32_t mask) 694{ 695 errno_t error = 0; 696 int tmp; 697 struct kev_msg ev_msg; 698 struct net_event_data ev_data; 699 700 if (ifp == NULL) 701 return (EINVAL); 702 703 ifnet_lock_exclusive(ifp); 704 tmp = (new_caps & mask) | (ifp->if_capenable & ~mask); 705 if ((tmp & ~IFCAP_VALID) || (tmp & ~ifp->if_capabilities)) 706 error = EINVAL; 707 else 708 ifp->if_capenable = tmp; 709 ifnet_lock_done(ifp); 710 711 /* Notify application of the change */ 712 bzero(&ev_data, sizeof (struct net_event_data)); 713 bzero(&ev_msg, sizeof (struct kev_msg)); 714 ev_msg.vendor_code = KEV_VENDOR_APPLE; 715 ev_msg.kev_class = KEV_NETWORK_CLASS; 716 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 717 718 ev_msg.event_code = KEV_DL_IFCAP_CHANGED; 719 strlcpy(&ev_data.if_name[0], ifp->if_name, IFNAMSIZ); 720 ev_data.if_family = ifp->if_family; 721 ev_data.if_unit = (u_int32_t)ifp->if_unit; 722 ev_msg.dv[0].data_length = sizeof (struct net_event_data); 723 ev_msg.dv[0].data_ptr = &ev_data; 724 ev_msg.dv[1].data_length = 0; 725 kev_post_msg(&ev_msg); 726 727 return (error); 728} 729 730u_int32_t 731ifnet_capabilities_enabled(ifnet_t ifp) 732{ 733 return ((ifp == NULL) ? 0 : ifp->if_capenable); 734} 735 736static const ifnet_offload_t offload_mask = 737 (IFNET_CSUM_IP | IFNET_CSUM_TCP | IFNET_CSUM_UDP | IFNET_CSUM_FRAGMENT | 738 IFNET_IP_FRAGMENT | IFNET_CSUM_TCPIPV6 | IFNET_CSUM_UDPIPV6 | 739 IFNET_IPV6_FRAGMENT | IFNET_CSUM_PARTIAL | IFNET_VLAN_TAGGING | 740 IFNET_VLAN_MTU | IFNET_MULTIPAGES | IFNET_TSO_IPV4 | IFNET_TSO_IPV6 | 741 IFNET_TX_STATUS); 742 743static const ifnet_offload_t any_offload_csum = 744 (IFNET_CSUM_IP | IFNET_CSUM_TCP | IFNET_CSUM_UDP | IFNET_CSUM_FRAGMENT | 745 IFNET_CSUM_TCPIPV6 | IFNET_CSUM_UDPIPV6 | IFNET_CSUM_PARTIAL); 746 747errno_t 748ifnet_set_offload(ifnet_t interface, ifnet_offload_t offload) 749{ 750 u_int32_t ifcaps = 0; 751 752 if (interface == NULL) 753 return (EINVAL); 754 755 ifnet_lock_exclusive(interface); 756 interface->if_hwassist = (offload & offload_mask); 757 /* 758 * Hardware capable of partial checksum offload is 759 * flexible enough to handle any transports utilizing 760 * Internet Checksumming. Include those transports 761 * here, and leave the final decision to IP. 762 */ 763 if (interface->if_hwassist & IFNET_CSUM_PARTIAL) { 764 interface->if_hwassist |= (IFNET_CSUM_TCP | IFNET_CSUM_UDP | 765 IFNET_CSUM_TCPIPV6 | IFNET_CSUM_UDPIPV6); 766 } 767 if (dlil_verbose) { 768 log(LOG_DEBUG, "%s: set offload flags=%b\n", 769 if_name(interface), 770 interface->if_hwassist, IFNET_OFFLOADF_BITS); 771 } 772 ifnet_lock_done(interface); 773 774 if ((offload & any_offload_csum)) 775 ifcaps |= IFCAP_HWCSUM; 776 if ((offload & IFNET_TSO_IPV4)) 777 ifcaps |= IFCAP_TSO4; 778 if ((offload & IFNET_TSO_IPV6)) 779 ifcaps |= IFCAP_TSO6; 780 if ((offload & IFNET_VLAN_MTU)) 781 ifcaps |= IFCAP_VLAN_MTU; 782 if ((offload & IFNET_VLAN_TAGGING)) 783 ifcaps |= IFCAP_VLAN_HWTAGGING; 784 if ((offload & IFNET_TX_STATUS)) 785 ifcaps |= IFNET_TX_STATUS; 786 if (ifcaps != 0) { 787 (void) ifnet_set_capabilities_supported(interface, ifcaps, 788 IFCAP_VALID); 789 (void) ifnet_set_capabilities_enabled(interface, ifcaps, 790 IFCAP_VALID); 791 } 792 793 return (0); 794} 795 796ifnet_offload_t 797ifnet_offload(ifnet_t interface) 798{ 799 return ((interface == NULL) ? 800 0 : (interface->if_hwassist & offload_mask)); 801} 802 803errno_t 804ifnet_set_tso_mtu(ifnet_t interface, sa_family_t family, u_int32_t mtuLen) 805{ 806 errno_t error = 0; 807 808 if (interface == NULL || mtuLen < interface->if_mtu) 809 return (EINVAL); 810 811 switch (family) { 812 case AF_INET: 813 if (interface->if_hwassist & IFNET_TSO_IPV4) 814 interface->if_tso_v4_mtu = mtuLen; 815 else 816 error = EINVAL; 817 break; 818 819 case AF_INET6: 820 if (interface->if_hwassist & IFNET_TSO_IPV6) 821 interface->if_tso_v6_mtu = mtuLen; 822 else 823 error = EINVAL; 824 break; 825 826 default: 827 error = EPROTONOSUPPORT; 828 break; 829 } 830 831 return (error); 832} 833 834errno_t 835ifnet_get_tso_mtu(ifnet_t interface, sa_family_t family, u_int32_t *mtuLen) 836{ 837 errno_t error = 0; 838 839 if (interface == NULL || mtuLen == NULL) 840 return (EINVAL); 841 842 switch (family) { 843 case AF_INET: 844 if (interface->if_hwassist & IFNET_TSO_IPV4) 845 *mtuLen = interface->if_tso_v4_mtu; 846 else 847 error = EINVAL; 848 break; 849 850 case AF_INET6: 851 if (interface->if_hwassist & IFNET_TSO_IPV6) 852 *mtuLen = interface->if_tso_v6_mtu; 853 else 854 error = EINVAL; 855 break; 856 857 default: 858 error = EPROTONOSUPPORT; 859 break; 860 } 861 862 return (error); 863} 864 865errno_t 866ifnet_set_wake_flags(ifnet_t interface, u_int32_t properties, u_int32_t mask) 867{ 868 struct kev_msg ev_msg; 869 struct net_event_data ev_data; 870 871 bzero(&ev_data, sizeof (struct net_event_data)); 872 bzero(&ev_msg, sizeof (struct kev_msg)); 873 874 if (interface == NULL) 875 return (EINVAL); 876 877 /* Do not accept wacky values */ 878 if ((properties & mask) & ~IF_WAKE_VALID_FLAGS) 879 return (EINVAL); 880 881 ifnet_lock_exclusive(interface); 882 883 interface->if_wake_properties = 884 (properties & mask) | (interface->if_wake_properties & ~mask); 885 886 ifnet_lock_done(interface); 887 888 (void) ifnet_touch_lastchange(interface); 889 890 /* Notify application of the change */ 891 ev_msg.vendor_code = KEV_VENDOR_APPLE; 892 ev_msg.kev_class = KEV_NETWORK_CLASS; 893 ev_msg.kev_subclass = KEV_DL_SUBCLASS; 894 895 ev_msg.event_code = KEV_DL_WAKEFLAGS_CHANGED; 896 strlcpy(&ev_data.if_name[0], interface->if_name, IFNAMSIZ); 897 ev_data.if_family = interface->if_family; 898 ev_data.if_unit = (u_int32_t)interface->if_unit; 899 ev_msg.dv[0].data_length = sizeof (struct net_event_data); 900 ev_msg.dv[0].data_ptr = &ev_data; 901 ev_msg.dv[1].data_length = 0; 902 kev_post_msg(&ev_msg); 903 904 return (0); 905} 906 907u_int32_t 908ifnet_get_wake_flags(ifnet_t interface) 909{ 910 return ((interface == NULL) ? 0 : interface->if_wake_properties); 911} 912 913/* 914 * Should MIB data store a copy? 915 */ 916errno_t 917ifnet_set_link_mib_data(ifnet_t interface, void *mibData, u_int32_t mibLen) 918{ 919 if (interface == NULL) 920 return (EINVAL); 921 922 ifnet_lock_exclusive(interface); 923 interface->if_linkmib = (void*)mibData; 924 interface->if_linkmiblen = mibLen; 925 ifnet_lock_done(interface); 926 return (0); 927} 928 929errno_t 930ifnet_get_link_mib_data(ifnet_t interface, void *mibData, u_int32_t *mibLen) 931{ 932 errno_t result = 0; 933 934 if (interface == NULL) 935 return (EINVAL); 936 937 ifnet_lock_shared(interface); 938 if (*mibLen < interface->if_linkmiblen) 939 result = EMSGSIZE; 940 if (result == 0 && interface->if_linkmib == NULL) 941 result = ENOTSUP; 942 943 if (result == 0) { 944 *mibLen = interface->if_linkmiblen; 945 bcopy(interface->if_linkmib, mibData, *mibLen); 946 } 947 ifnet_lock_done(interface); 948 949 return (result); 950} 951 952u_int32_t 953ifnet_get_link_mib_data_length(ifnet_t interface) 954{ 955 return ((interface == NULL) ? 0 : interface->if_linkmiblen); 956} 957 958errno_t 959ifnet_output(ifnet_t interface, protocol_family_t protocol_family, 960 mbuf_t m, void *route, const struct sockaddr *dest) 961{ 962 if (interface == NULL || protocol_family == 0 || m == NULL) { 963 if (m != NULL) 964 mbuf_freem_list(m); 965 return (EINVAL); 966 } 967 return (dlil_output(interface, protocol_family, m, route, dest, 0, NULL)); 968} 969 970errno_t 971ifnet_output_raw(ifnet_t interface, protocol_family_t protocol_family, mbuf_t m) 972{ 973 if (interface == NULL || m == NULL) { 974 if (m != NULL) 975 mbuf_freem_list(m); 976 return (EINVAL); 977 } 978 return (dlil_output(interface, protocol_family, m, NULL, NULL, 1, NULL)); 979} 980 981errno_t 982ifnet_set_mtu(ifnet_t interface, u_int32_t mtu) 983{ 984 if (interface == NULL) 985 return (EINVAL); 986 987 interface->if_mtu = mtu; 988 return (0); 989} 990 991u_int32_t 992ifnet_mtu(ifnet_t interface) 993{ 994 return ((interface == NULL) ? 0 : interface->if_mtu); 995} 996 997u_char 998ifnet_type(ifnet_t interface) 999{ 1000 return ((interface == NULL) ? 0 : interface->if_data.ifi_type); 1001} 1002 1003errno_t 1004ifnet_set_addrlen(ifnet_t interface, u_char addrlen) 1005{ 1006 if (interface == NULL) 1007 return (EINVAL); 1008 1009 interface->if_data.ifi_addrlen = addrlen; 1010 return (0); 1011} 1012 1013u_char 1014ifnet_addrlen(ifnet_t interface) 1015{ 1016 return ((interface == NULL) ? 0 : interface->if_data.ifi_addrlen); 1017} 1018 1019errno_t 1020ifnet_set_hdrlen(ifnet_t interface, u_char hdrlen) 1021{ 1022 if (interface == NULL) 1023 return (EINVAL); 1024 1025 interface->if_data.ifi_hdrlen = hdrlen; 1026 return (0); 1027} 1028 1029u_char 1030ifnet_hdrlen(ifnet_t interface) 1031{ 1032 return ((interface == NULL) ? 0 : interface->if_data.ifi_hdrlen); 1033} 1034 1035errno_t 1036ifnet_set_metric(ifnet_t interface, u_int32_t metric) 1037{ 1038 if (interface == NULL) 1039 return (EINVAL); 1040 1041 interface->if_data.ifi_metric = metric; 1042 return (0); 1043} 1044 1045u_int32_t 1046ifnet_metric(ifnet_t interface) 1047{ 1048 return ((interface == NULL) ? 0 : interface->if_data.ifi_metric); 1049} 1050 1051errno_t 1052ifnet_set_baudrate(struct ifnet *ifp, u_int64_t baudrate) 1053{ 1054 if (ifp == NULL) 1055 return (EINVAL); 1056 1057 ifp->if_output_bw.max_bw = ifp->if_input_bw.max_bw = 1058 ifp->if_output_bw.eff_bw = ifp->if_input_bw.eff_bw = baudrate; 1059 1060 /* Pin if_baudrate to 32 bits until we can change the storage size */ 1061 ifp->if_baudrate = (baudrate > 0xFFFFFFFF) ? 0xFFFFFFFF : baudrate; 1062 1063 return (0); 1064} 1065 1066u_int64_t 1067ifnet_baudrate(struct ifnet *ifp) 1068{ 1069 return ((ifp == NULL) ? 0 : ifp->if_baudrate); 1070} 1071 1072errno_t 1073ifnet_set_bandwidths(struct ifnet *ifp, struct if_bandwidths *output_bw, 1074 struct if_bandwidths *input_bw) 1075{ 1076 if (ifp == NULL) 1077 return (EINVAL); 1078 1079 /* set input values first (if any), as output values depend on them */ 1080 if (input_bw != NULL) 1081 (void) ifnet_set_input_bandwidths(ifp, input_bw); 1082 1083 if (output_bw != NULL) 1084 (void) ifnet_set_output_bandwidths(ifp, output_bw, FALSE); 1085 1086 return (0); 1087} 1088 1089errno_t 1090ifnet_set_output_bandwidths(struct ifnet *ifp, struct if_bandwidths *bw, 1091 boolean_t locked) 1092{ 1093 struct if_bandwidths old_bw; 1094 struct ifclassq *ifq; 1095 u_int64_t br; 1096 1097 VERIFY(ifp != NULL && bw != NULL); 1098 1099 ifq = &ifp->if_snd; 1100 if (!locked) 1101 IFCQ_LOCK(ifq); 1102 IFCQ_LOCK_ASSERT_HELD(ifq); 1103 1104 old_bw = ifp->if_output_bw; 1105 if (bw->eff_bw != 0) 1106 ifp->if_output_bw.eff_bw = bw->eff_bw; 1107 if (bw->max_bw != 0) 1108 ifp->if_output_bw.max_bw = bw->max_bw; 1109 if (ifp->if_output_bw.eff_bw > ifp->if_output_bw.max_bw) 1110 ifp->if_output_bw.max_bw = ifp->if_output_bw.eff_bw; 1111 else if (ifp->if_output_bw.eff_bw == 0) 1112 ifp->if_output_bw.eff_bw = ifp->if_output_bw.max_bw; 1113 1114 /* Pin if_baudrate to 32 bits */ 1115 br = MAX(ifp->if_output_bw.max_bw, ifp->if_input_bw.max_bw); 1116 if (br != 0) 1117 ifp->if_baudrate = (br > 0xFFFFFFFF) ? 0xFFFFFFFF : br; 1118 1119 /* Adjust queue parameters if needed */ 1120 if (old_bw.eff_bw != ifp->if_output_bw.eff_bw || 1121 old_bw.max_bw != ifp->if_output_bw.max_bw) 1122 ifnet_update_sndq(ifq, CLASSQ_EV_LINK_BANDWIDTH); 1123 1124 if (!locked) 1125 IFCQ_UNLOCK(ifq); 1126 1127 return (0); 1128} 1129 1130errno_t 1131ifnet_set_input_bandwidths(struct ifnet *ifp, struct if_bandwidths *bw) 1132{ 1133 struct if_bandwidths old_bw; 1134 1135 VERIFY(ifp != NULL && bw != NULL); 1136 1137 old_bw = ifp->if_input_bw; 1138 if (bw->eff_bw != 0) 1139 ifp->if_input_bw.eff_bw = bw->eff_bw; 1140 if (bw->max_bw != 0) 1141 ifp->if_input_bw.max_bw = bw->max_bw; 1142 if (ifp->if_input_bw.eff_bw > ifp->if_input_bw.max_bw) 1143 ifp->if_input_bw.max_bw = ifp->if_input_bw.eff_bw; 1144 else if (ifp->if_input_bw.eff_bw == 0) 1145 ifp->if_input_bw.eff_bw = ifp->if_input_bw.max_bw; 1146 1147 if (old_bw.eff_bw != ifp->if_input_bw.eff_bw || 1148 old_bw.max_bw != ifp->if_input_bw.max_bw) 1149 ifnet_update_rcv(ifp, CLASSQ_EV_LINK_BANDWIDTH); 1150 1151 return (0); 1152} 1153 1154u_int64_t 1155ifnet_output_linkrate(struct ifnet *ifp) 1156{ 1157 struct ifclassq *ifq = &ifp->if_snd; 1158 u_int64_t rate; 1159 1160 IFCQ_LOCK_ASSERT_HELD(ifq); 1161 1162 rate = ifp->if_output_bw.eff_bw; 1163 if (IFCQ_TBR_IS_ENABLED(ifq)) { 1164 u_int64_t tbr_rate = ifp->if_snd.ifcq_tbr.tbr_rate_raw; 1165 VERIFY(tbr_rate > 0); 1166 rate = MIN(rate, ifp->if_snd.ifcq_tbr.tbr_rate_raw); 1167 } 1168 1169 return (rate); 1170} 1171 1172u_int64_t 1173ifnet_input_linkrate(struct ifnet *ifp) 1174{ 1175 return (ifp->if_input_bw.eff_bw); 1176} 1177 1178errno_t 1179ifnet_bandwidths(struct ifnet *ifp, struct if_bandwidths *output_bw, 1180 struct if_bandwidths *input_bw) 1181{ 1182 if (ifp == NULL) 1183 return (EINVAL); 1184 1185 if (output_bw != NULL) 1186 *output_bw = ifp->if_output_bw; 1187 if (input_bw != NULL) 1188 *input_bw = ifp->if_input_bw; 1189 1190 return (0); 1191} 1192 1193errno_t 1194ifnet_set_latencies(struct ifnet *ifp, struct if_latencies *output_lt, 1195 struct if_latencies *input_lt) 1196{ 1197 if (ifp == NULL) 1198 return (EINVAL); 1199 1200 if (output_lt != NULL) 1201 (void) ifnet_set_output_latencies(ifp, output_lt, FALSE); 1202 1203 if (input_lt != NULL) 1204 (void) ifnet_set_input_latencies(ifp, input_lt); 1205 1206 return (0); 1207} 1208 1209errno_t 1210ifnet_set_output_latencies(struct ifnet *ifp, struct if_latencies *lt, 1211 boolean_t locked) 1212{ 1213 struct if_latencies old_lt; 1214 struct ifclassq *ifq; 1215 1216 VERIFY(ifp != NULL && lt != NULL); 1217 1218 ifq = &ifp->if_snd; 1219 if (!locked) 1220 IFCQ_LOCK(ifq); 1221 IFCQ_LOCK_ASSERT_HELD(ifq); 1222 1223 old_lt = ifp->if_output_lt; 1224 if (lt->eff_lt != 0) 1225 ifp->if_output_lt.eff_lt = lt->eff_lt; 1226 if (lt->max_lt != 0) 1227 ifp->if_output_lt.max_lt = lt->max_lt; 1228 if (ifp->if_output_lt.eff_lt > ifp->if_output_lt.max_lt) 1229 ifp->if_output_lt.max_lt = ifp->if_output_lt.eff_lt; 1230 else if (ifp->if_output_lt.eff_lt == 0) 1231 ifp->if_output_lt.eff_lt = ifp->if_output_lt.max_lt; 1232 1233 /* Adjust queue parameters if needed */ 1234 if (old_lt.eff_lt != ifp->if_output_lt.eff_lt || 1235 old_lt.max_lt != ifp->if_output_lt.max_lt) 1236 ifnet_update_sndq(ifq, CLASSQ_EV_LINK_LATENCY); 1237 1238 if (!locked) 1239 IFCQ_UNLOCK(ifq); 1240 1241 return (0); 1242} 1243 1244errno_t 1245ifnet_set_input_latencies(struct ifnet *ifp, struct if_latencies *lt) 1246{ 1247 struct if_latencies old_lt; 1248 1249 VERIFY(ifp != NULL && lt != NULL); 1250 1251 old_lt = ifp->if_input_lt; 1252 if (lt->eff_lt != 0) 1253 ifp->if_input_lt.eff_lt = lt->eff_lt; 1254 if (lt->max_lt != 0) 1255 ifp->if_input_lt.max_lt = lt->max_lt; 1256 if (ifp->if_input_lt.eff_lt > ifp->if_input_lt.max_lt) 1257 ifp->if_input_lt.max_lt = ifp->if_input_lt.eff_lt; 1258 else if (ifp->if_input_lt.eff_lt == 0) 1259 ifp->if_input_lt.eff_lt = ifp->if_input_lt.max_lt; 1260 1261 if (old_lt.eff_lt != ifp->if_input_lt.eff_lt || 1262 old_lt.max_lt != ifp->if_input_lt.max_lt) 1263 ifnet_update_rcv(ifp, CLASSQ_EV_LINK_LATENCY); 1264 1265 return (0); 1266} 1267 1268errno_t 1269ifnet_latencies(struct ifnet *ifp, struct if_latencies *output_lt, 1270 struct if_latencies *input_lt) 1271{ 1272 if (ifp == NULL) 1273 return (EINVAL); 1274 1275 if (output_lt != NULL) 1276 *output_lt = ifp->if_output_lt; 1277 if (input_lt != NULL) 1278 *input_lt = ifp->if_input_lt; 1279 1280 return (0); 1281} 1282 1283errno_t 1284ifnet_set_poll_params(struct ifnet *ifp, struct ifnet_poll_params *p) 1285{ 1286 errno_t err; 1287 1288 if (ifp == NULL) 1289 return (EINVAL); 1290 else if (!ifnet_is_attached(ifp, 1)) 1291 return (ENXIO); 1292 1293 err = dlil_rxpoll_set_params(ifp, p, FALSE); 1294 1295 /* Release the io ref count */ 1296 ifnet_decr_iorefcnt(ifp); 1297 1298 return (err); 1299} 1300 1301errno_t 1302ifnet_poll_params(struct ifnet *ifp, struct ifnet_poll_params *p) 1303{ 1304 errno_t err; 1305 1306 if (ifp == NULL || p == NULL) 1307 return (EINVAL); 1308 else if (!ifnet_is_attached(ifp, 1)) 1309 return (ENXIO); 1310 1311 err = dlil_rxpoll_get_params(ifp, p); 1312 1313 /* Release the io ref count */ 1314 ifnet_decr_iorefcnt(ifp); 1315 1316 return (err); 1317} 1318 1319errno_t 1320ifnet_stat_increment(struct ifnet *ifp, 1321 const struct ifnet_stat_increment_param *s) 1322{ 1323 if (ifp == NULL) 1324 return (EINVAL); 1325 1326 if (s->packets_in != 0) 1327 atomic_add_64(&ifp->if_data.ifi_ipackets, s->packets_in); 1328 if (s->bytes_in != 0) 1329 atomic_add_64(&ifp->if_data.ifi_ibytes, s->bytes_in); 1330 if (s->errors_in != 0) 1331 atomic_add_64(&ifp->if_data.ifi_ierrors, s->errors_in); 1332 1333 if (s->packets_out != 0) 1334 atomic_add_64(&ifp->if_data.ifi_opackets, s->packets_out); 1335 if (s->bytes_out != 0) 1336 atomic_add_64(&ifp->if_data.ifi_obytes, s->bytes_out); 1337 if (s->errors_out != 0) 1338 atomic_add_64(&ifp->if_data.ifi_oerrors, s->errors_out); 1339 1340 if (s->collisions != 0) 1341 atomic_add_64(&ifp->if_data.ifi_collisions, s->collisions); 1342 if (s->dropped != 0) 1343 atomic_add_64(&ifp->if_data.ifi_iqdrops, s->dropped); 1344 1345 /* Touch the last change time. */ 1346 TOUCHLASTCHANGE(&ifp->if_lastchange); 1347 1348 return (0); 1349} 1350 1351errno_t 1352ifnet_stat_increment_in(struct ifnet *ifp, u_int32_t packets_in, 1353 u_int32_t bytes_in, u_int32_t errors_in) 1354{ 1355 if (ifp == NULL) 1356 return (EINVAL); 1357 1358 if (packets_in != 0) 1359 atomic_add_64(&ifp->if_data.ifi_ipackets, packets_in); 1360 if (bytes_in != 0) 1361 atomic_add_64(&ifp->if_data.ifi_ibytes, bytes_in); 1362 if (errors_in != 0) 1363 atomic_add_64(&ifp->if_data.ifi_ierrors, errors_in); 1364 1365 TOUCHLASTCHANGE(&ifp->if_lastchange); 1366 1367 return (0); 1368} 1369 1370errno_t 1371ifnet_stat_increment_out(struct ifnet *ifp, u_int32_t packets_out, 1372 u_int32_t bytes_out, u_int32_t errors_out) 1373{ 1374 if (ifp == NULL) 1375 return (EINVAL); 1376 1377 if (packets_out != 0) 1378 atomic_add_64(&ifp->if_data.ifi_opackets, packets_out); 1379 if (bytes_out != 0) 1380 atomic_add_64(&ifp->if_data.ifi_obytes, bytes_out); 1381 if (errors_out != 0) 1382 atomic_add_64(&ifp->if_data.ifi_oerrors, errors_out); 1383 1384 TOUCHLASTCHANGE(&ifp->if_lastchange); 1385 1386 return (0); 1387} 1388 1389errno_t 1390ifnet_set_stat(struct ifnet *ifp, const struct ifnet_stats_param *s) 1391{ 1392 if (ifp == NULL) 1393 return (EINVAL); 1394 1395 atomic_set_64(&ifp->if_data.ifi_ipackets, s->packets_in); 1396 atomic_set_64(&ifp->if_data.ifi_ibytes, s->bytes_in); 1397 atomic_set_64(&ifp->if_data.ifi_imcasts, s->multicasts_in); 1398 atomic_set_64(&ifp->if_data.ifi_ierrors, s->errors_in); 1399 1400 atomic_set_64(&ifp->if_data.ifi_opackets, s->packets_out); 1401 atomic_set_64(&ifp->if_data.ifi_obytes, s->bytes_out); 1402 atomic_set_64(&ifp->if_data.ifi_omcasts, s->multicasts_out); 1403 atomic_set_64(&ifp->if_data.ifi_oerrors, s->errors_out); 1404 1405 atomic_set_64(&ifp->if_data.ifi_collisions, s->collisions); 1406 atomic_set_64(&ifp->if_data.ifi_iqdrops, s->dropped); 1407 atomic_set_64(&ifp->if_data.ifi_noproto, s->no_protocol); 1408 1409 /* Touch the last change time. */ 1410 TOUCHLASTCHANGE(&ifp->if_lastchange); 1411 1412 return (0); 1413} 1414 1415errno_t 1416ifnet_stat(struct ifnet *ifp, struct ifnet_stats_param *s) 1417{ 1418 if (ifp == NULL) 1419 return (EINVAL); 1420 1421 atomic_get_64(s->packets_in, &ifp->if_data.ifi_ipackets); 1422 atomic_get_64(s->bytes_in, &ifp->if_data.ifi_ibytes); 1423 atomic_get_64(s->multicasts_in, &ifp->if_data.ifi_imcasts); 1424 atomic_get_64(s->errors_in, &ifp->if_data.ifi_ierrors); 1425 1426 atomic_get_64(s->packets_out, &ifp->if_data.ifi_opackets); 1427 atomic_get_64(s->bytes_out, &ifp->if_data.ifi_obytes); 1428 atomic_get_64(s->multicasts_out, &ifp->if_data.ifi_omcasts); 1429 atomic_get_64(s->errors_out, &ifp->if_data.ifi_oerrors); 1430 1431 atomic_get_64(s->collisions, &ifp->if_data.ifi_collisions); 1432 atomic_get_64(s->dropped, &ifp->if_data.ifi_iqdrops); 1433 atomic_get_64(s->no_protocol, &ifp->if_data.ifi_noproto); 1434 1435 return (0); 1436} 1437 1438errno_t 1439ifnet_touch_lastchange(ifnet_t interface) 1440{ 1441 if (interface == NULL) 1442 return (EINVAL); 1443 1444 TOUCHLASTCHANGE(&interface->if_lastchange); 1445 1446 return (0); 1447} 1448 1449errno_t 1450ifnet_lastchange(ifnet_t interface, struct timeval *last_change) 1451{ 1452 if (interface == NULL) 1453 return (EINVAL); 1454 1455 *last_change = interface->if_data.ifi_lastchange; 1456 /* Crude conversion from uptime to calendar time */ 1457 last_change->tv_sec += boottime_sec(); 1458 1459 return (0); 1460} 1461 1462errno_t 1463ifnet_get_address_list(ifnet_t interface, ifaddr_t **addresses) 1464{ 1465 return (addresses == NULL ? EINVAL : 1466 ifnet_get_address_list_family(interface, addresses, 0)); 1467} 1468 1469struct ifnet_addr_list { 1470 SLIST_ENTRY(ifnet_addr_list) ifal_le; 1471 struct ifaddr *ifal_ifa; 1472}; 1473 1474errno_t 1475ifnet_get_address_list_family(ifnet_t interface, ifaddr_t **addresses, 1476 sa_family_t family) 1477{ 1478 return (ifnet_get_address_list_family_internal(interface, addresses, 1479 family, 0, M_NOWAIT, 0)); 1480} 1481 1482errno_t 1483ifnet_get_inuse_address_list(ifnet_t interface, ifaddr_t **addresses) 1484{ 1485 return (addresses == NULL ? EINVAL : 1486 ifnet_get_address_list_family_internal(interface, addresses, 1487 0, 0, M_NOWAIT, 1)); 1488} 1489 1490extern uint32_t tcp_find_anypcb_byaddr(struct ifaddr *ifa); 1491 1492extern uint32_t udp_find_anypcb_byaddr(struct ifaddr *ifa); 1493 1494__private_extern__ errno_t 1495ifnet_get_address_list_family_internal(ifnet_t interface, ifaddr_t **addresses, 1496 sa_family_t family, int detached, int how, int return_inuse_addrs) 1497{ 1498 SLIST_HEAD(, ifnet_addr_list) ifal_head; 1499 struct ifnet_addr_list *ifal, *ifal_tmp; 1500 struct ifnet *ifp; 1501 int count = 0; 1502 errno_t err = 0; 1503 int usecount = 0; 1504 int index = 0; 1505 1506 SLIST_INIT(&ifal_head); 1507 1508 if (addresses == NULL) { 1509 err = EINVAL; 1510 goto done; 1511 } 1512 *addresses = NULL; 1513 1514 if (detached) { 1515 /* 1516 * Interface has been detached, so skip the lookup 1517 * at ifnet_head and go directly to inner loop. 1518 */ 1519 ifp = interface; 1520 if (ifp == NULL) { 1521 err = EINVAL; 1522 goto done; 1523 } 1524 goto one; 1525 } 1526 1527 ifnet_head_lock_shared(); 1528 TAILQ_FOREACH(ifp, &ifnet_head, if_link) { 1529 if (interface != NULL && ifp != interface) 1530 continue; 1531one: 1532 ifnet_lock_shared(ifp); 1533 if (interface == NULL || interface == ifp) { 1534 struct ifaddr *ifa; 1535 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1536 IFA_LOCK(ifa); 1537 if (family != 0 && 1538 ifa->ifa_addr->sa_family != family) { 1539 IFA_UNLOCK(ifa); 1540 continue; 1541 } 1542 MALLOC(ifal, struct ifnet_addr_list *, 1543 sizeof (*ifal), M_TEMP, how); 1544 if (ifal == NULL) { 1545 IFA_UNLOCK(ifa); 1546 ifnet_lock_done(ifp); 1547 if (!detached) 1548 ifnet_head_done(); 1549 err = ENOMEM; 1550 goto done; 1551 } 1552 ifal->ifal_ifa = ifa; 1553 IFA_ADDREF_LOCKED(ifa); 1554 SLIST_INSERT_HEAD(&ifal_head, ifal, ifal_le); 1555 ++count; 1556 IFA_UNLOCK(ifa); 1557 } 1558 } 1559 ifnet_lock_done(ifp); 1560 if (detached) 1561 break; 1562 } 1563 if (!detached) 1564 ifnet_head_done(); 1565 1566 if (count == 0) { 1567 err = ENXIO; 1568 goto done; 1569 } 1570 MALLOC(*addresses, ifaddr_t *, sizeof (ifaddr_t) * (count + 1), 1571 M_TEMP, how); 1572 if (*addresses == NULL) { 1573 err = ENOMEM; 1574 goto done; 1575 } 1576 bzero(*addresses, sizeof (ifaddr_t) * (count + 1)); 1577 1578done: 1579 SLIST_FOREACH_SAFE(ifal, &ifal_head, ifal_le, ifal_tmp) { 1580 SLIST_REMOVE(&ifal_head, ifal, ifnet_addr_list, ifal_le); 1581 if (err == 0) { 1582 if (return_inuse_addrs) { 1583 usecount = tcp_find_anypcb_byaddr(ifal->ifal_ifa); 1584 usecount += udp_find_anypcb_byaddr(ifal->ifal_ifa); 1585 if (usecount) { 1586 (*addresses)[index] = ifal->ifal_ifa; 1587 index++; 1588 } 1589 else 1590 IFA_REMREF(ifal->ifal_ifa); 1591 } else { 1592 (*addresses)[--count] = ifal->ifal_ifa; 1593 } 1594 } 1595 else { 1596 IFA_REMREF(ifal->ifal_ifa); 1597 } 1598 FREE(ifal, M_TEMP); 1599 } 1600 1601 VERIFY(err == 0 || *addresses == NULL); 1602 if ((err == 0) && (count) && ((*addresses)[0] == NULL)) { 1603 VERIFY(return_inuse_addrs == 1); 1604 FREE(*addresses, M_TEMP); 1605 err = ENXIO; 1606 } 1607 return (err); 1608} 1609 1610void 1611ifnet_free_address_list(ifaddr_t *addresses) 1612{ 1613 int i; 1614 1615 if (addresses == NULL) 1616 return; 1617 1618 for (i = 0; addresses[i] != NULL; i++) 1619 IFA_REMREF(addresses[i]); 1620 1621 FREE(addresses, M_TEMP); 1622} 1623 1624void * 1625ifnet_lladdr(ifnet_t interface) 1626{ 1627 struct ifaddr *ifa; 1628 void *lladdr; 1629 1630 if (interface == NULL) 1631 return (NULL); 1632 1633 /* 1634 * if_lladdr points to the permanent link address of 1635 * the interface and it never gets deallocated; internal 1636 * code should simply use IF_LLADDR() for performance. 1637 */ 1638 ifa = interface->if_lladdr; 1639 IFA_LOCK_SPIN(ifa); 1640 lladdr = LLADDR(SDL((void *)ifa->ifa_addr)); 1641 IFA_UNLOCK(ifa); 1642 1643 return (lladdr); 1644} 1645 1646errno_t 1647ifnet_llbroadcast_copy_bytes(ifnet_t interface, void *addr, size_t buffer_len, 1648 size_t *out_len) 1649{ 1650 if (interface == NULL || addr == NULL || out_len == NULL) 1651 return (EINVAL); 1652 1653 *out_len = interface->if_broadcast.length; 1654 1655 if (buffer_len < interface->if_broadcast.length) 1656 return (EMSGSIZE); 1657 1658 if (interface->if_broadcast.length == 0) 1659 return (ENXIO); 1660 1661 if (interface->if_broadcast.length <= 1662 sizeof (interface->if_broadcast.u.buffer)) { 1663 bcopy(interface->if_broadcast.u.buffer, addr, 1664 interface->if_broadcast.length); 1665 } else { 1666 bcopy(interface->if_broadcast.u.ptr, addr, 1667 interface->if_broadcast.length); 1668 } 1669 1670 return (0); 1671} 1672 1673static errno_t 1674ifnet_lladdr_copy_bytes_internal(ifnet_t interface, void *lladdr, 1675 size_t lladdr_len, kauth_cred_t *credp) 1676{ 1677 const u_int8_t *bytes; 1678 size_t bytes_len; 1679 struct ifaddr *ifa; 1680 uint8_t sdlbuf[SOCK_MAXADDRLEN + 1]; 1681 errno_t error = 0; 1682 1683 /* 1684 * Make sure to accomodate the largest possible 1685 * size of SA(if_lladdr)->sa_len. 1686 */ 1687 _CASSERT(sizeof (sdlbuf) == (SOCK_MAXADDRLEN + 1)); 1688 1689 if (interface == NULL || lladdr == NULL) 1690 return (EINVAL); 1691 1692 ifa = interface->if_lladdr; 1693 IFA_LOCK_SPIN(ifa); 1694 bcopy(ifa->ifa_addr, &sdlbuf, SDL(ifa->ifa_addr)->sdl_len); 1695 IFA_UNLOCK(ifa); 1696 1697 bytes = dlil_ifaddr_bytes(SDL(&sdlbuf), &bytes_len, credp); 1698 if (bytes_len != lladdr_len) { 1699 bzero(lladdr, lladdr_len); 1700 error = EMSGSIZE; 1701 } else { 1702 bcopy(bytes, lladdr, bytes_len); 1703 } 1704 1705 return (error); 1706} 1707 1708errno_t 1709ifnet_lladdr_copy_bytes(ifnet_t interface, void *lladdr, size_t length) 1710{ 1711 return (ifnet_lladdr_copy_bytes_internal(interface, lladdr, length, 1712 NULL)); 1713} 1714 1715errno_t 1716ifnet_guarded_lladdr_copy_bytes(ifnet_t interface, void *lladdr, size_t length) 1717{ 1718#if CONFIG_MACF 1719 kauth_cred_t cred; 1720 net_thread_marks_t marks; 1721#endif 1722 kauth_cred_t *credp; 1723 errno_t error; 1724 1725 credp = NULL; 1726#if CONFIG_MACF 1727 marks = net_thread_marks_push(NET_THREAD_CKREQ_LLADDR); 1728 cred = kauth_cred_proc_ref(current_proc()); 1729 credp = &cred; 1730#else 1731 credp = NULL; 1732#endif 1733 1734 error = ifnet_lladdr_copy_bytes_internal(interface, lladdr, length, 1735 credp); 1736 1737#if CONFIG_MACF 1738 kauth_cred_unref(credp); 1739 net_thread_marks_pop(marks); 1740#endif 1741 1742 return (error); 1743} 1744 1745static errno_t 1746ifnet_set_lladdr_internal(ifnet_t interface, const void *lladdr, 1747 size_t lladdr_len, u_char new_type, int apply_type) 1748{ 1749 struct ifaddr *ifa; 1750 errno_t error = 0; 1751 1752 if (interface == NULL) 1753 return (EINVAL); 1754 1755 ifnet_head_lock_shared(); 1756 ifnet_lock_exclusive(interface); 1757 if (lladdr_len != 0 && 1758 (lladdr_len != interface->if_addrlen || lladdr == 0)) { 1759 ifnet_lock_done(interface); 1760 ifnet_head_done(); 1761 return (EINVAL); 1762 } 1763 ifa = ifnet_addrs[interface->if_index - 1]; 1764 if (ifa != NULL) { 1765 struct sockaddr_dl *sdl; 1766 1767 IFA_LOCK_SPIN(ifa); 1768 sdl = (struct sockaddr_dl *)(void *)ifa->ifa_addr; 1769 if (lladdr_len != 0) { 1770 bcopy(lladdr, LLADDR(sdl), lladdr_len); 1771 } else { 1772 bzero(LLADDR(sdl), interface->if_addrlen); 1773 } 1774 sdl->sdl_alen = lladdr_len; 1775 1776 if (apply_type) { 1777 sdl->sdl_type = new_type; 1778 } 1779 IFA_UNLOCK(ifa); 1780 } else { 1781 error = ENXIO; 1782 } 1783 ifnet_lock_done(interface); 1784 ifnet_head_done(); 1785 1786 /* Generate a kernel event */ 1787 if (error == 0) { 1788 dlil_post_msg(interface, KEV_DL_SUBCLASS, 1789 KEV_DL_LINK_ADDRESS_CHANGED, NULL, 0); 1790 } 1791 1792 return (error); 1793} 1794 1795errno_t 1796ifnet_set_lladdr(ifnet_t interface, const void* lladdr, size_t lladdr_len) 1797{ 1798 return (ifnet_set_lladdr_internal(interface, lladdr, lladdr_len, 0, 0)); 1799} 1800 1801errno_t 1802ifnet_set_lladdr_and_type(ifnet_t interface, const void* lladdr, 1803 size_t lladdr_len, u_char type) 1804{ 1805 return (ifnet_set_lladdr_internal(interface, lladdr, 1806 lladdr_len, type, 1)); 1807} 1808 1809errno_t 1810ifnet_add_multicast(ifnet_t interface, const struct sockaddr *maddr, 1811 ifmultiaddr_t *ifmap) 1812{ 1813 if (interface == NULL || maddr == NULL) 1814 return (EINVAL); 1815 1816 /* Don't let users screw up protocols' entries. */ 1817 if (maddr->sa_family != AF_UNSPEC && maddr->sa_family != AF_LINK) 1818 return (EINVAL); 1819 1820 return (if_addmulti_anon(interface, maddr, ifmap)); 1821} 1822 1823errno_t 1824ifnet_remove_multicast(ifmultiaddr_t ifma) 1825{ 1826 struct sockaddr *maddr; 1827 1828 if (ifma == NULL) 1829 return (EINVAL); 1830 1831 maddr = ifma->ifma_addr; 1832 /* Don't let users screw up protocols' entries. */ 1833 if (maddr->sa_family != AF_UNSPEC && maddr->sa_family != AF_LINK) 1834 return (EINVAL); 1835 1836 return (if_delmulti_anon(ifma->ifma_ifp, maddr)); 1837} 1838 1839errno_t 1840ifnet_get_multicast_list(ifnet_t ifp, ifmultiaddr_t **addresses) 1841{ 1842 int count = 0; 1843 int cmax = 0; 1844 struct ifmultiaddr *addr; 1845 1846 if (ifp == NULL || addresses == NULL) 1847 return (EINVAL); 1848 1849 ifnet_lock_shared(ifp); 1850 LIST_FOREACH(addr, &ifp->if_multiaddrs, ifma_link) { 1851 cmax++; 1852 } 1853 1854 MALLOC(*addresses, ifmultiaddr_t *, sizeof (ifmultiaddr_t) * (cmax + 1), 1855 M_TEMP, M_NOWAIT); 1856 if (*addresses == NULL) { 1857 ifnet_lock_done(ifp); 1858 return (ENOMEM); 1859 } 1860 1861 LIST_FOREACH(addr, &ifp->if_multiaddrs, ifma_link) { 1862 if (count + 1 > cmax) 1863 break; 1864 (*addresses)[count] = (ifmultiaddr_t)addr; 1865 ifmaddr_reference((*addresses)[count]); 1866 count++; 1867 } 1868 (*addresses)[cmax] = NULL; 1869 ifnet_lock_done(ifp); 1870 1871 return (0); 1872} 1873 1874void 1875ifnet_free_multicast_list(ifmultiaddr_t *addresses) 1876{ 1877 int i; 1878 1879 if (addresses == NULL) 1880 return; 1881 1882 for (i = 0; addresses[i] != NULL; i++) 1883 ifmaddr_release(addresses[i]); 1884 1885 FREE(addresses, M_TEMP); 1886} 1887 1888errno_t 1889ifnet_find_by_name(const char *ifname, ifnet_t *ifpp) 1890{ 1891 struct ifnet *ifp; 1892 int namelen; 1893 1894 if (ifname == NULL) 1895 return (EINVAL); 1896 1897 namelen = strlen(ifname); 1898 1899 *ifpp = NULL; 1900 1901 ifnet_head_lock_shared(); 1902 TAILQ_FOREACH(ifp, &ifnet_head, if_link) { 1903 struct ifaddr *ifa; 1904 struct sockaddr_dl *ll_addr; 1905 1906 ifa = ifnet_addrs[ifp->if_index - 1]; 1907 if (ifa == NULL) 1908 continue; 1909 1910 IFA_LOCK(ifa); 1911 ll_addr = (struct sockaddr_dl *)(void *)ifa->ifa_addr; 1912 1913 if (namelen == ll_addr->sdl_nlen && strncmp(ll_addr->sdl_data, 1914 ifname, ll_addr->sdl_nlen) == 0) { 1915 IFA_UNLOCK(ifa); 1916 *ifpp = ifp; 1917 ifnet_reference(*ifpp); 1918 break; 1919 } 1920 IFA_UNLOCK(ifa); 1921 } 1922 ifnet_head_done(); 1923 1924 return ((ifp == NULL) ? ENXIO : 0); 1925} 1926 1927errno_t 1928ifnet_list_get(ifnet_family_t family, ifnet_t **list, u_int32_t *count) 1929{ 1930 return (ifnet_list_get_common(family, FALSE, list, count)); 1931} 1932 1933__private_extern__ errno_t 1934ifnet_list_get_all(ifnet_family_t family, ifnet_t **list, u_int32_t *count) 1935{ 1936 return (ifnet_list_get_common(family, TRUE, list, count)); 1937} 1938 1939struct ifnet_list { 1940 SLIST_ENTRY(ifnet_list) ifl_le; 1941 struct ifnet *ifl_ifp; 1942}; 1943 1944static errno_t 1945ifnet_list_get_common(ifnet_family_t family, boolean_t get_all, ifnet_t **list, 1946 u_int32_t *count) 1947{ 1948#pragma unused(get_all) 1949 SLIST_HEAD(, ifnet_list) ifl_head; 1950 struct ifnet_list *ifl, *ifl_tmp; 1951 struct ifnet *ifp; 1952 int cnt = 0; 1953 errno_t err = 0; 1954 1955 SLIST_INIT(&ifl_head); 1956 1957 if (list == NULL || count == NULL) { 1958 err = EINVAL; 1959 goto done; 1960 } 1961 *count = 0; 1962 *list = NULL; 1963 1964 ifnet_head_lock_shared(); 1965 TAILQ_FOREACH(ifp, &ifnet_head, if_link) { 1966 if (family == IFNET_FAMILY_ANY || ifp->if_family == family) { 1967 MALLOC(ifl, struct ifnet_list *, sizeof (*ifl), 1968 M_TEMP, M_NOWAIT); 1969 if (ifl == NULL) { 1970 ifnet_head_done(); 1971 err = ENOMEM; 1972 goto done; 1973 } 1974 ifl->ifl_ifp = ifp; 1975 ifnet_reference(ifp); 1976 SLIST_INSERT_HEAD(&ifl_head, ifl, ifl_le); 1977 ++cnt; 1978 } 1979 } 1980 ifnet_head_done(); 1981 1982 if (cnt == 0) { 1983 err = ENXIO; 1984 goto done; 1985 } 1986 1987 MALLOC(*list, ifnet_t *, sizeof (ifnet_t) * (cnt + 1), 1988 M_TEMP, M_NOWAIT); 1989 if (*list == NULL) { 1990 err = ENOMEM; 1991 goto done; 1992 } 1993 bzero(*list, sizeof (ifnet_t) * (cnt + 1)); 1994 *count = cnt; 1995 1996done: 1997 SLIST_FOREACH_SAFE(ifl, &ifl_head, ifl_le, ifl_tmp) { 1998 SLIST_REMOVE(&ifl_head, ifl, ifnet_list, ifl_le); 1999 if (err == 0) 2000 (*list)[--cnt] = ifl->ifl_ifp; 2001 else 2002 ifnet_release(ifl->ifl_ifp); 2003 FREE(ifl, M_TEMP); 2004 } 2005 2006 return (err); 2007} 2008 2009void 2010ifnet_list_free(ifnet_t *interfaces) 2011{ 2012 int i; 2013 2014 if (interfaces == NULL) 2015 return; 2016 2017 for (i = 0; interfaces[i]; i++) 2018 ifnet_release(interfaces[i]); 2019 2020 FREE(interfaces, M_TEMP); 2021} 2022 2023void 2024ifnet_transmit_burst_start(ifnet_t ifp, mbuf_t pkt) 2025{ 2026#if MEASURE_BW 2027 uint32_t orig_flags; 2028 2029 if (ifp == NULL || !(pkt->m_flags & M_PKTHDR)) 2030 return; 2031 2032 orig_flags = OSBitOrAtomic(IF_MEASURED_BW_INPROGRESS, 2033 &ifp->if_bw.flags); 2034 if (orig_flags & IF_MEASURED_BW_INPROGRESS) { 2035 /* There is already a measurement in progress; skip this one */ 2036 return; 2037 } 2038 2039 ifp->if_bw.start_seq = pkt->m_pkthdr.pkt_bwseq; 2040 ifp->if_bw.start_ts = mach_absolute_time(); 2041#else /*!MEASURE_BW */ 2042#pragma unused(ifp, pkt) 2043#endif /* !MEASURE_BW */ 2044} 2045 2046void 2047ifnet_transmit_burst_end(ifnet_t ifp, mbuf_t pkt) 2048{ 2049#if MEASURE_BW 2050 uint64_t oseq, ots, bytes, ts, t; 2051 uint32_t flags; 2052 2053 if ( ifp == NULL || !(pkt->m_flags & M_PKTHDR)) 2054 return; 2055 2056 flags = OSBitOrAtomic(IF_MEASURED_BW_CALCULATION, &ifp->if_bw.flags); 2057 2058 /* If a calculation is already in progress, just return */ 2059 if (flags & IF_MEASURED_BW_CALCULATION) 2060 return; 2061 2062 /* Check if a measurement was started at all */ 2063 if (!(flags & IF_MEASURED_BW_INPROGRESS)) { 2064 /* 2065 * It is an error to call burst_end before burst_start. 2066 * Reset the calculation flag and return. 2067 */ 2068 goto done; 2069 } 2070 2071 oseq = pkt->m_pkthdr.pkt_bwseq; 2072 ots = mach_absolute_time(); 2073 2074 if (ifp->if_bw.start_seq > 0 && oseq > ifp->if_bw.start_seq) { 2075 ts = ots - ifp->if_bw.start_ts; 2076 if (ts > 0 ) { 2077 absolutetime_to_nanoseconds(ts, &t); 2078 bytes = oseq - ifp->if_bw.start_seq; 2079 ifp->if_bw.bytes = bytes; 2080 ifp->if_bw.ts = ts; 2081 2082 if (t > 0) { 2083 uint64_t bw = 0; 2084 2085 /* Compute bandwidth as bytes/ms */ 2086 bw = (bytes * NSEC_PER_MSEC) / t; 2087 if (bw > 0) { 2088 if (ifp->if_bw.bw > 0) { 2089 u_int32_t shft; 2090 2091 shft = if_bw_smoothing_val; 2092 /* Compute EWMA of bw */ 2093 ifp->if_bw.bw = (bw + 2094 ((ifp->if_bw.bw << shft) - 2095 ifp->if_bw.bw)) >> shft; 2096 } else { 2097 ifp->if_bw.bw = bw; 2098 } 2099 } 2100 } 2101 ifp->if_bw.last_seq = oseq; 2102 ifp->if_bw.last_ts = ots; 2103 } 2104 } 2105 2106done: 2107 flags = ~(IF_MEASURED_BW_INPROGRESS | IF_MEASURED_BW_CALCULATION); 2108 OSBitAndAtomic(flags, &ifp->if_bw.flags); 2109#else /* !MEASURE_BW */ 2110#pragma unused(ifp, pkt) 2111#endif /* !MEASURE_BW */ 2112} 2113 2114/****************************************************************************/ 2115/* ifaddr_t accessors */ 2116/****************************************************************************/ 2117 2118errno_t 2119ifaddr_reference(ifaddr_t ifa) 2120{ 2121 if (ifa == NULL) 2122 return (EINVAL); 2123 2124 IFA_ADDREF(ifa); 2125 return (0); 2126} 2127 2128errno_t 2129ifaddr_release(ifaddr_t ifa) 2130{ 2131 if (ifa == NULL) 2132 return (EINVAL); 2133 2134 IFA_REMREF(ifa); 2135 return (0); 2136} 2137 2138sa_family_t 2139ifaddr_address_family(ifaddr_t ifa) 2140{ 2141 sa_family_t family = 0; 2142 2143 if (ifa != NULL) { 2144 IFA_LOCK_SPIN(ifa); 2145 if (ifa->ifa_addr != NULL) 2146 family = ifa->ifa_addr->sa_family; 2147 IFA_UNLOCK(ifa); 2148 } 2149 return (family); 2150} 2151 2152errno_t 2153ifaddr_address(ifaddr_t ifa, struct sockaddr *out_addr, u_int32_t addr_size) 2154{ 2155 u_int32_t copylen; 2156 2157 if (ifa == NULL || out_addr == NULL) 2158 return (EINVAL); 2159 2160 IFA_LOCK_SPIN(ifa); 2161 if (ifa->ifa_addr == NULL) { 2162 IFA_UNLOCK(ifa); 2163 return (ENOTSUP); 2164 } 2165 2166 copylen = (addr_size >= ifa->ifa_addr->sa_len) ? 2167 ifa->ifa_addr->sa_len : addr_size; 2168 bcopy(ifa->ifa_addr, out_addr, copylen); 2169 2170 if (ifa->ifa_addr->sa_len > addr_size) { 2171 IFA_UNLOCK(ifa); 2172 return (EMSGSIZE); 2173 } 2174 2175 IFA_UNLOCK(ifa); 2176 return (0); 2177} 2178 2179errno_t 2180ifaddr_dstaddress(ifaddr_t ifa, struct sockaddr *out_addr, u_int32_t addr_size) 2181{ 2182 u_int32_t copylen; 2183 2184 if (ifa == NULL || out_addr == NULL) 2185 return (EINVAL); 2186 2187 IFA_LOCK_SPIN(ifa); 2188 if (ifa->ifa_dstaddr == NULL) { 2189 IFA_UNLOCK(ifa); 2190 return (ENOTSUP); 2191 } 2192 2193 copylen = (addr_size >= ifa->ifa_dstaddr->sa_len) ? 2194 ifa->ifa_dstaddr->sa_len : addr_size; 2195 bcopy(ifa->ifa_dstaddr, out_addr, copylen); 2196 2197 if (ifa->ifa_dstaddr->sa_len > addr_size) { 2198 IFA_UNLOCK(ifa); 2199 return (EMSGSIZE); 2200 } 2201 2202 IFA_UNLOCK(ifa); 2203 return (0); 2204} 2205 2206errno_t 2207ifaddr_netmask(ifaddr_t ifa, struct sockaddr *out_addr, u_int32_t addr_size) 2208{ 2209 u_int32_t copylen; 2210 2211 if (ifa == NULL || out_addr == NULL) 2212 return (EINVAL); 2213 2214 IFA_LOCK_SPIN(ifa); 2215 if (ifa->ifa_netmask == NULL) { 2216 IFA_UNLOCK(ifa); 2217 return (ENOTSUP); 2218 } 2219 2220 copylen = addr_size >= ifa->ifa_netmask->sa_len ? 2221 ifa->ifa_netmask->sa_len : addr_size; 2222 bcopy(ifa->ifa_netmask, out_addr, copylen); 2223 2224 if (ifa->ifa_netmask->sa_len > addr_size) { 2225 IFA_UNLOCK(ifa); 2226 return (EMSGSIZE); 2227 } 2228 2229 IFA_UNLOCK(ifa); 2230 return (0); 2231} 2232 2233ifnet_t 2234ifaddr_ifnet(ifaddr_t ifa) 2235{ 2236 struct ifnet *ifp; 2237 2238 if (ifa == NULL) 2239 return (NULL); 2240 2241 /* ifa_ifp is set once at creation time; it is never changed */ 2242 ifp = ifa->ifa_ifp; 2243 2244 return (ifp); 2245} 2246 2247ifaddr_t 2248ifaddr_withaddr(const struct sockaddr *address) 2249{ 2250 if (address == NULL) 2251 return (NULL); 2252 2253 return (ifa_ifwithaddr(address)); 2254} 2255 2256ifaddr_t 2257ifaddr_withdstaddr(const struct sockaddr *address) 2258{ 2259 if (address == NULL) 2260 return (NULL); 2261 2262 return (ifa_ifwithdstaddr(address)); 2263} 2264 2265ifaddr_t 2266ifaddr_withnet(const struct sockaddr *net) 2267{ 2268 if (net == NULL) 2269 return (NULL); 2270 2271 return (ifa_ifwithnet(net)); 2272} 2273 2274ifaddr_t 2275ifaddr_withroute(int flags, const struct sockaddr *destination, 2276 const struct sockaddr *gateway) 2277{ 2278 if (destination == NULL || gateway == NULL) 2279 return (NULL); 2280 2281 return (ifa_ifwithroute(flags, destination, gateway)); 2282} 2283 2284ifaddr_t 2285ifaddr_findbestforaddr(const struct sockaddr *addr, ifnet_t interface) 2286{ 2287 if (addr == NULL || interface == NULL) 2288 return (NULL); 2289 2290 return (ifaof_ifpforaddr(addr, interface)); 2291} 2292 2293errno_t 2294ifmaddr_reference(ifmultiaddr_t ifmaddr) 2295{ 2296 if (ifmaddr == NULL) 2297 return (EINVAL); 2298 2299 IFMA_ADDREF(ifmaddr); 2300 return (0); 2301} 2302 2303errno_t 2304ifmaddr_release(ifmultiaddr_t ifmaddr) 2305{ 2306 if (ifmaddr == NULL) 2307 return (EINVAL); 2308 2309 IFMA_REMREF(ifmaddr); 2310 return (0); 2311} 2312 2313errno_t 2314ifmaddr_address(ifmultiaddr_t ifma, struct sockaddr *out_addr, 2315 u_int32_t addr_size) 2316{ 2317 u_int32_t copylen; 2318 2319 if (ifma == NULL || out_addr == NULL) 2320 return (EINVAL); 2321 2322 IFMA_LOCK(ifma); 2323 if (ifma->ifma_addr == NULL) { 2324 IFMA_UNLOCK(ifma); 2325 return (ENOTSUP); 2326 } 2327 2328 copylen = (addr_size >= ifma->ifma_addr->sa_len ? 2329 ifma->ifma_addr->sa_len : addr_size); 2330 bcopy(ifma->ifma_addr, out_addr, copylen); 2331 2332 if (ifma->ifma_addr->sa_len > addr_size) { 2333 IFMA_UNLOCK(ifma); 2334 return (EMSGSIZE); 2335 } 2336 IFMA_UNLOCK(ifma); 2337 return (0); 2338} 2339 2340errno_t 2341ifmaddr_lladdress(ifmultiaddr_t ifma, struct sockaddr *out_addr, 2342 u_int32_t addr_size) 2343{ 2344 struct ifmultiaddr *ifma_ll; 2345 2346 if (ifma == NULL || out_addr == NULL) 2347 return (EINVAL); 2348 if ((ifma_ll = ifma->ifma_ll) == NULL) 2349 return (ENOTSUP); 2350 2351 return (ifmaddr_address(ifma_ll, out_addr, addr_size)); 2352} 2353 2354ifnet_t 2355ifmaddr_ifnet(ifmultiaddr_t ifma) 2356{ 2357 return ((ifma == NULL) ? NULL : ifma->ifma_ifp); 2358} 2359 2360/******************************************************************************/ 2361/* interface cloner */ 2362/******************************************************************************/ 2363 2364errno_t 2365ifnet_clone_attach(struct ifnet_clone_params *cloner_params, 2366 if_clone_t *ifcloner) 2367{ 2368 errno_t error = 0; 2369 struct if_clone *ifc = NULL; 2370 size_t namelen; 2371 2372 if (cloner_params == NULL || ifcloner == NULL || 2373 cloner_params->ifc_name == NULL || 2374 cloner_params->ifc_create == NULL || 2375 cloner_params->ifc_destroy == NULL || 2376 (namelen = strlen(cloner_params->ifc_name)) >= IFNAMSIZ) { 2377 error = EINVAL; 2378 goto fail; 2379 } 2380 2381 if (if_clone_lookup(cloner_params->ifc_name, NULL) != NULL) { 2382 printf("%s: already a cloner for %s\n", __func__, 2383 cloner_params->ifc_name); 2384 error = EEXIST; 2385 goto fail; 2386 } 2387 2388 /* Make room for name string */ 2389 ifc = _MALLOC(sizeof (struct if_clone) + IFNAMSIZ + 1, M_CLONE, 2390 M_WAITOK | M_ZERO); 2391 if (ifc == NULL) { 2392 printf("%s: _MALLOC failed\n", __func__); 2393 error = ENOBUFS; 2394 goto fail; 2395 } 2396 strlcpy((char *)(ifc + 1), cloner_params->ifc_name, IFNAMSIZ + 1); 2397 ifc->ifc_name = (char *)(ifc + 1); 2398 ifc->ifc_namelen = namelen; 2399 ifc->ifc_maxunit = IF_MAXUNIT; 2400 ifc->ifc_create = cloner_params->ifc_create; 2401 ifc->ifc_destroy = cloner_params->ifc_destroy; 2402 2403 error = if_clone_attach(ifc); 2404 if (error != 0) { 2405 printf("%s: if_clone_attach failed %d\n", __func__, error); 2406 goto fail; 2407 } 2408 *ifcloner = ifc; 2409 2410 return (0); 2411fail: 2412 if (ifc != NULL) 2413 FREE(ifc, M_CLONE); 2414 return (error); 2415} 2416 2417errno_t 2418ifnet_clone_detach(if_clone_t ifcloner) 2419{ 2420 errno_t error = 0; 2421 struct if_clone *ifc = ifcloner; 2422 2423 if (ifc == NULL || ifc->ifc_name == NULL) 2424 return (EINVAL); 2425 2426 if ((if_clone_lookup(ifc->ifc_name, NULL)) == NULL) { 2427 printf("%s: no cloner for %s\n", __func__, ifc->ifc_name); 2428 error = EINVAL; 2429 goto fail; 2430 } 2431 2432 if_clone_detach(ifc); 2433 2434 FREE(ifc, M_CLONE); 2435 2436fail: 2437 return (error); 2438} 2439 2440/******************************************************************************/ 2441/* misc */ 2442/******************************************************************************/ 2443 2444errno_t 2445ifnet_get_local_ports_extended(ifnet_t ifp, protocol_family_t protocol, 2446 u_int32_t wildcardok, u_int8_t *bitfield) 2447{ 2448 u_int32_t ifindex; 2449 2450 if (bitfield == NULL) 2451 return (EINVAL); 2452 2453 switch (protocol) { 2454 case PF_UNSPEC: 2455 case PF_INET: 2456 case PF_INET6: 2457 break; 2458 default: 2459 return (EINVAL); 2460 } 2461 2462 /* bit string is long enough to hold 16-bit port values */ 2463 bzero(bitfield, bitstr_size(65536)); 2464 2465 ifindex = (ifp != NULL) ? ifp->if_index : 0; 2466 2467 udp_get_ports_used(ifindex, protocol, wildcardok, bitfield); 2468 tcp_get_ports_used(ifindex, protocol, wildcardok, bitfield); 2469 2470 return (0); 2471} 2472 2473errno_t 2474ifnet_get_local_ports(ifnet_t ifp, u_int8_t *bitfield) 2475{ 2476 return (ifnet_get_local_ports_extended(ifp, PF_UNSPEC, 1, bitfield)); 2477} 2478 2479errno_t 2480ifnet_notice_node_presence(ifnet_t ifp, struct sockaddr* sa, int32_t rssi, 2481 int lqm, int npm, u_int8_t srvinfo[48]) 2482{ 2483 if (ifp == NULL || sa == NULL || srvinfo == NULL) 2484 return(EINVAL); 2485 if (sa->sa_len > sizeof(struct sockaddr_storage)) 2486 return(EINVAL); 2487 if (sa->sa_family != AF_LINK && sa->sa_family != AF_INET6) 2488 return(EINVAL); 2489 2490 dlil_node_present(ifp, sa, rssi, lqm, npm, srvinfo); 2491 return (0); 2492} 2493 2494errno_t 2495ifnet_notice_node_absence(ifnet_t ifp, struct sockaddr* sa) 2496{ 2497 if (ifp == NULL || sa == NULL) 2498 return(EINVAL); 2499 if (sa->sa_len > sizeof(struct sockaddr_storage)) 2500 return(EINVAL); 2501 if (sa->sa_family != AF_LINK && sa->sa_family != AF_INET6) 2502 return(EINVAL); 2503 2504 dlil_node_absent(ifp, sa); 2505 return (0); 2506} 2507 2508errno_t 2509ifnet_notice_master_elected(ifnet_t ifp) 2510{ 2511 if (ifp == NULL) 2512 return(EINVAL); 2513 2514 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_MASTER_ELECTED, NULL, 0); 2515 return (0); 2516} 2517 2518errno_t 2519ifnet_tx_compl_status(ifnet_t ifp, mbuf_t m, tx_compl_val_t val) 2520{ 2521#pragma unused(ifp, m, val) 2522 /* Dummy function to be implemented XXX */ 2523 return (0); 2524} 2525 2526errno_t 2527ifnet_report_issues(ifnet_t ifp, u_int8_t modid[IFNET_MODIDLEN], 2528 u_int8_t info[IFNET_MODARGLEN]) 2529{ 2530 if (ifp == NULL || modid == NULL) 2531 return (EINVAL); 2532 2533 dlil_report_issues(ifp, modid, info); 2534 return (0); 2535} 2536 2537extern errno_t 2538ifnet_set_delegate(ifnet_t ifp, ifnet_t delegated_ifp) 2539{ 2540 ifnet_t odifp = NULL; 2541 2542 if (ifp == NULL) 2543 return (EINVAL); 2544 else if (!ifnet_is_attached(ifp, 1)) 2545 return (ENXIO); 2546 2547 ifnet_lock_exclusive(ifp); 2548 odifp = ifp->if_delegated.ifp; 2549 if (odifp != NULL && odifp == delegated_ifp) { 2550 /* delegate info is unchanged; nothing more to do */ 2551 ifnet_lock_done(ifp); 2552 goto done; 2553 } 2554 bzero(&ifp->if_delegated, sizeof (ifp->if_delegated)); 2555 if (delegated_ifp != NULL && ifp != delegated_ifp) { 2556 ifp->if_delegated.ifp = delegated_ifp; 2557 ifnet_reference(delegated_ifp); 2558 ifp->if_delegated.type = delegated_ifp->if_type; 2559 ifp->if_delegated.family = delegated_ifp->if_family; 2560 ifp->if_delegated.subfamily = delegated_ifp->if_subfamily; 2561 printf("%s: is now delegating %s (type 0x%x, family %u, " 2562 "sub-family %u)\n", ifp->if_xname, delegated_ifp->if_xname, 2563 delegated_ifp->if_type, delegated_ifp->if_family, 2564 delegated_ifp->if_subfamily); 2565 } 2566 ifnet_lock_done(ifp); 2567 2568 if (odifp != NULL) { 2569 if (odifp != delegated_ifp) { 2570 printf("%s: is no longer delegating %s\n", 2571 ifp->if_xname, odifp->if_xname); 2572 } 2573 ifnet_release(odifp); 2574 } 2575 2576 /* Generate a kernel event */ 2577 dlil_post_msg(ifp, KEV_DL_SUBCLASS, KEV_DL_IFDELEGATE_CHANGED, NULL, 0); 2578 2579done: 2580 /* Release the io ref count */ 2581 ifnet_decr_iorefcnt(ifp); 2582 2583 return (0); 2584} 2585 2586extern errno_t 2587ifnet_get_delegate(ifnet_t ifp, ifnet_t *pdelegated_ifp) 2588{ 2589 if (ifp == NULL || pdelegated_ifp == NULL) 2590 return (EINVAL); 2591 else if (!ifnet_is_attached(ifp, 1)) 2592 return (ENXIO); 2593 2594 ifnet_lock_shared(ifp); 2595 if (ifp->if_delegated.ifp != NULL) 2596 ifnet_reference(ifp->if_delegated.ifp); 2597 *pdelegated_ifp = ifp->if_delegated.ifp; 2598 ifnet_lock_done(ifp); 2599 2600 /* Release the io ref count */ 2601 ifnet_decr_iorefcnt(ifp); 2602 2603 return (0); 2604} 2605