]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Northbound implementation for ssm prefix-list, ssmpingd command
authorSarita Patra <saritap@vmware.com>
Fri, 23 Oct 2020 13:58:51 +0000 (06:58 -0700)
committerSarita Patra <saritap@vmware.com>
Fri, 6 Nov 2020 11:42:00 +0000 (03:42 -0800)
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>
pimd/pim_cmd.c
pimd/pim_nb_config.c

index 609521823cb49171cad8cbb1c159916fa6d15cd2..aeaeefa75cbeddb0e2e93d8e9d2fa079fa21cc25 100644 (file)
@@ -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 (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);
 
@@ -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,
index faf492a41f17540d115ecf19f9903d2482996eb3..8eca915c6798f3d64f0d693abca76d2874ada28d 100644 (file)
@@ -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;
        }