]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Northbound implementation for mroute, use-source, boundary_oil cmd
authorSarita Patra <saritap@vmware.com>
Fri, 23 Oct 2020 12:59:37 +0000 (05:59 -0700)
committerSarita Patra <saritap@vmware.com>
Fri, 6 Nov 2020 11:41:59 +0000 (03:41 -0800)
interface_ip_pim_boundary_oil
interface_no_ip_pim_boundary_oil
interface_ip_mroute
interface_no_ip_mroute
interface_pim_use_source
interface_no_pim_use_source

Yang Model:
  augment /frr-interface:lib/frr-interface:interface:
    +--rw pim!
       +--rw address-family* [address-family]
          +--rw address-family            identityref
          +--rw use-source?               ietf-inet-types:ip-address
          +--rw multicast-boundary-oil?   plist-ref
          +--rw mroute* [source-addr group-addr]
             +--rw oif?           frr-interface:interface-ref
             +--rw source-addr    ietf-inet-types:ip-address
             +--rw group-addr     ietf-routing-types:ip-multicast-group-address

Signed-off-by: Sarita Patra <saritap@vmware.com>
pimd/pim_cmd.c
pimd/pim_nb_config.c

index a4111f080ed32a0a60ae3170074fcb3cc967bd2c..d945fe02661a275f27147da63ff17f976538d178 100644 (file)
@@ -8093,22 +8093,13 @@ DEFUN(interface_ip_pim_boundary_oil,
       "Filter OIL by group using prefix list\n"
       "Prefix list to filter OIL with\n")
 {
-       VTY_DECLVAR_CONTEXT(interface, iif);
-       struct pim_interface *pim_ifp;
-       int idx = 0;
-
-       argv_find(argv, argc, "WORD", &idx);
-
-       PIM_GET_PIM_INTERFACE(pim_ifp, iif);
+       nb_cli_enqueue_change(vty, "./multicast-boundary-oil", NB_OP_MODIFY,
+                       argv[4]->arg);
 
-       if (pim_ifp->boundary_oil_plist)
-               XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
+       return nb_cli_apply_changes(vty,
+                       "./frr-pim:pim/address-family[address-family='%s']",
+                       "frr-routing:ipv4");
 
-       pim_ifp->boundary_oil_plist =
-               XSTRDUP(MTYPE_PIM_INTERFACE, argv[idx]->arg);
-
-       /* Interface will be pruned from OIL on next Join */
-       return CMD_SUCCESS;
 }
 
 DEFUN(interface_no_ip_pim_boundary_oil,
@@ -8121,18 +8112,12 @@ DEFUN(interface_no_ip_pim_boundary_oil,
       "Filter OIL by group using prefix list\n"
       "Prefix list to filter OIL with\n")
 {
-       VTY_DECLVAR_CONTEXT(interface, iif);
-       struct pim_interface *pim_ifp;
-       int idx = 0;
-
-       argv_find(argv, argc, "WORD", &idx);
-
-       PIM_GET_PIM_INTERFACE(pim_ifp, iif);
+       nb_cli_enqueue_change(vty, "./multicast-boundary-oil", NB_OP_DESTROY,
+                       NULL);
 
-       if (pim_ifp->boundary_oil_plist)
-               XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
-
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty,
+                       "./frr-pim:pim/address-family[address-family='%s']",
+                       "frr-routing:ipv4");
 }
 
 DEFUN (interface_ip_mroute,
@@ -8144,56 +8129,21 @@ DEFUN (interface_ip_mroute,
        "Group address\n"
        "Source address\n")
 {
-       VTY_DECLVAR_CONTEXT(interface, iif);
-       struct pim_interface *pim_ifp;
-       struct pim_instance *pim;
        int idx_interface = 2;
        int idx_ipv4 = 3;
-       struct interface *oif;
-       const char *oifname;
-       const char *grp_str;
-       struct in_addr grp_addr;
-       const char *src_str;
-       struct in_addr src_addr;
-       int result;
-
-       PIM_GET_PIM_INTERFACE(pim_ifp, iif);
-       pim = pim_ifp->pim;
-
-       oifname = argv[idx_interface]->arg;
-       oif = if_lookup_by_name(oifname, pim->vrf_id);
-       if (!oif) {
-               vty_out(vty, "No such interface name %s\n", oifname);
-               return CMD_WARNING;
-       }
+       const char *source_str;
 
-       grp_str = argv[idx_ipv4]->arg;
-       result = inet_pton(AF_INET, grp_str, &grp_addr);
-       if (result <= 0) {
-               vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
-                       errno, safe_strerror(errno));
-               return CMD_WARNING;
-       }
+       if (argc == (idx_ipv4 + 1))
+               source_str = "0.0.0.0";
+       else
+               source_str = argv[idx_ipv4 + 1]->arg;
 
-        if (argc == (idx_ipv4 + 1)) {
-                src_addr.s_addr = INADDR_ANY;
-        }
-        else {
-                src_str = argv[idx_ipv4 + 1]->arg;
-                result = inet_pton(AF_INET, src_str, &src_addr);
-                if (result <= 0) {
-                        vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
-                                errno, safe_strerror(errno));
-                        return CMD_WARNING;
-                }
-        }
-
-       if (pim_static_add(pim, iif, oif, grp_addr, src_addr)) {
-               vty_out(vty, "Failed to add static mroute\n");
-               return CMD_WARNING;
-       }
+       nb_cli_enqueue_change(vty, "./oif", NB_OP_MODIFY,
+                       argv[idx_interface]->arg);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty,
+                       "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
+                       "frr-routing:ipv4", source_str, argv[idx_ipv4]->arg);
 }
 
 DEFUN (interface_no_ip_mroute,
@@ -8206,56 +8156,19 @@ DEFUN (interface_no_ip_mroute,
        "Group Address\n"
        "Source Address\n")
 {
-       VTY_DECLVAR_CONTEXT(interface, iif);
-       struct pim_interface *pim_ifp;
-       struct pim_instance *pim;
-       int idx_interface = 3;
        int idx_ipv4 = 4;
-       struct interface *oif;
-       const char *oifname;
-       const char *grp_str;
-       struct in_addr grp_addr;
-       const char *src_str;
-       struct in_addr src_addr;
-       int result;
-
-       PIM_GET_PIM_INTERFACE(pim_ifp, iif);
-       pim = pim_ifp->pim;
-
-       oifname = argv[idx_interface]->arg;
-       oif = if_lookup_by_name(oifname, pim->vrf_id);
-       if (!oif) {
-               vty_out(vty, "No such interface name %s\n", oifname);
-               return CMD_WARNING;
-       }
+       const char *source_str;
 
-       grp_str = argv[idx_ipv4]->arg;
-       result = inet_pton(AF_INET, grp_str, &grp_addr);
-       if (result <= 0) {
-               vty_out(vty, "Bad group address %s: errno=%d: %s\n", grp_str,
-                       errno, safe_strerror(errno));
-               return CMD_WARNING;
-       }
+       if (argc == (idx_ipv4 + 1))
+               source_str = "0.0.0.0";
+       else
+               source_str = argv[idx_ipv4 + 1]->arg;
 
-        if (argc == (idx_ipv4 + 1)) {
-                src_addr.s_addr = INADDR_ANY;
-        }
-        else {
-                src_str = argv[idx_ipv4 + 1]->arg;
-                result = inet_pton(AF_INET, src_str, &src_addr);
-                if (result <= 0) {
-                        vty_out(vty, "Bad source address %s: errno=%d: %s\n", src_str,
-                                errno, safe_strerror(errno));
-                        return CMD_WARNING;
-                }
-        }
-
-       if (pim_static_del(pim, iif, oif, grp_addr, src_addr)) {
-               vty_out(vty, "Failed to remove static mroute\n");
-               return CMD_WARNING;
-       }
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty,
+                       "./frr-pim:pim/address-family[address-family='%s']/mroute[source-addr='%s'][group-addr='%s']",
+                       "frr-routing:ipv4", source_str, argv[idx_ipv4]->arg);
 }
 
 DEFUN (interface_ip_pim_hello,
@@ -8957,7 +8870,11 @@ DEFUN (interface_pim_use_source,
        "Configure primary IP address\n"
        "source ip address\n")
 {
-       return interface_pim_use_src_cmd_worker(vty, argv[3]->arg);
+       nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, argv[3]->arg);
+
+       return nb_cli_apply_changes(vty,
+                       "./frr-pim:pim/address-family[address-family='%s']",
+                       "frr-routing:ipv4");
 }
 
 DEFUN (interface_no_pim_use_source,
@@ -8969,7 +8886,11 @@ DEFUN (interface_no_pim_use_source,
        "Delete source IP address\n"
        "source ip address\n")
 {
-       return interface_pim_use_src_cmd_worker(vty, "0.0.0.0");
+       nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, "0.0.0.0");
+
+       return nb_cli_apply_changes(vty,
+                       "./frr-pim:pim/address-family[address-family='%s']",
+                       "frr-routing:ipv4");
 }
 
 DEFUN (ip_pim_bfd,
index ef949d954a39e0ec3167f0842374b53e90edafdb..68111dc1e35f08b09d865a7e8f1e0b22c303c609 100644 (file)
@@ -24,6 +24,7 @@
 #include "pim_pim.h"
 #include "pim_mlag.h"
 #include "pim_bfd.h"
+#include "pim_static.h"
 
 static void pim_if_membership_clear(struct interface *ifp)
 {
@@ -154,6 +155,36 @@ static int pim_cmd_interface_delete(struct interface *ifp)
         return 1;
 }
 
+static int interface_pim_use_src_cmd_worker(struct interface *ifp,
+               struct in_addr source_addr,
+               char *errmsg, size_t errmsg_len)
+{
+       int result;
+       int ret = NB_OK;
+
+       result = pim_update_source_set(ifp, source_addr);
+
+       switch (result) {
+       case PIM_SUCCESS:
+               break;
+       case PIM_IFACE_NOT_FOUND:
+               ret = NB_ERR;
+               snprintf(errmsg, errmsg_len,
+                        "Pim not enabled on this interface %s",
+                        ifp->name);
+                       break;
+       case PIM_UPDATE_SOURCE_DUP:
+               ret = NB_ERR;
+               snprintf(errmsg, errmsg_len, "Source already set");
+               break;
+       default:
+               ret = NB_ERR;
+               snprintf(errmsg, errmsg_len, "Source set failed");
+       }
+
+       return ret;
+}
+
 static bool is_pim_interface(const struct lyd_node *dnode)
 {
        char if_xpath[XPATH_MAXLEN];
@@ -1413,7 +1444,6 @@ int lib_interface_pim_address_family_create(struct nb_cb_create_args *args)
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
        case NB_EV_APPLY:
-               /* TODO: implement me. */
                break;
        }
 
@@ -1427,7 +1457,6 @@ int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args)
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
        case NB_EV_APPLY:
-               /* TODO: implement me. */
                break;
        }
 
@@ -1439,12 +1468,34 @@ int lib_interface_pim_address_family_destroy(struct nb_cb_destroy_args *args)
  */
 int lib_interface_pim_address_family_use_source_modify(struct nb_cb_modify_args *args)
 {
+       struct interface *ifp;
+       struct ipaddr source_addr;
+       int result;
+       const struct lyd_node *if_dnode;
+
        switch (args->event) {
        case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
+               if_dnode = yang_dnode_get_parent(args->dnode, "interface");
+               if (!is_pim_interface(if_dnode)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "Pim not enabled on this interface");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_ABORT:
+       case NB_EV_PREPARE:
+               break;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               ifp = nb_running_get_entry(args->dnode, NULL, true);
+               yang_dnode_get_ip(&source_addr, args->dnode, NULL);
+
+               result = interface_pim_use_src_cmd_worker(
+                               ifp, source_addr.ip._v4_addr,
+                               args->errmsg, args->errmsg_len);
+
+               if (result != PIM_SUCCESS)
+                       return NB_ERR_INCONSISTENCY;
+
                break;
        }
 
@@ -1453,12 +1504,33 @@ int lib_interface_pim_address_family_use_source_modify(struct nb_cb_modify_args
 
 int lib_interface_pim_address_family_use_source_destroy(struct nb_cb_destroy_args *args)
 {
+       struct interface *ifp;
+       struct in_addr source_addr = {INADDR_ANY};
+       int result;
+       const struct lyd_node *if_dnode;
+
        switch (args->event) {
        case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
+               if_dnode = yang_dnode_get_parent(args->dnode, "interface");
+               if (!is_pim_interface(if_dnode)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "Pim not enabled on this interface");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_ABORT:
+       case NB_EV_PREPARE:
+               break;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               ifp = nb_running_get_entry(args->dnode, NULL, true);
+
+               result = interface_pim_use_src_cmd_worker(ifp, source_addr,
+                               args->errmsg,
+                               args->errmsg_len);
+
+               if (result != PIM_SUCCESS)
+                       return NB_ERR_INCONSISTENCY;
+
                break;
        }
 
@@ -1470,12 +1542,34 @@ int lib_interface_pim_address_family_use_source_destroy(struct nb_cb_destroy_arg
  */
 int lib_interface_pim_address_family_multicast_boundary_oil_modify(struct nb_cb_modify_args *args)
 {
+       struct interface *ifp;
+       struct pim_interface *pim_ifp;
+       const char *plist;
+       const struct lyd_node *if_dnode;
+
        switch (args->event) {
        case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
+               if_dnode = yang_dnode_get_parent(args->dnode, "interface");
+               if (!is_pim_interface(if_dnode)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "Pim not enabled on this interface");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_ABORT:
+       case NB_EV_PREPARE:
+               break;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               ifp = nb_running_get_entry(args->dnode, NULL, true);
+               pim_ifp = ifp->info;
+               plist = yang_dnode_get_string(args->dnode, NULL);
+
+               if (pim_ifp->boundary_oil_plist)
+                       XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
+
+               pim_ifp->boundary_oil_plist =
+                       XSTRDUP(MTYPE_PIM_INTERFACE, plist);
+
                break;
        }
 
@@ -1484,12 +1578,27 @@ int lib_interface_pim_address_family_multicast_boundary_oil_modify(struct nb_cb_
 
 int lib_interface_pim_address_family_multicast_boundary_oil_destroy(struct nb_cb_destroy_args *args)
 {
+       struct interface *ifp;
+       struct pim_interface *pim_ifp;
+       const struct lyd_node *if_dnode;
+
        switch (args->event) {
        case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
+               if_dnode = yang_dnode_get_parent(args->dnode, "interface");
+               if (!is_pim_interface(if_dnode)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "%% Enable PIM and/or IGMP on this interface first");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_ABORT:
+       case NB_EV_PREPARE:
+               break;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               ifp = nb_running_get_entry(args->dnode, NULL, true);
+               pim_ifp = ifp->info;
+               if (pim_ifp->boundary_oil_plist)
+                       XFREE(MTYPE_PIM_INTERFACE, pim_ifp->boundary_oil_plist);
                break;
        }
 
@@ -1506,7 +1615,6 @@ int lib_interface_pim_address_family_mroute_create(struct nb_cb_create_args *arg
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
        case NB_EV_APPLY:
-               /* TODO: implement me. */
                break;
        }
 
@@ -1515,12 +1623,52 @@ int lib_interface_pim_address_family_mroute_create(struct nb_cb_create_args *arg
 
 int lib_interface_pim_address_family_mroute_destroy(struct nb_cb_destroy_args *args)
 {
+       struct pim_instance *pim;
+       struct pim_interface *pim_iifp;
+       struct interface *iif;
+       struct interface *oif;
+       const char *oifname;
+       struct ipaddr source_addr;
+       struct ipaddr group_addr;
+       const struct lyd_node *if_dnode;
+
        switch (args->event) {
        case NB_EV_VALIDATE:
+               if_dnode = yang_dnode_get_parent(args->dnode, "interface");
+               if (!is_pim_interface(if_dnode)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "%% Enable PIM and/or IGMP on this interface first");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               break;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               iif = nb_running_get_entry(args->dnode, NULL, true);
+               pim_iifp = iif->info;
+               pim = pim_iifp->pim;
+
+               oifname = yang_dnode_get_string(args->dnode, "./oif");
+               oif = if_lookup_by_name(oifname, pim->vrf_id);
+
+               if (!oif) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "No such interface name %s",
+                                       oifname);
+                       return NB_ERR_INCONSISTENCY;
+               }
+
+               yang_dnode_get_ip(&source_addr, args->dnode, "./source-addr");
+               yang_dnode_get_ip(&group_addr, args->dnode, "./group-addr");
+
+               if (pim_static_del(pim, iif, oif, group_addr.ip._v4_addr,
+                                       source_addr.ip._v4_addr)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "Failed to remove static mroute");
+                       return NB_ERR_INCONSISTENCY;
+               }
+
                break;
        }
 
@@ -1532,12 +1680,52 @@ int lib_interface_pim_address_family_mroute_destroy(struct nb_cb_destroy_args *a
  */
 int lib_interface_pim_address_family_mroute_oif_modify(struct nb_cb_modify_args *args)
 {
+       struct pim_instance *pim;
+       struct pim_interface *pim_iifp;
+       struct interface *iif;
+       struct interface *oif;
+       const char *oifname;
+       struct ipaddr source_addr;
+       struct ipaddr group_addr;
+       const struct lyd_node *if_dnode;
+
        switch (args->event) {
        case NB_EV_VALIDATE:
+               if_dnode = yang_dnode_get_parent(args->dnode, "interface");
+               if (!is_pim_interface(if_dnode)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "%% Enable PIM and/or IGMP on this interface first");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               break;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               iif = nb_running_get_entry(args->dnode, NULL, true);
+               pim_iifp = iif->info;
+               pim = pim_iifp->pim;
+
+               oifname = yang_dnode_get_string(args->dnode, NULL);
+               oif = if_lookup_by_name(oifname, pim->vrf_id);
+
+               if (!oif) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "No such interface name %s",
+                                       oifname);
+                       return NB_ERR_INCONSISTENCY;
+               }
+
+               yang_dnode_get_ip(&source_addr, args->dnode, "../source-addr");
+               yang_dnode_get_ip(&group_addr, args->dnode, "../group-addr");
+
+               if (pim_static_add(pim, iif, oif, group_addr.ip._v4_addr,
+                                       source_addr.ip._v4_addr)) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                       "Failed to add static mroute");
+                       return NB_ERR_INCONSISTENCY;
+               }
+
                break;
        }
 
@@ -1551,7 +1739,6 @@ int lib_interface_pim_address_family_mroute_oif_destroy(struct nb_cb_destroy_arg
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
        case NB_EV_APPLY:
-               /* TODO: implement me. */
                break;
        }