]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_oil.c
Merge pull request #5288 from SumitAgarwal123/bfd_docs
[mirror_frr.git] / pimd / pim_oil.c
index 307a1760d9e7dedee43c53378607dcd16c7884f0..d14293491663d98e4ca19df1c41530021a69d6de 100644 (file)
@@ -146,6 +146,43 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
        return c_oil;
 }
 
+void pim_channel_oil_change_iif(struct pim_instance *pim,
+                               struct channel_oil *c_oil,
+                               int input_vif_index,
+                               const char *name)
+{
+       int old_vif_index = c_oil->oil.mfcc_parent;
+       struct prefix_sg sg = {.src = c_oil->oil.mfcc_mcastgrp,
+                              .grp = c_oil->oil.mfcc_origin};
+
+       if (c_oil->oil.mfcc_parent == input_vif_index) {
+               if (PIM_DEBUG_MROUTE_DETAIL)
+                       zlog_debug("%s(%s): Existing channel oil %pSG4 already using %d as IIF",
+                                  __PRETTY_FUNCTION__, name, &sg,
+                                  input_vif_index);
+
+               return;
+       }
+
+       if (PIM_DEBUG_MROUTE_DETAIL)
+               zlog_debug("%s(%s): Changing channel oil %pSG4 IIF from %d to %d installed: %d",
+                          __PRETTY_FUNCTION__, name, &sg,
+                          c_oil->oil.mfcc_parent, input_vif_index,
+                          c_oil->installed);
+
+       c_oil->oil.mfcc_parent = input_vif_index;
+       if (c_oil->installed) {
+               if (input_vif_index == MAXVIFS)
+                       pim_mroute_del(c_oil, name);
+               else
+                       pim_mroute_add(c_oil, name);
+       } else
+               if (old_vif_index == MAXVIFS)
+                       pim_mroute_add(c_oil, name);
+
+       return;
+}
+
 struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
                                        struct prefix_sg *sg,
                                        int input_vif_index, const char *name)
@@ -164,7 +201,8 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
                                        c_oil->oil.mfcc_parent,
                                        input_vif_index);
                }
-               c_oil->oil.mfcc_parent = input_vif_index;
+               pim_channel_oil_change_iif(pim, c_oil, input_vif_index,
+                                          name);
                ++c_oil->oil_ref_count;
                /* channel might be present prior to upstream */
                c_oil->up = pim_upstream_find(pim, sg);
@@ -364,10 +402,12 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
          IGMP must be protected against adding looped MFC entries created
          by both source and receiver attached to the same interface. See
          TODO T22.
+         We shall allow igmp to create upstream when it is DR for the intf.
+         Assume RP reachable via non DR.
        */
-       if (channel_oil->up &&
-                       PIM_UPSTREAM_FLAG_TEST_ALLOW_IIF_IN_OIL(
-                               channel_oil->up->flags)) {
+       if ((channel_oil->up &&
+           PIM_UPSTREAM_FLAG_TEST_ALLOW_IIF_IN_OIL(channel_oil->up->flags)) ||
+           ((proto_mask == PIM_OIF_FLAG_PROTO_IGMP) && PIM_I_am_DR(pim_ifp))) {
                allow_iif_in_oil = true;
        }