]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib, bgpd: Use 'struct prefix *' for filter matching
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 4 Aug 2017 19:55:44 +0000 (15:55 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 Aug 2017 16:55:03 +0000 (12:55 -0400)
There is no need for special casing of mac addresses,
since the mac address is it's own type integrated
into `struct prefix` now.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_routemap.c
lib/filter.c
lib/prefix.c
lib/prefix.h

index 69b798a01ca97dc9c0d93b68000da84288099068..a8e111d361c113b3c6d8606e3d9296f4c439b6e2 100644 (file)
@@ -585,6 +585,7 @@ static route_map_result_t route_match_mac_address(void *rule,
                                                  void *object)
 {
        struct access_list *alist;
+       struct prefix p;
 
        if (type == RMAP_BGP) {
                alist = access_list_lookup(AFI_L2VPN, (char *)rule);
@@ -594,7 +595,11 @@ static route_map_result_t route_match_mac_address(void *rule,
                if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE)
                        return RMAP_NOMATCH;
 
-               return (access_list_apply(alist, &(prefix->u.prefix_evpn.mac))
+               p.family = AF_ETHERNET;
+               p.prefixlen = ETH_ALEN * 8;
+               p.u.prefix_eth = prefix->u.prefix_evpn.mac;
+
+               return (access_list_apply(alist, &p)
                                        == FILTER_DENY
                                ? RMAP_NOMATCH
                                : RMAP_MATCH);
index fa52fed1c647e520db6d512a6fa143b8189c61b4..9b983d26f26400987eda74ca5919966b49187a95 100644 (file)
@@ -156,29 +156,6 @@ static const char *filter_type_str(struct filter *filter)
        }
 }
 
-/*
- * mac filter match
- * n is of type struct prefix_eth
- * p can be of type struct ethaddr
- */
-static int mac_filter_match(struct prefix *n, struct ethaddr *p)
-{
-       if (!n && !p)
-               return 1;
-
-       if (!n || !p)
-               return 0;
-
-       /* check if we are matching on any mac */
-       if (is_zero_mac(&(n->u.prefix_eth)))
-               return 1;
-
-       if (memcmp(&(n->u.prefix), p, sizeof(struct ethaddr)) == 0)
-               return 1;
-
-       return 0;
-}
-
 /* If filter match to the prefix then return 1. */
 static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
 {
@@ -204,24 +181,19 @@ static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
 }
 
 /* If filter match to the prefix then return 1. */
-static int filter_match_zebra(struct filter *mfilter, void *obj)
+static int filter_match_zebra(struct filter *mfilter, struct prefix *p)
 {
        struct filter_zebra *filter = NULL;
 
        filter = &mfilter->u.zfilter;
 
        if (filter->prefix.family == AF_ETHERNET) {
-               struct ethaddr *p = NULL;
-
-               p = (struct ethaddr *)obj;
-               return mac_filter_match(&filter->prefix, p);
+               return prefix_match(&filter->prefix, p);
        }
 
        if (filter->prefix.family == AF_INET
            || filter->prefix.family == AF_INET6) {
-               struct prefix *p = NULL;
 
-               p = (struct prefix *)obj;
                if (filter->prefix.family == p->family) {
                        if (filter->exact) {
                                if (filter->prefix.prefixlen == p->prefixlen)
@@ -413,9 +385,7 @@ static struct access_list *access_list_get(afi_t afi, const char *name)
 enum filter_type access_list_apply(struct access_list *access, void *object)
 {
        struct filter *filter;
-       struct prefix *p;
-
-       p = (struct prefix *)object;
+       struct prefix *p = (struct prefix *)object;
 
        if (access == NULL)
                return FILTER_DENY;
@@ -425,7 +395,7 @@ enum filter_type access_list_apply(struct access_list *access, void *object)
                        if (filter_match_cisco(filter, p))
                                return filter->type;
                } else {
-                       if (filter_match_zebra(filter, object))
+                       if (filter_match_zebra(filter, p))
                                return filter->type;
                }
        }
@@ -566,16 +536,8 @@ static struct filter *filter_lookup_zebra(struct access_list *access,
 
                if (filter->exact == new->exact
                    && mfilter->type == mnew->type) {
-                       if (new->prefix.family == AF_ETHERNET) {
-                               if (prefix_eth_same(
-                                           (struct prefix_eth *)&filter
-                                                   ->prefix,
-                                           (struct prefix_eth *)&new->prefix))
-                                       return mfilter;
-                       } else {
-                               if (prefix_same(&filter->prefix, &new->prefix))
-                                       return mfilter;
-                       }
+                       if (prefix_same(&filter->prefix, &new->prefix))
+                               return mfilter;
                }
        }
        return NULL;
index df638b0fc87b0a59129a34dd0290f5ce44f2e8e2..d12999067c931d0e6c4276121af0034751e7459c 100644 (file)
@@ -301,7 +301,7 @@ static const struct in6_addr maskbytes6[] = {
 
 #define MASKBIT(offset)  ((0xff << (PNBBY - (offset))) & 0xff)
 
-int is_zero_mac(struct ethaddr *mac)
+int is_zero_mac(const struct ethaddr *mac)
 {
        int i = 0;
 
@@ -479,24 +479,6 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
        }
 }
 
-/* check if the two prefix_eth struct are same*/
-int prefix_eth_same(struct prefix_eth *p1, struct prefix_eth *p2)
-{
-       if (!p1 && !p2)
-               return 1;
-
-       if (p1 && !p2)
-               return 0;
-
-       if (!p1 && p2)
-               return 0;
-
-       if (memcmp(p1, p2, sizeof(struct prefix_eth)) == 0)
-               return 1;
-
-       return 0;
-}
-
 /*
  * Return 1 if the address/netmask contained in the prefix structure
  * is the same, and else return 0.  For this routine, 'same' requires
@@ -699,6 +681,7 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
        const char *str_addr = str;
        unsigned int a[6];
        int i;
+       bool slash = false;
 
        /* Find slash inside string. */
        pnt = strchr(str, '/');
@@ -716,6 +699,7 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
                *(cp + (pnt - str)) = '\0';
 
                str_addr = cp;
+               slash = true;
        }
 
        /* Convert string to prefix. */
@@ -730,6 +714,15 @@ int str2prefix_eth(const char *str, struct prefix_eth *p)
        }
        p->prefixlen = plen;
        p->family = AF_ETHERNET;
+
+       /*
+        * special case to allow old configurations to work
+        * Since all zero's is implicitly meant to allow
+        * a comparison to zero, let's assume
+        */
+       if (!slash && is_zero_mac(&(p->eth_addr)))
+           p->prefixlen = 0;
+
        ret = 1;
 
 done:
index 3ebf6154684c1e8c9a8a890e687ea8944ee8add1..ddd01af76683f41b9c23a9f358896f0306276fa5 100644 (file)
@@ -276,7 +276,7 @@ union prefixconstptr {
 #endif /*s6_addr32*/
 
 /* Prototypes. */
-extern int is_zero_mac(struct ethaddr *mac);
+extern int is_zero_mac(const struct ethaddr *mac);
 extern int str2family(const char *);
 extern int afi2family(afi_t);
 extern afi_t family2afi(int);
@@ -305,7 +305,6 @@ extern int prefix_cmp(const struct prefix *, const struct prefix *);
 extern int prefix_common_bits(const struct prefix *, const struct prefix *);
 extern void prefix_copy(struct prefix *dest, const struct prefix *src);
 extern void apply_mask(struct prefix *);
-extern int prefix_eth_same(struct prefix_eth *p1, struct prefix_eth *p2);
 
 extern struct prefix *sockunion2prefix(const union sockunion *dest,
                                       const union sockunion *mask);