From bc36ccde9951722fb808af51bc12011d96ad0537 Mon Sep 17 00:00:00 2001 From: sarita patra Date: Wed, 2 Mar 2022 06:33:31 -0800 Subject: [PATCH] pimd: rpf update when pim disabled/enabled 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 --- pimd/pim_nb_config.c | 3 +++ pimd/pim_nht.c | 63 +++++++++++++++++++++++++++++++++++++++++++- pimd/pim_nht.h | 6 +++++ pimd/pim_rpf.c | 14 ++++++++-- 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 7fe7c0395f..265c0bb189 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -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); } diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 94dcfb8265..f1508f7631 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -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]; diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h index d51f622ece..16ff44291f 100644 --- a/pimd/pim_nht.h +++ b/pimd/pim_nht.h @@ -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 diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index cee542aa13..eebe38bb88 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -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) -- 2.39.5