diff options
author | Lakshman Krishnamoorthy <lkrishnamoor@vmware.com> | 2019-05-29 23:32:08 +0200 |
---|---|---|
committer | Lakshman Krishnamoorthy <lkrishnamoor@vmware.com> | 2019-05-30 20:21:28 +0200 |
commit | eadd168781d31a282b601735241fd83adb2cace0 (patch) | |
tree | 9625bc578097aa556517283c95288528db20f393 /zebra/zebra_routemap.c | |
parent | Merge pull request #4402 from chiragshah6/evpn_dev1 (diff) | |
download | frr-eadd168781d31a282b601735241fd83adb2cace0.tar.xz frr-eadd168781d31a282b601735241fd83adb2cace0.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:
Action: Apply route-map match and return the result (RMAP_MATCH/RMAP_NOMATCH)
State1: Receveived RMAP_MATCH
THEN: If Routemap type is PERMIT, execute other rules if applicable,
otherwise we PERMIT!
Else: If Routemap type is DENY, we DENYMATCH right away
State2: Received RMAP_NOMATCH, continue on to next route-map, otherwise,
return DENYMATCH by default if nothing matched.
With reference to PR 4078 (https://github.com/FRRouting/frr/pull/4078),
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.
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 (or another enum) to indicate
that it encountered an invalid check, and needs to abort just that rule,
but continue with other rules.
Question: Do we repurpose an existing enum RMAP_OKAY or RMAP_ERROR
as the 3rd state (or create a new enum like RMAP_NOOP)?
RMAP_OKAY and RMAP_ERROR are used to return the result of set cmd.
We chose to go with RMAP_NOOP (but open to ideas),
as a way to bypass the rmap filter
As a result we have a 3rd state:
State3: Received RMAP_NOOP
Then, proceed to other route-map, otherwise return RMAP_PERMITMATCH by default.
Signed-off-by:Lakshman Krishnamoorthy <lkrishnamoor@vmware.com>
Diffstat (limited to 'zebra/zebra_routemap.c')
-rw-r--r-- | zebra/zebra_routemap.c | 79 |
1 files changed, 36 insertions, 43 deletions
diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index f48bf3b03..51a644178 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_match_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_match_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_match_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; @@ -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_match_result_t route_match_ip_next_hop_prefix_list(void *rule, const struct prefix *prefix, route_map_object_t type, void *object) { @@ -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_match_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_match_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_match_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_match_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_match_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_match_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 ip address prefix-len PREFIXLEN' */ -static route_map_result_t +static enum route_map_match_result_t route_match_address_prefix_len(void *rule, const struct prefix *prefix, route_map_object_t type, void *object) { @@ -1307,7 +1301,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_match_result_t route_match_ip_nexthop_prefix_len(void *rule, const struct prefix *prefix, route_map_object_t type, void *object) { @@ -1347,10 +1341,9 @@ static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_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_match_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; @@ -1389,10 +1382,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_match_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; @@ -1432,8 +1424,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_match_result_t +route_set_src(void *rule, const struct prefix *prefix, route_map_object_t type, + void *object) { struct nh_rmap_obj *nh_data; @@ -1699,7 +1692,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; @@ -1745,7 +1738,7 @@ zebra_import_table_route_map_check(int family, int re_type, uint8_t instance, const char *rmap_name) { struct route_map *rmap = NULL; - route_map_result_t ret = RMAP_DENYMATCH; + enum route_map_match_result_t ret = RMAP_DENYMATCH; struct nh_rmap_obj nh_obj; nh_obj.nexthop = nexthop; @@ -1771,7 +1764,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; |