summaryrefslogtreecommitdiff
path: root/pimd/pim_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_cmd.c')
-rw-r--r--pimd/pim_cmd.c620
1 files changed, 325 insertions, 295 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 548c866e4d..812c8c1449 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -72,14 +72,6 @@
#include "pimd/pim_cmd_clippy.c"
#endif
-static struct cmd_node interface_node = {
- .name = "interface",
- .node = INTERFACE_NODE,
- .parent_node = CONFIG_NODE,
- .prompt = "%s(config-if)# ",
- .config_write = pim_interface_config_write,
-};
-
static struct cmd_node debug_node = {
.name = "debug",
.node = DEBUG_NODE,
@@ -497,6 +489,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
struct interface *ifp;
time_t now;
char buf[PREFIX_STRLEN];
+ char quer_buf[PREFIX_STRLEN];
json_object *json = NULL;
json_object *json_row = NULL;
@@ -506,7 +499,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
json = json_object_new_object();
else
vty_out(vty,
- "Interface State Address V Querier Query Timer Uptime\n");
+ "Interface State Address V Querier QuerierIp Query Timer Uptime\n");
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp;
@@ -544,6 +537,10 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
"queryTimer",
query_hhmmss);
}
+ json_object_string_add(
+ json_row, "querierIp",
+ inet_ntop(AF_INET, &igmp->querier_addr,
+ quer_buf, sizeof(quer_buf)));
json_object_object_add(json, ifp->name,
json_row);
@@ -554,18 +551,19 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
}
} else {
vty_out(vty,
- "%-16s %5s %15s %d %7s %11s %8s\n",
+ "%-16s %5s %15s %d %7s %17pI4 %11s %8s\n",
ifp->name,
if_is_up(ifp)
- ? (igmp->mtrace_only ? "mtrc"
- : "up")
- : "down",
- inet_ntop(AF_INET, &igmp->ifaddr,
- buf, sizeof(buf)),
+ ? (igmp->mtrace_only ? "mtrc"
+ : "up")
+ : "down",
+ inet_ntop(AF_INET, &igmp->ifaddr, buf,
+ sizeof(buf)),
pim_ifp->igmp_version,
igmp->t_igmp_query_timer ? "local"
- : "other",
- query_hhmmss, uptime);
+ : "other",
+ &igmp->querier_addr, query_hhmmss,
+ uptime);
}
}
}
@@ -586,6 +584,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
struct listnode *sock_node;
struct pim_interface *pim_ifp;
char uptime[10];
+ char quer_buf[PREFIX_STRLEN];
char query_hhmmss[10];
char other_hhmmss[10];
int found_ifname = 0;
@@ -670,6 +669,10 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
igmp->t_igmp_query_timer
? "local"
: "other");
+ json_object_string_add(
+ json_row, "querierIp",
+ inet_ntop(AF_INET, &igmp->querier_addr,
+ quer_buf, sizeof(quer_buf)));
json_object_int_add(json_row, "queryStartCount",
igmp->startup_query_count);
json_object_string_add(json_row,
@@ -739,6 +742,14 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
vty_out(vty, "Querier : %s\n",
igmp->t_igmp_query_timer ? "local"
: "other");
+ vty_out(vty, "QuerierIp : %pI4",
+ &igmp->querier_addr);
+ if (pim_ifp->primary_address.s_addr
+ == igmp->querier_addr.s_addr)
+ vty_out(vty, " (this router)\n");
+ else
+ vty_out(vty, "\n");
+
vty_out(vty, "Start Count : %d\n",
igmp->startup_query_count);
vty_out(vty, "Query Timer : %s\n",
@@ -810,7 +821,7 @@ static void igmp_show_interface_join(struct pim_instance *pim, struct vty *vty,
if (uj) {
json = json_object_new_object();
json_object_string_add(json, "vrf",
- vrf_id_to_name(pim->vrf_id));
+ vrf_id_to_name(pim->vrf->vrf_id));
} else {
vty_out(vty,
"Interface Address Source Group Socket Uptime \n");
@@ -1135,6 +1146,12 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
json_object_int_add(
json_row, "overrideIntervalHighest",
pim_ifp->pim_neighbors_highest_override_interval_msec);
+ if (pim_ifp->bsm_enable)
+ json_object_boolean_true_add(json_row,
+ "bsmEnabled");
+ if (pim_ifp->ucast_bsm_accept)
+ json_object_boolean_true_add(json_row,
+ "ucastBsmEnabled");
json_object_object_add(json, ifp->name, json_row);
} else {
@@ -1289,6 +1306,15 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
pim_ifp->pim_neighbors_highest_override_interval_msec);
vty_out(vty, "\n");
vty_out(vty, "\n");
+
+ vty_out(vty, "BSM Status\n");
+ vty_out(vty, "----------\n");
+ vty_out(vty, "Bsm Enabled : %s\n",
+ pim_ifp->bsm_enable ? "yes" : "no");
+ vty_out(vty, "Unicast Bsm Enabled : %s\n",
+ pim_ifp->ucast_bsm_accept ? "yes" : "no");
+ vty_out(vty, "\n");
+ vty_out(vty, "\n");
}
}
@@ -2971,7 +2997,7 @@ static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
first_ifindex = nh_node->ifindex;
- ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
+ ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
vty_out(vty, "%-15s ", inet_ntop(AF_INET,
&pnc->rpf.rpf_addr.u.prefix4,
@@ -3853,6 +3879,54 @@ static const char *pim_cli_get_vrf_name(struct vty *vty)
return yang_dnode_get_string(vrf_node, "./name");
}
+/**
+ * Compatibility function to keep the legacy mesh group CLI behavior:
+ * Delete group when there are no more configurations in it.
+ *
+ * NOTE:
+ * Don't forget to call `nb_cli_apply_changes` after this.
+ */
+static void pim_cli_legacy_mesh_group_behavior(struct vty *vty,
+ const char *gname)
+{
+ const char *vrfname;
+ char xpath_value[XPATH_MAXLEN];
+ char xpath_member_value[XPATH_MAXLEN];
+ const struct lyd_node *member_dnode;
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return;
+
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ FRR_PIM_AF_XPATH "/msdp-mesh-groups[name='%s']",
+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ /* Group must exists, otherwise just quit. */
+ if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
+ return;
+
+ /* Group members check: */
+ strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
+ strlcat(xpath_member_value, "/members", sizeof(xpath_member_value));
+ if (yang_dnode_exists(vty->candidate_config->dnode,
+ xpath_member_value)) {
+ member_dnode = yang_dnode_get(vty->candidate_config->dnode,
+ xpath_member_value);
+ if (!yang_is_last_list_dnode(member_dnode))
+ return;
+ }
+
+ /* Source address check: */
+ strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
+ strlcat(xpath_member_value, "/source", sizeof(xpath_member_value));
+ if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value))
+ return;
+
+ /* No configurations found: delete it. */
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
+}
+
DEFUN (clear_ip_interfaces,
clear_ip_interfaces_cmd,
"clear ip interfaces [vrf NAME]",
@@ -6275,7 +6349,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
if (!uj && !found_oif) {
vty_out(vty,
- "%-15s %-15s %-15s %-6s %-16s %-16s %-3d %8s\n",
+ "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
src_str, grp_str, state_str, "none", in_ifname,
"none", 0, "--:--:--");
}
@@ -6382,10 +6456,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
json_ifp_out);
} else {
vty_out(vty,
- "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
- src_str, grp_str, proto, in_ifname,
- out_ifname, ttl, oif_uptime,
- pim->vrf->name);
+ "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
+ src_str, grp_str, "-", proto, in_ifname,
+ out_ifname, ttl, oif_uptime);
if (first && !fill) {
src_str[0] = '\0';
grp_str[0] = '\0';
@@ -6397,9 +6470,9 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
if (!uj && !found_oif) {
vty_out(vty,
- "%-15s %-15s %-6s %-16s %-16s %-3d %8s %s\n",
- src_str, grp_str, proto, in_ifname, "none", 0,
- "--:--:--", pim->vrf->name);
+ "%-15s %-15s %-8s %-6s %-16s %-16s %-3d %8s\n",
+ src_str, grp_str, "-", proto, in_ifname, "none",
+ 0, "--:--:--");
}
}
@@ -7106,7 +7179,7 @@ DEFPY (pim_register_accept_list,
DEFUN (ip_pim_joinprune_time,
ip_pim_joinprune_time_cmd,
- "ip pim join-prune-interval (60-600)",
+ "ip pim join-prune-interval (5-600)",
IP_STR
"pim multicast routing\n"
"Join Prune Send Interval\n"
@@ -7120,7 +7193,7 @@ DEFUN (ip_pim_joinprune_time,
DEFUN (no_ip_pim_joinprune_time,
no_ip_pim_joinprune_time_cmd,
- "no ip pim join-prune-interval (60-600)",
+ "no ip pim join-prune-interval (5-600)",
NO_STR
IP_STR
"pim multicast routing\n"
@@ -8274,11 +8347,12 @@ DEFUN (interface_ip_igmp_last_member_query_count,
DEFUN (interface_no_ip_igmp_last_member_query_count,
interface_no_ip_igmp_last_member_query_count_cmd,
- "no ip igmp last-member-query-count",
+ "no ip igmp last-member-query-count [(1-7)]",
NO_STR
IP_STR
IFACE_IGMP_STR
- IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR)
+ IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR
+ "Last member query count\n")
{
char default_robustness[2];
@@ -8321,11 +8395,12 @@ DEFUN (interface_ip_igmp_last_member_query_interval,
DEFUN (interface_no_ip_igmp_last_member_query_interval,
interface_no_ip_igmp_last_member_query_interval_cmd,
- "no ip igmp last-member-query-interval",
+ "no ip igmp last-member-query-interval [(1-255)]",
NO_STR
IP_STR
IFACE_IGMP_STR
- IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR)
+ IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR
+ "Last member query interval in deciseconds\n")
{
char default_last_member_query_count[4];
@@ -8705,7 +8780,7 @@ DEFUN (interface_no_ip_mroute,
DEFUN (interface_ip_pim_hello,
interface_ip_pim_hello_cmd,
- "ip pim hello (1-180) [(1-180)]",
+ "ip pim hello (1-180) [(1-630)]",
IP_STR
PIM_STR
IFACE_PIM_HELLO_STR
@@ -8740,7 +8815,7 @@ DEFUN (interface_ip_pim_hello,
DEFUN (interface_no_ip_pim_hello,
interface_no_ip_pim_hello_cmd,
- "no ip pim hello [(1-180) [(1-180)]]",
+ "no ip pim hello [(1-180) [(1-630)]]",
NO_STR
IP_STR
PIM_STR
@@ -9621,15 +9696,14 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
"Desired min transmit interval\n")
#endif /* !HAVE_BFDD */
- DEFUN (ip_msdp_peer,
- ip_msdp_peer_cmd,
- "ip msdp peer A.B.C.D source A.B.C.D",
- IP_STR
- CFG_MSDP_STR
- "Configure MSDP peer\n"
- "peer ip address\n"
- "Source address for TCP connection\n"
- "local ip address\n")
+DEFPY(ip_msdp_peer, ip_msdp_peer_cmd,
+ "ip msdp peer A.B.C.D$peer source A.B.C.D$source",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP peer\n"
+ "Peer IP address\n"
+ "Source address for TCP connection\n"
+ "Local IP address\n")
{
const char *vrfname;
char temp_xpath[XPATH_MAXLEN];
@@ -9640,20 +9714,51 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
return CMD_WARNING_CONFIG_FAILED;
snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
+ FRR_PIM_AF_XPATH, "frr-pim:pimd", "pim", vrfname,
+ "frr-routing:ipv4");
snprintf(temp_xpath, sizeof(temp_xpath),
- "/msdp-peer[peer-ip='%s']/source-ip",
- argv[3]->arg);
+ "/msdp-peer[peer-ip='%s']/source-ip", peer_str);
strlcat(msdp_peer_source_xpath, temp_xpath,
sizeof(msdp_peer_source_xpath));
nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
- argv[5]->arg);
+ source_str);
return nb_cli_apply_changes(vty, NULL);
}
+DEFPY(ip_msdp_timers, ip_msdp_timers_cmd,
+ "ip msdp timers (2-600)$keepalive (3-600)$holdtime [(1-600)$connretry]",
+ IP_STR
+ CFG_MSDP_STR
+ "MSDP timers configuration\n"
+ "Keep alive period (in seconds)\n"
+ "Hold time period (in seconds)\n"
+ "Connection retry period (in seconds)\n")
+{
+ const char *vrfname;
+ char xpath[XPATH_MAXLEN];
+
+ vrfname = pim_cli_get_vrf_name(vty);
+ if (vrfname == NULL)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ snprintf(xpath, sizeof(xpath), FRR_PIM_MSDP_XPATH, "frr-pim:pimd",
+ "pim", vrfname, "frr-routing:ipv4");
+ nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str);
+ nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str);
+ if (connretry_str)
+ nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY,
+ connretry_str);
+ else
+ nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY,
+ NULL);
+
+ nb_cli_apply_changes(vty, xpath);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (no_ip_msdp_peer,
no_ip_msdp_peer_cmd,
"no ip msdp peer A.B.C.D",
@@ -9685,305 +9790,199 @@ DEFUN (no_ip_msdp_peer,
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (ip_msdp_mesh_group_member,
- ip_msdp_mesh_group_member_cmd,
- "ip msdp mesh-group WORD member A.B.C.D",
- IP_STR
- CFG_MSDP_STR
- "Configure MSDP mesh-group\n"
- "mesh group name\n"
- "mesh group member\n"
- "peer ip address\n")
+DEFPY(ip_msdp_mesh_group_member,
+ ip_msdp_mesh_group_member_cmd,
+ "ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP mesh-group\n"
+ "Mesh group name\n"
+ "Mesh group member\n"
+ "Peer IP address\n")
{
const char *vrfname;
- char msdp_mesh_group_name_xpath[XPATH_MAXLEN];
- char msdp_mesh_group_member_xpath[XPATH_MAXLEN];
+ char xpath_value[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
- snprintf(msdp_mesh_group_name_xpath, sizeof(msdp_mesh_group_name_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(msdp_mesh_group_name_xpath, "/msdp-mesh-group/mesh-group-name",
- sizeof(msdp_mesh_group_name_xpath));
- snprintf(msdp_mesh_group_member_xpath,
- sizeof(msdp_mesh_group_member_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(msdp_mesh_group_member_xpath, "/msdp-mesh-group/member-ip",
- sizeof(msdp_mesh_group_member_xpath));
+ /* Create mesh group. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ FRR_PIM_AF_XPATH "/msdp-mesh-groups[name='%s']",
+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
- nb_cli_enqueue_change(vty, msdp_mesh_group_name_xpath, NB_OP_MODIFY,
- argv[3]->arg);
- nb_cli_enqueue_change(vty, msdp_mesh_group_member_xpath, NB_OP_CREATE,
- argv[5]->arg);
+ /* Create mesh group member. */
+ strlcat(xpath_value, "/members[address='", sizeof(xpath_value));
+ strlcat(xpath_value, maddr_str, sizeof(xpath_value));
+ strlcat(xpath_value, "']", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (no_ip_msdp_mesh_group_member,
- no_ip_msdp_mesh_group_member_cmd,
- "no ip msdp mesh-group WORD member A.B.C.D",
- NO_STR
- IP_STR
- CFG_MSDP_STR
- "Delete MSDP mesh-group member\n"
- "mesh group name\n"
- "mesh group member\n"
- "peer ip address\n")
+DEFPY(no_ip_msdp_mesh_group_member,
+ no_ip_msdp_mesh_group_member_cmd,
+ "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group member\n"
+ "Mesh group name\n"
+ "Mesh group member\n"
+ "Peer IP address\n")
{
const char *vrfname;
- char pim_af_xpath[XPATH_MAXLEN];
- char mesh_group_xpath[XPATH_MAXLEN + 32];
- char group_member_list_xpath[XPATH_MAXLEN + 64];
- char group_member_xpath[XPATH_MAXLEN + 128];
- char source_xpath[XPATH_MAXLEN + 64];
- char mesh_group_name_xpath[XPATH_MAXLEN + 64];
- const char *mesh_group_name;
- const struct lyd_node *member_dnode;
+ char xpath_value[XPATH_MAXLEN];
+ char xpath_member_value[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
- snprintf(pim_af_xpath, sizeof(pim_af_xpath), FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
-
- snprintf(mesh_group_xpath, sizeof(mesh_group_xpath),
- "%s/msdp-mesh-group", pim_af_xpath);
-
- snprintf(group_member_list_xpath, sizeof(group_member_list_xpath),
- "%s/msdp-mesh-group/member-ip", pim_af_xpath);
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ FRR_PIM_AF_XPATH "/msdp-mesh-groups[name='%s']",
+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
- snprintf(group_member_xpath, sizeof(group_member_xpath), "%s[.='%s']",
- group_member_list_xpath, argv[6]->arg);
-
- snprintf(source_xpath, sizeof(source_xpath),
- "%s/msdp-mesh-group/source-ip", pim_af_xpath);
-
- snprintf(mesh_group_name_xpath, sizeof(mesh_group_name_xpath),
- "%s/msdp-mesh-group/mesh-group-name", pim_af_xpath);
-
- if (yang_dnode_exists(running_config->dnode, mesh_group_name_xpath)
- == true) {
- mesh_group_name = yang_dnode_get_string(running_config->dnode,
- mesh_group_name_xpath);
- if (strcmp(mesh_group_name, argv[4]->arg)) {
- vty_out(vty, "%% mesh-group does not exist\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) {
+ vty_out(vty, "%% mesh-group does not exist\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- if (yang_dnode_exists(vty->candidate_config->dnode,
- group_member_xpath)) {
- if (!yang_dnode_exists(vty->candidate_config->dnode,
- source_xpath)) {
- member_dnode = yang_dnode_get(
- vty->candidate_config->dnode,
- group_member_xpath);
- if (yang_is_last_list_dnode(member_dnode)) {
- nb_cli_enqueue_change(vty, mesh_group_xpath,
- NB_OP_DESTROY, NULL);
- return nb_cli_apply_changes(vty, NULL);
- }
- nb_cli_enqueue_change(vty, group_member_list_xpath,
- NB_OP_DESTROY, argv[6]->arg);
- return nb_cli_apply_changes(vty, NULL);
- }
- nb_cli_enqueue_change(vty, group_member_list_xpath,
- NB_OP_DESTROY, argv[6]->arg);
- return nb_cli_apply_changes(vty, NULL);
+ /* Remove mesh group member. */
+ strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value));
+ strlcat(xpath_member_value, "/members[address='",
+ sizeof(xpath_member_value));
+ strlcat(xpath_member_value, maddr_str, sizeof(xpath_member_value));
+ strlcat(xpath_member_value, "']", sizeof(xpath_member_value));
+ if (!yang_dnode_exists(vty->candidate_config->dnode,
+ xpath_member_value)) {
+ vty_out(vty, "%% mesh-group member does not exist\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- vty_out(vty, "%% mesh-group member does not exist\n");
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
- return CMD_SUCCESS;
+ /*
+ * If this is the last member, then we must remove the group altogether
+ * to not break legacy CLI behaviour.
+ */
+ pim_cli_legacy_mesh_group_behavior(vty, gname);
+
+ return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (ip_msdp_mesh_group_source,
- ip_msdp_mesh_group_source_cmd,
- "ip msdp mesh-group WORD source A.B.C.D",
- IP_STR
- CFG_MSDP_STR
- "Configure MSDP mesh-group\n"
- "mesh group name\n"
- "mesh group local address\n"
- "source ip address for the TCP connection\n")
+DEFPY(ip_msdp_mesh_group_source,
+ ip_msdp_mesh_group_source_cmd,
+ "ip msdp mesh-group WORD$gname source A.B.C.D$saddr",
+ IP_STR
+ CFG_MSDP_STR
+ "Configure MSDP mesh-group\n"
+ "Mesh group name\n"
+ "Mesh group local address\n"
+ "Source IP address for the TCP connection\n")
{
const char *vrfname;
- char msdp_mesh_source_ip_xpath[XPATH_MAXLEN];
- char msdp_mesh_group_name_xpath[XPATH_MAXLEN];
+ char xpath_value[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
- snprintf(msdp_mesh_group_name_xpath, sizeof(msdp_mesh_group_name_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(msdp_mesh_group_name_xpath, "/msdp-mesh-group/mesh-group-name",
- sizeof(msdp_mesh_group_name_xpath));
+ /* Create mesh group. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ FRR_PIM_AF_XPATH "/msdp-mesh-groups[name='%s']",
+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
- snprintf(msdp_mesh_source_ip_xpath, sizeof(msdp_mesh_source_ip_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(msdp_mesh_source_ip_xpath, "/msdp-mesh-group/source-ip",
- sizeof(msdp_mesh_source_ip_xpath));
-
- nb_cli_enqueue_change(vty, msdp_mesh_group_name_xpath, NB_OP_MODIFY,
- argv[3]->arg);
- nb_cli_enqueue_change(vty, msdp_mesh_source_ip_xpath, NB_OP_MODIFY,
- argv[5]->arg);
+ /* Create mesh group member. */
+ strlcat(xpath_value, "/source", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str);
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (no_ip_msdp_mesh_group_source,
- no_ip_msdp_mesh_group_source_cmd,
- "no ip msdp mesh-group WORD source [A.B.C.D]",
- NO_STR
- IP_STR
- CFG_MSDP_STR
- "Delete MSDP mesh-group source\n"
- "mesh group name\n"
- "mesh group source\n"
- "mesh group local address\n")
+DEFPY(no_ip_msdp_mesh_group_source,
+ no_ip_msdp_mesh_group_source_cmd,
+ "no ip msdp mesh-group WORD$gname source [A.B.C.D]",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group source\n"
+ "Mesh group name\n"
+ "Mesh group source\n"
+ "Mesh group local address\n")
{
const char *vrfname;
- char msdp_mesh_xpath[XPATH_MAXLEN];
- char source_xpath[XPATH_MAXLEN];
- char group_member_xpath[XPATH_MAXLEN];
- char mesh_group_name_xpath[XPATH_MAXLEN];
- const char *mesh_group_name;
+ char xpath_value[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
- snprintf(msdp_mesh_xpath, sizeof(msdp_mesh_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(msdp_mesh_xpath, "/msdp-mesh-group", sizeof(msdp_mesh_xpath));
-
- snprintf(source_xpath, sizeof(source_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(source_xpath, "/msdp-mesh-group/source-ip",
- sizeof(source_xpath));
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ FRR_PIM_AF_XPATH "/msdp-mesh-groups[name='%s']",
+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL);
- snprintf(group_member_xpath,
- sizeof(group_member_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(group_member_xpath, "/msdp-mesh-group/member-ip",
- sizeof(group_member_xpath));
+ /* Create mesh group member. */
+ strlcat(xpath_value, "/source", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
- snprintf(mesh_group_name_xpath, sizeof(mesh_group_name_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(mesh_group_name_xpath, "/msdp-mesh-group/mesh-group-name",
- sizeof(mesh_group_name_xpath));
-
- if (yang_dnode_exists(running_config->dnode, mesh_group_name_xpath)
- == true) {
- mesh_group_name = yang_dnode_get_string(running_config->dnode,
- mesh_group_name_xpath);
- if (strcmp(mesh_group_name, argv[4]->arg)) {
- vty_out(vty, "%% mesh-group does not exist\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
+ /*
+ * If this is the last member, then we must remove the group altogether
+ * to not break legacy CLI behaviour.
+ */
+ pim_cli_legacy_mesh_group_behavior(vty, gname);
- if (!yang_dnode_exists(vty->candidate_config->dnode,
- group_member_xpath)) {
- nb_cli_enqueue_change(vty, msdp_mesh_xpath, NB_OP_DESTROY,
- NULL);
- return nb_cli_apply_changes(vty, NULL);
- }
- nb_cli_enqueue_change(vty, source_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
-DEFUN (no_ip_msdp_mesh_group,
- no_ip_msdp_mesh_group_cmd,
- "no ip msdp mesh-group [WORD]",
- NO_STR
- IP_STR
- CFG_MSDP_STR
- "Delete MSDP mesh-group\n"
- "mesh group name")
+DEFPY(no_ip_msdp_mesh_group,
+ no_ip_msdp_mesh_group_cmd,
+ "no ip msdp mesh-group WORD$gname",
+ NO_STR
+ IP_STR
+ CFG_MSDP_STR
+ "Delete MSDP mesh-group\n"
+ "Mesh group name")
{
const char *vrfname;
- const char *mesh_group_name;
- char xpath[XPATH_MAXLEN];
- char msdp_mesh_xpath[XPATH_MAXLEN];
+ char xpath_value[XPATH_MAXLEN];
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
- if (argc == 5) {
- snprintf(xpath, sizeof(xpath), FRR_PIM_AF_XPATH, "frr-pim:pimd",
- "pim", vrfname, "frr-routing:ipv4");
- strlcat(xpath, "/msdp-mesh-group/mesh-group-name",
- sizeof(xpath));
-
- if (yang_dnode_exists(running_config->dnode, xpath) == true) {
- mesh_group_name =
- yang_dnode_get_string(running_config->dnode,
- xpath);
-
- if (strcmp(mesh_group_name, argv[4]->arg)) {
- vty_out(vty, "%% mesh-group does not exist\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
- }
-
- snprintf(msdp_mesh_xpath, sizeof(msdp_mesh_xpath),
- FRR_PIM_AF_XPATH,
- "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
- strlcat(msdp_mesh_xpath, "/msdp-mesh-group", sizeof(msdp_mesh_xpath));
+ /* Get mesh group base XPath. */
+ snprintf(xpath_value, sizeof(xpath_value),
+ FRR_PIM_AF_XPATH "/msdp-mesh-groups[name='%s']",
+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname);
+ if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value))
+ return CMD_SUCCESS;
- nb_cli_enqueue_change(vty, msdp_mesh_xpath, NB_OP_DESTROY, NULL);
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
-static void print_empty_json_obj(struct vty *vty)
-{
- json_object *json;
- json = json_object_new_object();
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
-}
-
-static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
- bool uj)
+static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg,
+ struct json_object *json)
{
struct listnode *mbrnode;
struct pim_msdp_mg_mbr *mbr;
- struct pim_msdp_mg *mg = pim->msdp.mg;
char mbr_str[INET_ADDRSTRLEN];
char src_str[INET_ADDRSTRLEN];
char state_str[PIM_MSDP_STATE_STRLEN];
enum pim_msdp_peer_state state;
- json_object *json = NULL;
json_object *json_mg_row = NULL;
json_object *json_members = NULL;
json_object *json_row = NULL;
- if (!mg) {
- if (uj)
- print_empty_json_obj(vty);
- return;
- }
-
pim_inet4_dump("<source?>", mg->src_ip, src_str, sizeof(src_str));
- if (uj) {
- json = json_object_new_object();
+ if (json) {
/* currently there is only one mesh group but we should still
* make
* it a dict with mg-name as key */
@@ -10005,7 +10004,7 @@ static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
state = PIM_MSDP_DISABLED;
}
pim_msdp_state_dump(state, state_str, sizeof(state_str));
- if (uj) {
+ if (json) {
json_row = json_object_new_object();
json_object_string_add(json_row, "member", mbr_str);
json_object_string_add(json_row, "state", state_str);
@@ -10020,12 +10019,8 @@ static void ip_msdp_show_mesh_group(struct pim_instance *pim, struct vty *vty,
}
}
- if (uj) {
+ if (json)
json_object_object_add(json, mg->mesh_group_name, json_mg_row);
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
}
DEFUN (show_ip_msdp_mesh_group,
@@ -10040,12 +10035,34 @@ DEFUN (show_ip_msdp_mesh_group,
{
bool uj = use_json(argc, argv);
int idx = 2;
+ struct pim_msdp_mg *mg;
struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
+ struct pim_instance *pim = vrf->info;
+ struct json_object *json = NULL;
if (!vrf)
return CMD_WARNING;
- ip_msdp_show_mesh_group(vrf->info, vty, uj);
+ /* Quick case: list is empty. */
+ if (SLIST_EMPTY(&pim->msdp.mglist)) {
+ if (uj)
+ vty_out(vty, "{}\n");
+
+ return CMD_SUCCESS;
+ }
+
+ if (uj)
+ json = json_object_new_object();
+
+ SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
+ ip_msdp_show_mesh_group(vty, mg, json);
+
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
return CMD_SUCCESS;
}
@@ -10061,23 +10078,32 @@ DEFUN (show_ip_msdp_mesh_group_vrf_all,
JSON_STR)
{
bool uj = use_json(argc, argv);
+ struct json_object *json = NULL, *vrf_json = NULL;
+ struct pim_instance *pim;
+ struct pim_msdp_mg *mg;
struct vrf *vrf;
- bool first = true;
if (uj)
- vty_out(vty, "{ ");
+ json = json_object_new_object();
+
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
if (uj) {
- if (!first)
- vty_out(vty, ", ");
- vty_out(vty, " \"%s\": ", vrf->name);
- first = false;
+ vrf_json = json_object_new_object();
+ json_object_object_add(json, vrf->name, vrf_json);
} else
vty_out(vty, "VRF: %s\n", vrf->name);
- ip_msdp_show_mesh_group(vrf->info, vty, uj);
+
+ pim = vrf->info;
+ SLIST_FOREACH (mg, &pim->msdp.mglist, mg_entry)
+ ip_msdp_show_mesh_group(vty, mg, vrf_json);
+ }
+
+ if (uj) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
}
- if (uj)
- vty_out(vty, "}\n");
return CMD_SUCCESS;
}
@@ -10182,8 +10208,10 @@ static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
json_row = json_object_new_object();
json_object_string_add(json_row, "peer", peer_str);
json_object_string_add(json_row, "local", local_str);
- json_object_string_add(json_row, "meshGroupName",
- mp->mesh_group_name);
+ if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
+ json_object_string_add(json_row,
+ "meshGroupName",
+ mp->mesh_group_name);
json_object_string_add(json_row, "state", state_str);
json_object_string_add(json_row, "upTime", timebuf);
json_object_string_add(json_row, "keepAliveTimer",
@@ -10207,8 +10235,9 @@ static void ip_msdp_show_peers_detail(struct pim_instance *pim, struct vty *vty,
} else {
vty_out(vty, "Peer : %s\n", peer_str);
vty_out(vty, " Local : %s\n", local_str);
- vty_out(vty, " Mesh Group : %s\n",
- mp->mesh_group_name);
+ if (mp->flags & PIM_MSDP_PEERF_IN_GROUP)
+ vty_out(vty, " Mesh Group : %s\n",
+ mp->mesh_group_name);
vty_out(vty, " State : %s\n", state_str);
vty_out(vty, " Uptime : %s\n", timebuf);
@@ -11069,8 +11098,7 @@ DEFUN_HIDDEN (ip_pim_mlag,
void pim_cmd_init(void)
{
- install_node(&interface_node); /* INTERFACE_NODE */
- if_cmd_init();
+ if_cmd_init(pim_interface_config_write);
install_node(&debug_node);
@@ -11353,6 +11381,8 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE, &debug_bsm_cmd);
install_element(CONFIG_NODE, &no_debug_bsm_cmd);
+ install_element(CONFIG_NODE, &ip_msdp_timers_cmd);
+ install_element(VRF_NODE, &ip_msdp_timers_cmd);
install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd);
install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd);
install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd);