]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: rpf update when pim disabled/enabled
authorsarita patra <saritap@vmware.com>
Wed, 2 Mar 2022 14:33:31 +0000 (06:33 -0800)
committersarita patra <saritap@vmware.com>
Mon, 28 Mar 2022 12:44:40 +0000 (05:44 -0700)
Topology :-

----ens192--------+---------+
R11 -------------R2--------R3
---ens256-------+---------+

R11: receiver
R2: RP
R3: source .
There are 2 links connected between each routers .

R11: Initially (,G) joins are sent over ens192 interface
R11(config)# do show ip pim upstream 225.0.7.208
Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt
ens192 * 225.0.7.208 J 00:00:4 00:00:30 --:--:-- --:--:-- 1

Remove PIM from interface ens192 still (*,G) iif not changed

R11(config)# interface ens192
R11(config-if)# no ip pim
R11(config-if)# exit
R11(config)# do show ip pim upstream 225.0.7.208
Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt
ens192 * 225.0.7.208 J 00:00:12 00:00:51 --:--:-- --:--:-- 1

Fix: pim upstream rpf update taken care when pim is enabled
or disabled on an interface.

Signed-off-by: sarita patra <saritap@vmware.com>
pimd/pim_nb_config.c
pimd/pim_nht.c
pimd/pim_nht.h
pimd/pim_rpf.c

index 7fe7c0395f0b9ad7451428a2bd899ce4c5372987..265c0bb1894ceeef14910497338a16816359b373 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_IF_DO_PIM(pim_ifp->options);
 
        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_IF_TEST_IGMP(pim_ifp->options)) {
                pim_if_addr_del_all(ifp);
+               pim_upstream_nh_if_update(pim_ifp->pim, ifp);
                pim_if_delete(ifp);
        }
 
index 94dcfb826558ee85cc8da4423f53907719623948..f1508f76311f0eafd5148672967778d5ca393a42 100644 (file)
@@ -483,6 +483,37 @@ 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))
+                       return HASHWALK_CONTINUE;
+
+               if (pnc->upstream_hash->count)
+                       pim_update_upstream_nh(pim, pnc);
+       }
+       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;
@@ -523,6 +554,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
 
        // Current Nexthop is VALID, check to stay on the current path.
        if (nexthop->interface && nexthop->interface->info &&
+           ((struct pim_interface *)nexthop->interface->info)->options &&
            (!pim_addr_is_any(nh_addr))) {
                /* User configured knob to explicitly switch
                   to new path is disabled or current path
@@ -637,6 +669,19 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
                        continue;
                }
 
+               if (!PIM_IF_TEST_PIM(
+                           ((struct pim_interface *)ifp->info)->options)) {
+                       if (PIM_DEBUG_PIM_NHT)
+                               zlog_debug(
+                                       "%s: pim not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pI4)",
+                                       __func__, ifp->name, pim->vrf->name,
+                                       first_ifindex, &src->u.prefix4);
+                       if (nh_iter == mod_val)
+                               mod_val++; // Select nexthpath
+                       nh_iter++;
+                       continue;
+               }
+
                if (neighbor_needed &&
                    !pim_if_connected_to_source(ifp, src_addr)) {
                        nbr = nbrs[nh_iter];
@@ -647,7 +692,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
                                                __func__, ifp->name,
                                                pim->vrf->name);
                                if (nh_iter == mod_val)
-                                       mod_val++; // Select nexthpath
+                                       /* Select nexthpath */
+                                       mod_val++;
                                nh_iter++;
                                continue;
                        }
@@ -984,6 +1030,21 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
                        i++;
                        continue;
                }
+
+
+               if (!PIM_IF_TEST_PIM(
+                           ((struct pim_interface *)ifp->info)->options)) {
+                       if (PIM_DEBUG_PIM_NHT)
+                               zlog_debug(
+                                       "%s: pim not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pI4)",
+                                       __func__, ifp->name, pim->vrf->name,
+                                       first_ifindex, &src->u.prefix4);
+                       if (i == mod_val)
+                               mod_val++;
+                       i++;
+                       continue;
+               }
+
                if (neighbor_needed &&
                    !pim_if_connected_to_source(ifp, src_addr)) {
                        nbr = nbrs[i];
index d51f622ece479284886d87241fbbcbea3817457d..16ff44291faca449c04d287125c7426e8c4a69b1 100644 (file)
@@ -53,6 +53,11 @@ struct pim_nexthop_cache {
        uint32_t bsr_count;
 };
 
+struct pnc_hash_walk_data {
+       struct pim_instance *pim;
+       struct interface *ifp;
+};
+
 int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
 int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
                              struct pim_upstream *up, struct rp_info *rp,
@@ -78,4 +83,5 @@ void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr bsr_addr);
 bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_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
index cee542aa136646978da391245bfad2625d9a7c83..eebe38bb884da13d4989bdcbe78cd12bd8a59e6b 100644 (file)
@@ -122,8 +122,18 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
                                        __func__, ifp->name, first_ifindex,
                                        &addr);
                        i++;
-               } else if (neighbor_needed
-                          && !pim_if_connected_to_source(ifp, addr)) {
+
+               } else if (!PIM_IF_TEST_PIM(((struct pim_interface *)ifp->info)
+                                                   ->options)) {
+                       if (PIM_DEBUG_ZEBRA)
+                               zlog_debug(
+                                       "%s: pim not enabled on input interface %s (ifindex=%d, RPF for source %pI4)",
+                                       __func__, ifp->name, first_ifindex,
+                                       &addr);
+                       i++;
+
+               } else if (neighbor_needed &&
+                          !pim_if_connected_to_source(ifp, addr)) {
                        nbr = pim_neighbor_find_prefix(
                                ifp, &nexthop_tab[i].nexthop_addr);
                        if (PIM_DEBUG_PIM_TRACE_DETAIL)