]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: add peerlink-rif to the origination-mroute's OIL
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 22 Mar 2019 19:40:39 +0000 (12:40 -0700)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Sat, 20 Apr 2019 15:33:22 +0000 (08:33 -0700)
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 <anuradhak@cumulusnetworks.com>
pimd/pim_vxlan.c

index f7e5ebec5334a1ebf031ada1d233ad337f581397..24b71bf3d838b1155b656b528db9c083d54444aa 100644 (file)
@@ -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);
 }