mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 20:07:46 +00:00
pimd: Northbound implementation for ssm prefix-list, ssmpingd command
ip_pim_ssm_prefix_list no_ip_pim_ssm_prefix_list no_ip_pim_ssm_prefix_list_name no_ip_ssmpingd ip_ssmpingd 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 ssm-prefix-list? plist-ref +--rw ssm-pingd-source-ip* ietf-inet-types:ip-address Signed-off-by: Sarita Patra <saritap@vmware.com>
This commit is contained in:
parent
db9cca95be
commit
f206085e19
205
pimd/pim_cmd.c
205
pimd/pim_cmd.c
@ -7409,30 +7409,6 @@ DEFUN (no_ip_pim_rp_prefix_list,
|
||||
return pim_no_rp_cmd_worker(pim, vty, argv[4]->arg, NULL, argv[6]->arg);
|
||||
}
|
||||
|
||||
static int pim_ssm_cmd_worker(struct pim_instance *pim, struct vty *vty,
|
||||
const char *plist)
|
||||
{
|
||||
int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
|
||||
int ret = CMD_WARNING_CONFIG_FAILED;
|
||||
|
||||
if (result == PIM_SSM_ERR_NONE)
|
||||
return CMD_SUCCESS;
|
||||
|
||||
switch (result) {
|
||||
case PIM_SSM_ERR_NO_VRF:
|
||||
vty_out(vty, "%% VRF doesn't exist\n");
|
||||
break;
|
||||
case PIM_SSM_ERR_DUP:
|
||||
vty_out(vty, "%% duplicate config\n");
|
||||
ret = CMD_WARNING;
|
||||
break;
|
||||
default:
|
||||
vty_out(vty, "%% ssm range config failed\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFUN (ip_pim_ssm_prefix_list,
|
||||
ip_pim_ssm_prefix_list_cmd,
|
||||
"ip pim ssm prefix-list WORD",
|
||||
@ -7442,8 +7418,31 @@ DEFUN (ip_pim_ssm_prefix_list,
|
||||
"group range prefix-list filter\n"
|
||||
"Name of a prefix-list\n")
|
||||
{
|
||||
PIM_DECLVAR_CONTEXT(vrf, pim);
|
||||
return pim_ssm_cmd_worker(pim, vty, argv[4]->arg);
|
||||
const struct lyd_node *vrf_dnode;
|
||||
const char *vrfname;
|
||||
char ssm_plist_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(ssm_plist_xpath, sizeof(ssm_plist_xpath),
|
||||
FRR_PIM_AF_XPATH,
|
||||
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
|
||||
strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
|
||||
|
||||
nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_pim_ssm_prefix_list,
|
||||
@ -7455,8 +7454,31 @@ DEFUN (no_ip_pim_ssm_prefix_list,
|
||||
"Source Specific Multicast\n"
|
||||
"group range prefix-list filter\n")
|
||||
{
|
||||
PIM_DECLVAR_CONTEXT(vrf, pim);
|
||||
return pim_ssm_cmd_worker(pim, vty, NULL);
|
||||
const struct lyd_node *vrf_dnode;
|
||||
const char *vrfname;
|
||||
char ssm_plist_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(ssm_plist_xpath, sizeof(ssm_plist_xpath),
|
||||
FRR_PIM_AF_XPATH,
|
||||
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
|
||||
strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
|
||||
|
||||
nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_pim_ssm_prefix_list_name,
|
||||
@ -7469,11 +7491,50 @@ DEFUN (no_ip_pim_ssm_prefix_list_name,
|
||||
"group range prefix-list filter\n"
|
||||
"Name of a prefix-list\n")
|
||||
{
|
||||
PIM_DECLVAR_CONTEXT(vrf, pim);
|
||||
struct pim_ssm *ssm = pim->ssm_info;
|
||||
const struct lyd_node *vrf_dnode;
|
||||
const char *vrfname;
|
||||
const struct lyd_node *ssm_plist_dnode;
|
||||
char ssm_plist_xpath[XPATH_MAXLEN];
|
||||
const char *ssm_plist_name;
|
||||
|
||||
if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
|
||||
return pim_ssm_cmd_worker(pim, vty, NULL);
|
||||
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(ssm_plist_xpath, sizeof(ssm_plist_xpath),
|
||||
FRR_PIM_AF_XPATH,
|
||||
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
|
||||
strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath));
|
||||
ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode,
|
||||
ssm_plist_xpath);
|
||||
|
||||
if (!ssm_plist_dnode) {
|
||||
vty_out(vty,
|
||||
"%% pim ssm prefix-list %s doesn't exist\n",
|
||||
argv[5]->arg);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, ".");
|
||||
|
||||
if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) {
|
||||
nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY,
|
||||
NULL);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
|
||||
|
||||
@ -7602,27 +7663,35 @@ DEFUN (ip_ssmpingd,
|
||||
CONF_SSMPINGD_STR
|
||||
"Source address\n")
|
||||
{
|
||||
PIM_DECLVAR_CONTEXT(vrf, pim);
|
||||
int idx_ipv4 = 2;
|
||||
int result;
|
||||
struct in_addr source_addr;
|
||||
const char *source_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0";
|
||||
const struct lyd_node *vrf_dnode;
|
||||
const char *vrfname;
|
||||
char ssmpingd_ip_xpath[XPATH_MAXLEN];
|
||||
|
||||
result = inet_pton(AF_INET, source_str, &source_addr);
|
||||
if (result <= 0) {
|
||||
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
|
||||
source_str, errno, safe_strerror(errno));
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
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;
|
||||
|
||||
result = pim_ssmpingd_start(pim, source_addr);
|
||||
if (result) {
|
||||
vty_out(vty, "%% Failure starting ssmpingd for source %s: %d\n",
|
||||
source_str, result);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
|
||||
FRR_PIM_AF_XPATH,
|
||||
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
|
||||
strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
|
||||
sizeof(ssmpingd_ip_xpath));
|
||||
|
||||
return CMD_SUCCESS;
|
||||
nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_CREATE,
|
||||
source_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (no_ip_ssmpingd,
|
||||
@ -7633,27 +7702,35 @@ DEFUN (no_ip_ssmpingd,
|
||||
CONF_SSMPINGD_STR
|
||||
"Source address\n")
|
||||
{
|
||||
PIM_DECLVAR_CONTEXT(vrf, pim);
|
||||
const struct lyd_node *vrf_dnode;
|
||||
const char *vrfname;
|
||||
int idx_ipv4 = 3;
|
||||
int result;
|
||||
struct in_addr source_addr;
|
||||
const char *source_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0";
|
||||
char ssmpingd_ip_xpath[XPATH_MAXLEN];
|
||||
|
||||
result = inet_pton(AF_INET, source_str, &source_addr);
|
||||
if (result <= 0) {
|
||||
vty_out(vty, "%% Bad source address %s: errno=%d: %s\n",
|
||||
source_str, errno, safe_strerror(errno));
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
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;
|
||||
|
||||
result = pim_ssmpingd_stop(pim, source_addr);
|
||||
if (result) {
|
||||
vty_out(vty, "%% Failure stopping ssmpingd for source %s: %d\n",
|
||||
source_str, result);
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
|
||||
FRR_PIM_AF_XPATH,
|
||||
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
|
||||
strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
|
||||
sizeof(ssmpingd_ip_xpath));
|
||||
|
||||
return CMD_SUCCESS;
|
||||
nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, NB_OP_DESTROY,
|
||||
source_str);
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
DEFUN (ip_pim_ecmp,
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "pim_mlag.h"
|
||||
#include "pim_bfd.h"
|
||||
#include "pim_static.h"
|
||||
#include "pim_ssm.h"
|
||||
#include "pim_ssmpingd.h"
|
||||
|
||||
static void pim_if_membership_clear(struct interface *ifp)
|
||||
{
|
||||
@ -210,6 +212,32 @@ static int pim_cmd_spt_switchover(struct pim_instance *pim,
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
static int pim_ssm_cmd_worker(struct pim_instance *pim, const char *plist,
|
||||
char *errmsg, size_t errmsg_len)
|
||||
{
|
||||
int result = pim_ssm_range_set(pim, pim->vrf_id, plist);
|
||||
int ret = NB_ERR;
|
||||
|
||||
if (result == PIM_SSM_ERR_NONE)
|
||||
return NB_OK;
|
||||
|
||||
switch (result) {
|
||||
case PIM_SSM_ERR_NO_VRF:
|
||||
snprintf(errmsg, errmsg_len,
|
||||
"VRF doesn't exist");
|
||||
break;
|
||||
case PIM_SSM_ERR_DUP:
|
||||
snprintf(errmsg, errmsg_len,
|
||||
"duplicate config");
|
||||
break;
|
||||
default:
|
||||
snprintf(errmsg, errmsg_len,
|
||||
"ssm range config failed");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_pim_interface(const struct lyd_node *dnode)
|
||||
{
|
||||
char if_xpath[XPATH_MAXLEN];
|
||||
@ -706,12 +734,26 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_sp
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_modify(struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
const char *plist_name;
|
||||
int result;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
/* TODO: implement me. */
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
plist_name = yang_dnode_get_string(args->dnode, NULL);
|
||||
result = pim_ssm_cmd_worker(pim, plist_name, args->errmsg,
|
||||
args->errmsg_len);
|
||||
|
||||
if (result)
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -720,12 +762,24 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
|
||||
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_prefix_list_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
int result;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
/* TODO: implement me. */
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
result = pim_ssm_cmd_worker(pim, NULL, args->errmsg,
|
||||
args->errmsg_len);
|
||||
|
||||
if (result)
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -737,13 +791,31 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
|
||||
*/
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_create(struct nb_cb_create_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
int result;
|
||||
struct ipaddr source_addr;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
case NB_EV_APPLY:
|
||||
/* TODO: implement me. */
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
yang_dnode_get_ip(&source_addr, args->dnode, NULL);
|
||||
result = pim_ssmpingd_start(pim, source_addr.ip._v4_addr);
|
||||
if (result) {
|
||||
char source_str[INET_ADDRSTRLEN];
|
||||
|
||||
ipaddr2str(&source_addr, source_str,
|
||||
sizeof(source_str));
|
||||
snprintf(args->errmsg, args->errmsg_len,
|
||||
"%% Failure starting ssmpingd for source %s: %d",
|
||||
source_str, result);
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
}
|
||||
}
|
||||
|
||||
return NB_OK;
|
||||
@ -751,12 +823,32 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
|
||||
|
||||
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ssm_pingd_source_ip_destroy(struct nb_cb_destroy_args *args)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct pim_instance *pim;
|
||||
int result;
|
||||
struct ipaddr source_addr;
|
||||
|
||||
switch (args->event) {
|
||||
case NB_EV_VALIDATE:
|
||||
case NB_EV_PREPARE:
|
||||
case NB_EV_ABORT:
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
/* TODO: implement me. */
|
||||
vrf = nb_running_get_entry(args->dnode, NULL, true);
|
||||
pim = vrf->info;
|
||||
yang_dnode_get_ip(&source_addr, args->dnode, NULL);
|
||||
result = pim_ssmpingd_stop(pim, source_addr.ip._v4_addr);
|
||||
if (result) {
|
||||
char source_str[INET_ADDRSTRLEN];
|
||||
|
||||
ipaddr2str(&source_addr, source_str,
|
||||
sizeof(source_str));
|
||||
snprintf(args->errmsg, args->errmsg_len,
|
||||
"%% Failure stopping ssmpingd for source %s: %d",
|
||||
source_str, result);
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user