summaryrefslogtreecommitdiff
path: root/pimd
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-07-08 19:46:01 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2019-07-18 07:54:04 -0400
commitafb2f47031e71f7dc3c8c98bec053426694dfc4f (patch)
treef7a40219f903ebde6c83d62b14f2b840cfa0d5c7 /pimd
parenta85de978b62c17db23fc502ddcd6bc0718e754a7 (diff)
pimd: Add pim_channel_oil_change_iif
Add a function that allows you to modify the channel oil's incoming interface and to appropriately install/remove it from the kernel. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim_mroute.c3
-rw-r--r--pimd/pim_oil.c40
-rw-r--r--pimd/pim_oil.h3
-rw-r--r--pimd/pim_rpf.c8
-rw-r--r--pimd/pim_static.c4
-rw-r--r--pimd/pim_zebra.c31
6 files changed, 54 insertions, 35 deletions
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index b1c55c1f43..dc2db33f65 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -238,7 +238,8 @@ static int pim_mroute_msg_nocache(int fd, struct interface *ifp,
vif_index = pim_if_find_vifindex_by_ifindex(
pim_ifp->pim,
up->rpf.source_nexthop.interface->ifindex);
- up->channel_oil->oil.mfcc_parent = vif_index;
+ pim_channel_oil_change_iif(pim_ifp->pim, up->channel_oil,
+ vif_index, __PRETTY_FUNCTION__);
}
pim_register_join(up);
diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c
index d4fc03e20c..d142934916 100644
--- a/pimd/pim_oil.c
+++ b/pimd/pim_oil.c
@@ -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);
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index 485299196d..319a1c91a3 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -114,6 +114,9 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
struct prefix_sg *sg,
int input_vif_index, 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);
void pim_channel_oil_del(struct channel_oil *c_oil, const char *name);
int pim_channel_add_oif(struct channel_oil *c_oil, struct interface *oif,
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index 7d263e99e3..357ad6ba46 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -307,11 +307,11 @@ void pim_upstream_rpf_clear(struct pim_instance *pim,
struct pim_upstream *up)
{
if (up->rpf.source_nexthop.interface) {
- if (up->channel_oil) {
- up->channel_oil->oil.mfcc_parent = MAXVIFS;
- pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
+ 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 =
diff --git a/pimd/pim_static.c b/pimd/pim_static.c
index 62c3216e86..e3138360c8 100644
--- a/pimd/pim_static.c
+++ b/pimd/pim_static.c
@@ -138,7 +138,9 @@ int pim_static_add(struct pim_instance *pim, struct interface *iif,
} else {
/* input interface changed */
s_route->iif = iif_index;
- s_route->c_oil.oil.mfcc_parent = iif_index;
+ pim_channel_oil_change_iif(pim, &s_route->c_oil,
+ iif_index,
+ __PRETTY_FUNCTION__);
#ifdef PIM_ENFORCE_LOOPFREE_MFC
/* check to make sure the new input was not an
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 675e81f5a1..3b93dd2b3c 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -601,7 +601,6 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
{
struct in_addr vif_source;
int input_iface_vif_index;
- int old_vif_index;
pim_rp_set_upstream_addr(c_oil->pim, &vif_source,
c_oil->oil.mfcc_origin,
@@ -701,33 +700,9 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
}
/* update iif vif_index */
- old_vif_index = c_oil->oil.mfcc_parent;
- c_oil->oil.mfcc_parent = input_iface_vif_index;
-
- /* update kernel multicast forwarding cache (MFC) */
- if (pim_mroute_add(c_oil, __PRETTY_FUNCTION__)) {
- if (PIM_DEBUG_MROUTE) {
- /* just log warning */
- struct interface *old_iif = pim_if_find_by_vif_index(
- c_oil->pim, old_vif_index);
- 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) failure updating input interface 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);
- }
- }
+ pim_channel_oil_change_iif(c_oil->pim, c_oil, input_iface_vif_index,
+ __PRETTY_FUNCTION__);
+ pim_mroute_add(c_oil, __PRETTY_FUNCTION__);
}
void pim_scan_oil(struct pim_instance *pim)