- Move L2 addr configuration for the primary port to a taskqueue. This fixes
LOR of softc rmlock in iflladdr_event handlers. - Call if_delmulti_ifma() after LACP_UNLOCK(). This fixes another LOR. - Fix a panic in lacp_transit_expire(). - Fix a panic in lagg_input() upon shutting down a port.
This commit is contained in:
parent
25108069ec
commit
6d47816791
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272547
@ -579,12 +579,13 @@ lacp_port_destroy(struct lagg_port *lgp)
|
||||
lacp_disable_distributing(lp);
|
||||
lacp_unselect(lp);
|
||||
|
||||
LIST_REMOVE(lp, lp_next);
|
||||
LACP_UNLOCK(lsc);
|
||||
|
||||
/* The address may have already been removed by if_purgemaddrs() */
|
||||
if (!lgp->lp_detaching)
|
||||
if_delmulti_ifma(lp->lp_ifma);
|
||||
|
||||
LIST_REMOVE(lp, lp_next);
|
||||
LACP_UNLOCK(lsc);
|
||||
free(lp, M_DEVBUF);
|
||||
}
|
||||
|
||||
@ -745,7 +746,9 @@ lacp_transit_expire(void *vp)
|
||||
|
||||
LACP_LOCK_ASSERT(lsc);
|
||||
|
||||
CURVNET_SET(lsc->lsc_softc->sc_ifp->if_vnet);
|
||||
LACP_TRACE(NULL);
|
||||
CURVNET_RESTORE();
|
||||
|
||||
lsc->lsc_suppress_distributing = FALSE;
|
||||
}
|
||||
|
@ -569,15 +569,15 @@ lagg_clone_destroy(struct ifnet *ifp)
|
||||
static void
|
||||
lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr)
|
||||
{
|
||||
struct ifnet *ifp = sc->sc_ifp;
|
||||
struct lagg_port lp;
|
||||
|
||||
if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
|
||||
return;
|
||||
LAGG_WLOCK_ASSERT(sc);
|
||||
|
||||
bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN);
|
||||
/* Let the protocol know the MAC has changed */
|
||||
lagg_proto_lladdr(sc);
|
||||
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
|
||||
bzero(&lp, sizeof(lp));
|
||||
lp.lp_ifp = sc->sc_ifp;
|
||||
lp.lp_softc = sc;
|
||||
|
||||
lagg_port_lladdr(&lp, lladdr);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -648,6 +648,7 @@ lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
|
||||
|
||||
/* Update the lladdr even if pending, it may have changed */
|
||||
llq->llq_ifp = ifp;
|
||||
llq->llq_primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
|
||||
bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
|
||||
|
||||
if (!pending)
|
||||
@ -680,14 +681,35 @@ lagg_port_setlladdr(void *arg, int pending)
|
||||
for (llq = head; llq != NULL; llq = head) {
|
||||
ifp = llq->llq_ifp;
|
||||
|
||||
/* Set the link layer address */
|
||||
CURVNET_SET(ifp->if_vnet);
|
||||
error = if_setlladdr(ifp, llq->llq_lladdr, ETHER_ADDR_LEN);
|
||||
if (llq->llq_primary == 0) {
|
||||
/*
|
||||
* Set the link layer address on the laggport interface.
|
||||
* if_setlladdr() triggers gratuitous ARPs for INET.
|
||||
*/
|
||||
error = if_setlladdr(ifp, llq->llq_lladdr,
|
||||
ETHER_ADDR_LEN);
|
||||
if (error)
|
||||
printf("%s: setlladdr failed on %s\n", __func__,
|
||||
ifp->if_xname);
|
||||
} else {
|
||||
/*
|
||||
* Set the link layer address on the lagg interface.
|
||||
* lagg_proto_lladdr() notifies the MAC change to
|
||||
* the aggregation protocol. iflladdr_event handler
|
||||
* may trigger gratuitous ARPs for INET.
|
||||
*/
|
||||
if (memcmp(llq->llq_lladdr, IF_LLADDR(ifp),
|
||||
ETHER_ADDR_LEN) != 0) {
|
||||
bcopy(llq->llq_lladdr, IF_LLADDR(ifp),
|
||||
ETHER_ADDR_LEN);
|
||||
LAGG_WLOCK(sc);
|
||||
lagg_proto_lladdr(sc);
|
||||
LAGG_WUNLOCK(sc);
|
||||
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
|
||||
}
|
||||
}
|
||||
CURVNET_RESTORE();
|
||||
if (error)
|
||||
printf("%s: setlladdr failed on %s\n", __func__,
|
||||
ifp->if_xname);
|
||||
|
||||
head = SLIST_NEXT(llq, llq_entries);
|
||||
free(llq, M_DEVBUF);
|
||||
}
|
||||
@ -1639,7 +1661,7 @@ lagg_input(struct ifnet *ifp, struct mbuf *m)
|
||||
|
||||
ETHER_BPF_MTAP(scifp, m);
|
||||
|
||||
m = lagg_proto_input(sc, lp, m);
|
||||
m = (lp->lp_detaching == 0) ? lagg_proto_input(sc, lp, m) : NULL;
|
||||
|
||||
if (m != NULL) {
|
||||
if (scifp->if_flags & IFF_MONITOR) {
|
||||
|
@ -159,6 +159,9 @@ struct lagg_reqopts {
|
||||
#define SIOCGLAGGOPTS _IOWR('i', 152, struct lagg_reqopts)
|
||||
#define SIOCSLAGGOPTS _IOW('i', 153, struct lagg_reqopts)
|
||||
|
||||
#define LAGG_OPT_BITS "\020\001USE_FLOWID\005LACP_STRICT" \
|
||||
"\006LACP_TXTEST\007LACP_RXTEST"
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
@ -203,6 +206,7 @@ struct lagg_mc {
|
||||
struct lagg_llq {
|
||||
struct ifnet *llq_ifp;
|
||||
uint8_t llq_lladdr[ETHER_ADDR_LEN];
|
||||
uint8_t llq_primary;
|
||||
SLIST_ENTRY(lagg_llq) llq_entries;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user