diff options
author | Chirag Shah <chirag@cumulusnetworks.com> | 2019-02-15 03:07:27 +0100 |
---|---|---|
committer | Chirag Shah <chirag@cumulusnetworks.com> | 2019-02-19 16:24:19 +0100 |
commit | 1dcc9e5bdb3968c1cc292036158c18138ba3e0f7 (patch) | |
tree | f35c371628c60d75caccaeb1dfa5906fda89f3f4 | |
parent | Merge pull request #3746 from ton31337/feature/rfc_8212 (diff) | |
download | frr-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.c | 11 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 78 | ||||
-rw-r--r-- | bgpd/subdir.am | 2 |
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 |