mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 20:51:17 +00:00
bgpd: add an API to get incoming VRF from a RT
This commit is relying on bgp vpn-policy. It is needed to configure several bgp vrf instances, and in each of the bgp instance, configure the following command under address-family ipv4 unicast node: [no] rt redirect import RTLIST Then, a function is provided, that will parse the BGP instances. The incoming ecommunity will be compared with the configured rt redirect import ecommunity list, and return the VRF first instance of the matching route target. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
6a32d26634
commit
301ad80a99
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user