zebra: migrate route map commands to northbound

Lets use the newly implemented zebra northbound to configure route maps.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
Rafael Zalamena 2019-10-08 16:21:26 -03:00
parent b87fa24d08
commit 07d030ea09

View File

@ -30,6 +30,8 @@
#include "filter.h" #include "filter.h"
#include "plist.h" #include "plist.h"
#include "nexthop.h" #include "nexthop.h"
#include "northbound_cli.h"
#include "route_types.h"
#include "vrf.h" #include "vrf.h"
#include "frrstr.h" #include "frrstr.h"
@ -58,82 +60,6 @@ struct nh_rmap_obj {
static void zebra_route_map_set_delay_timer(uint32_t value); 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 tag TAG'
* Match function return 1 if match is success else return 0 * 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; return CMD_SUCCESS;
} }
DEFUN (match_ip_address_prefix_len, DEFPY(
match_ip_address_prefix_len_cmd, match_ip_address_prefix_len, match_ip_address_prefix_len_cmd,
"match ip address prefix-len (0-32)", "match ip address prefix-len (0-32)$length",
MATCH_STR MATCH_STR
IP_STR IP_STR
"Match prefix length of ip address\n" "Match prefix length of IP address\n"
"Match prefix length of ip address\n" "Match prefix length of IP address\n"
"Prefix length\n") "Prefix length\n")
{ {
return zebra_route_match_add(vty, "ip address prefix-len", argv[4]->arg, const char *xpath = "./match-condition[condition='ipv4-prefix-length']";
RMAP_EVENT_MATCH_ADDED); 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, DEFPY(
no_match_ip_address_prefix_len_cmd, no_match_ip_address_prefix_len, no_match_ip_address_prefix_len_cmd,
"no match ip address prefix-len [(0-32)]", "no match ip address prefix-len [(0-32)]",
NO_STR NO_STR
MATCH_STR MATCH_STR
IP_STR IP_STR
"Match prefix length of ip address\n" "Match prefix length of IP address\n"
"Match prefix length of ip address\n" "Match prefix length of IP address\n"
"Prefix length\n") "Prefix length\n")
{ {
char *plen = (argc == 6) ? argv[5]->arg : NULL; const char *xpath = "./match-condition[condition='ipv4-prefix-length']";
return zebra_route_match_delete(vty, "ip address prefix-len", plen,
RMAP_EVENT_MATCH_DELETED); nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (match_ipv6_address_prefix_len, DEFPY(
match_ipv6_address_prefix_len_cmd, match_ipv6_address_prefix_len, match_ipv6_address_prefix_len_cmd,
"match ipv6 address prefix-len (0-128)", "match ipv6 address prefix-len (0-128)$length",
MATCH_STR MATCH_STR
IPV6_STR IPV6_STR
"Match prefix length of ipv6 address\n" "Match prefix length of IPv6 address\n"
"Match prefix length of ipv6 address\n" "Match prefix length of IPv6 address\n"
"Prefix length\n") "Prefix length\n")
{ {
return zebra_route_match_add(vty, "ipv6 address prefix-len", const char *xpath = "./match-condition[condition='ipv6-prefix-length']";
argv[4]->arg, RMAP_EVENT_MATCH_ADDED); 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, DEFPY(
no_match_ipv6_address_prefix_len_cmd, no_match_ipv6_address_prefix_len, no_match_ipv6_address_prefix_len_cmd,
"no match ipv6 address prefix-len [(0-128)]", "no match ipv6 address prefix-len [(0-128)]",
NO_STR NO_STR
MATCH_STR MATCH_STR
IPV6_STR IPV6_STR
"Match prefix length of ip address\n" "Match prefix length of IPv6 address\n"
"Match prefix length of ip address\n" "Match prefix length of IPv6 address\n"
"Prefix length\n") "Prefix length\n")
{ {
char *plen = (argc == 6) ? argv[5]->arg : NULL; const char *xpath = "./match-condition[condition='ipv6-prefix-length']";
return zebra_route_match_delete(vty, "ipv6 address prefix-len", plen,
RMAP_EVENT_MATCH_DELETED); nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (match_ip_nexthop_prefix_len, DEFPY(
match_ip_nexthop_prefix_len_cmd, match_ip_nexthop_prefix_len, match_ip_nexthop_prefix_len_cmd,
"match ip next-hop prefix-len (0-32)", "match ip next-hop prefix-len (0-32)$length",
MATCH_STR MATCH_STR
IP_STR IP_STR
"Match prefixlen of nexthop ip address\n" "Match prefixlen of nexthop IP address\n"
"Match prefixlen of given nexthop\n" "Match prefixlen of given nexthop\n"
"Prefix length\n") "Prefix length\n")
{ {
return zebra_route_match_add(vty, "ip next-hop prefix-len", const char *xpath =
argv[4]->arg, RMAP_EVENT_MATCH_ADDED); "./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, DEFPY(
no_match_ip_nexthop_prefix_len_cmd, no_match_ip_nexthop_prefix_len, no_match_ip_nexthop_prefix_len_cmd,
"no match ip next-hop prefix-len [(0-32)]", "no match ip next-hop prefix-len [(0-32)]",
NO_STR NO_STR
MATCH_STR MATCH_STR
IP_STR IP_STR
"Match prefixlen of nexthop ip address\n" "Match prefixlen of nexthop IP address\n"
"Match prefix length of nexthop\n" "Match prefix length of nexthop\n"
"Prefix length\n") "Prefix length\n")
{ {
char *plen = (argc == 6) ? argv[5]->arg : NULL; const char *xpath =
return zebra_route_match_delete(vty, "ip next-hop prefix-len", plen, "./match-condition[condition='ipv4-next-hop-prefix-length']";
RMAP_EVENT_MATCH_DELETED);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (match_source_protocol, DEFPY(
match_source_protocol_cmd, 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 source-protocol " FRR_REDIST_STR_ZEBRA "$proto",
MATCH_STR MATCH_STR
"Match protocol via which the route was learnt\n" "Match protocol via which the route was learnt\n"
"BGP protocol\n" FRR_REDIST_HELP_STR_ZEBRA)
"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; const char *xpath = "./match-condition[condition='source-protocol']";
int i; char xpath_value[XPATH_MAXLEN];
i = proto_name2num(proto); nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (i < 0) { snprintf(xpath_value, sizeof(xpath_value),
vty_out(vty, "invalid protocol name \"%s\"\n", proto); "%s/frr-zebra:source-protocol", xpath);
return CMD_WARNING_CONFIG_FAILED; nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, proto);
}
return zebra_route_match_add(vty, "source-protocol", proto, return nb_cli_apply_changes(vty, NULL);
RMAP_EVENT_MATCH_ADDED);
} }
DEFUN (no_match_source_protocol, DEFPY(
no_match_source_protocol_cmd, 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 match source-protocol [" FRR_REDIST_STR_ZEBRA "]",
NO_STR NO_STR
MATCH_STR MATCH_STR
"No match protocol via which the route was learnt\n" "Match protocol via which the route was learnt\n"
"BGP protocol\n" FRR_REDIST_HELP_STR_ZEBRA)
"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; const char *xpath = "./match-condition[condition='source-protocol']";
return zebra_route_match_delete(vty, "source-protocol", proto,
RMAP_EVENT_MATCH_DELETED); nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (match_source_instance, DEFPY(
match_source_instance_cmd, match_source_instance, match_source_instance_cmd,
"match source-instance (0-255)", "match source-instance (0-255)$instance",
MATCH_STR MATCH_STR
"Match the protocol's instance number\n" "Match the protocol's instance number\n"
"The instance number\n") "The instance number\n")
{ {
char *instance = argv[2]->arg; const char *xpath = "./match-condition[condition='source-instance']";
char xpath_value[XPATH_MAXLEN];
return zebra_route_match_add(vty, "source-instance", instance, nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
RMAP_EVENT_MATCH_ADDED); snprintf(xpath_value, sizeof(xpath_value),
"%s/frr-zebra:source-instance", xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, instance_str);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (no_match_source_instance, DEFPY(
no_match_source_instance_cmd, no_match_source_instance, no_match_source_instance_cmd,
"no match source-instance [(0-255)]", "no match source-instance [(0-255)]",
NO_STR MATCH_STR NO_STR MATCH_STR
"Match the protocol's instance number\n" "Match the protocol's instance number\n"
"The instance number\n") "The instance number\n")
{ {
char *instance = (argc == 4) ? argv[3]->arg : NULL; const char *xpath = "./match-condition[condition='source-instance']";
return zebra_route_match_delete(vty, "source-instance", instance, nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
RMAP_EVENT_MATCH_ADDED);
return nb_cli_apply_changes(vty, NULL);
} }
/* set functions */ /* set functions */
DEFUN (set_src, DEFPY(
set_src_cmd, set_src, set_src_cmd,
"set src <A.B.C.D|X:X::X:X>", "set src <A.B.C.D$addrv4|X:X::X:X$addrv6>",
SET_STR SET_STR
"src address for route\n" "src address for route\n"
"IPv4 src address\n" "IPv4 src address\n"
"IPv6 src address\n") "IPv6 src address\n")
{ {
int idx_ip = 2; const char *xpath = "./set-action[action='source']";
union g_addr src; char xpath_value[XPATH_MAXLEN];
struct interface *pif = NULL;
int family;
struct prefix p;
struct vrf *vrf;
if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) { nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1) { if (addrv4_str) {
vty_out(vty, "%% not a valid IPv4/v6 address\n"); snprintf(xpath_value, sizeof(xpath_value),
return CMD_WARNING_CONFIG_FAILED; "%s/frr-zebra:source-v4", xpath);
} nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
addrv4_str);
p.family = family = AF_INET6;
p.u.prefix6 = src.ipv6;
p.prefixlen = IPV6_MAX_BITLEN;
} else { } else {
p.family = family = AF_INET; snprintf(xpath_value, sizeof(xpath_value),
p.u.prefix4 = src.ipv4; "%s/frr-zebra:source-v6", xpath);
p.prefixlen = IPV4_MAX_BITLEN; nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
addrv6_str);
} }
if (!zebra_check_addr(&p)) { return nb_cli_apply_changes(vty, NULL);
vty_out(vty, "%% not a valid source IPv4/v6 address\n");
return CMD_WARNING_CONFIG_FAILED;
}
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);
if (pif != NULL)
break;
}
if (!pif) {
vty_out(vty, "%% not a local address\n");
return CMD_WARNING_CONFIG_FAILED;
}
VTY_DECLVAR_CONTEXT(route_map_index, index);
return generic_set_add(vty, index, "src", argv[idx_ip]->arg);
} }
DEFUN (no_set_src, DEFPY(
no_set_src_cmd, no_set_src, no_set_src_cmd,
"no set src [<A.B.C.D|X:X::X:X>]", "no set src [<A.B.C.D|X:X::X:X>]",
NO_STR NO_STR
SET_STR SET_STR
"Source address for route\n" "Source address for route\n"
"IPv4 address\n" "IPv4 address\n"
"IPv6 address\n") "IPv6 address\n")
{ {
char *ip = (argc == 4) ? argv[3]->arg : NULL; const char *xpath = "./set-action[action='source']";
VTY_DECLVAR_CONTEXT(route_map_index, index);
return generic_set_delete(vty, index, "src", ip); nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
} }
DEFUN (zebra_route_map_timer, DEFUN (zebra_route_map_timer,