From 3a79ad3fdcbb7af0b7911a9c610c6e7af970ad6d Mon Sep 17 00:00:00 2001 From: Hitoshi Irino Date: Sat, 2 Mar 2019 13:54:38 +0900 Subject: Supporting BGP/MPLS L3VPNs with Frrouting Zebra API 6 - This commit aims to solve reported problem on issues #1611, #1648 and #1912 - Partial changes of this commit duplicate with changes on PR #1587 (not merged) and PR #1766 (not merged and already closed) - This commit is tested with only FRRouting version 6.0.2 (which uses Zebra API 6) - This commit fixes lack of LABEL_MANAGER_CONNECT_ASYNC for ZAPI6. (This bug is introduced on commit 2bdb76f2dcf24b891f2b6327a57c31b26463b2dd "Supporting Zebra API version 6 which is used in FRRouting version 6") --- internal/pkg/table/table_manager.go | 76 +++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 8 deletions(-) (limited to 'internal/pkg/table/table_manager.go') 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)...) -- cgit v1.2.3