diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst index ba2c05a31a..96dec20f25 100644 --- a/doc/user/pimv6.rst +++ b/doc/user/pimv6.rst @@ -375,3 +375,20 @@ configure CLI mode. If you specify debug commands in the configuration cli mode, the debug commands can be persistent across restarts of the FRR pim6d if the config was written out. +PIMv6 Clear Commands +==================== +Clear commands reset various variables. + +.. clicmd:: clear ipv6 mroute + + Reset multicast routes. + +.. clicmd:: clear ipv6 mroute [vrf NAME] count + + When this command is issued, reset the counts of data shown for + packet count, byte count and wrong interface to 0 and start count + up from this spot. + +.. clicmd:: clear ipv6 pim oil + + Rescan PIMv6 OIL (output interface list). diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index 9b7faa0954..151ecdb177 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -42,6 +42,7 @@ #include "pim_nht.h" #include "pim_bsm.h" #include "pim_iface.h" +#include "pim_zebra.h" #ifndef VTYSH_EXTRACT_PL #include "pimd/pim6_cmd_clippy.c" @@ -1935,6 +1936,74 @@ DEFPY (show_ipv6_mroute_summary_vrf_all, return CMD_SUCCESS; } +DEFPY (clear_ipv6_pim_statistics, + clear_ipv6_pim_statistics_cmd, + "clear ipv6 pim statistics [vrf NAME]$name", + CLEAR_STR + IPV6_STR + CLEAR_IP_PIM_STR + VRF_CMD_HELP_STR + "Reset PIM statistics\n") +{ + struct vrf *v = pim_cmd_lookup(vty, name); + + if (!v) + return CMD_WARNING; + + clear_pim_statistics(v->info); + + return CMD_SUCCESS; +} + +DEFPY (clear_ipv6_mroute, + clear_ipv6_mroute_cmd, + "clear ipv6 mroute [vrf NAME]$name", + CLEAR_STR + IPV6_STR + "Reset multicast routes\n" + VRF_CMD_HELP_STR) +{ + struct vrf *v = pim_cmd_lookup(vty, name); + + if (!v) + return CMD_WARNING; + + clear_mroute(v->info); + + return CMD_SUCCESS; +} + +DEFPY (clear_ipv6_pim_oil, + clear_ipv6_pim_oil_cmd, + "clear ipv6 pim [vrf NAME]$name oil", + CLEAR_STR + IPV6_STR + CLEAR_IP_PIM_STR + VRF_CMD_HELP_STR + "Rescan PIMv6 OIL (output interface list)\n") +{ + struct vrf *v = pim_cmd_lookup(vty, name); + + if (!v) + return CMD_WARNING; + + pim_scan_oil(v->info); + + return CMD_SUCCESS; +} + +DEFPY (clear_ipv6_mroute_count, + clear_ipv6_mroute_count_cmd, + "clear ipv6 mroute [vrf NAME]$name count", + CLEAR_STR + IPV6_STR + MROUTE_STR + VRF_CMD_HELP_STR + "Route and packet count data\n") +{ + return clear_ip_mroute_count_command(vty, name); +} + void pim_cmd_init(void) { if_cmd_init(pim_interface_config_write); @@ -2041,4 +2110,9 @@ void pim_cmd_init(void) install_element(VIEW_NODE, &show_ipv6_mroute_count_vrf_all_cmd); install_element(VIEW_NODE, &show_ipv6_mroute_summary_cmd); install_element(VIEW_NODE, &show_ipv6_mroute_summary_vrf_all_cmd); + + install_element(ENABLE_NODE, &clear_ipv6_pim_statistics_cmd); + install_element(ENABLE_NODE, &clear_ipv6_mroute_cmd); + install_element(ENABLE_NODE, &clear_ipv6_pim_oil_cmd); + install_element(ENABLE_NODE, &clear_ipv6_mroute_count_cmd); } diff --git a/pimd/pim6_cmd.h b/pimd/pim6_cmd.h index d6853a7410..b7804c0db2 100644 --- a/pimd/pim6_cmd.h +++ b/pimd/pim6_cmd.h @@ -39,6 +39,7 @@ #define IFACE_PIM_HELLO_TIME_STR "Time in seconds for Hello Interval\n" #define IFACE_PIM_HELLO_HOLD_STR "Time in seconds for Hold Interval\n" #define MROUTE_STR "IP multicast routing table\n" +#define CLEAR_IP_PIM_STR "PIM clear commands\n" #define DEBUG_MLD_STR "MLD protocol activity\n" #define DEBUG_MLD_EVENTS_STR "MLD protocol events\n" #define DEBUG_MLD_PACKETS_STR "MLD protocol packets\n" diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 7e9ce5f933..34d646ec67 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1303,27 +1303,6 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim, vty_json(vty, json); } -static void clear_pim_statistics(struct pim_instance *pim) -{ - struct interface *ifp; - - pim->bsm_rcvd = 0; - pim->bsm_sent = 0; - pim->bsm_dropped = 0; - - /* scan interfaces */ - FOR_ALL_INTERFACES (pim->vrf, ifp) { - struct pim_interface *pim_ifp = ifp->info; - - if (!pim_ifp) - continue; - - pim_ifp->pim_ifstat_bsm_cfg_miss = 0; - pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0; - pim_ifp->pim_ifstat_bsm_invalid_sz = 0; - } -} - static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj) { struct interface *ifp; @@ -1842,79 +1821,39 @@ DEFUN (clear_ip_igmp_interfaces, return CMD_SUCCESS; } -DEFUN (clear_ip_pim_statistics, +DEFPY (clear_ip_pim_statistics, clear_ip_pim_statistics_cmd, - "clear ip pim statistics [vrf NAME]", + "clear ip pim statistics [vrf NAME]$name", CLEAR_STR IP_STR CLEAR_IP_PIM_STR VRF_CMD_HELP_STR "Reset PIM statistics\n") { - int idx = 2; - struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); + struct vrf *v = pim_cmd_lookup(vty, name); - if (!vrf) + if (!v) return CMD_WARNING; - clear_pim_statistics(vrf->info); + clear_pim_statistics(v->info); + return CMD_SUCCESS; } -static void clear_mroute(struct pim_instance *pim) -{ - struct pim_upstream *up; - struct interface *ifp; - - /* scan interfaces */ - FOR_ALL_INTERFACES (pim->vrf, ifp) { - struct pim_interface *pim_ifp = ifp->info; - struct pim_ifchannel *ch; - - if (!pim_ifp) - continue; - - /* deleting all ifchannels */ - while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { - ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); - - pim_ifchannel_delete(ch); - } - -#if PIM_IPV == 4 - /* clean up all igmp groups */ - struct gm_group *grp; - - if (pim_ifp->gm_group_list) { - while (pim_ifp->gm_group_list->count) { - grp = listnode_head(pim_ifp->gm_group_list); - igmp_group_delete(grp); - } - } -#endif - } - - /* clean up all upstreams*/ - while ((up = rb_pim_upstream_first(&pim->upstream_head))) - pim_upstream_del(pim, up, __func__); - -} - -DEFUN (clear_ip_mroute, +DEFPY (clear_ip_mroute, clear_ip_mroute_cmd, - "clear ip mroute [vrf NAME]", + "clear ip mroute [vrf NAME]$name", CLEAR_STR IP_STR "Reset multicast routes\n" VRF_CMD_HELP_STR) { - int idx = 2; - struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); + struct vrf *v = pim_cmd_lookup(vty, name); - if (!vrf) + if (!v) return CMD_WARNING; - clear_mroute(vrf->info); + clear_mroute(v->info); return CMD_SUCCESS; } @@ -1985,22 +1924,21 @@ DEFUN (clear_ip_pim_interface_traffic, return CMD_SUCCESS; } -DEFUN (clear_ip_pim_oil, +DEFPY (clear_ip_pim_oil, clear_ip_pim_oil_cmd, - "clear ip pim [vrf NAME] oil", + "clear ip pim [vrf NAME]$name oil", CLEAR_STR IP_STR CLEAR_IP_PIM_STR VRF_CMD_HELP_STR "Rescan PIM OIL (output interface list)\n") { - int idx = 2; - struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); + struct vrf *v = pim_cmd_lookup(vty, name); - if (!vrf) + if (!v) return CMD_WARNING; - pim_scan_oil(vrf->info); + pim_scan_oil(v->info); return CMD_SUCCESS; } @@ -3848,47 +3786,16 @@ DEFPY (show_ip_mroute_vrf_all, return CMD_SUCCESS; } -DEFUN (clear_ip_mroute_count, +DEFPY (clear_ip_mroute_count, clear_ip_mroute_count_cmd, - "clear ip mroute [vrf NAME] count", + "clear ip mroute [vrf NAME]$name count", CLEAR_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR "Route and packet count data\n") { - int idx = 2; - struct listnode *node; - struct channel_oil *c_oil; - struct static_route *sr; - struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); - struct pim_instance *pim; - - if (!vrf) - return CMD_WARNING; - - pim = vrf->info; - frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) { - if (!c_oil->installed) - continue; - - pim_mroute_update_counters(c_oil); - c_oil->cc.origpktcnt = c_oil->cc.pktcnt; - c_oil->cc.origbytecnt = c_oil->cc.bytecnt; - c_oil->cc.origwrong_if = c_oil->cc.wrong_if; - } - - for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) { - if (!sr->c_oil.installed) - continue; - - pim_mroute_update_counters(&sr->c_oil); - - sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt; - sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt; - sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if; - } - return CMD_SUCCESS; + return clear_ip_mroute_count_command(vty, name); } DEFPY (show_ip_mroute_count, diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index 6cff3a077e..b6cb3113ec 100644 --- a/pimd/pim_cmd_common.c +++ b/pimd/pim_cmd_common.c @@ -52,6 +52,7 @@ #include "pim_nht.h" #include "pim_sock.h" #include "pim_ssm.h" +#include "pim_static.h" #include "pim_addr.h" #include "pim_static.h" @@ -3563,3 +3564,112 @@ void show_mroute_summary(struct pim_instance *pim, struct vty *vty, sg_hw_mroute_cnt); } } + +int clear_ip_mroute_count_command(struct vty *vty, const char *name) +{ + struct listnode *node; + struct channel_oil *c_oil; + struct static_route *sr; + struct vrf *v = pim_cmd_lookup(vty, name); + struct pim_instance *pim; + + if (!v) + return CMD_WARNING; + + pim = v->info; + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { + if (!c_oil->installed) + continue; + + pim_mroute_update_counters(c_oil); + c_oil->cc.origpktcnt = c_oil->cc.pktcnt; + c_oil->cc.origbytecnt = c_oil->cc.bytecnt; + c_oil->cc.origwrong_if = c_oil->cc.wrong_if; + } + + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) { + if (!sr->c_oil.installed) + continue; + + pim_mroute_update_counters(&sr->c_oil); + + sr->c_oil.cc.origpktcnt = sr->c_oil.cc.pktcnt; + sr->c_oil.cc.origbytecnt = sr->c_oil.cc.bytecnt; + sr->c_oil.cc.origwrong_if = sr->c_oil.cc.wrong_if; + } + return CMD_SUCCESS; +} + +struct vrf *pim_cmd_lookup(struct vty *vty, const char *name) +{ + struct vrf *vrf; + + if (name) + vrf = vrf_lookup_by_name(name); + else + vrf = vrf_lookup_by_id(VRF_DEFAULT); + + if (!vrf) + vty_out(vty, "Specified VRF: %s does not exist\n", name); + + return vrf; +} + +void clear_mroute(struct pim_instance *pim) +{ + struct pim_upstream *up; + struct interface *ifp; + + /* scan interfaces */ + FOR_ALL_INTERFACES (pim->vrf, ifp) { + struct pim_interface *pim_ifp = ifp->info; + struct pim_ifchannel *ch; + + if (!pim_ifp) + continue; + + /* deleting all ifchannels */ + while (!RB_EMPTY(pim_ifchannel_rb, &pim_ifp->ifchannel_rb)) { + ch = RB_ROOT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); + + pim_ifchannel_delete(ch); + } + +#if PIM_IPV == 4 + /* clean up all igmp groups */ + struct gm_group *grp; + + if (pim_ifp->gm_group_list) { + while (pim_ifp->gm_group_list->count) { + grp = listnode_head(pim_ifp->gm_group_list); + igmp_group_delete(grp); + } + } +#endif + } + + /* clean up all upstreams*/ + while ((up = rb_pim_upstream_first(&pim->upstream_head))) + pim_upstream_del(pim, up, __func__); +} + +void clear_pim_statistics(struct pim_instance *pim) +{ + struct interface *ifp; + + pim->bsm_rcvd = 0; + pim->bsm_sent = 0; + pim->bsm_dropped = 0; + + /* scan interfaces */ + FOR_ALL_INTERFACES (pim->vrf, ifp) { + struct pim_interface *pim_ifp = ifp->info; + + if (!pim_ifp) + continue; + + pim_ifp->pim_ifstat_bsm_cfg_miss = 0; + pim_ifp->pim_ifstat_ucast_bsm_cfg_miss = 0; + pim_ifp->pim_ifstat_bsm_invalid_sz = 0; + } +} diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h index 4457ea57a9..283998592f 100644 --- a/pimd/pim_cmd_common.h +++ b/pimd/pim_cmd_common.h @@ -121,6 +121,10 @@ void show_mroute_count(struct pim_instance *pim, struct vty *vty, json_object *json); void show_mroute_summary(struct pim_instance *pim, struct vty *vty, json_object *json); +int clear_ip_mroute_count_command(struct vty *vty, const char *name); +struct vrf *pim_cmd_lookup(struct vty *vty, const char *name); +void clear_mroute(struct pim_instance *pim); +void clear_pim_statistics(struct pim_instance *pim); /* * Special Macro to allow us to get the correct pim_instance;