static int bgp_input_modifier(struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi,
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_path_info rmap_path = { 0 };
rmap_path.peer = peer;
rmap_path.attr = attr;
rmap_path.extra = &extra;
+ rmap_path.net = rn;
+
extra.num_labels = num_labels;
if (label && num_labels && num_labels <= BGP_MAX_LABELS)
memcpy(extra.label, label,
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
rmap_path.peer = peer;
rmap_path.attr = attr;
+ rmap_path.net = rn;
if (pi->extra) {
memcpy(&dummy_rmap_path_extra, pi->extra,
* intern
* the attr (which takes over the memory references) */
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++;
reason = "route-map;";
bgp_attr_flush(&new_attr);
/* Filter prefix using route-map */
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 &&
!route_filtered && ret != RMAP_DENY) {
"evpn route-type", route_match_evpn_route_type,
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 */
static enum route_map_cmd_result_t
route_match_vrl_source_vrf(void *rule, const struct prefix *prefix,
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)
{
uint32_t *local_pref;
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,
match_vrl_source_vrf_cmd,
"match source-vrf NAME$vrf_name",
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_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_vrl_source_vrf_cmd);
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
install_element(RMAP_NODE, &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, &no_match_evpn_default_route_cmd);
install_element(RMAP_NODE, &match_vrl_source_vrf_cmd);