summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2019-06-03 07:45:47 -0400
committerGitHub <noreply@github.com>2019-06-03 07:45:47 -0400
commit61b64d55014deba914d5ec7b0e4b40d9538d42c4 (patch)
tree2721eda4258a1a3cedaa238171fea49b50a70da8
parentb97480c54829728ad0d72328e3f6e3b830a15671 (diff)
parente241544469ab880da97db8edbc9d21e9cb000257 (diff)
Merge pull request #4078 from lkrishnamoor/rmap_vni_filter
bgpd: Filtering received EVPN routes based on VNI does not work
-rw-r--r--bgpd/bgp_route.c17
-rw-r--r--bgpd/bgp_routemap.c36
2 files changed, 42 insertions, 11 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index edaab88286..543df2b048 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -1236,10 +1236,12 @@ static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
static int bgp_input_modifier(struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi,
- const char *rmap_name)
+ const char *rmap_name, mpls_label_t *label,
+ uint32_t num_labels)
{
struct bgp_filter *filter;
- struct bgp_path_info rmap_path;
+ struct bgp_path_info rmap_path = { 0 };
+ struct bgp_path_info_extra extra = { 0 };
route_map_result_t ret;
struct route_map *rmap = NULL;
@@ -1269,6 +1271,11 @@ static int bgp_input_modifier(struct peer *peer, struct prefix *p,
/* Duplicate current value to new strucutre for modification. */
rmap_path.peer = peer;
rmap_path.attr = attr;
+ rmap_path.extra = &extra;
+ extra.num_labels = num_labels;
+ if (label && num_labels && num_labels <= BGP_MAX_LABELS)
+ memcpy(extra.label, label,
+ num_labels * sizeof(mpls_label_t));
SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
@@ -3124,8 +3131,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
* commands, so we need bgp_attr_flush in the error paths, until we
* intern
* the attr (which takes over the memory references) */
- if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL)
- == RMAP_DENY) {
+ if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
+ label, num_labels) == RMAP_DENY) {
reason = "route-map;";
bgp_attr_flush(&new_attr);
goto filtered;
@@ -11191,7 +11198,7 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
/* Filter prefix using route-map */
ret = bgp_input_modifier(peer, &rn->p, &attr,
- afi, safi, rmap_name);
+ afi, safi, rmap_name, NULL, 0);
if (type == bgp_show_adj_route_filtered &&
!route_filtered && ret != RMAP_DENY) {
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 85cab0d59f..790b2f7995 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -60,6 +60,7 @@
#include "bgpd/bgp_evpn_private.h"
#include "bgpd/bgp_evpn_vty.h"
#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_encap_types.h"
#if ENABLE_BGP_VNC
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
@@ -795,26 +796,49 @@ struct route_map_rule_cmd route_match_mac_address_cmd = {
"mac address", route_match_mac_address, route_match_mac_address_compile,
route_match_mac_address_free};
-/* `match vni' */
-
-/* Match function should return 1 if match is success else return
- zero. */
+/*
+ * Match function returns:
+ * ...RMAP_MATCH if match is found.
+ * ...RMAP_NOMATCH if match is not found.
+ * ...RMAP_NOOP to ignore this match check.
+ */
static enum route_map_match_result_t
route_match_vni(void *rule, const struct prefix *prefix,
route_map_object_t type, void *object)
{
vni_t vni = 0;
+ unsigned int label_cnt = 0;
struct bgp_path_info *path = NULL;
+ struct prefix_evpn *evp = (struct prefix_evpn *) prefix;
if (type == RMAP_BGP) {
vni = *((vni_t *)rule);
path = (struct bgp_path_info *)object;
+ /*
+ * This rmap filter is valid for vxlan tunnel type only.
+ * For any other tunnel type, return noop to ignore
+ * this check.
+ */
+ if (path->attr && path->attr->encap_tunneltype !=
+ BGP_ENCAP_TYPE_VXLAN)
+ return RMAP_NOOP;
+
+ /*
+ * We do not want to filter type 3 routes because
+ * they do not have vni associated with them.
+ */
+ if (evp && evp->prefix.route_type == BGP_EVPN_IMET_ROUTE)
+ return RMAP_NOOP;
+
if (path->extra == NULL)
return RMAP_NOMATCH;
- if (vni == label2vni(&path->extra->label[0]))
- return RMAP_MATCH;
+ for ( ; label_cnt < BGP_MAX_LABELS &&
+ label_cnt < path->extra->num_labels; label_cnt++) {
+ if (vni == label2vni(&path->extra->label[label_cnt]))
+ return RMAP_MATCH;
+ }
}
return RMAP_NOMATCH;