aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_carp.c
diff options
context:
space:
mode:
authorLuiz Otavio O Souza <loos@FreeBSD.org>2017-01-25 19:04:08 +0000
committerLuiz Otavio O Souza <loos@FreeBSD.org>2017-01-25 19:04:08 +0000
commit338e227ac0b27dd8ab7138e6f0c12105076195c6 (patch)
tree9a2a9e13efba20d937b18d29ec1a9c3aa0960e84 /sys/netinet/ip_carp.c
parent72dc1ba904078a24b3c1676748fe79ad37c7a54b (diff)
downloadsrc-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.c7
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);
}