diff options
author | Luiz Souza <luiz@netgate.com> | 2018-03-14 18:42:42 -0300 |
---|---|---|
committer | Luiz Souza <luiz@netgate.com> | 2018-03-14 19:05:46 -0300 |
commit | 1a95a7d50c513231cf5cc2d374f7babd09f03d2b (patch) | |
tree | de90ebb575065a004793c0545fcbe6f00de6f0e8 | |
parent | 851221bfbf64757933cfb7b818301961f6aa79b8 (diff) | |
download | FreeBSD-src-1a95a7d50c513231cf5cc2d374f7babd09f03d2b.zip FreeBSD-src-1a95a7d50c513231cf5cc2d374f7babd09f03d2b.tar.gz |
Avoid a deadlock when CARP is used with if_bridge.
As if_bridge calls carp_forus() with the bridge lock held, there is a race where a carp callout can trigger just before the call to carp_forus() and, with the CARP lock held, will now wait for the bridge lock while the next call to carp_forus() is trying to acquire the CARP lock with the bridge lock held.
Ticket: #8056
(cherry picked from commit ab6cc9dd898d6ecb61a8758547ebb0916fe2dfb7)
-rw-r--r-- | sys/netinet/ip_carp.c | 3 |
1 files changed, 0 insertions, 3 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 86e6a10..ac948e0 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1126,14 +1126,11 @@ carp_forus(struct ifnet *ifp, u_char *dhost) CIF_LOCK(ifp->if_carp); IFNET_FOREACH_CARP(ifp, sc) { - CARP_LOCK(sc); if (sc->sc_state == MASTER && !bcmp(dhost, LLADDR(&sc->sc_addr), ETHER_ADDR_LEN)) { - CARP_UNLOCK(sc); CIF_UNLOCK(ifp->if_carp); return (1); } - CARP_UNLOCK(sc); } CIF_UNLOCK(ifp->if_carp); |