Adding new show CLI to display pim upstream information.
Signed-off-by: Abhishek N R <abnr@vmware.com>
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);
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);
}
.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)
{
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);
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;
} 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
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;
}
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)
}
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];
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),
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),
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) {
* 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);
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,
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;