summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChirag Shah <chirag@cumulusnetworks.com>2019-02-15 03:07:27 +0100
committerChirag Shah <chirag@cumulusnetworks.com>2019-02-19 16:24:19 +0100
commit1dcc9e5bdb3968c1cc292036158c18138ba3e0f7 (patch)
treef35c371628c60d75caccaeb1dfa5906fda89f3f4
parentMerge pull request #3746 from ton31337/feature/rfc_8212 (diff)
downloadfrr-1dcc9e5bdb3968c1cc292036158c18138ba3e0f7.tar.xz
frr-1dcc9e5bdb3968c1cc292036158c18138ba3e0f7.zip
bgpd: vrl source-vrf route map filter
For VRF route leak, enable route map filter based on "source-vrf" check. Implemented match filter rule for "source-vrf" which compares leaked routes original vrf_id (where it leaked from) during importing into target VRF. Ticket:CM-23776 Reviewed By: Testing Done: Configure vrf route leak from vrf1 to vrf2, configure import vrf under vrf2 along with route-map with source-vrf filter. Add and remove source-vrf filter and checked routes were added and removed to vrf2 table via vpn (default) table. Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
-rw-r--r--bgpd/bgp_mplsvpn.c11
-rw-r--r--bgpd/bgp_routemap.c78
-rw-r--r--bgpd/subdir.am2
3 files changed, 88 insertions, 3 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index d0ccdcedf..4baac3e57 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1073,9 +1073,13 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
return;
}
- if (debug)
- zlog_debug("%s: updating to vrf %s", __func__,
- bgp_vrf->name_pretty);
+ if (debug) {
+ char buf_prefix[PREFIX_STRLEN];
+
+ prefix2str(p, buf_prefix, sizeof(buf_prefix));
+ zlog_debug("%s: updating %s to vrf %s", __func__,
+ buf_prefix, bgp_vrf->name_pretty);
+ }
bgp_attr_dup(&static_attr, path_vpn->attr); /* shallow copy */
@@ -1132,6 +1136,7 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf, /* to */
memset(&info, 0, sizeof(info));
info.peer = bgp_vrf->peer_self;
info.attr = &static_attr;
+ info.extra = path_vpn->extra; /* Used for source-vrf filter */
ret = route_map_apply(bgp_vrf->vpn_policy[afi]
.rmap[BGP_VPN_POLICY_DIR_FROMVPN],
p, RMAP_BGP, &info);
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index e28acdfba..18cb332ab 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -65,6 +65,10 @@
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
#endif
+#ifndef VTYSH_EXTRACT_PL
+#include "bgpd/bgp_routemap_clippy.c"
+#endif
+
/* Memo of route-map commands.
o Cisco route-map
@@ -905,6 +909,54 @@ struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
"evpn route-type", route_match_evpn_route_type,
route_match_evpn_route_type_compile, route_match_evpn_route_type_free};
+/* Route map commands for VRF route leak with source vrf matching */
+static route_map_result_t route_match_vrl_source_vrf(void *rule,
+ struct prefix *prefix,
+ route_map_object_t type,
+ void *object)
+{
+ struct bgp_path_info *path;
+ char *vrf_name;
+
+ if (type == RMAP_BGP) {
+ vrf_name = rule;
+ path = (struct bgp_path_info *)object;
+
+ if (strncmp(vrf_name, "n/a", VRF_NAMSIZ) == 0)
+ return RMAP_NOMATCH;
+
+ if (path->extra == NULL)
+ return RMAP_NOMATCH;
+
+ if (strncmp(vrf_name, vrf_id_to_name(
+ path->extra->bgp_orig->vrf_id), VRF_NAMSIZ)
+ == 0)
+ return RMAP_MATCH;
+ }
+
+ return RMAP_NOMATCH;
+}
+
+static void *route_match_vrl_source_vrf_compile(const char *arg)
+{
+ uint8_t *vrf_name = NULL;
+
+ vrf_name = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+
+ return vrf_name;
+}
+
+/* Free route map's compiled `route-type' value. */
+static void route_match_vrl_source_vrf_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+struct route_map_rule_cmd route_match_vrl_source_vrf_cmd = {
+ "source-vrf", route_match_vrl_source_vrf,
+ route_match_vrl_source_vrf_compile,
+ route_match_vrl_source_vrf_free};
+
/* `match local-preference LOCAL-PREF' */
/* Match function return 1 if match is success else return zero. */
@@ -3538,6 +3590,29 @@ DEFUN (no_match_evpn_default_route,
RMAP_EVENT_MATCH_DELETED);
}
+DEFPY(match_vrl_source_vrf,
+ match_vrl_source_vrf_cmd,
+ "match source-vrf NAME$vrf_name",
+ MATCH_STR
+ "source vrf\n"
+ "The VRF name\n")
+{
+ return bgp_route_match_add(vty, "source-vrf", vrf_name,
+ RMAP_EVENT_MATCH_ADDED);
+}
+
+DEFPY(no_match_vrl_source_vrf,
+ no_match_vrl_source_vrf_cmd,
+ "no match source-vrf NAME$vrf_name",
+ NO_STR
+ MATCH_STR
+ "source vrf\n"
+ "The VRF name\n")
+{
+ return bgp_route_match_delete(vty, "source-vrf", vrf_name,
+ RMAP_EVENT_MATCH_DELETED);
+}
+
DEFUN (match_peer,
match_peer_cmd,
"match peer <A.B.C.D|X:X::X:X|WORD>",
@@ -4992,6 +5067,7 @@ void bgp_route_map_init(void)
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_default_route_cmd);
+ route_map_install_match(&route_match_vrl_source_vrf_cmd);
route_map_install_set(&route_set_ip_nexthop_cmd);
route_map_install_set(&route_set_local_pref_cmd);
@@ -5030,6 +5106,8 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &no_match_evpn_route_type_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);
+ install_element(RMAP_NODE, &no_match_vrl_source_vrf_cmd);
install_element(RMAP_NODE, &match_aspath_cmd);
install_element(RMAP_NODE, &no_match_aspath_cmd);
diff --git a/bgpd/subdir.am b/bgpd/subdir.am
index aed2939d3..d281fe4e5 100644
--- a/bgpd/subdir.am
+++ b/bgpd/subdir.am
@@ -224,6 +224,8 @@ bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS)
bgpd/bgp_route.$(OBJEXT): bgpd/bgp_route_clippy.c
bgpd/bgp_debug_clippy.c: $(CLIPPY_DEPS)
bgpd/bgp_debug.$(OBJEXT): bgpd/bgp_debug_clippy.c
+bgpd/bgp_routemap_clippy.c: $(CLIPPY_DEPS)
+bgpd/bgp_routemap.$(OBJEXT): bgpd/bgp_routemap_clippy.c
bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS)
$(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c
$(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c