mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-11-01 12:47:16 +00:00
Merge pull request #11600 from patrasar/pimv6_bsm_clis
pim6d: BSM CLIs implementation
This commit is contained in:
commit
8e9729cc72
@ -578,7 +578,7 @@ cause great confusion.
|
||||
|
||||
.. clicmd:: show ip pim bsm-database
|
||||
|
||||
Display all fragments ofstored bootstrap message in user readable format.
|
||||
Display all fragments of stored bootstrap message in user readable format.
|
||||
|
||||
.. clicmd:: mtrace A.B.C.D [A.B.C.D]
|
||||
|
||||
|
||||
@ -162,6 +162,18 @@ is in a vrf, enter the interface command with the vrf keyword at the end.
|
||||
|
||||
Disable sending and receiving pim control packets on the interface.
|
||||
|
||||
.. clicmd:: ipv6 pim bsm
|
||||
|
||||
Tell pim that we would like to use this interface to process bootstrap
|
||||
messages. This is enabled by default. 'no' form of this command is used to
|
||||
restrict bsm messages on this interface.
|
||||
|
||||
.. clicmd:: ipv6 pim unicast-bsm
|
||||
|
||||
Tell pim that we would like to allow interface to process unicast bootstrap
|
||||
messages. This is enabled by default. 'no' form of this command is used to
|
||||
restrict processing of unicast bsm messages on this interface.
|
||||
|
||||
.. clicmd:: ipv6 mld
|
||||
|
||||
Tell pim to receive MLD reports and Query on this interface. The default
|
||||
@ -373,6 +385,18 @@ General multicast routing state
|
||||
Display total number of S,G mroutes and number of S,G mroutes
|
||||
installed into the kernel for all vrfs.
|
||||
|
||||
.. clicmd:: show ipv6 pim bsr
|
||||
|
||||
Display current bsr, its uptime and last received bsm age.
|
||||
|
||||
.. clicmd:: show ipv6 pim bsrp-info
|
||||
|
||||
Display group-to-rp mappings received from E-BSR.
|
||||
|
||||
.. clicmd:: show ipv6 pim bsm-database
|
||||
|
||||
Display all fragments of stored bootstrap message in user readable format.
|
||||
|
||||
PIMv6 Clear Commands
|
||||
====================
|
||||
|
||||
@ -472,3 +496,7 @@ the config was written out.
|
||||
.. clicmd:: debug mld trace [detail]
|
||||
|
||||
This traces mld code and how it is running.
|
||||
|
||||
.. clicmd:: debug pimv6 bsm
|
||||
|
||||
This turns on debugging for BSR message processing.
|
||||
|
||||
106
pimd/pim6_cmd.c
106
pimd/pim6_cmd.c
@ -476,6 +476,47 @@ DEFPY (no_ipv6_pim_rp_prefix_list,
|
||||
return pim_process_no_rp_plist_cmd(vty, rp_str, plist);
|
||||
}
|
||||
|
||||
DEFPY (ipv6_pim_bsm,
|
||||
ipv6_pim_bsm_cmd,
|
||||
"ipv6 pim bsm",
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Enable BSM support on the interface\n")
|
||||
{
|
||||
return pim_process_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFPY (no_ipv6_pim_bsm,
|
||||
no_ipv6_pim_bsm_cmd,
|
||||
"no ipv6 pim bsm",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Enable BSM support on the interface\n")
|
||||
{
|
||||
return pim_process_no_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFPY (ipv6_pim_ucast_bsm,
|
||||
ipv6_pim_ucast_bsm_cmd,
|
||||
"ipv6 pim unicast-bsm",
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Accept/Send unicast BSM on the interface\n")
|
||||
{
|
||||
return pim_process_unicast_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFPY (no_ipv6_pim_ucast_bsm,
|
||||
no_ipv6_pim_ucast_bsm_cmd,
|
||||
"no ipv6 pim unicast-bsm",
|
||||
NO_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"Accept/Send unicast BSM on the interface\n")
|
||||
{
|
||||
return pim_process_no_unicast_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFPY (ipv6_ssmpingd,
|
||||
ipv6_ssmpingd_cmd,
|
||||
@ -1240,6 +1281,44 @@ DEFPY (show_ipv6_pim_interface_traffic,
|
||||
return pim_show_interface_traffic_helper(vrf, if_name, vty, !!json);
|
||||
}
|
||||
|
||||
DEFPY (show_ipv6_pim_bsr,
|
||||
show_ipv6_pim_bsr_cmd,
|
||||
"show ipv6 pim bsr [vrf NAME] [json$json]",
|
||||
SHOW_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"boot-strap router information\n"
|
||||
VRF_CMD_HELP_STR
|
||||
JSON_STR)
|
||||
{
|
||||
return pim_show_bsr_helper(vrf, vty, !!json);
|
||||
}
|
||||
|
||||
DEFPY (show_ipv6_pim_bsm_db,
|
||||
show_ipv6_pim_bsm_db_cmd,
|
||||
"show ipv6 pim bsm-database [vrf NAME] [json$json]",
|
||||
SHOW_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"PIM cached bsm packets information\n"
|
||||
VRF_CMD_HELP_STR
|
||||
JSON_STR)
|
||||
{
|
||||
return pim_show_bsm_db_helper(vrf, vty, !!json);
|
||||
}
|
||||
|
||||
DEFPY (show_ipv6_pim_bsrp,
|
||||
show_ipv6_pim_bsrp_cmd,
|
||||
"show ipv6 pim bsrp-info [vrf NAME] [json$json]",
|
||||
SHOW_STR
|
||||
IPV6_STR
|
||||
PIM_STR
|
||||
"PIM cached group-rp mappings information\n"
|
||||
VRF_CMD_HELP_STR
|
||||
JSON_STR)
|
||||
{
|
||||
return pim_show_group_rp_mappings_info_helper(vrf, vty, !!json);
|
||||
}
|
||||
|
||||
DEFPY (clear_ipv6_pim_statistics,
|
||||
clear_ipv6_pim_statistics_cmd,
|
||||
@ -1648,6 +1727,22 @@ DEFPY (debug_mld_trace_detail,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY (debug_pimv6_bsm,
|
||||
debug_pimv6_bsm_cmd,
|
||||
"[no] debug pimv6 bsm",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
DEBUG_PIMV6_STR
|
||||
DEBUG_PIMV6_BSM_STR)
|
||||
{
|
||||
if (!no)
|
||||
PIM_DO_DEBUG_BSM;
|
||||
else
|
||||
PIM_DONT_DEBUG_BSM;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void pim_cmd_init(void)
|
||||
{
|
||||
if_cmd_init(pim_interface_config_write);
|
||||
@ -1685,6 +1780,11 @@ void pim_cmd_init(void)
|
||||
&interface_no_ipv6_pim_boundary_oil_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_ipv6_mroute_cmd);
|
||||
install_element(INTERFACE_NODE, &interface_no_ipv6_mroute_cmd);
|
||||
/* Install BSM command */
|
||||
install_element(INTERFACE_NODE, &ipv6_pim_bsm_cmd);
|
||||
install_element(INTERFACE_NODE, &no_ipv6_pim_bsm_cmd);
|
||||
install_element(INTERFACE_NODE, &ipv6_pim_ucast_bsm_cmd);
|
||||
install_element(INTERFACE_NODE, &no_ipv6_pim_ucast_bsm_cmd);
|
||||
install_element(CONFIG_NODE, &ipv6_pim_rp_cmd);
|
||||
install_element(VRF_NODE, &ipv6_pim_rp_cmd);
|
||||
install_element(CONFIG_NODE, &no_ipv6_pim_rp_cmd);
|
||||
@ -1757,7 +1857,9 @@ void pim_cmd_init(void)
|
||||
install_element(VIEW_NODE, &show_ipv6_mroute_summary_cmd);
|
||||
install_element(VIEW_NODE, &show_ipv6_mroute_summary_vrf_all_cmd);
|
||||
install_element(VIEW_NODE, &show_ipv6_pim_interface_traffic_cmd);
|
||||
|
||||
install_element(VIEW_NODE, &show_ipv6_pim_bsr_cmd);
|
||||
install_element(VIEW_NODE, &show_ipv6_pim_bsm_db_cmd);
|
||||
install_element(VIEW_NODE, &show_ipv6_pim_bsrp_cmd);
|
||||
install_element(ENABLE_NODE, &clear_ipv6_pim_statistics_cmd);
|
||||
install_element(ENABLE_NODE, &clear_ipv6_mroute_cmd);
|
||||
install_element(ENABLE_NODE, &clear_ipv6_pim_oil_cmd);
|
||||
@ -1785,6 +1887,7 @@ void pim_cmd_init(void)
|
||||
install_element(ENABLE_NODE, &debug_mld_packets_cmd);
|
||||
install_element(ENABLE_NODE, &debug_mld_trace_cmd);
|
||||
install_element(ENABLE_NODE, &debug_mld_trace_detail_cmd);
|
||||
install_element(ENABLE_NODE, &debug_pimv6_bsm_cmd);
|
||||
|
||||
install_element(CONFIG_NODE, &debug_pimv6_cmd);
|
||||
install_element(CONFIG_NODE, &debug_pimv6_nht_cmd);
|
||||
@ -1803,4 +1906,5 @@ void pim_cmd_init(void)
|
||||
install_element(CONFIG_NODE, &debug_mld_packets_cmd);
|
||||
install_element(CONFIG_NODE, &debug_mld_trace_cmd);
|
||||
install_element(CONFIG_NODE, &debug_mld_trace_detail_cmd);
|
||||
install_element(CONFIG_NODE, &debug_pimv6_bsm_cmd);
|
||||
}
|
||||
|
||||
@ -58,6 +58,7 @@
|
||||
#define DEBUG_PIMV6_TRACE_STR "PIMv6 internal daemon activity\n"
|
||||
#define DEBUG_PIMV6_ZEBRA_STR "ZEBRA protocol activity\n"
|
||||
#define DEBUG_MROUTE6_STR "PIMv6 interaction with kernel MFC cache\n"
|
||||
#define DEBUG_PIMV6_BSM_STR "BSR message processing activity\n"
|
||||
|
||||
void pim_cmd_init(void);
|
||||
|
||||
|
||||
453
pimd/pim_cmd.c
453
pimd/pim_cmd.c
@ -837,285 +837,6 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty,
|
||||
}
|
||||
}
|
||||
|
||||
/* Display the bsm database details */
|
||||
static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||
{
|
||||
int count = 0;
|
||||
int fragment = 1;
|
||||
struct bsm_frag *bsfrag;
|
||||
json_object *json = NULL;
|
||||
json_object *json_group = NULL;
|
||||
json_object *json_row = NULL;
|
||||
|
||||
count = bsm_frags_count(pim->global_scope.bsm_frags);
|
||||
|
||||
if (uj) {
|
||||
json = json_object_new_object();
|
||||
json_object_int_add(json, "Number of the fragments", count);
|
||||
} else {
|
||||
vty_out(vty, "Scope Zone: Global\n");
|
||||
vty_out(vty, "Number of the fragments: %d\n", count);
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
frr_each (bsm_frags, pim->global_scope.bsm_frags, bsfrag) {
|
||||
char grp_str[PREFIX_STRLEN];
|
||||
struct bsmmsg_grpinfo *group;
|
||||
struct bsmmsg_rpinfo *bsm_rpinfo;
|
||||
struct prefix grp;
|
||||
struct bsm_hdr *hdr;
|
||||
pim_addr bsr_addr;
|
||||
uint32_t offset = 0;
|
||||
uint8_t *buf;
|
||||
uint32_t len = 0;
|
||||
uint32_t frag_rp_cnt = 0;
|
||||
|
||||
buf = bsfrag->data;
|
||||
len = bsfrag->size;
|
||||
|
||||
/* skip pim header */
|
||||
buf += PIM_MSG_HEADER_LEN;
|
||||
len -= PIM_MSG_HEADER_LEN;
|
||||
|
||||
hdr = (struct bsm_hdr *)buf;
|
||||
/* NB: bshdr->bsr_addr.addr is packed/unaligned => memcpy */
|
||||
memcpy(&bsr_addr, &hdr->bsr_addr.addr, sizeof(bsr_addr));
|
||||
|
||||
/* BSM starts with bsr header */
|
||||
buf += sizeof(struct bsm_hdr);
|
||||
len -= sizeof(struct bsm_hdr);
|
||||
|
||||
if (uj) {
|
||||
json_object_string_addf(json, "BSR address", "%pPA",
|
||||
&bsr_addr);
|
||||
json_object_int_add(json, "BSR priority",
|
||||
hdr->bsr_prio);
|
||||
json_object_int_add(json, "Hashmask Length",
|
||||
hdr->hm_len);
|
||||
json_object_int_add(json, "Fragment Tag",
|
||||
ntohs(hdr->frag_tag));
|
||||
} else {
|
||||
vty_out(vty, "BSM Fragment : %d\n", fragment);
|
||||
vty_out(vty, "------------------\n");
|
||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
|
||||
"BSR-Priority", "Hashmask-len", "Fragment-Tag");
|
||||
vty_out(vty, "%-15pPA %-15d %-15d %-15d\n", &bsr_addr,
|
||||
hdr->bsr_prio, hdr->hm_len,
|
||||
ntohs(hdr->frag_tag));
|
||||
}
|
||||
|
||||
vty_out(vty, "\n");
|
||||
|
||||
while (offset < len) {
|
||||
group = (struct bsmmsg_grpinfo *)buf;
|
||||
|
||||
if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
|
||||
grp.family = AF_INET;
|
||||
else if (group->group.family ==
|
||||
PIM_MSG_ADDRESS_FAMILY_IPV6)
|
||||
grp.family = AF_INET6;
|
||||
|
||||
grp.prefixlen = group->group.mask;
|
||||
#if PIM_IPV == 4
|
||||
grp.u.prefix4 = group->group.addr;
|
||||
#else
|
||||
grp.u.prefix6 = group->group.addr;
|
||||
#endif
|
||||
|
||||
prefix2str(&grp, grp_str, sizeof(grp_str));
|
||||
|
||||
buf += sizeof(struct bsmmsg_grpinfo);
|
||||
offset += sizeof(struct bsmmsg_grpinfo);
|
||||
|
||||
if (uj) {
|
||||
json_object_object_get_ex(json, grp_str,
|
||||
&json_group);
|
||||
if (!json_group) {
|
||||
json_group = json_object_new_object();
|
||||
json_object_int_add(json_group,
|
||||
"Rp Count",
|
||||
group->rp_count);
|
||||
json_object_int_add(
|
||||
json_group, "Fragment Rp count",
|
||||
group->frag_rp_count);
|
||||
json_object_object_add(json, grp_str,
|
||||
json_group);
|
||||
}
|
||||
} else {
|
||||
vty_out(vty, "Group : %s\n", grp_str);
|
||||
vty_out(vty, "-------------------\n");
|
||||
vty_out(vty, "Rp Count:%d\n", group->rp_count);
|
||||
vty_out(vty, "Fragment Rp Count : %d\n",
|
||||
group->frag_rp_count);
|
||||
}
|
||||
|
||||
frag_rp_cnt = group->frag_rp_count;
|
||||
|
||||
if (!frag_rp_cnt)
|
||||
continue;
|
||||
|
||||
if (!uj)
|
||||
vty_out(vty,
|
||||
"RpAddress HoldTime Priority\n");
|
||||
|
||||
while (frag_rp_cnt--) {
|
||||
pim_addr rp_addr;
|
||||
|
||||
bsm_rpinfo = (struct bsmmsg_rpinfo *)buf;
|
||||
/* unaligned, again */
|
||||
memcpy(&rp_addr, &bsm_rpinfo->rpaddr.addr,
|
||||
sizeof(rp_addr));
|
||||
|
||||
buf += sizeof(struct bsmmsg_rpinfo);
|
||||
offset += sizeof(struct bsmmsg_rpinfo);
|
||||
|
||||
if (uj) {
|
||||
json_row = json_object_new_object();
|
||||
json_object_string_addf(
|
||||
json_row, "Rp Address", "%pPA",
|
||||
&rp_addr);
|
||||
json_object_int_add(
|
||||
json_row, "Rp HoldTime",
|
||||
ntohs(bsm_rpinfo->rp_holdtime));
|
||||
json_object_int_add(json_row,
|
||||
"Rp Priority",
|
||||
bsm_rpinfo->rp_pri);
|
||||
json_object_object_addf(
|
||||
json_group, json_row, "%pPA",
|
||||
&rp_addr);
|
||||
} else {
|
||||
vty_out(vty, "%-15pPA %-12d %d\n",
|
||||
&rp_addr,
|
||||
ntohs(bsm_rpinfo->rp_holdtime),
|
||||
bsm_rpinfo->rp_pri);
|
||||
}
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
fragment++;
|
||||
}
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
}
|
||||
|
||||
/*Display the group-rp mappings */
|
||||
static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
|
||||
struct vty *vty, bool uj)
|
||||
{
|
||||
struct bsgrp_node *bsgrp;
|
||||
struct bsm_rpinfo *bsm_rp;
|
||||
struct route_node *rn;
|
||||
json_object *json = NULL;
|
||||
json_object *json_group = NULL;
|
||||
json_object *json_row = NULL;
|
||||
|
||||
if (uj) {
|
||||
json = json_object_new_object();
|
||||
json_object_string_addf(json, "BSR Address", "%pPA",
|
||||
&pim->global_scope.current_bsr);
|
||||
} else
|
||||
vty_out(vty, "BSR Address %pPA\n",
|
||||
&pim->global_scope.current_bsr);
|
||||
|
||||
for (rn = route_top(pim->global_scope.bsrp_table); rn;
|
||||
rn = route_next(rn)) {
|
||||
bsgrp = (struct bsgrp_node *)rn->info;
|
||||
|
||||
if (!bsgrp)
|
||||
continue;
|
||||
|
||||
char grp_str[PREFIX_STRLEN];
|
||||
|
||||
prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
|
||||
|
||||
if (uj) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
vty_out(vty, "Group Address %pFX\n", &bsgrp->group);
|
||||
vty_out(vty, "--------------------------\n");
|
||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
|
||||
"priority", "Holdtime", "Hash");
|
||||
|
||||
vty_out(vty, "(ACTIVE)\n");
|
||||
}
|
||||
|
||||
frr_each (bsm_rpinfos, bsgrp->bsrp_list, bsm_rp) {
|
||||
if (uj) {
|
||||
json_row = json_object_new_object();
|
||||
json_object_string_addf(json_row, "Rp Address",
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
json_object_int_add(json_row, "Rp HoldTime",
|
||||
bsm_rp->rp_holdtime);
|
||||
json_object_int_add(json_row, "Rp Priority",
|
||||
bsm_rp->rp_prio);
|
||||
json_object_int_add(json_row, "Hash Val",
|
||||
bsm_rp->hash);
|
||||
json_object_object_addf(json_group, json_row,
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
|
||||
} else {
|
||||
vty_out(vty, "%-15pPA %-15u %-15u %-15u\n",
|
||||
&bsm_rp->rp_address, bsm_rp->rp_prio,
|
||||
bsm_rp->rp_holdtime, bsm_rp->hash);
|
||||
}
|
||||
}
|
||||
if (!bsm_rpinfos_count(bsgrp->bsrp_list) && !uj)
|
||||
vty_out(vty, "Active List is empty.\n");
|
||||
|
||||
if (uj) {
|
||||
json_object_int_add(json_group, "Pending RP count",
|
||||
bsgrp->pend_rp_cnt);
|
||||
} else {
|
||||
vty_out(vty, "(PENDING)\n");
|
||||
vty_out(vty, "Pending RP count :%d\n",
|
||||
bsgrp->pend_rp_cnt);
|
||||
if (bsgrp->pend_rp_cnt)
|
||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n",
|
||||
"Rp Address", "priority", "Holdtime",
|
||||
"Hash");
|
||||
}
|
||||
|
||||
frr_each (bsm_rpinfos, bsgrp->partial_bsrp_list, bsm_rp) {
|
||||
if (uj) {
|
||||
json_row = json_object_new_object();
|
||||
json_object_string_addf(json_row, "Rp Address",
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
json_object_int_add(json_row, "Rp HoldTime",
|
||||
bsm_rp->rp_holdtime);
|
||||
json_object_int_add(json_row, "Rp Priority",
|
||||
bsm_rp->rp_prio);
|
||||
json_object_int_add(json_row, "Hash Val",
|
||||
bsm_rp->hash);
|
||||
json_object_object_addf(json_group, json_row,
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
} else {
|
||||
vty_out(vty, "%-15pPA %-15u %-15u %-15u\n",
|
||||
&bsm_rp->rp_address, bsm_rp->rp_prio,
|
||||
bsm_rp->rp_holdtime, bsm_rp->hash);
|
||||
}
|
||||
}
|
||||
if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj)
|
||||
vty_out(vty, "Partial List is empty\n");
|
||||
|
||||
if (!uj)
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
}
|
||||
|
||||
static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||
{
|
||||
struct interface *ifp;
|
||||
@ -1439,77 +1160,6 @@ static void igmp_show_source_retransmission(struct pim_instance *pim,
|
||||
} /* scan interfaces */
|
||||
}
|
||||
|
||||
static void pim_show_bsr(struct pim_instance *pim,
|
||||
struct vty *vty,
|
||||
bool uj)
|
||||
{
|
||||
char uptime[10];
|
||||
char last_bsm_seen[10];
|
||||
time_t now;
|
||||
char bsr_state[20];
|
||||
json_object *json = NULL;
|
||||
|
||||
if (pim_addr_is_any(pim->global_scope.current_bsr)) {
|
||||
pim_time_uptime(uptime, sizeof(uptime),
|
||||
pim->global_scope.current_bsr_first_ts);
|
||||
pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
|
||||
pim->global_scope.current_bsr_last_ts);
|
||||
}
|
||||
|
||||
else {
|
||||
now = pim_time_monotonic_sec();
|
||||
pim_time_uptime(uptime, sizeof(uptime),
|
||||
(now - pim->global_scope.current_bsr_first_ts));
|
||||
pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
|
||||
now - pim->global_scope.current_bsr_last_ts);
|
||||
}
|
||||
|
||||
switch (pim->global_scope.state) {
|
||||
case NO_INFO:
|
||||
strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
|
||||
break;
|
||||
case ACCEPT_ANY:
|
||||
strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
|
||||
break;
|
||||
case ACCEPT_PREFERRED:
|
||||
strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
|
||||
break;
|
||||
default:
|
||||
strlcpy(bsr_state, "", sizeof(bsr_state));
|
||||
}
|
||||
|
||||
|
||||
if (uj) {
|
||||
json = json_object_new_object();
|
||||
json_object_string_addf(json, "bsr", "%pPA",
|
||||
&pim->global_scope.current_bsr);
|
||||
json_object_int_add(json, "priority",
|
||||
pim->global_scope.current_bsr_prio);
|
||||
json_object_int_add(json, "fragmentTag",
|
||||
pim->global_scope.bsm_frag_tag);
|
||||
json_object_string_add(json, "state", bsr_state);
|
||||
json_object_string_add(json, "upTime", uptime);
|
||||
json_object_string_add(json, "lastBsmSeen", last_bsm_seen);
|
||||
}
|
||||
|
||||
else {
|
||||
vty_out(vty, "PIMv2 Bootstrap information\n");
|
||||
vty_out(vty, "Current preferred BSR address: %pPA\n",
|
||||
&pim->global_scope.current_bsr);
|
||||
vty_out(vty,
|
||||
"Priority Fragment-Tag State UpTime\n");
|
||||
vty_out(vty, " %-12d %-12d %-13s %7s\n",
|
||||
pim->global_scope.current_bsr_prio,
|
||||
pim->global_scope.bsm_frag_tag,
|
||||
bsr_state,
|
||||
uptime);
|
||||
vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
|
||||
}
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
}
|
||||
|
||||
static void clear_igmp_interfaces(struct pim_instance *pim)
|
||||
{
|
||||
struct interface *ifp;
|
||||
@ -2772,9 +2422,9 @@ DEFPY (show_ip_pim_interface_traffic,
|
||||
return pim_show_interface_traffic_helper(vrf, if_name, vty, !!json);
|
||||
}
|
||||
|
||||
DEFUN (show_ip_pim_bsm_db,
|
||||
DEFPY (show_ip_pim_bsm_db,
|
||||
show_ip_pim_bsm_db_cmd,
|
||||
"show ip pim bsm-database [vrf NAME] [json]",
|
||||
"show ip pim bsm-database [vrf NAME] [json$json]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
@ -2782,20 +2432,12 @@ DEFUN (show_ip_pim_bsm_db,
|
||||
VRF_CMD_HELP_STR
|
||||
JSON_STR)
|
||||
{
|
||||
int idx = 2;
|
||||
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
||||
bool uj = use_json(argc, argv);
|
||||
|
||||
if (!vrf)
|
||||
return CMD_WARNING;
|
||||
|
||||
pim_show_bsm_db(vrf->info, vty, uj);
|
||||
return CMD_SUCCESS;
|
||||
return pim_show_bsm_db_helper(vrf, vty, !!json);
|
||||
}
|
||||
|
||||
DEFUN (show_ip_pim_bsrp,
|
||||
DEFPY (show_ip_pim_bsrp,
|
||||
show_ip_pim_bsrp_cmd,
|
||||
"show ip pim bsrp-info [vrf NAME] [json]",
|
||||
"show ip pim bsrp-info [vrf NAME] [json$json]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
@ -2803,16 +2445,7 @@ DEFUN (show_ip_pim_bsrp,
|
||||
VRF_CMD_HELP_STR
|
||||
JSON_STR)
|
||||
{
|
||||
int idx = 2;
|
||||
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
||||
bool uj = use_json(argc, argv);
|
||||
|
||||
if (!vrf)
|
||||
return CMD_WARNING;
|
||||
|
||||
pim_show_group_rp_mappings_info(vrf->info, vty, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
return pim_show_group_rp_mappings_info_helper(vrf, vty, !!json);
|
||||
}
|
||||
|
||||
DEFPY (show_ip_pim_statistics,
|
||||
@ -3586,25 +3219,17 @@ DEFUN (show_ip_pim_group_type,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ip_pim_bsr,
|
||||
DEFPY (show_ip_pim_bsr,
|
||||
show_ip_pim_bsr_cmd,
|
||||
"show ip pim bsr [json]",
|
||||
"show ip pim bsr [vrf NAME] [json$json]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
"boot-strap router information\n"
|
||||
VRF_CMD_HELP_STR
|
||||
JSON_STR)
|
||||
{
|
||||
int idx = 2;
|
||||
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
|
||||
bool uj = use_json(argc, argv);
|
||||
|
||||
if (!vrf)
|
||||
return CMD_WARNING;
|
||||
|
||||
pim_show_bsr(vrf->info, vty, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
return pim_show_bsr_helper(vrf, vty, !!json);
|
||||
}
|
||||
|
||||
DEFUN (ip_ssmpingd,
|
||||
@ -5010,41 +4635,19 @@ DEFUN (ip_pim_bsm,
|
||||
"ip pim bsm",
|
||||
IP_STR
|
||||
PIM_STR
|
||||
"Enables BSM support on the interface\n")
|
||||
"Enable BSM support on the interface\n")
|
||||
{
|
||||
const struct lyd_node *igmp_enable_dnode;
|
||||
|
||||
igmp_enable_dnode =
|
||||
yang_dnode_getf(vty->candidate_config->dnode,
|
||||
FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
|
||||
"frr-routing:ipv4");
|
||||
if (!igmp_enable_dnode)
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
else {
|
||||
if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
}
|
||||
|
||||
nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "true");
|
||||
|
||||
return nb_cli_apply_changes(vty,
|
||||
FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
|
||||
return pim_process_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_pim_bsm,
|
||||
no_ip_pim_bsm_cmd,
|
||||
"no ip pim bsm",
|
||||
NO_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
"Disables BSM support\n")
|
||||
"Enable BSM support on the interface\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "false");
|
||||
|
||||
return nb_cli_apply_changes(vty,
|
||||
FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
|
||||
return pim_process_no_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFUN (ip_pim_ucast_bsm,
|
||||
@ -5054,26 +4657,7 @@ DEFUN (ip_pim_ucast_bsm,
|
||||
PIM_STR
|
||||
"Accept/Send unicast BSM on the interface\n")
|
||||
{
|
||||
const struct lyd_node *igmp_enable_dnode;
|
||||
|
||||
igmp_enable_dnode =
|
||||
yang_dnode_getf(vty->candidate_config->dnode,
|
||||
FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
|
||||
"frr-routing:ipv4");
|
||||
if (!igmp_enable_dnode)
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
else {
|
||||
if (!yang_dnode_get_bool(igmp_enable_dnode, "."))
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
}
|
||||
|
||||
nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "true");
|
||||
|
||||
return nb_cli_apply_changes(vty,
|
||||
FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
|
||||
|
||||
return pim_process_unicast_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_pim_ucast_bsm,
|
||||
@ -5082,12 +4666,9 @@ DEFUN (no_ip_pim_ucast_bsm,
|
||||
NO_STR
|
||||
IP_STR
|
||||
PIM_STR
|
||||
"Block send/receive unicast BSM on this interface\n")
|
||||
"Accept/Send unicast BSM on the interface\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "false");
|
||||
|
||||
return nb_cli_apply_changes(vty,
|
||||
FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4");
|
||||
return pim_process_no_unicast_bsm_cmd(vty);
|
||||
}
|
||||
|
||||
#if HAVE_BFDD > 0
|
||||
|
||||
@ -3416,6 +3416,66 @@ int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
int pim_process_bsm_cmd(struct vty *vty)
|
||||
{
|
||||
const struct lyd_node *gm_enable_dnode;
|
||||
|
||||
gm_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
|
||||
FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
|
||||
FRR_PIM_AF_XPATH_VAL);
|
||||
if (!gm_enable_dnode)
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
else {
|
||||
if (!yang_dnode_get_bool(gm_enable_dnode, "."))
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
}
|
||||
|
||||
nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "true");
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH,
|
||||
FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
int pim_process_no_bsm_cmd(struct vty *vty)
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./bsm", NB_OP_MODIFY, "false");
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH,
|
||||
FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
int pim_process_unicast_bsm_cmd(struct vty *vty)
|
||||
{
|
||||
const struct lyd_node *gm_enable_dnode;
|
||||
|
||||
gm_enable_dnode = yang_dnode_getf(vty->candidate_config->dnode,
|
||||
FRR_GMP_ENABLE_XPATH, VTY_CURR_XPATH,
|
||||
FRR_PIM_AF_XPATH_VAL);
|
||||
if (!gm_enable_dnode)
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
else {
|
||||
if (!yang_dnode_get_bool(gm_enable_dnode, "."))
|
||||
nb_cli_enqueue_change(vty, "./pim-enable", NB_OP_MODIFY,
|
||||
"true");
|
||||
}
|
||||
|
||||
nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "true");
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH,
|
||||
FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
int pim_process_no_unicast_bsm_cmd(struct vty *vty)
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./unicast-bsm", NB_OP_MODIFY, "false");
|
||||
|
||||
return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH,
|
||||
FRR_PIM_AF_XPATH_VAL);
|
||||
}
|
||||
|
||||
static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
|
||||
time_t now)
|
||||
{
|
||||
@ -5183,3 +5243,416 @@ void clear_pim_interfaces(struct pim_instance *pim)
|
||||
pim_neighbor_delete_all(ifp, "interface cleared");
|
||||
}
|
||||
}
|
||||
|
||||
void pim_show_bsr(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||
{
|
||||
char uptime[10];
|
||||
char last_bsm_seen[10];
|
||||
time_t now;
|
||||
char bsr_state[20];
|
||||
json_object *json = NULL;
|
||||
|
||||
if (pim_addr_is_any(pim->global_scope.current_bsr)) {
|
||||
pim_time_uptime(uptime, sizeof(uptime),
|
||||
pim->global_scope.current_bsr_first_ts);
|
||||
pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
|
||||
pim->global_scope.current_bsr_last_ts);
|
||||
}
|
||||
|
||||
else {
|
||||
now = pim_time_monotonic_sec();
|
||||
pim_time_uptime(uptime, sizeof(uptime),
|
||||
(now - pim->global_scope.current_bsr_first_ts));
|
||||
pim_time_uptime(last_bsm_seen, sizeof(last_bsm_seen),
|
||||
now - pim->global_scope.current_bsr_last_ts);
|
||||
}
|
||||
|
||||
switch (pim->global_scope.state) {
|
||||
case NO_INFO:
|
||||
strlcpy(bsr_state, "NO_INFO", sizeof(bsr_state));
|
||||
break;
|
||||
case ACCEPT_ANY:
|
||||
strlcpy(bsr_state, "ACCEPT_ANY", sizeof(bsr_state));
|
||||
break;
|
||||
case ACCEPT_PREFERRED:
|
||||
strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
|
||||
break;
|
||||
default:
|
||||
strlcpy(bsr_state, "", sizeof(bsr_state));
|
||||
}
|
||||
|
||||
|
||||
if (uj) {
|
||||
json = json_object_new_object();
|
||||
json_object_string_addf(json, "bsr", "%pPA",
|
||||
&pim->global_scope.current_bsr);
|
||||
json_object_int_add(json, "priority",
|
||||
pim->global_scope.current_bsr_prio);
|
||||
json_object_int_add(json, "fragmentTag",
|
||||
pim->global_scope.bsm_frag_tag);
|
||||
json_object_string_add(json, "state", bsr_state);
|
||||
json_object_string_add(json, "upTime", uptime);
|
||||
json_object_string_add(json, "lastBsmSeen", last_bsm_seen);
|
||||
}
|
||||
|
||||
else {
|
||||
vty_out(vty, "PIMv2 Bootstrap information\n");
|
||||
vty_out(vty, "Current preferred BSR address: %pPA\n",
|
||||
&pim->global_scope.current_bsr);
|
||||
vty_out(vty,
|
||||
"Priority Fragment-Tag State UpTime\n");
|
||||
vty_out(vty, " %-12d %-12d %-13s %7s\n",
|
||||
pim->global_scope.current_bsr_prio,
|
||||
pim->global_scope.bsm_frag_tag, bsr_state, uptime);
|
||||
vty_out(vty, "Last BSM seen: %s\n", last_bsm_seen);
|
||||
}
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
}
|
||||
|
||||
int pim_show_bsr_helper(const char *vrf, struct vty *vty, bool uj)
|
||||
{
|
||||
struct pim_instance *pim;
|
||||
struct vrf *v;
|
||||
|
||||
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
|
||||
if (!v)
|
||||
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;
|
||||
}
|
||||
|
||||
pim_show_bsr(v->info, vty, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/*Display the group-rp mappings */
|
||||
static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
|
||||
struct vty *vty, bool uj)
|
||||
{
|
||||
struct bsgrp_node *bsgrp;
|
||||
struct bsm_rpinfo *bsm_rp;
|
||||
struct route_node *rn;
|
||||
json_object *json = NULL;
|
||||
json_object *json_group = NULL;
|
||||
json_object *json_row = NULL;
|
||||
|
||||
if (uj) {
|
||||
json = json_object_new_object();
|
||||
json_object_string_addf(json, "BSR Address", "%pPA",
|
||||
&pim->global_scope.current_bsr);
|
||||
} else
|
||||
vty_out(vty, "BSR Address %pPA\n",
|
||||
&pim->global_scope.current_bsr);
|
||||
|
||||
for (rn = route_top(pim->global_scope.bsrp_table); rn;
|
||||
rn = route_next(rn)) {
|
||||
bsgrp = (struct bsgrp_node *)rn->info;
|
||||
|
||||
if (!bsgrp)
|
||||
continue;
|
||||
|
||||
char grp_str[PREFIX_STRLEN];
|
||||
|
||||
prefix2str(&bsgrp->group, grp_str, sizeof(grp_str));
|
||||
|
||||
if (uj) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
vty_out(vty, "Group Address %pFX\n", &bsgrp->group);
|
||||
vty_out(vty, "--------------------------\n");
|
||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
|
||||
"priority", "Holdtime", "Hash");
|
||||
|
||||
vty_out(vty, "(ACTIVE)\n");
|
||||
}
|
||||
|
||||
frr_each (bsm_rpinfos, bsgrp->bsrp_list, bsm_rp) {
|
||||
if (uj) {
|
||||
json_row = json_object_new_object();
|
||||
json_object_string_addf(json_row, "Rp Address",
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
json_object_int_add(json_row, "Rp HoldTime",
|
||||
bsm_rp->rp_holdtime);
|
||||
json_object_int_add(json_row, "Rp Priority",
|
||||
bsm_rp->rp_prio);
|
||||
json_object_int_add(json_row, "Hash Val",
|
||||
bsm_rp->hash);
|
||||
json_object_object_addf(json_group, json_row,
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
|
||||
} else {
|
||||
vty_out(vty, "%-15pPA %-15u %-15u %-15u\n",
|
||||
&bsm_rp->rp_address, bsm_rp->rp_prio,
|
||||
bsm_rp->rp_holdtime, bsm_rp->hash);
|
||||
}
|
||||
}
|
||||
if (!bsm_rpinfos_count(bsgrp->bsrp_list) && !uj)
|
||||
vty_out(vty, "Active List is empty.\n");
|
||||
|
||||
if (uj) {
|
||||
json_object_int_add(json_group, "Pending RP count",
|
||||
bsgrp->pend_rp_cnt);
|
||||
} else {
|
||||
vty_out(vty, "(PENDING)\n");
|
||||
vty_out(vty, "Pending RP count :%d\n",
|
||||
bsgrp->pend_rp_cnt);
|
||||
if (bsgrp->pend_rp_cnt)
|
||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n",
|
||||
"Rp Address", "priority", "Holdtime",
|
||||
"Hash");
|
||||
}
|
||||
|
||||
frr_each (bsm_rpinfos, bsgrp->partial_bsrp_list, bsm_rp) {
|
||||
if (uj) {
|
||||
json_row = json_object_new_object();
|
||||
json_object_string_addf(json_row, "Rp Address",
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
json_object_int_add(json_row, "Rp HoldTime",
|
||||
bsm_rp->rp_holdtime);
|
||||
json_object_int_add(json_row, "Rp Priority",
|
||||
bsm_rp->rp_prio);
|
||||
json_object_int_add(json_row, "Hash Val",
|
||||
bsm_rp->hash);
|
||||
json_object_object_addf(json_group, json_row,
|
||||
"%pPA",
|
||||
&bsm_rp->rp_address);
|
||||
} else {
|
||||
vty_out(vty, "%-15pPA %-15u %-15u %-15u\n",
|
||||
&bsm_rp->rp_address, bsm_rp->rp_prio,
|
||||
bsm_rp->rp_holdtime, bsm_rp->hash);
|
||||
}
|
||||
}
|
||||
if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj)
|
||||
vty_out(vty, "Partial List is empty\n");
|
||||
|
||||
if (!uj)
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
}
|
||||
|
||||
int pim_show_group_rp_mappings_info_helper(const char *vrf, struct vty *vty,
|
||||
bool uj)
|
||||
{
|
||||
struct pim_instance *pim;
|
||||
struct vrf *v;
|
||||
|
||||
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
|
||||
if (!v)
|
||||
return CMD_WARNING;
|
||||
|
||||
pim = v->info;
|
||||
|
||||
if (!pim) {
|
||||
vty_out(vty, "%% Unable to find pim instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
pim_show_group_rp_mappings_info(v->info, vty, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* Display the bsm database details */
|
||||
static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||
{
|
||||
int count = 0;
|
||||
int fragment = 1;
|
||||
struct bsm_frag *bsfrag;
|
||||
json_object *json = NULL;
|
||||
json_object *json_group = NULL;
|
||||
json_object *json_row = NULL;
|
||||
|
||||
count = bsm_frags_count(pim->global_scope.bsm_frags);
|
||||
|
||||
if (uj) {
|
||||
json = json_object_new_object();
|
||||
json_object_int_add(json, "Number of the fragments", count);
|
||||
} else {
|
||||
vty_out(vty, "Scope Zone: Global\n");
|
||||
vty_out(vty, "Number of the fragments: %d\n", count);
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
frr_each (bsm_frags, pim->global_scope.bsm_frags, bsfrag) {
|
||||
char grp_str[PREFIX_STRLEN];
|
||||
struct bsmmsg_grpinfo *group;
|
||||
struct bsmmsg_rpinfo *bsm_rpinfo;
|
||||
struct prefix grp;
|
||||
struct bsm_hdr *hdr;
|
||||
pim_addr bsr_addr;
|
||||
uint32_t offset = 0;
|
||||
uint8_t *buf;
|
||||
uint32_t len = 0;
|
||||
uint32_t frag_rp_cnt = 0;
|
||||
|
||||
buf = bsfrag->data;
|
||||
len = bsfrag->size;
|
||||
|
||||
/* skip pim header */
|
||||
buf += PIM_MSG_HEADER_LEN;
|
||||
len -= PIM_MSG_HEADER_LEN;
|
||||
|
||||
hdr = (struct bsm_hdr *)buf;
|
||||
/* NB: bshdr->bsr_addr.addr is packed/unaligned => memcpy */
|
||||
memcpy(&bsr_addr, &hdr->bsr_addr.addr, sizeof(bsr_addr));
|
||||
|
||||
/* BSM starts with bsr header */
|
||||
buf += sizeof(struct bsm_hdr);
|
||||
len -= sizeof(struct bsm_hdr);
|
||||
|
||||
if (uj) {
|
||||
json_object_string_addf(json, "BSR address", "%pPA",
|
||||
&bsr_addr);
|
||||
json_object_int_add(json, "BSR priority",
|
||||
hdr->bsr_prio);
|
||||
json_object_int_add(json, "Hashmask Length",
|
||||
hdr->hm_len);
|
||||
json_object_int_add(json, "Fragment Tag",
|
||||
ntohs(hdr->frag_tag));
|
||||
} else {
|
||||
vty_out(vty, "BSM Fragment : %d\n", fragment);
|
||||
vty_out(vty, "------------------\n");
|
||||
vty_out(vty, "%-15s %-15s %-15s %-15s\n", "BSR-Address",
|
||||
"BSR-Priority", "Hashmask-len", "Fragment-Tag");
|
||||
vty_out(vty, "%-15pPA %-15d %-15d %-15d\n", &bsr_addr,
|
||||
hdr->bsr_prio, hdr->hm_len,
|
||||
ntohs(hdr->frag_tag));
|
||||
}
|
||||
|
||||
vty_out(vty, "\n");
|
||||
|
||||
while (offset < len) {
|
||||
group = (struct bsmmsg_grpinfo *)buf;
|
||||
|
||||
if (group->group.family == PIM_MSG_ADDRESS_FAMILY_IPV4)
|
||||
grp.family = AF_INET;
|
||||
else if (group->group.family ==
|
||||
PIM_MSG_ADDRESS_FAMILY_IPV6)
|
||||
grp.family = AF_INET6;
|
||||
|
||||
grp.prefixlen = group->group.mask;
|
||||
#if PIM_IPV == 4
|
||||
grp.u.prefix4 = group->group.addr;
|
||||
#else
|
||||
grp.u.prefix6 = group->group.addr;
|
||||
#endif
|
||||
|
||||
prefix2str(&grp, grp_str, sizeof(grp_str));
|
||||
|
||||
buf += sizeof(struct bsmmsg_grpinfo);
|
||||
offset += sizeof(struct bsmmsg_grpinfo);
|
||||
|
||||
if (uj) {
|
||||
json_object_object_get_ex(json, grp_str,
|
||||
&json_group);
|
||||
if (!json_group) {
|
||||
json_group = json_object_new_object();
|
||||
json_object_int_add(json_group,
|
||||
"Rp Count",
|
||||
group->rp_count);
|
||||
json_object_int_add(
|
||||
json_group, "Fragment Rp count",
|
||||
group->frag_rp_count);
|
||||
json_object_object_add(json, grp_str,
|
||||
json_group);
|
||||
}
|
||||
} else {
|
||||
vty_out(vty, "Group : %s\n", grp_str);
|
||||
vty_out(vty, "-------------------\n");
|
||||
vty_out(vty, "Rp Count:%d\n", group->rp_count);
|
||||
vty_out(vty, "Fragment Rp Count : %d\n",
|
||||
group->frag_rp_count);
|
||||
}
|
||||
|
||||
frag_rp_cnt = group->frag_rp_count;
|
||||
|
||||
if (!frag_rp_cnt)
|
||||
continue;
|
||||
|
||||
if (!uj)
|
||||
vty_out(vty,
|
||||
"RpAddress HoldTime Priority\n");
|
||||
|
||||
while (frag_rp_cnt--) {
|
||||
pim_addr rp_addr;
|
||||
|
||||
bsm_rpinfo = (struct bsmmsg_rpinfo *)buf;
|
||||
/* unaligned, again */
|
||||
memcpy(&rp_addr, &bsm_rpinfo->rpaddr,
|
||||
sizeof(rp_addr));
|
||||
|
||||
buf += sizeof(struct bsmmsg_rpinfo);
|
||||
offset += sizeof(struct bsmmsg_rpinfo);
|
||||
|
||||
if (uj) {
|
||||
json_row = json_object_new_object();
|
||||
json_object_string_addf(
|
||||
json_row, "Rp Address", "%pPA",
|
||||
&rp_addr);
|
||||
json_object_int_add(
|
||||
json_row, "Rp HoldTime",
|
||||
ntohs(bsm_rpinfo->rp_holdtime));
|
||||
json_object_int_add(json_row,
|
||||
"Rp Priority",
|
||||
bsm_rpinfo->rp_pri);
|
||||
json_object_object_addf(
|
||||
json_group, json_row, "%pPA",
|
||||
&rp_addr);
|
||||
} else {
|
||||
vty_out(vty, "%-15pPA %-12d %d\n",
|
||||
&rp_addr,
|
||||
ntohs(bsm_rpinfo->rp_holdtime),
|
||||
bsm_rpinfo->rp_pri);
|
||||
}
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
fragment++;
|
||||
}
|
||||
|
||||
if (uj)
|
||||
vty_json(vty, json);
|
||||
}
|
||||
|
||||
int pim_show_bsm_db_helper(const char *vrf, struct vty *vty, bool uj)
|
||||
{
|
||||
struct pim_instance *pim;
|
||||
struct vrf *v;
|
||||
|
||||
v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
|
||||
if (!v)
|
||||
return CMD_WARNING;
|
||||
|
||||
pim = v->info;
|
||||
|
||||
if (!pim) {
|
||||
vty_out(vty, "%% Unable to find pim instance\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
pim_show_bsm_db(v->info, vty, uj);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@ -62,6 +62,10 @@ int pim_process_ip_mroute_cmd(struct vty *vty, const char *interface,
|
||||
const char *group_str, const char *source_str);
|
||||
int pim_process_no_ip_mroute_cmd(struct vty *vty, const char *interface,
|
||||
const char *group_str, const char *src_str);
|
||||
int pim_process_bsm_cmd(struct vty *vty);
|
||||
int pim_process_no_bsm_cmd(struct vty *vty);
|
||||
int pim_process_unicast_bsm_cmd(struct vty *vty);
|
||||
int pim_process_no_unicast_bsm_cmd(struct vty *vty);
|
||||
void json_object_pim_upstream_add(json_object *json, struct pim_upstream *up);
|
||||
void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json);
|
||||
void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty);
|
||||
@ -114,6 +118,9 @@ void pim_show_neighbors_single(struct pim_instance *pim, struct vty *vty,
|
||||
const char *neighbor, json_object *json);
|
||||
void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
|
||||
json_object *json);
|
||||
int pim_show_group_rp_mappings_info_helper(const char *vrf, struct vty *vty,
|
||||
bool uj);
|
||||
int pim_show_bsm_db_helper(const char *vrf, struct vty *vty, bool uj);
|
||||
int gm_process_query_max_response_time_cmd(struct vty *vty,
|
||||
const char *qmrt_str);
|
||||
int gm_process_no_query_max_response_time_cmd(struct vty *vty);
|
||||
@ -186,6 +193,8 @@ void pim_show_interface_traffic(struct pim_instance *pim, struct vty *vty,
|
||||
int pim_show_interface_traffic_helper(const char *vrf, const char *if_name,
|
||||
struct vty *vty, bool uj);
|
||||
void clear_pim_interfaces(struct pim_instance *pim);
|
||||
void pim_show_bsr(struct pim_instance *pim, struct vty *vty, bool uj);
|
||||
int pim_show_bsr_helper(const char *vrf, struct vty *vty, bool uj);
|
||||
/*
|
||||
* Special Macro to allow us to get the correct pim_instance;
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user