From 39df629ac8fc76e02292e1059ce3ecfced63a868 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Fri, 22 Mar 2019 12:40:39 -0700 Subject: [PATCH] pimd: add peerlink-rif to the origination-mroute's OIL In a PIM MLAG setup (say L11<->L12 is the anycast VTEP pair) the RP can choose to join either MLAG switch as the anycast VTEP-IP is present on both. Let's say the RP joins L11. Hosts are dual connected to L11<->L12 and can send traffic to either switch. Let's say a host sends broadcast traffic to L12; now L12 must encapsulate and send the traffic toward L11. To do that the origination-mroute on L12 must include the ISL in its OIL - (36.0.0.9, 239.1.1.100) Iif: peerlink-3.4094 Oifs: peerlink-3.4094 L11 has a similar mroute - (36.0.0.9, 239.1.1.100) Iif: peerlink-3.4094 Oifs: peerlink-3.4094 uplink-1 This mroute is used to rx traffic on peerlink-3.4094 and send it out of uplink-1. Note that this mroute also includes the peerlink-rif in its OIL. Explicit removal of IIF from OIL is done by the kernel (and other dataplanes) to prevent traffic looping. Signed-off-by: Anuradha Karuppiah --- pimd/pim_vxlan.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index f7e5ebec53..24b71bf3d8 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -226,6 +226,46 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg) pim_upstream_inherited_olist(vxlan_sg->pim, up); } +static void pim_vxlan_orig_mr_oif_add(struct pim_vxlan_sg *vxlan_sg) +{ + if (!vxlan_sg->up || !vxlan_sg->orig_oif) + return; + + if (PIM_DEBUG_VXLAN) + zlog_debug("vxlan SG %s oif %s add", + vxlan_sg->sg_str, vxlan_sg->orig_oif->name); + + vxlan_sg->flags |= PIM_VXLAN_SGF_OIF_INSTALLED; + pim_channel_add_oif(vxlan_sg->up->channel_oil, + vxlan_sg->orig_oif, PIM_OIF_FLAG_PROTO_VXLAN); +} + +static void pim_vxlan_orig_mr_oif_del(struct pim_vxlan_sg *vxlan_sg) +{ + struct interface *orig_oif; + + orig_oif = vxlan_sg->orig_oif; + vxlan_sg->orig_oif = NULL; + + if (!(vxlan_sg->flags & PIM_VXLAN_SGF_OIF_INSTALLED)) + return; + + if (PIM_DEBUG_VXLAN) + zlog_debug("vxlan SG %s oif %s del", + vxlan_sg->sg_str, orig_oif->name); + + vxlan_sg->flags &= ~PIM_VXLAN_SGF_OIF_INSTALLED; + pim_channel_del_oif(vxlan_sg->up->channel_oil, + orig_oif, PIM_OIF_FLAG_PROTO_VXLAN); +} + +static inline struct interface *pim_vxlan_orig_mr_oif_get( + struct pim_instance *pim) +{ + return (vxlan_mlag.flags & PIM_VXLAN_MLAGF_ENABLED) ? + pim->vxlan.peerlink_rif : NULL; +} + /* Single VTEPs: IIF for the vxlan-origination-mroutes is lo or vrf-dev (if * the mroute is in a non-default vrf). * Anycast VTEPs: IIF is the MLAG ISL/peerlink. @@ -256,6 +296,9 @@ static bool pim_vxlan_orig_mr_add_is_ok(struct pim_vxlan_sg *vxlan_sg) static void pim_vxlan_orig_mr_install(struct pim_vxlan_sg *vxlan_sg) { pim_vxlan_orig_mr_up_add(vxlan_sg); + + vxlan_sg->orig_oif = pim_vxlan_orig_mr_oif_get(vxlan_sg->pim); + pim_vxlan_orig_mr_oif_add(vxlan_sg); } static void pim_vxlan_orig_mr_add(struct pim_vxlan_sg *vxlan_sg) @@ -273,6 +316,8 @@ static void pim_vxlan_orig_mr_del(struct pim_vxlan_sg *vxlan_sg) { if (PIM_DEBUG_VXLAN) zlog_debug("vxlan SG %s orig-mr del", vxlan_sg->sg_str); + + pim_vxlan_orig_mr_oif_del(vxlan_sg); pim_vxlan_orig_mr_up_del(vxlan_sg); }