]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: inherit MLAG DF role from the parent (*, G) entry
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Thu, 6 Feb 2020 17:30:40 +0000 (09:30 -0800)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 14 Feb 2020 17:18:30 +0000 (09:18 -0800)
DF election is only run for (*,G) entries i.e. election is skipped
for (S,G) entries that are setup as a result of SPT switchover. (S,G)
entries inherit the DF role from the parent (*,G) entry. So the DF is
responsible for terminating all sources associated with a group.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
pimd/pim_upstream.c
pimd/pim_vxlan.c
pimd/pim_vxlan.h

index 2d3a44b646662f70ff3d9398c80270a5c0a51018..8f7e1741e730d297fa286a50a8c7d8474558d8f9 100644 (file)
@@ -194,6 +194,9 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
                zlog_debug("pim_upstream free vrf:%s %s flags 0x%x",
                           pim->vrf->name, up->sg_str, up->flags);
 
+       if (pim_up_mlag_is_local(up))
+               pim_mlag_up_local_del(pim, up);
+
        THREAD_OFF(up->t_ka_timer);
        THREAD_OFF(up->t_rs_timer);
        THREAD_OFF(up->t_msdp_reg_timer);
@@ -884,6 +887,18 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
                }
        }
 
+       /* If (S, G) inherit the MLAG_VXLAN from the parent
+        * (*, G) entry.
+        */
+       if ((up->sg.src.s_addr != INADDR_ANY) &&
+               up->parent &&
+               PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(up->parent->flags)) {
+               PIM_UPSTREAM_FLAG_SET_MLAG_VXLAN(up->flags);
+               if (PIM_DEBUG_VXLAN)
+                       zlog_debug("upstream %s inherited mlag vxlan flag from parent",
+                                       up->sg_str);
+       }
+
        /* send the entry to the MLAG peer */
        /* XXX - duplicate send is possible here if pim_rpf_update
         * successfully resolved the nexthop
index f1f5c81c00bce636efc08ca9fe161364d03c0980..58d988e9200731a648207595dc015344356cc13d 100644 (file)
@@ -551,6 +551,37 @@ static void pim_vxlan_term_mr_oif_del(struct pim_vxlan_sg *vxlan_sg)
        pim_ifchannel_local_membership_del(vxlan_sg->term_oif, &vxlan_sg->sg);
 }
 
+static void pim_vxlan_update_sg_entry_mlag(struct pim_instance *pim,
+               struct pim_upstream *up, bool inherit)
+{
+       bool is_df = true;
+
+       if (inherit && up->parent &&
+                       PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(up->parent->flags) &&
+                       PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->parent->flags))
+               is_df = false;
+
+       pim_mlag_up_df_role_update(pim, up, is_df, "inherit_xg_df");
+}
+
+/* We run MLAG DF election only on mroutes that have the termination
+ * device ipmr-lo in the immediate OIL. This is only (*, G) entries at the
+ * moment. For (S, G) entries that (with ipmr-lo in the inherited OIL) we
+ * inherit the DF role from the (*, G) entry.
+ */
+void pim_vxlan_inherit_mlag_flags(struct pim_instance *pim,
+               struct pim_upstream *up, bool inherit)
+{
+       struct listnode *listnode;
+       struct pim_upstream *child;
+
+       for (ALL_LIST_ELEMENTS_RO(up->sources, listnode,
+                               child)) {
+               pim_vxlan_update_sg_entry_mlag(pim,
+                               child, true /* inherit */);
+       }
+}
+
 static void pim_vxlan_term_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
 {
        struct pim_upstream *up;
@@ -577,7 +608,11 @@ static void pim_vxlan_term_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
        if (!up) {
                zlog_warn("vxlan SG %s term mroute-up add failed",
                        vxlan_sg->sg_str);
+               return;
        }
+
+       /* update existing SG entries with the parent's MLAG flag */
+       pim_vxlan_inherit_mlag_flags(vxlan_sg->pim, up, true /*enable*/);
 }
 
 static void pim_vxlan_term_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
@@ -592,6 +627,9 @@ static void pim_vxlan_term_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
                        vxlan_sg->sg_str);
        vxlan_sg->up = NULL;
        if (up->flags & PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM) {
+               /* update SG entries that are inheriting from this XG entry */
+               pim_vxlan_inherit_mlag_flags(vxlan_sg->pim, up,
+                               false /*enable*/);
                /* clear out all the vxlan related flags */
                up->flags &= ~(PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM |
                        PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN);
index 4495dca6d787de42d7a1c450b64fd133b216cf54..7adba2eee2d029f348a69a504b42522aaf4e62f0 100644 (file)
@@ -139,5 +139,7 @@ extern void pim_vxlan_mlag_update(bool enable, bool peer_state, uint32_t role,
                                struct interface *peerlink_rif,
                                struct in_addr *reg_addr);
 extern bool pim_vxlan_do_mlag_reg(void);
+extern void pim_vxlan_inherit_mlag_flags(struct pim_instance *pim,
+               struct pim_upstream *up, bool inherit);
 
 #endif /* PIM_VXLAN_H */