mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 06:50:17 +00:00
pimd: Introduce show command for protocol counters
For all pim enabled interfaces and single pim enable interface command. Clear command to clear protocol counters stats. 'show ip pim interface traffic {WORD} {json}' 'clear ip pim interface traffic' Testing Done: bringup Pim configuration and form RPT and SPT and check show ip pim interface traffic command output, perform clear form of interface traffic command and verified all counters reset via show form of command. tor-21# show ip pim interface traffic swp2 Interface HELLO JOIN PRUNE REGISTER REGISTER-STOP ASSERT Rx/Tx Rx/Tx Rx/Tx Rx/Tx Rx/Tx Rx/Tx --------------------------------------------------------------------------------------------------------------- swp2 22/22 0/10 0/0 0/0 0/0 0/0 leaf-22# show ip pim interface traffic swp3 Interface HELLO JOIN PRUNE REGISTER REGISTER-STOP ASSERT Rx/Tx Rx/Tx Rx/Tx Rx/Tx Rx/Tx Rx/Tx --------------------------------------------------------------------------------------------------------------- swp3 23/22 10/0 0/0 0/0 0/0 0/0 spine-1#show ip pim interface traffic Interface HELLO JOIN PRUNE REGISTER REGISTER-STOP ASSERT Rx/Tx Rx/Tx Rx/Tx Rx/Tx Rx/Tx Rx/Tx --------------------------------------------------------------------------------------------------------------- br1 0/1 0/0 0/0 0/0 0/0 0/0 lo 0/0 0/0 0/0 0/0 0/0 0/0 swp1 0/1 0/0 0/0 0/0 0/0 0/0 swp2 0/1 0/0 0/0 0/0 0/0 0/0 Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
parent
e81b861617
commit
394381887e
@ -230,6 +230,7 @@ int pim_assert_recv(struct interface *ifp,
|
||||
int offset;
|
||||
uint8_t *curr;
|
||||
int curr_size;
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
|
||||
on_trace(__PRETTY_FUNCTION__, ifp, src_addr);
|
||||
|
||||
@ -311,6 +312,10 @@ int pim_assert_recv(struct interface *ifp,
|
||||
|
||||
msg_metric.ip_address = src_addr;
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
zassert(pim_ifp);
|
||||
++pim_ifp->pim_ifstat_assert_recv;
|
||||
|
||||
return dispatch_assert(ifp,
|
||||
msg_source_addr.u.prefix4,
|
||||
sg.grp,
|
||||
@ -473,6 +478,7 @@ static int pim_assert_do(struct pim_ifchannel *ch,
|
||||
metric.route_metric,
|
||||
PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
|
||||
}
|
||||
++pim_ifp->pim_ifstat_assert_send;
|
||||
|
||||
if (pim_msg_send(pim_ifp->pim_sock_fd,
|
||||
pim_ifp->primary_address,
|
||||
|
238
pimd/pim_cmd.c
238
pimd/pim_cmd.c
@ -1123,6 +1123,163 @@ static void pim_show_interfaces(struct vty *vty, u_char uj)
|
||||
json_object_free(json);
|
||||
}
|
||||
|
||||
static void pim_show_interface_traffic (struct vty *vty, u_char uj)
|
||||
{
|
||||
struct interface *ifp = NULL;
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
struct listnode *node = NULL;
|
||||
json_object *json = NULL;
|
||||
json_object *json_row = NULL;
|
||||
|
||||
if (uj)
|
||||
json = json_object_new_object ();
|
||||
else
|
||||
{
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
|
||||
" HELLO", " JOIN", " PRUNE", " REGISTER",
|
||||
" REGISTER-STOP", " ASSERT", VTY_NEWLINE);
|
||||
vty_out (vty,
|
||||
"%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
|
||||
"", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
|
||||
" Rx/Tx", " Rx/Tx", VTY_NEWLINE);
|
||||
vty_out (vty,
|
||||
"---------------------------------------------------------------------------------------------------------------%s",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
|
||||
{
|
||||
pim_ifp = ifp->info;
|
||||
|
||||
if (!pim_ifp)
|
||||
continue;
|
||||
|
||||
if (pim_ifp->pim_sock_fd < 0)
|
||||
continue;
|
||||
if (uj)
|
||||
{
|
||||
json_row = json_object_new_object ();
|
||||
json_object_pim_ifp_add (json_row, ifp);
|
||||
json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
|
||||
json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
|
||||
json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
|
||||
json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
|
||||
json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
|
||||
json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
|
||||
json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
|
||||
json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
|
||||
json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
|
||||
json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
|
||||
|
||||
json_object_object_add (json, ifp->name, json_row);
|
||||
}
|
||||
else
|
||||
{
|
||||
vty_out (vty,
|
||||
"%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
|
||||
ifp->name, pim_ifp->pim_ifstat_hello_recv,
|
||||
pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
|
||||
pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
|
||||
pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
|
||||
pim_ifp->pim_ifstat_reg_send,
|
||||
pim_ifp->pim_ifstat_reg_stop_recv,
|
||||
pim_ifp->pim_ifstat_reg_stop_send,
|
||||
pim_ifp->pim_ifstat_assert_recv,
|
||||
pim_ifp->pim_ifstat_assert_send, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
if (uj)
|
||||
{
|
||||
vty_out (vty, "%s%s", json_object_to_json_string_ext (json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
|
||||
json_object_free (json);
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_show_interface_traffic_single (struct vty *vty, const char *ifname, u_char uj)
|
||||
{
|
||||
struct interface *ifp = NULL;
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
struct listnode *node = NULL;
|
||||
json_object *json = NULL;
|
||||
json_object *json_row = NULL;
|
||||
uint8_t found_ifname = 0;
|
||||
|
||||
if (uj)
|
||||
json = json_object_new_object ();
|
||||
else
|
||||
{
|
||||
vty_out (vty, "%s", VTY_NEWLINE);
|
||||
vty_out (vty, "%-12s%-17s%-17s%-17s%-17s%-17s%-17s%s", "Interface",
|
||||
" HELLO", " JOIN", " PRUNE", " REGISTER",
|
||||
" REGISTER-STOP", " ASSERT", VTY_NEWLINE);
|
||||
vty_out (vty,
|
||||
"%-10s%-18s%-17s%-17s%-17s%-17s%-17s%s",
|
||||
"", " Rx/Tx", " Rx/Tx", " Rx/Tx", " Rx/Tx",
|
||||
" Rx/Tx", " Rx/Tx", VTY_NEWLINE);
|
||||
vty_out (vty,
|
||||
"---------------------------------------------------------------------------------------------------------------%s",
|
||||
VTY_NEWLINE);
|
||||
}
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
|
||||
{
|
||||
if (strcmp (ifname, ifp->name))
|
||||
continue;
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
|
||||
if (!pim_ifp)
|
||||
continue;
|
||||
|
||||
if (pim_ifp->pim_sock_fd < 0)
|
||||
continue;
|
||||
|
||||
found_ifname = 1;
|
||||
if (uj)
|
||||
{
|
||||
json_row = json_object_new_object ();
|
||||
json_object_pim_ifp_add (json_row, ifp);
|
||||
json_object_int_add (json_row, "helloRx", pim_ifp->pim_ifstat_hello_recv);
|
||||
json_object_int_add (json_row, "helloTx", pim_ifp->pim_ifstat_hello_sent);
|
||||
json_object_int_add (json_row, "joinRx", pim_ifp->pim_ifstat_join_recv);
|
||||
json_object_int_add (json_row, "joinTx", pim_ifp->pim_ifstat_join_send);
|
||||
json_object_int_add (json_row, "registerRx", pim_ifp->pim_ifstat_reg_recv);
|
||||
json_object_int_add (json_row, "registerTx", pim_ifp->pim_ifstat_reg_recv);
|
||||
json_object_int_add (json_row, "registerStopRx", pim_ifp->pim_ifstat_reg_stop_recv);
|
||||
json_object_int_add (json_row, "registerStopTx", pim_ifp->pim_ifstat_reg_stop_send);
|
||||
json_object_int_add (json_row, "assertRx", pim_ifp->pim_ifstat_assert_recv);
|
||||
json_object_int_add (json_row, "assertTx", pim_ifp->pim_ifstat_assert_send);
|
||||
|
||||
json_object_object_add (json, ifp->name, json_row);
|
||||
}
|
||||
else
|
||||
{
|
||||
vty_out (vty,
|
||||
"%-10s %8u/%-8u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %7u/%-7u %s",
|
||||
ifp->name, pim_ifp->pim_ifstat_hello_recv,
|
||||
pim_ifp->pim_ifstat_hello_sent, pim_ifp->pim_ifstat_join_recv,
|
||||
pim_ifp->pim_ifstat_join_send, pim_ifp->pim_ifstat_prune_recv,
|
||||
pim_ifp->pim_ifstat_prune_send, pim_ifp->pim_ifstat_reg_recv,
|
||||
pim_ifp->pim_ifstat_reg_send,
|
||||
pim_ifp->pim_ifstat_reg_stop_recv,
|
||||
pim_ifp->pim_ifstat_reg_stop_send,
|
||||
pim_ifp->pim_ifstat_assert_recv,
|
||||
pim_ifp->pim_ifstat_assert_send, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
if (uj)
|
||||
{
|
||||
vty_out (vty, "%s%s", json_object_to_json_string_ext (json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
|
||||
json_object_free (json);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!found_ifname)
|
||||
vty_out (vty, "%% No such interface%s", VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
static void pim_show_join(struct vty *vty, u_char uj)
|
||||
{
|
||||
struct pim_interface *pim_ifp;
|
||||
@ -2497,6 +2654,45 @@ DEFUN (clear_ip_pim_interfaces,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (clear_ip_pim_interface_traffic,
|
||||
clear_ip_pim_interface_traffic_cmd,
|
||||
"clear ip pim interface traffic",
|
||||
"Reset functions\n"
|
||||
"IP information\n"
|
||||
"PIM clear commands\n"
|
||||
"Reset PIM interfaces\n"
|
||||
"Reset Protocol Packet counters\n")
|
||||
{
|
||||
struct listnode *ifnode = NULL;
|
||||
struct listnode *ifnextnode = NULL;
|
||||
struct interface *ifp = NULL;
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
|
||||
for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), ifnode, ifnextnode, ifp))
|
||||
{
|
||||
pim_ifp = ifp->info;
|
||||
|
||||
if (!pim_ifp)
|
||||
continue;
|
||||
|
||||
pim_ifp->pim_ifstat_hello_recv = 0;
|
||||
pim_ifp->pim_ifstat_hello_sent = 0;
|
||||
pim_ifp->pim_ifstat_join_recv = 0;
|
||||
pim_ifp->pim_ifstat_join_send = 0;
|
||||
pim_ifp->pim_ifstat_prune_recv = 0;
|
||||
pim_ifp->pim_ifstat_prune_send = 0;
|
||||
pim_ifp->pim_ifstat_reg_recv = 0;
|
||||
pim_ifp->pim_ifstat_reg_send = 0;
|
||||
pim_ifp->pim_ifstat_reg_stop_recv = 0;
|
||||
pim_ifp->pim_ifstat_reg_stop_send = 0;
|
||||
pim_ifp->pim_ifstat_assert_recv = 0;
|
||||
pim_ifp->pim_ifstat_assert_send = 0;
|
||||
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (clear_ip_pim_oil,
|
||||
clear_ip_pim_oil_cmd,
|
||||
"clear ip pim oil",
|
||||
@ -2883,7 +3079,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
|
||||
char nexthop_addr_str[PREFIX_STRLEN];
|
||||
char grp_str[PREFIX_STRLEN];
|
||||
|
||||
addr_str = (const char *)argv[0];
|
||||
addr_str = argv[4]->arg;
|
||||
result = inet_pton (AF_INET, addr_str, &src_addr);
|
||||
if (result <= 0)
|
||||
{
|
||||
@ -2898,7 +3094,7 @@ DEFUN (show_ip_pim_nexthop_lookup,
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
addr_str1 = (const char *)argv[1];
|
||||
addr_str1 = argv[5]->arg;
|
||||
result = inet_pton (AF_INET, addr_str1, &grp_addr);
|
||||
if (result <= 0)
|
||||
{
|
||||
@ -2942,6 +3138,41 @@ DEFUN (show_ip_pim_nexthop_lookup,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ip_pim_interface_traffic,
|
||||
show_ip_pim_interface_traffic_cmd,
|
||||
"show ip pim interface traffic {json}",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
"PIM interface information\n"
|
||||
"Protocol Packet counters\n"
|
||||
"JavaScript Object Notation\n")
|
||||
{
|
||||
u_char uj = use_json (argc, argv);
|
||||
|
||||
pim_show_interface_traffic (vty, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ip_pim_interface_traffic_single,
|
||||
show_ip_pim_interface_traffic_single_cmd,
|
||||
"show ip pim interface traffic (WORD) {json}",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
"PIM interface information\n"
|
||||
"Protocol Packet counters\n")
|
||||
{
|
||||
u_char uj = use_json (argc, argv);
|
||||
const char *if_str;
|
||||
if_str = argv[5]->arg;
|
||||
|
||||
pim_show_interface_traffic_single (vty, if_str, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void show_multicast_interfaces(struct vty *vty)
|
||||
{
|
||||
struct listnode *node;
|
||||
@ -6497,6 +6728,8 @@ void pim_cmd_init()
|
||||
install_element (VIEW_NODE, &show_ip_pim_assert_internal_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_assert_metric_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_assert_winner_metric_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_interface_traffic_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_interface_traffic_single_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_interface_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_join_cmd);
|
||||
install_element (VIEW_NODE, &show_ip_pim_local_membership_cmd);
|
||||
@ -6521,6 +6754,7 @@ void pim_cmd_init()
|
||||
install_element (ENABLE_NODE, &clear_ip_igmp_interfaces_cmd);
|
||||
install_element (ENABLE_NODE, &clear_ip_mroute_cmd);
|
||||
install_element (ENABLE_NODE, &clear_ip_pim_interfaces_cmd);
|
||||
install_element (ENABLE_NODE, &clear_ip_pim_interface_traffic_cmd);
|
||||
install_element (ENABLE_NODE, &clear_ip_pim_oil_cmd);
|
||||
|
||||
install_element (ENABLE_NODE, &debug_igmp_cmd);
|
||||
|
@ -118,6 +118,16 @@ struct pim_interface {
|
||||
uint32_t pim_ifstat_hello_sendfail;
|
||||
uint32_t pim_ifstat_hello_recv;
|
||||
uint32_t pim_ifstat_hello_recvfail;
|
||||
uint32_t pim_ifstat_join_recv;
|
||||
uint32_t pim_ifstat_join_send;
|
||||
uint32_t pim_ifstat_prune_recv;
|
||||
uint32_t pim_ifstat_prune_send;
|
||||
uint32_t pim_ifstat_reg_recv;
|
||||
uint32_t pim_ifstat_reg_send;
|
||||
uint32_t pim_ifstat_reg_stop_recv;
|
||||
uint32_t pim_ifstat_reg_stop_send;
|
||||
uint32_t pim_ifstat_assert_recv;
|
||||
uint32_t pim_ifstat_assert_send;
|
||||
};
|
||||
|
||||
extern struct interface *pim_regiface;
|
||||
|
@ -59,6 +59,8 @@ static void recv_join(struct interface *ifp,
|
||||
struct prefix_sg *sg,
|
||||
uint8_t source_flags)
|
||||
{
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
|
||||
if (PIM_DEBUG_PIM_TRACE) {
|
||||
char up_str[INET_ADDRSTRLEN];
|
||||
char neigh_str[INET_ADDRSTRLEN];
|
||||
@ -72,6 +74,11 @@ static void recv_join(struct interface *ifp,
|
||||
up_str, holdtime, neigh_str, ifp->name);
|
||||
}
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
zassert(pim_ifp);
|
||||
|
||||
++pim_ifp->pim_ifstat_join_recv;
|
||||
|
||||
/*
|
||||
* If the RPT and WC are set it's a (*,G)
|
||||
* and the source is the RP
|
||||
@ -104,6 +111,8 @@ static void recv_prune(struct interface *ifp,
|
||||
struct prefix_sg *sg,
|
||||
uint8_t source_flags)
|
||||
{
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
|
||||
if (PIM_DEBUG_PIM_TRACE) {
|
||||
char up_str[INET_ADDRSTRLEN];
|
||||
char neigh_str[INET_ADDRSTRLEN];
|
||||
@ -117,6 +126,11 @@ static void recv_prune(struct interface *ifp,
|
||||
up_str, holdtime, neigh_str, ifp->name);
|
||||
}
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
zassert(pim_ifp);
|
||||
|
||||
++pim_ifp->pim_ifstat_prune_recv;
|
||||
|
||||
if ((source_flags & PIM_RPT_BIT_MASK) &&
|
||||
(source_flags & PIM_WILDCARD_BIT_MASK))
|
||||
{
|
||||
@ -495,6 +509,9 @@ int pim_joinprune_send(struct pim_rpf *rpf,
|
||||
packet_size += group_size;
|
||||
pim_msg_build_jp_groups (grp, group, group_size);
|
||||
|
||||
pim_ifp->pim_ifstat_join_send += ntohs(grp->joins);
|
||||
pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes);
|
||||
|
||||
grp = (struct pim_jp_groups *)curr_ptr;
|
||||
if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255)
|
||||
{
|
||||
|
@ -110,6 +110,7 @@ pim_register_stop_send (struct interface *ifp, struct prefix_sg *sg,
|
||||
__PRETTY_FUNCTION__, ifp->name);
|
||||
}
|
||||
}
|
||||
++pinfo->pim_ifstat_reg_stop_send;
|
||||
}
|
||||
|
||||
int
|
||||
@ -205,6 +206,8 @@ pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct
|
||||
|
||||
pim_msg_build_header(buffer, buf_size + PIM_MSG_REGISTER_LEN, PIM_MSG_TYPE_REGISTER);
|
||||
|
||||
++pinfo->pim_ifstat_reg_send;
|
||||
|
||||
if (pim_msg_send(pinfo->pim_sock_fd,
|
||||
src,
|
||||
rpg->rpf_addr.u.prefix4,
|
||||
@ -274,6 +277,7 @@ pim_register_recv (struct interface *ifp,
|
||||
struct prefix_sg sg;
|
||||
uint32_t *bits;
|
||||
int i_am_rp = 0;
|
||||
struct pim_interface *pim_ifp = NULL;
|
||||
|
||||
#define PIM_MSG_REGISTER_BIT_RESERVED_LEN 4
|
||||
ip_hdr = (struct ip *)(tlv_buf + PIM_MSG_REGISTER_BIT_RESERVED_LEN);
|
||||
@ -289,6 +293,10 @@ pim_register_recv (struct interface *ifp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
pim_ifp = ifp->info;
|
||||
zassert(pim_ifp);
|
||||
++pim_ifp->pim_ifstat_reg_recv;
|
||||
|
||||
/*
|
||||
* Please note this is not drawn to get the correct bit/data size
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user