Changeset View
Changeset View
Standalone View
Standalone View
head/sys/net/if_lagg.c
Show First 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | |||||
static int lagg_clone_create(struct if_clone *, int, caddr_t); | static int lagg_clone_create(struct if_clone *, int, caddr_t); | ||||
static void lagg_clone_destroy(struct ifnet *); | static void lagg_clone_destroy(struct ifnet *); | ||||
static VNET_DEFINE(struct if_clone *, lagg_cloner); | static VNET_DEFINE(struct if_clone *, lagg_cloner); | ||||
#define V_lagg_cloner VNET(lagg_cloner) | #define V_lagg_cloner VNET(lagg_cloner) | ||||
static const char laggname[] = "lagg"; | static const char laggname[] = "lagg"; | ||||
static void lagg_lladdr(struct lagg_softc *, uint8_t *); | static void lagg_lladdr(struct lagg_softc *, uint8_t *); | ||||
static void lagg_capabilities(struct lagg_softc *); | static void lagg_capabilities(struct lagg_softc *); | ||||
static void lagg_port_lladdr(struct lagg_port *, uint8_t *); | static void lagg_port_lladdr(struct lagg_port *, uint8_t *, lagg_llqtype); | ||||
static void lagg_port_setlladdr(void *, int); | static void lagg_port_setlladdr(void *, int); | ||||
static int lagg_port_create(struct lagg_softc *, struct ifnet *); | static int lagg_port_create(struct lagg_softc *, struct ifnet *); | ||||
static int lagg_port_destroy(struct lagg_port *, int); | static int lagg_port_destroy(struct lagg_port *, int); | ||||
static struct mbuf *lagg_input(struct ifnet *, struct mbuf *); | static struct mbuf *lagg_input(struct ifnet *, struct mbuf *); | ||||
static void lagg_linkstate(struct lagg_softc *); | static void lagg_linkstate(struct lagg_softc *); | ||||
static void lagg_port_state(struct ifnet *, int); | static void lagg_port_state(struct ifnet *, int); | ||||
static int lagg_port_ioctl(struct ifnet *, u_long, caddr_t); | static int lagg_port_ioctl(struct ifnet *, u_long, caddr_t); | ||||
static int lagg_port_output(struct ifnet *, struct mbuf *, | static int lagg_port_output(struct ifnet *, struct mbuf *, | ||||
▲ Show 20 Lines • Show All 426 Lines • ▼ Show 20 Lines | lagg_clone_destroy(struct ifnet *ifp) | ||||
EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach); | EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach); | ||||
EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach); | EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach); | ||||
/* Shutdown and remove lagg ports */ | /* Shutdown and remove lagg ports */ | ||||
while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) | while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) | ||||
lagg_port_destroy(lp, 1); | lagg_port_destroy(lp, 1); | ||||
/* Unhook the aggregation protocol */ | /* Unhook the aggregation protocol */ | ||||
lagg_proto_detach(sc); | lagg_proto_detach(sc); | ||||
LAGG_UNLOCK_ASSERT(sc); | |||||
ifmedia_removeall(&sc->sc_media); | ifmedia_removeall(&sc->sc_media); | ||||
ether_ifdetach(ifp); | ether_ifdetach(ifp); | ||||
if_free(ifp); | if_free(ifp); | ||||
LAGG_LIST_LOCK(); | LAGG_LIST_LOCK(); | ||||
SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries); | SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries); | ||||
LAGG_LIST_UNLOCK(); | LAGG_LIST_UNLOCK(); | ||||
taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task); | taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task); | ||||
LAGG_LOCK_DESTROY(sc); | LAGG_LOCK_DESTROY(sc); | ||||
free(sc, M_DEVBUF); | free(sc, M_DEVBUF); | ||||
} | } | ||||
static void | /* | ||||
* Set link-layer address on the lagg interface itself. | |||||
* | |||||
* Set noinline to be dtrace-friendly | |||||
*/ | |||||
static __noinline void | |||||
lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr) | lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr) | ||||
{ | { | ||||
struct ifnet *ifp = sc->sc_ifp; | struct ifnet *ifp = sc->sc_ifp; | ||||
struct lagg_port lp; | struct lagg_port lp; | ||||
if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0) | if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0) | ||||
return; | return; | ||||
LAGG_WLOCK_ASSERT(sc); | LAGG_WLOCK_ASSERT(sc); | ||||
/* | /* | ||||
* Set the link layer address on the lagg interface. | * Set the link layer address on the lagg interface. | ||||
* lagg_proto_lladdr() notifies the MAC change to | * lagg_proto_lladdr() notifies the MAC change to | ||||
* the aggregation protocol. iflladdr_event handler which | * the aggregation protocol. iflladdr_event handler which | ||||
* may trigger gratuitous ARPs for INET will be handled in | * may trigger gratuitous ARPs for INET will be handled in | ||||
* a taskqueue. | * a taskqueue. | ||||
*/ | */ | ||||
bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN); | bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN); | ||||
lagg_proto_lladdr(sc); | lagg_proto_lladdr(sc); | ||||
/* | |||||
* Send notification request for lagg interface | |||||
* itself. Note that new lladdr is already set. | |||||
*/ | |||||
bzero(&lp, sizeof(lp)); | bzero(&lp, sizeof(lp)); | ||||
lp.lp_ifp = sc->sc_ifp; | lp.lp_ifp = sc->sc_ifp; | ||||
lp.lp_softc = sc; | lp.lp_softc = sc; | ||||
lagg_port_lladdr(&lp, lladdr); | /* Do not request lladdr change */ | ||||
lagg_port_lladdr(&lp, lladdr, LAGG_LLQTYPE_VIRT); | |||||
} | } | ||||
static void | static void | ||||
lagg_capabilities(struct lagg_softc *sc) | lagg_capabilities(struct lagg_softc *sc) | ||||
{ | { | ||||
struct lagg_port *lp; | struct lagg_port *lp; | ||||
int cap = ~0, ena = ~0; | int cap = ~0, ena = ~0; | ||||
u_long hwa = ~0UL; | u_long hwa = ~0UL; | ||||
Show All 24 Lines | if (sc->sc_ifp->if_capabilities != cap || | ||||
getmicrotime(&sc->sc_ifp->if_lastchange); | getmicrotime(&sc->sc_ifp->if_lastchange); | ||||
if (sc->sc_ifflags & IFF_DEBUG) | if (sc->sc_ifflags & IFF_DEBUG) | ||||
if_printf(sc->sc_ifp, | if_printf(sc->sc_ifp, | ||||
"capabilities 0x%08x enabled 0x%08x\n", cap, ena); | "capabilities 0x%08x enabled 0x%08x\n", cap, ena); | ||||
} | } | ||||
} | } | ||||
static void | /* | ||||
lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr) | * Enqueue interface lladdr notification. | ||||
* If request is already queued, it is updated. | |||||
* If setting lladdr is also desired, @do_change has to be set to 1. | |||||
* | |||||
* Set noinline to be dtrace-friendly | |||||
*/ | |||||
static __noinline void | |||||
lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr, lagg_llqtype llq_type) | |||||
{ | { | ||||
struct lagg_softc *sc = lp->lp_softc; | struct lagg_softc *sc = lp->lp_softc; | ||||
struct ifnet *ifp = lp->lp_ifp; | struct ifnet *ifp = lp->lp_ifp; | ||||
struct lagg_llq *llq; | struct lagg_llq *llq; | ||||
int pending = 0; | |||||
int primary; | |||||
LAGG_WLOCK_ASSERT(sc); | LAGG_WLOCK_ASSERT(sc); | ||||
primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0; | /* | ||||
if (primary == 0 && (lp->lp_detaching || | * Do not enqueue requests where lladdr is the same for | ||||
memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)) | * "physical" interfaces (e.g. ports in lagg) | ||||
*/ | |||||
if (llq_type == LAGG_LLQTYPE_PHYS && | |||||
memcmp(IF_LLADDR(ifp), lladdr, ETHER_ADDR_LEN) == 0) | |||||
return; | return; | ||||
/* Check to make sure its not already queued to be changed */ | /* Check to make sure its not already queued to be changed */ | ||||
SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { | SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { | ||||
if (llq->llq_ifp == ifp && llq->llq_primary == primary) { | if (llq->llq_ifp == ifp) { | ||||
pending = 1; | /* Update lladdr, it may have changed */ | ||||
break; | bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN); | ||||
return; | |||||
} | } | ||||
} | } | ||||
if (!pending) { | llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT | M_ZERO); | ||||
llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT); | |||||
if (llq == NULL) /* XXX what to do */ | if (llq == NULL) /* XXX what to do */ | ||||
return; | return; | ||||
} | |||||
/* Update the lladdr even if pending, it may have changed */ | |||||
llq->llq_ifp = ifp; | llq->llq_ifp = ifp; | ||||
llq->llq_primary = primary; | llq->llq_type = llq_type; | ||||
bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN); | bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN); | ||||
/* XXX: We should insert to tail */ | |||||
if (!pending) | |||||
SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries); | SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries); | ||||
taskqueue_enqueue(taskqueue_swi, &sc->sc_lladdr_task); | taskqueue_enqueue(taskqueue_swi, &sc->sc_lladdr_task); | ||||
} | } | ||||
/* | /* | ||||
* Set the interface MAC address from a taskqueue to avoid a LOR. | * Set the interface MAC address from a taskqueue to avoid a LOR. | ||||
* | |||||
* Set noinline to be dtrace-friendly | |||||
*/ | */ | ||||
static void | static __noinline void | ||||
lagg_port_setlladdr(void *arg, int pending) | lagg_port_setlladdr(void *arg, int pending) | ||||
{ | { | ||||
struct lagg_softc *sc = (struct lagg_softc *)arg; | struct lagg_softc *sc = (struct lagg_softc *)arg; | ||||
struct lagg_llq *llq, *head; | struct lagg_llq *llq, *head; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
int error; | int error; | ||||
/* Grab a local reference of the queue and remove it from the softc */ | /* Grab a local reference of the queue and remove it from the softc */ | ||||
LAGG_WLOCK(sc); | LAGG_WLOCK(sc); | ||||
head = SLIST_FIRST(&sc->sc_llq_head); | head = SLIST_FIRST(&sc->sc_llq_head); | ||||
SLIST_FIRST(&sc->sc_llq_head) = NULL; | SLIST_FIRST(&sc->sc_llq_head) = NULL; | ||||
LAGG_WUNLOCK(sc); | LAGG_WUNLOCK(sc); | ||||
/* | /* | ||||
* Traverse the queue and set the lladdr on each ifp. It is safe to do | * Traverse the queue and set the lladdr on each ifp. It is safe to do | ||||
* unlocked as we have the only reference to it. | * unlocked as we have the only reference to it. | ||||
*/ | */ | ||||
for (llq = head; llq != NULL; llq = head) { | for (llq = head; llq != NULL; llq = head) { | ||||
ifp = llq->llq_ifp; | ifp = llq->llq_ifp; | ||||
CURVNET_SET(ifp->if_vnet); | CURVNET_SET(ifp->if_vnet); | ||||
if (llq->llq_primary == 0) { | error = 0; | ||||
/* | /* | ||||
* Set the link layer address on the laggport interface. | * Set the link layer address on the laggport interface. | ||||
* if_setlladdr() triggers gratuitous ARPs for INET. | * Note that if_setlladdr() or iflladdr_event handler | ||||
* may result in arp transmission / lltable updates. | |||||
*/ | */ | ||||
if (llq->llq_type == LAGG_LLQTYPE_PHYS) | |||||
error = if_setlladdr(ifp, llq->llq_lladdr, | error = if_setlladdr(ifp, llq->llq_lladdr, | ||||
ETHER_ADDR_LEN); | ETHER_ADDR_LEN); | ||||
if (error) | if (error) | ||||
printf("%s: setlladdr failed on %s\n", __func__, | printf("%s: setlladdr failed on %s\n", __func__, | ||||
ifp->if_xname); | ifp->if_xname); | ||||
} else | else | ||||
EVENTHANDLER_INVOKE(iflladdr_event, ifp); | EVENTHANDLER_INVOKE(iflladdr_event, ifp); | ||||
CURVNET_RESTORE(); | CURVNET_RESTORE(); | ||||
head = SLIST_NEXT(llq, llq_entries); | head = SLIST_NEXT(llq, llq_entries); | ||||
free(llq, M_DEVBUF); | free(llq, M_DEVBUF); | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
Show All 15 Lines | if (ifp->if_lagg != NULL) { | ||||
/* Port is already in the current lagg? */ | /* Port is already in the current lagg? */ | ||||
lp = (struct lagg_port *)ifp->if_lagg; | lp = (struct lagg_port *)ifp->if_lagg; | ||||
if (lp->lp_softc == sc) | if (lp->lp_softc == sc) | ||||
return (EEXIST); | return (EEXIST); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
/* XXX Disallow non-ethernet interfaces (this should be any of 802) */ | /* XXX Disallow non-ethernet interfaces (this should be any of 802) */ | ||||
if (ifp->if_type != IFT_ETHER) | if (ifp->if_type != IFT_ETHER && ifp->if_type != IFT_L2VLAN) | ||||
return (EPROTONOSUPPORT); | return (EPROTONOSUPPORT); | ||||
/* Allow the first Ethernet member to define the MTU */ | /* Allow the first Ethernet member to define the MTU */ | ||||
if (SLIST_EMPTY(&sc->sc_ports)) | if (SLIST_EMPTY(&sc->sc_ports)) | ||||
sc->sc_ifp->if_mtu = ifp->if_mtu; | sc->sc_ifp->if_mtu = ifp->if_mtu; | ||||
else if (sc->sc_ifp->if_mtu != ifp->if_mtu) { | else if (sc->sc_ifp->if_mtu != ifp->if_mtu) { | ||||
if_printf(sc->sc_ifp, "invalid MTU for %s\n", | if_printf(sc->sc_ifp, "invalid MTU for %s\n", | ||||
ifp->if_xname); | ifp->if_xname); | ||||
Show All 37 Lines | #endif | ||||
lp->lp_ifp = ifp; | lp->lp_ifp = ifp; | ||||
lp->lp_softc = sc; | lp->lp_softc = sc; | ||||
/* Save port link layer address */ | /* Save port link layer address */ | ||||
bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN); | bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN); | ||||
if (SLIST_EMPTY(&sc->sc_ports)) { | if (SLIST_EMPTY(&sc->sc_ports)) { | ||||
sc->sc_primary = lp; | sc->sc_primary = lp; | ||||
/* First port in lagg. Update/notify lagg lladdress */ | |||||
lagg_lladdr(sc, IF_LLADDR(ifp)); | lagg_lladdr(sc, IF_LLADDR(ifp)); | ||||
} else { | } else { | ||||
/* Update link layer address for this port */ | |||||
lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp)); | /* | ||||
* Update link layer address for this port and | |||||
* send notifications to other subsystems. | |||||
*/ | |||||
lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp), LAGG_LLQTYPE_PHYS); | |||||
} | } | ||||
/* | /* | ||||
* Insert into the list of ports. | * Insert into the list of ports. | ||||
* Keep ports sorted by if_index. It is handy, when configuration | * Keep ports sorted by if_index. It is handy, when configuration | ||||
* is predictable and `ifconfig laggN create ...` command | * is predictable and `ifconfig laggN create ...` command | ||||
* will lead to the same result each time. | * will lead to the same result each time. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | lagg_port_destroy(struct lagg_port *lp, int rundelport) | ||||
/* | /* | ||||
* Remove multicast addresses and interface flags from this port and | * Remove multicast addresses and interface flags from this port and | ||||
* reset the MAC address, skip if the interface is being detached. | * reset the MAC address, skip if the interface is being detached. | ||||
*/ | */ | ||||
if (!lp->lp_detaching) { | if (!lp->lp_detaching) { | ||||
lagg_ether_cmdmulti(lp, 0); | lagg_ether_cmdmulti(lp, 0); | ||||
lagg_setflags(lp, 0); | lagg_setflags(lp, 0); | ||||
lagg_port_lladdr(lp, lp->lp_lladdr); | lagg_port_lladdr(lp, lp->lp_lladdr, LAGG_LLQTYPE_PHYS); | ||||
} | } | ||||
/* Restore interface */ | /* Restore interface */ | ||||
ifp->if_type = lp->lp_iftype; | ifp->if_type = lp->lp_iftype; | ||||
ifp->if_ioctl = lp->lp_ioctl; | ifp->if_ioctl = lp->lp_ioctl; | ||||
ifp->if_output = lp->lp_output; | ifp->if_output = lp->lp_output; | ||||
ifp->if_lagg = NULL; | ifp->if_lagg = NULL; | ||||
Show All 15 Lines | if (lp == sc->sc_primary) { | ||||
if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL) { | if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL) { | ||||
bzero(&lladdr, ETHER_ADDR_LEN); | bzero(&lladdr, ETHER_ADDR_LEN); | ||||
} else { | } else { | ||||
bcopy(lp0->lp_lladdr, | bcopy(lp0->lp_lladdr, | ||||
lladdr, ETHER_ADDR_LEN); | lladdr, ETHER_ADDR_LEN); | ||||
} | } | ||||
lagg_lladdr(sc, lladdr); | lagg_lladdr(sc, lladdr); | ||||
/* Mark lp0 as new primary */ | |||||
sc->sc_primary = lp0; | |||||
/* | /* | ||||
* Update link layer address for each port. No port is | * Enqueue lladdr update/notification for each port | ||||
* marked as primary at this moment. | * (new primary needs update as well, to switch from | ||||
* old lladdr to its 'real' one). | |||||
*/ | */ | ||||
SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries) | SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries) | ||||
lagg_port_lladdr(lp_ptr, lladdr); | lagg_port_lladdr(lp_ptr, lladdr, LAGG_LLQTYPE_PHYS); | ||||
/* | |||||
* Mark lp0 as the new primary. This invokes an | |||||
* iflladdr_event. | |||||
*/ | |||||
sc->sc_primary = lp0; | |||||
if (lp0 != NULL) | |||||
lagg_port_lladdr(lp0, lladdr); | |||||
} | } | ||||
/* Remove any pending lladdr changes from the queue */ | /* Remove any pending lladdr changes from the queue */ | ||||
if (lp->lp_detaching) { | if (lp->lp_detaching) { | ||||
SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { | SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { | ||||
if (llq->llq_ifp == ifp) { | if (llq->llq_ifp == ifp) { | ||||
SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq, | SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq, | ||||
llq_entries); | llq_entries); | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | lagg_port2req(struct lagg_port *lp, struct lagg_reqport *rp) | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
lagg_init(void *xsc) | lagg_init(void *xsc) | ||||
{ | { | ||||
struct lagg_softc *sc = (struct lagg_softc *)xsc; | struct lagg_softc *sc = (struct lagg_softc *)xsc; | ||||
struct lagg_port *lp; | |||||
struct ifnet *ifp = sc->sc_ifp; | struct ifnet *ifp = sc->sc_ifp; | ||||
struct lagg_port *lp; | |||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) | if (ifp->if_drv_flags & IFF_DRV_RUNNING) | ||||
return; | return; | ||||
LAGG_WLOCK(sc); | LAGG_WLOCK(sc); | ||||
ifp->if_drv_flags |= IFF_DRV_RUNNING; | ifp->if_drv_flags |= IFF_DRV_RUNNING; | ||||
/* Update the port lladdrs */ | |||||
/* | |||||
* Update the port lladdrs if needed. | |||||
* This might be if_setlladdr() notification | |||||
* that lladdr has been changed. | |||||
*/ | |||||
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) | SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) | ||||
lagg_port_lladdr(lp, IF_LLADDR(ifp)); | lagg_port_lladdr(lp, IF_LLADDR(ifp), LAGG_LLQTYPE_PHYS); | ||||
lagg_proto_init(sc); | lagg_proto_init(sc); | ||||
LAGG_WUNLOCK(sc); | LAGG_WUNLOCK(sc); | ||||
} | } | ||||
static void | static void | ||||
lagg_stop(struct lagg_softc *sc) | lagg_stop(struct lagg_softc *sc) | ||||
▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | if (error) | ||||
break; | break; | ||||
if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) { | if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) { | ||||
error = EPROTONOSUPPORT; | error = EPROTONOSUPPORT; | ||||
break; | break; | ||||
} | } | ||||
LAGG_WLOCK(sc); | LAGG_WLOCK(sc); | ||||
lagg_proto_detach(sc); | lagg_proto_detach(sc); | ||||
LAGG_UNLOCK_ASSERT(sc); | |||||
lagg_proto_attach(sc, ra->ra_proto); | lagg_proto_attach(sc, ra->ra_proto); | ||||
break; | break; | ||||
case SIOCGLAGGOPTS: | case SIOCGLAGGOPTS: | ||||
ro->ro_opts = sc->sc_opts; | ro->ro_opts = sc->sc_opts; | ||||
if (sc->sc_proto == LAGG_PROTO_LACP) { | if (sc->sc_proto == LAGG_PROTO_LACP) { | ||||
struct lacp_softc *lsc; | struct lacp_softc *lsc; | ||||
lsc = (struct lacp_softc *)sc->sc_psc; | lsc = (struct lacp_softc *)sc->sc_psc; | ||||
▲ Show 20 Lines • Show All 941 Lines • Show Last 20 Lines |