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",
"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,
"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,
"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 (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);
- if (ssm->plist_name && !strcmp(ssm->plist_name, argv[5]->arg))
- return pim_ssm_cmd_worker(pim, vty, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+ }
vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg);
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,
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,
#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)
{
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];
*/
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;
}
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;
}
*/
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;
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;
}