mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 08:50:26 +00:00
bgpd,lib: route-map/plist matching via type-2/5 routes
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>
This commit is contained in:
parent
24df337988
commit
6eb8350586
@ -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)
|
||||
@ -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);
|
||||
}
|
||||
|
57
lib/prefix.c
57
lib/prefix.c
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user