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 /ospfd/ospf_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 'ospfd/ospf_routemap.c')
-rw-r--r-- | ospfd/ospf_routemap.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index ab2d5ae58..d725837fe 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -126,10 +126,9 @@ static void ospf_route_map_event(const char *name) /* `match ip netxthop ' */ /* Match function return 1 if match is success else return zero. */ -static route_map_result_t route_match_ip_nexthop(void *rule, - const struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_match_result_t +route_match_ip_nexthop(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) { struct access_list *alist; struct external_info *ei = object; @@ -171,7 +170,7 @@ struct route_map_rule_cmd route_match_ip_nexthop_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) { @@ -213,10 +212,9 @@ struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { /* `match ip address IP_ACCESS_LIST' */ /* Match function should return 1 if match is success else return zero. */ -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) { struct access_list *alist; /* struct prefix_ipv4 match; */ @@ -252,7 +250,7 @@ struct route_map_rule_cmd route_match_ip_address_cmd = { route_match_ip_address_free}; /* `match ip address prefix-list PREFIX_LIST' */ -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) { @@ -288,10 +286,9 @@ struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { /* `match interface IFNAME' */ /* Match function should 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 interface *ifp; struct external_info *ei; @@ -327,9 +324,9 @@ struct route_map_rule_cmd route_match_interface_cmd = { route_match_interface_free}; /* Match function return 1 if match is success else return zero. */ -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 external_info *ei; @@ -358,10 +355,9 @@ struct ospf_metric { /* `set metric METRIC' */ /* Set metric to attribute. */ -static route_map_result_t route_set_metric(void *rule, - const struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_match_result_t +route_set_metric(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) { struct ospf_metric *metric; struct external_info *ei; @@ -439,10 +435,9 @@ struct route_map_rule_cmd route_set_metric_cmd = { /* `set metric-type TYPE' */ /* Set metric-type to attribute. */ -static route_map_result_t route_set_metric_type(void *rule, - const struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_match_result_t +route_set_metric_type(void *rule, const struct prefix *prefix, + route_map_object_t type, void *object) { uint32_t *metric_type; struct external_info *ei; @@ -489,8 +484,9 @@ struct route_map_rule_cmd route_set_metric_type_cmd = { route_set_metric_type_free, }; -static route_map_result_t route_set_tag(void *rule, const struct prefix *prefix, - route_map_object_t type, void *object) +static enum route_map_match_result_t +route_set_tag(void *rule, const struct prefix *prefix, route_map_object_t type, + void *object) { route_tag_t *tag; struct external_info *ei; |