1 /* $NetBSD: if_lagg.c,v 1.57 2023/12/01 09:27:17 yamaguchi Exp $ */ 2 3 /* 4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> 5 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org> 6 * Copyright (c) 2014, 2016 Marcelo Araujo <araujo@FreeBSD.org> 7 * Copyright (c) 2021, Internet Initiative Japan Inc. 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 #include <sys/cdefs.h> 23 __KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.57 2023/12/01 09:27:17 yamaguchi Exp $"); 24 25 #ifdef _KERNEL_OPT 26 #include "opt_inet.h" 27 #include "opt_lagg.h" 28 #endif 29 30 #include <sys/param.h> 31 #include <sys/types.h> 32 33 #include <sys/cprng.h> 34 #include <sys/cpu.h> 35 #include <sys/device.h> 36 #include <sys/evcnt.h> 37 #include <sys/hash.h> 38 #include <sys/kmem.h> 39 #include <sys/module.h> 40 #include <sys/pserialize.h> 41 #include <sys/pslist.h> 42 #include <sys/psref.h> 43 #include <sys/sysctl.h> 44 #include <sys/syslog.h> 45 #include <sys/workqueue.h> 46 47 #include <net/bpf.h> 48 #include <net/if.h> 49 #include <net/if_dl.h> 50 #include <net/if_ether.h> 51 #include <net/if_media.h> 52 #include <net/if_types.h> 53 #include <net/if_vlanvar.h> 54 #include <netinet/ip.h> 55 #include <netinet/ip6.h> 56 #include <netinet/tcp.h> 57 #include <netinet/udp.h> 58 59 #if defined(INET) || defined(INET6) 60 #include <netinet/in.h> 61 #endif 62 63 #ifdef INET6 64 #include <netinet6/in6_ifattach.h> 65 #include <netinet6/in6_var.h> 66 #endif 67 68 #include <net/lagg/if_lagg.h> 69 #include <net/lagg/if_laggproto.h> 70 71 #include "ioconf.h" 72 73 enum lagg_portctrl { 74 LAGG_PORTCTRL_ALLOC, 75 LAGG_PORTCTRL_FREE, 76 LAGG_PORTCTRL_START, 77 LAGG_PORTCTRL_STOP 78 }; 79 80 enum lagg_iftypes { 81 LAGG_IF_TYPE_ETHERNET, 82 }; 83 84 static const struct lagg_proto lagg_protos[] = { 85 [LAGG_PROTO_NONE] = { 86 .pr_num = LAGG_PROTO_NONE, 87 .pr_attach = lagg_none_attach, 88 }, 89 [LAGG_PROTO_LACP] = { 90 .pr_num = LAGG_PROTO_LACP, 91 .pr_attach = lacp_attach, 92 .pr_detach = lacp_detach, 93 .pr_up = lacp_up, 94 .pr_down = lacp_down, 95 .pr_transmit = lacp_transmit, 96 .pr_input = lacp_input, 97 .pr_allocport = lacp_allocport, 98 .pr_freeport = lacp_freeport, 99 .pr_startport = lacp_startport, 100 .pr_stopport = lacp_stopport, 101 .pr_protostat = lacp_protostat, 102 .pr_portstat = lacp_portstat, 103 .pr_linkstate = lacp_linkstate_ifnet_locked, 104 .pr_ioctl = lacp_ioctl, 105 }, 106 [LAGG_PROTO_FAILOVER] = { 107 .pr_num = LAGG_PROTO_FAILOVER, 108 .pr_attach = lagg_fail_attach, 109 .pr_detach = lagg_common_detach, 110 .pr_transmit = lagg_fail_transmit, 111 .pr_input = lagg_fail_input, 112 .pr_allocport = lagg_common_allocport, 113 .pr_freeport = lagg_common_freeport, 114 .pr_startport = lagg_common_startport, 115 .pr_stopport = lagg_common_stopport, 116 .pr_portstat = lagg_fail_portstat, 117 .pr_linkstate = lagg_common_linkstate_ifnet_locked, 118 .pr_ioctl = lagg_fail_ioctl, 119 }, 120 [LAGG_PROTO_LOADBALANCE] = { 121 .pr_num = LAGG_PROTO_LOADBALANCE, 122 .pr_attach = lagg_lb_attach, 123 .pr_detach = lagg_common_detach, 124 .pr_transmit = lagg_lb_transmit, 125 .pr_input = lagg_lb_input, 126 .pr_allocport = lagg_common_allocport, 127 .pr_freeport = lagg_common_freeport, 128 .pr_startport = lagg_lb_startport, 129 .pr_stopport = lagg_lb_stopport, 130 .pr_portstat = lagg_lb_portstat, 131 .pr_linkstate = lagg_common_linkstate_ifnet_locked, 132 }, 133 }; 134 135 static int lagg_chg_sadl(struct ifnet *, const uint8_t *, size_t); 136 static void lagg_input_ethernet(struct ifnet *, struct mbuf *); 137 static int lagg_clone_create(struct if_clone *, int); 138 static int lagg_clone_destroy(struct ifnet *); 139 static int lagg_init(struct ifnet *); 140 static int lagg_init_locked(struct lagg_softc *); 141 static void lagg_stop(struct ifnet *, int); 142 static void lagg_stop_locked(struct lagg_softc *); 143 static int lagg_ioctl(struct ifnet *, u_long, void *); 144 static int lagg_transmit(struct ifnet *, struct mbuf *); 145 static void lagg_start(struct ifnet *); 146 static int lagg_media_change(struct ifnet *); 147 static void lagg_media_status(struct ifnet *, struct ifmediareq *); 148 static int lagg_vlan_cb(struct ethercom *, uint16_t, bool); 149 static void lagg_linkstate_changed(void *); 150 static void lagg_ifdetach(void *); 151 static struct lagg_softc * 152 lagg_softc_alloc(enum lagg_iftypes); 153 static void lagg_softc_free(struct lagg_softc *); 154 static int lagg_setup_sysctls(struct lagg_softc *); 155 static void lagg_teardown_sysctls(struct lagg_softc *); 156 static int lagg_proto_attach(struct lagg_softc *, lagg_proto, 157 struct lagg_proto_softc **); 158 static void lagg_proto_detach(struct lagg_variant *); 159 static int lagg_proto_up(struct lagg_softc *); 160 static void lagg_proto_down(struct lagg_softc *); 161 static int lagg_proto_allocport(struct lagg_softc *, struct lagg_port *); 162 static void lagg_proto_freeport(struct lagg_softc *, struct lagg_port *); 163 static void lagg_proto_startport(struct lagg_softc *, 164 struct lagg_port *); 165 static void lagg_proto_stopport(struct lagg_softc *, 166 struct lagg_port *); 167 static struct mbuf * 168 lagg_proto_input(struct lagg_softc *, struct lagg_port *, 169 struct mbuf *); 170 static void lagg_proto_linkstate(struct lagg_softc *, struct lagg_port *); 171 static int lagg_proto_ioctl(struct lagg_softc *, struct lagg_req *); 172 static int lagg_get_stats(struct lagg_softc *, struct lagg_req *, size_t); 173 static int lagg_pr_attach(struct lagg_softc *, lagg_proto); 174 static void lagg_pr_detach(struct lagg_softc *); 175 static int lagg_addport(struct lagg_softc *, struct ifnet *); 176 static int lagg_delport(struct lagg_softc *, struct ifnet *); 177 static int lagg_delport_all(struct lagg_softc *); 178 static int lagg_port_ioctl(struct ifnet *, u_long, void *); 179 static int lagg_port_output(struct ifnet *, struct mbuf *, 180 const struct sockaddr *, const struct rtentry *); 181 static void lagg_config_promisc(struct lagg_softc *, struct lagg_port *); 182 static void lagg_unconfig_promisc(struct lagg_softc *, struct lagg_port *); 183 static struct lagg_variant * 184 lagg_variant_getref(struct lagg_softc *, struct psref *); 185 static void lagg_variant_putref(struct lagg_variant *, struct psref *); 186 static int lagg_ether_addmulti(struct lagg_softc *, struct ifreq *); 187 static int lagg_ether_delmulti(struct lagg_softc *, struct ifreq *); 188 static void lagg_port_syncmulti(struct lagg_softc *, struct lagg_port *); 189 static void lagg_port_purgemulti(struct lagg_softc *, struct lagg_port *); 190 static int lagg_port_setup(struct lagg_softc *, struct lagg_port *, 191 struct ifnet *); 192 static void lagg_port_teardown(struct lagg_softc *, struct lagg_port *, 193 bool); 194 static void lagg_port_syncvlan(struct lagg_softc *, struct lagg_port *); 195 static void lagg_port_purgevlan(struct lagg_softc *, struct lagg_port *); 196 static void lagg_capabilities_update(struct lagg_softc *); 197 static void lagg_sync_ifcaps(struct lagg_softc *); 198 static void lagg_sync_ethcaps(struct lagg_softc *); 199 static void lagg_sync_sadl(struct lagg_softc *); 200 201 static struct if_clone lagg_cloner = 202 IF_CLONE_INITIALIZER("lagg", lagg_clone_create, lagg_clone_destroy); 203 static unsigned int lagg_count; 204 static struct psref_class 205 *lagg_psref_class __read_mostly; 206 static struct psref_class 207 *lagg_port_psref_class __read_mostly; 208 209 static enum lagg_iftypes 210 lagg_iftype = LAGG_IF_TYPE_ETHERNET; 211 212 #ifdef LAGG_DEBUG 213 #define __LAGGDEBUGUSED 214 #define LAGG_DPRINTF(_sc, _fmt, _args...) do { \ 215 printf("%s: " _fmt, (_sc) != NULL ? \ 216 (_sc)->sc_if.if_xname : "lagg", ##_args); \ 217 } while (0) 218 #else 219 #define __LAGGDEBUGUSED __unused 220 #define LAGG_DPRINTF(_sc, _fmt, _args...) __nothing 221 #endif 222 223 #ifndef LAGG_SETCAPS_RETRY 224 #define LAGG_SETCAPS_RETRY (LAGG_MAX_PORTS * 2) 225 #endif 226 227 static size_t 228 lagg_sizeof_softc(enum lagg_iftypes ift) 229 { 230 struct lagg_softc *_dummy = NULL; 231 size_t s; 232 233 s = sizeof(*_dummy) - sizeof(_dummy->sc_if); 234 235 switch (ift) { 236 case LAGG_IF_TYPE_ETHERNET: 237 s += sizeof(struct ethercom); 238 break; 239 default: 240 s += sizeof(struct ifnet); 241 break; 242 } 243 244 return s; 245 } 246 247 static void 248 lagg_evcnt_attach(struct lagg_softc *sc, 249 struct evcnt *ev, const char *name) 250 { 251 252 evcnt_attach_dynamic(ev, EVCNT_TYPE_MISC, NULL, 253 sc->sc_evgroup, name); 254 } 255 256 static void 257 lagg_in6_ifattach(struct ifnet *ifp) 258 { 259 260 #ifdef INET6 261 KERNEL_LOCK_UNLESS_NET_MPSAFE(); 262 if (in6_present) { 263 if (ISSET(ifp->if_flags, IFF_UP)) 264 in6_ifattach(ifp, NULL); 265 } 266 KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); 267 #endif 268 } 269 270 static void 271 lagg_in6_ifdetach(struct ifnet *ifp) 272 { 273 274 #ifdef INET6 275 KERNEL_LOCK_UNLESS_NET_MPSAFE(); 276 if (in6_present) 277 in6_ifdetach(ifp); 278 KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); 279 #endif 280 } 281 282 static int 283 lagg_lp_ioctl(struct lagg_port *lp, u_long cmd, void *data) 284 { 285 struct ifnet *ifp_port; 286 int error; 287 288 if (lp->lp_ioctl == NULL) 289 return EINVAL; 290 291 ifp_port = lp->lp_ifp; 292 IFNET_LOCK(ifp_port); 293 error = lp->lp_ioctl(ifp_port, cmd, data); 294 IFNET_UNLOCK(ifp_port); 295 296 return error; 297 } 298 299 static bool 300 lagg_lladdr_equal(const uint8_t *a, const uint8_t *b) 301 { 302 303 if (memcmp(a, b, ETHER_ADDR_LEN) == 0) 304 return true; 305 306 return false; 307 } 308 309 static void 310 lagg_lladdr_cpy(uint8_t *dst, const uint8_t *src) 311 { 312 313 memcpy(dst, src, ETHER_ADDR_LEN); 314 } 315 316 void 317 laggattach(int n) 318 { 319 320 /* 321 * Nothing to do here, initialization is handled by the 322 * module initialization code in lagginit() below). 323 */ 324 } 325 326 static void 327 lagginit(void) 328 { 329 size_t i; 330 331 lagg_psref_class = psref_class_create("laggvariant", IPL_SOFTNET); 332 lagg_port_psref_class = psref_class_create("laggport", IPL_SOFTNET); 333 334 for (i = 0; i < LAGG_PROTO_MAX; i++) { 335 if (lagg_protos[i].pr_init != NULL) 336 lagg_protos[i].pr_init(); 337 } 338 339 if_clone_attach(&lagg_cloner); 340 } 341 342 static int 343 laggdetach(void) 344 { 345 size_t i; 346 347 if (lagg_count > 0) 348 return EBUSY; 349 350 if_clone_detach(&lagg_cloner); 351 352 for (i = 0; i < LAGG_PROTO_MAX; i++) { 353 if (lagg_protos[i].pr_fini != NULL) 354 lagg_protos[i].pr_fini(); 355 } 356 357 psref_class_destroy(lagg_port_psref_class); 358 psref_class_destroy(lagg_psref_class); 359 360 return 0; 361 } 362 363 static int 364 lagg_clone_create(struct if_clone *ifc, int unit) 365 { 366 struct lagg_softc *sc; 367 struct ifnet *ifp; 368 struct ethercom *ec; 369 int error; 370 371 sc = lagg_softc_alloc(lagg_iftype); 372 ifp = &sc->sc_if; 373 374 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTNET); 375 sc->sc_psz = pserialize_create(); 376 SIMPLEQ_INIT(&sc->sc_ports); 377 LIST_INIT(&sc->sc_mclist); 378 TAILQ_INIT(&sc->sc_vtags); 379 sc->sc_hash_mac = true; 380 sc->sc_hash_ipaddr = true; 381 sc->sc_hash_ip6addr = true; 382 sc->sc_hash_tcp = true; 383 sc->sc_hash_udp = true; 384 385 if_initname(ifp, ifc->ifc_name, unit); 386 ifp->if_softc = sc; 387 ifp->if_init = lagg_init; 388 ifp->if_stop = lagg_stop; 389 ifp->if_ioctl = lagg_ioctl; 390 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 391 ifp->if_extflags = IFEF_MPSAFE; 392 ifp->if_transmit = lagg_transmit; 393 ifp->if_start = lagg_start; 394 IFQ_SET_READY(&ifp->if_snd); 395 396 error = lagg_setup_sysctls(sc); 397 if (error != 0) 398 goto destroy_psz; 399 400 /*XXX dependent on ethernet */ 401 ifmedia_init_with_lock(&sc->sc_media, 0, lagg_media_change, 402 lagg_media_status, &sc->sc_lock); 403 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 404 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 405 406 if_initialize(ifp); 407 408 switch (lagg_iftype) { 409 case LAGG_IF_TYPE_ETHERNET: 410 ec = (struct ethercom *)ifp; 411 cprng_fast(sc->sc_lladdr_rand, sizeof(sc->sc_lladdr_rand)); 412 sc->sc_lladdr_rand[0] &= 0xFE; /* clear I/G bit */ 413 sc->sc_lladdr_rand[0] |= 0x02; /* set G/L bit */ 414 lagg_lladdr_cpy(sc->sc_lladdr, sc->sc_lladdr_rand); 415 ether_set_vlan_cb(ec, lagg_vlan_cb); 416 417 /* 418 * notify ETHERCAP_VLAN_HWTAGGING to ether_ifattach 419 * to handle VLAN tag, stripped by hardware, in bpf(4) 420 */ 421 ec->ec_capabilities = ETHERCAP_VLAN_HWTAGGING; 422 423 ether_ifattach(ifp, sc->sc_lladdr_rand); 424 break; 425 default: 426 panic("unknown if type"); 427 } 428 429 snprintf(sc->sc_evgroup, sizeof(sc->sc_evgroup), 430 "%s", ifp->if_xname); 431 lagg_evcnt_attach(sc, &sc->sc_novar, "no lagg variant"); 432 if_link_state_change(&sc->sc_if, LINK_STATE_DOWN); 433 lagg_setup_sysctls(sc); 434 (void)lagg_pr_attach(sc, LAGG_PROTO_NONE); 435 if_register(ifp); 436 lagg_count++; 437 438 return 0; 439 440 destroy_psz: 441 pserialize_destroy(sc->sc_psz); 442 mutex_destroy(&sc->sc_lock); 443 lagg_softc_free(sc); 444 445 return error; 446 } 447 448 static int 449 lagg_clone_destroy(struct ifnet *ifp) 450 { 451 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 452 struct lagg_port *lp; 453 454 lagg_stop(ifp, 1); 455 456 IFNET_LOCK(ifp); 457 LAGG_LOCK(sc); 458 while ((lp = LAGG_PORTS_FIRST(sc)) != NULL) { 459 lagg_port_teardown(sc, lp, false); 460 } 461 LAGG_UNLOCK(sc); 462 IFNET_UNLOCK(ifp); 463 464 switch (ifp->if_type) { 465 case IFT_ETHER: 466 ether_ifdetach(ifp); 467 KASSERT(TAILQ_EMPTY(&sc->sc_vtags)); 468 break; 469 } 470 471 if_detach(ifp); 472 ifmedia_fini(&sc->sc_media); 473 lagg_pr_detach(sc); 474 evcnt_detach(&sc->sc_novar); 475 lagg_teardown_sysctls(sc); 476 477 pserialize_destroy(sc->sc_psz); 478 mutex_destroy(&sc->sc_lock); 479 lagg_softc_free(sc); 480 481 if (lagg_count > 0) 482 lagg_count--; 483 484 return 0; 485 } 486 487 static int 488 lagg_init(struct ifnet *ifp) 489 { 490 struct lagg_softc *sc; 491 int rv; 492 493 sc = ifp->if_softc; 494 LAGG_LOCK(sc); 495 rv = lagg_init_locked(sc); 496 LAGG_UNLOCK(sc); 497 498 return rv; 499 } 500 501 static int 502 lagg_init_locked(struct lagg_softc *sc) 503 { 504 struct ifnet *ifp = &sc->sc_if; 505 int rv; 506 507 KASSERT(LAGG_LOCKED(sc)); 508 509 if (ISSET(ifp->if_flags, IFF_RUNNING)) 510 lagg_stop_locked(sc); 511 512 lagg_sync_sadl(sc); 513 514 SET(ifp->if_flags, IFF_RUNNING); 515 516 rv = lagg_proto_up(sc); 517 if (rv != 0) 518 lagg_stop_locked(sc); 519 520 return rv; 521 } 522 523 static void 524 lagg_stop(struct ifnet *ifp, int disable __unused) 525 { 526 struct lagg_softc *sc; 527 528 sc = ifp->if_softc; 529 LAGG_LOCK(sc); 530 lagg_stop_locked(sc); 531 LAGG_UNLOCK(sc); 532 } 533 534 static void 535 lagg_stop_locked(struct lagg_softc *sc) 536 { 537 struct ifnet *ifp = &sc->sc_if; 538 539 KASSERT(LAGG_LOCKED(sc)); 540 541 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 542 return; 543 544 CLR(ifp->if_flags, IFF_RUNNING); 545 lagg_proto_down(sc); 546 547 } 548 549 static int 550 lagg_config(struct lagg_softc *sc, struct lagg_req *lrq) 551 { 552 struct ifnet *ifp_port; 553 struct laggreqport *rp; 554 struct lagg_port *lp; 555 struct psref psref; 556 size_t i; 557 int error, bound; 558 559 error = 0; 560 bound = curlwp_bind(); 561 562 switch (lrq->lrq_ioctl) { 563 case LAGGIOC_SETPROTO: 564 if (lrq->lrq_proto >= LAGG_PROTO_MAX) { 565 error = EPROTONOSUPPORT; 566 break; 567 } 568 569 error = lagg_delport_all(sc); 570 if (error != 0) 571 break; 572 error = lagg_pr_attach(sc, lrq->lrq_proto); 573 if (error != 0) 574 break; 575 576 for (i = 0; i < lrq->lrq_nports; i++) { 577 rp = &lrq->lrq_reqports[i]; 578 ifp_port = if_get(rp->rp_portname, &psref); 579 if (ifp_port == NULL) { 580 error = ENOENT; 581 break; /* break for */ 582 } 583 584 error = lagg_addport(sc, ifp_port); 585 if_put(ifp_port, &psref); 586 587 if (error != 0) 588 break; /* break for */ 589 } 590 break; /* break switch */ 591 case LAGGIOC_ADDPORT: 592 rp = &lrq->lrq_reqports[0]; 593 ifp_port = if_get(rp->rp_portname, &psref); 594 if (ifp_port == NULL) { 595 error = ENOENT; 596 break; 597 } 598 599 error = lagg_addport(sc, ifp_port); 600 if_put(ifp_port, &psref); 601 break; 602 case LAGGIOC_DELPORT: 603 rp = &lrq->lrq_reqports[0]; 604 ifp_port = if_get(rp->rp_portname, &psref); 605 if (ifp_port == NULL) { 606 error = ENOENT; 607 break; 608 } 609 610 error = lagg_delport(sc, ifp_port); 611 if_put(ifp_port, &psref); 612 break; 613 case LAGGIOC_SETPORTPRI: 614 rp = &lrq->lrq_reqports[0]; 615 ifp_port = if_get(rp->rp_portname, &psref); 616 if (ifp_port == NULL) { 617 error = ENOENT; 618 break; 619 } 620 621 lp = ifp_port->if_lagg; 622 if (lp == NULL || lp->lp_softc != sc) { 623 if_put(ifp_port, &psref); 624 error = ENOENT; 625 break; 626 } 627 628 lp->lp_prio = rp->rp_prio; 629 630 /* restart protocol */ 631 LAGG_LOCK(sc); 632 lagg_proto_stopport(sc, lp); 633 lagg_proto_startport(sc, lp); 634 LAGG_UNLOCK(sc); 635 if_put(ifp_port, &psref); 636 break; 637 case LAGGIOC_SETPROTOOPT: 638 error = lagg_proto_ioctl(sc, lrq); 639 break; 640 default: 641 error = ENOTTY; 642 } 643 644 curlwp_bindx(bound); 645 return error; 646 } 647 648 static int 649 lagg_ioctl(struct ifnet *ifp, u_long cmd, void *data) 650 { 651 struct lagg_softc *sc; 652 struct ifreq *ifr = (struct ifreq *)data; 653 struct lagg_req laggreq, *laggresp; 654 struct lagg_port *lp; 655 size_t allocsiz, outlen, nports; 656 char *outbuf; 657 void *buf; 658 int error = 0, rv; 659 660 sc = ifp->if_softc; 661 662 switch (cmd) { 663 case SIOCGLAGG: 664 error = copyin(ifr->ifr_data, &laggreq, sizeof(laggreq)); 665 if (error != 0) 666 break; 667 668 nports = sc->sc_nports; 669 nports = MIN(nports, laggreq.lrq_nports); 670 671 allocsiz = sizeof(*laggresp) 672 + sizeof(laggresp->lrq_reqports[0]) * nports; 673 laggresp = kmem_zalloc(allocsiz, KM_SLEEP); 674 675 rv = lagg_get_stats(sc, laggresp, nports); 676 677 outbuf = (char *)laggresp; 678 679 nports = MIN(laggresp->lrq_nports, nports); 680 outlen = sizeof(*laggresp) 681 + sizeof(laggresp->lrq_reqports[0]) * nports; 682 683 error = copyout(outbuf, ifr->ifr_data, outlen); 684 kmem_free(outbuf, allocsiz); 685 686 if (error == 0 && rv != 0) 687 error = rv; 688 689 break; 690 case SIOCSLAGG: 691 error = copyin(ifr->ifr_data, &laggreq, sizeof(laggreq)); 692 if (error != 0) 693 break; 694 695 nports = laggreq.lrq_nports; 696 if (nports > 1) { 697 allocsiz = sizeof(struct lagg_req) 698 + sizeof(struct laggreqport) * nports; 699 buf = kmem_alloc(allocsiz, KM_SLEEP); 700 701 error = copyin(ifr->ifr_data, buf, allocsiz); 702 if (error != 0) { 703 kmem_free(buf, allocsiz); 704 break; 705 } 706 } else { 707 buf = (void *)&laggreq; 708 allocsiz = 0; 709 } 710 711 error = lagg_config(sc, buf); 712 if (allocsiz > 0) 713 kmem_free(buf, allocsiz); 714 break; 715 case SIOCSIFFLAGS: 716 error = ifioctl_common(ifp, cmd, data); 717 if (error != 0) 718 break; 719 720 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 721 case IFF_RUNNING: 722 if_stop(ifp, 1); 723 break; 724 case IFF_UP: 725 error = if_init(ifp); 726 break; 727 } 728 729 if (error != 0) 730 break; 731 732 /* Set flags on ports too */ 733 LAGG_LOCK(sc); 734 LAGG_PORTS_FOREACH(sc, lp) { 735 (void)lagg_config_promisc(sc, lp); 736 } 737 LAGG_UNLOCK(sc); 738 break; 739 case SIOCSIFMTU: 740 /* set the MTU to each port */ 741 LAGG_LOCK(sc); 742 LAGG_PORTS_FOREACH(sc, lp) { 743 error = lagg_lp_ioctl(lp, cmd, (void *)ifr); 744 745 if (error != 0) { 746 LAGG_LOG(sc, LOG_ERR, 747 "failed to change MTU to %d on port %s, " 748 "reverting all ports to original " 749 "MTU(%" PRIu64 ")\n", 750 ifr->ifr_mtu, lp->lp_ifp->if_xname, 751 ifp->if_mtu); 752 break; 753 } 754 } 755 LAGG_UNLOCK(sc); 756 757 /* set the MTU to the lagg interface */ 758 if (error == 0) 759 error = ether_ioctl(ifp, cmd, data); 760 761 if (error != 0) { 762 /* undo the changed MTU */ 763 ifr->ifr_mtu = ifp->if_mtu; 764 765 LAGG_LOCK(sc); 766 LAGG_PORTS_FOREACH(sc, lp) { 767 if (lp->lp_ioctl != NULL) 768 lagg_lp_ioctl(lp, cmd, (void *)ifr); 769 } 770 LAGG_UNLOCK(sc); 771 } 772 break; 773 case SIOCADDMULTI: 774 if (sc->sc_if.if_type == IFT_ETHER) { 775 error = lagg_ether_addmulti(sc, ifr); 776 } else { 777 error = EPROTONOSUPPORT; 778 } 779 break; 780 case SIOCDELMULTI: 781 if (sc->sc_if.if_type == IFT_ETHER) { 782 error = lagg_ether_delmulti(sc, ifr); 783 } else { 784 error = EPROTONOSUPPORT; 785 } 786 break; 787 case SIOCSIFCAP: 788 error = ether_ioctl(ifp, cmd, data); 789 if (error == 0) 790 lagg_sync_ifcaps(sc); 791 break; 792 case SIOCSETHERCAP: 793 error = ether_ioctl(ifp, cmd, data); 794 if (error == 0) 795 lagg_sync_ethcaps(sc); 796 break; 797 default: 798 error = ether_ioctl(ifp, cmd, data); 799 } 800 return error; 801 } 802 803 static int 804 lagg_setup_sysctls(struct lagg_softc *sc) 805 { 806 struct sysctllog **slog; 807 const struct sysctlnode **rnode, *hashnode; 808 const char *ifname; 809 int error; 810 811 slog = &sc->sc_sysctllog; 812 rnode = &sc->sc_sysctlnode; 813 ifname = sc->sc_if.if_xname; 814 815 error = sysctl_createv(slog, 0, NULL, rnode, 816 CTLFLAG_PERMANENT, CTLTYPE_NODE, ifname, 817 SYSCTL_DESCR("lagg information and settings"), 818 NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL); 819 if (error != 0) 820 goto done; 821 822 error = sysctl_createv(slog, 0, rnode, &hashnode, 823 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hash", 824 SYSCTL_DESCR("hash calculation settings"), 825 NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL); 826 if (error != 0) 827 goto done; 828 829 error = sysctl_createv(slog, 0, &hashnode, NULL, 830 CTLFLAG_READWRITE, CTLTYPE_BOOL, "macaddr", 831 SYSCTL_DESCR("use src/dst mac addresses"), 832 NULL, 0, &sc->sc_hash_mac, 0, CTL_CREATE, CTL_EOL); 833 if (error != 0) 834 goto done; 835 836 error = sysctl_createv(slog, 0, &hashnode, NULL, 837 CTLFLAG_READWRITE, CTLTYPE_BOOL, "ipaddr", 838 SYSCTL_DESCR("use src/dst IPv4 addresses"), 839 NULL, 0, &sc->sc_hash_ipaddr, 0, CTL_CREATE, CTL_EOL); 840 if (error != 0) 841 goto done; 842 843 error = sysctl_createv(slog, 0, &hashnode, NULL, 844 CTLFLAG_READWRITE, CTLTYPE_BOOL, "ip6addr", 845 SYSCTL_DESCR("use src/dst IPv6 addresses"), 846 NULL, 0, &sc->sc_hash_ip6addr, 0, CTL_CREATE, CTL_EOL); 847 if (error != 0) 848 goto done; 849 850 error = sysctl_createv(slog, 0, &hashnode, NULL, 851 CTLFLAG_READWRITE, CTLTYPE_BOOL, "tcp", 852 SYSCTL_DESCR("use TCP src/dst port"), 853 NULL, 0, &sc->sc_hash_tcp, 0, CTL_CREATE, CTL_EOL); 854 if (error != 0) 855 goto done; 856 857 error = sysctl_createv(slog, 0, &hashnode, NULL, 858 CTLFLAG_READWRITE, CTLTYPE_BOOL, "udp", 859 SYSCTL_DESCR("use UDP src/dst port"), 860 NULL, 0, &sc->sc_hash_udp, 0, CTL_CREATE, CTL_EOL); 861 done: 862 if (error != 0) { 863 LAGG_LOG(sc, LOG_ERR, "unable to create sysctl node\n"); 864 sysctl_teardown(slog); 865 } 866 867 return error; 868 } 869 870 static void 871 lagg_teardown_sysctls(struct lagg_softc *sc) 872 { 873 874 sc->sc_sysctlnode = NULL; 875 sysctl_teardown(&sc->sc_sysctllog); 876 } 877 878 uint32_t 879 lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m) 880 { 881 union { 882 struct ether_header _eh; 883 struct ether_vlan_header _evl; 884 struct ip _ip; 885 struct ip6_hdr _ip6; 886 struct tcphdr _th; 887 struct udphdr _uh; 888 } buf; 889 const struct ether_header *eh; 890 const struct ether_vlan_header *evl; 891 const struct ip *ip; 892 const struct ip6_hdr *ip6; 893 const struct tcphdr *th; 894 const struct udphdr *uh; 895 uint32_t hash, hash_src, hash_dst; 896 uint32_t flowlabel; 897 uint16_t etype, vlantag; 898 uint8_t proto; 899 size_t off; 900 901 KASSERT(ISSET(m->m_flags, M_PKTHDR)); 902 903 hash = HASH32_BUF_INIT; 904 hash_src = HASH32_BUF_INIT; 905 hash_dst = HASH32_BUF_INIT; 906 907 #define LAGG_HASH_ADD(hp, v) do { \ 908 *(hp) = hash32_buf(&(v), sizeof(v), *(hp)); \ 909 } while(0) 910 911 eh = lagg_m_extract(m, 0, sizeof(*eh), __alignof(*eh), &buf); 912 if (eh == NULL) 913 goto out; 914 915 off = ETHER_HDR_LEN; 916 etype = ntohs(eh->ether_type); 917 918 if (etype == ETHERTYPE_VLAN) { 919 evl = lagg_m_extract(m, 0, sizeof(*evl), __alignof(*evl), 920 &buf); 921 if (evl == NULL) 922 goto out; 923 924 vlantag = ntohs(evl->evl_tag); 925 etype = ntohs(evl->evl_proto); 926 off += ETHER_VLAN_ENCAP_LEN; 927 } else if (vlan_has_tag(m)) { 928 vlantag = vlan_get_tag(m); 929 } else { 930 vlantag = 0; 931 } 932 933 if (sc->sc_hash_mac) { 934 LAGG_HASH_ADD(&hash_dst, eh->ether_dhost); 935 LAGG_HASH_ADD(&hash_src, eh->ether_shost); 936 LAGG_HASH_ADD(&hash, vlantag); 937 } 938 939 switch (etype) { 940 case ETHERTYPE_IP: 941 ip = lagg_m_extract(m, off, sizeof(*ip), __alignof(*ip), &buf); 942 if (ip == NULL) 943 goto out; 944 945 if (sc->sc_hash_ipaddr) { 946 LAGG_HASH_ADD(&hash_src, ip->ip_src); 947 LAGG_HASH_ADD(&hash_dst, ip->ip_dst); 948 LAGG_HASH_ADD(&hash, ip->ip_p); 949 } 950 off += ip->ip_hl << 2; 951 proto = ip->ip_p; 952 break; 953 case ETHERTYPE_IPV6: 954 ip6 = lagg_m_extract(m, off, sizeof(*ip6), __alignof(*ip6), 955 &buf); 956 if (ip6 == NULL) 957 goto out; 958 959 if (sc->sc_hash_ip6addr) { 960 LAGG_HASH_ADD(&hash_src, ip6->ip6_src); 961 LAGG_HASH_ADD(&hash_dst, ip6->ip6_dst); 962 flowlabel = ip6->ip6_flow & IPV6_FLOWLABEL_MASK; 963 LAGG_HASH_ADD(&hash, flowlabel); 964 } 965 proto = ip6->ip6_nxt; 966 off += sizeof(*ip6); 967 break; 968 969 default: 970 return hash; 971 } 972 973 switch (proto) { 974 case IPPROTO_TCP: 975 th = lagg_m_extract(m, off, sizeof(*th), __alignof(*th), &buf); 976 if (th == NULL) 977 goto out; 978 979 if (sc->sc_hash_tcp) { 980 LAGG_HASH_ADD(&hash_src, th->th_sport); 981 LAGG_HASH_ADD(&hash_dst, th->th_dport); 982 } 983 break; 984 case IPPROTO_UDP: 985 uh = lagg_m_extract(m, off, sizeof(*uh), __alignof(*uh), &buf); 986 if (uh == NULL) 987 goto out; 988 989 if (sc->sc_hash_udp) { 990 LAGG_HASH_ADD(&hash_src, uh->uh_sport); 991 LAGG_HASH_ADD(&hash_dst, uh->uh_dport); 992 } 993 break; 994 } 995 996 out: 997 hash_src ^= hash_dst; 998 LAGG_HASH_ADD(&hash, hash_src); 999 #undef LAGG_HASH_ADD 1000 1001 return hash; 1002 } 1003 1004 static int 1005 lagg_tx_common(struct ifnet *ifp, struct mbuf *m) 1006 { 1007 struct lagg_variant *var; 1008 lagg_proto pr; 1009 struct psref psref; 1010 int error; 1011 1012 var = lagg_variant_getref(ifp->if_softc, &psref); 1013 1014 if (__predict_false(var == NULL)) { 1015 m_freem(m); 1016 if_statinc(ifp, if_oerrors); 1017 return ENOENT; 1018 } 1019 1020 pr = var->lv_proto; 1021 if (__predict_true(lagg_protos[pr].pr_transmit != NULL)) { 1022 error = lagg_protos[pr].pr_transmit(var->lv_psc, m); 1023 /* mbuf is already freed */ 1024 } else { 1025 m_freem(m); 1026 if_statinc(ifp, if_oerrors); 1027 error = ENOBUFS; 1028 } 1029 1030 lagg_variant_putref(var, &psref); 1031 1032 return error; 1033 } 1034 1035 static int 1036 lagg_transmit(struct ifnet *ifp, struct mbuf *m) 1037 { 1038 1039 return lagg_tx_common(ifp, m); 1040 } 1041 1042 static void 1043 lagg_start(struct ifnet *ifp) 1044 { 1045 struct mbuf *m; 1046 1047 for (;;) { 1048 IFQ_DEQUEUE(&ifp->if_snd, m); 1049 if (m == NULL) 1050 break; 1051 1052 (void)lagg_tx_common(ifp, m); 1053 } 1054 } 1055 1056 void 1057 lagg_output(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) 1058 { 1059 struct ifnet *ifp; 1060 int len, error; 1061 short mflags; 1062 1063 ifp = &sc->sc_if; 1064 len = m->m_pkthdr.len; 1065 mflags = m->m_flags; 1066 1067 error = pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_OUT); 1068 if (error != 0) 1069 return; 1070 bpf_mtap(ifp, m, BPF_D_OUT); 1071 1072 error = lagg_port_xmit(lp, m); 1073 if (error) { 1074 /* mbuf is already freed */ 1075 if_statinc(ifp, if_oerrors); 1076 } 1077 1078 net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 1079 if_statinc_ref(nsr, if_opackets); 1080 if_statadd_ref(nsr, if_obytes, len); 1081 if (mflags & M_MCAST) 1082 if_statinc_ref(nsr, if_omcasts); 1083 IF_STAT_PUTREF(ifp); 1084 } 1085 1086 static struct mbuf * 1087 lagg_proto_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) 1088 { 1089 struct psref psref; 1090 struct lagg_variant *var; 1091 lagg_proto pr; 1092 1093 var = lagg_variant_getref(sc, &psref); 1094 1095 if (var == NULL) { 1096 sc->sc_novar.ev_count++; 1097 m_freem(m); 1098 return NULL; 1099 } 1100 1101 pr = var->lv_proto; 1102 1103 if (lagg_protos[pr].pr_input != NULL) { 1104 m = lagg_protos[pr].pr_input(var->lv_psc, lp, m); 1105 } else { 1106 m_freem(m); 1107 m = NULL; 1108 } 1109 1110 lagg_variant_putref(var, &psref); 1111 1112 return m; 1113 } 1114 1115 static void 1116 lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m) 1117 { 1118 struct ifnet *ifp; 1119 struct psref psref; 1120 struct lagg_port *lp; 1121 struct ether_header *eh; 1122 int s; 1123 1124 /* sanity check */ 1125 s = pserialize_read_enter(); 1126 lp = atomic_load_consume(&ifp_port->if_lagg); 1127 if (lp == NULL) { 1128 /* This interface is not a member of lagg */ 1129 pserialize_read_exit(s); 1130 m_freem(m); 1131 if_statinc(ifp_port, if_ierrors); 1132 return; 1133 } 1134 lagg_port_getref(lp, &psref); 1135 pserialize_read_exit(s); 1136 1137 ifp = &lp->lp_softc->sc_if; 1138 1139 /* 1140 * Drop promiscuously received packets 1141 * if we are not in promiscuous mode. 1142 */ 1143 1144 if (__predict_false(m->m_len < (int)sizeof(*eh))) { 1145 if ((m = m_pullup(m, sizeof(*eh))) == NULL) { 1146 if_statinc(ifp, if_ierrors); 1147 goto out; 1148 } 1149 } 1150 1151 eh = mtod(m, struct ether_header *); 1152 1153 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 1154 /* 1155 * If this is not a simplex interface, drop the packet 1156 * if it came from us. 1157 */ 1158 if ((ifp->if_flags & IFF_SIMPLEX) == 0 && 1159 memcmp(CLLADDR(ifp->if_sadl), eh->ether_shost, 1160 ETHER_ADDR_LEN) == 0) { 1161 goto drop; 1162 } 1163 1164 if_statinc(ifp_port, if_imcasts); 1165 } else { 1166 if ((ifp->if_flags & IFF_PROMISC) == 0 && 1167 (ifp_port->if_flags & IFF_PROMISC) != 0 && 1168 memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost, 1169 ETHER_ADDR_LEN) != 0) 1170 goto drop; 1171 } 1172 1173 if_statadd(ifp_port, if_ibytes, m->m_pkthdr.len); 1174 1175 if (pfil_run_hooks(ifp_port->if_pfil, &m, 1176 ifp_port, PFIL_IN) != 0) 1177 goto out; 1178 1179 m = lagg_proto_input(lp->lp_softc, lp, m); 1180 if (m != NULL) { 1181 m_set_rcvif(m, ifp); 1182 m->m_flags &= ~M_PROMISC; 1183 if_input(ifp, m); 1184 } 1185 1186 out: 1187 lagg_port_putref(lp, &psref); 1188 return; 1189 1190 drop: 1191 lagg_port_putref(lp, &psref); 1192 m_freem(m); 1193 if_statinc(ifp_port, if_iqdrops); 1194 return; 1195 } 1196 1197 static int 1198 lagg_media_change(struct ifnet *ifp) 1199 { 1200 1201 if (ISSET(ifp->if_flags, IFF_DEBUG)) 1202 printf("%s: ignore media change\n", ifp->if_xname); 1203 1204 return 0; 1205 } 1206 1207 static void 1208 lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1209 { 1210 struct lagg_softc *sc; 1211 struct lagg_port *lp; 1212 1213 sc = ifp->if_softc; 1214 1215 imr->ifm_status = IFM_AVALID; 1216 imr->ifm_active = IFM_ETHER | IFM_AUTO; 1217 1218 LAGG_LOCK(sc); 1219 1220 imr->ifm_active |= sc->sc_media_active; 1221 1222 LAGG_PORTS_FOREACH(sc, lp) { 1223 if (lagg_portactive(lp)) 1224 imr->ifm_status |= IFM_ACTIVE; 1225 } 1226 LAGG_UNLOCK(sc); 1227 } 1228 1229 static uint64_t 1230 lagg_search_media_type(uint64_t linkspeed) 1231 { 1232 1233 if (linkspeed == IF_Gbps(40)) 1234 return IFM_40G_T | IFM_FDX; 1235 1236 if (linkspeed == IF_Gbps(25)) 1237 return IFM_25G_T | IFM_FDX; 1238 1239 if (linkspeed == IF_Gbps(10)) 1240 return IFM_10G_T | IFM_FDX; 1241 1242 if (linkspeed == IF_Gbps(5)) 1243 return IFM_5000_T | IFM_FDX; 1244 1245 if (linkspeed == IF_Mbps(2500)) 1246 return IFM_2500_T | IFM_FDX; 1247 1248 if (linkspeed == IF_Gbps(1)) 1249 return IFM_1000_T | IFM_FDX; 1250 1251 if (linkspeed == IF_Mbps(100)) 1252 return IFM_100_TX | IFM_FDX; 1253 1254 if (linkspeed == IF_Mbps(10)) 1255 return IFM_10_T | IFM_FDX; 1256 1257 return 0; 1258 } 1259 1260 void 1261 lagg_set_linkspeed(struct lagg_softc *sc, uint64_t linkspeed) 1262 { 1263 struct ifnet *ifp; 1264 1265 ifp = &sc->sc_if; 1266 1267 KASSERT(LAGG_LOCKED(sc)); 1268 1269 ifp->if_baudrate = linkspeed; 1270 1271 sc->sc_media_active = 1272 lagg_search_media_type(linkspeed); 1273 } 1274 1275 static int 1276 lagg_port_vlan_cb(struct lagg_port *lp, 1277 struct lagg_vlantag *lvt, bool set) 1278 { 1279 struct ifnet *ifp_port; 1280 int error; 1281 1282 if (lp->lp_iftype != IFT_ETHER) 1283 return 0; 1284 1285 error = 0; 1286 ifp_port = lp->lp_ifp; 1287 1288 if (set) { 1289 error = ether_add_vlantag(ifp_port, 1290 lvt->lvt_vtag, NULL); 1291 } else { 1292 error = ether_del_vlantag(ifp_port, 1293 lvt->lvt_vtag); 1294 } 1295 1296 return error; 1297 } 1298 1299 static int 1300 lagg_vlan_cb(struct ethercom *ec, uint16_t vtag, bool set) 1301 { 1302 struct ifnet *ifp; 1303 struct lagg_softc *sc; 1304 struct lagg_vlantag *lvt, *lvt0; 1305 struct lagg_port *lp; 1306 int error; 1307 1308 ifp = (struct ifnet *)ec; 1309 sc = ifp->if_softc; 1310 1311 if (set) { 1312 lvt = kmem_zalloc(sizeof(*lvt), KM_SLEEP); 1313 lvt->lvt_vtag = vtag; 1314 TAILQ_INSERT_TAIL(&sc->sc_vtags, lvt, lvt_entry); 1315 } else { 1316 TAILQ_FOREACH_SAFE(lvt, &sc->sc_vtags, lvt_entry, lvt0) { 1317 if (lvt->lvt_vtag == vtag) { 1318 TAILQ_REMOVE(&sc->sc_vtags, lvt, lvt_entry); 1319 break; 1320 } 1321 } 1322 1323 if (lvt == NULL) 1324 return ENOENT; 1325 } 1326 1327 KASSERT(lvt != NULL); 1328 LAGG_PORTS_FOREACH(sc, lp) { 1329 error = lagg_port_vlan_cb(lp, lvt, set); 1330 if (error != 0) { 1331 LAGG_LOG(sc, LOG_WARNING, 1332 "%s failed to configure vlan on %d\n", 1333 lp->lp_ifp->if_xname, error); 1334 } 1335 } 1336 1337 return 0; 1338 } 1339 1340 static struct lagg_softc * 1341 lagg_softc_alloc(enum lagg_iftypes ift) 1342 { 1343 struct lagg_softc *sc; 1344 size_t s; 1345 1346 s = lagg_sizeof_softc(ift); 1347 KASSERT(s > 0); 1348 1349 sc = kmem_zalloc(s, KM_SLEEP); 1350 KASSERT(sc != NULL); 1351 1352 return sc; 1353 } 1354 1355 static void 1356 lagg_softc_free(struct lagg_softc *sc) 1357 { 1358 1359 kmem_free(sc, 1360 lagg_sizeof_softc(sc->sc_iftype)); 1361 } 1362 1363 static void 1364 lagg_variant_update(struct lagg_softc *sc, struct lagg_variant *newvar) 1365 { 1366 struct lagg_variant *oldvar; 1367 1368 KASSERT(LAGG_LOCKED(sc)); 1369 1370 psref_target_init(&newvar->lv_psref, lagg_psref_class); 1371 1372 oldvar = sc->sc_var; 1373 atomic_store_release(&sc->sc_var, newvar); 1374 pserialize_perform(sc->sc_psz); 1375 1376 if (__predict_true(oldvar != NULL)) 1377 psref_target_destroy(&oldvar->lv_psref, lagg_psref_class); 1378 } 1379 1380 static struct lagg_variant * 1381 lagg_variant_getref(struct lagg_softc *sc, struct psref *psref) 1382 { 1383 struct lagg_variant *var; 1384 int s; 1385 1386 s = pserialize_read_enter(); 1387 var = atomic_load_consume(&sc->sc_var); 1388 if (var == NULL) { 1389 pserialize_read_exit(s); 1390 return NULL; 1391 } 1392 1393 psref_acquire(psref, &var->lv_psref, lagg_psref_class); 1394 pserialize_read_exit(s); 1395 1396 return var; 1397 } 1398 1399 static void 1400 lagg_variant_putref(struct lagg_variant *var, struct psref *psref) 1401 { 1402 1403 if (__predict_false(var == NULL)) 1404 return; 1405 psref_release(psref, &var->lv_psref, lagg_psref_class); 1406 } 1407 1408 static int 1409 lagg_proto_attach(struct lagg_softc *sc, lagg_proto pr, 1410 struct lagg_proto_softc **psc) 1411 { 1412 1413 KASSERT(lagg_protos[pr].pr_attach != NULL); 1414 return lagg_protos[pr].pr_attach(sc, psc); 1415 } 1416 1417 static void 1418 lagg_proto_detach(struct lagg_variant *oldvar) 1419 { 1420 lagg_proto pr; 1421 1422 pr = oldvar->lv_proto; 1423 1424 if (lagg_protos[pr].pr_detach == NULL) 1425 return; 1426 1427 lagg_protos[pr].pr_detach(oldvar->lv_psc); 1428 } 1429 1430 static int 1431 lagg_proto_updown(struct lagg_softc *sc, bool is_up) 1432 { 1433 struct lagg_variant *var; 1434 struct psref psref; 1435 lagg_proto pr; 1436 int error, bound; 1437 1438 error = 0; 1439 bound = curlwp_bind(); 1440 1441 var = lagg_variant_getref(sc, &psref); 1442 if (var == NULL) { 1443 curlwp_bindx(bound); 1444 return ENXIO; 1445 } 1446 1447 pr = var->lv_proto; 1448 1449 if (is_up && lagg_protos[pr].pr_up != NULL) { 1450 error = lagg_protos[pr].pr_up(var->lv_psc); 1451 } else if (!is_up && lagg_protos[pr].pr_down != NULL) { 1452 lagg_protos[pr].pr_down(var->lv_psc); 1453 } 1454 1455 lagg_variant_putref(var, &psref); 1456 curlwp_bindx(bound); 1457 1458 return error; 1459 } 1460 1461 static int 1462 lagg_proto_up(struct lagg_softc *sc) 1463 { 1464 1465 return lagg_proto_updown(sc, true); 1466 } 1467 1468 static void 1469 lagg_proto_down(struct lagg_softc *sc) 1470 { 1471 1472 (void)lagg_proto_updown(sc, false); 1473 } 1474 1475 static int 1476 lagg_proto_portctrl(struct lagg_softc *sc, struct lagg_port *lp, 1477 enum lagg_portctrl ctrl) 1478 { 1479 struct lagg_variant *var; 1480 struct psref psref; 1481 lagg_proto pr; 1482 int error, bound; 1483 1484 error = 0; 1485 bound = curlwp_bind(); 1486 1487 var = lagg_variant_getref(sc, &psref); 1488 if (var == NULL) { 1489 curlwp_bindx(bound); 1490 return ENXIO; 1491 } 1492 1493 pr = var->lv_proto; 1494 1495 switch (ctrl) { 1496 case LAGG_PORTCTRL_ALLOC: 1497 if (lagg_protos[pr].pr_allocport == NULL) { 1498 goto nosupport; 1499 } 1500 error = lagg_protos[pr].pr_allocport(var->lv_psc, lp); 1501 break; 1502 case LAGG_PORTCTRL_FREE: 1503 if (lagg_protos[pr].pr_freeport == NULL) { 1504 goto nosupport; 1505 } 1506 lagg_protos[pr].pr_freeport(var->lv_psc, lp); 1507 break; 1508 case LAGG_PORTCTRL_START: 1509 if (lagg_protos[pr].pr_startport == NULL) { 1510 goto nosupport; 1511 } 1512 lagg_protos[pr].pr_startport(var->lv_psc, lp); 1513 break; 1514 case LAGG_PORTCTRL_STOP: 1515 if (lagg_protos[pr].pr_stopport == NULL) { 1516 goto nosupport; 1517 } 1518 lagg_protos[pr].pr_stopport(var->lv_psc, lp); 1519 break; 1520 default: 1521 goto nosupport; 1522 } 1523 1524 lagg_variant_putref(var, &psref); 1525 curlwp_bindx(bound); 1526 return error; 1527 1528 nosupport: 1529 lagg_variant_putref(var, &psref); 1530 curlwp_bindx(bound); 1531 return EPROTONOSUPPORT; 1532 } 1533 1534 static int 1535 lagg_proto_allocport(struct lagg_softc *sc, struct lagg_port *lp) 1536 { 1537 1538 return lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_ALLOC); 1539 } 1540 1541 static void 1542 lagg_proto_freeport(struct lagg_softc *sc, struct lagg_port *lp) 1543 { 1544 1545 lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_FREE); 1546 } 1547 1548 static void 1549 lagg_proto_startport(struct lagg_softc *sc, struct lagg_port *lp) 1550 { 1551 1552 lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_START); 1553 } 1554 1555 static void 1556 lagg_proto_stopport(struct lagg_softc *sc, struct lagg_port *lp) 1557 { 1558 1559 lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_STOP); 1560 } 1561 1562 static void 1563 lagg_proto_linkstate(struct lagg_softc *sc, struct lagg_port *lp) 1564 { 1565 struct lagg_variant *var; 1566 struct psref psref; 1567 lagg_proto pr; 1568 int bound; 1569 1570 KASSERT(IFNET_LOCKED(lp->lp_ifp)); 1571 1572 bound = curlwp_bind(); 1573 var = lagg_variant_getref(sc, &psref); 1574 1575 if (var == NULL) { 1576 curlwp_bindx(bound); 1577 return; 1578 } 1579 1580 pr = var->lv_proto; 1581 1582 if (lagg_protos[pr].pr_linkstate) 1583 lagg_protos[pr].pr_linkstate(var->lv_psc, lp); 1584 1585 lagg_variant_putref(var, &psref); 1586 curlwp_bindx(bound); 1587 } 1588 1589 static void 1590 lagg_proto_stat(struct lagg_variant *var, struct laggreqproto *resp) 1591 { 1592 lagg_proto pr; 1593 1594 pr = var->lv_proto; 1595 1596 if (lagg_protos[pr].pr_protostat != NULL) 1597 lagg_protos[pr].pr_protostat(var->lv_psc, resp); 1598 } 1599 1600 static void 1601 lagg_proto_portstat(struct lagg_variant *var, struct lagg_port *lp, 1602 struct laggreqport *resp) 1603 { 1604 lagg_proto pr; 1605 1606 pr = var->lv_proto; 1607 1608 if (lagg_protos[pr].pr_portstat != NULL) 1609 lagg_protos[pr].pr_portstat(var->lv_psc, lp, resp); 1610 } 1611 1612 static int 1613 lagg_proto_ioctl(struct lagg_softc *sc, struct lagg_req *lreq) 1614 { 1615 struct lagg_variant *var; 1616 struct psref psref; 1617 lagg_proto pr; 1618 int bound, error; 1619 1620 error = ENOTTY; 1621 bound = curlwp_bind(); 1622 var = lagg_variant_getref(sc, &psref); 1623 1624 if (var == NULL) { 1625 error = ENXIO; 1626 goto done; 1627 } 1628 1629 pr = var->lv_proto; 1630 if (pr != lreq->lrq_proto) { 1631 error = EBUSY; 1632 goto done; 1633 } 1634 1635 if (lagg_protos[pr].pr_ioctl != NULL) { 1636 error = lagg_protos[pr].pr_ioctl(var->lv_psc, 1637 &lreq->lrq_reqproto); 1638 } 1639 1640 done: 1641 if (var != NULL) 1642 lagg_variant_putref(var, &psref); 1643 curlwp_bindx(bound); 1644 return error; 1645 } 1646 1647 static int 1648 lagg_pr_attach(struct lagg_softc *sc, lagg_proto pr) 1649 { 1650 struct lagg_variant *newvar, *oldvar; 1651 struct lagg_proto_softc *psc; 1652 bool cleanup_oldvar; 1653 int error; 1654 1655 error = 0; 1656 cleanup_oldvar = false; 1657 newvar = kmem_alloc(sizeof(*newvar), KM_SLEEP); 1658 1659 LAGG_LOCK(sc); 1660 oldvar = sc->sc_var; 1661 1662 if (oldvar != NULL && oldvar->lv_proto == pr) { 1663 error = 0; 1664 goto done; 1665 } 1666 1667 error = lagg_proto_attach(sc, pr, &psc); 1668 if (error != 0) 1669 goto done; 1670 1671 newvar->lv_proto = pr; 1672 newvar->lv_psc = psc; 1673 1674 lagg_variant_update(sc, newvar); 1675 newvar = NULL; 1676 1677 if (oldvar != NULL) { 1678 lagg_proto_detach(oldvar); 1679 cleanup_oldvar = true; 1680 } 1681 1682 lagg_set_linkspeed(sc, 0); 1683 done: 1684 LAGG_UNLOCK(sc); 1685 1686 if (newvar != NULL) 1687 kmem_free(newvar, sizeof(*newvar)); 1688 if (cleanup_oldvar) 1689 kmem_free(oldvar, sizeof(*oldvar)); 1690 1691 return error; 1692 } 1693 1694 static void 1695 lagg_pr_detach(struct lagg_softc *sc) 1696 { 1697 struct lagg_variant *var; 1698 1699 LAGG_LOCK(sc); 1700 1701 var = sc->sc_var; 1702 atomic_store_release(&sc->sc_var, NULL); 1703 pserialize_perform(sc->sc_psz); 1704 1705 if (var != NULL) 1706 lagg_proto_detach(var); 1707 1708 LAGG_UNLOCK(sc); 1709 1710 if (var != NULL) 1711 kmem_free(var, sizeof(*var)); 1712 } 1713 1714 static int 1715 lagg_ether_addmulti(struct lagg_softc *sc, struct ifreq *ifr) 1716 { 1717 struct lagg_port *lp; 1718 struct lagg_mc_entry *mc; 1719 struct ethercom *ec; 1720 const struct sockaddr *sa; 1721 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1722 int error; 1723 1724 if (sc->sc_if.if_type != IFT_ETHER) 1725 return EPROTONOSUPPORT; 1726 1727 ec = (struct ethercom *)&sc->sc_if; 1728 sa = ifreq_getaddr(SIOCADDMULTI, ifr); 1729 1730 error = ether_addmulti(sa, ec); 1731 if (error != ENETRESET) 1732 return error; 1733 1734 error = ether_multiaddr(sa, addrlo, addrhi); 1735 KASSERT(error == 0); 1736 1737 mc = kmem_zalloc(sizeof(*mc), KM_SLEEP); 1738 1739 ETHER_LOCK(ec); 1740 mc->mc_enm = ether_lookup_multi(addrlo, addrhi, ec); 1741 ETHER_UNLOCK(ec); 1742 1743 KASSERT(mc->mc_enm != NULL); 1744 1745 LAGG_LOCK(sc); 1746 LAGG_PORTS_FOREACH(sc, lp) { 1747 (void)lagg_lp_ioctl(lp, SIOCADDMULTI, (void *)ifr); 1748 } 1749 LAGG_UNLOCK(sc); 1750 1751 KASSERT(sa->sa_len <= sizeof(mc->mc_addr)); 1752 memcpy(&mc->mc_addr, sa, sa->sa_len); 1753 LIST_INSERT_HEAD(&sc->sc_mclist, mc, mc_entry); 1754 1755 return 0; 1756 } 1757 1758 static int 1759 lagg_ether_delmulti(struct lagg_softc *sc, struct ifreq *ifr) 1760 { 1761 struct lagg_port *lp; 1762 struct lagg_mc_entry *mc; 1763 const struct sockaddr *sa; 1764 struct ethercom *ec; 1765 struct ether_multi *enm; 1766 uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN]; 1767 int error; 1768 1769 ec = (struct ethercom *)&sc->sc_if; 1770 sa = ifreq_getaddr(SIOCDELMULTI, ifr); 1771 error = ether_multiaddr(sa, addrlo, addrhi); 1772 if (error != 0) 1773 return error; 1774 1775 ETHER_LOCK(ec); 1776 enm = ether_lookup_multi(addrlo, addrhi, ec); 1777 ETHER_UNLOCK(ec); 1778 1779 if (enm == NULL) 1780 return ENOENT; 1781 1782 LIST_FOREACH(mc, &sc->sc_mclist, mc_entry) { 1783 if (mc->mc_enm == enm) 1784 break; 1785 } 1786 1787 if (mc == NULL) 1788 return ENOENT; 1789 1790 error = ether_delmulti(sa, ec); 1791 if (error != ENETRESET) 1792 return error; 1793 1794 LAGG_LOCK(sc); 1795 LAGG_PORTS_FOREACH(sc, lp) { 1796 (void)lagg_lp_ioctl(lp, SIOCDELMULTI, (void *)ifr); 1797 } 1798 LAGG_UNLOCK(sc); 1799 1800 LIST_REMOVE(mc, mc_entry); 1801 kmem_free(mc, sizeof(*mc)); 1802 1803 return 0; 1804 } 1805 1806 static void 1807 lagg_port_multi(struct lagg_softc *sc, struct lagg_port *lp, 1808 u_long cmd) 1809 { 1810 struct lagg_mc_entry *mc; 1811 struct ifreq ifr; 1812 struct ifnet *ifp_port; 1813 const struct sockaddr *sa; 1814 1815 ifp_port = lp->lp_ifp; 1816 1817 memset(&ifr, 0, sizeof(ifr)); 1818 strlcpy(ifr.ifr_name, ifp_port->if_xname, sizeof(ifr.ifr_name)); 1819 1820 LIST_FOREACH(mc, &sc->sc_mclist, mc_entry) { 1821 sa = (struct sockaddr *)&mc->mc_addr; 1822 KASSERT(sizeof(ifr.ifr_space) >= sa->sa_len); 1823 memcpy(&ifr.ifr_addr, sa, sa->sa_len); 1824 (void)lagg_lp_ioctl(lp, cmd, (void *)&ifr); 1825 } 1826 1827 } 1828 1829 static void 1830 lagg_port_syncmulti(struct lagg_softc *sc, struct lagg_port *lp) 1831 { 1832 1833 lagg_port_multi(sc, lp, SIOCADDMULTI); 1834 } 1835 1836 static void 1837 lagg_port_purgemulti(struct lagg_softc *sc, struct lagg_port *lp) 1838 { 1839 1840 lagg_port_multi(sc, lp, SIOCDELMULTI); 1841 } 1842 1843 static void 1844 lagg_port_vlan(struct lagg_softc *sc, struct lagg_port *lp, 1845 bool set) 1846 { 1847 struct lagg_vlantag *lvt; 1848 int error; 1849 1850 TAILQ_FOREACH(lvt, &sc->sc_vtags, lvt_entry) { 1851 error = lagg_port_vlan_cb(lp, lvt, set); 1852 if (error != 0) { 1853 LAGG_LOG(sc, LOG_WARNING, 1854 "%s failed to configure vlan on %d\n", 1855 lp->lp_ifp->if_xname, error); 1856 } 1857 } 1858 } 1859 1860 static void 1861 lagg_port_syncvlan(struct lagg_softc *sc, struct lagg_port *lp) 1862 1863 { 1864 lagg_port_vlan(sc, lp, true); 1865 } 1866 1867 static void 1868 lagg_port_purgevlan(struct lagg_softc *sc, struct lagg_port *lp) 1869 { 1870 1871 lagg_port_vlan(sc, lp, false); 1872 } 1873 1874 static int 1875 lagg_setifcaps(struct lagg_port *lp, uint64_t cap) 1876 { 1877 struct ifcapreq ifcr; 1878 int error; 1879 1880 if (lp->lp_ifp->if_capenable == cap) 1881 return 0; 1882 1883 memset(&ifcr, 0, sizeof(ifcr)); 1884 ifcr.ifcr_capenable = cap; 1885 1886 IFNET_LOCK(lp->lp_ifp); 1887 error = LAGG_PORT_IOCTL(lp, SIOCSIFCAP, &ifcr); 1888 IFNET_UNLOCK(lp->lp_ifp); 1889 1890 return error; 1891 } 1892 1893 static void 1894 lagg_sync_ifcaps(struct lagg_softc *sc) 1895 { 1896 struct lagg_port *lp; 1897 struct ifnet *ifp; 1898 int error = 0; 1899 1900 ifp = (struct ifnet *)&sc->sc_if; 1901 1902 LAGG_LOCK(sc); 1903 LAGG_PORTS_FOREACH(sc, lp) { 1904 error = lagg_setifcaps(lp, ifp->if_capenable); 1905 1906 if (error != 0) { 1907 LAGG_LOG(sc, LOG_WARNING, 1908 "failed to update capabilities " 1909 "of %s, error=%d\n", 1910 lp->lp_ifp->if_xname, error); 1911 } 1912 } 1913 LAGG_UNLOCK(sc); 1914 } 1915 1916 static int 1917 lagg_setethcaps(struct lagg_port *lp, int cap) 1918 { 1919 struct ethercom *ec; 1920 struct eccapreq eccr; 1921 int error; 1922 1923 KASSERT(lp->lp_iftype == IFT_ETHER); 1924 ec = (struct ethercom *)lp->lp_ifp; 1925 1926 if (ec->ec_capenable == cap) 1927 return 0; 1928 1929 memset(&eccr, 0, sizeof(eccr)); 1930 eccr.eccr_capenable = cap; 1931 1932 IFNET_LOCK(lp->lp_ifp); 1933 error = LAGG_PORT_IOCTL(lp, SIOCSETHERCAP, &eccr); 1934 IFNET_UNLOCK(lp->lp_ifp); 1935 1936 return error; 1937 } 1938 1939 static void 1940 lagg_sync_ethcaps(struct lagg_softc *sc) 1941 { 1942 struct ethercom *ec; 1943 struct lagg_port *lp; 1944 int error; 1945 1946 ec = (struct ethercom *)&sc->sc_if; 1947 1948 LAGG_LOCK(sc); 1949 LAGG_PORTS_FOREACH(sc, lp) { 1950 if (lp->lp_iftype != IFT_ETHER) 1951 continue; 1952 1953 error = lagg_setethcaps(lp, ec->ec_capenable); 1954 if (error != 0) { 1955 LAGG_LOG(sc, LOG_WARNING, 1956 "failed to update ether " 1957 "capabilities"" of %s, error=%d\n", 1958 lp->lp_ifp->if_xname, error); 1959 } 1960 1961 } 1962 LAGG_UNLOCK(sc); 1963 } 1964 1965 static void 1966 lagg_ifcap_update(struct lagg_softc *sc) 1967 { 1968 struct ifnet *ifp; 1969 struct lagg_port *lp; 1970 uint64_t cap, ena, pena; 1971 size_t i; 1972 1973 KASSERT(LAGG_LOCKED(sc)); 1974 1975 /* Get common capabilities for the lagg ports */ 1976 ena = ~(uint64_t)0; 1977 cap = ~(uint64_t)0; 1978 LAGG_PORTS_FOREACH(sc, lp) { 1979 ena &= lp->lp_ifp->if_capenable; 1980 cap &= lp->lp_ifp->if_capabilities; 1981 } 1982 1983 if (ena == ~(uint64_t)0) 1984 ena = 0; 1985 if (cap == ~(uint64_t)0) 1986 cap = 0; 1987 1988 /* 1989 * Apply common enabled capabilities back to the lagg ports. 1990 * May require several iterations if they are dependent. 1991 */ 1992 for (i = 0; i < LAGG_SETCAPS_RETRY; i++) { 1993 pena = ena; 1994 LAGG_PORTS_FOREACH(sc, lp) { 1995 lagg_setifcaps(lp, ena); 1996 ena &= lp->lp_ifp->if_capenable; 1997 } 1998 1999 if (pena == ena) 2000 break; 2001 } 2002 2003 if (pena != ena) { 2004 LAGG_LOG(sc, LOG_DEBUG, "couldn't set " 2005 "capabilities 0x%08"PRIx64"\n", pena); 2006 } 2007 2008 ifp = &sc->sc_if; 2009 2010 if (ifp->if_capabilities != cap || 2011 ifp->if_capenable != ena) { 2012 ifp->if_capabilities = cap; 2013 ifp->if_capenable = ena; 2014 2015 LAGG_LOG(sc, LOG_DEBUG,"capabilities " 2016 "0x%08"PRIx64" enabled 0x%08"PRIx64"\n", 2017 cap, ena); 2018 } 2019 } 2020 2021 static void 2022 lagg_ethercap_update(struct lagg_softc *sc) 2023 { 2024 struct ethercom *ec; 2025 struct lagg_port *lp; 2026 int cap, ena, pena; 2027 size_t i; 2028 2029 KASSERT(LAGG_LOCKED(sc)); 2030 2031 if (sc->sc_if.if_type != IFT_ETHER) 2032 return; 2033 2034 if (SIMPLEQ_EMPTY(&sc->sc_ports)) { 2035 ena = 0; 2036 cap = ETHERCAP_VLAN_HWTAGGING; 2037 } else { 2038 /* Get common enabled capabilities for the lagg ports */ 2039 ena = ~0; 2040 cap = ~0; 2041 LAGG_PORTS_FOREACH(sc, lp) { 2042 switch (lp->lp_iftype) { 2043 case IFT_ETHER: 2044 ec = (struct ethercom *)lp->lp_ifp; 2045 ena &= ec->ec_capenable; 2046 cap &= ec->ec_capabilities; 2047 break; 2048 case IFT_L2TP: 2049 ena &= (ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU); 2050 cap &= (ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU); 2051 break; 2052 default: 2053 ena = 0; 2054 cap = 0; 2055 } 2056 } 2057 } 2058 2059 /* 2060 * Apply common enabled capabilities back to the lagg ports. 2061 * May require several iterations if they are dependent. 2062 */ 2063 for (i = 0; i < LAGG_SETCAPS_RETRY; i++) { 2064 pena = ena; 2065 LAGG_PORTS_FOREACH(sc, lp) { 2066 if (lp->lp_iftype != IFT_ETHER) 2067 continue; 2068 2069 ec = (struct ethercom *)lp->lp_ifp; 2070 lagg_setethcaps(lp, ena); 2071 ena &= ec->ec_capenable; 2072 } 2073 2074 if (pena == ena) 2075 break; 2076 } 2077 2078 if (pena != ena) { 2079 LAGG_LOG(sc, LOG_DEBUG, "couldn't set " 2080 "ether capabilities 0x%08x\n", pena); 2081 } 2082 2083 ec = (struct ethercom *)&sc->sc_if; 2084 2085 if (ec->ec_capabilities != cap || 2086 ec->ec_capenable != ena) { 2087 ec->ec_capabilities = cap; 2088 ec->ec_capenable = ena; 2089 2090 LAGG_LOG(sc, LOG_DEBUG, 2091 "ether capabilities 0x%08x" 2092 " enabled 0x%08x\n", cap, ena); 2093 } 2094 } 2095 2096 static void 2097 lagg_capabilities_update(struct lagg_softc *sc) 2098 { 2099 2100 lagg_ifcap_update(sc); 2101 lagg_ethercap_update(sc); 2102 } 2103 2104 static int 2105 lagg_setmtu(struct ifnet *ifp, uint64_t mtu) 2106 { 2107 struct lagg_softc *sc __LAGGDEBUGUSED; 2108 struct lagg_port *lp; 2109 struct ifreq ifr; 2110 int error; 2111 2112 KASSERT(IFNET_LOCKED(ifp)); 2113 2114 memset(&ifr, 0, sizeof(ifr)); 2115 ifr.ifr_mtu = mtu; 2116 lp = ifp->if_lagg; 2117 2118 if (lp != NULL) { 2119 /* ioctl for port interface */ 2120 error = lp->lp_ioctl(ifp, SIOCSIFMTU, &ifr); 2121 sc = lp->lp_softc; 2122 } else { 2123 /* ioctl for lagg interface */ 2124 error = ether_ioctl(ifp, SIOCSIFMTU, &ifr); 2125 sc = ifp->if_softc; 2126 } 2127 2128 if (error != 0) { 2129 LAGG_DPRINTF(sc, 2130 "couldn't change MTU for %s\n", 2131 ifp->if_xname); 2132 } 2133 2134 return error; 2135 } 2136 2137 static void 2138 lagg_port_setsadl(struct lagg_port *lp, const uint8_t *lladdr) 2139 { 2140 struct ifnet *ifp_port; 2141 int error; 2142 2143 ifp_port = lp->lp_ifp; 2144 2145 KASSERT(LAGG_LOCKED(lp->lp_softc)); 2146 KASSERT(IFNET_LOCKED(ifp_port)); 2147 2148 switch (lp->lp_iftype) { 2149 case IFT_ETHER: 2150 if (lladdr == NULL) { 2151 lladdr = lp->lp_lladdr; 2152 } else { 2153 if (lagg_lladdr_equal(lladdr, 2154 CLLADDR(ifp_port->if_sadl))) 2155 break; 2156 } 2157 2158 lagg_chg_sadl(ifp_port, 2159 lladdr, ETHER_ADDR_LEN); 2160 2161 if (ifp_port->if_init != NULL) { 2162 error = 0; 2163 if (ISSET(ifp_port->if_flags, IFF_RUNNING)) 2164 error = if_init(ifp_port); 2165 2166 if (error != 0) { 2167 LAGG_LOG(lp->lp_softc, LOG_WARNING, 2168 "%s failed to if_init() on %d\n", 2169 ifp_port->if_xname, error); 2170 } 2171 } 2172 break; 2173 default: 2174 if_alloc_sadl(ifp_port); 2175 break; 2176 } 2177 } 2178 2179 static void 2180 lagg_if_setsadl(struct lagg_softc *sc, uint8_t *lladdr) 2181 { 2182 struct ifnet *ifp; 2183 2184 KASSERT(LAGG_LOCKED(sc)); 2185 2186 ifp = &sc->sc_if; 2187 2188 if (lagg_lladdr_equal(CLLADDR(ifp->if_sadl), lladdr)) 2189 return; 2190 2191 lagg_chg_sadl(ifp, lladdr, ETHER_ADDR_LEN); 2192 2193 LAGG_UNLOCK(sc); 2194 lagg_in6_ifdetach(ifp); 2195 lagg_in6_ifattach(ifp); 2196 LAGG_LOCK(sc); 2197 2198 lagg_sync_sadl(sc); 2199 } 2200 2201 static void 2202 lagg_sync_sadl(struct lagg_softc *sc) 2203 { 2204 struct ifnet *ifp; 2205 struct lagg_port *lp; 2206 const uint8_t *lla; 2207 2208 ifp = &sc->sc_if; 2209 KASSERT(IFNET_LOCKED(ifp)); 2210 2211 lla = CLLADDR(ifp->if_sadl); 2212 if (lagg_lladdr_equal(lla, sc->sc_lladdr)) 2213 return; 2214 2215 lagg_lladdr_cpy(sc->sc_lladdr, lla); 2216 2217 LAGG_PORTS_FOREACH(sc, lp) { 2218 IFNET_LOCK(lp->lp_ifp); 2219 lagg_port_setsadl(lp, lla); 2220 IFNET_UNLOCK(lp->lp_ifp); 2221 } 2222 } 2223 2224 static int 2225 lagg_port_setup(struct lagg_softc *sc, 2226 struct lagg_port *lp, struct ifnet *ifp_port) 2227 { 2228 struct ifnet *ifp; 2229 u_char if_type; 2230 int error; 2231 bool stopped, use_lagg_sadl; 2232 2233 KASSERT(LAGG_LOCKED(sc)); 2234 IFNET_ASSERT_UNLOCKED(ifp_port); 2235 2236 ifp = &sc->sc_if; 2237 2238 use_lagg_sadl = true; 2239 if (SIMPLEQ_EMPTY(&sc->sc_ports) && 2240 ifp_port->if_type == IFT_ETHER) { 2241 if (lagg_lladdr_equal(CLLADDR(ifp->if_sadl), 2242 sc->sc_lladdr_rand)) 2243 use_lagg_sadl = false; 2244 } 2245 2246 if (&sc->sc_if == ifp_port) { 2247 LAGG_DPRINTF(sc, "cannot add a lagg to itself as a port\n"); 2248 return EINVAL; 2249 } 2250 2251 if (sc->sc_nports > LAGG_MAX_PORTS) 2252 return ENOSPC; 2253 2254 if (ifp_port->if_lagg != NULL) { 2255 lp = (struct lagg_port *)ifp_port->if_lagg; 2256 if (lp->lp_softc == sc) 2257 return EEXIST; 2258 return EBUSY; 2259 } 2260 2261 switch (ifp_port->if_type) { 2262 case IFT_ETHER: 2263 case IFT_L2TP: 2264 if_type = IFT_IEEE8023ADLAG; 2265 break; 2266 default: 2267 return ENOTSUP; 2268 } 2269 2270 error = 0; 2271 stopped = false; 2272 lp->lp_softc = sc; 2273 lp->lp_prio = LAGG_PORT_PRIO; 2274 lp->lp_linkstate_hook = if_linkstate_change_establish(ifp_port, 2275 lagg_linkstate_changed, ifp_port); 2276 lp->lp_ifdetach_hook = ether_ifdetachhook_establish(ifp_port, 2277 lagg_ifdetach, ifp_port); 2278 psref_target_init(&lp->lp_psref, lagg_port_psref_class); 2279 2280 IFNET_LOCK(ifp_port); 2281 /* stop packet processing */ 2282 if (ISSET(ifp_port->if_flags, IFF_RUNNING) && 2283 ifp_port->if_init != NULL) { 2284 if_stop(ifp_port, 0); 2285 stopped = true; 2286 } 2287 2288 /* to delete ipv6 link local address */ 2289 lagg_in6_ifdetach(ifp_port); 2290 2291 /* backup members */ 2292 lp->lp_iftype = ifp_port->if_type; 2293 lp->lp_ioctl = ifp_port->if_ioctl; 2294 lp->lp_input = ifp_port->_if_input; 2295 lp->lp_output = ifp_port->if_output; 2296 lp->lp_ifcapenable = ifp_port->if_capenable; 2297 lp->lp_mtu = ifp_port->if_mtu; 2298 if (lp->lp_iftype == IFT_ETHER) { 2299 struct ethercom *ec; 2300 ec = (struct ethercom *)ifp_port; 2301 2302 lagg_lladdr_cpy(lp->lp_lladdr, CLLADDR(ifp_port->if_sadl)); 2303 lp->lp_eccapenable = ec->ec_capenable; 2304 } 2305 2306 /* change callbacks and others */ 2307 atomic_store_release(&ifp_port->if_lagg, (void *)lp); 2308 ifp_port->if_type = if_type; 2309 ifp_port->if_ioctl = lagg_port_ioctl; 2310 ifp_port->_if_input = lagg_input_ethernet; 2311 ifp_port->if_output = lagg_port_output; 2312 2313 /* update Link address */ 2314 if (use_lagg_sadl) { 2315 lagg_port_setsadl(lp, CLLADDR(ifp->if_sadl)); 2316 } else { 2317 /* update if_type in if_sadl */ 2318 if (lp->lp_iftype != ifp_port->if_type) 2319 lagg_port_setsadl(lp, NULL); 2320 } 2321 2322 error = lagg_setmtu(ifp_port, ifp->if_mtu); 2323 if (error != 0) 2324 goto restore_sadl; 2325 2326 error = lagg_proto_allocport(sc, lp); 2327 if (error != 0) 2328 goto restore_mtu; 2329 2330 /* restart packet processing */ 2331 if (stopped) { 2332 error = if_init(ifp_port); 2333 if (error != 0) 2334 goto free_port; 2335 } 2336 2337 /* setup of ifp_port is complete */ 2338 IFNET_UNLOCK(ifp_port); 2339 2340 /* copy sadl from added port to lagg */ 2341 if (!use_lagg_sadl) 2342 lagg_if_setsadl(sc, lp->lp_lladdr); 2343 2344 SIMPLEQ_INSERT_TAIL(&sc->sc_ports, lp, lp_entry); 2345 sc->sc_nports++; 2346 2347 lagg_capabilities_update(sc); 2348 lagg_port_syncmulti(sc, lp); 2349 lagg_port_syncvlan(sc, lp); 2350 lagg_config_promisc(sc, lp); 2351 2352 lagg_proto_startport(sc, lp); 2353 2354 return 0; 2355 2356 free_port: 2357 KASSERT(IFNET_LOCKED(ifp_port)); 2358 lagg_proto_freeport(sc, lp); 2359 restore_mtu: 2360 KASSERT(IFNET_LOCKED(ifp_port)); 2361 if (ifp_port->if_mtu != lp->lp_mtu) 2362 lagg_setmtu(ifp_port, lp->lp_mtu); 2363 restore_sadl: 2364 KASSERT(IFNET_LOCKED(ifp_port)); 2365 2366 /* restore if_type before changing sadl */ 2367 if_type = ifp_port->if_type; 2368 ifp_port->if_type = lp->lp_iftype; 2369 2370 if (!SIMPLEQ_EMPTY(&sc->sc_ports)) { 2371 lagg_port_setsadl(lp, lp->lp_lladdr); 2372 } else { 2373 if (ifp_port->if_type != if_type) 2374 lagg_port_setsadl(lp, NULL); 2375 } 2376 2377 lagg_in6_ifattach(ifp_port); 2378 if (stopped) { 2379 if (if_init(ifp_port) != 0) { 2380 LAGG_LOG(sc, LOG_WARNING, 2381 "couldn't re-start port %s\n", 2382 ifp_port->if_xname); 2383 } 2384 } 2385 2386 ifp_port->if_ioctl = lp->lp_ioctl; 2387 ifp_port->_if_input = lp->lp_input; 2388 ifp_port->if_output = lp->lp_output; 2389 atomic_store_release(&ifp_port->if_lagg, NULL); 2390 IFNET_UNLOCK(ifp_port); 2391 2392 psref_target_destroy(&lp->lp_psref, lagg_port_psref_class); 2393 if_linkstate_change_disestablish(ifp_port, 2394 lp->lp_linkstate_hook, NULL); 2395 ether_ifdetachhook_disestablish(ifp_port, 2396 lp->lp_ifdetach_hook, &sc->sc_lock); 2397 2398 return error; 2399 } 2400 2401 static void 2402 lagg_port_teardown(struct lagg_softc *sc, struct lagg_port *lp, 2403 bool is_ifdetach) 2404 { 2405 struct ifnet *ifp, *ifp_port; 2406 bool stopped, is_1st_port, iftype_changed; 2407 2408 KASSERT(LAGG_LOCKED(sc)); 2409 2410 ifp = &sc->sc_if; 2411 ifp_port = lp->lp_ifp; 2412 stopped = false; 2413 is_1st_port = 2414 SIMPLEQ_FIRST(&sc->sc_ports) == lp ? true : false; 2415 2416 ether_ifdetachhook_disestablish(ifp_port, 2417 lp->lp_ifdetach_hook, &sc->sc_lock); 2418 2419 if (ifp_port->if_lagg == NULL) { 2420 /* already done in lagg_ifdetach() */ 2421 return; 2422 } 2423 2424 if_linkstate_change_disestablish(ifp_port, 2425 lp->lp_linkstate_hook, NULL); 2426 2427 lagg_proto_stopport(sc, lp); 2428 2429 lagg_port_purgemulti(sc, lp); 2430 lagg_port_purgevlan(sc, lp); 2431 if (is_ifdetach == false) { 2432 lagg_unconfig_promisc(sc, lp); 2433 lagg_setifcaps(lp, lp->lp_ifcapenable); 2434 if (lp->lp_iftype == IFT_ETHER) 2435 lagg_setethcaps(lp, lp->lp_eccapenable); 2436 } 2437 2438 SIMPLEQ_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entry); 2439 sc->sc_nports--; 2440 2441 if (is_1st_port) { 2442 if (lp->lp_iftype == IFT_ETHER && 2443 lagg_lladdr_equal(lp->lp_lladdr, 2444 CLLADDR(ifp->if_sadl))) { 2445 struct lagg_port *lp0; 2446 uint8_t *lla; 2447 2448 lp0 = SIMPLEQ_FIRST(&sc->sc_ports); 2449 if (lp0 != NULL && 2450 lp0->lp_iftype == IFT_ETHER) { 2451 lla = lp0->lp_lladdr; 2452 } else { 2453 lla = sc->sc_lladdr_rand; 2454 } 2455 2456 lagg_if_setsadl(sc, lla); 2457 } 2458 } 2459 2460 IFNET_LOCK(ifp_port); 2461 /* stop packet processing */ 2462 if (ISSET(ifp_port->if_flags, IFF_RUNNING) && 2463 ifp_port->if_init != NULL) { 2464 if_stop(ifp_port, 0); 2465 stopped = true; 2466 } 2467 2468 lagg_proto_freeport(sc, lp); 2469 2470 /* change if_type before set sadl */ 2471 iftype_changed = ifp_port->if_type != lp->lp_iftype ? 2472 true : false; 2473 ifp_port->if_type = lp->lp_iftype; 2474 2475 if (is_ifdetach == false) { 2476 if (iftype_changed && 2477 lagg_lladdr_equal(CLLADDR(ifp_port->if_sadl), 2478 lp->lp_lladdr)) { 2479 lagg_port_setsadl(lp, NULL); 2480 } 2481 lagg_port_setsadl(lp, lp->lp_lladdr); 2482 lagg_in6_ifattach(ifp_port); 2483 (void)lagg_setmtu(ifp_port, lp->lp_mtu); 2484 } 2485 2486 ifp_port->_if_input = lp->lp_input; 2487 ifp_port->if_output = lp->lp_output; 2488 if (ifp_port->if_ioctl == lagg_port_ioctl) 2489 ifp_port->if_ioctl = lp->lp_ioctl; 2490 atomic_store_release(&ifp_port->if_lagg, NULL); 2491 pserialize_perform(sc->sc_psz); 2492 2493 /* to assign ipv6 link local address */ 2494 if (is_ifdetach == false) { 2495 lagg_in6_ifattach(ifp_port); 2496 } 2497 2498 /* restart packet processing */ 2499 if (stopped) { 2500 int error; 2501 error = if_init(ifp_port); 2502 if (error != 0) { 2503 LAGG_LOG(sc, LOG_WARNING, 2504 "%s failed to if_init() on %d\n", 2505 ifp_port->if_xname, error); 2506 } 2507 } 2508 IFNET_UNLOCK(ifp_port); 2509 2510 psref_target_destroy(&lp->lp_psref, lagg_port_psref_class); 2511 kmem_free(lp, sizeof(*lp)); 2512 } 2513 2514 static int 2515 lagg_addport(struct lagg_softc *sc, struct ifnet *ifp_port) 2516 { 2517 struct lagg_port *lp; 2518 int error; 2519 2520 lp = kmem_zalloc(sizeof(*lp), KM_SLEEP); 2521 lp->lp_ifp = ifp_port; 2522 2523 LAGG_LOCK(sc); 2524 error = lagg_port_setup(sc, lp, ifp_port); 2525 LAGG_UNLOCK(sc); 2526 2527 if (error != 0) 2528 kmem_free(lp, sizeof(*lp)); 2529 2530 return error; 2531 } 2532 2533 static int 2534 lagg_delport(struct lagg_softc *sc, struct ifnet *ifp_port) 2535 { 2536 struct lagg_port *lp; 2537 int error; 2538 2539 KASSERT(IFNET_LOCKED(&sc->sc_if)); 2540 2541 error = 0; 2542 LAGG_LOCK(sc); 2543 lp = ifp_port->if_lagg; 2544 if (lp == NULL || lp->lp_softc != sc) { 2545 error = ENOENT; 2546 goto out; 2547 } 2548 2549 if (lp->lp_ifdetaching) { 2550 error = EBUSY; 2551 goto out; 2552 } 2553 2554 lagg_port_teardown(sc, lp, false); 2555 2556 out: 2557 LAGG_UNLOCK(sc); 2558 2559 return error; 2560 } 2561 2562 static int 2563 lagg_delport_all(struct lagg_softc *sc) 2564 { 2565 struct lagg_port *lp; 2566 int error; 2567 2568 KASSERT(IFNET_LOCKED(&sc->sc_if)); 2569 2570 error = 0; 2571 2572 LAGG_LOCK(sc); 2573 while ((lp = LAGG_PORTS_FIRST(sc)) != NULL) { 2574 if (lp->lp_ifdetaching) { 2575 error = EBUSY; 2576 continue; 2577 } 2578 2579 lagg_port_teardown(sc, lp, false); 2580 } 2581 2582 LAGG_UNLOCK(sc); 2583 2584 return error; 2585 } 2586 2587 static int 2588 lagg_get_stats(struct lagg_softc *sc, struct lagg_req *resp, 2589 size_t nports) 2590 { 2591 struct lagg_variant *var; 2592 struct lagg_port *lp; 2593 struct laggreqport *port; 2594 struct psref psref; 2595 struct ifnet *ifp; 2596 int bound; 2597 size_t n; 2598 2599 bound = curlwp_bind(); 2600 var = lagg_variant_getref(sc, &psref); 2601 if (var == NULL) { 2602 curlwp_bindx(bound); 2603 return ENOENT; 2604 } 2605 2606 resp->lrq_proto = var->lv_proto; 2607 2608 lagg_proto_stat(var, &resp->lrq_reqproto); 2609 2610 n = 0; 2611 LAGG_LOCK(sc); 2612 LAGG_PORTS_FOREACH(sc, lp) { 2613 if (n < nports) { 2614 port = &resp->lrq_reqports[n]; 2615 2616 ifp = lp->lp_ifp; 2617 strlcpy(port->rp_portname, ifp->if_xname, 2618 sizeof(port->rp_portname)); 2619 2620 port->rp_prio = lp->lp_prio; 2621 port->rp_flags = lp->lp_flags; 2622 lagg_proto_portstat(var, lp, port); 2623 } 2624 n++; 2625 } 2626 LAGG_UNLOCK(sc); 2627 2628 resp->lrq_nports = n; 2629 2630 lagg_variant_putref(var, &psref); 2631 curlwp_bindx(bound); 2632 2633 if (resp->lrq_nports > nports) { 2634 return ENOBUFS; 2635 } 2636 return 0; 2637 } 2638 2639 static void 2640 lagg_config_promisc(struct lagg_softc *sc, struct lagg_port *lp) 2641 { 2642 struct ifnet *ifp, *ifp_port; 2643 int error; 2644 bool promisc; 2645 2646 KASSERT(LAGG_LOCKED(sc)); 2647 2648 ifp = &sc->sc_if; 2649 ifp_port = lp->lp_ifp; 2650 2651 if (lp->lp_iftype == IFT_ETHER) { 2652 promisc = ISSET(ifp->if_flags, IFF_PROMISC) ? 2653 true : false; 2654 } else { 2655 promisc = true; 2656 } 2657 2658 if (lp->lp_promisc == promisc) 2659 return; 2660 2661 error = ifpromisc(ifp_port, promisc ? 1 : 0); 2662 if (error == ENETRESET) { 2663 error = ifp_port->if_init(ifp_port); 2664 } 2665 2666 if (error == 0) { 2667 lp->lp_promisc = promisc; 2668 } else { 2669 LAGG_LOG(sc, LOG_WARNING, 2670 "couldn't %s promisc on %s\n", 2671 promisc ? "set" : "unset", 2672 ifp_port->if_xname); 2673 } 2674 } 2675 2676 static void 2677 lagg_unconfig_promisc(struct lagg_softc *sc, struct lagg_port *lp) 2678 { 2679 struct ifnet *ifp_port; 2680 int error; 2681 2682 KASSERT(LAGG_LOCKED(sc)); 2683 2684 ifp_port = lp->lp_ifp; 2685 2686 if (lp->lp_promisc == false) 2687 return; 2688 2689 error = ifpromisc(ifp_port, 0); 2690 if (error == ENETRESET) { 2691 error = ifp_port->if_init(ifp_port); 2692 } 2693 2694 if (error != 0) { 2695 LAGG_LOG(sc, LOG_WARNING, 2696 "couldn't unset promisc on %s\n", 2697 ifp_port->if_xname); 2698 } 2699 } 2700 2701 static int 2702 lagg_port_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2703 { 2704 struct lagg_softc *sc; 2705 struct lagg_port *lp; 2706 int error = 0; 2707 u_int ifflags; 2708 2709 if ((lp = ifp->if_lagg) == NULL || 2710 (sc = lp->lp_softc) == NULL) { 2711 goto fallback; 2712 } 2713 2714 KASSERT(IFNET_LOCKED(lp->lp_ifp)); 2715 2716 switch (cmd) { 2717 case SIOCSIFCAP: 2718 case SIOCSIFMTU: 2719 case SIOCSETHERCAP: 2720 /* Do not allow the setting to be cahanged once joined */ 2721 error = EINVAL; 2722 break; 2723 case SIOCSIFFLAGS: 2724 ifflags = ifp->if_flags; 2725 error = LAGG_PORT_IOCTL(lp, cmd, data); 2726 ifflags ^= ifp->if_flags; 2727 2728 if ((ifflags & (IFF_UP | IFF_RUNNING)) != 0) 2729 lagg_proto_linkstate(sc, lp); 2730 break; 2731 default: 2732 goto fallback; 2733 } 2734 2735 return error; 2736 fallback: 2737 if (lp != NULL) { 2738 error = LAGG_PORT_IOCTL(lp, cmd, data); 2739 } else { 2740 error = ENOTTY; 2741 } 2742 2743 return error; 2744 } 2745 2746 static int 2747 lagg_port_output(struct ifnet *ifp, struct mbuf *m, 2748 const struct sockaddr *dst, const struct rtentry *rt) 2749 { 2750 struct lagg_port *lp = ifp->if_lagg; 2751 int error = 0; 2752 2753 switch (dst->sa_family) { 2754 case pseudo_AF_HDRCMPLT: 2755 case AF_UNSPEC: 2756 if (lp != NULL) 2757 error = lp->lp_output(ifp, m, dst, rt); 2758 else 2759 error = ENETDOWN; 2760 break; 2761 default: 2762 m_freem(m); 2763 error = ENETDOWN; 2764 } 2765 2766 return error; 2767 } 2768 2769 void 2770 lagg_ifdetach(void *xifp_port) 2771 { 2772 struct ifnet *ifp_port = xifp_port; 2773 struct lagg_port *lp; 2774 struct lagg_softc *sc; 2775 int s; 2776 2777 IFNET_ASSERT_UNLOCKED(ifp_port); 2778 2779 s = pserialize_read_enter(); 2780 lp = atomic_load_consume(&ifp_port->if_lagg); 2781 if (lp == NULL) { 2782 pserialize_read_exit(s); 2783 return; 2784 } 2785 2786 sc = lp->lp_softc; 2787 if (sc == NULL) { 2788 pserialize_read_exit(s); 2789 return; 2790 } 2791 pserialize_read_exit(s); 2792 2793 LAGG_LOCK(sc); 2794 lp = ifp_port->if_lagg; 2795 if (lp == NULL) { 2796 LAGG_UNLOCK(sc); 2797 return; 2798 } 2799 2800 /* 2801 * mark as a detaching to prevent other 2802 * lagg_port_teardown() processings with IFNET_LOCK() held 2803 */ 2804 lp->lp_ifdetaching = true; 2805 2806 LAGG_UNLOCK(sc); 2807 2808 IFNET_LOCK(&sc->sc_if); 2809 LAGG_LOCK(sc); 2810 lp = ifp_port->if_lagg; 2811 if (lp != NULL) { 2812 lagg_port_teardown(sc, lp, true); 2813 } 2814 LAGG_UNLOCK(sc); 2815 IFNET_UNLOCK(&sc->sc_if); 2816 } 2817 2818 void 2819 lagg_linkstate_changed(void *xifp) 2820 { 2821 struct ifnet *ifp = xifp; 2822 struct lagg_port *lp; 2823 struct psref psref; 2824 int s, bound; 2825 2826 s = pserialize_read_enter(); 2827 lp = atomic_load_consume(&ifp->if_lagg); 2828 if (lp != NULL) { 2829 bound = curlwp_bind(); 2830 lagg_port_getref(lp, &psref); 2831 } else { 2832 pserialize_read_exit(s); 2833 return; 2834 } 2835 pserialize_read_exit(s); 2836 2837 IFNET_LOCK(lp->lp_ifp); 2838 lagg_proto_linkstate(lp->lp_softc, lp); 2839 IFNET_UNLOCK(lp->lp_ifp); 2840 2841 lagg_port_putref(lp, &psref); 2842 curlwp_bindx(bound); 2843 } 2844 2845 void 2846 lagg_port_getref(struct lagg_port *lp, struct psref *psref) 2847 { 2848 2849 psref_acquire(psref, &lp->lp_psref, lagg_port_psref_class); 2850 } 2851 2852 void 2853 lagg_port_putref(struct lagg_port *lp, struct psref *psref) 2854 { 2855 2856 psref_release(psref, &lp->lp_psref, lagg_port_psref_class); 2857 } 2858 2859 static void 2860 lagg_workq_work(struct work *wk, void *context) 2861 { 2862 struct lagg_work *lw; 2863 2864 lw = container_of(wk, struct lagg_work, lw_cookie); 2865 2866 atomic_cas_uint(&lw->lw_state, LAGG_WORK_ENQUEUED, LAGG_WORK_IDLE); 2867 lw->lw_func(lw, lw->lw_arg); 2868 } 2869 2870 struct workqueue * 2871 lagg_workq_create(const char *name, pri_t prio, int ipl, int flags) 2872 { 2873 struct workqueue *wq; 2874 int error; 2875 2876 error = workqueue_create(&wq, name, lagg_workq_work, 2877 NULL, prio, ipl, flags); 2878 2879 if (error) 2880 return NULL; 2881 2882 return wq; 2883 } 2884 2885 void 2886 lagg_workq_destroy(struct workqueue *wq) 2887 { 2888 2889 workqueue_destroy(wq); 2890 } 2891 2892 void 2893 lagg_workq_add(struct workqueue *wq, struct lagg_work *lw) 2894 { 2895 2896 if (atomic_cas_uint(&lw->lw_state, LAGG_WORK_IDLE, 2897 LAGG_WORK_ENQUEUED) != LAGG_WORK_IDLE) 2898 return; 2899 2900 KASSERT(lw->lw_func != NULL); 2901 kpreempt_disable(); 2902 workqueue_enqueue(wq, &lw->lw_cookie, NULL); 2903 kpreempt_enable(); 2904 } 2905 2906 void 2907 lagg_workq_wait(struct workqueue *wq, struct lagg_work *lw) 2908 { 2909 2910 atomic_swap_uint(&lw->lw_state, LAGG_WORK_STOPPING); 2911 workqueue_wait(wq, &lw->lw_cookie); 2912 } 2913 2914 static int 2915 lagg_chg_sadl(struct ifnet *ifp, const uint8_t *lla, size_t lla_len) 2916 { 2917 struct psref psref_cur, psref_next; 2918 struct ifaddr *ifa_cur, *ifa_next, *ifa_lla; 2919 const struct sockaddr_dl *sdl, *nsdl; 2920 int s, error; 2921 2922 KASSERT(!cpu_intr_p() && !cpu_softintr_p()); 2923 KASSERT(IFNET_LOCKED(ifp)); 2924 KASSERT(ifp->if_addrlen == lla_len); 2925 2926 error = 0; 2927 ifa_lla = NULL; 2928 2929 while (1) { 2930 s = pserialize_read_enter(); 2931 IFADDR_READER_FOREACH(ifa_cur, ifp) { 2932 sdl = satocsdl(ifa_cur->ifa_addr); 2933 if (sdl->sdl_family != AF_LINK) 2934 continue; 2935 2936 if (sdl->sdl_type != ifp->if_type) { 2937 ifa_acquire(ifa_cur, &psref_cur); 2938 break; 2939 } 2940 } 2941 pserialize_read_exit(s); 2942 2943 if (ifa_cur == NULL) 2944 break; 2945 2946 ifa_next = if_dl_create(ifp, &nsdl); 2947 if (ifa_next == NULL) { 2948 error = ENOMEM; 2949 ifa_release(ifa_cur, &psref_cur); 2950 goto done; 2951 } 2952 ifa_acquire(ifa_next, &psref_next); 2953 (void)sockaddr_dl_setaddr(__UNCONST(nsdl), nsdl->sdl_len, 2954 CLLADDR(sdl), ifp->if_addrlen); 2955 ifa_insert(ifp, ifa_next); 2956 2957 if (ifa_lla == NULL && 2958 memcmp(CLLADDR(sdl), lla, lla_len) == 0) { 2959 ifa_lla = ifa_next; 2960 ifaref(ifa_lla); 2961 } 2962 2963 if (ifa_cur == ifp->if_dl) 2964 if_activate_sadl(ifp, ifa_next, nsdl); 2965 2966 if (ifa_cur == ifp->if_hwdl) { 2967 ifp->if_hwdl = ifa_next; 2968 ifaref(ifa_next); 2969 ifafree(ifa_cur); 2970 } 2971 2972 ifaref(ifa_cur); 2973 ifa_release(ifa_cur, &psref_cur); 2974 ifa_remove(ifp, ifa_cur); 2975 KASSERTMSG(ifa_cur->ifa_refcnt == 1, 2976 "ifa_refcnt=%d", ifa_cur->ifa_refcnt); 2977 ifafree(ifa_cur); 2978 ifa_release(ifa_next, &psref_next); 2979 } 2980 2981 if (ifa_lla != NULL) { 2982 ifa_next = ifa_lla; 2983 2984 ifa_acquire(ifa_next, &psref_next); 2985 ifafree(ifa_lla); 2986 2987 nsdl = satocsdl(ifa_next->ifa_addr); 2988 } else { 2989 ifa_next = if_dl_create(ifp, &nsdl); 2990 if (ifa_next == NULL) { 2991 error = ENOMEM; 2992 goto done; 2993 } 2994 ifa_acquire(ifa_next, &psref_next); 2995 (void)sockaddr_dl_setaddr(__UNCONST(nsdl), 2996 nsdl->sdl_len, lla, ifp->if_addrlen); 2997 ifa_insert(ifp, ifa_next); 2998 } 2999 3000 if (ifa_next != ifp->if_dl) { 3001 ifa_cur = ifp->if_dl; 3002 if (ifa_cur != NULL) 3003 ifa_acquire(ifa_cur, &psref_cur); 3004 3005 if_activate_sadl(ifp, ifa_next, nsdl); 3006 3007 if (ifa_cur != NULL) { 3008 if (ifa_cur != ifp->if_hwdl) { 3009 ifaref(ifa_cur); 3010 ifa_release(ifa_cur, &psref_cur); 3011 ifa_remove(ifp, ifa_cur); 3012 KASSERTMSG(ifa_cur->ifa_refcnt == 1, 3013 "ifa_refcnt=%d", 3014 ifa_cur->ifa_refcnt); 3015 ifafree(ifa_cur); 3016 } else { 3017 ifa_release(ifa_cur, &psref_cur); 3018 } 3019 } 3020 } 3021 3022 ifa_release(ifa_next, &psref_next); 3023 3024 done: 3025 return error; 3026 } 3027 3028 /* 3029 * Module infrastructure 3030 */ 3031 #include <net/if_module.h> 3032 3033 IF_MODULE(MODULE_CLASS_DRIVER, lagg, NULL) 3034