]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd : Added the command to clear the pim bsr data. 7775/head
authorvdhingra <vdhingra@vmware.com>
Mon, 21 Dec 2020 10:24:11 +0000 (02:24 -0800)
committervdhingra <vdhingra@vmware.com>
Fri, 8 Jan 2021 12:45:49 +0000 (04:45 -0800)
This command has been added in the context of
PIM BSM functionality. This command will clear the
data structs having bsr information.

Co-authored-by: Sarita Patra <saritap@vmware.com>
Signed-off-by: vishaldhingra <vdhingra@vmware.com>
doc/user/pim.rst
pimd/pim_bsm.c
pimd/pim_bsm.h
pimd/pim_cmd.c
pimd/pim_rp.c
pimd/pim_rp.h

index bacf8637ae9629c43d5fbd1410a6181b88116101..05297a0609c219d62d95bc3df88a23d1062d2efe 100644 (file)
@@ -726,6 +726,13 @@ Clear commands reset various variables.
 
    Rescan PIM OIL (output interface list).
 
+.. index:: clear ip pim [vrf NAME] bsr-data
+.. clicmd:: clear ip pim [vrf NAME] bsr-data
+
+   This command will clear the BSM scope data struct. This command also
+   removes the next hop tracking for the bsr and resets the upstreams
+   for the dynamically learnt RPs.
+
 PIM EVPN configuration
 ======================
 To use PIM in the underlay for overlay BUM forwarding associate a multicast
index 1acfece895a0aaeed020b01e19273355552facc5..e873af57598ccaa517e320b2ccb3987f1243f17d 100644 (file)
@@ -63,7 +63,7 @@ void pim_bsm_write_config(struct vty *vty, struct interface *ifp)
        }
 }
 
-static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
+void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
 {
        if (bsgrp_node->bsrp_list)
                list_delete(&bsgrp_node->bsrp_list);
@@ -72,7 +72,7 @@ static void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node)
        XFREE(MTYPE_PIM_BSGRP_NODE, bsgrp_node);
 }
 
-static void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp)
+void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp)
 {
        struct route_node *rn;
 
@@ -222,7 +222,7 @@ static int pim_on_bs_timer(struct thread *t)
        return 0;
 }
 
-static void pim_bs_timer_stop(struct bsm_scope *scope)
+void pim_bs_timer_stop(struct bsm_scope *scope)
 {
        if (PIM_DEBUG_BSM)
                zlog_debug("%s : BS timer being stopped of sz: %d", __func__,
index 0758c94f1947400c687006da7d25f15a6ee4abe6..2829c1e05a46d06e8fec78525f41bfd22b1229b5 100644 (file)
@@ -195,4 +195,7 @@ int  pim_bsm_process(struct interface *ifp,
 bool pim_bsm_new_nbr_fwd(struct pim_neighbor *neigh, struct interface *ifp);
 struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope,
                                          struct prefix *grp);
+void pim_bs_timer_stop(struct bsm_scope *scope);
+void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node);
+void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp);
 #endif
index 8e7b13cc17289773989011c49c6a689c0632de5a..ff85151839444fb7a2c8334eba24eb9bea7d56ed 100644 (file)
@@ -4001,6 +4001,152 @@ DEFUN (clear_ip_pim_oil,
        return CMD_SUCCESS;
 }
 
+static void clear_pim_bsr_db(struct pim_instance *pim)
+{
+       struct route_node *rn;
+       struct route_node *rpnode;
+       struct bsgrp_node *bsgrp;
+       struct prefix nht_p;
+       struct prefix g_all;
+       struct rp_info *rp_all;
+       struct pim_upstream *up;
+       struct rp_info *rp_info;
+       bool is_bsr_tracking = true;
+
+       /* Remove next hop tracking for the bsr */
+       nht_p.family = AF_INET;
+       nht_p.prefixlen = IPV4_MAX_BITLEN;
+       nht_p.u.prefix4 = pim->global_scope.current_bsr;
+       if (PIM_DEBUG_BSM) {
+               zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
+                          __func__, &nht_p);
+       }
+       pim_delete_tracked_nexthop(pim, &nht_p, NULL, NULL, is_bsr_tracking);
+
+       /* Reset scope zone data */
+       pim->global_scope.accept_nofwd_bsm = false;
+       pim->global_scope.state = ACCEPT_ANY;
+       pim->global_scope.current_bsr.s_addr = INADDR_ANY;
+       pim->global_scope.current_bsr_prio = 0;
+       pim->global_scope.current_bsr_first_ts = 0;
+       pim->global_scope.current_bsr_last_ts = 0;
+       pim->global_scope.bsm_frag_tag = 0;
+       list_delete_all_node(pim->global_scope.bsm_list);
+
+       pim_bs_timer_stop(&pim->global_scope);
+
+       for (rn = route_top(pim->global_scope.bsrp_table); rn;
+            rn = route_next(rn)) {
+               bsgrp = rn->info;
+               if (!bsgrp)
+                       continue;
+
+               rpnode = route_node_lookup(pim->rp_table, &bsgrp->group);
+
+               if (!rpnode) {
+                       pim_free_bsgrp_node(bsgrp->scope->bsrp_table,
+                                           &bsgrp->group);
+                       pim_free_bsgrp_data(bsgrp);
+                       continue;
+               }
+
+               rp_info = (struct rp_info *)rpnode->info;
+
+               if ((!rp_info) || (rp_info->rp_src != RP_SRC_BSR)) {
+                       pim_free_bsgrp_node(bsgrp->scope->bsrp_table,
+                                           &bsgrp->group);
+                       pim_free_bsgrp_data(bsgrp);
+                       continue;
+               }
+
+               /* Deregister addr with Zebra NHT */
+               nht_p.family = AF_INET;
+               nht_p.prefixlen = IPV4_MAX_BITLEN;
+               nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
+
+               if (PIM_DEBUG_PIM_NHT_RP) {
+                       zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
+                                  __func__, &nht_p);
+               }
+
+               pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false);
+
+               if (!str2prefix("224.0.0.0/4", &g_all))
+                       return;
+
+               rp_all = pim_rp_find_match_group(pim, &g_all);
+
+               if (rp_all == rp_info) {
+                       rp_all->rp.rpf_addr.family = AF_INET;
+                       rp_all->rp.rpf_addr.u.prefix4.s_addr = INADDR_NONE;
+                       rp_all->i_am_rp = 0;
+               } else {
+                       /* Delete the rp_info from rp-list */
+                       listnode_delete(pim->rp_list, rp_info);
+
+                       /* Delete the rp node from rp_table */
+                       rpnode->info = NULL;
+                       route_unlock_node(rpnode);
+                       route_unlock_node(rpnode);
+               }
+
+               XFREE(MTYPE_PIM_RP, rp_info);
+
+               pim_free_bsgrp_node(bsgrp->scope->bsrp_table, &bsgrp->group);
+               pim_free_bsgrp_data(bsgrp);
+       }
+       pim_rp_refresh_group_to_rp_mapping(pim);
+
+
+       frr_each (rb_pim_upstream, &pim->upstream_head, up) {
+               /* Find the upstream (*, G) whose upstream address is same as
+                * the RP
+                */
+               if (up->sg.src.s_addr != INADDR_ANY)
+                       continue;
+
+               struct prefix grp;
+               struct rp_info *trp_info;
+
+               grp.family = AF_INET;
+               grp.prefixlen = IPV4_MAX_BITLEN;
+               grp.u.prefix4 = up->sg.grp;
+
+               trp_info = pim_rp_find_match_group(pim, &grp);
+
+               /* RP not found for the group grp */
+               if (pim_rpf_addr_is_inaddr_none(&trp_info->rp)) {
+                       pim_upstream_rpf_clear(pim, up);
+                       pim_rp_set_upstream_addr(pim, &up->upstream_addr,
+                                                up->sg.src, up->sg.grp);
+               } else {
+                       /* RP found for the group grp */
+                       pim_upstream_update(pim, up);
+               }
+       }
+}
+
+
+DEFUN (clear_ip_pim_bsr_db,
+       clear_ip_pim_bsr_db_cmd,
+       "clear ip pim [vrf NAME] bsr-data",
+       CLEAR_STR
+       IP_STR
+       CLEAR_IP_PIM_STR
+       VRF_CMD_HELP_STR
+       "Reset pim bsr data\n")
+{
+       int idx = 2;
+       struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+
+       if (!vrf)
+               return CMD_WARNING;
+
+       clear_pim_bsr_db(vrf->info);
+
+       return CMD_SUCCESS;
+}
+
 DEFUN (show_ip_igmp_interface,
        show_ip_igmp_interface_cmd,
        "show ip igmp [vrf NAME] interface [detail|WORD] [json]",
@@ -11396,6 +11542,7 @@ void pim_cmd_init(void)
        install_element(ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
        install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
        install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
+       install_element(ENABLE_NODE, &clear_ip_pim_bsr_db_cmd);
 
        install_element(ENABLE_NODE, &show_debugging_pim_cmd);
 
index fa5d6f37bf8979a491dbcd514c90d7060ce69c8b..301a27001f93f7c828690885d4816e13700a3d32 100644 (file)
@@ -271,7 +271,7 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
  *
  * This is a placeholder function for now.
  */
-static void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim)
+void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim)
 {
        pim_msdp_i_am_rp_changed(pim);
        pim_upstream_reeval_use_rpt(pim);
index 8a12cb076cca83d9249b77197e69ad93917e95e4..dd7cd5d75e35504a7c57851355042be7f5d07aab 100644 (file)
@@ -86,4 +86,5 @@ int pim_rp_list_cmp(void *v1, void *v2);
 struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
                                        const struct prefix *group);
 void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up);
+void pim_rp_refresh_group_to_rp_mapping(struct pim_instance *pim);
 #endif