diff options
author | Luiz Otavio O Souza <loos@FreeBSD.org> | 2017-01-25 19:04:08 +0000 |
---|---|---|
committer | Luiz Otavio O Souza <loos@FreeBSD.org> | 2017-01-25 19:04:08 +0000 |
commit | 338e227ac0b27dd8ab7138e6f0c12105076195c6 (patch) | |
tree | 9a2a9e13efba20d937b18d29ec1a9c3aa0960e84 /sys/netinet/ip_carp.c | |
parent | 72dc1ba904078a24b3c1676748fe79ad37c7a54b (diff) | |
download | src-338e227ac0b27dd8ab7138e6f0c12105076195c6.tar.gz src-338e227ac0b27dd8ab7138e6f0c12105076195c6.zip |
After the in_control() changes in r257692, an existing address is
(intentionally) deleted first and then completely added again (so all the
events, announces and hooks are given a chance to run).
This cause an issue with CARP where the existing CARP data structure is
removed together with the last address for a given VHID, which will cause
a subsequent fail when the address is later re-added.
This change fixes this issue by adding a new flag to keep the CARP data
structure when an address is not being removed.
There was an additional issue with IPv6 CARP addresses, where the CARP data
structure would never be removed after a change and lead to VHIDs which
cannot be destroyed.
Reviewed by: glebius
Obtained from: pfSense
MFC after: 2 weeks
Sponsored by: Rubicon Communications, LLC (Netgate)
Notes
Notes:
svn path=/head/; revision=312770
Diffstat (limited to 'sys/netinet/ip_carp.c')
-rw-r--r-- | sys/netinet/ip_carp.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 0a5fed782951..b84df2396082 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1969,7 +1969,7 @@ carp_attach(struct ifaddr *ifa, int vhid) } void -carp_detach(struct ifaddr *ifa) +carp_detach(struct ifaddr *ifa, bool keep_cif) { struct ifnet *ifp = ifa->ifa_ifp; struct carp_if *cif = ifp->if_carp; @@ -2015,12 +2015,13 @@ carp_detach(struct ifaddr *ifa) carp_hmac_prepare(sc); carp_sc_state(sc); - if (sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) + if (!keep_cif && sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) carp_destroy(sc); else CARP_UNLOCK(sc); - CIF_FREE(cif); + if (!keep_cif) + CIF_FREE(cif); sx_xunlock(&carp_sx); } |