From 33c2ff625e0865a65713a81cc25cf8c8cc47d22f Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Fri, 26 Jan 2018 17:16:48 -0800 Subject: [PATCH] bgpd: support for filtering EVPN routes based on route-types. In many situations, it is desirable to only exchange EVPN routes of a particular type. For e.g., a common deployment scenario for large DCs is to sub-divide the DC into multiple PODs with full host mobility within a POD (i.e., all subnets provisioned on all leaf switches within the POD) but only do prefix-based routing across PODs. This can be achieved by only exchanging EVPN type-5 routes across PODs. Implement a policy to filter EVPN routes based on route type. Ticket: CM-19394 Review: CCR-7139 Testing: Manual Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_routemap.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 8c9f9f65ca..f5edcf381d 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -696,6 +696,58 @@ struct route_map_rule_cmd route_match_evpn_vni_cmd = { "evpn vni", route_match_vni, route_match_vni_compile, route_match_vni_free}; +/* `match evpn route-type' */ + +/* Match function should return 1 if match is success else return + zero. */ +static route_map_result_t route_match_evpn_route_type(void *rule, + struct prefix *prefix, + route_map_object_t type, + void *object) +{ + u_char route_type = 0; + + if (type == RMAP_BGP) { + route_type = *((u_char *)rule); + + if (route_type == prefix->u.prefix_evpn.route_type) + return RMAP_MATCH; + } + + return RMAP_NOMATCH; +} + +/* Route map `route-type' match statement. */ +static void *route_match_evpn_route_type_compile(const char *arg) +{ + u_char *route_type = NULL; + + route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_char)); + if (!route_type) + return NULL; + + if (strncmp(arg, "ma", 2) == 0) + *route_type = BGP_EVPN_MAC_IP_ROUTE; + else if (strncmp(arg, "mu", 2) == 0) + *route_type = BGP_EVPN_IMET_ROUTE; + else + *route_type = BGP_EVPN_IP_PREFIX_ROUTE; + + return route_type; +} + +/* Free route map's compiled `route-type' value. */ +static void route_match_evpn_route_type_free(void *rule) +{ + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for evpn route-type matching. */ +struct route_map_rule_cmd route_match_evpn_route_type_cmd = { + "evpn route-type", route_match_evpn_route_type, + route_match_evpn_route_type_compile, + route_match_evpn_route_type_free}; + /* `match local-preference LOCAL-PREF' */ /* Match function return 1 if match is success else return zero. */ @@ -3132,6 +3184,36 @@ DEFUN (no_match_mac_address, RMAP_EVENT_FILTER_DELETED); } +DEFUN (match_evpn_route_type, + match_evpn_route_type_cmd, + "match evpn route-type {macip | multicast | prefix}", + MATCH_STR + EVPN_HELP_STR + "Match route-type\n" + "mac-ip route\n" + "IMET route\n" + "prefix route\n") +{ + return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg, + RMAP_EVENT_MATCH_ADDED); +} + +DEFUN (no_match_evpn_route_type, + no_match_evpn_route_type_cmd, + "no match evpn route-type {macip | multicast | prefix}", + NO_STR + MATCH_STR + EVPN_HELP_STR + "Match route-type\n" + "mac-ip route\n" + "IMET route\n" + "prefix route\n") +{ + return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg, + RMAP_EVENT_MATCH_DELETED); +} + + DEFUN (match_evpn_vni, match_evpn_vni_cmd, "match evpn vni (1-16777215)", @@ -4534,6 +4616,7 @@ void bgp_route_map_init(void) route_map_install_match(&route_match_tag_cmd); route_map_install_match(&route_match_mac_address_cmd); route_map_install_match(&route_match_evpn_vni_cmd); + route_map_install_match(&route_match_evpn_route_type_cmd); route_map_install_set(&route_set_ip_nexthop_cmd); route_map_install_set(&route_set_local_pref_cmd); @@ -4568,6 +4651,8 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &no_match_mac_address_cmd); install_element(RMAP_NODE, &match_evpn_vni_cmd); install_element(RMAP_NODE, &no_match_evpn_vni_cmd); + install_element(RMAP_NODE, &match_evpn_route_type_cmd); + install_element(RMAP_NODE, &no_match_evpn_route_type_cmd); install_element(RMAP_NODE, &match_aspath_cmd); install_element(RMAP_NODE, &no_match_aspath_cmd); -- 2.39.5