summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorLakshman Krishnamoorthy <lkrishnamoor@vmware.com>2019-06-19 23:04:36 +0200
committerLakshman Krishnamoorthy <lkrishnamoor@vmware.com>2019-07-22 17:08:13 +0200
commitb68885f9b7fecc50b74c86801c3aee31b62aa061 (patch)
treec506a6cb5e8e98c0dc1968dcd8001eb368fa0706 /zebra
parentMerge pull request #4688 from qlyoung/alpine-docker-rpki (diff)
downloadfrr-b68885f9b7fecc50b74c86801c3aee31b62aa061.tar.xz
frr-b68885f9b7fecc50b74c86801c3aee31b62aa061.zip
lib: Introducing a 3rd state for route-map match cmd: RMAP_NOOP
Introducing a 3rd state for route_map_apply library function: RMAP_NOOP Traditionally route map MATCH rule apis were designed to return a binary response, consisting of either RMAP_MATCH or RMAP_NOMATCH. (Route-map SET rule apis return RMAP_OKAY or RMAP_ERROR). Depending on this response, the following statemachine decided the course of action: State1: If match cmd returns RMAP_MATCH then, keep existing behaviour. If routemap type is PERMIT, execute set cmds or call cmds if applicable, otherwise PERMIT! Else If routemap type is DENY, we DENYMATCH right away State2: If match cmd returns RMAP_NOMATCH, continue on to next route-map. If there are no other rules or if all the rules return RMAP_NOMATCH, return DENYMATCH We require a 3rd state because of the following situation: The issue - what if, the rule api needs to abort or ignore a rule?: "match evpn vni xx" route-map filter can be applied to incoming routes regardless of whether the tunnel type is vxlan or mpls. This rule should be N/A for mpls based evpn route, but applicable to only vxlan based evpn route. Also, this rule should be applicable for routes with VNI label only, and not for routes without labels. For example, type 3 and type 4 EVPN routes do not have labels, so, this match cmd should let them through. Today, the filter produces either a match or nomatch response regardless of whether it is mpls/vxlan, resulting in either permitting or denying the route.. So an mpls evpn route may get filtered out incorrectly. Eg: "route-map RM1 permit 10 ; match evpn vni 20" or "route-map RM2 deny 20 ; match vni 20" With the introduction of the 3rd state, we can abort this rule check safely. How? The rules api can now return RMAP_NOOP to indicate that it encountered an invalid check, and needs to abort just that rule, but continue with other rules. As a result we have a 3rd state: State3: If match cmd returned RMAP_NOOP Then, proceed to other route-map, otherwise if there are no more rules or if all the rules return RMAP_NOOP, then, return RMAP_PERMITMATCH. Signed-off-by: Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
Diffstat (limited to 'zebra')
-rw-r--r--zebra/redistribute.c4
-rw-r--r--zebra/zebra_nhg.c2
-rw-r--r--zebra/zebra_rnh.c2
-rw-r--r--zebra/zebra_routemap.c95
4 files changed, 48 insertions, 55 deletions
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index d56579ff4..0280cde23 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -574,7 +574,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
struct route_entry *newre;
struct route_entry *same;
struct prefix p;
- route_map_result_t ret = RMAP_MATCH;
+ route_map_result_t ret = RMAP_PERMITMATCH;
afi_t afi;
afi = family2afi(rn->p.family);
@@ -583,7 +583,7 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,
afi, re->type, re->instance, &rn->p, re->ng.nexthop,
zvrf->vrf->vrf_id, re->tag, rmap_name);
- if (ret != RMAP_MATCH) {
+ if (ret != RMAP_PERMITMATCH) {
UNSET_FLAG(re->flags, ZEBRA_FLAG_SELECTED);
zebra_del_import_table_entry(zvrf, rn, re);
return 0;
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 4a8829605..ea42f4dd5 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -339,7 +339,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
struct nexthop *nexthop)
{
struct interface *ifp;
- route_map_result_t ret = RMAP_MATCH;
+ route_map_result_t ret = RMAP_PERMITMATCH;
int family;
char buf[SRCDEST2STR_BUFFER];
const struct prefix *p, *src_p;
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 6f65f8ab7..80defd062 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -403,7 +403,7 @@ static int zebra_rnh_apply_nht_rmap(afi_t afi, struct zebra_vrf *zvrf,
{
int at_least_one = 0;
struct nexthop *nexthop;
- int ret;
+ route_map_result_t ret;
if (prn && re) {
for (nexthop = re->ng.nexthop; nexthop;
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c
index 2f7d50541..cee2c8980 100644
--- a/zebra/zebra_routemap.c
+++ b/zebra/zebra_routemap.c
@@ -136,9 +136,9 @@ static int zebra_route_match_delete(struct vty *vty, const char *command,
/* 'match tag TAG'
* Match function return 1 if match is success else return 0
*/
-static route_map_result_t route_match_tag(void *rule,
- const struct prefix *prefix,
- route_map_object_t type, void *object)
+static enum route_map_cmd_result_t
+route_match_tag(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
{
route_tag_t *tag;
struct nh_rmap_obj *nh_data;
@@ -162,10 +162,9 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
/* `match interface IFNAME' */
/* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_interface(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
+static enum route_map_cmd_result_t
+route_match_interface(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
{
struct nh_rmap_obj *nh_data;
char *ifname = rule;
@@ -1025,10 +1024,9 @@ DEFPY (show_ipv6_protocol_nht,
/* `match ip next-hop IP_ACCESS_LIST' */
/* Match function return 1 if match is success else return zero. */
-static route_map_result_t route_match_ip_next_hop(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
+static enum route_map_cmd_result_t
+route_match_ip_next_hop(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
{
struct access_list *alist;
struct nh_rmap_obj *nh_data;
@@ -1037,7 +1035,7 @@ static route_map_result_t route_match_ip_next_hop(void *rule,
if (type == RMAP_ZEBRA) {
nh_data = object;
if (!nh_data)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
switch (nh_data->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
@@ -1083,7 +1081,7 @@ static struct route_map_rule_cmd route_match_ip_next_hop_cmd = {
/* `match ip next-hop prefix-list PREFIX_LIST' */
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1094,7 +1092,7 @@ route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix,
if (type == RMAP_ZEBRA) {
nh_data = (struct nh_rmap_obj *)object;
if (!nh_data)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
switch (nh_data->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
@@ -1139,10 +1137,9 @@ static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = {
/* Match function should return 1 if match is success else return
zero. */
-static route_map_result_t route_match_address(afi_t afi, void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
+static enum route_map_cmd_result_t
+route_match_address(afi_t afi, void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
{
struct access_list *alist;
@@ -1158,19 +1155,16 @@ static route_map_result_t route_match_address(afi_t afi, void *rule,
return RMAP_NOMATCH;
}
-static route_map_result_t route_match_ip_address(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
+static enum route_map_cmd_result_t
+route_match_ip_address(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
{
return route_match_address(AFI_IP, rule, prefix, type, object);
}
-static route_map_result_t route_match_ipv6_address(void *rule,
- const struct prefix *prefix,
- route_map_object_t type,
- void *object)
-
+static enum route_map_cmd_result_t
+route_match_ipv6_address(void *rule, const struct prefix *prefix,
+ route_map_object_t type, void *object)
{
return route_match_address(AFI_IP6, rule, prefix, type, object);
}
@@ -1200,7 +1194,7 @@ static struct route_map_rule_cmd route_match_ipv6_address_cmd = {
/* `match ip address prefix-list PREFIX_LIST' */
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_address_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object, afi_t afi)
{
@@ -1218,7 +1212,7 @@ route_match_address_prefix_list(void *rule, const struct prefix *prefix,
return RMAP_NOMATCH;
}
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1241,7 +1235,7 @@ static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = {
route_match_address_prefix_list_compile,
route_match_address_prefix_list_free};
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1256,7 +1250,7 @@ static struct route_map_rule_cmd route_match_ipv6_address_prefix_list_cmd = {
/* `match ipv6 next-hop type <TYPE>' */
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1265,7 +1259,7 @@ route_match_ipv6_next_hop_type(void *rule, const struct prefix *prefix,
if (type == RMAP_ZEBRA && prefix->family == AF_INET6) {
nh_data = (struct nh_rmap_obj *)object;
if (!nh_data)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
return RMAP_MATCH;
@@ -1290,7 +1284,7 @@ struct route_map_rule_cmd route_match_ipv6_next_hop_type_cmd = {
/* `match ip address prefix-len PREFIXLEN' */
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_address_prefix_len(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1341,7 +1335,7 @@ static struct route_map_rule_cmd route_match_ipv6_address_prefix_len_cmd = {
/* `match ip nexthop prefix-len PREFIXLEN' */
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1352,7 +1346,7 @@ route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix,
if (type == RMAP_ZEBRA) {
nh_data = (struct nh_rmap_obj *)object;
if (!nh_data || !nh_data->nexthop)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
switch (nh_data->nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
@@ -1381,7 +1375,7 @@ static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = {
/* `match ip next-hop type <blackhole>' */
-static route_map_result_t
+static enum route_map_cmd_result_t
route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
@@ -1390,7 +1384,7 @@ route_match_ip_next_hop_type(void *rule, const struct prefix *prefix,
if (type == RMAP_ZEBRA && prefix->family == AF_INET) {
nh_data = (struct nh_rmap_obj *)object;
if (!nh_data)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
if (nh_data->nexthop->type == NEXTHOP_TYPE_BLACKHOLE)
return RMAP_MATCH;
@@ -1415,10 +1409,9 @@ static struct route_map_rule_cmd route_match_ip_next_hop_type_cmd = {
/* `match source-protocol PROTOCOL' */
-static route_map_result_t route_match_source_protocol(void *rule,
- const struct prefix *p,
- route_map_object_t type,
- void *object)
+static enum route_map_cmd_result_t
+route_match_source_protocol(void *rule, const struct prefix *p,
+ route_map_object_t type, void *object)
{
uint32_t *rib_type = (uint32_t *)rule;
struct nh_rmap_obj *nh_data;
@@ -1426,7 +1419,7 @@ static route_map_result_t route_match_source_protocol(void *rule,
if (type == RMAP_ZEBRA) {
nh_data = (struct nh_rmap_obj *)object;
if (!nh_data)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
return ((nh_data->source_protocol == *rib_type) ? RMAP_MATCH
: RMAP_NOMATCH);
@@ -1457,10 +1450,9 @@ static struct route_map_rule_cmd route_match_source_protocol_cmd = {
route_match_source_protocol_compile, route_match_source_protocol_free};
/* `source-instance` */
-static route_map_result_t route_match_source_instance(void *rule,
- const struct prefix *p,
- route_map_object_t type,
- void *object)
+static enum route_map_cmd_result_t
+route_match_source_instance(void *rule, const struct prefix *p,
+ route_map_object_t type, void *object)
{
uint8_t *instance = (uint8_t *)rule;
struct nh_rmap_obj *nh_data;
@@ -1470,7 +1462,7 @@ static route_map_result_t route_match_source_instance(void *rule,
nh_data = (struct nh_rmap_obj *)object;
if (!nh_data)
- return RMAP_DENYMATCH;
+ return RMAP_NOMATCH;
return (nh_data->instance == *instance) ? RMAP_MATCH : RMAP_NOMATCH;
}
@@ -1500,8 +1492,9 @@ static struct route_map_rule_cmd route_match_source_instance_cmd = {
/* `set src A.B.C.D' */
/* Set src. */
-static route_map_result_t route_set_src(void *rule, const struct prefix *prefix,
- route_map_object_t type, void *object)
+static enum route_map_cmd_result_t
+route_set_src(void *rule, const struct prefix *prefix, route_map_object_t type,
+ void *object)
{
struct nh_rmap_obj *nh_data;
@@ -1767,7 +1760,7 @@ zebra_route_map_check(int family, int rib_type, uint8_t instance,
struct zebra_vrf *zvrf, route_tag_t tag)
{
struct route_map *rmap = NULL;
- route_map_result_t ret = RMAP_MATCH;
+ route_map_result_t ret = RMAP_PERMITMATCH;
struct nh_rmap_obj nh_obj;
nh_obj.nexthop = nexthop;
@@ -1839,7 +1832,7 @@ route_map_result_t zebra_nht_route_map_check(afi_t afi, int client_proto,
struct nexthop *nexthop)
{
struct route_map *rmap = NULL;
- route_map_result_t ret = RMAP_MATCH;
+ route_map_result_t ret = RMAP_PERMITMATCH;
struct nh_rmap_obj nh_obj;
nh_obj.nexthop = nexthop;