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.c449
1 files changed, 209 insertions, 240 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index f6072b1771..b3d4444652 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -3853,6 +3853,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]",
@@ -9685,305 +9733,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");
+ /* 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(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);
-
- 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));
-
- 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));
+ /* 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_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));
+ /* 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(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));
+ /* Create mesh group member. */
+ strlcat(xpath_value, "/source", sizeof(xpath_value));
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, 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));
+ /*
+ * 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);
- 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 (!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 +9947,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 +9962,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 +9978,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 +10021,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;
}