summaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/table/table_manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pkg/table/table_manager.go')
-rw-r--r--internal/pkg/table/table_manager.go76
1 files changed, 68 insertions, 8 deletions
diff --git a/internal/pkg/table/table_manager.go b/internal/pkg/table/table_manager.go
index 58c09bf3..45698504 100644
--- a/internal/pkg/table/table_manager.go
+++ b/internal/pkg/table/table_manager.go
@@ -105,9 +105,10 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time)
}
type TableManager struct {
- Tables map[bgp.RouteFamily]*Table
- Vrfs map[string]*Vrf
- rfList []bgp.RouteFamily
+ Tables map[bgp.RouteFamily]*Table
+ Vrfs map[string]*Vrf
+ rfList []bgp.RouteFamily
+ mplsLabelMaps map[uint64]*Bitmap
}
func NewTableManager(rfList []bgp.RouteFamily) *TableManager {
@@ -122,6 +123,63 @@ func NewTableManager(rfList []bgp.RouteFamily) *TableManager {
return t
}
+func (manager *TableManager) EnableMplsLabelAllocation() error {
+ if manager.mplsLabelMaps != nil {
+ return fmt.Errorf("label allocation already enabled")
+ }
+ manager.mplsLabelMaps = make(map[uint64]*Bitmap)
+ return nil
+}
+
+func (manager *TableManager) AllocateMplsLabelRange(start, end uint32) error {
+ if manager.mplsLabelMaps == nil {
+ return fmt.Errorf("label allocation not yet enabled")
+ }
+ log.WithFields(log.Fields{
+ "Topic": "Vrf",
+ "Start": start,
+ "End": end,
+ }).Debug("allocate new MPLS label range")
+ startEnd := uint64(start)<<32 | uint64(end)
+ manager.mplsLabelMaps[startEnd] = NewBitmap(int(end - start + 1))
+ return nil
+}
+
+func (manager *TableManager) AssignMplsLabel() (uint32, error) {
+ if manager.mplsLabelMaps == nil {
+ return 0, nil
+ }
+ var label uint32
+ for startEnd, bitmap := range manager.mplsLabelMaps {
+ start := uint32(startEnd >> 32)
+ end := uint32(startEnd & 0xffffffff)
+ l, err := bitmap.FindandSetZeroBit()
+ if err == nil && start+uint32(l) <= end {
+ label = start + uint32(l)
+ break
+ }
+ }
+ if label == 0 {
+ return 0, fmt.Errorf("could not assign new MPLS label; need to allocate new MPLS label range")
+ }
+ return label, nil
+}
+
+func (manager *TableManager) releaseMplsLabel(label uint32) {
+ if manager.mplsLabelMaps == nil {
+ return
+ }
+ for startEnd, bitmap := range manager.mplsLabelMaps {
+ start := uint32(startEnd >> 32)
+ end := uint32(startEnd & 0xffffffff)
+ if start <= label && label <= end {
+ bitmap.Unflag(uint(label - start))
+ return
+ }
+ }
+ return
+}
+
func (manager *TableManager) GetRFlist() []bgp.RouteFamily {
return manager.rfList
}
@@ -166,12 +224,14 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) {
msgs = append(msgs, t.deletePathsByVrf(vrf)...)
}
log.WithFields(log.Fields{
- "Topic": "Vrf",
- "Key": vrf.Name,
- "Rd": vrf.Rd,
- "ImportRt": vrf.ImportRt,
- "ExportRt": vrf.ExportRt,
+ "Topic": "Vrf",
+ "Key": vrf.Name,
+ "Rd": vrf.Rd,
+ "ImportRt": vrf.ImportRt,
+ "ExportRt": vrf.ExportRt,
+ "MplsLabel": vrf.MplsLabel,
}).Debugf("delete vrf")
+ manager.releaseMplsLabel(vrf.MplsLabel)
delete(manager.Vrfs, name)
rtcTable := manager.Tables[bgp.RF_RTC_UC]
msgs = append(msgs, rtcTable.deleteRTCPathsByVrf(vrf, manager.Vrfs)...)