summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_mplsvpn.h
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_mplsvpn.h')
-rw-r--r--bgpd/bgp_mplsvpn.h43
1 files changed, 38 insertions, 5 deletions
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 19b6f4e..cd25899 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -13,6 +13,7 @@
#include "bgpd/bgp_rd.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_label.h"
#define MPLS_LABEL_IS_SPECIAL(label) ((label) <= MPLS_LABEL_EXTENSION)
#define MPLS_LABEL_IS_NULL(label) \
@@ -112,7 +113,8 @@ static inline bool is_bgp_vrf_mplsvpn(struct bgp *bgp)
}
static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
- const char **pmsg)
+ const char **pmsg,
+ bool ignore_export_rt_list)
{
if (bgp_vrf->inst_type != BGP_INSTANCE_TYPE_VRF
&& bgp_vrf->inst_type != BGP_INSTANCE_TYPE_DEFAULT) {
@@ -132,8 +134,21 @@ static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
return 0;
}
- /* Is there an RT list set? */
- if (!bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
+ /* Before performing withdrawal, VPN activation is checked; however,
+ * when the route-map modifies the export route-target (RT) list, it
+ * becomes challenging to determine if VPN prefixes were previously
+ * present, or not. The 'ignore_export_rt_list' parameter will be
+ * used to force the withdraw operation by not checking the possible
+ * route-map changes.
+ * Of the 'ignore_export_rt_list' is set to false, check the following:
+ * - Is there an RT list set?
+ * - Is there a route-map that sets RT communities
+ */
+ if (!ignore_export_rt_list &&
+ !bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN] &&
+ (!bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN] ||
+ !bgp_route_map_has_extcommunity_rt(
+ bgp_vrf->vpn_policy[afi].rmap[BGP_VPN_POLICY_DIR_TOVPN]))) {
if (pmsg)
*pmsg = "rtlist tovpn not defined";
return 0;
@@ -165,6 +180,25 @@ static inline int vpn_leak_to_vpn_active(struct bgp *bgp_vrf, afi_t afi,
return 0;
}
+ /* Is there a "manual" export label that isn't allocated yet? */
+ if (!CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO) &&
+ bgp_vrf->vpn_policy[afi].tovpn_label != BGP_PREVENT_VRF_2_VRF_LEAK &&
+ bgp_vrf->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE &&
+ (bgp_vrf->vpn_policy[afi].tovpn_label >= MPLS_LABEL_UNRESERVED_MIN &&
+ !CHECK_FLAG(bgp_vrf->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG))) {
+ if (!bgp_zebra_request_label_range(bgp_vrf->vpn_policy[afi]
+ .tovpn_label,
+ 1, false)) {
+ if (pmsg)
+ *pmsg = "manual label could not be allocated";
+ return 0;
+ }
+ SET_FLAG(bgp_vrf->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG);
+ }
+
return 1;
}
@@ -226,8 +260,7 @@ static inline void vpn_leak_prechange(enum vpn_policy_direction direction,
vpn_leak_to_vrf_withdraw_all(bgp_vrf, afi);
}
if ((direction == BGP_VPN_POLICY_DIR_TOVPN) &&
- vpn_leak_to_vpn_active(bgp_vrf, afi, NULL)) {
-
+ vpn_leak_to_vpn_active(bgp_vrf, afi, NULL, true)) {
vpn_leak_from_vrf_withdraw_all(bgp_vpn, bgp_vrf, afi);
}
}