]> git.proxmox.com Git - mirror_frr.git/commitdiff
pimd: decide between SPT based and RPT based forwarding
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 15 Nov 2019 18:40:00 +0000 (10:40 -0800)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Fri, 15 Nov 2019 20:00:29 +0000 (12:00 -0800)
An (S,G) mroute can be created as a result of rpt prune. However that
entry needs to stay on the parent (*,G)'s tree (IIF) till a decision is
made to switch the source to the SPT.

The decision to stay on the RPT is made based on the SPTbit setting
according to - RFC7761, Section 4.2 “Data Packet Forwarding Rules”

However those rules are hard to achieve when hw acceleration i.e.
control and data planes are separate. So instead of relying on data
we make the decision of using SPT if we have decided to join the SPT -
Use_RPT(S,G) {
    if (Joined(S,G) == TRUE          // we have decided to join the SPT
            OR Directly_Connected(S) == TRUE // source is directly connected
            OR I_am_RP(G) == TRUE)   // RP
        //use_spt
        return FALSE;
    //use_rpt
    return TRUE;
}

To make that change some re-org was needed -
1. pim static mroutes and dynamic (upstream mroutes) top level APIs
have been separated. This is to limit the state machine to dynamic
mroutes.
2. c_oil->oil.mfcc_parent is re-evaluated based on if we decided
to use the SPT or stay on the RPT.
3. upstream mroute re-eval is done when any of the criteria involved
in Use_RPT changes.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
pimd/pim_mroute.c
pimd/pim_mroute.h
pimd/pim_oil.c
pimd/pim_static.c
pimd/pim_upstream.c
pimd/pim_upstream.h
pimd/pim_vxlan.c
pimd/pim_zebra.c

index f28d801f0bed9f17b91b47cbd87ba21296fa7dd3..c8e92025864c5822433c4e9bf38990a43a9da159 100644 (file)
@@ -207,7 +207,7 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
                up = pim_upstream_find_or_add(
                        &sg, ifp, PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE,
                        __PRETTY_FUNCTION__);
-               pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
+               pim_upstream_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
 
                return 0;
        }
@@ -228,7 +228,6 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
        pim_upstream_keep_alive_timer_start(up, pim_ifp->pim->keep_alive_time);
 
        up->channel_oil->cc.pktcnt++;
-       PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
        // resolve mfcc_parent prior to mroute_add in channel_add_oif
        if (up->rpf.source_nexthop.interface &&
            up->channel_oil->oil.mfcc_parent >= MAXVIFS) {
@@ -518,7 +517,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
 
                        pim_upstream_inherited_olist(pim_ifp->pim, up);
                        if (!up->channel_oil->installed)
-                               pim_mroute_add(up->channel_oil,
+                               pim_upstream_mroute_add(up->channel_oil,
                                               __PRETTY_FUNCTION__);
                } else {
                        if (I_am_RP(pim_ifp->pim, up->sg.grp)) {
@@ -557,6 +556,8 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
                up->channel_oil->cc.pktcnt++;
                pim_register_join(up);
                pim_upstream_inherited_olist(pim_ifp->pim, up);
+               if (!up->channel_oil->installed)
+                       pim_upstream_mroute_add(up->channel_oil, __func__);
 
                // Send the packet to the RP
                pim_mroute_msg_wholepkt(fd, ifp, buf);
@@ -565,7 +566,8 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,
                                      PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE,
                                      __PRETTY_FUNCTION__, NULL);
                if (!up->channel_oil->installed)
-                       pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
+                       pim_upstream_mroute_add(up->channel_oil,
+                                       __PRETTY_FUNCTION__);
        }
 
        return 0;
@@ -899,7 +901,10 @@ static inline void pim_mroute_copy(struct mfcctl *oil,
        }
 }
 
-int pim_mroute_add(struct channel_oil *c_oil, const char *name)
+/* This function must not be called directly 0
+ * use pim_upstream_mroute_add or pim_static_mroute_add instead
+ */
+static int pim_mroute_add(struct channel_oil *c_oil, const char *name)
 {
        struct pim_instance *pim = c_oil->pim;
        struct mfcctl tmp_oil;
@@ -908,18 +913,6 @@ int pim_mroute_add(struct channel_oil *c_oil, const char *name)
        pim->mroute_add_last = pim_time_monotonic_sec();
        ++pim->mroute_add_events;
 
-       /* Do not install route if incoming interface is undefined. */
-       if (c_oil->oil.mfcc_parent >= MAXVIFS) {
-               if (PIM_DEBUG_MROUTE) {
-                       char buf[1000];
-                       zlog_debug(
-                               "%s(%s) %s Attempting to add vifi that is invalid to mroute table",
-                               __PRETTY_FUNCTION__, name,
-                               pim_channel_oil_dump(c_oil, buf, sizeof(buf)));
-               }
-               return -2;
-       }
-
        /* Copy the oil to a temporary structure to fixup (without need to
         * later restore) before sending the mroute add to the dataplane
         */
@@ -976,6 +969,60 @@ 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)
+{
+       vifi_t iif = MAXVIFS;
+       char buf[1000];
+       struct interface *ifp = NULL;
+       struct pim_interface *pim_ifp;
+       struct pim_upstream *up = c_oil->up;
+
+       if (up) {
+               if (PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags)) {
+                       if (up->parent)
+                               ifp = up->parent->rpf.source_nexthop.interface;
+               } else {
+                       ifp = up->rpf.source_nexthop.interface;
+               }
+               if (ifp) {
+                       pim_ifp = (struct pim_interface *)ifp->info;
+                       if (pim_ifp)
+                               iif = pim_ifp->mroute_vif_index;
+               }
+       }
+
+       c_oil->oil.mfcc_parent = iif;
+
+       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,
+                                       pim_channel_oil_dump(c_oil, buf,
+                                               sizeof(buf)),
+                                       c_oil->installed ?
+                                       "uninstall" : "skip");
+               /* if already installed flush it out as we are going to stop
+                * updates to it leaving it in a stale state
+                */
+               if (c_oil->installed)
+                       pim_mroute_del(c_oil, name);
+               /* return success (skipped) */
+               return 0;
+       }
+
+       return pim_mroute_add(c_oil, name);
+}
+
+int pim_static_mroute_add(struct channel_oil *c_oil, const char *name)
+{
+       return pim_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 bd71acbf82cab506d7e05a161ea575585f0d4c63..3f5468143295fef45c03016ae9822cddca9afc5e 100644 (file)
@@ -174,7 +174,8 @@ int pim_mroute_add_vif(struct interface *ifp, struct in_addr ifaddr,
                       unsigned char flags);
 int pim_mroute_del_vif(struct interface *ifp);
 
-int pim_mroute_add(struct channel_oil *c_oil, const char *name);
+int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name);
+int pim_static_mroute_add(struct channel_oil *c_oil, 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 8933245de190a82d144ee8a085a3f131a5cdfe8d..3e73e6cc8f29d4c94f1e7391c80b8cb55cd520db 100644 (file)
@@ -178,10 +178,10 @@ void pim_channel_oil_change_iif(struct pim_instance *pim,
                if (input_vif_index == MAXVIFS)
                        pim_mroute_del(c_oil, name);
                else
-                       pim_mroute_add(c_oil, name);
+                       pim_upstream_mroute_add(c_oil, name);
        } else
                if (old_vif_index == MAXVIFS)
-                       pim_mroute_add(c_oil, name);
+                       pim_upstream_mroute_add(c_oil, name);
 
        return;
 }
@@ -368,7 +368,7 @@ int pim_channel_del_oif(struct channel_oil *channel_oil, struct interface *oif,
        /* clear mute; will be re-evaluated when the OIF becomes valid again */
        channel_oil->oif_flags[pim_ifp->mroute_vif_index] &= ~PIM_OIF_FLAG_MUTE;
 
-       if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
+       if (pim_upstream_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
                if (PIM_DEBUG_MROUTE) {
                        char group_str[INET_ADDRSTRLEN];
                        char source_str[INET_ADDRSTRLEN];
@@ -475,7 +475,7 @@ void pim_channel_update_oif_mute(struct channel_oil *c_oil,
                c_oil->oif_flags[pim_ifp->mroute_vif_index] &=
                        ~PIM_OIF_FLAG_MUTE;
 
-       pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
+       pim_upstream_mroute_add(c_oil, __PRETTY_FUNCTION__);
 }
 
 /* pim_upstream has been set or cleared on the c_oil. re-eval mute state
@@ -654,7 +654,7 @@ int pim_channel_add_oif(struct channel_oil *channel_oil, struct interface *oif,
         * valid to get installed in kernel.
         */
        if (channel_oil->oil.mfcc_parent != MAXVIFS) {
-               if (pim_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
+               if (pim_upstream_mroute_add(channel_oil, __PRETTY_FUNCTION__)) {
                        if (PIM_DEBUG_MROUTE) {
                                char group_str[INET_ADDRSTRLEN];
                                char source_str[INET_ADDRSTRLEN];
index e3138360c825feb45a2e85adcf6bc358d8f77f5f..be2321dc33155d4eb4cc2c16128b437c534c51d4 100644 (file)
@@ -179,7 +179,7 @@ int pim_static_add(struct pim_instance *pim, struct interface *iif,
 
        s_route->c_oil.pim = pim;
 
-       if (pim_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
+       if (pim_static_mroute_add(&s_route->c_oil, __PRETTY_FUNCTION__)) {
                char gifaddr_str[INET_ADDRSTRLEN];
                char sifaddr_str[INET_ADDRSTRLEN];
                pim_inet4_dump("<ifaddr?>", group, gifaddr_str,
@@ -264,7 +264,7 @@ int pim_static_del(struct pim_instance *pim, struct interface *iif,
                        if (s_route->c_oil.oil_ref_count <= 0
                                    ? pim_mroute_del(&s_route->c_oil,
                                                     __PRETTY_FUNCTION__)
-                                   : pim_mroute_add(&s_route->c_oil,
+                                   : pim_static_mroute_add(&s_route->c_oil,
                                                     __PRETTY_FUNCTION__)) {
                                char gifaddr_str[INET_ADDRSTRLEN];
                                char sifaddr_str[INET_ADDRSTRLEN];
index fdb7363042e9c1d2a6705f1262b4c7d1e9009424..e9382be33fc9b3d4822433353c62709ad069391f 100644 (file)
@@ -561,6 +561,63 @@ void pim_upstream_register_reevaluate(struct pim_instance *pim)
        }
 }
 
+/* RFC7761, Section 4.2 “Data Packet Forwarding Rules” says we should
+ * forward a S -
+ * 1. along the SPT if SPTbit is set
+ * 2. and along the RPT if SPTbit is not set
+ * If forwarding is hw accelerated i.e. control and dataplane components
+ * are separate you may not be able to reliably set SPT bit on intermediate
+ * routers while still fowarding on the (S,G,rpt).
+ *
+ * This macro is a slight deviation on the RFC and uses "traffic-agnostic"
+ * criteria to decide between using the RPT vs. SPT for forwarding.
+ */
+void pim_upstream_update_use_rpt(struct pim_upstream *up,
+                       bool update_mroute)
+{
+       bool old_use_rpt;
+       bool new_use_rpt;
+
+       if (up->sg.src.s_addr == INADDR_ANY)
+               return;
+
+       old_use_rpt = !!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags);
+
+       /* We will use the SPT (IIF=RPF_interface(S) if -
+        * 1. We have decided to join the SPT
+        * 2. We are FHR
+        * 3. Source is directly connected
+        * 4. We are RP (parent's IIF is lo or vrf-device)
+        * In all other cases the source will stay along the RPT and
+        * IIF=RPF_interface(RP).
+        */
+       if (up->join_state == PIM_UPSTREAM_JOINED ||
+                       PIM_UPSTREAM_FLAG_TEST_FHR(up->flags) ||
+                       pim_if_connected_to_source(
+                               up->rpf.source_nexthop.interface,
+                               up->sg.src) ||
+                       /* XXX - need to switch this to a more efficient
+                        * lookup API
+                        */
+                       I_am_RP(up->pim, up->sg.grp))
+               /* use SPT */
+               PIM_UPSTREAM_FLAG_UNSET_USE_RPT(up->flags);
+       else
+               /* use RPT */
+               PIM_UPSTREAM_FLAG_SET_USE_RPT(up->flags);
+
+       new_use_rpt = !!PIM_UPSTREAM_FLAG_TEST_USE_RPT(up->flags);
+       if (old_use_rpt != new_use_rpt) {
+               if (PIM_DEBUG_PIM_EVENTS)
+                       zlog_debug("%s switched from %s to %s",
+                                       up->sg_str,
+                                       old_use_rpt?"RPT":"SPT",
+                                       new_use_rpt?"RPT":"SPT");
+               if (update_mroute)
+                       pim_upstream_mroute_add(up->channel_oil, __func__);
+       }
+}
+
 void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
                         enum pim_upstream_state new_state)
 {
@@ -642,6 +699,9 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
                                                        0 /* prune */);
                join_timer_stop(up);
        }
+
+       if (old_state != new_state)
+               pim_upstream_update_use_rpt(up, true /*update_mroute*/);
 }
 
 int pim_upstream_compare(void *arg1, void *arg2)
@@ -693,6 +753,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
 
        up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
 
+       up->pim = pim;
        up->sg = *sg;
        pim_str_sg_set(sg, up->sg_str);
        if (ch)
@@ -776,6 +837,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
                                        pim_ifp->mroute_vif_index,
                                        __PRETTY_FUNCTION__);
                }
+               pim_upstream_update_use_rpt(up,
+                               false /*update_mroute*/);
        }
 
        listnode_add_sort(pim->upstream_list, up);
@@ -802,35 +865,26 @@ struct pim_upstream *pim_upstream_find(struct pim_instance *pim,
 }
 
 struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,
-                                             struct interface *incoming,
-                                             int flags, const char *name)
+               struct interface *incoming,
+               int flags, const char *name)
 {
-       struct pim_upstream *up;
-       struct pim_interface *pim_ifp;
-
-       pim_ifp = incoming->info;
-
-       up = pim_upstream_find(pim_ifp->pim, sg);
+       struct pim_interface *pim_ifp = incoming->info;
 
-       if (up) {
-               if (!(up->flags & flags)) {
-                       up->flags |= flags;
-                       up->ref_count++;
-                       if (PIM_DEBUG_PIM_TRACE)
-                               zlog_debug(
-                                       "%s(%s): upstream %s ref count %d increment",
-                                       __PRETTY_FUNCTION__, name, up->sg_str,
-                                       up->ref_count);
-               }
-       } else
-               up = pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name,
-                                     NULL);
-
-       return up;
+       return (pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name,
+                               NULL));
 }
 
 void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)
 {
+       /* when we go from non-FHR to FHR we need to re-eval traffic
+        * forwarding path
+        */
+       if (!PIM_UPSTREAM_FLAG_TEST_FHR(up->flags) &&
+                       PIM_UPSTREAM_FLAG_TEST_FHR(flags)) {
+               PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
+               pim_upstream_update_use_rpt(up, true /*update_mroute*/);
+       }
+
        up->flags |= flags;
        ++up->ref_count;
        if (PIM_DEBUG_PIM_TRACE)
@@ -1146,6 +1200,7 @@ static void pim_upstream_fhr_kat_start(struct pim_upstream *up)
                PIM_UPSTREAM_FLAG_SET_FHR(up->flags);
                if (up->reg_state == PIM_REG_NOINFO)
                        pim_register_join(up);
+               pim_upstream_update_use_rpt(up, true /*update_mroute*/);
        }
 }
 
index c6c9291eed493a1559f74b73728465d56107375d..7597baaa32a1082356119beb900e3d3420519210 100644 (file)
  * associated with an upstream
  */
 #define PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE             (1 << 19)
+/* By default as SG entry will use the SPT for forwarding traffic
+ * unless it was setup as a result of a Prune(S,G,rpt) from a
+ * downstream router and has JoinDesired(S,G) as False.
+ * This flag is only relevant for (S,G) entries.
+ */
+#define PIM_UPSTREAM_FLAG_MASK_USE_RPT                 (1 << 20)
 
 #define PIM_UPSTREAM_FLAG_ALL 0xFFFFFFFF
 
 #define PIM_UPSTREAM_FLAG_TEST_MLAG_VXLAN(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
 #define PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
 #define PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(flags) ((flags) &PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE)
+#define PIM_UPSTREAM_FLAG_TEST_USE_RPT(flags) ((flags) & PIM_UPSTREAM_FLAG_MASK_USE_RPT)
 
 #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
 #define PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
 #define PIM_UPSTREAM_FLAG_SET_SRC_VXLAN_TERM(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_SRC_VXLAN_TERM)
 #define PIM_UPSTREAM_FLAG_SET_MLAG_VXLAN(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
 #define PIM_UPSTREAM_FLAG_SET_MLAG_NON_DF(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
+#define PIM_UPSTREAM_FLAG_SET_USE_RPT(flags) ((flags) |= PIM_UPSTREAM_FLAG_MASK_USE_RPT)
 
 #define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
 #define PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED_UPDATED)
 #define PIM_UPSTREAM_FLAG_UNSET_MLAG_VXLAN(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_MLAG_VXLAN)
 #define PIM_UPSTREAM_FLAG_UNSET_MLAG_NON_DF(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_MLAG_NON_DF)
 #define PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_SRC_NOCACHE)
+#define PIM_UPSTREAM_FLAG_UNSET_USE_RPT(flags) ((flags) &= ~PIM_UPSTREAM_FLAG_MASK_USE_RPT)
 
 enum pim_upstream_state {
        PIM_UPSTREAM_NOTJOINED,
@@ -188,6 +197,7 @@ enum pim_upstream_sptbit {
 
 */
 struct pim_upstream {
+       struct pim_instance *pim;
        struct pim_upstream *parent;
        struct in_addr upstream_addr;     /* Who we are talking to */
        struct in_addr upstream_register; /*Who we received a register from*/
@@ -324,4 +334,6 @@ struct pim_upstream *pim_upstream_keep_alive_timer_proc(
                struct pim_upstream *up);
 void pim_upstream_fill_static_iif(struct pim_upstream *up,
                                struct interface *incoming);
+void pim_upstream_update_use_rpt(struct pim_upstream *up,
+               bool update_mroute);
 #endif /* PIM_UPSTREAM_H */
index 4ca75e57ea2c4c25e7ac9ec268f9cdb9ca59411f..daec0951c3f8a9d21599b9b578aa6784a65c4ee8 100644 (file)
@@ -347,6 +347,8 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
                        pim_delete_tracked_nexthop(vxlan_sg->pim,
                                &nht_p, up, NULL, false);
                }
+               /* We are acting FHR; clear out use_rpt setting if any */
+               pim_upstream_update_use_rpt(up, false /*update_mroute*/);
                pim_upstream_ref(up, flags, __PRETTY_FUNCTION__);
                vxlan_sg->up = up;
                pim_vxlan_orig_mr_up_iif_update(vxlan_sg);
@@ -378,6 +380,8 @@ static void pim_vxlan_orig_mr_up_add(struct pim_vxlan_sg *vxlan_sg)
 
        /* update the inherited OIL */
        pim_upstream_inherited_olist(vxlan_sg->pim, up);
+       if (!up->channel_oil->installed)
+               pim_upstream_mroute_add(up->channel_oil, __func__);
 }
 
 static void pim_vxlan_orig_mr_oif_add(struct pim_vxlan_sg *vxlan_sg)
index a0ca618b736e8dd9308bde44bc55894e8a1f0273..9b1261976daf2542487a40d6872749ea7103485d 100644 (file)
@@ -289,7 +289,7 @@ void pim_zebra_upstream_rpf_changed(struct pim_instance *pim,
                         * so install it.
                         */
                        if (!up->channel_oil->installed)
-                               pim_mroute_add(up->channel_oil,
+                               pim_upstream_mroute_add(up->channel_oil,
                                        __PRETTY_FUNCTION__);
 
                        /*
@@ -325,7 +325,8 @@ void pim_zebra_upstream_rpf_changed(struct pim_instance *pim,
                }
 
                if (!up->channel_oil->installed)
-                       pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
+                       pim_upstream_mroute_add(up->channel_oil,
+                                       __PRETTY_FUNCTION__);
        }
 
        /* FIXME can join_desired actually be changed by pim_rpf_update()
@@ -440,7 +441,7 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
 
        if (input_iface_vif_index == c_oil->oil.mfcc_parent) {
                if (!c_oil->installed)
-                       pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
+                       pim_upstream_mroute_add(c_oil, __PRETTY_FUNCTION__);
 
                /* RPF unchanged */
                return;
@@ -490,7 +491,7 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
        /* update iif vif_index */
        pim_channel_oil_change_iif(c_oil->pim, c_oil, input_iface_vif_index,
                                   __PRETTY_FUNCTION__);
-       pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
+       pim_upstream_mroute_add(c_oil, __PRETTY_FUNCTION__);
 }
 
 void pim_scan_oil(struct pim_instance *pim)
@@ -1008,7 +1009,7 @@ void pim_forward_stop(struct pim_ifchannel *ch, bool install_it)
                                    PIM_OIF_FLAG_PROTO_PIM, __func__);
 
        if (install_it && !up->channel_oil->installed)
-               pim_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
+               pim_upstream_mroute_add(up->channel_oil, __PRETTY_FUNCTION__);
 }
 
 void pim_zebra_zclient_update(struct vty *vty)