mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 11:15:47 +00:00
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:
parent
4f58b6aaa4
commit
95023bd72a
@ -847,6 +847,91 @@ DEFPY (show_ipv6_pim_statistics,
|
|||||||
return CMD_SUCCESS;
|
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)
|
void pim_cmd_init(void)
|
||||||
{
|
{
|
||||||
if_cmd_init(pim_interface_config_write);
|
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_rpf_vrf_all_cmd);
|
||||||
install_element(VIEW_NODE, &show_ipv6_pim_secondary_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_statistics_cmd);
|
||||||
|
install_element(VIEW_NODE, &show_ipv6_pim_upstream_cmd);
|
||||||
|
install_element(VIEW_NODE, &show_ipv6_pim_upstream_vrf_all_cmd);
|
||||||
}
|
}
|
||||||
|
@ -80,14 +80,6 @@ static struct cmd_node debug_node = {
|
|||||||
.config_write = pim_debug_config_write,
|
.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[],
|
static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
|
||||||
const int argc, int *idx)
|
const int argc, int *idx)
|
||||||
{
|
{
|
||||||
@ -4427,6 +4419,7 @@ DEFPY (show_ip_pim_upstream,
|
|||||||
struct vrf *v;
|
struct vrf *v;
|
||||||
bool uj = !!json;
|
bool uj = !!json;
|
||||||
struct pim_instance *pim;
|
struct pim_instance *pim;
|
||||||
|
json_object *json_parent = NULL;
|
||||||
|
|
||||||
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
||||||
|
|
||||||
@ -4441,6 +4434,9 @@ DEFPY (show_ip_pim_upstream,
|
|||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uj)
|
||||||
|
json_parent = json_object_new_object();
|
||||||
|
|
||||||
if (s_or_g.s_addr != INADDR_ANY) {
|
if (s_or_g.s_addr != INADDR_ANY) {
|
||||||
if (g.s_addr != INADDR_ANY) {
|
if (g.s_addr != INADDR_ANY) {
|
||||||
sg.src = s_or_g;
|
sg.src = s_or_g;
|
||||||
@ -4448,14 +4444,17 @@ DEFPY (show_ip_pim_upstream,
|
|||||||
} else
|
} else
|
||||||
sg.grp = s_or_g;
|
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;
|
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_upstream_vrf_all_cmd,
|
||||||
"show ip pim vrf all upstream [json]",
|
"show ip pim vrf all upstream [json$json]",
|
||||||
SHOW_STR
|
SHOW_STR
|
||||||
IP_STR
|
IP_STR
|
||||||
PIM_STR
|
PIM_STR
|
||||||
@ -4464,23 +4463,27 @@ DEFUN (show_ip_pim_upstream_vrf_all,
|
|||||||
JSON_STR)
|
JSON_STR)
|
||||||
{
|
{
|
||||||
pim_sgaddr sg = {0};
|
pim_sgaddr sg = {0};
|
||||||
bool uj = use_json(argc, argv);
|
|
||||||
struct vrf *vrf;
|
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) {
|
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||||
if (uj) {
|
if (!json)
|
||||||
if (!first)
|
|
||||||
vty_out(vty, ", ");
|
|
||||||
vty_out(vty, " \"%s\": ", vrf->name);
|
|
||||||
first = false;
|
|
||||||
} else
|
|
||||||
vty_out(vty, "VRF: %s\n", vrf->name);
|
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 CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
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)
|
void json_object_pim_upstream_add(json_object *json, struct pim_upstream *up)
|
||||||
{
|
{
|
||||||
if (up->flags & PIM_UPSTREAM_FLAG_MASK_DR_JOIN_DESIRED)
|
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,
|
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;
|
struct pim_upstream *up;
|
||||||
time_t now;
|
time_t now;
|
||||||
json_object *json = NULL;
|
|
||||||
json_object *json_group = NULL;
|
json_object *json_group = NULL;
|
||||||
json_object *json_row = NULL;
|
json_object *json_row = NULL;
|
||||||
|
|
||||||
now = pim_time_monotonic_sec();
|
now = pim_time_monotonic_sec();
|
||||||
|
|
||||||
if (uj)
|
if (!json)
|
||||||
json = json_object_new_object();
|
|
||||||
else
|
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
|
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
|
||||||
|
|
||||||
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
char src_str[INET_ADDRSTRLEN];
|
|
||||||
char grp_str[INET_ADDRSTRLEN];
|
|
||||||
char uptime[10];
|
char uptime[10];
|
||||||
char join_timer[10];
|
char join_timer[10];
|
||||||
char rs_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 msdp_reg_timer[10];
|
||||||
char state_str[PIM_REG_STATE_STR_LEN];
|
char state_str[PIM_REG_STATE_STR_LEN];
|
||||||
|
|
||||||
if (sg->grp.s_addr != INADDR_ANY &&
|
if (!pim_sgaddr_match(up->sg, *sg))
|
||||||
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)
|
|
||||||
continue;
|
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),
|
pim_time_uptime(uptime, sizeof(uptime),
|
||||||
now - up->state_transition);
|
now - up->state_transition);
|
||||||
pim_time_timer_to_hhmmss(join_timer, sizeof(join_timer),
|
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) {
|
if (!up->t_join_timer && up->rpf.source_nexthop.interface) {
|
||||||
struct pim_neighbor *nbr;
|
struct pim_neighbor *nbr;
|
||||||
|
|
||||||
nbr = pim_neighbor_find(
|
nbr = pim_neighbor_find_prefix(
|
||||||
up->rpf.source_nexthop.interface,
|
up->rpf.source_nexthop.interface,
|
||||||
up->rpf.rpf_addr.u.prefix4);
|
&up->rpf.rpf_addr);
|
||||||
if (nbr)
|
if (nbr)
|
||||||
pim_time_timer_to_hhmmss(join_timer,
|
pim_time_timer_to_hhmmss(join_timer,
|
||||||
sizeof(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));
|
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);
|
json_object_object_get_ex(json, grp_str, &json_group);
|
||||||
|
|
||||||
if (!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
|
* the RP as the rpfAddress
|
||||||
*/
|
*/
|
||||||
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR ||
|
||||||
up->sg.src.s_addr == INADDR_ANY) {
|
pim_addr_is_any(up->sg.src)) {
|
||||||
char rpf[PREFIX_STRLEN];
|
|
||||||
struct pim_rpf *rpg;
|
struct pim_rpf *rpg;
|
||||||
|
|
||||||
rpg = RP(pim, up->sg.grp);
|
rpg = RP(pim, up->sg.grp);
|
||||||
pim_inet4_dump("<rpf?>",
|
json_object_string_addf(json_row, "rpfAddress",
|
||||||
rpg->rpf_addr.u.prefix4, rpf,
|
"%pFX", &rpg->rpf_addr);
|
||||||
sizeof(rpf));
|
|
||||||
json_object_string_add(json_row, "rpfAddress",
|
|
||||||
rpf);
|
|
||||||
} else {
|
} else {
|
||||||
json_object_string_add(json_row, "rpfAddress",
|
json_object_string_add(json_row, "rpfAddress",
|
||||||
src_str);
|
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);
|
json_object_object_add(json_group, src_str, json_row);
|
||||||
} else {
|
} else {
|
||||||
vty_out(vty,
|
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
|
||||||
? up->rpf.source_nexthop.interface->name
|
? up->rpf.source_nexthop.interface->name
|
||||||
: "Unknown",
|
: "Unknown",
|
||||||
src_str, grp_str, state_str, uptime, join_timer,
|
&up->sg.src, &up->sg.grp, state_str, uptime,
|
||||||
rs_timer, ka_timer, up->ref_count);
|
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,
|
static void pim_show_join_desired_helper(struct pim_instance *pim,
|
||||||
|
@ -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,
|
void pim_show_statistics(struct pim_instance *pim, struct vty *vty,
|
||||||
const char *ifname, bool uj);
|
const char *ifname, bool uj);
|
||||||
void pim_show_upstream(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);
|
||||||
void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, bool uj);
|
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_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj);
|
||||||
void pim_show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
|
void pim_show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim,
|
||||||
time_t now, json_object *json);
|
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;
|
* Special Macro to allow us to get the correct pim_instance;
|
||||||
|
Loading…
Reference in New Issue
Block a user