]> git.proxmox.com Git - mirror_frr.git/commitdiff
pimd: set mfcc_parent at the time of MFCC programming
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 15 Nov 2019 19:09:13 +0000 (11:09 -0800)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 15 Nov 2019 20:00:29 +0000 (12:00 -0800)
mfcc_parent for an (S, G) entry was being updated on any upstream RPF
change. With the change to use RPT for (S,G) in some cases we can no
longer do that. Instead the upstream entry's RPF neigbor is managed
separately form the channel_oil's mfcc_parent i.e. via NHT. And the
mfcc_parent is evaluated at the time of mroute programming.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
12 files changed:
pimd/pim_mroute.c
pimd/pim_mroute.h
pimd/pim_nht.c
pimd/pim_oil.c
pimd/pim_oil.h
pimd/pim_register.c
pimd/pim_rp.c
pimd/pim_rpf.c
pimd/pim_static.c
pimd/pim_upstream.c
pimd/pim_vxlan.c
pimd/pim_zebra.c

index c8e92025864c5822433c4e9bf38990a43a9da159..6fa95d4b6fab5b59163b5cc2a7244f3059c899fe 100644 (file)
@@ -231,12 +231,7 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
        // resolve mfcc_parent prior to mroute_add in channel_add_oif
        if (up->rpf.source_nexthop.interface &&
            up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
-               int vif_index = 0;
-               vif_index = pim_if_find_vifindex_by_ifindex(
-                       pim_ifp->pim,
-                       up->rpf.source_nexthop.interface->ifindex);
-               pim_channel_oil_change_iif(pim_ifp->pim, up->channel_oil,
-                                          vif_index, __PRETTY_FUNCTION__);
+               pim_upstream_mroute_iif_update(up->channel_oil, __func__);
        }
        pim_register_join(up);
 
@@ -969,13 +964,10 @@ static int pim_mroute_add(struct channel_oil *c_oil, const char *name)
        return 0;
 }
 
-/* In the case of "PIM state machine" added mroutes an upstream entry
- * must be present to decide on the SPT-forwarding vs. RPT-forwarding.
- */
-int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
+static int pim_upstream_get_mroute_iif(struct channel_oil *c_oil,
+               const char *name)
 {
        vifi_t iif = MAXVIFS;
-       char buf[1000];
        struct interface *ifp = NULL;
        struct pim_interface *pim_ifp;
        struct pim_upstream *up = c_oil->up;
@@ -993,15 +985,20 @@ int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
                                iif = pim_ifp->mroute_vif_index;
                }
        }
+       return iif;
+}
 
-       c_oil->oil.mfcc_parent = iif;
+static int pim_upstream_mroute_update(struct channel_oil *c_oil,
+               const char *name)
+{
+       char buf[1000];
 
        if (c_oil->oil.mfcc_parent >= MAXVIFS) {
                /* the c_oil cannot be installed as a mroute yet */
                if (PIM_DEBUG_MROUTE)
                        zlog_debug(
                                        "%s(%s) %s mroute not ready to be installed; %s",
-                                       __PRETTY_FUNCTION__, name,
+                                       __func__, name,
                                        pim_channel_oil_dump(c_oil, buf,
                                                sizeof(buf)),
                                        c_oil->installed ?
@@ -1018,11 +1015,60 @@ int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
        return pim_mroute_add(c_oil, name);
 }
 
+/* In the case of "PIM state machine" added mroutes an upstream entry
+ * must be present to decide on the SPT-forwarding vs. RPT-forwarding.
+ */
+int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
+{
+       c_oil->oil.mfcc_parent = pim_upstream_get_mroute_iif(c_oil, name);
+
+       return pim_upstream_mroute_update(c_oil, name);
+}
+
+/* Look for IIF changes and update the dateplane entry only if the IIF
+ * has changed.
+ */
+int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name)
+{
+       vifi_t iif;
+       char buf[1000];
+
+       iif = pim_upstream_get_mroute_iif(c_oil, name);
+       if (c_oil->oil.mfcc_parent == iif) {
+               /* no change */
+               return 0;
+       }
+       c_oil->oil.mfcc_parent = iif;
+
+       if (PIM_DEBUG_MROUTE_DETAIL)
+               zlog_debug("%s(%s) %s mroute iif update %d",
+                               __func__, name,
+                               pim_channel_oil_dump(c_oil, buf,
+                                       sizeof(buf)), iif);
+       /* XXX: is this hack needed? */
+       c_oil->oil_inherited_rescan = 1;
+       return pim_upstream_mroute_update(c_oil, name);
+}
+
 int pim_static_mroute_add(struct channel_oil *c_oil, const char *name)
 {
        return pim_mroute_add(c_oil, name);
 }
 
+void pim_static_mroute_iif_update(struct channel_oil *c_oil,
+                               int input_vif_index,
+                               const char *name)
+{
+       if (c_oil->oil.mfcc_parent == input_vif_index)
+               return;
+
+       c_oil->oil.mfcc_parent = input_vif_index;
+       if (input_vif_index == MAXVIFS)
+               pim_mroute_del(c_oil, name);
+       else
+               pim_static_mroute_add(c_oil, name);
+}
+
 int pim_mroute_del(struct channel_oil *c_oil, const char *name)
 {
        struct pim_instance *pim = c_oil->pim;
index 3f5468143295fef45c03016ae9822cddca9afc5e..eadd39eecef3ee48e001a407b34e4929489e87d2 100644 (file)
@@ -175,7 +175,11 @@ int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
 int pim_mroute_del_vif(struct interface *ifp);
 
 int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name);
+int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name);
 int pim_static_mroute_add(struct channel_oil *c_oil, const char *name);
+void pim_static_mroute_iif_update(struct channel_oil *c_oil,
+                               int input_vif_index,
+                               const char *name);
 int pim_mroute_del(struct channel_oil *c_oil, const char *name);
 
 void pim_mroute_update_counters(struct channel_oil *c_oil);
index 7900e392312571a7db1ac96f25fad89d7e24ee43..c4212ec10f01d9dc80e3fa55c4b783fac2e70d30 100644 (file)
@@ -441,7 +441,6 @@ static int pim_update_upstream_nh_helper(struct hash_bucket *bucket, void *arg)
 {
        struct pim_instance *pim = (struct pim_instance *)arg;
        struct pim_upstream *up = (struct pim_upstream *)bucket->data;
-       int vif_index = 0;
 
        enum pim_rpf_result rpf_result;
        struct pim_rpf old;
@@ -454,22 +453,7 @@ static int pim_update_upstream_nh_helper(struct hash_bucket *bucket, void *arg)
        }
 
        /* update kernel multicast forwarding cache (MFC) */
-       if (up->rpf.source_nexthop.interface) {
-               ifindex_t ifindex = up->rpf.source_nexthop.interface->ifindex;
-
-               vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
-               /* Pass Current selected NH vif index to mroute download
-                */
-               if (vif_index)
-                       pim_scan_individual_oil(up->channel_oil, vif_index);
-               else {
-                       if (PIM_DEBUG_PIM_NHT)
-                               zlog_debug(
-                                       "%s: NHT upstream %s channel_oil IIF %s vif_index is not valid",
-                                       __PRETTY_FUNCTION__, up->sg_str,
-                                       up->rpf.source_nexthop.interface->name);
-               }
-       }
+       pim_upstream_mroute_iif_update(up->channel_oil, __func__);
 
        if (rpf_result == PIM_RPF_CHANGED)
                pim_zebra_upstream_rpf_changed(pim, up, &old);
index 3e73e6cc8f29d4c94f1e7391c80b8cb55cd520db..979bc669fe99f0c3ebcc52cabbdbb033f36ec64c 100644 (file)
@@ -149,63 +149,14 @@ 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_upstream_mroute_add(c_oil, name);
-       } else
-               if (old_vif_index == MAXVIFS)
-                       pim_upstream_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)
+                                       const char *name)
 {
        struct channel_oil *c_oil;
-       struct interface *ifp;
 
        c_oil = pim_find_channel_oil(pim, sg);
        if (c_oil) {
-               if (c_oil->oil.mfcc_parent != input_vif_index) {
-                       c_oil->oil_inherited_rescan = 1;
-                       if (PIM_DEBUG_MROUTE_DETAIL)
-                               zlog_debug(
-                                       "%s: Existing channel oil %pSG4 points to %d, modifying to point at %d",
-                                       __PRETTY_FUNCTION__, sg,
-                                       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;
 
                if (!c_oil->up) {
@@ -219,6 +170,11 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
                        pim_channel_update_mute(c_oil);
                }
 
+               /* check if the IIF has changed
+                * XXX - is this really needed
+                */
+               pim_upstream_mroute_iif_update(c_oil, __func__);
+
                if (PIM_DEBUG_MROUTE)
                        zlog_debug(
                                "%s(%s): Existing oil for %pSG4 Ref Count: %d (Post Increment)",
@@ -227,23 +183,13 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
                return c_oil;
        }
 
-       if (input_vif_index != MAXVIFS) {
-               ifp = pim_if_find_by_vif_index(pim, input_vif_index);
-               if (!ifp) {
-                       /* warning only */
-                       zlog_warn(
-                               "%s:%s (S,G)=%pSG4 could not find input interface for input_vif_index=%d",
-                               __PRETTY_FUNCTION__, name, sg, input_vif_index);
-               }
-       }
-
        c_oil = XCALLOC(MTYPE_PIM_CHANNEL_OIL, sizeof(*c_oil));
 
        c_oil->oil.mfcc_mcastgrp = sg->grp;
        c_oil->oil.mfcc_origin = sg->src;
        c_oil = hash_get(pim->channel_oil_hash, c_oil, hash_alloc_intern);
 
-       c_oil->oil.mfcc_parent = input_vif_index;
+       c_oil->oil.mfcc_parent = MAXVIFS;
        c_oil->oil_ref_count = 1;
        c_oil->installed = 0;
        c_oil->up = pim_upstream_find(pim, sg);
@@ -252,9 +198,9 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
        listnode_add_sort(pim->channel_oil_list, c_oil);
 
        if (PIM_DEBUG_MROUTE)
-               zlog_debug(
-                       "%s(%s): New oil for %pSG4 vif_index: %d Ref Count: 1 (Post Increment)",
-                       __PRETTY_FUNCTION__, name, sg, input_vif_index);
+               zlog_debug("%s(%s): c_oil %s add",
+                               __func__, name, pim_str_sg_dump(sg));
+
        return c_oil;
 }
 
index 087f47121d2c3c8597f912a12d5f1c070fe813fc..20c94b65bc09c9f0d5590c5e0aa9958e9736e5b4 100644 (file)
@@ -116,7 +116,7 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
                                         struct prefix_sg *sg);
 struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
                                        struct prefix_sg *sg,
-                                       int input_vif_index, const char *name);
+                                       const char *name);
 void pim_channel_oil_change_iif(struct pim_instance *pim,
                                struct channel_oil *c_oil, int input_vif_index,
                                const char *name);
index ce23de314a16161d66c565f593ffaafb2bd1fe0b..3b48232391ceb999eaa522eb10fcefc07c918dea 100644 (file)
@@ -455,7 +455,6 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,
                    || ((SwitchToSptDesired(pim_ifp->pim, &sg))
                        && pim_upstream_inherited_olist(pim_ifp->pim, upstream)
                                   == 0)) {
-                       // pim_scan_individual_oil (upstream->channel_oil);
                        pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
                        sentRegisterStop = 1;
                } else {
index 3fa5760c5379ba0e924b3177a51d537253464bf2..9ccba37f10104c8bf55728aecd19f5e4ceb3493f 100644 (file)
@@ -386,20 +386,8 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
                pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
 
        /* update kernel multicast forwarding cache (MFC) */
-       if (up->rpf.source_nexthop.interface && up->channel_oil) {
-               ifindex_t ifindex = up->rpf.source_nexthop.interface->ifindex;
-               int vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
-               /* Pass Current selected NH vif index to mroute download */
-               if (vif_index)
-                       pim_scan_individual_oil(up->channel_oil, vif_index);
-               else {
-                       if (PIM_DEBUG_PIM_NHT)
-                               zlog_debug(
-                                 "%s: NHT upstream %s channel_oil IIF %s vif_index is not valid",
-                                 __PRETTY_FUNCTION__, up->sg_str,
-                                 up->rpf.source_nexthop.interface->name);
-               }
-       }
+       if (up->rpf.source_nexthop.interface && up->channel_oil)
+               pim_upstream_mroute_iif_update(up->channel_oil, __func__);
 
        if (rpf_result == PIM_RPF_CHANGED)
                pim_zebra_upstream_rpf_changed(pim, up, &old_rpf);
index d383ef5249454a2dda68c47449fc43fdb4f9c409..ebac4a4d6fae8ef22a4745b1b5352a2d2d5ea3b5 100644 (file)
@@ -307,11 +307,6 @@ void pim_upstream_rpf_clear(struct pim_instance *pim,
                            struct pim_upstream *up)
 {
        if (up->rpf.source_nexthop.interface) {
-               if (up->channel_oil)
-                       pim_channel_oil_change_iif(pim, up->channel_oil,
-                                                  MAXVIFS,
-                                                  __PRETTY_FUNCTION__);
-
                pim_upstream_switch(pim, up, PIM_UPSTREAM_NOTJOINED);
                up->rpf.source_nexthop.interface = NULL;
                up->rpf.source_nexthop.mrib_nexthop_addr.u.prefix4.s_addr =
@@ -321,6 +316,7 @@ void pim_upstream_rpf_clear(struct pim_instance *pim,
                up->rpf.source_nexthop.mrib_route_metric =
                        router->infinite_assert_metric.route_metric;
                up->rpf.rpf_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY;
+               pim_upstream_mroute_iif_update(up->channel_oil, __func__);
        }
 }
 
index be2321dc33155d4eb4cc2c16128b437c534c51d4..7b121c9136bbc2708251ab1609c145f6ef1d5c18 100644 (file)
@@ -138,7 +138,7 @@ int pim_static_add(struct pim_instance *pim, struct interface *iif,
                        } else {
                                /* input interface changed */
                                s_route->iif = iif_index;
-                               pim_channel_oil_change_iif(pim, &s_route->c_oil,
+                               pim_static_mroute_iif_update(&s_route->c_oil,
                                                           iif_index,
                                                           __PRETTY_FUNCTION__);
 
index e9382be33fc9b3d4822433353c62709ad069391f..ee9fece51c358e3cdc2d2f451157e564d7ae07b3 100644 (file)
@@ -788,7 +788,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
        up->reg_state = PIM_REG_NOINFO;
        up->state_transition = pim_time_monotonic_sec();
        up->channel_oil =
-               pim_channel_oil_add(pim, &up->sg, MAXVIFS, __PRETTY_FUNCTION__);
+               pim_channel_oil_add(pim, &up->sg, __PRETTY_FUNCTION__);
        up->sptbit = PIM_UPSTREAM_SPTBIT_FALSE;
 
        up->rpf.source_nexthop.interface = NULL;
@@ -813,9 +813,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
                pim_upstream_fill_static_iif(up, incoming);
                pim_ifp = up->rpf.source_nexthop.interface->info;
                assert(pim_ifp);
-               pim_channel_oil_change_iif(pim, up->channel_oil,
-                                          pim_ifp->mroute_vif_index,
-                                          __PRETTY_FUNCTION__);
+               pim_upstream_mroute_iif_update(up->channel_oil, __func__);
 
                if (PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(up->flags))
                        pim_upstream_keep_alive_timer_start(
@@ -832,10 +830,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
                if (up->rpf.source_nexthop.interface) {
                        pim_ifp = up->rpf.source_nexthop.interface->info;
                        if (pim_ifp)
-                               pim_channel_oil_change_iif(
-                                       pim, up->channel_oil,
-                                       pim_ifp->mroute_vif_index,
-                                       __PRETTY_FUNCTION__);
+                               pim_upstream_mroute_iif_update(up->channel_oil,
+                                               __func__);
                }
                pim_upstream_update_use_rpt(up,
                                false /*update_mroute*/);
index daec0951c3f8a9d21599b9b578aa6784a65c4ee8..1a0c4a91cdfd824b7a3d607d9d1a87d360f928f2 100644 (file)
@@ -251,20 +251,14 @@ static void pim_vxlan_orig_mr_up_del(struct pim_vxlan_sg *vxlan_sg)
 
 static void pim_vxlan_orig_mr_up_iif_update(struct pim_vxlan_sg *vxlan_sg)
 {
-       int vif_index;
-
        /* update MFC with the new IIF */
        pim_upstream_fill_static_iif(vxlan_sg->up, vxlan_sg->iif);
-       vif_index = pim_if_find_vifindex_by_ifindex(vxlan_sg->pim,
-                       vxlan_sg->iif->ifindex);
-       if (vif_index > 0)
-               pim_scan_individual_oil(vxlan_sg->up->channel_oil,
-                               vif_index);
+       pim_upstream_mroute_iif_update(vxlan_sg->up->channel_oil, __func__);
 
        if (PIM_DEBUG_VXLAN)
-               zlog_debug("vxlan SG %s orig mroute-up updated with iif %s vifi %d",
+               zlog_debug("vxlan SG %s orig mroute-up updated with iif %s",
                        vxlan_sg->sg_str,
-                       vxlan_sg->iif?vxlan_sg->iif->name:"-", vif_index);
+                       vxlan_sg->iif?vxlan_sg->iif->name:"-");
 
 }
 
index 9b1261976daf2542487a40d6872749ea7103485d..b6847a273a14d8c752fdfe7081451777c0119053 100644 (file)
@@ -386,137 +386,17 @@ static void pim_zebra_vxlan_replay(void)
        zclient_send_message(zclient);
 }
 
-void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
-{
-       struct in_addr vif_source;
-       int input_iface_vif_index;
-
-       pim_rp_set_upstream_addr(c_oil->pim, &vif_source,
-                                     c_oil->oil.mfcc_origin,
-                                     c_oil->oil.mfcc_mcastgrp);
-
-       if (in_vif_index)
-               input_iface_vif_index = in_vif_index;
-       else {
-               struct prefix src, grp;
-
-               src.family = AF_INET;
-               src.prefixlen = IPV4_MAX_BITLEN;
-               src.u.prefix4 = vif_source;
-               grp.family = AF_INET;
-               grp.prefixlen = IPV4_MAX_BITLEN;
-               grp.u.prefix4 = c_oil->oil.mfcc_mcastgrp;
-
-               if (PIM_DEBUG_ZEBRA) {
-                       char source_str[INET_ADDRSTRLEN];
-                       char group_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
-                                      source_str, sizeof(source_str));
-                       pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
-                                      group_str, sizeof(group_str));
-                       zlog_debug(
-                               "%s: channel_oil (%s,%s) upstream info is not present.",
-                               __PRETTY_FUNCTION__, source_str, group_str);
-               }
-               input_iface_vif_index = pim_ecmp_fib_lookup_if_vif_index(
-                       c_oil->pim, &src, &grp);
-       }
-
-       if (input_iface_vif_index < 1) {
-               if (PIM_DEBUG_ZEBRA) {
-                       char source_str[INET_ADDRSTRLEN];
-                       char group_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
-                                      source_str, sizeof(source_str));
-                       pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
-                                      group_str, sizeof(group_str));
-                       zlog_debug(
-                               "%s %s: could not find input interface(%d) for (S,G)=(%s,%s)",
-                               __FILE__, __PRETTY_FUNCTION__,
-                               c_oil->oil.mfcc_parent, source_str, group_str);
-               }
-               pim_mroute_del(c_oil, __PRETTY_FUNCTION__);
-               return;
-       }
-
-       if (input_iface_vif_index == c_oil->oil.mfcc_parent) {
-               if (!c_oil->installed)
-                       pim_upstream_mroute_add(c_oil, __PRETTY_FUNCTION__);
-
-               /* RPF unchanged */
-               return;
-       }
-
-       if (PIM_DEBUG_ZEBRA) {
-               struct interface *old_iif = pim_if_find_by_vif_index(
-                       c_oil->pim, c_oil->oil.mfcc_parent);
-               struct interface *new_iif = pim_if_find_by_vif_index(
-                       c_oil->pim, input_iface_vif_index);
-               char source_str[INET_ADDRSTRLEN];
-               char group_str[INET_ADDRSTRLEN];
-               pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin, source_str,
-                              sizeof(source_str));
-               pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp, group_str,
-                              sizeof(group_str));
-               zlog_debug(
-                       "%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
-                       __FILE__, __PRETTY_FUNCTION__, source_str, group_str,
-                       (old_iif) ? old_iif->name : "<old_iif?>",
-                       c_oil->oil.mfcc_parent,
-                       (new_iif) ? new_iif->name : "<new_iif?>",
-                       input_iface_vif_index);
-       }
-
-       /* new iif loops to existing oif ? */
-       if (c_oil->oil.mfcc_ttls[input_iface_vif_index]) {
-               struct interface *new_iif = pim_if_find_by_vif_index(
-                       c_oil->pim, input_iface_vif_index);
-
-               if (PIM_DEBUG_ZEBRA) {
-                       char source_str[INET_ADDRSTRLEN];
-                       char group_str[INET_ADDRSTRLEN];
-                       pim_inet4_dump("<source?>", c_oil->oil.mfcc_origin,
-                                      source_str, sizeof(source_str));
-                       pim_inet4_dump("<group?>", c_oil->oil.mfcc_mcastgrp,
-                                      group_str, sizeof(group_str));
-                       zlog_debug(
-                               "%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
-                               __FILE__, __PRETTY_FUNCTION__, source_str,
-                               group_str,
-                               (new_iif) ? new_iif->name : "<new_iif?>",
-                               input_iface_vif_index);
-               }
-       }
-
-       /* update iif vif_index */
-       pim_channel_oil_change_iif(c_oil->pim, c_oil, input_iface_vif_index,
-                                  __PRETTY_FUNCTION__);
-       pim_upstream_mroute_add(c_oil, __PRETTY_FUNCTION__);
-}
-
 void pim_scan_oil(struct pim_instance *pim)
 {
        struct listnode *node;
        struct listnode *nextnode;
        struct channel_oil *c_oil;
-       ifindex_t ifindex;
-       int vif_index = 0;
 
        pim->scan_oil_last = pim_time_monotonic_sec();
        ++pim->scan_oil_events;
 
        for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode, c_oil)) {
-               if (c_oil->up && c_oil->up->rpf.source_nexthop.interface) {
-                       ifindex = c_oil->up->rpf.source_nexthop
-                                         .interface->ifindex;
-                       vif_index =
-                               pim_if_find_vifindex_by_ifindex(pim, ifindex);
-                       /* Pass Current selected NH vif index to mroute
-                        * download */
-                       if (vif_index)
-                               pim_scan_individual_oil(c_oil, vif_index);
-               } else
-                       pim_scan_individual_oil(c_oil, 0);
+               pim_upstream_mroute_iif_update(c_oil, __func__);
        }
 }
 
@@ -755,7 +635,7 @@ void igmp_source_forward_start(struct pim_instance *pim,
                                              source->source_addr, sg.grp)) {
                        /*Create a dummy channel oil */
                        source->source_channel_oil = pim_channel_oil_add(
-                               pim, &sg, MAXVIFS, __PRETTY_FUNCTION__);
+                               pim, &sg, __PRETTY_FUNCTION__);
                }
 
                else {
@@ -806,7 +686,7 @@ void igmp_source_forward_start(struct pim_instance *pim,
                                }
                                source->source_channel_oil =
                                        pim_channel_oil_add(
-                                               pim, &sg, MAXVIFS,
+                                               pim, &sg,
                                                __PRETTY_FUNCTION__);
                        }
 
@@ -840,7 +720,7 @@ void igmp_source_forward_start(struct pim_instance *pim,
 
                                source->source_channel_oil =
                                        pim_channel_oil_add(
-                                               pim, &sg, input_iface_vif_index,
+                                               pim, &sg,
                                                __PRETTY_FUNCTION__);
                                if (!source->source_channel_oil) {
                                        if (PIM_DEBUG_IGMP_TRACE) {