diff options
Diffstat (limited to 'table/table_manager.go')
-rw-r--r-- | table/table_manager.go | 261 |
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 +} |