// 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);
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;
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 ?
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;
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);
{
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;
}
/* 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);
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) {
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)",
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);
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;
}
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);
|| ((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 {
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);
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 =
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__);
}
}
} 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__);
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;
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(
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*/);
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:"-");
}
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__);
}
}
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 {
}
source->source_channel_oil =
pim_channel_oil_add(
- pim, &sg, MAXVIFS,
+ pim, &sg,
__PRETTY_FUNCTION__);
}
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) {