summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_labelpool.c5
-rw-r--r--bgpd/bgp_mplsvpn.h20
-rw-r--r--bgpd/bgp_vty.c20
-rw-r--r--bgpd/bgp_zebra.c14
-rw-r--r--bgpd/bgp_zebra.h3
-rw-r--r--bgpd/bgpd.h2
6 files changed, 56 insertions, 8 deletions
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index 883338610..d33f14ac4 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -448,7 +448,7 @@ void bgp_lp_get(
if (lp_fifo_count(&lp->requests) > lp->pending_count) {
if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY,
- lp->next_chunksize))
+ lp->next_chunksize, true))
return;
lp->pending_count += lp->next_chunksize;
@@ -650,7 +650,8 @@ void bgp_lp_event_zebra_up(void)
*/
list_delete_all_node(lp->chunks);
- if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY, labels_needed))
+ if (!bgp_zebra_request_label_range(MPLS_LABEL_BASE_ANY, labels_needed,
+ true))
return;
lp->pending_count = labels_needed;
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 19b6f4eb7..b2bdfcec0 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) \
@@ -165,6 +166,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;
}
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 48eaf1ed7..1ec66824c 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -9471,9 +9471,16 @@ DEFPY (af_label_vpn_export,
vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
bgp_get_default(), bgp);
- /* release any previous auto label */
if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+ BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG)) {
+ bgp_zebra_release_label_range(bgp->vpn_policy[afi].tovpn_label,
+ bgp->vpn_policy[afi].tovpn_label);
+ UNSET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG);
+
+ } else if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+ /* release any previous auto label */
if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) {
/*
@@ -9501,9 +9508,16 @@ DEFPY (af_label_vpn_export,
bgp_lp_get(LP_TYPE_VRF, &bgp->vpn_policy[afi],
vpn_leak_label_callback);
} else {
+ bgp->vpn_policy[afi].tovpn_label = label;
UNSET_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_LABEL_AUTO);
- bgp->vpn_policy[afi].tovpn_label = label;
+ if (bgp->vpn_policy[afi].tovpn_label >=
+ MPLS_LABEL_UNRESERVED_MIN &&
+ bgp_zebra_request_label_range(bgp->vpn_policy[afi]
+ .tovpn_label,
+ 1, false))
+ SET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG);
}
} else {
UNSET_FLAG(bgp->vpn_policy[afi].flags,
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 212b7f398..e53416044 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -3423,6 +3423,9 @@ static bool bgp_zebra_label_manager_connect(void)
/* tell label pool that zebra is connected */
bgp_lp_event_zebra_up();
+ /* tell BGP L3VPN that label manager is available */
+ if (bgp_get_default())
+ vpn_leak_postchange_all();
return true;
}
@@ -3921,7 +3924,8 @@ void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
zebra_send_mpls_labels(zclient, cmd, &zl);
}
-bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size)
+bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size,
+ bool label_auto)
{
int ret;
uint32_t start, end;
@@ -3943,7 +3947,13 @@ bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size)
return false;
}
- bgp_lp_event_chunk(start, end);
+ if (label_auto)
+ /* label automatic is serviced by the bgp label pool
+ * manager, which allocates label chunks in
+ * pre-pools, and which needs to be notified about
+ * new chunks availability
+ */
+ bgp_lp_event_chunk(start, end);
return true;
}
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index 0edae041d..4696e4dc4 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -124,6 +124,7 @@ extern void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
enum lsp_types_t ltype,
struct prefix *p, uint32_t num_labels,
mpls_label_t out_labels[]);
-extern bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size);
+extern bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size,
+ bool label_auto);
extern void bgp_zebra_release_label_range(uint32_t start, uint32_t end);
#endif /* _QUAGGA_BGP_ZEBRA_H */
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index bc2008b78..0dd421b46 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -217,6 +217,8 @@ struct vpn_policy {
#define BGP_VPN_POLICY_TOVPN_NEXTHOP_SET (1 << 2)
#define BGP_VPN_POLICY_TOVPN_SID_AUTO (1 << 3)
#define BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP (1 << 4)
+/* Manual label is registered with zebra label manager */
+#define BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG (1 << 5)
/*
* If we are importing another vrf into us keep a list of