summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_mplsvpn.c19
-rw-r--r--bgpd/bgp_mplsvpn.h2
-rw-r--r--bgpd/bgp_vty.c69
-rw-r--r--bgpd/bgpd.c8
-rw-r--r--bgpd/bgpd.h1
5 files changed, 99 insertions, 0 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 9f740db325..68eb35776e 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1774,3 +1774,22 @@ void bgp_mplsvpn_init(void)
&show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd);
#endif /* KEEP_OLD_VPN_COMMANDS */
}
+
+vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey)
+{
+ struct listnode *mnode, *mnnode;
+ struct bgp *bgp;
+
+ for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
+ struct ecommunity *ec;
+
+ if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
+ continue;
+
+ ec = bgp->vpn_policy[AFI_IP].import_redirect_rtlist;
+
+ if (ecom_intersect(ec, eckey))
+ return bgp->vrf_id;
+ }
+ return VRF_UNKNOWN;
+}
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index d35568b838..fa3ddbac73 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -176,4 +176,6 @@ static inline void vpn_leak_postchange(vpn_policy_direction_t direction,
extern void vpn_policy_routemap_event(const char *rmap_name);
+extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
+
#endif /* _QUAGGA_BGP_MPLSVPN_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index ad6f1a5588..3f51c1509c 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -6588,6 +6588,63 @@ DEFPY (bgp_imexport_vpn,
return CMD_SUCCESS;
}
+DEFPY (af_routetarget_import,
+ af_routetarget_import_cmd,
+ "[no] <rt|route-target> redirect import RTLIST...",
+ NO_STR
+ "Specify route target list\n"
+ "Specify route target list\n"
+ "Flow-spec redirect type route target\n"
+ "Import routes to this address-family\n"
+ "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct ecommunity *ecom = NULL;
+ int doafi[AFI_MAX] = {0};
+ afi_t afi;
+ int idx = 0;
+ int yes = 1;
+
+ if (argv_find(argv, argc, "no", &idx))
+ yes = 0;
+
+ ret = vpn_policy_getafi(vty, doafi);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ if (yes) {
+ if (!argv_find(argv, argc, "RTLIST", &idx)) {
+ vty_out(vty, "%% Missing RTLIST\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ ret = set_ecom_list(vty, argc - idx, argv + idx, &ecom);
+ if (ret != CMD_SUCCESS)
+ return ret;
+ }
+ for (afi = 0; afi < AFI_MAX; ++afi) {
+ if (!doafi[afi])
+ continue;
+ if (yes) {
+ if (bgp->vpn_policy[afi].import_redirect_rtlist)
+ ecommunity_free(
+ &bgp->vpn_policy[afi]
+ .import_redirect_rtlist);
+ bgp->vpn_policy[afi].import_redirect_rtlist =
+ ecommunity_dup(ecom);
+ } else {
+ if (bgp->vpn_policy[afi].import_redirect_rtlist)
+ ecommunity_free(
+ &bgp->vpn_policy[afi]
+ .import_redirect_rtlist);
+ bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
+ }
+ }
+ if (ecom)
+ ecommunity_free(&ecom);
+
+ return CMD_SUCCESS;
+}
+
DEFUN_NOSH (address_family_ipv4_safi,
address_family_ipv4_safi_cmd,
"address-family ipv4 [<unicast|multicast|vpn|labeled-unicast>]",
@@ -11685,7 +11742,16 @@ void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
bgp->vpn_policy[afi]
.rmap_name[BGP_VPN_POLICY_DIR_TOVPN]);
}
+ if (bgp->vpn_policy[afi].import_redirect_rtlist) {
+ char *b = ecommunity_ecom2str(
+ bgp->vpn_policy[afi]
+ .import_redirect_rtlist,
+ ECOMMUNITY_FORMAT_ROUTE_MAP,
+ ECOMMUNITY_ROUTE_TARGET);
+ vty_out(vty, "%*srt redirect import %s\n", indent, "", b);
+ XFREE(MTYPE_ECOMMUNITY_STR, b);
+ }
}
@@ -12897,6 +12963,9 @@ void bgp_vty_init(void)
install_element(BGP_IPV4_NODE, &af_route_map_vpn_imexport_cmd);
install_element(BGP_IPV6_NODE, &af_route_map_vpn_imexport_cmd);
+ install_element(BGP_IPV4_NODE, &af_routetarget_import_cmd);
+ install_element(BGP_IPV6_NODE, &af_routetarget_import_cmd);
+
install_element(BGP_IPV4_NODE, &af_no_rd_vpn_export_cmd);
install_element(BGP_IPV6_NODE, &af_no_rd_vpn_export_cmd);
install_element(BGP_IPV4_NODE, &af_no_label_vpn_export_cmd);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index d103584594..c1c1ee07df 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3272,6 +3272,14 @@ int bgp_delete(struct bgp *bgp)
#endif
bgp_cleanup_routes(bgp);
+ for (afi = 0; afi < AFI_MAX; ++afi) {
+ if (!bgp->vpn_policy[afi].import_redirect_rtlist)
+ continue;
+ ecommunity_free(
+ &bgp->vpn_policy[afi]
+ .import_redirect_rtlist);
+ bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
+ }
/* Remove visibility via the master list - there may however still be
* routes to be processed still referencing the struct bgp.
*/
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 79fe8c8c3b..d4c2a1aba9 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -465,6 +465,7 @@ struct bgp {
/* vpn-policy */
struct {
struct ecommunity *rtlist[BGP_VPN_POLICY_DIR_MAX];
+ struct ecommunity *import_redirect_rtlist;
char *rmap_name[BGP_VPN_POLICY_DIR_MAX];
struct route_map *rmap[BGP_VPN_POLICY_DIR_MAX];