]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: PIM not sending register packets after changing from non DR to DR
authorSai Gomathi N <nsaigomathi@vmware.com>
Fri, 17 Mar 2023 10:51:16 +0000 (03:51 -0700)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Tue, 2 May 2023 15:56:34 +0000 (15:56 +0000)
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 <saravanank@vmware.com>
Signed-off-by: Sai Gomathi N <nsaigomathi@vmware.com>
(cherry picked from commit 1c883aef96013753f5467ba5e5028dee0f0a82c5)

pimd/pim_neighbor.c
pimd/pim_oil.c
pimd/pim_oil.h

index 7726ac00b0a85047a000e5d712902d7dcc81d62b..b941eae126a96e6182d1d9cd1c6ed4f1aecce207 100644 (file)
@@ -42,6 +42,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)
 {
@@ -136,9 +137,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;
index 3bfb31e0c6978d6a83588e95b3d8577bd21002d0..5c8d81640674c1f1985f36cc8ea502af4d5f3fe5 100644 (file)
@@ -162,6 +162,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)
 {
index 5a2647b93f33e19234e32adcfe78152b74dc5003..2ee80654470574259a0744f987b29fa9f8b941f8 100644 (file)
@@ -195,6 +195,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);