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);
 }

Reply via email to