pimd: Northbound implementation for msdp mesh group, msdp peer commands

ip_msdp_peer
no_ip_msdp_peer
ip_msdp_mesh_group_member
no_ip_msdp_mesh_group_member
ip_msdp_mesh_group_source
no_ip_msdp_mesh_group_source
no_ip_msdp_mesh_group

Yang Model:
  augment /frr-routing:routing/frr-routing:control-plane-protocols/frr-routing:control-plane-protocol:
    +--rw pim
       +--rw address-family* [address-family]
          +--rw address-family          identityref
          +--rw msdp-mesh-group!
          |  +--rw mesh-group-name?   string
          |  +--rw member-ip*         ietf-inet-types:ip-address
          |  +--rw source-ip?         ietf-inet-types:ip-address
          +--rw msdp-peer* [peer-ip]
          |  +--rw peer-ip      ietf-inet-types:ip-address
          |  +--rw source-ip?   ietf-inet-types:ip-address

Signed-off-by: Sarita Patra <saritap@vmware.com>
This commit is contained in:
Sarita Patra 2020-10-23 07:29:44 -07:00
parent f206085e19
commit cf740d2e72
4 changed files with 675 additions and 234 deletions

View File

@ -790,8 +790,7 @@ const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
return NULL; return NULL;
} }
/* API to check if the given node is last node in the list */ bool yang_is_last_list_dnode(const struct lyd_node *dnode)
static bool yang_is_last_list_dnode(const struct lyd_node *dnode)
{ {
return (((dnode->next == NULL) return (((dnode->next == NULL)
|| (dnode->next || (dnode->next
@ -803,8 +802,7 @@ static bool yang_is_last_list_dnode(const struct lyd_node *dnode)
!= 0))); != 0)));
} }
/* API to check if the given node is last node in the data tree level */ bool yang_is_last_level_dnode(const struct lyd_node *dnode)
static bool yang_is_last_level_dnode(const struct lyd_node *dnode)
{ {
const struct lyd_node *parent; const struct lyd_node *parent;
const struct lys_node_list *snode; const struct lys_node_list *snode;

View File

@ -605,6 +605,11 @@ extern uint32_t yang_get_list_elements_count(const struct lyd_node *node);
/* To get the immediate child of a dnode */ /* To get the immediate child of a dnode */
const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode); const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode);
/* API to check if the given node is last node in the list */
bool yang_is_last_list_dnode(const struct lyd_node *dnode);
/* API to check if the given node is last node in the data tree level */
bool yang_is_last_level_dnode(const struct lyd_node *dnode);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -9553,53 +9553,6 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
"Desired min transmit interval\n") "Desired min transmit interval\n")
#endif /* !HAVE_BFDD */ #endif /* !HAVE_BFDD */
static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
const char *peer, const char *local)
{
enum pim_msdp_err result;
struct in_addr peer_addr;
struct in_addr local_addr;
int ret = CMD_SUCCESS;
result = inet_pton(AF_INET, peer, &peer_addr);
if (result <= 0) {
vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer,
errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
}
result = inet_pton(AF_INET, local, &local_addr);
if (result <= 0) {
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", local,
errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
}
result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
NULL /* mp_p */);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_OOM:
ret = CMD_WARNING_CONFIG_FAILED;
vty_out(vty, "%% Out of memory\n");
break;
case PIM_MSDP_ERR_PEER_EXISTS:
ret = CMD_WARNING;
vty_out(vty, "%% Peer exists\n");
break;
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
ret = CMD_WARNING_CONFIG_FAILED;
vty_out(vty, "%% Only one mesh-group allowed currently\n");
break;
default:
ret = CMD_WARNING_CONFIG_FAILED;
vty_out(vty, "%% peer add failed\n");
}
return ret;
}
DEFUN (ip_msdp_peer, DEFUN (ip_msdp_peer,
ip_msdp_peer_cmd, ip_msdp_peer_cmd,
"ip msdp peer A.B.C.D source A.B.C.D", "ip msdp peer A.B.C.D source A.B.C.D",
@ -9610,35 +9563,37 @@ DEFUN (ip_msdp_peer,
"Source address for TCP connection\n" "Source address for TCP connection\n"
"local ip address\n") "local ip address\n")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
return ip_msdp_peer_cmd_worker(pim, vty, argv[3]->arg, argv[5]->arg); const char *vrfname;
} char temp_xpath[XPATH_MAXLEN];
char msdp_peer_source_xpath[XPATH_MAXLEN];
static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty, if (vty->xpath_index) {
const char *peer) vrf_dnode =
{ yang_dnode_get(vty->candidate_config->dnode,
enum pim_msdp_err result; VTY_CURR_XPATH);
struct in_addr peer_addr; if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
result = inet_pton(AF_INET, peer, &peer_addr); snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath),
if (result <= 0) { FRR_PIM_AF_XPATH,
vty_out(vty, "%% Bad peer address %s: errno=%d: %s\n", peer, "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
errno, safe_strerror(errno)); snprintf(temp_xpath, sizeof(temp_xpath),
return CMD_WARNING_CONFIG_FAILED; "/msdp-peer[peer-ip='%s']/source-ip",
} argv[3]->arg);
strlcat(msdp_peer_source_xpath, temp_xpath,
sizeof(msdp_peer_source_xpath));
result = pim_msdp_peer_del(pim, peer_addr); nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY,
switch (result) { argv[5]->arg);
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_PEER:
vty_out(vty, "%% Peer does not exist\n");
break;
default:
vty_out(vty, "%% peer del failed\n");
}
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (no_ip_msdp_peer, DEFUN (no_ip_msdp_peer,
@ -9650,47 +9605,36 @@ DEFUN (no_ip_msdp_peer,
"Delete MSDP peer\n" "Delete MSDP peer\n"
"peer ip address\n") "peer ip address\n")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
return ip_no_msdp_peer_cmd_worker(pim, vty, argv[4]->arg); const char *vrfname;
} char msdp_peer_xpath[XPATH_MAXLEN];
char temp_xpath[XPATH_MAXLEN];
static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim, if (vty->xpath_index) {
struct vty *vty, const char *mg, vrf_dnode =
const char *mbr) yang_dnode_get(vty->candidate_config->dnode,
{ VTY_CURR_XPATH);
enum pim_msdp_err result; if (!vrf_dnode) {
struct in_addr mbr_ip; vty_out(vty,
int ret = CMD_SUCCESS; "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
result = inet_pton(AF_INET, mbr, &mbr_ip); snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath),
if (result <= 0) { FRR_PIM_AF_XPATH,
vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr, "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
errno, safe_strerror(errno)); snprintf(temp_xpath, sizeof(temp_xpath),
return CMD_WARNING_CONFIG_FAILED; "/msdp-peer[peer-ip='%s']",
} argv[4]->arg);
result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip); strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath));
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_OOM:
ret = CMD_WARNING_CONFIG_FAILED;
vty_out(vty, "%% Out of memory\n");
break;
case PIM_MSDP_ERR_MG_MBR_EXISTS:
ret = CMD_WARNING;
vty_out(vty, "%% mesh-group member exists\n");
break;
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
ret = CMD_WARNING_CONFIG_FAILED;
vty_out(vty, "%% Only one mesh-group allowed currently\n");
break;
default:
ret = CMD_WARNING_CONFIG_FAILED;
vty_out(vty, "%% member add failed\n");
}
return ret; nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (ip_msdp_mesh_group_member, DEFUN (ip_msdp_mesh_group_member,
@ -9703,42 +9647,44 @@ DEFUN (ip_msdp_mesh_group_member,
"mesh group member\n" "mesh group member\n"
"peer ip address\n") "peer ip address\n")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
return ip_msdp_mesh_group_member_cmd_worker(pim, vty, argv[3]->arg, const char *vrfname;
argv[5]->arg); char msdp_mesh_group_name_xpath[XPATH_MAXLEN];
char msdp_mesh_group_member_xpath[XPATH_MAXLEN];
if (vty->xpath_index) {
vrf_dnode =
yang_dnode_get(vty->candidate_config->dnode,
VTY_CURR_XPATH);
if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
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));
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);
return nb_cli_apply_changes(vty, NULL);
} }
static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
struct vty *vty,
const char *mg,
const char *mbr)
{
enum pim_msdp_err result;
struct in_addr mbr_ip;
result = inet_pton(AF_INET, mbr, &mbr_ip);
if (result <= 0) {
vty_out(vty, "%% Bad member address %s: errno=%d: %s\n", mbr,
errno, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
}
result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_MG:
vty_out(vty, "%% mesh-group does not exist\n");
break;
case PIM_MSDP_ERR_NO_MG_MBR:
vty_out(vty, "%% mesh-group member does not exist\n");
break;
default:
vty_out(vty, "%% mesh-group member del failed\n");
}
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
}
DEFUN (no_ip_msdp_mesh_group_member, DEFUN (no_ip_msdp_mesh_group_member,
no_ip_msdp_mesh_group_member_cmd, no_ip_msdp_mesh_group_member_cmd,
"no ip msdp mesh-group WORD member A.B.C.D", "no ip msdp mesh-group WORD member A.B.C.D",
@ -9750,42 +9696,89 @@ DEFUN (no_ip_msdp_mesh_group_member,
"mesh group member\n" "mesh group member\n"
"peer ip address\n") "peer ip address\n")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
return ip_no_msdp_mesh_group_member_cmd_worker(pim, vty, argv[4]->arg, const char *vrfname;
argv[6]->arg); char temp_xpath[XPATH_MAXLEN];
} char mesh_group_xpath[XPATH_MAXLEN];
char group_member_xpath[XPATH_MAXLEN];
char source_xpath[XPATH_MAXLEN];
char mesh_group_name_xpath[XPATH_MAXLEN];
const char *mesh_group_name;
const struct lyd_node *member_dnode;
static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim, if (vty->xpath_index) {
struct vty *vty, const char *mg, vrf_dnode =
const char *src) yang_dnode_get(vty->candidate_config->dnode,
{ VTY_CURR_XPATH);
enum pim_msdp_err result; if (!vrf_dnode) {
struct in_addr src_ip; vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
result = inet_pton(AF_INET, src, &src_ip); snprintf(mesh_group_xpath, sizeof(mesh_group_xpath),
if (result <= 0) { FRR_PIM_AF_XPATH,
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n", src, "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
errno, safe_strerror(errno)); strlcat(mesh_group_xpath, "/msdp-mesh-group", sizeof(mesh_group_xpath));
return CMD_WARNING_CONFIG_FAILED;
snprintf(group_member_xpath, sizeof(group_member_xpath),
FRR_PIM_AF_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
snprintf(temp_xpath, sizeof(temp_xpath),
"/msdp-mesh-group/member-ip[.='%s']", argv[6]->arg);
strlcat(group_member_xpath, temp_xpath, sizeof(group_member_xpath));
snprintf(source_xpath, sizeof(source_xpath),
FRR_PIM_AF_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
snprintf(temp_xpath, sizeof(temp_xpath),
"/msdp-mesh-group/source-ip");
strlcat(source_xpath, temp_xpath, sizeof(source_xpath));
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;
}
} }
result = pim_msdp_mg_src_add(pim, mg, src_ip); if (yang_dnode_exists(vty->candidate_config->dnode,
switch (result) { group_member_xpath)) {
case PIM_MSDP_ERR_NONE: if (!yang_dnode_exists(vty->candidate_config->dnode,
break; source_xpath)) {
case PIM_MSDP_ERR_OOM: member_dnode = yang_dnode_get(
vty_out(vty, "%% Out of memory\n"); vty->candidate_config->dnode,
break; group_member_xpath);
case PIM_MSDP_ERR_MAX_MESH_GROUPS: if (yang_is_last_list_dnode(member_dnode)) {
vty_out(vty, "%% Only one mesh-group allowed currently\n"); nb_cli_enqueue_change(vty, mesh_group_xpath,
break; NB_OP_DESTROY, NULL);
default: return nb_cli_apply_changes(vty, NULL);
vty_out(vty, "%% source add failed\n"); }
nb_cli_enqueue_change(vty, group_member_xpath,
NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
nb_cli_enqueue_change(vty, group_member_xpath,
NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; vty_out(vty, "%% mesh-group member does not exist\n");
}
return CMD_SUCCESS;
}
DEFUN (ip_msdp_mesh_group_source, DEFUN (ip_msdp_mesh_group_source,
ip_msdp_mesh_group_source_cmd, ip_msdp_mesh_group_source_cmd,
@ -9797,48 +9790,42 @@ DEFUN (ip_msdp_mesh_group_source,
"mesh group local address\n" "mesh group local address\n"
"source ip address for the TCP connection\n") "source ip address for the TCP connection\n")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
return ip_msdp_mesh_group_source_cmd_worker(pim, vty, argv[3]->arg, const char *vrfname;
argv[5]->arg); char msdp_mesh_source_ip_xpath[XPATH_MAXLEN];
} char msdp_mesh_group_name_xpath[XPATH_MAXLEN];
static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim, if (vty->xpath_index) {
struct vty *vty, vrf_dnode =
const char *mg) yang_dnode_get(vty->candidate_config->dnode,
{ VTY_CURR_XPATH);
enum pim_msdp_err result; if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
result = pim_msdp_mg_src_del(pim, mg); snprintf(msdp_mesh_group_name_xpath, sizeof(msdp_mesh_group_name_xpath),
switch (result) { FRR_PIM_AF_XPATH,
case PIM_MSDP_ERR_NONE: "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
break; strlcat(msdp_mesh_group_name_xpath, "/msdp-mesh-group/mesh-group-name",
case PIM_MSDP_ERR_NO_MG: sizeof(msdp_mesh_group_name_xpath));
vty_out(vty, "%% mesh-group does not exist\n");
break;
default:
vty_out(vty, "%% mesh-group source del failed\n");
}
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS; 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));
static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim, nb_cli_enqueue_change(vty, msdp_mesh_group_name_xpath, NB_OP_MODIFY,
struct vty *vty, const char *mg) argv[3]->arg);
{ nb_cli_enqueue_change(vty, msdp_mesh_source_ip_xpath, NB_OP_MODIFY,
enum pim_msdp_err result; argv[5]->arg);
result = pim_msdp_mg_del(pim, mg); return nb_cli_apply_changes(vty, NULL);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_MG:
vty_out(vty, "%% mesh-group does not exist\n");
break;
default:
vty_out(vty, "%% mesh-group source del failed\n");
}
return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
} }
DEFUN (no_ip_msdp_mesh_group_source, DEFUN (no_ip_msdp_mesh_group_source,
@ -9852,9 +9839,69 @@ DEFUN (no_ip_msdp_mesh_group_source,
"mesh group source\n" "mesh group source\n"
"mesh group local address\n") "mesh group local address\n")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
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;
return ip_no_msdp_mesh_group_source_cmd_worker(pim, vty, argv[4]->arg); if (vty->xpath_index) {
vrf_dnode =
yang_dnode_get(vty->candidate_config->dnode,
VTY_CURR_XPATH);
if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
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));
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));
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, DEFUN (no_ip_msdp_mesh_group,
@ -9866,12 +9913,50 @@ DEFUN (no_ip_msdp_mesh_group,
"Delete MSDP mesh-group\n" "Delete MSDP mesh-group\n"
"mesh group name") "mesh group name")
{ {
PIM_DECLVAR_CONTEXT(vrf, pim); const struct lyd_node *vrf_dnode;
const char *vrfname;
const char *mesh_group_name;
char xpath[XPATH_MAXLEN];
char msdp_mesh_xpath[XPATH_MAXLEN];
if (argc == 5) if (vty->xpath_index) {
return ip_no_msdp_mesh_group_cmd_worker(pim, vty, argv[4]->arg); vrf_dnode =
else yang_dnode_get(vty->candidate_config->dnode,
return ip_no_msdp_mesh_group_cmd_worker(pim, vty, NULL); VTY_CURR_XPATH);
if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;
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));
nb_cli_enqueue_change(vty, msdp_mesh_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
static void print_empty_json_obj(struct vty *vty) static void print_empty_json_obj(struct vty *vty)

View File

@ -238,6 +238,207 @@ static int pim_ssm_cmd_worker(struct pim_instance *pim, const char *plist,
return ret; return ret;
} }
static int ip_no_msdp_mesh_group_cmd_worker(struct pim_instance *pim,
const char *mg,
char *errmsg, size_t errmsg_len)
{
enum pim_msdp_err result;
result = pim_msdp_mg_del(pim, mg);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_MG:
snprintf(errmsg, errmsg_len,
"%% mesh-group does not exist");
break;
default:
snprintf(errmsg, errmsg_len,
"mesh-group source del failed");
}
return result ? NB_ERR : NB_OK;
}
static int ip_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
const char *mg,
struct in_addr mbr_ip,
char *errmsg, size_t errmsg_len)
{
enum pim_msdp_err result;
int ret = NB_OK;
result = pim_msdp_mg_mbr_add(pim, mg, mbr_ip);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_OOM:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% Out of memory");
break;
case PIM_MSDP_ERR_MG_MBR_EXISTS:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% mesh-group member exists");
break;
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% Only one mesh-group allowed currently");
break;
default:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% member add failed");
}
return ret;
}
static int ip_no_msdp_mesh_group_member_cmd_worker(struct pim_instance *pim,
const char *mg,
struct in_addr mbr_ip,
char *errmsg,
size_t errmsg_len)
{
enum pim_msdp_err result;
result = pim_msdp_mg_mbr_del(pim, mg, mbr_ip);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_MG:
snprintf(errmsg, errmsg_len,
"%% mesh-group does not exist");
break;
case PIM_MSDP_ERR_NO_MG_MBR:
snprintf(errmsg, errmsg_len,
"%% mesh-group member does not exist");
break;
default:
snprintf(errmsg, errmsg_len,
"%% mesh-group member del failed");
}
return result ? NB_ERR : NB_OK;
}
static int ip_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
const char *mg,
struct in_addr src_ip,
char *errmsg, size_t errmsg_len)
{
enum pim_msdp_err result;
result = pim_msdp_mg_src_add(pim, mg, src_ip);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_OOM:
snprintf(errmsg, errmsg_len,
"%% Out of memory");
break;
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
snprintf(errmsg, errmsg_len,
"%% Only one mesh-group allowed currently");
break;
default:
snprintf(errmsg, errmsg_len,
"%% source add failed");
}
return result ? NB_ERR : NB_OK;
}
static int ip_no_msdp_mesh_group_source_cmd_worker(struct pim_instance *pim,
const char *mg,
char *errmsg,
size_t errmsg_len)
{
enum pim_msdp_err result;
result = pim_msdp_mg_src_del(pim, mg);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_MG:
snprintf(errmsg, errmsg_len,
"%% mesh-group does not exist");
break;
default:
snprintf(errmsg, errmsg_len,
"%% mesh-group source del failed");
}
return result ? NB_ERR : NB_OK;
}
static int ip_msdp_peer_cmd_worker(struct pim_instance *pim,
struct in_addr peer_addr,
struct in_addr local_addr,
char *errmsg, size_t errmsg_len)
{
enum pim_msdp_err result;
int ret = NB_OK;
result = pim_msdp_peer_add(pim, peer_addr, local_addr, "default",
NULL /* mp_p */);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_OOM:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% Out of memory");
break;
case PIM_MSDP_ERR_PEER_EXISTS:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% Peer exists");
break;
case PIM_MSDP_ERR_MAX_MESH_GROUPS:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% Only one mesh-group allowed currently");
break;
default:
ret = NB_ERR;
snprintf(errmsg, errmsg_len,
"%% peer add failed");
}
return ret;
}
static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim,
struct in_addr peer_addr,
char *errmsg, size_t errmsg_len)
{
enum pim_msdp_err result;
result = pim_msdp_peer_del(pim, peer_addr);
switch (result) {
case PIM_MSDP_ERR_NONE:
break;
case PIM_MSDP_ERR_NO_PEER:
snprintf(errmsg, errmsg_len,
"%% Peer does not exist");
break;
default:
snprintf(errmsg, errmsg_len,
"%% peer del failed");
}
return result ? NB_ERR : NB_OK;
}
static bool is_pim_interface(const struct lyd_node *dnode) static bool is_pim_interface(const struct lyd_node *dnode)
{ {
char if_xpath[XPATH_MAXLEN]; char if_xpath[XPATH_MAXLEN];
@ -865,7 +1066,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */
break; break;
} }
@ -874,12 +1074,28 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_destroy(struct nb_cb_destroy_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_destroy(struct nb_cb_destroy_args *args)
{ {
struct vrf *vrf;
struct pim_instance *pim;
const char *mesh_group_name;
int result;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
mesh_group_name = yang_dnode_get_string(args->dnode, ".");
result = ip_no_msdp_mesh_group_cmd_worker(pim, mesh_group_name,
args->errmsg,
args->errmsg_len);
if (result != PIM_MSDP_ERR_NONE)
return NB_ERR_INCONSISTENCY;
break; break;
} }
@ -891,12 +1107,30 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
*/ */
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_mesh_group_name_modify(struct nb_cb_modify_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_mesh_group_name_modify(struct nb_cb_modify_args *args)
{ {
const char *mesh_group_name;
const char *mesh_group_name_old;
char xpath[XPATH_MAXLEN];
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
mesh_group_name = yang_dnode_get_string(args->dnode, ".");
yang_dnode_get_path(args->dnode, xpath, sizeof(xpath));
if (yang_dnode_exists(running_config->dnode, xpath) == false)
break;
mesh_group_name_old = yang_dnode_get_string(running_config->dnode,
xpath);
if (strcmp(mesh_group_name, mesh_group_name_old)) {
/* currently only one mesh-group can exist at a time */
snprintf(args->errmsg, args->errmsg_len,
"Only one mesh-group allowed currently");
return NB_ERR_VALIDATION;
}
break;
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */
break; break;
} }
@ -910,7 +1144,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */
break; break;
} }
@ -922,12 +1155,31 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
*/ */
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_member_ip_create(struct nb_cb_create_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_member_ip_create(struct nb_cb_create_args *args)
{ {
struct vrf *vrf;
struct pim_instance *pim;
const char *mesh_group_name;
struct ipaddr mbr_ip;
enum pim_msdp_err result;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
mesh_group_name = yang_dnode_get_string(args->dnode,
"../mesh-group-name");
yang_dnode_get_ip(&mbr_ip, args->dnode, NULL);
result = ip_msdp_mesh_group_member_cmd_worker(
pim, mesh_group_name, mbr_ip.ip._v4_addr,
args->errmsg, args->errmsg_len);
if (result != PIM_MSDP_ERR_NONE)
return NB_ERR_INCONSISTENCY;
break; break;
} }
@ -936,12 +1188,31 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_member_ip_destroy(struct nb_cb_destroy_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_member_ip_destroy(struct nb_cb_destroy_args *args)
{ {
struct vrf *vrf;
struct pim_instance *pim;
const char *mesh_group_name;
struct ipaddr mbr_ip;
enum pim_msdp_err result;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
mesh_group_name = yang_dnode_get_string(args->dnode,
"../mesh-group-name");
yang_dnode_get_ip(&mbr_ip, args->dnode, NULL);
result = ip_no_msdp_mesh_group_member_cmd_worker(
pim, mesh_group_name, mbr_ip.ip._v4_addr,
args->errmsg, args->errmsg_len);
if (result != PIM_MSDP_ERR_NONE)
return NB_ERR_INCONSISTENCY;
break; break;
} }
@ -953,29 +1224,62 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
*/ */
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_source_ip_modify(struct nb_cb_modify_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_source_ip_modify(struct nb_cb_modify_args *args)
{ {
struct vrf *vrf;
struct pim_instance *pim;
const char *mesh_group_name;
struct ipaddr src_ip;
enum pim_msdp_err result;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
mesh_group_name = yang_dnode_get_string(args->dnode,
"../mesh-group-name");
yang_dnode_get_ip(&src_ip, args->dnode, NULL);
result = ip_msdp_mesh_group_source_cmd_worker(
pim, mesh_group_name, src_ip.ip._v4_addr,
args->errmsg, args->errmsg_len);
if (result != PIM_MSDP_ERR_NONE)
return NB_ERR_INCONSISTENCY;
break; break;
} }
return NB_OK; return NB_OK;
} }
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_source_ip_destroy(struct nb_cb_destroy_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_mesh_group_source_ip_destroy(struct nb_cb_destroy_args *args)
{ {
struct vrf *vrf;
struct pim_instance *pim;
const char *mesh_group_name;
enum pim_msdp_err result;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
mesh_group_name = yang_dnode_get_string(args->dnode,
"../mesh-group-name");
result = ip_no_msdp_mesh_group_source_cmd_worker(
pim, mesh_group_name, args->errmsg, args->errmsg_len);
if (result != PIM_MSDP_ERR_NONE)
return NB_ERR_INCONSISTENCY;
break; break;
} }
return NB_OK; return NB_OK;
} }
@ -989,7 +1293,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */
break; break;
} }
@ -998,12 +1301,27 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(struct nb_cb_destroy_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_destroy(struct nb_cb_destroy_args *args)
{ {
int result;
struct pim_instance *pim;
struct ipaddr peer_ip;
struct vrf *vrf;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
yang_dnode_get_ip(&peer_ip, args->dnode, "./peer-ip");
result = ip_no_msdp_peer_cmd_worker(pim, peer_ip.ip._v4_addr,
args->errmsg,
args->errmsg_len);
if (result)
return NB_ERR_INCONSISTENCY;
break; break;
} }
@ -1015,12 +1333,48 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
*/ */
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(struct nb_cb_modify_args *args) int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify(struct nb_cb_modify_args *args)
{ {
int result;
struct vrf *vrf;
struct pim_instance *pim;
struct ipaddr peer_ip;
struct ipaddr source_ip;
const struct lyd_node *mesh_group_name_dnode;
const char *mesh_group_name;
switch (args->event) { switch (args->event) {
case NB_EV_VALIDATE: case NB_EV_VALIDATE:
mesh_group_name_dnode =
yang_dnode_get(args->dnode,
"../../msdp-mesh-group/mesh-group-name");
if (mesh_group_name_dnode) {
mesh_group_name =
yang_dnode_get_string(mesh_group_name_dnode,
".");
if (strcmp(mesh_group_name, "default")) {
/* currently only one mesh-group can exist at a time */
snprintf(args->errmsg, args->errmsg_len,
"%% Only one mesh-group allowed currently");
return NB_ERR_VALIDATION;
}
}
break;
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
break;
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */ vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
yang_dnode_get_ip(&peer_ip, args->dnode, "../peer-ip");
yang_dnode_get_ip(&source_ip, args->dnode, NULL);
result = ip_msdp_peer_cmd_worker(pim, peer_ip.ip._v4_addr,
source_ip.ip._v4_addr,
args->errmsg,
args->errmsg_len);
if (result)
return NB_ERR_INCONSISTENCY;
break; break;
} }
@ -1034,7 +1388,6 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
case NB_EV_PREPARE: case NB_EV_PREPARE:
case NB_EV_ABORT: case NB_EV_ABORT:
case NB_EV_APPLY: case NB_EV_APPLY:
/* TODO: implement me. */
break; break;
} }