summaryrefslogtreecommitdiffhomepage
path: root/table/table_manager.go
diff options
context:
space:
mode:
Diffstat (limited to 'table/table_manager.go')
-rw-r--r--table/table_manager.go261
1 files changed, 61 insertions, 200 deletions
diff --git a/table/table_manager.go b/table/table_manager.go
index 637299b9..cc73c89b 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -24,6 +24,10 @@ import (
"time"
)
+const (
+ GLOBAL_RIB_NAME = "global"
+)
+
func nlri2Path(m *bgp.BGPMessage, p *PeerInfo, now time.Time) []*Path {
updateMsg := m.Body.(*bgp.BGPUpdate)
pathAttributes := updateMsg.PathAttributes
@@ -105,17 +109,13 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time)
}
type TableManager struct {
- Tables map[bgp.RouteFamily]*Table
- Vrfs map[string]*Vrf
- owner string
- minLabel uint32
- maxLabel uint32
- nextLabel uint32
- rfList []bgp.RouteFamily
- importPolicies []*Policy
- defaultImportPolicy RouteType
- exportPolicies []*Policy
- defaultExportPolicy RouteType
+ Tables map[bgp.RouteFamily]*Table
+ Vrfs map[string]*Vrf
+ owner string
+ minLabel uint32
+ maxLabel uint32
+ nextLabel uint32
+ rfList []bgp.RouteFamily
}
func NewTableManager(owner string, rfList []bgp.RouteFamily, minLabel, maxLabel uint32) *TableManager {
@@ -138,82 +138,6 @@ func (manager *TableManager) GetRFlist() []bgp.RouteFamily {
return manager.rfList
}
-func (manager *TableManager) GetPolicy(d PolicyDirection) []*Policy {
- switch d {
- case POLICY_DIRECTION_IMPORT:
- return manager.importPolicies
- case POLICY_DIRECTION_EXPORT:
- return manager.exportPolicies
- }
- return nil
-}
-
-func (manager *TableManager) SetPolicy(d PolicyDirection, policies []*Policy) error {
- switch d {
- case POLICY_DIRECTION_IMPORT:
- manager.importPolicies = policies
- case POLICY_DIRECTION_EXPORT:
- manager.exportPolicies = policies
- default:
- return fmt.Errorf("unsupported policy type: %d", d)
- }
- return nil
-}
-
-func (manager *TableManager) GetDefaultPolicy(d PolicyDirection) RouteType {
- switch d {
- case POLICY_DIRECTION_IMPORT:
- return manager.defaultImportPolicy
- case POLICY_DIRECTION_EXPORT:
- return manager.defaultExportPolicy
- }
- return ROUTE_TYPE_NONE
-}
-
-func (manager *TableManager) SetDefaultPolicy(d PolicyDirection, typ RouteType) error {
- switch d {
- case POLICY_DIRECTION_IMPORT:
- manager.defaultImportPolicy = typ
- case POLICY_DIRECTION_EXPORT:
- manager.defaultExportPolicy = typ
- default:
- return fmt.Errorf("unsupported policy type: %d", d)
- }
- return nil
-}
-
-func (manager *TableManager) ApplyPolicy(d PolicyDirection, paths []*Path) []*Path {
- newpaths := make([]*Path, 0, len(paths))
- for _, path := range paths {
- result := ROUTE_TYPE_NONE
- newpath := path
- for _, p := range manager.GetPolicy(d) {
- result, newpath = p.Apply(path)
- if result != ROUTE_TYPE_NONE {
- break
- }
- }
-
- if result == ROUTE_TYPE_NONE {
- result = manager.GetDefaultPolicy(d)
- }
-
- switch result {
- case ROUTE_TYPE_ACCEPT:
- newpaths = append(newpaths, newpath)
- case ROUTE_TYPE_REJECT:
- path.Filtered = true
- log.WithFields(log.Fields{
- "Topic": "Peer",
- "Key": path.GetSource().Address,
- "Path": path,
- "Direction": d,
- }).Debug("reject")
- }
- }
- return newpaths
-}
-
func (manager *TableManager) GetNextLabel(name, nexthop string, isWithdraw bool) (uint32, error) {
var label uint32
var err error
@@ -295,122 +219,67 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) {
return msgs, nil
}
-func (manager *TableManager) calculate(destinationList []*Destination) ([]*Path, error) {
- newPaths := make([]*Path, 0)
-
- for _, destination := range destinationList {
- // compute best path
-
+func (manager *TableManager) calculate(destinations []*Destination) {
+ for _, destination := range destinations {
log.WithFields(log.Fields{
"Topic": "table",
"Owner": manager.owner,
"Key": destination.GetNlri().String(),
}).Debug("Processing destination")
+ destination.Calculate()
+ }
+}
- newBestPath, reason, err := destination.Calculate()
-
- if err != nil {
- log.Error(err)
- continue
- }
-
- destination.setBestPathReason(reason)
- currentBestPath := destination.GetBestPath()
-
- if newBestPath != nil && newBestPath.Equal(currentBestPath) {
- // best path is not changed
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "Key": destination.GetNlri().String(),
- "peer": newBestPath.GetSource().Address,
- "next_hop": newBestPath.GetNexthop().String(),
- "reason": reason,
- }).Debug("best path is not changed")
- continue
- }
-
- if newBestPath == nil {
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "Key": destination.GetNlri().String(),
- }).Debug("best path is nil")
-
- if len(destination.GetKnownPathList()) == 0 {
- // create withdraw path
- if currentBestPath != nil {
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "Key": destination.GetNlri().String(),
- "peer": currentBestPath.GetSource().Address,
- "next_hop": currentBestPath.GetNexthop().String(),
- }).Debug("best path is lost")
-
- p := destination.GetBestPath()
- newPaths = append(newPaths, p.Clone(p.Owner, true))
- }
- destination.setBestPath(nil)
- } else {
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "Key": destination.GetNlri().String(),
- }).Error("known path list is not empty")
- }
- } else {
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "Key": newBestPath.GetNlri().String(),
- "peer": newBestPath.GetSource().Address,
- "next_hop": newBestPath.GetNexthop(),
- "reason": reason,
- }).Debug("new best path")
-
- newPaths = append(newPaths, newBestPath)
- destination.setBestPath(newBestPath)
- }
-
- if len(destination.GetKnownPathList()) == 0 && destination.GetBestPath() == nil {
- rf := destination.getRouteFamily()
- t := manager.Tables[rf]
- t.deleteDest(destination)
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "Key": destination.GetNlri().String(),
- "route_family": rf,
- }).Debug("destination removed")
- }
+func (manager *TableManager) DeletePathsByPeer(info *PeerInfo, rf bgp.RouteFamily) []*Destination {
+ if t, ok := manager.Tables[rf]; ok {
+ dsts := t.DeleteDestByPeer(info)
+ manager.calculate(dsts)
+ return dsts
}
- return newPaths, nil
+ return nil
}
-func (manager *TableManager) DeletePathsforPeer(peerInfo *PeerInfo, rf bgp.RouteFamily) ([]*Path, error) {
+func (manager *TableManager) DeletePathsforPeer(id string, peerInfo *PeerInfo, rf bgp.RouteFamily) ([]*Path, error) {
if t, ok := manager.Tables[rf]; ok {
destinationList := t.DeleteDestByPeer(peerInfo)
- return manager.calculate(destinationList)
+ manager.calculate(destinationList)
+ paths := make([]*Path, 0, len(destinationList))
+ for _, dst := range destinationList {
+ paths = append(paths, dst.NewFeed(id))
+ }
+ return paths, nil
}
- return []*Path{}, nil
+ return nil, nil
}
-func (manager *TableManager) ProcessPaths(pathList []*Path) ([]*Path, error) {
- destinationList := make([]*Destination, 0, len(pathList))
+func (manager *TableManager) ProcessPaths(pathList []*Path) []*Destination {
+ m := make(map[string]bool, len(pathList))
+ dsts := make([]*Destination, 0, len(pathList))
for _, path := range pathList {
+ if path == nil {
+ continue
+ }
rf := path.GetRouteFamily()
if t, ok := manager.Tables[rf]; ok {
- destinationList = append(destinationList, t.insert(path))
+ dst := t.insert(path)
+ key := dst.GetNlri().String()
+ if !m[key] {
+ m[key] = true
+ dsts = append(dsts, dst)
+ }
if rf == bgp.RF_EVPN {
- dsts := manager.handleMacMobility(path)
- if len(dsts) > 0 {
- destinationList = append(destinationList, dsts...)
+ for _, dst := range manager.handleMacMobility(path) {
+ key := dst.GetNlri().String()
+ if !m[key] {
+ m[key] = true
+ dsts = append(dsts, dst)
+ }
}
}
}
}
- return manager.calculate(destinationList)
+ manager.calculate(dsts)
+ return dsts
}
// EVPN MAC MOBILITY HANDLING
@@ -427,7 +296,7 @@ func (manager *TableManager) handleMacMobility(path *Path) []*Destination {
if path.IsWithdraw || path.IsLocal() || nlri.RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT {
return nil
}
- for _, path2 := range manager.GetPathList(bgp.RF_EVPN) {
+ for _, path2 := range manager.GetPathList(GLOBAL_RIB_NAME, bgp.RF_EVPN) {
if !path2.IsLocal() || path2.GetNlri().(*bgp.EVPNNLRI).RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT {
continue
}
@@ -464,27 +333,19 @@ func (manager *TableManager) getDestinationCount(rfList []bgp.RouteFamily) int {
return count
}
-func (manager *TableManager) GetPathList(rf bgp.RouteFamily) []*Path {
- if _, ok := manager.Tables[rf]; !ok {
- return []*Path{}
- }
- destinations := manager.Tables[rf].GetDestinations()
- paths := make([]*Path, 0, len(destinations))
- for _, dest := range destinations {
- paths = append(paths, dest.knownPathList...)
- }
- return paths
-}
-
-func (manager *TableManager) GetBestPathList(rfList []bgp.RouteFamily) []*Path {
+func (manager *TableManager) GetBestPathList(id string, rfList []bgp.RouteFamily) []*Path {
paths := make([]*Path, 0, manager.getDestinationCount(rfList))
for _, rf := range rfList {
- if _, ok := manager.Tables[rf]; ok {
- destinations := manager.Tables[rf].GetDestinations()
- for _, dest := range destinations {
- paths = append(paths, dest.GetBestPath())
- }
+ if t, ok := manager.Tables[rf]; ok {
+ paths = append(paths, t.Bests(id)...)
}
}
return paths
}
+
+func (manager *TableManager) GetPathList(id string, rf bgp.RouteFamily) []*Path {
+ if t, ok := manager.Tables[rf]; ok {
+ return t.GetKnownPathList(id)
+ }
+ return nil
+}