]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: extend bgp routemap prefix-list to flowspec entries 4511/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 14 Jun 2019 10:05:18 +0000 (06:05 -0400)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 8 Jul 2019 06:36:45 +0000 (08:36 +0200)
Some code to cleanup bgp routemap.c a bit.
Addint to this, if a bgp flowspec entry contains a destination IP address,
then the ip address is compared against the prefix-list referenced into
the route-map used.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Signed-off-by: Donald Sharp <sharpd@cumulunetworks.com>
bgpd/bgp_routemap.c

index e43f9486f636de9bf0aa783ec2e1292972ef4006..24c8cc442422102e08ea41d37a8df7eed53af4ce 100644 (file)
@@ -60,6 +60,8 @@
 #include "bgpd/bgp_evpn_private.h"
 #include "bgpd/bgp_evpn_vty.h"
 #include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_pbr.h"
+#include "bgpd/bgp_flowspec_util.h"
 
 #if ENABLE_BGP_VNC
 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
@@ -569,24 +571,67 @@ struct route_map_rule_cmd route_match_ip_route_source_cmd = {
        "ip route-source", route_match_ip_route_source,
        route_match_ip_route_source_compile, route_match_ip_route_source_free};
 
-/* `match ip address prefix-list PREFIX_LIST' */
+static route_map_result_t route_match_prefix_list_flowspec(afi_t afi,
+                                                          struct prefix_list *plist,
+                                                          const struct prefix *p)
+{
+       int ret;
+       struct bgp_pbr_entry_main api;
+
+       memset(&api, 0, sizeof(api));
+
+       /* extract match from flowspec entries */
+       ret = bgp_flowspec_match_rules_fill(
+                                           (uint8_t *)p->u.prefix_flowspec.ptr,
+                                           p->u.prefix_flowspec.prefixlen, &api);
+       if (ret < 0)
+               return RMAP_NOMATCH;
+       if (api.match_bitmask & PREFIX_DST_PRESENT ||
+           api.match_bitmask_iprule & PREFIX_DST_PRESENT) {
+               if (family2afi((&api.dst_prefix)->family) != afi)
+                       return RMAP_NOMATCH;
+               return prefix_list_apply(plist, &api.dst_prefix) == PREFIX_DENY
+                       ? RMAP_NOMATCH
+                       : RMAP_MATCH;
+       } else if (api.match_bitmask & PREFIX_SRC_PRESENT ||
+                  api.match_bitmask_iprule & PREFIX_SRC_PRESENT) {
+               if (family2afi((&api.src_prefix)->family) != afi)
+                       return RMAP_NOMATCH;
+               return (prefix_list_apply(plist, &api.src_prefix) == PREFIX_DENY
+                       ? RMAP_NOMATCH
+                       : RMAP_MATCH);
+       }
+       return RMAP_NOMATCH;
+}
 
+/* `match ip address prefix-list PREFIX_LIST' */
 static route_map_result_t
-route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
-                                  route_map_object_t type, void *object)
+route_match_address_prefix_list(void *rule, afi_t afi,
+                               const struct prefix *prefix,
+                               route_map_object_t type, void *object)
 {
        struct prefix_list *plist;
 
-       if (type == RMAP_BGP && prefix->family == AF_INET) {
-               plist = prefix_list_lookup(AFI_IP, (char *)rule);
-               if (plist == NULL)
-                       return RMAP_NOMATCH;
+       if (type != RMAP_BGP)
+               return RMAP_NOMATCH;
 
-               return (prefix_list_apply(plist, prefix) == PREFIX_DENY
-                               ? RMAP_NOMATCH
-                               : RMAP_MATCH);
-       }
-       return RMAP_NOMATCH;
+       plist = prefix_list_lookup(afi, (char *)rule);
+       if (plist == NULL)
+               return RMAP_NOMATCH;
+
+       if (prefix->family == AF_FLOWSPEC)
+               return route_match_prefix_list_flowspec(afi, plist,
+                                                       prefix);
+       return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
+                                                               : RMAP_MATCH);
+}
+
+static route_map_result_t
+route_match_ip_address_prefix_list(void *rule, const struct prefix *prefix,
+                                  route_map_object_t type, void *object)
+{
+       return route_match_address_prefix_list(rule, AFI_IP, prefix, type,
+                                              object);
 }
 
 static void *route_match_ip_address_prefix_list_compile(const char *arg)
@@ -2540,18 +2585,8 @@ static route_map_result_t
 route_match_ipv6_address_prefix_list(void *rule, const struct prefix *prefix,
                                     route_map_object_t type, void *object)
 {
-       struct prefix_list *plist;
-
-       if (type == RMAP_BGP && prefix->family == AF_INET6) {
-               plist = prefix_list_lookup(AFI_IP6, (char *)rule);
-               if (plist == NULL)
-                       return RMAP_NOMATCH;
-
-               return (prefix_list_apply(plist, prefix) == PREFIX_DENY
-                               ? RMAP_NOMATCH
-                               : RMAP_MATCH);
-       }
-       return RMAP_NOMATCH;
+       return route_match_address_prefix_list(rule, AFI_IP6, prefix, type,
+                                              object);
 }
 
 static void *route_match_ipv6_address_prefix_list_compile(const char *arg)