Merge pull request #11600 from patrasar/pimv6_bsm_clis

pim6d:  BSM CLIs implementation
This commit is contained in:
Donatas Abraitis 2022-10-21 09:41:22 +03:00 committed by GitHub
commit 8e9729cc72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 634 additions and 438 deletions

View File

@ -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]

View File

@ -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.

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;
*/