Skip to content

Commit

Permalink
bgpd,lib: route-map/plist matching via type-2/5 routes
Browse files Browse the repository at this point in the history
Implement the ability to match type-2 and type-5 routes
via a route-map and a prefix-list.

Add some library code to convert an evpn prefix into
a general ipv4/ipv6 prefix for type-2 and type-5 routes.
evpn prefix is really just another subtype of prefix so all
the info needed can be extracted right there.

Add a special handler to bgp_routemap for evpn type routes
when applying the outbound route-map. This calls the library
code to convert the evpn_prefix to a ipv4/ipv6 prefix and
run it through the plist code. In this we assume type-2 routes
are a /32.

Signed-off-by: Stephen Worley <sworley@nvidia.com>
  • Loading branch information
sworleys committed Aug 23, 2022
1 parent 24df337 commit 6eb8350
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
18 changes: 18 additions & 0 deletions bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,20 @@ route_match_prefix_list_flowspec(afi_t afi, struct prefix_list *plist,
return RMAP_NOMATCH;
}

static enum route_map_cmd_result_t
route_match_prefix_list_evpn(afi_t afi, struct prefix_list *plist,
const struct prefix *p)
{
/* Convert to match a general plist */
struct prefix new;

if (evpn_prefix2prefix(p, &new))
return RMAP_NOMATCH;

return (prefix_list_apply(plist, &new) == PREFIX_DENY ? RMAP_NOMATCH
: RMAP_MATCH);
}

static enum route_map_cmd_result_t
route_match_address_prefix_list(void *rule, afi_t afi,
const struct prefix *prefix, void *object)
Expand All @@ -655,6 +669,10 @@ route_match_address_prefix_list(void *rule, afi_t afi,
if (prefix->family == AF_FLOWSPEC)
return route_match_prefix_list_flowspec(afi, plist,
prefix);

else if (prefix->family == AF_EVPN)
return route_match_prefix_list_evpn(afi, plist, prefix);

return (prefix_list_apply(plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH
: RMAP_MATCH);
}
Expand Down
57 changes: 57 additions & 0 deletions lib/prefix.c
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,63 @@ bool ipv4_unicast_valid(const struct in_addr *addr)
return true;
}

static int ipaddr2prefix(const struct ipaddr *ip, uint16_t prefixlen,
struct prefix *p)
{
switch (ip->ipa_type) {
case (IPADDR_V4):
p->family = AF_INET;
p->u.prefix4 = ip->ipaddr_v4;
p->prefixlen = prefixlen;
break;
case (IPADDR_V6):
p->family = AF_INET6;
p->u.prefix6 = ip->ipaddr_v6;
p->prefixlen = prefixlen;
break;
case (IPADDR_NONE):
p->family = AF_UNSPEC;
break;
}

return 0;
}

/*
* Convert type-2 and type-5 evpn route prefixes into the more
* general ipv4/ipv6 prefix types so we can match prefix lists
* and such.
*/
int evpn_prefix2prefix(const struct prefix *evpn, struct prefix *to)
{
const struct evpn_addr *addr;

if (evpn->family != AF_EVPN)
return -1;

addr = &evpn->u.prefix_evpn;

switch (addr->route_type) {
case (2):
if (IS_IPADDR_V4(&addr->macip_addr.ip))
ipaddr2prefix(&addr->macip_addr.ip, 32, to);
else if (IS_IPADDR_V6(&addr->macip_addr.ip))
ipaddr2prefix(&addr->macip_addr.ip, 128, to);
else
return -1; /* mac only? */

break;
case (5):
ipaddr2prefix(&addr->prefix_addr.ip,
addr->prefix_addr.ip_prefix_length, to);
break;
default:
return -1;
}

return 0;
}

printfrr_ext_autoreg_p("EA", printfrr_ea);
static ssize_t printfrr_ea(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
Expand Down
1 change: 1 addition & 0 deletions lib/prefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ extern char *esi_to_str(const esi_t *esi, char *buf, int size);
extern char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len);
extern void prefix_evpn_hexdump(const struct prefix_evpn *p);
extern bool ipv4_unicast_valid(const struct in_addr *addr);
extern int evpn_prefix2prefix(const struct prefix *evpn, struct prefix *to);

static inline int ipv6_martian(const struct in6_addr *addr)
{
Expand Down

0 comments on commit 6eb8350

Please sign in to comment.