From 3b767e4b6d031795c78216e3460a38d519cedde1 Mon Sep 17 00:00:00 2001 From: Abhishek N R Date: Thu, 7 Apr 2022 22:42:03 -0700 Subject: [PATCH] pimd: Moving the common functions from pim_cmd.c Moving the functions that are used by both IPV4 and IPV6 to a common file pim_cmd_common.c file Signed-off-by: Abhishek N R --- pimd/pim_cmd.c | 530 ----------------------------------------- pimd/pim_cmd_common.c | 532 ++++++++++++++++++++++++++++++++++++++++++ pimd/pim_cmd_common.h | 6 + 3 files changed, 538 insertions(+), 530 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 75fc903020..f49b7a21fb 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3766,383 +3766,6 @@ DEFPY (show_ip_multicast_count_vrf_all, return CMD_SUCCESS; } -static void show_mroute(struct pim_instance *pim, struct vty *vty, - pim_sgaddr *sg, bool fill, bool uj) -{ - struct listnode *node; - struct channel_oil *c_oil; - struct static_route *s_route; - time_t now; - json_object *json = NULL; - json_object *json_group = NULL; - json_object *json_source = NULL; - json_object *json_oil = NULL; - json_object *json_ifp_out = NULL; - int found_oif; - int first; - char grp_str[INET_ADDRSTRLEN]; - char src_str[INET_ADDRSTRLEN]; - char in_ifname[INTERFACE_NAMSIZ + 1]; - char out_ifname[INTERFACE_NAMSIZ + 1]; - int oif_vif_index; - struct interface *ifp_in; - char proto[100]; - char state_str[PIM_REG_STATE_STR_LEN]; - char mroute_uptime[10]; - - if (uj) { - json = json_object_new_object(); - } else { - vty_out(vty, "IP Multicast Routing Table\n"); - vty_out(vty, "Flags: S - Sparse, C - Connected, P - Pruned\n"); - vty_out(vty, - " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n"); - vty_out(vty, - "\nSource Group Flags Proto Input Output TTL Uptime\n"); - } - - now = pim_time_monotonic_sec(); - - /* print list of PIM and IGMP routes */ - frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { - found_oif = 0; - first = 1; - if (!c_oil->installed) - continue; - - if (!pim_addr_is_any(sg->grp) && - pim_addr_cmp(sg->grp, c_oil->oil.mfcc_mcastgrp)) - continue; - if (!pim_addr_is_any(sg->src) && - pim_addr_cmp(sg->src, c_oil->oil.mfcc_origin)) - continue; - - pim_inet4_dump("", c_oil->oil.mfcc_mcastgrp, grp_str, - sizeof(grp_str)); - pim_inet4_dump("", c_oil->oil.mfcc_origin, src_str, - sizeof(src_str)); - - strlcpy(state_str, "S", sizeof(state_str)); - /* When a non DR receives a igmp join, it creates a (*,G) - * channel_oil without any upstream creation */ - if (c_oil->up) { - if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil->up->flags)) - strlcat(state_str, "C", sizeof(state_str)); - if (pim_upstream_is_sg_rpt(c_oil->up)) - strlcat(state_str, "R", sizeof(state_str)); - if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil->up->flags)) - strlcat(state_str, "F", sizeof(state_str)); - if (c_oil->up->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) - strlcat(state_str, "T", sizeof(state_str)); - } - if (pim_channel_oil_empty(c_oil)) - strlcat(state_str, "P", sizeof(state_str)); - - ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent); - - if (ifp_in) - strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname)); - else - strlcpy(in_ifname, "", sizeof(in_ifname)); - - - pim_time_uptime(mroute_uptime, sizeof(mroute_uptime), - now - c_oil->mroute_creation); - - if (uj) { - - /* Find the group, create it if it doesn't exist */ - json_object_object_get_ex(json, grp_str, &json_group); - - if (!json_group) { - json_group = json_object_new_object(); - json_object_object_add(json, grp_str, - json_group); - } - - /* Find the source nested under the group, create it if - * it doesn't exist - */ - json_object_object_get_ex(json_group, src_str, - &json_source); - - if (!json_source) { - json_source = json_object_new_object(); - json_object_object_add(json_group, src_str, - json_source); - } - - /* Find the inbound interface nested under the source, - * create it if it doesn't exist */ - json_object_string_add(json_source, "source", - src_str); - json_object_string_add(json_source, "group", - grp_str); - json_object_int_add(json_source, "installed", - c_oil->installed); - json_object_int_add(json_source, "refCount", - c_oil->oil_ref_count); - json_object_int_add(json_source, "oilSize", - c_oil->oil_size); - json_object_int_add(json_source, "OilInheritedRescan", - c_oil->oil_inherited_rescan); - json_object_int_add(json_source, "oilInheritedRescan", - c_oil->oil_inherited_rescan); - json_object_string_add(json_source, "iif", in_ifname); - json_object_string_add(json_source, "upTime", - mroute_uptime); - json_oil = NULL; - } - - for (oif_vif_index = 0; oif_vif_index < MAXVIFS; - ++oif_vif_index) { - struct interface *ifp_out; - int ttl; - - ttl = c_oil->oil.mfcc_ttls[oif_vif_index]; - if (ttl < 1) - continue; - - /* do not display muted OIFs */ - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_MUTE) - continue; - - if (c_oil->oil.mfcc_parent == oif_vif_index && - !pim_mroute_allow_iif_in_oil(c_oil, - oif_vif_index)) - continue; - - ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index); - found_oif = 1; - - if (ifp_out) - strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname)); - else - strlcpy(out_ifname, "", sizeof(out_ifname)); - - if (uj) { - json_ifp_out = json_object_new_object(); - json_object_string_add(json_ifp_out, "source", - src_str); - json_object_string_add(json_ifp_out, "group", - grp_str); - - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_PROTO_PIM) - json_object_boolean_true_add( - json_ifp_out, "protocolPim"); - - if (c_oil->oif_flags[oif_vif_index] & - PIM_OIF_FLAG_PROTO_GM) - json_object_boolean_true_add( - json_ifp_out, "protocolIgmp"); - - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_PROTO_VXLAN) - json_object_boolean_true_add( - json_ifp_out, "protocolVxlan"); - - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_PROTO_STAR) - json_object_boolean_true_add( - json_ifp_out, - "protocolInherited"); - - json_object_string_add(json_ifp_out, - "inboundInterface", - in_ifname); - json_object_int_add(json_ifp_out, "iVifI", - c_oil->oil.mfcc_parent); - json_object_string_add(json_ifp_out, - "outboundInterface", - out_ifname); - json_object_int_add(json_ifp_out, "oVifI", - oif_vif_index); - 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, - "oil", json_oil); - } - json_object_object_add(json_oil, out_ifname, - json_ifp_out); - } else { - proto[0] = '\0'; - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_PROTO_PIM) { - strlcpy(proto, "PIM", sizeof(proto)); - } - - if (c_oil->oif_flags[oif_vif_index] & - PIM_OIF_FLAG_PROTO_GM) { - strlcpy(proto, "IGMP", sizeof(proto)); - } - - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_PROTO_VXLAN) { - strlcpy(proto, "VxLAN", sizeof(proto)); - } - - if (c_oil->oif_flags[oif_vif_index] - & PIM_OIF_FLAG_PROTO_STAR) { - strlcpy(proto, "STAR", sizeof(proto)); - } - - vty_out(vty, - "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", - src_str, grp_str, state_str, proto, - in_ifname, out_ifname, ttl, - mroute_uptime); - - if (first) { - src_str[0] = '\0'; - grp_str[0] = '\0'; - in_ifname[0] = '\0'; - state_str[0] = '\0'; - mroute_uptime[0] = '\0'; - first = 0; - } - } - } - - if (!uj && !found_oif) { - vty_out(vty, - "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", - src_str, grp_str, state_str, "none", in_ifname, - "none", 0, "--:--:--"); - } - } - - /* Print list of static routes */ - for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) { - first = 1; - - if (!s_route->c_oil.installed) - continue; - - pim_inet4_dump("", s_route->group, grp_str, - sizeof(grp_str)); - pim_inet4_dump("", s_route->source, src_str, - sizeof(src_str)); - ifp_in = pim_if_find_by_vif_index(pim, s_route->iif); - found_oif = 0; - - if (ifp_in) - strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname)); - else - strlcpy(in_ifname, "", sizeof(in_ifname)); - - if (uj) { - - /* Find the group, create it if it doesn't exist */ - json_object_object_get_ex(json, grp_str, &json_group); - - if (!json_group) { - json_group = json_object_new_object(); - json_object_object_add(json, grp_str, - json_group); - } - - /* Find the source nested under the group, create it if - * it doesn't exist */ - json_object_object_get_ex(json_group, src_str, - &json_source); - - if (!json_source) { - json_source = json_object_new_object(); - json_object_object_add(json_group, src_str, - json_source); - } - - json_object_string_add(json_source, "iif", in_ifname); - json_oil = NULL; - } else { - strlcpy(proto, "STATIC", sizeof(proto)); - } - - for (oif_vif_index = 0; oif_vif_index < MAXVIFS; - ++oif_vif_index) { - struct interface *ifp_out; - char oif_uptime[10]; - int ttl; - - ttl = s_route->oif_ttls[oif_vif_index]; - if (ttl < 1) - continue; - - ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index); - pim_time_uptime( - oif_uptime, sizeof(oif_uptime), - now - - s_route->c_oil - .oif_creation[oif_vif_index]); - found_oif = 1; - - if (ifp_out) - strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname)); - else - strlcpy(out_ifname, "", sizeof(out_ifname)); - - if (uj) { - json_ifp_out = json_object_new_object(); - json_object_string_add(json_ifp_out, "source", - src_str); - json_object_string_add(json_ifp_out, "group", - grp_str); - json_object_boolean_true_add(json_ifp_out, - "protocolStatic"); - json_object_string_add(json_ifp_out, - "inboundInterface", - in_ifname); - json_object_int_add( - json_ifp_out, "iVifI", - s_route->c_oil.oil.mfcc_parent); - json_object_string_add(json_ifp_out, - "outboundInterface", - out_ifname); - json_object_int_add(json_ifp_out, "oVifI", - oif_vif_index); - json_object_int_add(json_ifp_out, "ttl", ttl); - json_object_string_add(json_ifp_out, "upTime", - oif_uptime); - if (!json_oil) { - json_oil = json_object_new_object(); - json_object_object_add(json_source, - "oil", json_oil); - } - json_object_object_add(json_oil, out_ifname, - json_ifp_out); - } else { - vty_out(vty, - "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", - src_str, grp_str, "-", proto, in_ifname, - out_ifname, ttl, oif_uptime); - if (first && !fill) { - src_str[0] = '\0'; - grp_str[0] = '\0'; - in_ifname[0] = '\0'; - first = 0; - } - } - } - - if (!uj && !found_oif) { - vty_out(vty, - "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", - src_str, grp_str, "-", proto, in_ifname, "none", - 0, "--:--:--"); - } - } - - if (uj) - vty_json(vty, json); -} - DEFPY (show_ip_mroute, show_ip_mroute_cmd, "show ip mroute [vrf NAME] [A.B.C.D$s_or_g [A.B.C.D$g]] [fill$fill] [json$json]", @@ -4264,78 +3887,6 @@ DEFUN (clear_ip_mroute_count, return CMD_SUCCESS; } -static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil, - json_object *json, - struct vty *vty) -{ - char group_str[INET_ADDRSTRLEN]; - char source_str[INET_ADDRSTRLEN]; - json_object *json_group = NULL; - json_object *json_source = NULL; - - if (!c_oil->installed) - return; - - pim_mroute_update_counters(c_oil); - - 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 (json) { - json_object_object_get_ex(json, group_str, &json_group); - - if (!json_group) { - json_group = json_object_new_object(); - json_object_object_add(json, group_str, json_group); - } - - 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); - } -} - -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 (uj) - json = json_object_new_object(); - else { - vty_out(vty, "\n"); - - vty_out(vty, - "Source Group LastUsed Packets Bytes WrongIf \n"); - } - - /* 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); - - for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) - show_mroute_count_per_channel_oil(&sr->c_oil, json, vty); - - if (uj) - vty_json(vty, json); -} - DEFUN (show_ip_mroute_count, show_ip_mroute_count_cmd, "show ip mroute [vrf NAME] count [json]", @@ -4389,87 +3940,6 @@ DEFUN (show_ip_mroute_count_vrf_all, return CMD_SUCCESS; } -static void show_mroute_summary(struct pim_instance *pim, struct vty *vty, - json_object *json) -{ - struct listnode *node; - struct channel_oil *c_oil; - struct static_route *s_route; - uint32_t starg_sw_mroute_cnt = 0; - 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; - - 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) { - if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) - starg_sw_mroute_cnt++; - else - sg_sw_mroute_cnt++; - } else { - if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) - starg_hw_mroute_cnt++; - else - sg_hw_mroute_cnt++; - } - } - - for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) { - if (!s_route->c_oil.installed) { - if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY) - starg_sw_mroute_cnt++; - else - sg_sw_mroute_cnt++; - } else { - if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY) - starg_hw_mroute_cnt++; - else - 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 [json]", diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index 5bcde48e2e..bd7b802afa 100644 --- a/pimd/pim_cmd_common.c +++ b/pimd/pim_cmd_common.c @@ -52,6 +52,7 @@ #include "pim_sock.h" #include "pim_ssm.h" #include "pim_addr.h" +#include "pim_static.h" /** * Get current node VRF name. @@ -3007,3 +3008,534 @@ void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vty *vty) show_multicast_interfaces(pim, vty, NULL); } +#if PIM_IPV == 4 +void show_mroute(struct pim_instance *pim, struct vty *vty, + pim_sgaddr *sg, bool fill, bool uj) +{ + struct listnode *node; + struct channel_oil *c_oil; + struct static_route *s_route; + time_t now; + json_object *json = NULL; + json_object *json_group = NULL; + json_object *json_source = NULL; + json_object *json_oil = NULL; + json_object *json_ifp_out = NULL; + int found_oif; + int first; + char grp_str[INET_ADDRSTRLEN]; + char src_str[INET_ADDRSTRLEN]; + char in_ifname[INTERFACE_NAMSIZ + 1]; + char out_ifname[INTERFACE_NAMSIZ + 1]; + int oif_vif_index; + struct interface *ifp_in; + char proto[100]; + char state_str[PIM_REG_STATE_STR_LEN]; + char mroute_uptime[10]; + + if (uj) { + json = json_object_new_object(); + } else { + vty_out(vty, "IP Multicast Routing Table\n"); + vty_out(vty, "Flags: S - Sparse, C - Connected, P - Pruned\n"); + vty_out(vty, + " R - SGRpt Pruned, F - Register flag, T - SPT-bit set\n"); + vty_out(vty, + "\nSource Group Flags Proto Input Output TTL Uptime\n"); + } + + now = pim_time_monotonic_sec(); + + /* print list of PIM and IGMP routes */ + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { + found_oif = 0; + first = 1; + if (!c_oil->installed) + continue; + + if (!pim_addr_is_any(sg->grp) && + pim_addr_cmp(sg->grp, c_oil->oil.mfcc_mcastgrp)) + continue; + if (!pim_addr_is_any(sg->src) && + pim_addr_cmp(sg->src, c_oil->oil.mfcc_origin)) + continue; + + pim_inet4_dump("", c_oil->oil.mfcc_mcastgrp, grp_str, + sizeof(grp_str)); + pim_inet4_dump("", c_oil->oil.mfcc_origin, src_str, + sizeof(src_str)); + + strlcpy(state_str, "S", sizeof(state_str)); + /* When a non DR receives a igmp join, it creates a (*,G) + * channel_oil without any upstream creation */ + if (c_oil->up) { + if (PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(c_oil->up->flags)) + strlcat(state_str, "C", sizeof(state_str)); + if (pim_upstream_is_sg_rpt(c_oil->up)) + strlcat(state_str, "R", sizeof(state_str)); + if (PIM_UPSTREAM_FLAG_TEST_FHR(c_oil->up->flags)) + strlcat(state_str, "F", sizeof(state_str)); + if (c_oil->up->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) + strlcat(state_str, "T", sizeof(state_str)); + } + if (pim_channel_oil_empty(c_oil)) + strlcat(state_str, "P", sizeof(state_str)); + + ifp_in = pim_if_find_by_vif_index(pim, c_oil->oil.mfcc_parent); + + if (ifp_in) + strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname)); + else + strlcpy(in_ifname, "", sizeof(in_ifname)); + + + pim_time_uptime(mroute_uptime, sizeof(mroute_uptime), + now - c_oil->mroute_creation); + + if (uj) { + + /* Find the group, create it if it doesn't exist */ + json_object_object_get_ex(json, grp_str, &json_group); + + if (!json_group) { + json_group = json_object_new_object(); + json_object_object_add(json, grp_str, + json_group); + } + + /* Find the source nested under the group, create it if + * it doesn't exist + */ + json_object_object_get_ex(json_group, src_str, + &json_source); + + if (!json_source) { + json_source = json_object_new_object(); + json_object_object_add(json_group, src_str, + json_source); + } + + /* Find the inbound interface nested under the source, + * create it if it doesn't exist */ + json_object_string_add(json_source, "source", + src_str); + json_object_string_add(json_source, "group", + grp_str); + json_object_int_add(json_source, "installed", + c_oil->installed); + json_object_int_add(json_source, "refCount", + c_oil->oil_ref_count); + json_object_int_add(json_source, "oilSize", + c_oil->oil_size); + json_object_int_add(json_source, "OilInheritedRescan", + c_oil->oil_inherited_rescan); + json_object_int_add(json_source, "oilInheritedRescan", + c_oil->oil_inherited_rescan); + json_object_string_add(json_source, "iif", in_ifname); + json_object_string_add(json_source, "upTime", + mroute_uptime); + json_oil = NULL; + } + + for (oif_vif_index = 0; oif_vif_index < MAXVIFS; + ++oif_vif_index) { + struct interface *ifp_out; + int ttl; + + ttl = c_oil->oil.mfcc_ttls[oif_vif_index]; + if (ttl < 1) + continue; + + /* do not display muted OIFs */ + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_MUTE) + continue; + + if (c_oil->oil.mfcc_parent == oif_vif_index && + !pim_mroute_allow_iif_in_oil(c_oil, + oif_vif_index)) + continue; + + ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index); + found_oif = 1; + + if (ifp_out) + strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname)); + else + strlcpy(out_ifname, "", sizeof(out_ifname)); + + if (uj) { + json_ifp_out = json_object_new_object(); + json_object_string_add(json_ifp_out, "source", + src_str); + json_object_string_add(json_ifp_out, "group", + grp_str); + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_PIM) + json_object_boolean_true_add( + json_ifp_out, "protocolPim"); + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_IGMP) + json_object_boolean_true_add( + json_ifp_out, "protocolIgmp"); + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_VXLAN) + json_object_boolean_true_add( + json_ifp_out, "protocolVxlan"); + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_STAR) + json_object_boolean_true_add( + json_ifp_out, + "protocolInherited"); + + json_object_string_add(json_ifp_out, + "inboundInterface", + in_ifname); + json_object_int_add(json_ifp_out, "iVifI", + c_oil->oil.mfcc_parent); + json_object_string_add(json_ifp_out, + "outboundInterface", + out_ifname); + json_object_int_add(json_ifp_out, "oVifI", + oif_vif_index); + 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, + "oil", json_oil); + } + json_object_object_add(json_oil, out_ifname, + json_ifp_out); + } else { + proto[0] = '\0'; + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_PIM) { + strlcpy(proto, "PIM", sizeof(proto)); + } + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_IGMP) { + strlcpy(proto, "IGMP", sizeof(proto)); + } + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_VXLAN) { + strlcpy(proto, "VxLAN", sizeof(proto)); + } + + if (c_oil->oif_flags[oif_vif_index] + & PIM_OIF_FLAG_PROTO_STAR) { + strlcpy(proto, "STAR", sizeof(proto)); + } + + vty_out(vty, + "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", + src_str, grp_str, state_str, proto, + in_ifname, out_ifname, ttl, + mroute_uptime); + + if (first) { + src_str[0] = '\0'; + grp_str[0] = '\0'; + in_ifname[0] = '\0'; + state_str[0] = '\0'; + mroute_uptime[0] = '\0'; + first = 0; + } + } + } + + if (!uj && !found_oif) { + vty_out(vty, + "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", + src_str, grp_str, state_str, "none", in_ifname, + "none", 0, "--:--:--"); + } + } + + /* Print list of static routes */ + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) { + first = 1; + + if (!s_route->c_oil.installed) + continue; + + pim_inet4_dump("", s_route->group, grp_str, + sizeof(grp_str)); + pim_inet4_dump("", s_route->source, src_str, + sizeof(src_str)); + ifp_in = pim_if_find_by_vif_index(pim, s_route->iif); + found_oif = 0; + + if (ifp_in) + strlcpy(in_ifname, ifp_in->name, sizeof(in_ifname)); + else + strlcpy(in_ifname, "", sizeof(in_ifname)); + + if (uj) { + + /* Find the group, create it if it doesn't exist */ + json_object_object_get_ex(json, grp_str, &json_group); + + if (!json_group) { + json_group = json_object_new_object(); + json_object_object_add(json, grp_str, + json_group); + } + + /* Find the source nested under the group, create it if + * it doesn't exist */ + json_object_object_get_ex(json_group, src_str, + &json_source); + + if (!json_source) { + json_source = json_object_new_object(); + json_object_object_add(json_group, src_str, + json_source); + } + + json_object_string_add(json_source, "iif", in_ifname); + json_oil = NULL; + } else { + strlcpy(proto, "STATIC", sizeof(proto)); + } + + for (oif_vif_index = 0; oif_vif_index < MAXVIFS; + ++oif_vif_index) { + struct interface *ifp_out; + char oif_uptime[10]; + int ttl; + + ttl = s_route->oif_ttls[oif_vif_index]; + if (ttl < 1) + continue; + + ifp_out = pim_if_find_by_vif_index(pim, oif_vif_index); + pim_time_uptime( + oif_uptime, sizeof(oif_uptime), + now + - s_route->c_oil + .oif_creation[oif_vif_index]); + found_oif = 1; + + if (ifp_out) + strlcpy(out_ifname, ifp_out->name, sizeof(out_ifname)); + else + strlcpy(out_ifname, "", sizeof(out_ifname)); + + if (uj) { + json_ifp_out = json_object_new_object(); + json_object_string_add(json_ifp_out, "source", + src_str); + json_object_string_add(json_ifp_out, "group", + grp_str); + json_object_boolean_true_add(json_ifp_out, + "protocolStatic"); + json_object_string_add(json_ifp_out, + "inboundInterface", + in_ifname); + json_object_int_add( + json_ifp_out, "iVifI", + s_route->c_oil.oil.mfcc_parent); + json_object_string_add(json_ifp_out, + "outboundInterface", + out_ifname); + json_object_int_add(json_ifp_out, "oVifI", + oif_vif_index); + json_object_int_add(json_ifp_out, "ttl", ttl); + json_object_string_add(json_ifp_out, "upTime", + oif_uptime); + if (!json_oil) { + json_oil = json_object_new_object(); + json_object_object_add(json_source, + "oil", json_oil); + } + json_object_object_add(json_oil, out_ifname, + json_ifp_out); + } else { + vty_out(vty, + "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", + src_str, grp_str, "-", proto, in_ifname, + out_ifname, ttl, oif_uptime); + if (first && !fill) { + src_str[0] = '\0'; + grp_str[0] = '\0'; + in_ifname[0] = '\0'; + first = 0; + } + } + } + + if (!uj && !found_oif) { + vty_out(vty, + "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n", + src_str, grp_str, "-", proto, in_ifname, "none", + 0, "--:--:--"); + } + } + + if (uj) + vty_json(vty, json); +} + +static void show_mroute_count_per_channel_oil(struct channel_oil *c_oil, + json_object *json, + struct vty *vty) +{ + char group_str[INET_ADDRSTRLEN]; + char source_str[INET_ADDRSTRLEN]; + json_object *json_group = NULL; + json_object *json_source = NULL; + + if (!c_oil->installed) + return; + + pim_mroute_update_counters(c_oil); + + 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 (json) { + json_object_object_get_ex(json, group_str, &json_group); + + if (!json_group) { + json_group = json_object_new_object(); + json_object_object_add(json, group_str, json_group); + } + + 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); + } +} + +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 (uj) + json = json_object_new_object(); + else { + vty_out(vty, "\n"); + + vty_out(vty, + "Source Group LastUsed Packets Bytes WrongIf \n"); + } + + /* 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); + + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, sr)) + show_mroute_count_per_channel_oil(&sr->c_oil, json, vty); + + if (uj) + vty_json(vty, json); +} + +void show_mroute_summary(struct pim_instance *pim, struct vty *vty, + json_object *json) +{ + struct listnode *node; + struct channel_oil *c_oil; + struct static_route *s_route; + uint32_t starg_sw_mroute_cnt = 0; + 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; + + 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) { + if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) + starg_sw_mroute_cnt++; + else + sg_sw_mroute_cnt++; + } else { + if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) + starg_hw_mroute_cnt++; + else + sg_hw_mroute_cnt++; + } + } + + for (ALL_LIST_ELEMENTS_RO(pim->static_routes, node, s_route)) { + if (!s_route->c_oil.installed) { + if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY) + starg_sw_mroute_cnt++; + else + sg_sw_mroute_cnt++; + } else { + if (s_route->c_oil.oil.mfcc_origin.s_addr == INADDR_ANY) + starg_hw_mroute_cnt++; + else + 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); + } +} +#endif diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h index 9fac2c111b..52d703c95c 100644 --- a/pimd/pim_cmd_common.h +++ b/pimd/pim_cmd_common.h @@ -108,6 +108,12 @@ void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vty *vty); void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty, json_object *json); +void show_mroute(struct pim_instance *pim, struct vty *vty, + pim_sgaddr *sg, bool fill, bool uj); +void show_mroute_count(struct pim_instance *pim, struct vty *vty, + bool uj); +void show_mroute_summary(struct pim_instance *pim, struct vty *vty, + json_object *json); /* * Special Macro to allow us to get the correct pim_instance;