]> git.proxmox.com Git - mirror_frr.git/commitdiff
pimd, pim6d: Update upstream rpf disable/enable pim on interface
authorSarita Patra <saritap@vmware.com>
Fri, 11 Nov 2022 06:59:58 +0000 (22:59 -0800)
committerSarita Patra <saritap@vmware.com>
Mon, 14 Nov 2022 08:17:48 +0000 (00:17 -0800)
Problem:
When "no ip pim" is executed on source connected interface, its
ifp->info is set to NULL. But KAT on this interface is still
running, it wrongly dereferences NULL. This leads to crash.

Root Cause:
pim upstream IIF is still pointing towards the source connected
interface which is not pim enabled and Mroute is still present in
the kernel.

Fix:
When “no ip pim” command gets executed on source connected interface,
then loop through all the pnc->nexthop, if any new nexthop found,
then update the upstream IIF accordindly, if not found then update
the upstream IIF as Unknown and uninstall the mroute from kernel.

When “ip pim” command gets executed on source connected interface,
then also loop through all the pnc->nexthop  and update the upstream IIF,
install the mroute in kernel.

Issue: #10782
Issue: #11931

Signed-off-by: Sarita Patra <saritap@vmware.com>
pimd/pim_nb_config.c
pimd/pim_nht.c
pimd/pim_nht.h

index 12f8ffedfe28b344c4e2d27f6f2226312c7e530c..c4ff912cde99862c9c300e3cfb6aca85bd1d58b5 100644 (file)
@@ -24,6 +24,7 @@
 #include "lib/northbound_cli.h"
 #include "pim_igmpv3.h"
 #include "pim_neighbor.h"
+#include "pim_nht.h"
 #include "pim_pim.h"
 #include "pim_mlag.h"
 #include "pim_bfd.h"
@@ -146,6 +147,7 @@ static int pim_cmd_interface_add(struct interface *ifp)
                pim_ifp->pim_enable = true;
 
        pim_if_addr_add_all(ifp);
+       pim_upstream_nh_if_update(pim_ifp->pim, ifp);
        pim_if_membership_refresh(ifp);
 
        pim_if_create_pimreg(pim_ifp->pim);
@@ -171,6 +173,7 @@ static int pim_cmd_interface_delete(struct interface *ifp)
 
        if (!pim_ifp->gm_enable) {
                pim_if_addr_del_all(ifp);
+               pim_upstream_nh_if_update(pim_ifp->pim, ifp);
                pim_if_delete(ifp);
        }
 
index f9a9aeb1b0673665a9a43dd1541bce735a7e5bec..c3e72557b7807c6683ea4cc498916771d0cd987f 100644 (file)
@@ -469,6 +469,40 @@ static int pim_update_upstream_nh(struct pim_instance *pim,
        return 0;
 }
 
+static int pim_upstream_nh_if_update_helper(struct hash_bucket *bucket,
+                                           void *arg)
+{
+       struct pim_nexthop_cache *pnc = bucket->data;
+       struct pnc_hash_walk_data *pwd = arg;
+       struct pim_instance *pim = pwd->pim;
+       struct interface *ifp = pwd->ifp;
+       struct nexthop *nh_node = NULL;
+       ifindex_t first_ifindex;
+
+       for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
+               first_ifindex = nh_node->ifindex;
+               if (ifp != if_lookup_by_index(first_ifindex, pim->vrf->vrf_id))
+                       continue;
+
+               if (pnc->upstream_hash->count) {
+                       pim_update_upstream_nh(pim, pnc);
+                       break;
+               }
+       }
+
+       return HASHWALK_CONTINUE;
+}
+
+void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp)
+{
+       struct pnc_hash_walk_data pwd;
+
+       pwd.pim = pim;
+       pwd.ifp = ifp;
+
+       hash_walk(pim->rpf_hash, pim_upstream_nh_if_update_helper, &pwd);
+}
+
 uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
 {
        uint32_t hash_val;
index 316b7b46ee7e1cc1c33a9135e73ff6eb6addf1fd..f487a21ba4c9683c28271b7eb831ff1a9fda1815 100644 (file)
@@ -82,5 +82,5 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr bsr_addr);
 /* RPF(bsr_addr) == src_ip%src_ifp? */
 bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
                           struct interface *src_ifp, pim_addr src_ip);
-
+void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
 #endif