]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: remove pim and igmp OIFs when ifchannel_delete happens
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 7 Jun 2019 17:17:39 +0000 (10:17 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sat, 22 Jun 2019 18:02:14 +0000 (14:02 -0400)
In a pim-evpn setup (say TORC11<=>TORC12) an mroute can have a mix of
PIM and IGMP joins. The vxlan termination device ipmr-lo is IGMP
joined on termination mroutes and the peerlink-rif can be pim joined
on the same mroute if the MLAG peer (TORC11) loses all its uplinks to
underlay -
root@TORC12:~# net show pim state 239.1.1.101|grep pimreg
1         *                239.1.1.101      uplink-1
             pimreg(I    ), ipmr-lo( J   ), peerlink-3.4094( J   )
root@TORC12:~#

When the uplinks come back up on TORC11 it will prune the peerlink-rif
and join the RP (say spine) via the uplinks.

TORC12 is rxing the prune and removing the if_channel
(pim_ifchannel_delete). However it is not removing the OIF from
mfcc_ttl basically leaving behind a leaked OIF in the forwarding
entry. And this is because it is deriving the owner flag from the
parent upstream entry and incorrectly concluding that all OIFs are
IGMP joined.

Thix fix flushes out both PIM and IGMP ownership when the ifchannel is
deleted.

There is a second fix in the commit and that is to set the proto mask
correctly (to STAR) for inherited OIFs. (S,G) entries can inherit the
OIF from the (*, G) entry and this decision can change when the pim/igmp
ifchannel is removed. The earlier code was setting the proto-mask
incorrectly to PIM or IGMP.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
(cherry picked from commit d4d1d968dbbe61347393f7dace8b675496ff1024)

pimd/pim_ifchannel.c

index 8f6c68f055b7f9e70106f033b8ea66f2b5fe1fa2..15bdf6ee6eedbdefaa228fec78988402b8799322 100644 (file)
@@ -133,7 +133,7 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
        if (ch->upstream->channel_oil) {
                uint32_t mask = PIM_OIF_FLAG_PROTO_PIM;
                if (ch->upstream->flags & PIM_UPSTREAM_FLAG_MASK_SRC_IGMP)
-                       mask = PIM_OIF_FLAG_PROTO_IGMP;
+                       mask |= PIM_OIF_FLAG_PROTO_IGMP;
 
                /*
                 * A S,G RPT channel can have an empty oil, we also
@@ -142,13 +142,15 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
                 * being inherited.  So let's figure out what
                 * needs to be done here
                 */
-               if (pim_upstream_evaluate_join_desired_interface(
-                           ch->upstream, ch, ch->parent))
+               if ((ch->sg.src.s_addr != INADDR_ANY) &&
+                               pim_upstream_evaluate_join_desired_interface(
+                                       ch->upstream, ch, ch->parent))
                        pim_channel_add_oif(ch->upstream->channel_oil,
-                                           ch->interface, mask);
-               else
-                       pim_channel_del_oif(ch->upstream->channel_oil,
-                                           ch->interface, mask);
+                                       ch->interface,
+                                       PIM_OIF_FLAG_PROTO_STAR);
+
+               pim_channel_del_oif(ch->upstream->channel_oil,
+                                       ch->interface, mask);
                /*
                 * Do we have any S,G's that are inheriting?
                 * Nuke from on high too.