summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_mroute.c81
-rw-r--r--pimd/pim_mroute.h3
-rw-r--r--pimd/pim_oil.c10
-rw-r--r--pimd/pim_static.c4
-rw-r--r--pimd/pim_upstream.c101
-rw-r--r--pimd/pim_upstream.h12
-rw-r--r--pimd/pim_vxlan.c4
-rw-r--r--pimd/pim_zebra.c11
8 files changed, 173 insertions, 53 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index f28d801f0b..c8e9202586 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -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;
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index bd71acbf82..3f54681432 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -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);
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index 8933245de1..3e73e6cc8f 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -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];
diff --git a/pimd/pim_static.c b/pimd/pim_static.c
index e3138360c8..be2321dc33 100644
--- a/pimd/pim_static.c
+++ b/pimd/pim_static.c
@@ -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];
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index fdb7363042..e9382be33f 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -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*/);
}
}
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index c6c9291eed..7597baaa32 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -80,6 +80,12 @@
* 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
@@ -103,6 +109,7 @@
#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)
@@ -122,6 +129,7 @@
#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)
@@ -142,6 +150,7 @@
#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 */
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 4ca75e57ea..daec0951c3 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -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)
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index a0ca618b73..9b1261976d 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -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)