pim6d: Implementing "show ipv6 pim upstream" CLI

Adding new show CLI to display pim upstream information.

Signed-off-by: Abhishek N R <abnr@vmware.com>
This commit is contained in:
Abhishek N R 2022-02-10 21:15:31 -08:00
parent 4f58b6aaa4
commit 95023bd72a
4 changed files with 142 additions and 53 deletions

View File

@ -847,6 +847,91 @@ DEFPY (show_ipv6_pim_statistics,
return CMD_SUCCESS;
}
DEFPY (show_ipv6_pim_upstream,
show_ipv6_pim_upstream_cmd,
"show ipv6 pim [vrf NAME] upstream [X:X::X:X$s_or_g [X:X::X:X$g]] [json$json]",
SHOW_STR
IPV6_STR
PIM_STR
VRF_CMD_HELP_STR
"PIM upstream information\n"
"The Source or Group\n"
"The Group\n"
JSON_STR)
{
pim_sgaddr sg = {0};
struct vrf *v;
bool uj = !!json;
struct pim_instance *pim;
json_object *json_parent = NULL;
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
if (!v) {
vty_out(vty, "%% Vrf specified: %s does not exist\n", vrf);
return CMD_WARNING;
}
pim = pim_get_pim_instance(v->vrf_id);
if (!pim) {
vty_out(vty, "%% Unable to find pim instance\n");
return CMD_WARNING;
}
if (uj)
json_parent = json_object_new_object();
if (!pim_addr_is_any(s_or_g)) {
if (!pim_addr_is_any(g)) {
sg.src = s_or_g;
sg.grp = g;
} else
sg.grp = s_or_g;
}
pim_show_upstream(pim, vty, &sg, json_parent);
if (uj)
vty_json(vty, json_parent);
return CMD_SUCCESS;
}
DEFPY (show_ipv6_pim_upstream_vrf_all,
show_ipv6_pim_upstream_vrf_all_cmd,
"show ipv6 pim vrf all upstream [json$json]",
SHOW_STR
IPV6_STR
PIM_STR
VRF_CMD_HELP_STR
"PIM upstream information\n"
JSON_STR)
{
pim_sgaddr sg = {0};
struct vrf *vrf;
json_object *json_parent = NULL;
json_object *json_vrf = NULL;
if (json)
json_parent = json_object_new_object();
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
else
json_vrf = json_object_new_object();
pim_show_upstream(vrf->info, vty, &sg, json_vrf);
if (json)
json_object_object_add(json_parent, vrf->name,
json_vrf);
}
if (json)
vty_json(vty, json_parent);
return CMD_SUCCESS;
}
void pim_cmd_init(void)
{
if_cmd_init(pim_interface_config_write);
@ -905,4 +990,6 @@ void pim_cmd_init(void)
install_element(VIEW_NODE, &show_ipv6_pim_rpf_vrf_all_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_secondary_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_statistics_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_upstream_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_upstream_vrf_all_cmd);
}

View File

@ -80,14 +80,6 @@ static struct cmd_node debug_node = {
.config_write = pim_debug_config_write,
};
static inline bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
{
return (pim_addr_is_any(match.grp) ||
!pim_addr_cmp(match.grp, item.grp)) &&
(pim_addr_is_any(match.src) ||
!pim_addr_cmp(match.src, item.src));
}
static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
const int argc, int *idx)
{
@ -4427,6 +4419,7 @@ DEFPY (show_ip_pim_upstream,
struct vrf *v;
bool uj = !!json;
struct pim_instance *pim;
json_object *json_parent = NULL;
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
@ -4441,6 +4434,9 @@ DEFPY (show_ip_pim_upstream,
return CMD_WARNING;
}
if (uj)
json_parent = json_object_new_object();
if (s_or_g.s_addr != INADDR_ANY) {
if (g.s_addr != INADDR_ANY) {
sg.src = s_or_g;
@ -4448,14 +4444,17 @@ DEFPY (show_ip_pim_upstream,
} else
sg.grp = s_or_g;
}
pim_show_upstream(pim, vty, &sg, uj);
pim_show_upstream(pim, vty, &sg, json_parent);
if (uj)
vty_json(vty, json_parent);
return CMD_SUCCESS;
}
DEFUN (show_ip_pim_upstream_vrf_all,
DEFPY (show_ip_pim_upstream_vrf_all,
show_ip_pim_upstream_vrf_all_cmd,
"show ip pim vrf all upstream [json]",
"show ip pim vrf all upstream [json$json]",
SHOW_STR
IP_STR
PIM_STR
@ -4464,23 +4463,27 @@ DEFUN (show_ip_pim_upstream_vrf_all,
JSON_STR)
{
pim_sgaddr sg = {0};
bool uj = use_json(argc, argv);
struct vrf *vrf;
bool first = true;
json_object *json_parent = NULL;
json_object *json_vrf = NULL;
if (json)
json_parent = json_object_new_object();
if (uj)
vty_out(vty, "{ ");
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if (uj) {
if (!first)
vty_out(vty, ", ");
vty_out(vty, " \"%s\": ", vrf->name);
first = false;
} else
if (!json)
vty_out(vty, "VRF: %s\n", vrf->name);
pim_show_upstream(vrf->info, vty, &sg, uj);
else
json_vrf = json_object_new_object();
pim_show_upstream(vrf->info, vty, &sg, json_vrf);
if (json)
json_object_object_add(json_parent, vrf->name,
json_vrf);
}
if (json)
vty_json(vty, json_parent);
return CMD_SUCCESS;
}

View File

@ -664,6 +664,14 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
return nb_cli_apply_changes(vty, NULL);
}
bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
{
return (pim_addr_is_any(match.grp) ||
!pim_addr_cmp(match.grp, item.grp)) &&
(pim_addr_is_any(match.src) ||
!pim_addr_cmp(match.src, item.src));
}
void json_object_pim_upstream_add(json_object *json, struct pim_upstream *up)
{
if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
@ -1247,25 +1255,20 @@ void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
}
void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
pim_sgaddr *sg, bool uj)
pim_sgaddr *sg, json_object *json)
{
struct pim_upstream *up;
time_t now;
json_object *json = NULL;
json_object *json_group = NULL;
json_object *json_row = NULL;
now = pim_time_monotonic_sec();
if (uj)
json = json_object_new_object();
else
if (!json)
vty_out(vty,
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN];
char uptime[10];
char join_timer[10];
char rs_timer[10];
@ -1273,15 +1276,9 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
char msdp_reg_timer[10];
char state_str[PIM_REG_STATE_STR_LEN];
if (sg->grp.s_addr != INADDR_ANY &&
sg->grp.s_addr != up->sg.grp.s_addr)
continue;
if (sg->src.s_addr != INADDR_ANY &&
sg->src.s_addr != up->sg.src.s_addr)
if (!pim_sgaddr_match(up->sg, *sg))
continue;
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
pim_time_uptime(uptime, sizeof(uptime),
now - up->state_transition);
pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
@ -1294,9 +1291,9 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
struct pim_neighbor *nbr;
nbr = pim_neighbor_find(
nbr = pim_neighbor_find_prefix(
up->rpf.source_nexthop.interface,
up->rpf.rpf_addr.u.prefix4);
&up->rpf.rpf_addr);
if (nbr)
pim_time_timer_to_hhmmss(join_timer,
sizeof(join_timer),
@ -1322,7 +1319,15 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
strlcat(state_str, tmp, sizeof(state_str));
}
if (uj) {
if (json) {
char grp_str[PIM_ADDRSTRLEN];
char src_str[PIM_ADDRSTRLEN];
snprintfrr(grp_str, sizeof(grp_str), "%pPAs",
&up->sg.grp);
snprintfrr(src_str, sizeof(src_str), "%pPAs",
&up->sg.src);
json_object_object_get_ex(json, grp_str, &json_group);
if (!json_group) {
@ -1347,16 +1352,12 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
* the RP as the rpfAddress
*/
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
up->sg.src.s_addr == INADDR_ANY) {
char rpf[PREFIX_STRLEN];
pim_addr_is_any(up->sg.src)) {
struct pim_rpf *rpg;
rpg = RP(pim, up->sg.grp);
pim_inet4_dump("<rpf?>",
rpg->rpf_addr.u.prefix4, rpf,
sizeof(rpf));
json_object_string_add(json_row, "rpfAddress",
rpf);
json_object_string_addf(json_row, "rpfAddress",
"%pFX", &rpg->rpf_addr);
} else {
json_object_string_add(json_row, "rpfAddress",
src_str);
@ -1387,17 +1388,14 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
json_object_object_add(json_group, src_str, json_row);
} else {
vty_out(vty,
"%-16s%-15s %-15s %-11s %-8s %-9s %-9s %-9s %6d\n",
"%-16s%-15pPAs %-15pPAs %-11s %-8s %-9s %-9s %-9s %6d\n",
up->rpf.source_nexthop.interface
? up->rpf.source_nexthop.interface->name
: "Unknown",
src_str, grp_str, state_str, uptime, join_timer,
rs_timer, ka_timer, up->ref_count);
&up->sg.src, &up->sg.grp, state_str, uptime,
join_timer, rs_timer, ka_timer, up->ref_count);
}
}
if (uj)
vty_json(vty, json);
}
static void pim_show_join_desired_helper(struct pim_instance *pim,

View File

@ -66,11 +66,12 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
const char *ifname, bool uj);
void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
pim_sgaddr *sg, bool uj);
pim_sgaddr *sg, json_object *json);
void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, bool uj);
void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj);
void pim_show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
time_t now, json_object *json);
bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match);
/*
* Special Macro to allow us to get the correct pim_instance;