Hi, This patch fixes the carp mode 'balancing ip-stealth'.
Problem: System A carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:00:5e:00:01:01 description: Carp-intern index 7 priority 15 llprio 3 carp: carpdev vio2 advbase 1 balancing ip-stealth state MASTER vhid 1 advskew 0 state BACKUP vhid 2 advskew 100 System B carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:00:5e:00:01:01 description: Carp-intern index 7 priority 15 llprio 3 carp: carpdev vio2 advbase 1 balancing ip-stealth state BACKUP vhid 1 advskew 100 state MASTER vhid 2 advskew 0 System B was setting the if_link_state to LINK_STATE_DOWN because vhid 1 was in state BACKUP. The cloning routes were missing the RTF_UP flag then. We musst set the link state UP if at least one vhid is in state MASTER. Please note that carp 'balancing ip' (non-stealth-mode) is still broken. My next patch will address this problem. Regards friehm Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.309 diff -u -p -r1.309 ip_carp.c --- netinet/ip_carp.c 4 May 2017 17:58:46 -0000 1.309 +++ netinet/ip_carp.c 27 May 2017 08:11:22 -0000 @@ -2362,6 +2362,7 @@ carp_set_state(struct carp_vhost_entry * struct carp_softc *sc = vhe->parent_sc; static const char *carp_states[] = { CARP_STATES }; int loglevel; + struct carp_vhost_entry *vhe0; KASSERT(vhe->state != state); @@ -2382,20 +2383,20 @@ carp_set_state(struct carp_vhost_entry * vhe->state = state; carp_update_lsmask(sc); - /* only the master vhe creates link state messages */ - if (!vhe->vhe_leader) - return; - - switch (state) { - case BACKUP: - sc->sc_if.if_link_state = LINK_STATE_DOWN; - break; - case MASTER: - sc->sc_if.if_link_state = LINK_STATE_UP; - break; - default: - sc->sc_if.if_link_state = LINK_STATE_INVALID; - break; + KERNEL_ASSERT_LOCKED(); /* touching carp_vhosts */ + + sc->sc_if.if_link_state = LINK_STATE_INVALID; + SRPL_FOREACH_LOCKED(vhe0, &sc->carp_vhosts, vhost_entries) { + /* + * Link must be up if at least one vhe is in state MASTER to + * bring or keep route up. + */ + if (vhe0->state == MASTER) { + sc->sc_if.if_link_state = LINK_STATE_UP; + break; + } else if (vhe0->state == BACKUP) { + sc->sc_if.if_link_state = LINK_STATE_DOWN; + } } if_link_state_change(&sc->sc_if); }