if_lagg.c revision 169327
1/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */ 2 3/* 4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/cdefs.h> 20__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 169327 2007-05-07 00:18:56Z thompsa $"); 21 22#include "opt_inet.h" 23#include "opt_inet6.h" 24 25#include <sys/param.h> 26#include <sys/kernel.h> 27#include <sys/malloc.h> 28#include <sys/mbuf.h> 29#include <sys/queue.h> 30#include <sys/socket.h> 31#include <sys/sockio.h> 32#include <sys/sysctl.h> 33#include <sys/module.h> 34#include <sys/priv.h> 35#include <sys/systm.h> 36#include <sys/proc.h> 37#include <sys/hash.h> 38 39#include <net/ethernet.h> 40#include <net/if.h> 41#include <net/if_clone.h> 42#include <net/if_arp.h> 43#include <net/if_dl.h> 44#include <net/if_llc.h> 45#include <net/if_media.h> 46#include <net/if_types.h> 47#include <net/if_var.h> 48#include <net/bpf.h> 49 50#ifdef INET 51#include <netinet/in.h> 52#include <netinet/in_systm.h> 53#include <netinet/if_ether.h> 54#include <netinet/ip.h> 55#endif 56 57#ifdef INET6 58#include <netinet/ip6.h> 59#endif 60 61#include <net/if_vlan_var.h> 62#include <net/if_lagg.h> 63#include <net/ieee8023ad_lacp.h> 64 65/* Special flags we should propagate to the lagg ports. */ 66static struct { 67 int flag; 68 int (*func)(struct ifnet *, int); 69} lagg_pflags[] = { 70 {IFF_PROMISC, ifpromisc}, 71 {IFF_ALLMULTI, if_allmulti}, 72 {0, NULL} 73}; 74 75SLIST_HEAD(__trhead, lagg_softc) lagg_list; /* list of laggs */ 76static struct mtx lagg_list_mtx; 77eventhandler_tag lagg_detach_cookie = NULL; 78 79static int lagg_clone_create(struct if_clone *, int, caddr_t); 80static void lagg_clone_destroy(struct ifnet *); 81static void lagg_lladdr(struct lagg_softc *, uint8_t *); 82static int lagg_capabilities(struct lagg_softc *); 83static void lagg_port_lladdr(struct lagg_port *, uint8_t *); 84static int lagg_port_create(struct lagg_softc *, struct ifnet *); 85static int lagg_port_destroy(struct lagg_port *, int); 86static struct mbuf *lagg_input(struct ifnet *, struct mbuf *); 87static void lagg_port_state(struct ifnet *, int); 88static int lagg_port_ioctl(struct ifnet *, u_long, caddr_t); 89static int lagg_port_output(struct ifnet *, struct mbuf *, 90 struct sockaddr *, struct rtentry *); 91static void lagg_port_ifdetach(void *arg __unused, struct ifnet *); 92static int lagg_port_checkstacking(struct lagg_softc *); 93static void lagg_port2req(struct lagg_port *, struct lagg_reqport *); 94static void lagg_init(void *); 95static void lagg_stop(struct lagg_softc *); 96static int lagg_ioctl(struct ifnet *, u_long, caddr_t); 97static int lagg_ether_setmulti(struct lagg_softc *); 98static int lagg_ether_cmdmulti(struct lagg_port *, int); 99static void lagg_ether_purgemulti(struct lagg_softc *); 100static int lagg_setflag(struct lagg_port *, int, int, 101 int (*func)(struct ifnet *, int)); 102static int lagg_setflags(struct lagg_port *, int status); 103static void lagg_start(struct ifnet *); 104static int lagg_media_change(struct ifnet *); 105static void lagg_media_status(struct ifnet *, struct ifmediareq *); 106static struct lagg_port *lagg_link_active(struct lagg_softc *, 107 struct lagg_port *); 108static const void *lagg_gethdr(struct mbuf *, u_int, u_int, void *); 109 110IFC_SIMPLE_DECLARE(lagg, 0); 111 112/* Simple round robin */ 113static int lagg_rr_attach(struct lagg_softc *); 114static int lagg_rr_detach(struct lagg_softc *); 115static void lagg_rr_port_destroy(struct lagg_port *); 116static int lagg_rr_start(struct lagg_softc *, struct mbuf *); 117static struct mbuf *lagg_rr_input(struct lagg_softc *, struct lagg_port *, 118 struct mbuf *); 119 120/* Active failover */ 121static int lagg_fail_attach(struct lagg_softc *); 122static int lagg_fail_detach(struct lagg_softc *); 123static int lagg_fail_start(struct lagg_softc *, struct mbuf *); 124static struct mbuf *lagg_fail_input(struct lagg_softc *, struct lagg_port *, 125 struct mbuf *); 126 127/* Loadbalancing */ 128static int lagg_lb_attach(struct lagg_softc *); 129static int lagg_lb_detach(struct lagg_softc *); 130static int lagg_lb_port_create(struct lagg_port *); 131static void lagg_lb_port_destroy(struct lagg_port *); 132static int lagg_lb_start(struct lagg_softc *, struct mbuf *); 133static struct mbuf *lagg_lb_input(struct lagg_softc *, struct lagg_port *, 134 struct mbuf *); 135static int lagg_lb_porttable(struct lagg_softc *, struct lagg_port *); 136 137/* 802.3ad LACP */ 138static int lagg_lacp_attach(struct lagg_softc *); 139static int lagg_lacp_detach(struct lagg_softc *); 140static int lagg_lacp_start(struct lagg_softc *, struct mbuf *); 141static struct mbuf *lagg_lacp_input(struct lagg_softc *, struct lagg_port *, 142 struct mbuf *); 143static void lagg_lacp_lladdr(struct lagg_softc *); 144 145/* lagg protocol table */ 146static const struct { 147 int ti_proto; 148 int (*ti_attach)(struct lagg_softc *); 149} lagg_protos[] = { 150 { LAGG_PROTO_ROUNDROBIN, lagg_rr_attach }, 151 { LAGG_PROTO_FAILOVER, lagg_fail_attach }, 152 { LAGG_PROTO_LOADBALANCE, lagg_lb_attach }, 153 { LAGG_PROTO_ETHERCHANNEL, lagg_lb_attach }, 154 { LAGG_PROTO_LACP, lagg_lacp_attach }, 155 { LAGG_PROTO_NONE, NULL } 156}; 157 158static int 159lagg_modevent(module_t mod, int type, void *data) 160{ 161 162 switch (type) { 163 case MOD_LOAD: 164 mtx_init(&lagg_list_mtx, "if_lagg list", NULL, MTX_DEF); 165 SLIST_INIT(&lagg_list); 166 if_clone_attach(&lagg_cloner); 167 lagg_input_p = lagg_input; 168 lagg_linkstate_p = lagg_port_state; 169 lagg_detach_cookie = EVENTHANDLER_REGISTER( 170 ifnet_departure_event, lagg_port_ifdetach, NULL, 171 EVENTHANDLER_PRI_ANY); 172 break; 173 case MOD_UNLOAD: 174 EVENTHANDLER_DEREGISTER(ifnet_departure_event, 175 lagg_detach_cookie); 176 if_clone_detach(&lagg_cloner); 177 lagg_input_p = NULL; 178 lagg_linkstate_p = NULL; 179 mtx_destroy(&lagg_list_mtx); 180 break; 181 default: 182 return (EOPNOTSUPP); 183 } 184 return (0); 185} 186 187static moduledata_t lagg_mod = { 188 "if_lagg", 189 lagg_modevent, 190 0 191}; 192 193DECLARE_MODULE(if_lagg, lagg_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 194 195static int 196lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params) 197{ 198 struct lagg_softc *sc; 199 struct ifnet *ifp; 200 int i, error = 0; 201 static const u_char eaddr[6]; /* 00:00:00:00:00:00 */ 202 203 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); 204 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); 205 if (ifp == NULL) { 206 free(sc, M_DEVBUF); 207 return (ENOSPC); 208 } 209 210 sc->sc_proto = LAGG_PROTO_NONE; 211 for (i = 0; lagg_protos[i].ti_proto != LAGG_PROTO_NONE; i++) { 212 if (lagg_protos[i].ti_proto == LAGG_PROTO_DEFAULT) { 213 sc->sc_proto = lagg_protos[i].ti_proto; 214 if ((error = lagg_protos[i].ti_attach(sc)) != 0) { 215 if_free_type(ifp, IFT_ETHER); 216 free(sc, M_DEVBUF); 217 return (error); 218 } 219 break; 220 } 221 } 222 LAGG_LOCK_INIT(sc); 223 SLIST_INIT(&sc->sc_ports); 224 225 /* Initialise pseudo media types */ 226 ifmedia_init(&sc->sc_media, 0, lagg_media_change, 227 lagg_media_status); 228 ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL); 229 ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO); 230 231 if_initname(ifp, ifc->ifc_name, unit); 232 ifp->if_type = IFT_ETHER; 233 ifp->if_softc = sc; 234 ifp->if_start = lagg_start; 235 ifp->if_init = lagg_init; 236 ifp->if_ioctl = lagg_ioctl; 237 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 238 239 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 240 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 241 IFQ_SET_READY(&ifp->if_snd); 242 243 /* 244 * Attach as an ordinary ethernet device, childs will be attached 245 * as special device IFT_IEEE8023ADLAG. 246 */ 247 ether_ifattach(ifp, eaddr); 248 249 /* Insert into the global list of laggs */ 250 mtx_lock(&lagg_list_mtx); 251 SLIST_INSERT_HEAD(&lagg_list, sc, sc_entries); 252 mtx_unlock(&lagg_list_mtx); 253 254 return (0); 255} 256 257static void 258lagg_clone_destroy(struct ifnet *ifp) 259{ 260 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 261 struct lagg_port *lp; 262 263 LAGG_LOCK(sc); 264 265 lagg_stop(sc); 266 ifp->if_flags &= ~IFF_UP; 267 268 /* Shutdown and remove lagg ports */ 269 while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) 270 lagg_port_destroy(lp, 1); 271 /* Unhook the aggregation protocol */ 272 if (sc->sc_detach != NULL) 273 (*sc->sc_detach)(sc); 274 275 /* Remove any multicast groups that we may have joined. */ 276 lagg_ether_purgemulti(sc); 277 278 LAGG_UNLOCK(sc); 279 280 ifmedia_removeall(&sc->sc_media); 281 ether_ifdetach(ifp); 282 if_free_type(ifp, IFT_ETHER); 283 284 mtx_lock(&lagg_list_mtx); 285 SLIST_REMOVE(&lagg_list, sc, lagg_softc, sc_entries); 286 mtx_unlock(&lagg_list_mtx); 287 288 LAGG_LOCK_DESTROY(sc); 289 free(sc, M_DEVBUF); 290} 291 292static void 293lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr) 294{ 295 struct ifnet *ifp = sc->sc_ifp; 296 297 if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0) 298 return; 299 300 bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN); 301 /* Let the protocol know the MAC has changed */ 302 if (sc->sc_lladdr != NULL) 303 (*sc->sc_lladdr)(sc); 304} 305 306static int 307lagg_capabilities(struct lagg_softc *sc) 308{ 309 struct lagg_port *lp; 310 int cap = ~0, priv; 311 312 LAGG_LOCK_ASSERT(sc); 313 314 /* Preserve private capabilities */ 315 priv = sc->sc_capabilities & IFCAP_LAGG_MASK; 316 317 /* Get capabilities from the lagg ports */ 318 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 319 cap &= lp->lp_capabilities; 320 321 if (sc->sc_ifflags & IFF_DEBUG) { 322 printf("%s: capabilities 0x%08x\n", 323 sc->sc_ifname, cap == ~0 ? priv : (cap | priv)); 324 } 325 326 return (cap == ~0 ? priv : (cap | priv)); 327} 328 329static void 330lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr) 331{ 332 struct ifnet *ifp = lp->lp_ifp; 333 int error; 334 335 if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0) 336 return; 337 338 /* Set the link layer address */ 339 error = if_setlladdr(ifp, lladdr, ETHER_ADDR_LEN); 340 if (error) 341 printf("%s: setlladdr failed on %s\n", __func__, lp->lp_ifname); 342 343} 344 345static int 346lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) 347{ 348 struct lagg_softc *sc_ptr; 349 struct lagg_port *lp; 350 int error = 0; 351 352 LAGG_LOCK_ASSERT(sc); 353 354 /* Limit the maximal number of lagg ports */ 355 if (sc->sc_count >= LAGG_MAX_PORTS) 356 return (ENOSPC); 357 358 /* New lagg port has to be in an idle state */ 359 if (ifp->if_drv_flags & IFF_DRV_OACTIVE) 360 return (EBUSY); 361 362 /* Check if port has already been associated to a lagg */ 363 if (ifp->if_lagg != NULL) 364 return (EBUSY); 365 366 /* XXX Disallow non-ethernet interfaces (this should be any of 802) */ 367 if (ifp->if_type != IFT_ETHER) 368 return (EPROTONOSUPPORT); 369 370 if ((lp = malloc(sizeof(struct lagg_port), 371 M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) 372 return (ENOMEM); 373 374 /* Check if port is a stacked lagg */ 375 mtx_lock(&lagg_list_mtx); 376 SLIST_FOREACH(sc_ptr, &lagg_list, sc_entries) { 377 if (ifp == sc_ptr->sc_ifp) { 378 mtx_unlock(&lagg_list_mtx); 379 free(lp, M_DEVBUF); 380 return (EINVAL); 381 /* XXX disable stacking for the moment, its untested 382 lp->lp_flags |= LAGG_PORT_STACK; 383 if (lagg_port_checkstacking(sc_ptr) >= 384 LAGG_MAX_STACKING) { 385 mtx_unlock(&lagg_list_mtx); 386 free(lp, M_DEVBUF); 387 return (E2BIG); 388 } 389 */ 390 } 391 } 392 mtx_unlock(&lagg_list_mtx); 393 394 /* Change the interface type */ 395 lp->lp_iftype = ifp->if_type; 396 ifp->if_type = IFT_IEEE8023ADLAG; 397 ifp->if_lagg = lp; 398 lp->lp_ioctl = ifp->if_ioctl; 399 ifp->if_ioctl = lagg_port_ioctl; 400 lp->lp_output = ifp->if_output; 401 ifp->if_output = lagg_port_output; 402 403 lp->lp_ifp = ifp; 404 lp->lp_lagg = sc; 405 406 /* Save port link layer address */ 407 bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN); 408 409 if (SLIST_EMPTY(&sc->sc_ports)) { 410 sc->sc_primary = lp; 411 lagg_lladdr(sc, IF_LLADDR(ifp)); 412 } else { 413 /* Update link layer address for this port */ 414 lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp)); 415 } 416 417 /* Insert into the list of ports */ 418 SLIST_INSERT_HEAD(&sc->sc_ports, lp, lp_entries); 419 sc->sc_count++; 420 421 /* Update lagg capabilities */ 422 sc->sc_capabilities = lagg_capabilities(sc); 423 424 /* Add multicast addresses and interface flags to this port */ 425 lagg_ether_cmdmulti(lp, 1); 426 lagg_setflags(lp, 1); 427 428 if (sc->sc_port_create != NULL) 429 error = (*sc->sc_port_create)(lp); 430 if (error) { 431 /* remove the port again, without calling sc_port_destroy */ 432 lagg_port_destroy(lp, 0); 433 return (error); 434 } 435 436 return (error); 437} 438 439static int 440lagg_port_checkstacking(struct lagg_softc *sc) 441{ 442 struct lagg_softc *sc_ptr; 443 struct lagg_port *lp; 444 int m = 0; 445 446 LAGG_LOCK_ASSERT(sc); 447 448 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { 449 if (lp->lp_flags & LAGG_PORT_STACK) { 450 sc_ptr = (struct lagg_softc *)lp->lp_ifp->if_softc; 451 m = MAX(m, lagg_port_checkstacking(sc_ptr)); 452 } 453 } 454 455 return (m + 1); 456} 457 458static int 459lagg_port_destroy(struct lagg_port *lp, int runpd) 460{ 461 struct lagg_softc *sc = lp->lp_lagg; 462 struct lagg_port *lp_ptr; 463 struct ifnet *ifp = lp->lp_ifp; 464 465 LAGG_LOCK_ASSERT(sc); 466 467 if (runpd && sc->sc_port_destroy != NULL) 468 (*sc->sc_port_destroy)(lp); 469 470 /* Remove multicast addresses and interface flags from this port */ 471 lagg_ether_cmdmulti(lp, 0); 472 lagg_setflags(lp, 0); 473 474 /* Restore interface */ 475 ifp->if_type = lp->lp_iftype; 476 ifp->if_ioctl = lp->lp_ioctl; 477 ifp->if_output = lp->lp_output; 478 ifp->if_lagg = NULL; 479 480 /* Finally, remove the port from the lagg */ 481 SLIST_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entries); 482 sc->sc_count--; 483 484 /* Update the primary interface */ 485 if (lp == sc->sc_primary) { 486 uint8_t lladdr[ETHER_ADDR_LEN]; 487 488 if ((lp_ptr = SLIST_FIRST(&sc->sc_ports)) == NULL) { 489 bzero(&lladdr, ETHER_ADDR_LEN); 490 } else { 491 bcopy(lp_ptr->lp_lladdr, 492 lladdr, ETHER_ADDR_LEN); 493 } 494 lagg_lladdr(sc, lladdr); 495 sc->sc_primary = lp_ptr; 496 497 /* Update link layer address for each port */ 498 SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries) 499 lagg_port_lladdr(lp_ptr, lladdr); 500 } 501 502 /* Reset the port lladdr */ 503 lagg_port_lladdr(lp, lp->lp_lladdr); 504 505 if (lp->lp_ifflags) 506 if_printf(ifp, "%s: lp_ifflags unclean\n", __func__); 507 508 free(lp, M_DEVBUF); 509 510 /* Update lagg capabilities */ 511 sc->sc_capabilities = lagg_capabilities(sc); 512 513 return (0); 514} 515 516static int 517lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 518{ 519 struct lagg_reqport *rp = (struct lagg_reqport *)data; 520 struct lagg_softc *sc; 521 struct lagg_port *lp = NULL; 522 int error = 0; 523 524 /* Should be checked by the caller */ 525 if (ifp->if_type != IFT_IEEE8023ADLAG || 526 (lp = ifp->if_lagg) == NULL || (sc = lp->lp_lagg) == NULL) 527 goto fallback; 528 529 switch (cmd) { 530 case SIOCGLAGGPORT: 531 LAGG_LOCK(sc); 532 if (rp->rp_portname[0] == '\0' || 533 ifunit(rp->rp_portname) != ifp) { 534 error = EINVAL; 535 break; 536 } 537 538 if (lp->lp_lagg != sc) { 539 error = ENOENT; 540 break; 541 } 542 543 lagg_port2req(lp, rp); 544 LAGG_UNLOCK(sc); 545 break; 546 default: 547 goto fallback; 548 } 549 550 return (error); 551 552fallback: 553 if (lp != NULL) 554 return ((*lp->lp_ioctl)(ifp, cmd, data)); 555 556 return (EINVAL); 557} 558 559static int 560lagg_port_output(struct ifnet *ifp, struct mbuf *m, 561 struct sockaddr *dst, struct rtentry *rt0) 562{ 563 struct lagg_port *lp = ifp->if_lagg; 564 struct ether_header *eh; 565 short type = 0; 566 567 switch (dst->sa_family) { 568 case pseudo_AF_HDRCMPLT: 569 case AF_UNSPEC: 570 eh = (struct ether_header *)dst->sa_data; 571 type = eh->ether_type; 572 break; 573 } 574 575 /* 576 * Only allow ethernet types required to initiate or maintain the link, 577 * aggregated frames take a different path. 578 */ 579 switch (ntohs(type)) { 580 case ETHERTYPE_PAE: /* EAPOL PAE/802.1x */ 581 return ((*lp->lp_output)(ifp, m, dst, rt0)); 582 } 583 584 /* drop any other frames */ 585 m_freem(m); 586 return (EBUSY); 587} 588 589static void 590lagg_port_ifdetach(void *arg __unused, struct ifnet *ifp) 591{ 592 struct lagg_port *lp; 593 struct lagg_softc *sc; 594 595 if ((lp = ifp->if_lagg) == NULL) 596 return; 597 598 sc = lp->lp_lagg; 599 600 LAGG_LOCK(sc); 601 lagg_port_destroy(lp, 1); 602 LAGG_UNLOCK(sc); 603} 604 605static void 606lagg_port2req(struct lagg_port *lp, struct lagg_reqport *rp) 607{ 608 struct lagg_softc *sc = lp->lp_lagg; 609 strlcpy(rp->rp_ifname, sc->sc_ifname, sizeof(rp->rp_ifname)); 610 strlcpy(rp->rp_portname, lp->lp_ifp->if_xname, sizeof(rp->rp_portname)); 611 rp->rp_prio = lp->lp_prio; 612 rp->rp_flags = lp->lp_flags; 613 614 /* Add protocol specific flags */ 615 switch (sc->sc_proto) { 616 case LAGG_PROTO_FAILOVER: 617 if (lp == sc->sc_primary) 618 rp->rp_flags |= LAGG_PORT_MASTER; 619 /* FALLTHROUGH */ 620 case LAGG_PROTO_ROUNDROBIN: 621 case LAGG_PROTO_LOADBALANCE: 622 case LAGG_PROTO_ETHERCHANNEL: 623 if (LAGG_PORTACTIVE(lp)) 624 rp->rp_flags |= LAGG_PORT_ACTIVE; 625 break; 626 627 case LAGG_PROTO_LACP: 628 /* LACP has a different definition of active */ 629 if (lacp_port_isactive(lp)) 630 rp->rp_flags |= LAGG_PORT_ACTIVE; 631 break; 632 } 633 634} 635 636static void 637lagg_init(void *xsc) 638{ 639 struct lagg_softc *sc = (struct lagg_softc *)xsc; 640 struct lagg_port *lp; 641 struct ifnet *ifp = sc->sc_ifp; 642 643 if (ifp->if_drv_flags & IFF_DRV_RUNNING) 644 return; 645 646 LAGG_LOCK(sc); 647 648 ifp->if_drv_flags |= IFF_DRV_RUNNING; 649 /* Update the port lladdrs */ 650 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 651 lagg_port_lladdr(lp, IF_LLADDR(ifp)); 652 653 if (sc->sc_init != NULL) 654 (*sc->sc_init)(sc); 655 656 LAGG_UNLOCK(sc); 657} 658 659static void 660lagg_stop(struct lagg_softc *sc) 661{ 662 struct ifnet *ifp = sc->sc_ifp; 663 664 LAGG_LOCK_ASSERT(sc); 665 666 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 667 return; 668 669 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 670 671 if (sc->sc_stop != NULL) 672 (*sc->sc_stop)(sc); 673} 674 675static int 676lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 677{ 678 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 679 struct lagg_reqall *ra = (struct lagg_reqall *)data; 680 struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf; 681 struct ifreq *ifr = (struct ifreq *)data; 682 struct lagg_port *lp; 683 struct ifnet *tpif; 684 struct thread *td = curthread; 685 int i, error = 0, unlock = 1; 686 687 LAGG_LOCK(sc); 688 689 bzero(&rpbuf, sizeof(rpbuf)); 690 691 switch (cmd) { 692 case SIOCGLAGG: 693 ra->ra_proto = sc->sc_proto; 694 ra->ra_ports = i = 0; 695 lp = SLIST_FIRST(&sc->sc_ports); 696 while (lp && ra->ra_size >= 697 i + sizeof(struct lagg_reqport)) { 698 lagg_port2req(lp, &rpbuf); 699 error = copyout(&rpbuf, (caddr_t)ra->ra_port + i, 700 sizeof(struct lagg_reqport)); 701 if (error) 702 break; 703 i += sizeof(struct lagg_reqport); 704 ra->ra_ports++; 705 lp = SLIST_NEXT(lp, lp_entries); 706 } 707 break; 708 case SIOCSLAGG: 709 error = priv_check(td, PRIV_NET_LAGG); 710 if (error) 711 break; 712 if (ra->ra_proto >= LAGG_PROTO_MAX) { 713 error = EPROTONOSUPPORT; 714 break; 715 } 716 if (sc->sc_proto != LAGG_PROTO_NONE) { 717 error = sc->sc_detach(sc); 718 /* Reset protocol and pointers */ 719 sc->sc_proto = LAGG_PROTO_NONE; 720 sc->sc_detach = NULL; 721 sc->sc_start = NULL; 722 sc->sc_input = NULL; 723 sc->sc_port_create = NULL; 724 sc->sc_port_destroy = NULL; 725 sc->sc_linkstate = NULL; 726 sc->sc_init = NULL; 727 sc->sc_stop = NULL; 728 sc->sc_lladdr = NULL; 729 } 730 if (error != 0) 731 break; 732 for (i = 0; i < (sizeof(lagg_protos) / 733 sizeof(lagg_protos[0])); i++) { 734 if (lagg_protos[i].ti_proto == ra->ra_proto) { 735 if (sc->sc_ifflags & IFF_DEBUG) 736 printf("%s: using proto %u\n", 737 sc->sc_ifname, 738 lagg_protos[i].ti_proto); 739 sc->sc_proto = lagg_protos[i].ti_proto; 740 if (sc->sc_proto != LAGG_PROTO_NONE) 741 error = lagg_protos[i].ti_attach(sc); 742 goto out; 743 } 744 } 745 error = EPROTONOSUPPORT; 746 break; 747 case SIOCGLAGGPORT: 748 if (rp->rp_portname[0] == '\0' || 749 (tpif = ifunit(rp->rp_portname)) == NULL) { 750 error = EINVAL; 751 break; 752 } 753 754 if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL || 755 lp->lp_lagg != sc) { 756 error = ENOENT; 757 break; 758 } 759 760 lagg_port2req(lp, rp); 761 break; 762 case SIOCSLAGGPORT: 763 error = priv_check(td, PRIV_NET_LAGG); 764 if (error) 765 break; 766 if (rp->rp_portname[0] == '\0' || 767 (tpif = ifunit(rp->rp_portname)) == NULL) { 768 error = EINVAL; 769 break; 770 } 771 error = lagg_port_create(sc, tpif); 772 break; 773 case SIOCSLAGGDELPORT: 774 error = priv_check(td, PRIV_NET_LAGG); 775 if (error) 776 break; 777 if (rp->rp_portname[0] == '\0' || 778 (tpif = ifunit(rp->rp_portname)) == NULL) { 779 error = EINVAL; 780 break; 781 } 782 783 if ((lp = (struct lagg_port *)tpif->if_lagg) == NULL || 784 lp->lp_lagg != sc) { 785 error = ENOENT; 786 break; 787 } 788 789 error = lagg_port_destroy(lp, 1); 790 break; 791 case SIOCSIFFLAGS: 792 /* Set flags on ports too */ 793 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { 794 lagg_setflags(lp, 1); 795 } 796 797 if (!(ifp->if_flags & IFF_UP) && 798 (ifp->if_drv_flags & IFF_DRV_RUNNING)) { 799 /* 800 * If interface is marked down and it is running, 801 * then stop and disable it. 802 */ 803 lagg_stop(sc); 804 } else if ((ifp->if_flags & IFF_UP) && 805 !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { 806 /* 807 * If interface is marked up and it is stopped, then 808 * start it. 809 */ 810 LAGG_UNLOCK(sc); 811 unlock = 0; 812 (*ifp->if_init)(sc); 813 } 814 break; 815 case SIOCADDMULTI: 816 case SIOCDELMULTI: 817 error = lagg_ether_setmulti(sc); 818 break; 819 case SIOCSIFMEDIA: 820 case SIOCGIFMEDIA: 821 LAGG_UNLOCK(sc); 822 unlock = 0; 823 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 824 break; 825 default: 826 LAGG_UNLOCK(sc); 827 unlock = 0; 828 error = ether_ioctl(ifp, cmd, data); 829 break; 830 } 831 832out: 833 if (unlock) 834 LAGG_UNLOCK(sc); 835 return (error); 836} 837 838static int 839lagg_ether_setmulti(struct lagg_softc *sc) 840{ 841 struct lagg_port *lp; 842 843 LAGG_LOCK_ASSERT(sc); 844 845 /* First, remove any existing filter entries. */ 846 lagg_ether_purgemulti(sc); 847 848 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { 849 lagg_ether_cmdmulti(lp, 1); 850 } 851 return (0); 852} 853 854static int 855lagg_ether_cmdmulti(struct lagg_port *lp, int set) 856{ 857 struct lagg_softc *sc = lp->lp_lagg; 858 struct ifnet *ifp = lp->lp_ifp; 859 struct ifnet *trifp = sc->sc_ifp; 860 struct lagg_mc *mc; 861 struct ifmultiaddr *ifma, *rifma = NULL; 862 struct sockaddr_dl sdl; 863 int error; 864 865 LAGG_LOCK_ASSERT(sc); 866 867 bzero((char *)&sdl, sizeof(sdl)); 868 sdl.sdl_len = sizeof(sdl); 869 sdl.sdl_family = AF_LINK; 870 sdl.sdl_type = IFT_ETHER; 871 sdl.sdl_alen = ETHER_ADDR_LEN; 872 sdl.sdl_index = ifp->if_index; 873 874 if (set) { 875 TAILQ_FOREACH(ifma, &trifp->if_multiaddrs, ifma_link) { 876 if (ifma->ifma_addr->sa_family != AF_LINK) 877 continue; 878 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 879 LLADDR(&sdl), ETHER_ADDR_LEN); 880 881 error = if_addmulti(ifp, (struct sockaddr *)&sdl, &rifma); 882 if (error) 883 return (error); 884 mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT); 885 if (mc == NULL) 886 return (ENOMEM); 887 mc->mc_ifma = rifma; 888 SLIST_INSERT_HEAD(&lp->lp_mc_head, mc, mc_entries); 889 } 890 } else { 891 while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) { 892 SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries); 893 if_delmulti_ifma(mc->mc_ifma); 894 free(mc, M_DEVBUF); 895 } 896 } 897 return (0); 898} 899 900static void 901lagg_ether_purgemulti(struct lagg_softc *sc) 902{ 903 struct lagg_port *lp; 904 905 LAGG_LOCK_ASSERT(sc); 906 907 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 908 lagg_ether_cmdmulti(lp, 0); 909} 910 911/* Handle a ref counted flag that should be set on the lagg port as well */ 912static int 913lagg_setflag(struct lagg_port *lp, int flag, int status, 914 int (*func)(struct ifnet *, int)) 915{ 916 struct lagg_softc *sc = lp->lp_lagg; 917 struct ifnet *trifp = sc->sc_ifp; 918 struct ifnet *ifp = lp->lp_ifp; 919 int error; 920 921 LAGG_LOCK_ASSERT(sc); 922 923 status = status ? (trifp->if_flags & flag) : 0; 924 /* Now "status" contains the flag value or 0 */ 925 926 /* 927 * See if recorded ports status is different from what 928 * we want it to be. If it is, flip it. We record ports 929 * status in lp_ifflags so that we won't clear ports flag 930 * we haven't set. In fact, we don't clear or set ports 931 * flags directly, but get or release references to them. 932 * That's why we can be sure that recorded flags still are 933 * in accord with actual ports flags. 934 */ 935 if (status != (lp->lp_ifflags & flag)) { 936 error = (*func)(ifp, status); 937 if (error) 938 return (error); 939 lp->lp_ifflags &= ~flag; 940 lp->lp_ifflags |= status; 941 } 942 return (0); 943} 944 945/* 946 * Handle IFF_* flags that require certain changes on the lagg port 947 * if "status" is true, update ports flags respective to the lagg 948 * if "status" is false, forcedly clear the flags set on port. 949 */ 950static int 951lagg_setflags(struct lagg_port *lp, int status) 952{ 953 int error, i; 954 955 for (i = 0; lagg_pflags[i].flag; i++) { 956 error = lagg_setflag(lp, lagg_pflags[i].flag, 957 status, lagg_pflags[i].func); 958 if (error) 959 return (error); 960 } 961 return (0); 962} 963 964static void 965lagg_start(struct ifnet *ifp) 966{ 967 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 968 struct mbuf *m; 969 int error = 0; 970 971 for (;; error = 0) { 972 IFQ_DEQUEUE(&ifp->if_snd, m); 973 if (m == NULL) 974 break; 975 976 BPF_MTAP(ifp, m); 977 978 if (sc->sc_proto != LAGG_PROTO_NONE) { 979 LAGG_LOCK(sc); 980 error = (*sc->sc_start)(sc, m); 981 LAGG_UNLOCK(sc); 982 } else 983 m_free(m); 984 985 if (error == 0) 986 ifp->if_opackets++; 987 else 988 ifp->if_oerrors++; 989 } 990 991 return; 992} 993 994static struct mbuf * 995lagg_input(struct ifnet *ifp, struct mbuf *m) 996{ 997 struct lagg_port *lp = ifp->if_lagg; 998 struct lagg_softc *sc = lp->lp_lagg; 999 struct ifnet *trifp = sc->sc_ifp; 1000 1001 if ((trifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 1002 (lp->lp_flags & LAGG_PORT_DISABLED) || 1003 sc->sc_proto == LAGG_PROTO_NONE) { 1004 m_freem(m); 1005 return (NULL); 1006 } 1007 1008 LAGG_LOCK(sc); 1009 BPF_MTAP(trifp, m); 1010 1011 m = (*sc->sc_input)(sc, lp, m); 1012 1013 if (m != NULL) { 1014 ifp->if_ipackets++; 1015 ifp->if_ibytes += m->m_pkthdr.len; 1016 trifp->if_ipackets++; 1017 trifp->if_ibytes += m->m_pkthdr.len; 1018 } 1019 1020 LAGG_UNLOCK(sc); 1021 return (m); 1022} 1023 1024static int 1025lagg_media_change(struct ifnet *ifp) 1026{ 1027 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 1028 1029 if (sc->sc_ifflags & IFF_DEBUG) 1030 printf("%s\n", __func__); 1031 1032 /* Ignore */ 1033 return (0); 1034} 1035 1036static void 1037lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr) 1038{ 1039 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc; 1040 struct lagg_port *lp; 1041 1042 imr->ifm_status = IFM_AVALID; 1043 imr->ifm_active = IFM_ETHER | IFM_AUTO; 1044 1045 LAGG_LOCK(sc); 1046 lp = sc->sc_primary; 1047 if (lp != NULL && lp->lp_ifp->if_flags & IFF_UP) 1048 imr->ifm_status |= IFM_ACTIVE; 1049 LAGG_UNLOCK(sc); 1050} 1051 1052static void 1053lagg_port_state(struct ifnet *ifp, int state) 1054{ 1055 struct lagg_port *lp = (struct lagg_port *)ifp->if_lagg; 1056 struct lagg_softc *sc = NULL; 1057 1058 if (lp != NULL) 1059 sc = lp->lp_lagg; 1060 if (sc == NULL) 1061 return; 1062 1063 LAGG_LOCK(sc); 1064 if (sc->sc_linkstate != NULL) 1065 (*sc->sc_linkstate)(lp); 1066 LAGG_UNLOCK(sc); 1067} 1068 1069struct lagg_port * 1070lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp) 1071{ 1072 struct lagg_port *lp_next, *rval = NULL; 1073 // int new_link = LINK_STATE_DOWN; 1074 1075 LAGG_LOCK_ASSERT(sc); 1076 /* 1077 * Search a port which reports an active link state. 1078 */ 1079 1080 if (lp == NULL) 1081 goto search; 1082 if (LAGG_PORTACTIVE(lp)) { 1083 rval = lp; 1084 goto found; 1085 } 1086 if ((lp_next = SLIST_NEXT(lp, lp_entries)) != NULL && 1087 LAGG_PORTACTIVE(lp_next)) { 1088 rval = lp_next; 1089 goto found; 1090 } 1091 1092search: 1093 SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) { 1094 if (LAGG_PORTACTIVE(lp_next)) { 1095 rval = lp_next; 1096 goto found; 1097 } 1098 } 1099 1100found: 1101 if (rval != NULL) { 1102 /* 1103 * The IEEE 802.1D standard assumes that a lagg with 1104 * multiple ports is always full duplex. This is valid 1105 * for load sharing laggs and if at least two links 1106 * are active. Unfortunately, checking the latter would 1107 * be too expensive at this point. 1108 XXX 1109 if ((sc->sc_capabilities & IFCAP_LAGG_FULLDUPLEX) && 1110 (sc->sc_count > 1)) 1111 new_link = LINK_STATE_FULL_DUPLEX; 1112 else 1113 new_link = rval->lp_link_state; 1114 */ 1115 } 1116 1117 return (rval); 1118} 1119 1120static const void * 1121lagg_gethdr(struct mbuf *m, u_int off, u_int len, void *buf) 1122{ 1123 if (m->m_pkthdr.len < (off + len)) { 1124 return (NULL); 1125 } else if (m->m_len < (off + len)) { 1126 m_copydata(m, off, len, buf); 1127 return (buf); 1128 } 1129 return (mtod(m, char *) + off); 1130} 1131 1132uint32_t 1133lagg_hashmbuf(struct mbuf *m, uint32_t key) 1134{ 1135 uint16_t etype; 1136 uint32_t p = 0; 1137 int off; 1138 struct ether_header *eh; 1139 struct ether_vlan_header vlanbuf; 1140 const struct ether_vlan_header *vlan; 1141#ifdef INET 1142 const struct ip *ip; 1143 struct ip ipbuf; 1144#endif 1145#ifdef INET6 1146 const struct ip6_hdr *ip6; 1147 struct ip6_hdr ip6buf; 1148#endif 1149 1150 off = sizeof(*eh); 1151 if (m->m_len < off) 1152 goto out; 1153 eh = mtod(m, struct ether_header *); 1154 etype = ntohs(eh->ether_type); 1155 p = hash32_buf(&eh->ether_shost, ETHER_ADDR_LEN, key); 1156 p = hash32_buf(&eh->ether_dhost, ETHER_ADDR_LEN, p); 1157 1158 /* Special handling for encapsulating VLAN frames */ 1159 if (m->m_flags & M_VLANTAG) { 1160 p = hash32_buf(&m->m_pkthdr.ether_vtag, 1161 sizeof(m->m_pkthdr.ether_vtag), p); 1162 } else if (etype == ETHERTYPE_VLAN) { 1163 vlan = lagg_gethdr(m, off, sizeof(*vlan), &vlanbuf); 1164 if (vlan == NULL) 1165 goto out; 1166 1167 p = hash32_buf(&vlan->evl_tag, sizeof(vlan->evl_tag), p); 1168 etype = ntohs(vlan->evl_proto); 1169 off += sizeof(*vlan) - sizeof(*eh); 1170 } 1171 1172 switch (etype) { 1173#ifdef INET 1174 case ETHERTYPE_IP: 1175 ip = lagg_gethdr(m, off, sizeof(*ip), &ipbuf); 1176 if (ip == NULL) 1177 goto out; 1178 1179 p = hash32_buf(&ip->ip_src, sizeof(struct in_addr), p); 1180 p = hash32_buf(&ip->ip_dst, sizeof(struct in_addr), p); 1181 break; 1182#endif 1183#ifdef INET6 1184 case ETHERTYPE_IPV6: 1185 ip6 = lagg_gethdr(m, off, sizeof(*ip6), &ip6buf); 1186 if (ip6 == NULL) 1187 goto out; 1188 1189 p = hash32_buf(&ip6->ip6_src, sizeof(struct in6_addr), p); 1190 p = hash32_buf(&ip6->ip6_dst, sizeof(struct in6_addr), p); 1191 break; 1192#endif 1193 } 1194out: 1195 return (p); 1196} 1197 1198int 1199lagg_enqueue(struct ifnet *ifp, struct mbuf *m) 1200{ 1201 int error = 0; 1202 1203 /* Send mbuf */ 1204 IFQ_ENQUEUE(&ifp->if_snd, m, error); 1205 if (error) 1206 return (error); 1207 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) 1208 (*ifp->if_start)(ifp); 1209 1210 ifp->if_obytes += m->m_pkthdr.len; 1211 if (m->m_flags & M_MCAST) 1212 ifp->if_omcasts++; 1213 1214 return (error); 1215} 1216 1217/* 1218 * Simple round robin aggregation 1219 */ 1220 1221static int 1222lagg_rr_attach(struct lagg_softc *sc) 1223{ 1224 struct lagg_port *lp; 1225 1226 sc->sc_detach = lagg_rr_detach; 1227 sc->sc_start = lagg_rr_start; 1228 sc->sc_input = lagg_rr_input; 1229 sc->sc_port_create = NULL; 1230 sc->sc_port_destroy = lagg_rr_port_destroy; 1231 sc->sc_capabilities = IFCAP_LAGG_FULLDUPLEX; 1232 1233 lp = SLIST_FIRST(&sc->sc_ports); 1234 sc->sc_psc = (caddr_t)lp; 1235 1236 return (0); 1237} 1238 1239static int 1240lagg_rr_detach(struct lagg_softc *sc) 1241{ 1242 sc->sc_psc = NULL; 1243 return (0); 1244} 1245 1246static void 1247lagg_rr_port_destroy(struct lagg_port *lp) 1248{ 1249 struct lagg_softc *sc = lp->lp_lagg; 1250 1251 if (lp == (struct lagg_port *)sc->sc_psc) 1252 sc->sc_psc = NULL; 1253} 1254 1255static int 1256lagg_rr_start(struct lagg_softc *sc, struct mbuf *m) 1257{ 1258 struct lagg_port *lp = (struct lagg_port *)sc->sc_psc, *lp_next; 1259 int error = 0; 1260 1261 if (lp == NULL && (lp = lagg_link_active(sc, NULL)) == NULL) 1262 return (ENOENT); 1263 1264 /* Send mbuf */ 1265 error = lagg_enqueue(lp->lp_ifp, m); 1266 1267 /* Get next active port */ 1268 lp_next = lagg_link_active(sc, SLIST_NEXT(lp, lp_entries)); 1269 sc->sc_psc = (caddr_t)lp_next; 1270 1271 return (error); 1272} 1273 1274static struct mbuf * 1275lagg_rr_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) 1276{ 1277 struct ifnet *ifp = sc->sc_ifp; 1278 1279 /* Just pass in the packet to our lagg device */ 1280 m->m_pkthdr.rcvif = ifp; 1281 1282 return (m); 1283} 1284 1285/* 1286 * Active failover 1287 */ 1288 1289static int 1290lagg_fail_attach(struct lagg_softc *sc) 1291{ 1292 sc->sc_detach = lagg_fail_detach; 1293 sc->sc_start = lagg_fail_start; 1294 sc->sc_input = lagg_fail_input; 1295 sc->sc_port_create = NULL; 1296 sc->sc_port_destroy = NULL; 1297 1298 return (0); 1299} 1300 1301static int 1302lagg_fail_detach(struct lagg_softc *sc) 1303{ 1304 return (0); 1305} 1306 1307static int 1308lagg_fail_start(struct lagg_softc *sc, struct mbuf *m) 1309{ 1310 struct lagg_port *lp; 1311 1312 /* Use the master port if active or the next available port */ 1313 if ((lp = lagg_link_active(sc, sc->sc_primary)) == NULL) 1314 return (ENOENT); 1315 1316 /* Send mbuf */ 1317 return (lagg_enqueue(lp->lp_ifp, m)); 1318} 1319 1320static struct mbuf * 1321lagg_fail_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) 1322{ 1323 struct ifnet *ifp = sc->sc_ifp; 1324 struct lagg_port *tmp_tp; 1325 1326 if (lp == sc->sc_primary) { 1327 m->m_pkthdr.rcvif = ifp; 1328 return (m); 1329 } 1330 1331 if (sc->sc_primary->lp_link_state == LINK_STATE_DOWN) { 1332 tmp_tp = lagg_link_active(sc, NULL); 1333 /* 1334 * If tmp_tp is null, we've recieved a packet when all 1335 * our links are down. Weird, but process it anyways. 1336 */ 1337 if ((tmp_tp == NULL || tmp_tp == lp)) { 1338 m->m_pkthdr.rcvif = ifp; 1339 return (m); 1340 } 1341 } 1342 1343 m_freem(m); 1344 return (NULL); 1345} 1346 1347/* 1348 * Loadbalancing 1349 */ 1350 1351static int 1352lagg_lb_attach(struct lagg_softc *sc) 1353{ 1354 struct lagg_port *lp; 1355 struct lagg_lb *lb; 1356 1357 if ((lb = (struct lagg_lb *)malloc(sizeof(struct lagg_lb), 1358 M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) 1359 return (ENOMEM); 1360 1361 sc->sc_detach = lagg_lb_detach; 1362 sc->sc_start = lagg_lb_start; 1363 sc->sc_input = lagg_lb_input; 1364 sc->sc_port_create = lagg_lb_port_create; 1365 sc->sc_port_destroy = lagg_lb_port_destroy; 1366 sc->sc_capabilities = IFCAP_LAGG_FULLDUPLEX; 1367 1368 lb->lb_key = arc4random(); 1369 sc->sc_psc = (caddr_t)lb; 1370 1371 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1372 lagg_lb_port_create(lp); 1373 1374 return (0); 1375} 1376 1377static int 1378lagg_lb_detach(struct lagg_softc *sc) 1379{ 1380 struct lagg_lb *lb = (struct lagg_lb *)sc->sc_psc; 1381 if (lb != NULL) 1382 free(lb, M_DEVBUF); 1383 return (0); 1384} 1385 1386static int 1387lagg_lb_porttable(struct lagg_softc *sc, struct lagg_port *lp) 1388{ 1389 struct lagg_lb *lb = (struct lagg_lb *)sc->sc_psc; 1390 struct lagg_port *lp_next; 1391 int i = 0; 1392 1393 bzero(&lb->lb_ports, sizeof(lb->lb_ports)); 1394 SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) { 1395 if (lp_next == lp) 1396 continue; 1397 if (i >= LAGG_MAX_PORTS) 1398 return (EINVAL); 1399 if (sc->sc_ifflags & IFF_DEBUG) 1400 printf("%s: port %s at index %d\n", 1401 sc->sc_ifname, lp_next->lp_ifname, i); 1402 lb->lb_ports[i++] = lp_next; 1403 } 1404 1405 return (0); 1406} 1407 1408static int 1409lagg_lb_port_create(struct lagg_port *lp) 1410{ 1411 struct lagg_softc *sc = lp->lp_lagg; 1412 return (lagg_lb_porttable(sc, NULL)); 1413} 1414 1415static void 1416lagg_lb_port_destroy(struct lagg_port *lp) 1417{ 1418 struct lagg_softc *sc = lp->lp_lagg; 1419 lagg_lb_porttable(sc, lp); 1420} 1421 1422static int 1423lagg_lb_start(struct lagg_softc *sc, struct mbuf *m) 1424{ 1425 struct lagg_lb *lb = (struct lagg_lb *)sc->sc_psc; 1426 struct lagg_port *lp = NULL; 1427 uint32_t p = 0; 1428 int idx; 1429 1430 p = lagg_hashmbuf(m, lb->lb_key); 1431 if ((idx = p % sc->sc_count) >= LAGG_MAX_PORTS) 1432 return (EINVAL); 1433 lp = lb->lb_ports[idx]; 1434 1435 /* 1436 * Check the port's link state. This will return the next active 1437 * port if the link is down or the port is NULL. 1438 */ 1439 if ((lp = lagg_link_active(sc, lp)) == NULL) 1440 return (ENOENT); 1441 1442 /* Send mbuf */ 1443 return (lagg_enqueue(lp->lp_ifp, m)); 1444} 1445 1446static struct mbuf * 1447lagg_lb_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) 1448{ 1449 struct ifnet *ifp = sc->sc_ifp; 1450 1451 /* Just pass in the packet to our lagg device */ 1452 m->m_pkthdr.rcvif = ifp; 1453 1454 return (m); 1455} 1456 1457/* 1458 * 802.3ad LACP 1459 */ 1460 1461static int 1462lagg_lacp_attach(struct lagg_softc *sc) 1463{ 1464 struct lagg_port *lp; 1465 int error; 1466 1467 sc->sc_detach = lagg_lacp_detach; 1468 sc->sc_port_create = lacp_port_create; 1469 sc->sc_port_destroy = lacp_port_destroy; 1470 sc->sc_linkstate = lacp_linkstate; 1471 sc->sc_start = lagg_lacp_start; 1472 sc->sc_input = lagg_lacp_input; 1473 sc->sc_init = lacp_init; 1474 sc->sc_stop = lacp_stop; 1475 sc->sc_lladdr = lagg_lacp_lladdr; 1476 1477 error = lacp_attach(sc); 1478 if (error) 1479 return (error); 1480 1481 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1482 lacp_port_create(lp); 1483 1484 return (error); 1485} 1486 1487static int 1488lagg_lacp_detach(struct lagg_softc *sc) 1489{ 1490 struct lagg_port *lp; 1491 int error; 1492 1493 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1494 lacp_port_destroy(lp); 1495 1496 /* unlocking is safe here */ 1497 LAGG_UNLOCK(sc); 1498 error = lacp_detach(sc); 1499 LAGG_LOCK(sc); 1500 1501 return (error); 1502} 1503 1504static void 1505lagg_lacp_lladdr(struct lagg_softc *sc) 1506{ 1507 struct lagg_port *lp; 1508 1509 /* purge all the lacp ports */ 1510 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1511 lacp_port_destroy(lp); 1512 1513 /* add them back in */ 1514 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) 1515 lacp_port_create(lp); 1516} 1517 1518static int 1519lagg_lacp_start(struct lagg_softc *sc, struct mbuf *m) 1520{ 1521 struct lagg_port *lp; 1522 1523 lp = lacp_select_tx_port(sc, m); 1524 if (lp == NULL) 1525 return (EBUSY); 1526 1527 /* Send mbuf */ 1528 return (lagg_enqueue(lp->lp_ifp, m)); 1529} 1530 1531static struct mbuf * 1532lagg_lacp_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m) 1533{ 1534 struct ifnet *ifp = sc->sc_ifp; 1535 struct ether_header *eh; 1536 u_short etype; 1537 uint8_t subtype; 1538 1539 eh = mtod(m, struct ether_header *); 1540 etype = ntohs(eh->ether_type); 1541 1542 /* Tap off LACP control messages */ 1543 if (etype == ETHERTYPE_SLOW) { 1544 if (m->m_pkthdr.len < sizeof(*eh) + sizeof(subtype)) { 1545 m_freem(m); 1546 return (NULL); 1547 } 1548 1549 m_copydata(m, sizeof(*eh), sizeof(subtype), &subtype); 1550 switch (subtype) { 1551 case SLOWPROTOCOLS_SUBTYPE_LACP: 1552 lacp_input(lp, m); 1553 break; 1554 1555 case SLOWPROTOCOLS_SUBTYPE_MARKER: 1556 lacp_marker_input(lp, m); 1557 break; 1558 1559 default: 1560 /* Unknown LACP packet type */ 1561 m_freem(m); 1562 break; 1563 } 1564 return (NULL); 1565 } 1566 1567 /* 1568 * If the port is not collecting or not in the active aggregator then 1569 * free and return. 1570 */ 1571 if ((lp->lp_flags & LAGG_PORT_COLLECTING) == 0 || 1572 lacp_port_isactive(lp) == 0) { 1573 m_freem(m); 1574 return (NULL); 1575 } 1576 1577 m->m_pkthdr.rcvif = ifp; 1578 return (m); 1579} 1580