diff options
-rw-r--r-- | bgpd/bgp_labelpool.c | 5 | ||||
-rw-r--r-- | bgpd/bgp_mplsvpn.h | 20 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 20 | ||||
-rw-r--r-- | bgpd/bgp_zebra.c | 14 | ||||
-rw-r--r-- | bgpd/bgp_zebra.h | 3 | ||||
-rw-r--r-- | bgpd/bgpd.h | 2 |
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 |