diff options
Diffstat (limited to 'internal/pkg/table/table_manager.go')
-rw-r--r-- | internal/pkg/table/table_manager.go | 76 |
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)...) |