summaryrefslogtreecommitdiffhomepage
path: root/internal/pkg/table
diff options
context:
space:
mode:
Diffstat (limited to 'internal/pkg/table')
-rw-r--r--internal/pkg/table/path.go38
-rw-r--r--internal/pkg/table/table_manager.go76
-rw-r--r--internal/pkg/table/vrf.go22
3 files changed, 105 insertions, 31 deletions
diff --git a/internal/pkg/table/path.go b/internal/pkg/table/path.go
index eba0a6ec..bdeb6ff2 100644
--- a/internal/pkg/table/path.go
+++ b/internal/pkg/table/path.go
@@ -133,13 +133,14 @@ type Validation struct {
}
type Path struct {
- info *originInfo
- parent *Path
- pathAttrs []bgp.PathAttributeInterface
- dels []bgp.BGPAttrType
- attrsHash uint32
- aslooped bool
- reason BestPathReason
+ info *originInfo
+ parent *Path
+ pathAttrs []bgp.PathAttributeInterface
+ dels []bgp.BGPAttrType
+ attrsHash uint32
+ aslooped bool
+ reason BestPathReason
+ receiveVrfId uint32 //VRF in which the path was received.
// For BGP Nexthop Tracking, this field shows if nexthop is invalidated by IGP.
IsNexthopInvalid bool
@@ -167,8 +168,9 @@ func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pa
timestamp: timestamp.Unix(),
noImplicitWithdraw: noImplicitWithdraw,
},
- IsWithdraw: isWithdraw,
- pathAttrs: pattrs,
+ IsWithdraw: isWithdraw,
+ pathAttrs: pattrs,
+ receiveVrfId: 0,
}
}
@@ -332,6 +334,13 @@ func (path *Path) IsIBGP() bool {
return (as == path.GetSource().LocalAS) && as != 0
}
+func (path *Path) ReceiveVrfId() uint32 {
+ return path.receiveVrfId
+}
+func (path *Path) SetReceiveVrfId(vrfId uint32) {
+ path.receiveVrfId = vrfId
+}
+
// create new PathAttributes
func (path *Path) Clone(isWithdraw bool) *Path {
return &Path{
@@ -339,6 +348,7 @@ func (path *Path) Clone(isWithdraw bool) *Path {
IsWithdraw: isWithdraw,
IsNexthopInvalid: path.IsNexthopInvalid,
attrsHash: path.attrsHash,
+ receiveVrfId: path.receiveVrfId,
}
}
@@ -580,6 +590,7 @@ func (path *Path) String() string {
if path.IsWithdraw {
s.WriteString(", withdraw")
}
+ s.WriteString(fmt.Sprintf(", receiveVrfId: %d", path.receiveVrfId))
s.WriteString(" }")
return s.String()
}
@@ -1069,12 +1080,12 @@ func (v *Vrf) ToGlobalPath(path *Path) error {
case bgp.RF_IPv4_UC:
n := nlri.(*bgp.IPAddrPrefix)
pathIdentifier := path.GetNlri().PathIdentifier()
- path.OriginInfo().nlri = bgp.NewLabeledVPNIPAddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), v.Rd)
+ path.OriginInfo().nlri = bgp.NewLabeledVPNIPAddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(v.MplsLabel), v.Rd)
path.GetNlri().SetPathIdentifier(pathIdentifier)
case bgp.RF_IPv6_UC:
n := nlri.(*bgp.IPv6AddrPrefix)
pathIdentifier := path.GetNlri().PathIdentifier()
- path.OriginInfo().nlri = bgp.NewLabeledVPNIPv6AddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), v.Rd)
+ path.OriginInfo().nlri = bgp.NewLabeledVPNIPv6AddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(v.MplsLabel), v.Rd)
path.GetNlri().SetPathIdentifier(pathIdentifier)
case bgp.RF_EVPN:
n := nlri.(*bgp.EVPNNLRI)
@@ -1098,11 +1109,11 @@ func (p *Path) ToGlobal(vrf *Vrf) *Path {
switch rf := p.GetRouteFamily(); rf {
case bgp.RF_IPv4_UC:
n := nlri.(*bgp.IPAddrPrefix)
- nlri = bgp.NewLabeledVPNIPAddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), vrf.Rd)
+ nlri = bgp.NewLabeledVPNIPAddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(vrf.MplsLabel), vrf.Rd)
nlri.SetPathIdentifier(pathId)
case bgp.RF_IPv6_UC:
n := nlri.(*bgp.IPv6AddrPrefix)
- nlri = bgp.NewLabeledVPNIPv6AddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), vrf.Rd)
+ nlri = bgp.NewLabeledVPNIPv6AddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(vrf.MplsLabel), vrf.Rd)
nlri.SetPathIdentifier(pathId)
case bgp.RF_EVPN:
n := nlri.(*bgp.EVPNNLRI)
@@ -1138,6 +1149,7 @@ func (p *Path) ToGlobal(vrf *Vrf) *Path {
path.delPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
path.setPathAttr(bgp.NewPathAttributeMpReachNLRI(nh.String(), []bgp.AddrPrefixInterface{nlri}))
path.IsNexthopInvalid = p.IsNexthopInvalid
+ path.receiveVrfId = p.receiveVrfId
return path
}
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)...)
diff --git a/internal/pkg/table/vrf.go b/internal/pkg/table/vrf.go
index 053f85ce..dc98e57d 100644
--- a/internal/pkg/table/vrf.go
+++ b/internal/pkg/table/vrf.go
@@ -20,11 +20,12 @@ import (
)
type Vrf struct {
- Name string
- Id uint32
- Rd bgp.RouteDistinguisherInterface
- ImportRt []bgp.ExtendedCommunityInterface
- ExportRt []bgp.ExtendedCommunityInterface
+ Name string
+ Id uint32
+ Rd bgp.RouteDistinguisherInterface
+ ImportRt []bgp.ExtendedCommunityInterface
+ ExportRt []bgp.ExtendedCommunityInterface
+ MplsLabel uint32
}
func (v *Vrf) Clone() *Vrf {
@@ -33,11 +34,12 @@ func (v *Vrf) Clone() *Vrf {
return append(l, rt...)
}
return &Vrf{
- Name: v.Name,
- Id: v.Id,
- Rd: v.Rd,
- ImportRt: f(v.ImportRt),
- ExportRt: f(v.ExportRt),
+ Name: v.Name,
+ Id: v.Id,
+ Rd: v.Rd,
+ ImportRt: f(v.ImportRt),
+ ExportRt: f(v.ExportRt),
+ MplsLabel: v.MplsLabel,
}
}