]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: migrate route map commands to northbound
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Tue, 8 Oct 2019 19:21:26 +0000 (16:21 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Mon, 23 Mar 2020 10:55:13 +0000 (07:55 -0300)
Lets use the newly implemented zebra northbound to configure route maps.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
zebra/zebra_routemap.c

index 500c2c84a1a961b039d3df05d48ec3e2efc4c074..2b3b3afbb57635be4a5889fc721f706431e93925 100644 (file)
@@ -30,6 +30,8 @@
 #include "filter.h"
 #include "plist.h"
 #include "nexthop.h"
+#include "northbound_cli.h"
+#include "route_types.h"
 #include "vrf.h"
 #include "frrstr.h"
 
@@ -58,82 +60,6 @@ struct nh_rmap_obj {
 
 static void zebra_route_map_set_delay_timer(uint32_t value);
 
-
-/* Add zebra route map rule */
-static int zebra_route_match_add(struct vty *vty, const char *command,
-                                const char *arg, route_map_event_t type)
-{
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       enum rmap_compile_rets ret;
-       int retval = CMD_SUCCESS;
-
-       ret = route_map_add_match(index, command, arg, type);
-       switch (ret) {
-       case RMAP_RULE_MISSING:
-               vty_out(vty, "%% Zebra Can't find rule.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_ERROR:
-               vty_out(vty, "%% Zebra Argument is malformed.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_SUCCESS:
-               /*
-                * Nothing to do here
-                */
-               break;
-       }
-
-       return retval;
-}
-
-/* Delete zebra route map rule. */
-static int zebra_route_match_delete(struct vty *vty, const char *command,
-                                   const char *arg, route_map_event_t type)
-{
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       enum rmap_compile_rets ret;
-       int retval = CMD_SUCCESS;
-       char *dep_name = NULL;
-       const char *tmpstr;
-       char *rmap_name = NULL;
-
-       if (type != RMAP_EVENT_MATCH_DELETED) {
-               /* ignore the mundane, the types without any dependency */
-               if (arg == NULL) {
-                       if ((tmpstr = route_map_get_match_arg(index, command))
-                           != NULL)
-                               dep_name =
-                                       XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
-               } else {
-                       dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
-               }
-               rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
-       }
-
-       ret = route_map_delete_match(index, command, arg, type);
-       switch (ret) {
-       case RMAP_RULE_MISSING:
-               vty_out(vty, "%% Zebra Can't find rule.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_ERROR:
-               vty_out(vty, "%% Zebra Argument is malformed.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_SUCCESS:
-               /*
-                * Nothing to do here
-                */
-               break;
-       }
-
-       XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
-       XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
-
-       return retval;
-}
-
 /* 'match tag TAG'
  * Match function return 1 if match is success else return 0
  */
@@ -425,246 +351,227 @@ static int ip_nht_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype,
        return CMD_SUCCESS;
 }
 
-DEFUN (match_ip_address_prefix_len,
-       match_ip_address_prefix_len_cmd,
-       "match ip address prefix-len (0-32)",
-       MATCH_STR
-       IP_STR
-       "Match prefix length of ip address\n"
-       "Match prefix length of ip address\n"
-       "Prefix length\n")
+DEFPY(
+       match_ip_address_prefix_len, match_ip_address_prefix_len_cmd,
+       "match ip address prefix-len (0-32)$length",
+       MATCH_STR
+       IP_STR
+       "Match prefix length of IP address\n"
+       "Match prefix length of IP address\n"
+       "Prefix length\n")
 {
-       return zebra_route_match_add(vty, "ip address prefix-len", argv[4]->arg,
-                                    RMAP_EVENT_MATCH_ADDED);
+       const char *xpath = "./match-condition[condition='ipv4-prefix-length']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/frr-zebra:ipv4-prefix-length", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_ip_address_prefix_len,
-       no_match_ip_address_prefix_len_cmd,
-       "no match ip address prefix-len [(0-32)]",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match prefix length of ip address\n"
-       "Match prefix length of ip address\n"
-       "Prefix length\n")
+DEFPY(
+       no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd,
+       "no match ip address prefix-len [(0-32)]",
+       NO_STR
+       MATCH_STR
+       IP_STR
+       "Match prefix length of IP address\n"
+       "Match prefix length of IP address\n"
+       "Prefix length\n")
 {
-       char *plen = (argc == 6) ? argv[5]->arg : NULL;
-       return zebra_route_match_delete(vty, "ip address prefix-len", plen,
-                                       RMAP_EVENT_MATCH_DELETED);
+       const char *xpath = "./match-condition[condition='ipv4-prefix-length']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_ipv6_address_prefix_len,
-       match_ipv6_address_prefix_len_cmd,
-       "match ipv6 address prefix-len (0-128)",
-       MATCH_STR
-       IPV6_STR
-       "Match prefix length of ipv6 address\n"
-       "Match prefix length of ipv6 address\n"
-       "Prefix length\n")
+DEFPY(
+       match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd,
+       "match ipv6 address prefix-len (0-128)$length",
+       MATCH_STR
+       IPV6_STR
+       "Match prefix length of IPv6 address\n"
+       "Match prefix length of IPv6 address\n"
+       "Prefix length\n")
 {
-       return zebra_route_match_add(vty, "ipv6 address prefix-len",
-                                    argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
+       const char *xpath = "./match-condition[condition='ipv6-prefix-length']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/frr-zebra:ipv6-prefix-length", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_ipv6_address_prefix_len,
-       no_match_ipv6_address_prefix_len_cmd,
-       "no match ipv6 address prefix-len [(0-128)]",
-       NO_STR
-       MATCH_STR
-       IPV6_STR
-       "Match prefix length of ip address\n"
-       "Match prefix length of ip address\n"
-       "Prefix length\n")
+DEFPY(
+       no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd,
+       "no match ipv6 address prefix-len [(0-128)]",
+       NO_STR
+       MATCH_STR
+       IPV6_STR
+       "Match prefix length of IPv6 address\n"
+       "Match prefix length of IPv6 address\n"
+       "Prefix length\n")
 {
-       char *plen = (argc == 6) ? argv[5]->arg : NULL;
-       return zebra_route_match_delete(vty, "ipv6 address prefix-len", plen,
-                                       RMAP_EVENT_MATCH_DELETED);
+       const char *xpath = "./match-condition[condition='ipv6-prefix-length']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_ip_nexthop_prefix_len,
-       match_ip_nexthop_prefix_len_cmd,
-       "match ip next-hop prefix-len (0-32)",
-       MATCH_STR
-       IP_STR
-       "Match prefixlen of nexthop ip address\n"
-       "Match prefixlen of given nexthop\n"
-       "Prefix length\n")
+DEFPY(
+       match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd,
+       "match ip next-hop prefix-len (0-32)$length",
+       MATCH_STR
+       IP_STR
+       "Match prefixlen of nexthop IP address\n"
+       "Match prefixlen of given nexthop\n"
+       "Prefix length\n")
 {
-       return zebra_route_match_add(vty, "ip next-hop prefix-len",
-                                    argv[4]->arg, RMAP_EVENT_MATCH_ADDED);
+       const char *xpath =
+               "./match-condition[condition='ipv4-next-hop-prefix-length']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/frr-zebra:ipv4-prefix-length", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, length_str);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_ip_nexthop_prefix_len,
-       no_match_ip_nexthop_prefix_len_cmd,
-       "no match ip next-hop prefix-len [(0-32)]",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match prefixlen of nexthop ip address\n"
-       "Match prefix length of nexthop\n"
-       "Prefix length\n")
-{
-       char *plen = (argc == 6) ? argv[5]->arg : NULL;
-       return zebra_route_match_delete(vty, "ip next-hop prefix-len", plen,
-                                       RMAP_EVENT_MATCH_DELETED);
-}
-
-DEFUN (match_source_protocol,
-       match_source_protocol_cmd,
-       "match source-protocol <bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>",
-       MATCH_STR
-       "Match protocol via which the route was learnt\n"
-       "BGP protocol\n"
-       "OSPF protocol\n"
-       "RIP protocol\n"
-       "RIPNG protocol\n"
-       "ISIS protocol\n"
-       "OSPF6 protocol\n"
-       "PIM protocol\n"
-       "NHRP protocol\n"
-       "EIGRP protocol\n"
-       "BABEL protocol\n"
-       "Routes from directly connected peer\n"
-       "Routes from system configuration\n"
-       "Routes from kernel\n"
-       "Statically configured routes\n"
-       "SHARP process\n")
-{
-       char *proto = argv[2]->text;
-       int i;
+DEFPY(
+       no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd,
+       "no match ip next-hop prefix-len [(0-32)]",
+       NO_STR
+       MATCH_STR
+       IP_STR
+       "Match prefixlen of nexthop IP address\n"
+       "Match prefix length of nexthop\n"
+       "Prefix length\n")
+{
+       const char *xpath =
+               "./match-condition[condition='ipv4-next-hop-prefix-length']";
 
-       i = proto_name2num(proto);
-       if (i < 0) {
-               vty_out(vty, "invalid protocol name \"%s\"\n", proto);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       return zebra_route_match_add(vty, "source-protocol", proto,
-                                    RMAP_EVENT_MATCH_ADDED);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_source_protocol,
-       no_match_source_protocol_cmd,
-       "no match source-protocol [<bgp|ospf|rip|ripng|isis|ospf6|pim|nhrp|eigrp|babel|connected|system|kernel|static|sharp>]",
-       NO_STR
-       MATCH_STR
-       "No match protocol via which the route was learnt\n"
-       "BGP protocol\n"
-       "OSPF protocol\n"
-       "RIP protocol\n"
-       "RIPNG protocol\n"
-       "ISIS protocol\n"
-       "OSPF6 protocol\n"
-       "PIM protocol\n"
-       "NHRP protocol\n"
-       "EIGRP protocol\n"
-       "BABEL protocol\n"
-       "Routes from directly connected peer\n"
-       "Routes from system configuration\n"
-       "Routes from kernel\n"
-       "Statically configured routes\n"
-       "SHARP process\n")
-{
-       char *proto = (argc == 4) ? argv[3]->text : NULL;
-       return zebra_route_match_delete(vty, "source-protocol", proto,
-                                       RMAP_EVENT_MATCH_DELETED);
-}
-
-DEFUN (match_source_instance,
-       match_source_instance_cmd,
-       "match source-instance (0-255)",
-       MATCH_STR
-       "Match the protocol's instance number\n"
-       "The instance number\n")
-{
-       char *instance = argv[2]->arg;
-
-       return zebra_route_match_add(vty, "source-instance", instance,
-                                    RMAP_EVENT_MATCH_ADDED);
-}
-
-DEFUN (no_match_source_instance,
-       no_match_source_instance_cmd,
-       "no match source-instance [(0-255)]",
-       NO_STR MATCH_STR
-       "Match the protocol's instance number\n"
-       "The instance number\n")
-{
-       char *instance = (argc == 4) ? argv[3]->arg : NULL;
-
-       return zebra_route_match_delete(vty, "source-instance", instance,
-                                       RMAP_EVENT_MATCH_ADDED);
+DEFPY(
+       match_source_protocol, match_source_protocol_cmd,
+       "match source-protocol " FRR_REDIST_STR_ZEBRA "$proto",
+       MATCH_STR
+       "Match protocol via which the route was learnt\n"
+       FRR_REDIST_HELP_STR_ZEBRA)
+{
+       const char *xpath = "./match-condition[condition='source-protocol']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/frr-zebra:source-protocol", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-/* set functions */
+DEFPY(
+       no_match_source_protocol, no_match_source_protocol_cmd,
+       "no match source-protocol [" FRR_REDIST_STR_ZEBRA "]",
+       NO_STR
+       MATCH_STR
+       "Match protocol via which the route was learnt\n"
+       FRR_REDIST_HELP_STR_ZEBRA)
+{
+       const char *xpath = "./match-condition[condition='source-protocol']";
 
-DEFUN (set_src,
-       set_src_cmd,
-       "set src <A.B.C.D|X:X::X:X>",
-       SET_STR
-       "src address for route\n"
-       "IPv4 src address\n"
-       "IPv6 src address\n")
-{
-       int idx_ip = 2;
-       union g_addr src;
-       struct interface *pif = NULL;
-       int family;
-       struct prefix p;
-       struct vrf *vrf;
-
-       if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) {
-               if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1) {
-                       vty_out(vty, "%% not a valid IPv4/v6 address\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
 
-               p.family = family = AF_INET6;
-               p.u.prefix6 = src.ipv6;
-               p.prefixlen = IPV6_MAX_BITLEN;
-       } else {
-               p.family = family = AF_INET;
-               p.u.prefix4 = src.ipv4;
-               p.prefixlen = IPV4_MAX_BITLEN;
-       }
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       if (!zebra_check_addr(&p)) {
-               vty_out(vty, "%% not a valid source IPv4/v6 address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+DEFPY(
+       match_source_instance, match_source_instance_cmd,
+       "match source-instance (0-255)$instance",
+       MATCH_STR
+       "Match the protocol's instance number\n"
+       "The instance number\n")
+{
+       const char *xpath = "./match-condition[condition='source-instance']";
+       char xpath_value[XPATH_MAXLEN];
 
-       RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
-               if (family == AF_INET)
-                       pif = if_lookup_exact_address((void *)&src.ipv4,
-                                                     AF_INET, vrf->vrf_id);
-               else if (family == AF_INET6)
-                       pif = if_lookup_exact_address((void *)&src.ipv6,
-                                                     AF_INET6, vrf->vrf_id);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/frr-zebra:source-instance", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, instance_str);
 
-               if (pif != NULL)
-                       break;
-       }
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       if (!pif) {
-               vty_out(vty, "%% not a local address\n");
-               return CMD_WARNING_CONFIG_FAILED;
+DEFPY(
+       no_match_source_instance, no_match_source_instance_cmd,
+       "no match source-instance [(0-255)]",
+       NO_STR MATCH_STR
+       "Match the protocol's instance number\n"
+       "The instance number\n")
+{
+       const char *xpath = "./match-condition[condition='source-instance']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+/* set functions */
+
+DEFPY(
+       set_src, set_src_cmd,
+       "set src <A.B.C.D$addrv4|X:X::X:X$addrv6>",
+       SET_STR
+       "src address for route\n"
+       "IPv4 src address\n"
+       "IPv6 src address\n")
+{
+       const char *xpath = "./set-action[action='source']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       if (addrv4_str) {
+               snprintf(xpath_value, sizeof(xpath_value),
+                        "%s/frr-zebra:source-v4", xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     addrv4_str);
+       } else {
+               snprintf(xpath_value, sizeof(xpath_value),
+                        "%s/frr-zebra:source-v6", xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     addrv6_str);
        }
 
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       return generic_set_add(vty, index, "src", argv[idx_ip]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_src,
-       no_set_src_cmd,
-       "no set src [<A.B.C.D|X:X::X:X>]",
-       NO_STR
-       SET_STR
-       "Source address for route\n"
-       "IPv4 address\n"
-       "IPv6 address\n")
-{
-       char *ip = (argc == 4) ? argv[3]->arg : NULL;
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       return generic_set_delete(vty, index, "src", ip);
+DEFPY(
+       no_set_src, no_set_src_cmd,
+       "no set src [<A.B.C.D|X:X::X:X>]",
+       NO_STR
+       SET_STR
+       "Source address for route\n"
+       "IPv4 address\n"
+       "IPv6 address\n")
+{
+       const char *xpath = "./set-action[action='source']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 DEFUN (zebra_route_map_timer,