From 1c883aef96013753f5467ba5e5028dee0f0a82c5 Mon Sep 17 00:00:00 2001 From: Sai Gomathi N Date: Fri, 17 Mar 2023 03:51:16 -0700 Subject: [PATCH] pimd: PIM not sending register packets after changing from non DR to DR When the router is non dr for an interface, it installs mroute to drop the packets from directly connected source. This was done to avoid packets coming to cpu as nocache hit. Later when it gets change from non-DR to DR, these entries are not cleared. So the packets are still dropped. This causes register packets not getting generated. So cleaning up the mroute entries and channel oil without upstream reference which was created to drop. Co-authored-by: Saravanan K Signed-off-by: Sai Gomathi N --- pimd/pim_neighbor.c | 6 ++++-- pimd/pim_oil.c | 25 +++++++++++++++++++++++++ pimd/pim_oil.h | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 0b7ea0ad9d..6adf7a9eda 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -29,6 +29,7 @@ #include "pim_jp_agg.h" #include "pim_bfd.h" #include "pim_register.h" +#include "pim_oil.h" static void dr_election_by_addr(struct interface *ifp) { @@ -123,9 +124,10 @@ int pim_if_dr_election(struct interface *ifp) pim_if_update_could_assert(ifp); pim_if_update_assert_tracking_desired(ifp); - if (PIM_I_am_DR(pim_ifp)) + if (PIM_I_am_DR(pim_ifp)) { pim_ifp->am_i_dr = true; - else { + pim_clear_nocache_state(pim_ifp); + } else { if (pim_ifp->am_i_dr == true) { pim_reg_del_on_couldreg_fail(ifp); pim_ifp->am_i_dr = false; diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 63ddb85d00..4d3c51b7f0 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -149,6 +149,31 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, return c_oil; } + +/* + * Clean up mroute and channel oil created for dropping pkts from directly + * connected source when the interface was non DR. + */ +void pim_clear_nocache_state(struct pim_interface *pim_ifp) +{ + struct channel_oil *c_oil; + + frr_each_safe (rb_pim_oil, &pim_ifp->pim->channel_oil_head, c_oil) { + + if ((!c_oil->up) || + !(PIM_UPSTREAM_FLAG_TEST_SRC_NOCACHE(c_oil->up->flags))) + continue; + + if (*oil_parent(c_oil) != pim_ifp->mroute_vif_index) + continue; + + THREAD_OFF(c_oil->up->t_ka_timer); + PIM_UPSTREAM_FLAG_UNSET_SRC_NOCACHE(c_oil->up->flags); + PIM_UPSTREAM_FLAG_UNSET_SRC_STREAM(c_oil->up->flags); + pim_upstream_del(pim_ifp->pim, c_oil->up, __func__); + } +} + struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil, const char *name) { diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index 45b337cc72..dc66eaace4 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -182,6 +182,7 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim, pim_sgaddr *sg); struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, pim_sgaddr *sg, const char *name); +void pim_clear_nocache_state(struct pim_interface *pim_ifp); struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil, const char *name); -- 2.39.5