diff options
| author | Sarita Patra <saritap@vmware.com> | 2022-11-10 22:59:58 -0800 |
|---|---|---|
| committer | Sarita Patra <saritap@vmware.com> | 2022-11-14 00:17:48 -0800 |
| commit | 93d4f4f0dd6c3d9b42d5f7604a064a7303c0c282 (patch) | |
| tree | 1282064bf402f169017d6ecfbd74d54df871476a | |
| parent | 12211791a9e6bb7002c3c24af68c2defa02ff747 (diff) | |
pimd, pim6d: Update upstream rpf disable/enable pim on interface
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>
| -rw-r--r-- | pimd/pim_nb_config.c | 3 | ||||
| -rw-r--r-- | pimd/pim_nht.c | 34 | ||||
| -rw-r--r-- | pimd/pim_nht.h | 2 |
3 files changed, 38 insertions, 1 deletions
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 12f8ffedfe..c4ff912cde 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_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); } diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index f9a9aeb1b0..c3e72557b7 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -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; diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h index 316b7b46ee..f487a21ba4 100644 --- a/pimd/pim_nht.h +++ b/pimd/pim_nht.h @@ -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 |
