From 95586137e6662f9cdeede87dc75e70ab70877360 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Thu, 6 Feb 2020 09:30:40 -0800 Subject: [PATCH] pimd: inherit MLAG DF role from the parent (*, G) entry 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 --- pimd/pim_upstream.c | 15 +++++++++++++++ pimd/pim_vxlan.c | 38 ++++++++++++++++++++++++++++++++++++++ pimd/pim_vxlan.h | 2 ++ 3 files changed, 55 insertions(+) diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 2d3a44b646..8f7e1741e7 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -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 diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index f1f5c81c00..58d988e920 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -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); diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h index 4495dca6d7..7adba2eee2 100644 --- a/pimd/pim_vxlan.h +++ b/pimd/pim_vxlan.h @@ -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 */ -- 2.39.5