forked from Mirror/frr
Merge pull request #5327 from lkrishnamoor/rm_rd_filter
bgpd: route-map support for evpn RD filter
This commit is contained in:
commit
75b3bd3534
|
@ -1244,7 +1244,7 @@ static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
|
||||||
static int bgp_input_modifier(struct peer *peer, struct prefix *p,
|
static int bgp_input_modifier(struct peer *peer, struct prefix *p,
|
||||||
struct attr *attr, afi_t afi, safi_t safi,
|
struct attr *attr, afi_t afi, safi_t safi,
|
||||||
const char *rmap_name, mpls_label_t *label,
|
const char *rmap_name, mpls_label_t *label,
|
||||||
uint32_t num_labels)
|
uint32_t num_labels, struct bgp_node *rn)
|
||||||
{
|
{
|
||||||
struct bgp_filter *filter;
|
struct bgp_filter *filter;
|
||||||
struct bgp_path_info rmap_path = { 0 };
|
struct bgp_path_info rmap_path = { 0 };
|
||||||
|
@ -1279,6 +1279,8 @@ static int bgp_input_modifier(struct peer *peer, struct prefix *p,
|
||||||
rmap_path.peer = peer;
|
rmap_path.peer = peer;
|
||||||
rmap_path.attr = attr;
|
rmap_path.attr = attr;
|
||||||
rmap_path.extra = &extra;
|
rmap_path.extra = &extra;
|
||||||
|
rmap_path.net = rn;
|
||||||
|
|
||||||
extra.num_labels = num_labels;
|
extra.num_labels = num_labels;
|
||||||
if (label && num_labels && num_labels <= BGP_MAX_LABELS)
|
if (label && num_labels && num_labels <= BGP_MAX_LABELS)
|
||||||
memcpy(extra.label, label,
|
memcpy(extra.label, label,
|
||||||
|
@ -1795,6 +1797,7 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
|
||||||
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
|
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
|
||||||
rmap_path.peer = peer;
|
rmap_path.peer = peer;
|
||||||
rmap_path.attr = attr;
|
rmap_path.attr = attr;
|
||||||
|
rmap_path.net = rn;
|
||||||
|
|
||||||
if (pi->extra) {
|
if (pi->extra) {
|
||||||
memcpy(&dummy_rmap_path_extra, pi->extra,
|
memcpy(&dummy_rmap_path_extra, pi->extra,
|
||||||
|
@ -3153,7 +3156,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
|
||||||
* intern
|
* intern
|
||||||
* the attr (which takes over the memory references) */
|
* the attr (which takes over the memory references) */
|
||||||
if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
|
if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
|
||||||
label, num_labels) == RMAP_DENY) {
|
label, num_labels, rn) == RMAP_DENY) {
|
||||||
peer->stat_pfx_filter++;
|
peer->stat_pfx_filter++;
|
||||||
reason = "route-map;";
|
reason = "route-map;";
|
||||||
bgp_attr_flush(&new_attr);
|
bgp_attr_flush(&new_attr);
|
||||||
|
@ -11299,7 +11302,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
|
||||||
|
|
||||||
/* Filter prefix using route-map */
|
/* Filter prefix using route-map */
|
||||||
ret = bgp_input_modifier(peer, &rn->p, &attr,
|
ret = bgp_input_modifier(peer, &rn->p, &attr,
|
||||||
afi, safi, rmap_name, NULL, 0);
|
afi, safi, rmap_name, NULL, 0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (type == bgp_show_adj_route_filtered &&
|
if (type == bgp_show_adj_route_filtered &&
|
||||||
!route_filtered && ret != RMAP_DENY) {
|
!route_filtered && ret != RMAP_DENY) {
|
||||||
|
|
|
@ -969,6 +969,63 @@ struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
|
||||||
"evpn route-type", route_match_evpn_route_type,
|
"evpn route-type", route_match_evpn_route_type,
|
||||||
route_match_evpn_route_type_compile, route_match_evpn_route_type_free};
|
route_match_evpn_route_type_compile, route_match_evpn_route_type_free};
|
||||||
|
|
||||||
|
/* `match rd' */
|
||||||
|
|
||||||
|
/* Match function should return 1 if match is success else return zero. */
|
||||||
|
static enum route_map_cmd_result_t
|
||||||
|
route_match_rd(void *rule, const struct prefix *prefix,
|
||||||
|
route_map_object_t type, void *object)
|
||||||
|
{
|
||||||
|
struct prefix_rd *prd_rule = NULL;
|
||||||
|
struct prefix_rd *prd_route = NULL;
|
||||||
|
struct bgp_path_info *path = NULL;
|
||||||
|
|
||||||
|
if (type == RMAP_BGP) {
|
||||||
|
if (prefix->family != AF_EVPN)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
|
prd_rule = (struct prefix_rd *)rule;
|
||||||
|
path = (struct bgp_path_info *)object;
|
||||||
|
|
||||||
|
if (path->net == NULL || path->net->prn == NULL)
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
|
||||||
|
prd_route = (struct prefix_rd *)&path->net->prn->p;
|
||||||
|
if (memcmp(prd_route->val, prd_rule->val, ECOMMUNITY_SIZE) == 0)
|
||||||
|
return RMAP_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RMAP_NOMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Route map `rd' match statement. */
|
||||||
|
static void *route_match_rd_compile(const char *arg)
|
||||||
|
{
|
||||||
|
struct prefix_rd *prd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
prd = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct prefix_rd));
|
||||||
|
|
||||||
|
ret = str2prefix_rd(arg, prd);
|
||||||
|
if (!ret) {
|
||||||
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, prd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free route map's compiled `rd' value. */
|
||||||
|
static void route_match_rd_free(void *rule)
|
||||||
|
{
|
||||||
|
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Route map commands for rd matching. */
|
||||||
|
struct route_map_rule_cmd route_match_evpn_rd_cmd = {
|
||||||
|
"evpn rd", route_match_rd, route_match_rd_compile,
|
||||||
|
route_match_rd_free};
|
||||||
|
|
||||||
/* Route map commands for VRF route leak with source vrf matching */
|
/* Route map commands for VRF route leak with source vrf matching */
|
||||||
static enum route_map_cmd_result_t
|
static enum route_map_cmd_result_t
|
||||||
route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,
|
route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,
|
||||||
|
@ -1038,8 +1095,10 @@ route_match_local_pref(void *rule, const struct prefix *prefix,
|
||||||
return RMAP_NOMATCH;
|
return RMAP_NOMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Route map `match local-preference' match statement.
|
/*
|
||||||
`arg' is local-pref value */
|
* Route map `match local-preference' match statement.
|
||||||
|
* `arg' is local-pref value
|
||||||
|
*/
|
||||||
static void *route_match_local_pref_compile(const char *arg)
|
static void *route_match_local_pref_compile(const char *arg)
|
||||||
{
|
{
|
||||||
uint32_t *local_pref;
|
uint32_t *local_pref;
|
||||||
|
@ -3666,6 +3725,31 @@ DEFUN (no_match_evpn_default_route,
|
||||||
RMAP_EVENT_MATCH_DELETED);
|
RMAP_EVENT_MATCH_DELETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN (match_evpn_rd,
|
||||||
|
match_evpn_rd_cmd,
|
||||||
|
"match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
|
||||||
|
MATCH_STR
|
||||||
|
EVPN_HELP_STR
|
||||||
|
"Route Distinguisher\n"
|
||||||
|
"ASN:XX or A.B.C.D:XX\n")
|
||||||
|
{
|
||||||
|
return bgp_route_match_add(vty, "evpn rd", argv[3]->arg,
|
||||||
|
RMAP_EVENT_MATCH_ADDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN (no_match_evpn_rd,
|
||||||
|
no_match_evpn_rd_cmd,
|
||||||
|
"no match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
|
||||||
|
NO_STR
|
||||||
|
MATCH_STR
|
||||||
|
EVPN_HELP_STR
|
||||||
|
"Route Distinguisher\n"
|
||||||
|
"ASN:XX or A.B.C.D:XX\n")
|
||||||
|
{
|
||||||
|
return bgp_route_match_delete(vty, "evpn rd", argv[4]->arg,
|
||||||
|
RMAP_EVENT_MATCH_DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
DEFPY(match_vrl_source_vrf,
|
DEFPY(match_vrl_source_vrf,
|
||||||
match_vrl_source_vrf_cmd,
|
match_vrl_source_vrf_cmd,
|
||||||
"match source-vrf NAME$vrf_name",
|
"match source-vrf NAME$vrf_name",
|
||||||
|
@ -5216,6 +5300,7 @@ void bgp_route_map_init(void)
|
||||||
route_map_install_match(&route_match_mac_address_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_vni_cmd);
|
||||||
route_map_install_match(&route_match_evpn_route_type_cmd);
|
route_map_install_match(&route_match_evpn_route_type_cmd);
|
||||||
|
route_map_install_match(&route_match_evpn_rd_cmd);
|
||||||
route_map_install_match(&route_match_evpn_default_route_cmd);
|
route_map_install_match(&route_match_evpn_default_route_cmd);
|
||||||
route_map_install_match(&route_match_vrl_source_vrf_cmd);
|
route_map_install_match(&route_match_vrl_source_vrf_cmd);
|
||||||
|
|
||||||
|
@ -5256,6 +5341,8 @@ void bgp_route_map_init(void)
|
||||||
install_element(RMAP_NODE, &no_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, &match_evpn_route_type_cmd);
|
||||||
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
|
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
|
||||||
|
install_element(RMAP_NODE, &match_evpn_rd_cmd);
|
||||||
|
install_element(RMAP_NODE, &no_match_evpn_rd_cmd);
|
||||||
install_element(RMAP_NODE, &match_evpn_default_route_cmd);
|
install_element(RMAP_NODE, &match_evpn_default_route_cmd);
|
||||||
install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
|
install_element(RMAP_NODE, &no_match_evpn_default_route_cmd);
|
||||||
install_element(RMAP_NODE, &match_vrl_source_vrf_cmd);
|
install_element(RMAP_NODE, &match_vrl_source_vrf_cmd);
|
||||||
|
|
Loading…
Reference in a new issue