From b68885f9b7fecc50b74c86801c3aee31b62aa061 Mon Sep 17 00:00:00 2001 From: Lakshman Krishnamoorthy Date: Wed, 19 Jun 2019 14:04:36 -0700 Subject: 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 --- eigrpd/eigrp_routemap.c | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) (limited to 'eigrpd/eigrp_routemap.c') diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c index f080ba487..bac749477 100644 --- a/eigrpd/eigrp_routemap.c +++ b/eigrpd/eigrp_routemap.c @@ -251,9 +251,9 @@ void eigrp_route_map_update(const char *notused) /* `match metric METRIC' */ /* Match function return 1 if match is success else return zero. */ -static route_map_result_t route_match_metric(void *rule, struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_cmd_result_t +route_match_metric(void *rule, struct prefix *prefix, route_map_object_t type, + void *object) { // uint32_t *metric; // uint32_t check; @@ -311,10 +311,9 @@ struct route_map_rule_cmd route_match_metric_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, - struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_cmd_result_t +route_match_interface(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { // struct rip_info *rinfo; // struct interface *ifp; @@ -360,10 +359,9 @@ struct route_map_rule_cmd route_match_interface_cmd = { /* `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, - struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_cmd_result_t +route_match_ip_next_hop(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { // struct access_list *alist; // struct rip_info *rinfo; @@ -407,7 +405,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, struct prefix *prefix, route_map_object_t type, void *object) { @@ -452,10 +450,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_ip_address(void *rule, - struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_cmd_result_t +route_match_ip_address(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { struct access_list *alist; @@ -491,7 +488,7 @@ static struct route_map_rule_cmd route_match_ip_address_cmd = { /* `match ip address prefix-list PREFIX_LIST' */ -static route_map_result_t +static enum route_map_cmd_result_t route_match_ip_address_prefix_list(void *rule, struct prefix *prefix, route_map_object_t type, void *object) { @@ -526,8 +523,9 @@ static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { /* `match tag TAG' */ /* Match function return 1 if match is success else return zero. */ -static route_map_result_t route_match_tag(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static enum route_map_cmd_result_t +route_match_tag(void *rule, struct prefix *prefix, route_map_object_t type, + void *object) { // unsigned short *tag; // struct rip_info *rinfo; @@ -568,9 +566,9 @@ struct route_map_rule_cmd route_match_tag_cmd = { "tag", route_match_tag, route_match_tag_compile, route_match_tag_free}; /* Set metric to attribute. */ -static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_cmd_result_t +route_set_metric(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { // if (type == RMAP_RIP) // { @@ -662,10 +660,9 @@ static struct route_map_rule_cmd route_set_metric_cmd = { /* `set ip next-hop IP_ADDRESS' */ /* Set nexthop to object. ojbect must be pointer to struct attr. */ -static route_map_result_t route_set_ip_nexthop(void *rule, - struct prefix *prefix, - route_map_object_t type, - void *object) +static enum route_map_cmd_result_t +route_set_ip_nexthop(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { // struct in_addr *address; // struct rip_info *rinfo; @@ -718,8 +715,9 @@ static struct route_map_rule_cmd route_set_ip_nexthop_cmd = { /* `set tag TAG' */ /* Set tag to object. ojbect must be pointer to struct attr. */ -static route_map_result_t route_set_tag(void *rule, struct prefix *prefix, - route_map_object_t type, void *object) +static enum route_map_cmd_result_t +route_set_tag(void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { // unsigned short *tag; // struct rip_info *rinfo; -- cgit v1.2.3