diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 4e04a0117d..fcd12c31ed 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -378,17 +378,30 @@ cause great confusion. Source Group. The keyword `fill` says to fill in all assumed data for test/data gathering purposes. -.. index:: show ip mroute count -.. clicmd:: show ip mroute count +.. index:: show ip mroute [vrf NAME] count [json] +.. clicmd:: show ip mroute [vrf NAME] count [json] Display information about installed into the kernel S,G mroutes and in - addition display data about packet flow for the mroutes. + addition display data about packet flow for the mroutes for a specific + vrf. -.. index:: show ip mroute summary -.. clicmd:: show ip mroute summary +.. index:: show ip mroute vrf all count [json] +.. clicmd:: show ip mroute vrf all count [json] + + Display information about installed into the kernel S,G mroutes and in + addition display data about packet flow for the mroutes for all vrfs. + +.. index:: show ip mroute [vrf NAME] summary [json] +.. clicmd:: show ip mroute [vrf NAME] summary [json] Display total number of S,G mroutes and number of S,G mroutes installed - into the kernel. + into the kernel for a specific vrf. + +.. index:: show ip mroute vrf all summary [json] +.. clicmd:: show ip mroute vrf all summary [json] + + Display total number of S,G mroutes and number of S,G mroutes + installed into the kernel for all vrfs. .. index:: show ip pim assert .. clicmd:: show ip pim assert diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 3ba02d628d..6919ed9a6d 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -5929,7 +5929,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { found_oif = 0; first = 1; - if (!c_oil->installed && !uj) + if (!c_oil->installed) continue; if (sg->grp.s_addr != 0 && @@ -6078,6 +6078,8 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, json_object_int_add(json_ifp_out, "ttl", ttl); json_object_string_add(json_ifp_out, "upTime", mroute_uptime); + json_object_string_add(json_source, "flags", + state_str); if (!json_oil) { json_oil = json_object_new_object(); json_object_object_add(json_source, @@ -6381,88 +6383,112 @@ DEFUN (clear_ip_mroute_count, return CMD_SUCCESS; } -static void show_mroute_count(struct pim_instance *pim, struct vty *vty) +static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil, + json_object *json, + struct vty *vty) { - struct listnode *node; - struct channel_oil *c_oil; - struct static_route *sr; + char group_str[INET_ADDRSTRLEN]; + char source_str[INET_ADDRSTRLEN]; + json_object *json_group = NULL; + json_object *json_source = NULL; - vty_out(vty, "\n"); + if (!c_oil->installed) + return; - vty_out(vty, - "Source Group LastUsed Packets Bytes WrongIf \n"); + pim_mroute_update_counters(c_oil); - /* Print PIM and IGMP route counts */ - frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { - char group_str[INET_ADDRSTRLEN]; - char source_str[INET_ADDRSTRLEN]; + pim_inet4_dump("", c_oil->oil.mfcc_mcastgrp, group_str, + sizeof(group_str)); + pim_inet4_dump("", c_oil->oil.mfcc_origin, source_str, + sizeof(source_str)); - if (!c_oil->installed) - continue; + if (json) { + json_object_object_get_ex(json, group_str, &json_group); - pim_mroute_update_counters(c_oil); + if (!json_group) { + json_group = json_object_new_object(); + json_object_object_add(json, group_str, json_group); + } - pim_inet4_dump("", c_oil->oil.mfcc_mcastgrp, group_str, - sizeof(group_str)); - pim_inet4_dump("", c_oil->oil.mfcc_origin, source_str, - sizeof(source_str)); + json_source = json_object_new_object(); + json_object_object_add(json_group, source_str, json_source); + json_object_int_add(json_source, "lastUsed", + c_oil->cc.lastused / 100); + json_object_int_add(json_source, "packets", c_oil->cc.pktcnt); + json_object_int_add(json_source, "bytes", c_oil->cc.bytecnt); + json_object_int_add(json_source, "wrongIf", c_oil->cc.wrong_if); + } else { vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n", source_str, group_str, c_oil->cc.lastused / 100, c_oil->cc.pktcnt - c_oil->cc.origpktcnt, c_oil->cc.bytecnt - c_oil->cc.origbytecnt, c_oil->cc.wrong_if - c_oil->cc.origwrong_if); } +} - for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) { - char group_str[INET_ADDRSTRLEN]; - char source_str[INET_ADDRSTRLEN]; +static void show_mroute_count(struct pim_instance *pim, struct vty *vty, + bool uj) +{ + struct listnode *node; + struct channel_oil *c_oil; + struct static_route *sr; + json_object *json = NULL; - if (!sr->c_oil.installed) - continue; + if (uj) + json = json_object_new_object(); + else { + vty_out(vty, "\n"); - pim_mroute_update_counters(&sr->c_oil); + vty_out(vty, + "Source Group LastUsed Packets Bytes WrongIf \n"); + } - pim_inet4_dump("", sr->c_oil.oil.mfcc_mcastgrp, - group_str, sizeof(group_str)); - pim_inet4_dump("", sr->c_oil.oil.mfcc_origin, - source_str, sizeof(source_str)); + /* Print PIM and IGMP route counts */ + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) + show_mroute_count_per_channel_oil(c_oil, json, vty); - vty_out(vty, "%-15s %-15s %-8llu %-7ld %-10ld %-7ld\n", - source_str, group_str, sr->c_oil.cc.lastused, - sr->c_oil.cc.pktcnt - sr->c_oil.cc.origpktcnt, - sr->c_oil.cc.bytecnt - sr->c_oil.cc.origbytecnt, - sr->c_oil.cc.wrong_if - sr->c_oil.cc.origwrong_if); + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) + show_mroute_count_per_channel_oil(&sr->c_oil, json, vty); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); } } DEFUN (show_ip_mroute_count, show_ip_mroute_count_cmd, - "show ip mroute [vrf NAME] count", + "show ip mroute [vrf NAME] count [json]", SHOW_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR - "Route and packet count data\n") + "Route and packet count data\n" + JSON_STR) { int idx = 2; + bool uj = use_json(argc, argv); struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); if (!vrf) return CMD_WARNING; - show_mroute_count(vrf->info, vty); + show_mroute_count(vrf->info, vty, uj); return CMD_SUCCESS; } DEFUN (show_ip_mroute_count_vrf_all, show_ip_mroute_count_vrf_all_cmd, - "show ip mroute vrf all count", + "show ip mroute vrf all count [json]", SHOW_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR - "Route and packet count data\n") + "Route and packet count data\n" + JSON_STR) { bool uj = use_json(argc, argv); struct vrf *vrf; @@ -6478,7 +6504,7 @@ DEFUN (show_ip_mroute_count_vrf_all, first = false; } else vty_out(vty, "VRF: %s\n", vrf->name); - show_mroute_count(vrf->info, vty); + show_mroute_count(vrf->info, vty, uj); } if (uj) vty_out(vty, "}\n"); @@ -6486,7 +6512,8 @@ DEFUN (show_ip_mroute_count_vrf_all, return CMD_SUCCESS; } -static void show_mroute_summary(struct pim_instance *pim, struct vty *vty) +static void show_mroute_summary(struct pim_instance *pim, struct vty *vty, + json_object *json) { struct listnode *node; struct channel_oil *c_oil; @@ -6495,8 +6522,11 @@ static void show_mroute_summary(struct pim_instance *pim, struct vty *vty) uint32_t sg_sw_mroute_cnt = 0; uint32_t starg_hw_mroute_cnt = 0; uint32_t sg_hw_mroute_cnt = 0; + json_object *json_starg = NULL; + json_object *json_sg = NULL; - vty_out(vty, "Mroute Type Installed/Total\n"); + if (!json) + vty_out(vty, "Mroute Type Installed/Total\n"); frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { if (!c_oil->installed) { @@ -6526,52 +6556,110 @@ static void show_mroute_summary(struct pim_instance *pim, struct vty *vty) } } - vty_out(vty, "%-20s %d/%d\n", "(*, G)", starg_hw_mroute_cnt, - starg_sw_mroute_cnt + starg_hw_mroute_cnt); - vty_out(vty, "%-20s %d/%d\n", "(S, G)", sg_hw_mroute_cnt, - sg_sw_mroute_cnt + sg_hw_mroute_cnt); - vty_out(vty, "------\n"); - vty_out(vty, "%-20s %d/%d\n", "Total", - (starg_hw_mroute_cnt + sg_hw_mroute_cnt), - (starg_sw_mroute_cnt + - starg_hw_mroute_cnt + - sg_sw_mroute_cnt + - sg_hw_mroute_cnt)); + if (!json) { + vty_out(vty, "%-20s %u/%u\n", "(*, G)", starg_hw_mroute_cnt, + starg_sw_mroute_cnt + starg_hw_mroute_cnt); + vty_out(vty, "%-20s %u/%u\n", "(S, G)", sg_hw_mroute_cnt, + sg_sw_mroute_cnt + sg_hw_mroute_cnt); + vty_out(vty, "------\n"); + vty_out(vty, "%-20s %u/%u\n", "Total", + (starg_hw_mroute_cnt + sg_hw_mroute_cnt), + (starg_sw_mroute_cnt + starg_hw_mroute_cnt + + sg_sw_mroute_cnt + sg_hw_mroute_cnt)); + } else { + /* (*,G) route details */ + json_starg = json_object_new_object(); + json_object_object_add(json, "wildcardGroup", json_starg); + + json_object_int_add(json_starg, "installed", + starg_hw_mroute_cnt); + json_object_int_add(json_starg, "total", + starg_sw_mroute_cnt + starg_hw_mroute_cnt); + + /* (S, G) route details */ + json_sg = json_object_new_object(); + json_object_object_add(json, "sourceGroup", json_sg); + + json_object_int_add(json_sg, "installed", sg_hw_mroute_cnt); + json_object_int_add(json_sg, "total", + sg_sw_mroute_cnt + sg_hw_mroute_cnt); + + json_object_int_add(json, "totalNumOfInstalledMroutes", + starg_hw_mroute_cnt + sg_hw_mroute_cnt); + json_object_int_add(json, "totalNumOfMroutes", + starg_sw_mroute_cnt + starg_hw_mroute_cnt + + sg_sw_mroute_cnt + + sg_hw_mroute_cnt); + } } DEFUN (show_ip_mroute_summary, show_ip_mroute_summary_cmd, - "show ip mroute [vrf NAME] summary", + "show ip mroute [vrf NAME] summary [json]", SHOW_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR - "Summary of all mroutes\n") + "Summary of all mroutes\n" + JSON_STR) { int idx = 2; + bool uj = use_json(argc, argv); struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx); + json_object *json = NULL; + + if (uj) + json = json_object_new_object(); if (!vrf) return CMD_WARNING; - show_mroute_summary(vrf->info, vty); + show_mroute_summary(vrf->info, vty, json); + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } return CMD_SUCCESS; } DEFUN (show_ip_mroute_summary_vrf_all, show_ip_mroute_summary_vrf_all_cmd, - "show ip mroute vrf all summary", + "show ip mroute vrf all summary [json]", SHOW_STR IP_STR MROUTE_STR VRF_CMD_HELP_STR - "Summary of all mroutes\n") + "Summary of all mroutes\n" + JSON_STR) { struct vrf *vrf; + bool uj = use_json(argc, argv); + json_object *json = NULL; + json_object *json_vrf = NULL; + + if (uj) + json = json_object_new_object(); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - vty_out(vty, "VRF: %s\n", vrf->name); - show_mroute_summary(vrf->info, vty); + if (uj) + json_vrf = json_object_new_object(); + else + vty_out(vty, "VRF: %s\n", vrf->name); + + show_mroute_summary(vrf->info, vty, json_vrf); + + if (uj) + json_object_object_add(json, vrf->name, json_vrf); + } + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); } return CMD_SUCCESS;