From afb2f47031e71f7dc3c8c98bec053426694dfc4f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 8 Jul 2019 19:46:01 -0400 Subject: [PATCH] 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 --- pimd/pim_mroute.c | 3 ++- pimd/pim_oil.c | 40 +++++++++++++++++++++++++++++++++++++++- pimd/pim_oil.h | 3 +++ pimd/pim_rpf.c | 8 ++++---- pimd/pim_static.c | 4 +++- pimd/pim_zebra.c | 31 +++---------------------------- 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("", c_oil->oil.mfcc_origin, - source_str, sizeof(source_str)); - pim_inet4_dump("", 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 : "", - c_oil->oil.mfcc_parent, - new_iif ? new_iif->name : "", - 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)