summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/user/pim.rst2
-rw-r--r--doc/user/pimv6.rst28
-rw-r--r--pimd/pim6_cmd.c106
-rw-r--r--pimd/pim6_cmd.h1
-rw-r--r--pimd/pim_cmd.c453
-rw-r--r--pimd/pim_cmd_common.c473
-rw-r--r--pimd/pim_cmd_common.h9
7 files changed, 634 insertions, 438 deletions
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index 44ade916a2..5d849c7b8a 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -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]
diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst
index b242f4fe17..7fd2856001 100644
--- a/doc/user/pimv6.rst
+++ b/doc/user/pimv6.rst
@@ -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.
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index f6b370cee3..ae272bbb92 100644
--- a/pimd/pim6_cmd.c
+++ b/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);
}
diff --git a/pimd/pim6_cmd.h b/pimd/pim6_cmd.h
index c45c998453..d9ff2ca70b 100644
--- a/pimd/pim6_cmd.h
+++ b/pimd/pim6_cmd.h
@@ -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);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index ab0689a156..efa1382fc0 100644
--- a/pimd/pim_cmd.c
+++ b/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
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index 9283016d08..08f6c6f61e 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -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;
+}
diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h
index 27c029670e..d34a4af9e1 100644
--- a/pimd/pim_cmd_common.h
+++ b/pimd/pim_cmd_common.h
@@ -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;
*/