From 2dbca9e29a6813f2df53261ffaa59b9439c13fdd Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 10 Apr 2018 22:24:41 +0900 Subject: use sorted single master table for route server setup https://github.com/osrg/gobgp/issues/1249 The IN policy was removed. The modification by the IMPORT policy are visible to all route server peers. This saves some dozens bytes memory per a path. Signed-off-by: FUJITA Tomonori --- api/grpc_server.go | 5 - api/util.go | 3 - client/client.go | 6 - gobgp/cmd/mrt.go | 2 +- gobgp/cmd/neighbor.go | 16 +- server/fsm.go | 18 -- server/peer.go | 19 +- server/server.go | 125 +++------ server/server_test.go | 4 +- table/adj.go | 29 +- table/destination.go | 49 +++- table/destination_test.go | 118 +-------- table/path.go | 14 - table/policy.go | 4 +- table/table.go | 17 +- table/table_manager.go | 16 +- table/table_manager_test.go | 2 +- test/scenario_test/route_server_ipv4_v6_test.py | 4 +- .../scenario_test/route_server_policy_grpc_test.py | 245 ----------------- test/scenario_test/route_server_policy_test.py | 293 --------------------- test/scenario_test/route_server_softreset_test.py | 2 +- 21 files changed, 125 insertions(+), 866 deletions(-) diff --git a/api/grpc_server.go b/api/grpc_server.go index 817199b5..30934cda 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -388,7 +388,6 @@ func ToPathApi(path *table.Path) *Path { IsWithdraw: path.IsWithdraw, Validation: int32(path.ValidationStatus().ToInt()), ValidationDetail: NewValidationFromTableStruct(path.Validation()), - Filtered: path.Filtered("") == table.POLICY_DIRECTION_IN, Family: family, Stale: path.IsStale(), IsFromExternal: path.IsFromExternal(), @@ -2132,8 +2131,6 @@ func NewAPIPolicyAssignmentFromTableStruct(t *table.PolicyAssignment) *PolicyAss return &PolicyAssignment{ Type: func() PolicyType { switch t.Type { - case table.POLICY_DIRECTION_IN: - return PolicyType_IN case table.POLICY_DIRECTION_IMPORT: return PolicyType_IMPORT case table.POLICY_DIRECTION_EXPORT: @@ -2261,8 +2258,6 @@ func toPolicyAssignmentName(a *PolicyAssignment) (string, table.PolicyDirection, } case Resource_LOCAL: switch a.Type { - case PolicyType_IN: - return a.Name, table.POLICY_DIRECTION_IN, nil case PolicyType_IMPORT: return a.Name, table.POLICY_DIRECTION_IMPORT, nil case PolicyType_EXPORT: diff --git a/api/util.go b/api/util.go index 53a94ed3..9a16bef5 100644 --- a/api/util.go +++ b/api/util.go @@ -135,9 +135,6 @@ func (p *Path) ToNativePath(option ...ToNativeOption) (*table.Path, error) { }) path.MarkStale(p.Stale) path.SetUUID(p.Uuid) - if p.Filtered { - path.Filter("", table.POLICY_DIRECTION_IN) - } path.IsNexthopInvalid = p.IsNexthopInvalid return path, nil } diff --git a/client/client.go b/client/client.go index 4cd22526..c31ac2b3 100644 --- a/client/client.go +++ b/client/client.go @@ -718,8 +718,6 @@ func (cli *Client) ReplacePolicy(t *table.Policy, refer, preserve bool) error { func (cli *Client) getPolicyAssignment(name string, dir table.PolicyDirection) (*table.PolicyAssignment, error) { var typ api.PolicyType switch dir { - case table.POLICY_DIRECTION_IN: - typ = api.PolicyType_IN case table.POLICY_DIRECTION_IMPORT: typ = api.PolicyType_IMPORT case table.POLICY_DIRECTION_EXPORT: @@ -770,10 +768,6 @@ func (cli *Client) GetExportPolicy() (*table.PolicyAssignment, error) { return cli.getPolicyAssignment("", table.POLICY_DIRECTION_EXPORT) } -func (cli *Client) GetRouteServerInPolicy(name string) (*table.PolicyAssignment, error) { - return cli.getPolicyAssignment(name, table.POLICY_DIRECTION_IN) -} - func (cli *Client) GetRouteServerImportPolicy(name string) (*table.PolicyAssignment, error) { return cli.getPolicyAssignment(name, table.POLICY_DIRECTION_IMPORT) } diff --git a/gobgp/cmd/mrt.go b/gobgp/cmd/mrt.go index 844cf66c..acafbc33 100644 --- a/gobgp/cmd/mrt.go +++ b/gobgp/cmd/mrt.go @@ -146,7 +146,7 @@ func injectMrt() error { for _, p := range paths { dst.AddNewPath(p) } - best, _, _ := dst.Calculate().GetChanges(table.GLOBAL_RIB_NAME, false) + best, _, _ := dst.Calculate().GetChanges(table.GLOBAL_RIB_NAME, 0, false) if best == nil { exitWithError(fmt.Errorf("Can't find the best %v", nlri)) } diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go index b965786f..6bbf6d39 100644 --- a/gobgp/cmd/neighbor.go +++ b/gobgp/cmd/neighbor.go @@ -769,7 +769,7 @@ func showNeighborRib(r string, name string, args []string) error { switch r { case CMD_LOCAL, CMD_ADJ_IN, CMD_ACCEPTED, CMD_REJECTED, CMD_ADJ_OUT: - if rib.Info("").NumDestination == 0 { + if rib.Info("", 0).NumDestination == 0 { peer, err := client.GetNeighbor(name, false) if err != nil { return err @@ -807,18 +807,10 @@ func showNeighborRib(r string, name string, args []string) error { switch r { case CMD_ACCEPTED: for _, p := range d.GetAllKnownPathList() { - if p.Filtered("") > table.POLICY_DIRECTION_NONE { - continue - } ps = append(ps, p) } case CMD_REJECTED: - for _, p := range d.GetAllKnownPathList() { - if p.Filtered("") == table.POLICY_DIRECTION_NONE { - continue - } - ps = append(ps, p) - } + // always nothing default: ps = d.GetAllKnownPathList() } @@ -872,8 +864,6 @@ func showNeighborPolicy(remoteIP, policyType string, indent int) error { var err error switch strings.ToLower(policyType) { - case "in": - assignment, err = client.GetRouteServerInPolicy(remoteIP) case "import": assignment, err = client.GetRouteServerImportPolicy(remoteIP) case "export": @@ -926,8 +916,6 @@ func modNeighborPolicy(remoteIP, policyType, cmdType string, args []string) erro Name: remoteIP, } switch strings.ToLower(policyType) { - case "in": - assign.Type = table.POLICY_DIRECTION_IN case "import": assign.Type = table.POLICY_DIRECTION_IMPORT case "export": diff --git a/server/fsm.go b/server/fsm.go index b38cc9a1..db3efe1f 100644 --- a/server/fsm.go +++ b/server/fsm.go @@ -897,25 +897,7 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) { return fmsg, err } - // RFC4271 9.1.2 Phase 2: Route Selection - // - // If the AS_PATH attribute of a BGP route contains an AS loop, the BGP - // route should be excluded from the Phase 2 decision function. - var asLoop bool - if attr := getPathAttrFromBGPUpdate(body, bgp.BGP_ATTR_TYPE_AS_PATH); attr != nil { - asLoop = hasOwnASLoop(h.fsm.peerInfo.LocalAS, int(h.fsm.pConf.AsPathOptions.Config.AllowOwnAs), attr.(*bgp.PathAttributeAsPath)) - } - fmsg.PathList = table.ProcessMessage(m, h.fsm.peerInfo, fmsg.timestamp) - id := h.fsm.pConf.State.NeighborAddress - for _, path := range fmsg.PathList { - if path.IsEOR() { - continue - } - if asLoop || (h.fsm.policy.ApplyPolicy(id, table.POLICY_DIRECTION_IN, path, nil) == nil) { - path.Filter(id, table.POLICY_DIRECTION_IN) - } - } fallthrough case bgp.BGP_MSG_KEEPALIVE: // if the length of h.holdTimerResetCh diff --git a/server/peer.go b/server/peer.go index 96cb4170..4be180a5 100644 --- a/server/peer.go +++ b/server/peer.go @@ -340,7 +340,7 @@ func (peer *Peer) filterpath(path, old *table.Path) *table.Path { // (*Destination) GetChanges(). dst := peer.localRib.GetDestination(path) path = nil - for _, p := range dst.GetKnownPathList(peer.TableID()) { + for _, p := range dst.GetKnownPathList(peer.TableID(), peer.AS()) { // Just take care not to send back. if peer.ID() != p.GetSource().Address.String() { path = p @@ -453,9 +453,9 @@ func (peer *Peer) getBestFromLocal(rfList []bgp.RouteFamily) ([]*table.Path, []* for _, family := range peer.toGlobalFamilies(rfList) { pl := func() []*table.Path { if peer.isAddPathSendEnabled(family) { - return peer.localRib.GetPathList(peer.TableID(), []bgp.RouteFamily{family}) + return peer.localRib.GetPathList(peer.TableID(), peer.AS(), []bgp.RouteFamily{family}) } - return peer.localRib.GetBestPathList(peer.TableID(), []bgp.RouteFamily{family}) + return peer.localRib.GetBestPathList(peer.TableID(), peer.AS(), []bgp.RouteFamily{family}) }() for _, path := range pl { if p := peer.filterpath(path, nil); p != nil { @@ -616,11 +616,16 @@ func (peer *Peer) handleUpdate(e *FsmMsg) ([]*table.Path, []bgp.RouteFamily, *bg eor = append(eor, family) continue } - if path.Filtered(peer.ID()) != table.POLICY_DIRECTION_IN { - paths = append(paths, path) - } else { - paths = append(paths, path.Clone(true)) + // RFC4271 9.1.2 Phase 2: Route Selection + // + // If the AS_PATH attribute of a BGP route contains an AS loop, the BGP + // route should be excluded from the Phase 2 decision function. + if aspath := path.GetAsPath(); aspath != nil { + if hasOwnASLoop(peer.fsm.peerInfo.LocalAS, int(peer.fsm.pConf.AsPathOptions.Config.AllowOwnAs), aspath) { + continue + } } + paths = append(paths, path) } return paths, eor, nil } diff --git a/server/server.go b/server/server.go index abd32dfa..47bebd7b 100644 --- a/server/server.go +++ b/server/server.go @@ -545,7 +545,7 @@ func (server *BgpServer) notifyPostPolicyUpdateWatcher(peer *Peer, pathList []*t server.notifyWatcher(WATCH_EVENT_TYPE_POST_UPDATE, ev) } -func dstsToPaths(id string, dsts []*table.Destination, addpath bool) ([]*table.Path, []*table.Path, [][]*table.Path) { +func dstsToPaths(id string, as uint32, dsts []*table.Destination, addpath bool) ([]*table.Path, []*table.Path, [][]*table.Path) { if table.SelectionOptions.DisableBestPathSelection { // Note: If best path selection disabled, there is no best path. return nil, nil, nil @@ -558,7 +558,7 @@ func dstsToPaths(id string, dsts []*table.Destination, addpath bool) ([]*table.P if addpath { bestList = append(bestList, dst.GetAddPathChanges(id)...) } else { - best, old, mpath := dst.GetChanges(id, false) + best, old, mpath := dst.GetChanges(id, as, false) bestList = append(bestList, best) oldList = append(oldList, old) if mpath != nil { @@ -583,7 +583,7 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil for _, rf := range families { dsts := rib.DeletePathsByPeer(peer.fsm.peerInfo, rf) if !peer.isRouteServerClient() { - gBestList, _, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts, false) + gBestList, _, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, 0, dsts, false) server.notifyBestWatcher(gBestList, mpathList) } @@ -592,9 +592,9 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil continue } if targetPeer.isAddPathSendEnabled(rf) { - bestList, _, _ = dstsToPaths(targetPeer.TableID(), dsts, true) + bestList, _, _ = dstsToPaths(targetPeer.TableID(), targetPeer.AS(), dsts, true) } else if targetPeer.isRouteServerClient() { - bestList, _, _ = dstsToPaths(targetPeer.TableID(), dsts, false) + bestList, _, _ = dstsToPaths(targetPeer.TableID(), targetPeer.AS(), dsts, false) } else { bestList = gBestList } @@ -661,30 +661,6 @@ func (server *BgpServer) notifyRecvMessageWatcher(peer *Peer, timestamp time.Tim server.notifyMessageWatcher(peer, timestamp, msg, false) } -func (server *BgpServer) RSimportPaths(peer *Peer, pathList []*table.Path) []*table.Path { - moded := make([]*table.Path, 0, len(pathList)/2) - for _, before := range pathList { - if isASLoop(peer, before) { - before.Filter(peer.ID(), table.POLICY_DIRECTION_IMPORT) - continue - } - after := server.policy.ApplyPolicy(peer.TableID(), table.POLICY_DIRECTION_IMPORT, before, nil) - if after == nil { - before.Filter(peer.ID(), table.POLICY_DIRECTION_IMPORT) - } else if after != before { - before.Filter(peer.ID(), table.POLICY_DIRECTION_IMPORT) - for _, n := range server.neighborMap { - if n == peer { - continue - } - after.Filter(n.ID(), table.POLICY_DIRECTION_IMPORT) - } - moded = append(moded, after) - } - } - return moded -} - func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { var dsts []*table.Destination @@ -702,17 +678,15 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { if peer != nil && peer.isRouteServerClient() { rib = server.rsRib - for _, path := range pathList { - path.Filter(peer.ID(), table.POLICY_DIRECTION_IMPORT) - } - moded := make([]*table.Path, 0) - for _, targetPeer := range server.neighborMap { - if !targetPeer.isRouteServerClient() || peer == targetPeer { - continue + for idx, path := range pathList { + if p := server.policy.ApplyPolicy(peer.TableID(), table.POLICY_DIRECTION_IMPORT, path, nil); p != nil { + path = p + } else { + path = path.Clone(true) } - moded = append(moded, server.RSimportPaths(targetPeer, pathList)...) + pathList[idx] = path } - dsts = rib.ProcessPaths(append(pathList, moded...)) + dsts = rib.ProcessPaths(pathList) } else { for idx, path := range pathList { var options *table.PolicyOptions @@ -752,7 +726,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { if path.IsWithdraw { candidates, _ = peer.getBestFromLocal(peer.configuredRFlist()) } else { - candidates = rib.GetBestPathList(peer.TableID(), fs) + candidates = rib.GetBestPathList(peer.TableID(), 0, fs) } paths := make([]*table.Path, 0, len(candidates)) for _, p := range candidates { @@ -777,7 +751,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { server.notifyPostPolicyUpdateWatcher(peer, pathList) dsts = rib.ProcessPaths(pathList) - gBestList, gOldList, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts, false) + gBestList, gOldList, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, 0, dsts, false) server.notifyBestWatcher(gBestList, mpathList) } @@ -805,9 +779,9 @@ func (server *BgpServer) propagateUpdateToNeighbors(peer *Peer, dsts []*table.De continue } if targetPeer.isAddPathSendEnabled(family) { - bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), l, true) + bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), targetPeer.AS(), l, true) } else if targetPeer.isRouteServerClient() { - bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), l, false) + bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), targetPeer.AS(), l, false) } else { bestList = gBestList oldList = gOldList @@ -1293,7 +1267,7 @@ func (server *BgpServer) fixupApiPath(vrfId string, pathList []*table.Path) erro switch r := nlri.RouteTypeData.(type) { case *bgp.EVPNMacIPAdvertisementRoute: // MAC Mobility Extended Community - paths := server.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, []bgp.RouteFamily{bgp.RF_EVPN}) + paths := server.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, 0, []bgp.RouteFamily{bgp.RF_EVPN}) if m := getMacMobilityExtendedCommunity(r.ETag, r.MacAddress, paths); m != nil { path.SetExtCommunities([]bgp.ExtendedCommunityInterface{m}, false) } @@ -1347,7 +1321,7 @@ func (s *BgpServer) DeletePath(uuid []byte, f bgp.RouteFamily, vrfId string, pat if len(uuid) > 0 { // Delete locally generated path which has the given UUID path := func() *table.Path { - for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, s.globalRib.GetRFlist()) { + for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, 0, s.globalRib.GetRFlist()) { if path.IsLocal() && len(path.UUID()) > 0 && bytes.Equal(path.UUID().Bytes(), uuid) { return path } @@ -1364,7 +1338,7 @@ func (s *BgpServer) DeletePath(uuid []byte, f bgp.RouteFamily, vrfId string, pat if f != 0 { families = []bgp.RouteFamily{f} } - for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, families) { + for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, 0, families) { if path.IsLocal() { deletePathList = append(deletePathList, path.Clone(true)) } @@ -1386,7 +1360,7 @@ func (s *BgpServer) UpdatePath(vrfId string, pathList []*table.Path) error { return err } dsts := s.globalRib.ProcessPaths(pathList) - gBestList, gOldList, gMPathList := dstsToPaths(table.GLOBAL_RIB_NAME, dsts, false) + gBestList, gOldList, gMPathList := dstsToPaths(table.GLOBAL_RIB_NAME, 0, dsts, false) s.notifyBestWatcher(gBestList, gMPathList) s.propagateUpdateToNeighbors(nil, dsts, gBestList, gOldList) return nil @@ -1501,36 +1475,16 @@ func (s *BgpServer) softResetIn(addr string, family bgp.RouteFamily) error { families = peer.configuredRFlist() } for _, path := range peer.adjRibIn.PathList(families, false) { - exResult := path.Filtered(peer.ID()) - path.Filter(peer.ID(), table.POLICY_DIRECTION_NONE) - // RFC4271 9.1.2 Phase 2: Route Selection // // If the AS_PATH attribute of a BGP route contains an AS loop, the BGP // route should be excluded from the Phase 2 decision function. - var asLoop bool if aspath := path.GetAsPath(); aspath != nil { - asLoop = hasOwnASLoop(peer.fsm.peerInfo.LocalAS, int(peer.fsm.pConf.AsPathOptions.Config.AllowOwnAs), aspath) - } - - if !asLoop && s.policy.ApplyPolicy(peer.ID(), table.POLICY_DIRECTION_IN, path, nil) != nil { - pathList = append(pathList, path.Clone(false)) - // this path still in rib's - // knownPathList. We can't - // drop - // table.POLICY_DIRECTION_IMPORT - // flag here. Otherwise, this - // path could be the old best - // path. - if peer.isRouteServerClient() { - path.Filter(peer.ID(), table.POLICY_DIRECTION_IMPORT) - } - } else { - path.Filter(peer.ID(), table.POLICY_DIRECTION_IN) - if exResult != table.POLICY_DIRECTION_IN { - pathList = append(pathList, path.Clone(true)) + if hasOwnASLoop(peer.fsm.peerInfo.LocalAS, int(peer.fsm.pConf.AsPathOptions.Config.AllowOwnAs), aspath) { + continue } } + pathList = append(pathList, path.Clone(false)) } peer.adjRibIn.RefreshAcceptedNumber(families) s.propagateUpdate(peer, pathList) @@ -1626,6 +1580,7 @@ func (s *BgpServer) GetRib(addr string, family bgp.RouteFamily, prefixes []*tabl err = s.mgmtOperation(func() error { m := s.globalRib id := table.GLOBAL_RIB_NAME + as := uint32(0) if len(addr) > 0 { peer, ok := s.neighborMap[addr] if !ok { @@ -1635,6 +1590,7 @@ func (s *BgpServer) GetRib(addr string, family bgp.RouteFamily, prefixes []*tabl return fmt.Errorf("Neighbor %v doesn't have local rib", addr) } id = peer.ID() + as = peer.AS() m = s.rsRib } af := bgp.RouteFamily(family) @@ -1642,7 +1598,7 @@ func (s *BgpServer) GetRib(addr string, family bgp.RouteFamily, prefixes []*tabl if !ok { return fmt.Errorf("address family: %s not supported", af) } - rib, err = tbl.Select(table.TableSelectOption{ID: id, LookupPrefixes: prefixes}) + rib, err = tbl.Select(table.TableSelectOption{ID: id, AS: as, LookupPrefixes: prefixes}) return err }, true) return @@ -1681,6 +1637,7 @@ func (s *BgpServer) GetAdjRib(addr string, family bgp.RouteFamily, in bool, pref return fmt.Errorf("Neighbor that has %v doesn't exist.", addr) } id := peer.ID() + as := peer.AS() var adjRib *table.AdjRib if in { @@ -1690,7 +1647,7 @@ func (s *BgpServer) GetAdjRib(addr string, family bgp.RouteFamily, in bool, pref accepted, _ := peer.getBestFromLocal(peer.configuredRFlist()) adjRib.Update(accepted) } - rib, err = adjRib.Select(family, false, table.TableSelectOption{ID: id, LookupPrefixes: prefixes}) + rib, err = adjRib.Select(family, false, table.TableSelectOption{ID: id, AS: as, LookupPrefixes: prefixes}) return err }, true) return @@ -1700,6 +1657,7 @@ func (s *BgpServer) GetRibInfo(addr string, family bgp.RouteFamily) (info *table err = s.mgmtOperation(func() error { m := s.globalRib id := table.GLOBAL_RIB_NAME + as := uint32(0) if len(addr) > 0 { peer, ok := s.neighborMap[addr] if !ok { @@ -1709,9 +1667,10 @@ func (s *BgpServer) GetRibInfo(addr string, family bgp.RouteFamily) (info *table return fmt.Errorf("Neighbor %v doesn't have local rib", addr) } id = peer.ID() + as = peer.AS() m = s.rsRib } - info, err = m.TableInfo(id, family) + info, err = m.TableInfo(id, as, family) return err }, true) return @@ -1842,20 +1801,6 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error { } peer := NewPeer(&server.bgpConfig.Global, c, rib, server.policy) server.policy.Reset(nil, map[string]config.ApplyPolicy{peer.ID(): c.ApplyPolicy}) - if peer.isRouteServerClient() { - pathList := make([]*table.Path, 0) - rfList := peer.configuredRFlist() - for _, p := range server.neighborMap { - if !p.isRouteServerClient() { - continue - } - pathList = append(pathList, p.getAccepted(rfList)...) - } - moded := server.RSimportPaths(peer, pathList) - if len(moded) > 0 { - server.rsRib.ProcessPaths(moded) - } - } server.neighborMap[addr] = peer if name := c.Config.PeerGroup; name != "" { server.peerGroupMap[name].AddMember(*c) @@ -2577,6 +2522,7 @@ func (w *Watcher) Generate(t WatchEventType) error { w.notify(&WatchEventAdjIn{PathList: clonePathList(pathList)}) case WATCH_EVENT_TYPE_TABLE: rib := w.s.globalRib + as := uint32(0) id := table.GLOBAL_RIB_NAME if len(w.opts.tableName) > 0 { peer, ok := w.s.neighborMap[w.opts.tableName] @@ -2587,6 +2533,7 @@ func (w *Watcher) Generate(t WatchEventType) error { return fmt.Errorf("Neighbor %v doesn't have local rib", w.opts.tableName) } id = peer.ID() + as = peer.AS() rib = w.s.rsRib } @@ -2594,7 +2541,7 @@ func (w *Watcher) Generate(t WatchEventType) error { pathList := make(map[string][]*table.Path) for _, t := range rib.Tables { for _, dst := range t.GetSortedDestinations() { - if paths := dst.GetKnownPathList(id); len(paths) > 0 { + if paths := dst.GetKnownPathList(id, as); len(paths) > 0 { pathList[dst.GetNlri().String()] = clonePathList(paths) } } @@ -2698,7 +2645,7 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { } if w.opts.initBest && s.active() == nil { w.notify(&WatchEventBestPath{ - PathList: s.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, nil), + PathList: s.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, 0, nil), MultiPathList: s.globalRib.GetBestMultiPathList(table.GLOBAL_RIB_NAME, nil), }) } @@ -2753,7 +2700,7 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { continue } pathsByPeer := make(map[*table.PeerInfo][]*table.Path) - for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, []bgp.RouteFamily{rf}) { + for _, path := range s.globalRib.GetPathList(table.GLOBAL_RIB_NAME, 0, []bgp.RouteFamily{rf}) { pathsByPeer[path.GetSource()] = append(pathsByPeer[path.GetSource()], path) } for peerInfo, paths := range pathsByPeer { diff --git a/server/server_test.go b/server/server_test.go index 82a926ae..7eaea7b7 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -166,7 +166,7 @@ func TestMonitor(test *testing.T) { if err != nil { log.Fatal(err) } - if len(rib.GetKnownPathList("")) > 0 { + if len(rib.GetKnownPathList("", 0)) > 0 { break } time.Sleep(1) @@ -269,7 +269,7 @@ func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (* } func process(rib *table.TableManager, l []*table.Path) (*table.Path, *table.Path) { - news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, rib.ProcessPaths(l), false) + news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, 0, rib.ProcessPaths(l), false) if len(news) != 1 { panic("can't handle multiple paths") } diff --git a/table/adj.go b/table/adj.go index 98c714e6..d16f8d76 100644 --- a/table/adj.go +++ b/table/adj.go @@ -51,23 +51,12 @@ func (adj *AdjRib) Update(pathList []*Path) { if path.IsWithdraw { if found { delete(adj.table[rf], key) - if old.Filtered(adj.id) != POLICY_DIRECTION_IN { - adj.accepted[rf]-- - } + adj.accepted[rf]-- } } else { - n := path.Filtered(adj.id) if found { - o := old.Filtered(adj.id) - if o == POLICY_DIRECTION_IN && n == POLICY_DIRECTION_NONE { - adj.accepted[rf]++ - } else if o != POLICY_DIRECTION_IN && n == POLICY_DIRECTION_IN { - adj.accepted[rf]-- - } } else { - if n == POLICY_DIRECTION_NONE { - adj.accepted[rf]++ - } + adj.accepted[rf]++ } if found && old.Equal(path) { path.setTimestamp(old.GetTimestamp()) @@ -79,12 +68,7 @@ func (adj *AdjRib) Update(pathList []*Path) { func (adj *AdjRib) RefreshAcceptedNumber(rfList []bgp.RouteFamily) { for _, rf := range rfList { - adj.accepted[rf] = 0 - for _, p := range adj.table[rf] { - if p.Filtered(adj.id) != POLICY_DIRECTION_IN { - adj.accepted[rf]++ - } - } + adj.accepted[rf] = len(adj.table[rf]) } } @@ -92,9 +76,6 @@ func (adj *AdjRib) PathList(rfList []bgp.RouteFamily, accepted bool) []*Path { pathList := make([]*Path, 0, adj.Count(rfList)) for _, rf := range rfList { for _, rr := range adj.table[rf] { - if accepted && rr.Filtered(adj.id) == POLICY_DIRECTION_IN { - continue - } pathList = append(pathList, rr) } } @@ -137,9 +118,7 @@ func (adj *AdjRib) DropStale(rfList []bgp.RouteFamily) []*Path { for _, p := range table { if p.IsStale() { delete(table, p.getPrefix()) - if p.Filtered(adj.id) == POLICY_DIRECTION_NONE { - adj.accepted[rf]-- - } + adj.accepted[rf]-- pathList = append(pathList, p.Clone(true)) } } diff --git a/table/destination.go b/table/destination.go index fd32371d..32169f59 100644 --- a/table/destination.go +++ b/table/destination.go @@ -216,34 +216,55 @@ func (dd *Destination) GetAllKnownPathList() []*Path { return dd.knownPathList } -func (dd *Destination) GetKnownPathList(id string) []*Path { +func rsFilter(id string, as uint32, path *Path) bool { + isASLoop := func(as uint32, path *Path) bool { + for _, v := range path.GetAsList() { + if as == v { + return true + } + } + return false + } + + if id != GLOBAL_RIB_NAME && (path.GetSource().Address.String() == id || isASLoop(as, path)) { + return true + } + return false +} + +func (dd *Destination) GetKnownPathList(id string, as uint32) []*Path { list := make([]*Path, 0, len(dd.knownPathList)) for _, p := range dd.knownPathList { - if p.Filtered(id) == POLICY_DIRECTION_NONE { - list = append(list, p) + if rsFilter(id, as, p) { + continue } + list = append(list, p) } return list } -func getBestPath(id string, pathList *paths) *Path { +func getBestPath(id string, as uint32, pathList *paths) *Path { for _, p := range *pathList { - if p.Filtered(id) == POLICY_DIRECTION_NONE && !p.IsNexthopInvalid { + if rsFilter(id, as, p) { + continue + } + + if !p.IsNexthopInvalid { return p } } return nil } -func (dd *Destination) GetBestPath(id string) *Path { - return getBestPath(id, &dd.knownPathList) +func (dd *Destination) GetBestPath(id string, as uint32) *Path { + return getBestPath(id, as, &dd.knownPathList) } func getMultiBestPath(id string, pathList *paths) []*Path { list := make([]*Path, 0, len(*pathList)) var best *Path for _, p := range *pathList { - if p.Filtered(id) == POLICY_DIRECTION_NONE && !p.IsNexthopInvalid { + if !p.IsNexthopInvalid { if best == nil { best = p list = append(list, p) @@ -270,10 +291,10 @@ func (dd *Destination) GetAddPathChanges(id string) []*Path { return l } -func (dd *Destination) GetChanges(id string, peerDown bool) (*Path, *Path, []*Path) { +func (dd *Destination) GetChanges(id string, as uint32, peerDown bool) (*Path, *Path, []*Path) { best, old := func(id string) (*Path, *Path) { - old := getBestPath(id, &dd.oldKnownPathList) - best := dd.GetBestPath(id) + old := getBestPath(id, as, &dd.oldKnownPathList) + best := dd.GetBestPath(id, as) if best != nil && best.Equal(old) { // RFC4684 3.2. Intra-AS VPN Route Distribution // When processing RT membership NLRIs received from internal iBGP @@ -1012,6 +1033,7 @@ func (dest *Destination) String() string { type DestinationSelectOption struct { ID string + AS uint32 VRF *Vrf adj bool Best bool @@ -1028,6 +1050,7 @@ func (old *Destination) Select(option ...DestinationSelectOption) *Destination { adj := false best := false mp := false + as := uint32(0) for _, o := range option { if o.ID != "" { id = o.ID @@ -1038,12 +1061,13 @@ func (old *Destination) Select(option ...DestinationSelectOption) *Destination { adj = o.adj best = o.Best mp = o.MultiPath + as = o.AS } var paths []*Path if adj { paths = old.knownPathList } else { - paths = old.GetKnownPathList(id) + paths = old.GetKnownPathList(id, as) if vrf != nil { ps := make([]*Path, 0, len(paths)) for _, p := range paths { @@ -1077,7 +1101,6 @@ func (old *Destination) Select(option ...DestinationSelectOption) *Destination { new := NewDestination(old.nlri, 0) for _, path := range paths { p := path.Clone(path.IsWithdraw) - p.Filter("", path.Filtered(id)) new.knownPathList = append(new.knownPathList, p) } return new diff --git a/table/destination_test.go b/table/destination_test.go index 48430bd6..f488d4ac 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -66,47 +66,6 @@ func TestDestinationGetNlri(t *testing.T) { assert.Equal(t, r_nlri, nlri) } -func TestCalculate(t *testing.T) { - origin := bgp.NewPathAttributeOrigin(0) - aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} - aspath := bgp.NewPathAttributeAsPath(aspathParam) - nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") - med := bgp.NewPathAttributeMultiExitDisc(0) - pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} - nlri := bgp.NewIPAddrPrefix(24, "10.10.0.101") - updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) - peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} - path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] - path1.Filter("1", POLICY_DIRECTION_IMPORT) - - action := &AsPathPrependAction{ - asn: 100, - repeat: 10, - } - - path2 := action.Apply(path1.Clone(false), nil) - path1.Filter("2", POLICY_DIRECTION_IMPORT) - path2.Filter("1", POLICY_DIRECTION_IMPORT) - - d := NewDestination(nlri, 0) - d.AddNewPath(path1) - d.AddNewPath(path2) - - d.Calculate() - - assert.Equal(t, len(d.GetKnownPathList("1")), 0) - assert.Equal(t, len(d.GetKnownPathList("2")), 1) - assert.Equal(t, len(d.knownPathList), 2) - - d.AddWithdraw(path1.Clone(true)) - - d.Calculate() - - assert.Equal(t, len(d.GetKnownPathList("1")), 0) - assert.Equal(t, len(d.GetKnownPathList("2")), 0) - assert.Equal(t, len(d.knownPathList), 0) -} - func TestCalculate2(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) @@ -162,63 +121,6 @@ func TestCalculate2(t *testing.T) { assert.Equal(t, len(d.knownPathList), 3) } -func TestImplicitWithdrawCalculate(t *testing.T) { - origin := bgp.NewPathAttributeOrigin(0) - aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} - aspath := bgp.NewPathAttributeAsPath(aspathParam) - nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") - med := bgp.NewPathAttributeMultiExitDisc(0) - pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} - nlri := bgp.NewIPAddrPrefix(24, "10.10.0.101") - updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) - peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} - path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] - path1.Filter("1", POLICY_DIRECTION_IMPORT) - - // suppose peer2 has import policy to prepend as-path - action := &AsPathPrependAction{ - asn: 100, - repeat: 1, - } - - path2 := action.Apply(path1.Clone(false), nil) - path1.Filter("2", POLICY_DIRECTION_IMPORT) - path2.Filter("1", POLICY_DIRECTION_IMPORT) - path2.Filter("3", POLICY_DIRECTION_IMPORT) - - d := NewDestination(nlri, 0) - d.AddNewPath(path1) - d.AddNewPath(path2) - - d.Calculate() - - assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator - assert.Equal(t, len(d.GetKnownPathList("2")), 1) - assert.Equal(t, d.GetKnownPathList("2")[0].GetAsString(), "100 65001") // peer "2" has modified path {100, 65001} - assert.Equal(t, len(d.GetKnownPathList("3")), 1) - assert.Equal(t, d.GetKnownPathList("3")[0].GetAsString(), "65001") // peer "3" has original path {65001} - assert.Equal(t, len(d.knownPathList), 2) - - // say, we removed peer2's import policy and - // peer1 advertised new path with the same prefix - aspathParam = []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001, 65002})} - aspath = bgp.NewPathAttributeAsPath(aspathParam) - pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med} - updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) - path3 := ProcessMessage(updateMsg, peer1, time.Now())[0] - path3.Filter("1", POLICY_DIRECTION_IMPORT) - - d.AddNewPath(path3) - d.Calculate() - - assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator - assert.Equal(t, len(d.GetKnownPathList("2")), 1) - assert.Equal(t, d.GetKnownPathList("2")[0].GetAsString(), "65001 65002") // peer "2" has new original path {65001, 65002} - assert.Equal(t, len(d.GetKnownPathList("3")), 1) - assert.Equal(t, d.GetKnownPathList("3")[0].GetAsString(), "65001 65002") // peer "3" has new original path {65001, 65002} - assert.Equal(t, len(d.knownPathList), 1) -} - func TestMedTieBreaker(t *testing.T) { nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0") @@ -297,7 +199,7 @@ func TestTimeTieBreaker(t *testing.T) { d.Calculate() assert.Equal(t, len(d.knownPathList), 2) - assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{2, 2, 2, 2})) // path from peer2 win + assert.Equal(t, true, d.GetBestPath("", 0).GetSource().ID.Equal(net.IP{2, 2, 2, 2})) // path from peer2 win // this option disables tie breaking by age SelectionOptions.ExternalCompareRouterId = true @@ -308,7 +210,7 @@ func TestTimeTieBreaker(t *testing.T) { d.Calculate() assert.Equal(t, len(d.knownPathList), 2) - assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{1, 1, 1, 1})) // path from peer1 win + assert.Equal(t, true, d.GetBestPath("", 0).GetSource().ID.Equal(net.IP{1, 1, 1, 1})) // path from peer1 win } func DestCreatePeer() []*PeerInfo { @@ -462,20 +364,20 @@ func TestMultipath(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - best, old, multi := d.Calculate().GetChanges(GLOBAL_RIB_NAME, false) + best, old, multi := d.Calculate().GetChanges(GLOBAL_RIB_NAME, 0, false) assert.NotNil(t, best) assert.Equal(t, old, (*Path)(nil)) assert.Equal(t, len(multi), 2) - assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) + assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME, 0)), 2) path3 := path2.Clone(true) d.AddWithdraw(path3) dd := d.Calculate() - best, old, multi = dd.GetChanges(GLOBAL_RIB_NAME, false) + best, old, multi = dd.GetChanges(GLOBAL_RIB_NAME, 0, false) assert.Nil(t, best) assert.Equal(t, old, path1) assert.Equal(t, len(multi), 1) - assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 1) + assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME, 0)), 1) peer3 := &PeerInfo{AS: 3, Address: net.IP{3, 3, 3, 3}, ID: net.IP{3, 3, 3, 3}} med = bgp.NewPathAttributeMultiExitDisc(50) @@ -490,10 +392,10 @@ func TestMultipath(t *testing.T) { path4 := ProcessMessage(updateMsg, peer3, time.Now())[0] d.AddNewPath(path4) - best, _, multi = d.Calculate().GetChanges(GLOBAL_RIB_NAME, false) + best, _, multi = d.Calculate().GetChanges(GLOBAL_RIB_NAME, 0, false) assert.NotNil(t, best) assert.Equal(t, len(multi), 1) - assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) + assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME, 0)), 2) nexthop = bgp.NewPathAttributeNextHop("192.168.150.2") pathAttributes = []bgp.PathAttributeInterface{ @@ -506,10 +408,10 @@ func TestMultipath(t *testing.T) { path5 := ProcessMessage(updateMsg, peer2, time.Now())[0] d.AddNewPath(path5) - best, _, multi = d.Calculate().GetChanges(GLOBAL_RIB_NAME, false) + best, _, multi = d.Calculate().GetChanges(GLOBAL_RIB_NAME, 0, false) assert.NotNil(t, best) assert.Equal(t, len(multi), 2) - assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 3) + assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME, 0)), 3) UseMultiplePaths.Enabled = false } diff --git a/table/path.go b/table/path.go index 0c201447..4704758e 100644 --- a/table/path.go +++ b/table/path.go @@ -146,7 +146,6 @@ type Path struct { reason BestPathReason parent *Path dels []bgp.BGPAttrType - filtered map[string]PolicyDirection VrfIds []uint16 // For BGP Nexthop Tracking, this field shows if nexthop is invalidated by IGP. IsNexthopInvalid bool @@ -170,7 +169,6 @@ func NewPath(source *PeerInfo, nlri bgp.AddrPrefixInterface, isWithdraw bool, pa }, IsWithdraw: isWithdraw, pathAttrs: pattrs, - filtered: make(map[string]PolicyDirection), } } @@ -182,7 +180,6 @@ func NewEOR(family bgp.RouteFamily) *Path { nlri: nlri, eor: true, }, - filtered: make(map[string]PolicyDirection), } } @@ -339,7 +336,6 @@ func (path *Path) Clone(isWithdraw bool) *Path { return &Path{ parent: path, IsWithdraw: isWithdraw, - filtered: make(map[string]PolicyDirection), IsNexthopInvalid: path.IsNexthopInvalid, } } @@ -396,14 +392,6 @@ func (path *Path) AssignNewUUID() { path.OriginInfo().uuid, _ = uuid.NewV4() } -func (path *Path) Filter(id string, reason PolicyDirection) { - path.filtered[id] = reason -} - -func (path *Path) Filtered(id string) PolicyDirection { - return path.filtered[id] -} - func (path *Path) GetRouteFamily() bgp.RouteFamily { return bgp.AfiSafiToRouteFamily(path.OriginInfo().nlri.AFI(), path.OriginInfo().nlri.SAFI()) } @@ -1094,7 +1082,6 @@ func (path *Path) MarshalJSON() ([]byte, error) { SourceID net.IP `json:"source-id,omitempty"` NeighborIP net.IP `json:"neighbor-ip,omitempty"` Stale bool `json:"stale,omitempty"` - Filtered bool `json:"filtered,omitempty"` UUID string `json:"uuid,omitempty"` ID uint32 `json:"id,omitempty"` }{ @@ -1106,7 +1093,6 @@ func (path *Path) MarshalJSON() ([]byte, error) { SourceID: path.GetSource().ID, NeighborIP: path.GetSource().Address, Stale: path.IsStale(), - Filtered: path.Filtered("") > POLICY_DIRECTION_NONE, UUID: path.UUID().String(), ID: path.GetNlri().PathIdentifier(), }) diff --git a/table/policy.go b/table/policy.go index a7d02b06..299a976b 100644 --- a/table/policy.go +++ b/table/policy.go @@ -2863,9 +2863,7 @@ func (r *RoutingPolicy) ApplyPolicy(id string, dir PolicyDirection, before *Path if before == nil { return nil } - if filtered := before.Filtered(id); filtered > POLICY_DIRECTION_NONE && filtered < dir { - return nil - } + if before.IsWithdraw { return before } diff --git a/table/table.go b/table/table.go index 893c9343..6662376e 100644 --- a/table/table.go +++ b/table/table.go @@ -41,6 +41,7 @@ type LookupPrefix struct { type TableSelectOption struct { ID string + AS uint32 LookupPrefixes []*LookupPrefix VRF *Vrf adj bool @@ -328,10 +329,10 @@ func (t *Table) tableKey(nlri bgp.AddrPrefixInterface) string { return nlri.String() } -func (t *Table) Bests(id string) []*Path { +func (t *Table) Bests(id string, as uint32) []*Path { paths := make([]*Path, 0, len(t.destinations)) for _, dst := range t.destinations { - path := dst.GetBestPath(id) + path := dst.GetBestPath(id, as) if path != nil { paths = append(paths, path) } @@ -350,10 +351,10 @@ func (t *Table) MultiBests(id string) [][]*Path { return paths } -func (t *Table) GetKnownPathList(id string) []*Path { +func (t *Table) GetKnownPathList(id string, as uint32) []*Path { paths := make([]*Path, 0, len(t.destinations)) for _, dst := range t.destinations { - paths = append(paths, dst.GetKnownPathList(id)...) + paths = append(paths, dst.GetKnownPathList(id, as)...) } return paths } @@ -365,6 +366,7 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) { prefixes := make([]*LookupPrefix, 0, len(option)) best := false mp := false + as := uint32(0) for _, o := range option { if o.ID != "" { id = o.ID @@ -376,8 +378,9 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) { prefixes = append(prefixes, o.LookupPrefixes...) best = o.Best mp = o.MultiPath + as = o.AS } - dOption := DestinationSelectOption{ID: id, VRF: vrf, adj: adj, Best: best, MultiPath: mp} + dOption := DestinationSelectOption{ID: id, AS: as, VRF: vrf, adj: adj, Best: best, MultiPath: mp} dsts := make(map[string]*Destination) if len(prefixes) != 0 { @@ -471,10 +474,10 @@ type TableInfo struct { NumAccepted int } -func (t *Table) Info(id string) *TableInfo { +func (t *Table) Info(id string, as uint32) *TableInfo { var numD, numP int for _, d := range t.destinations { - ps := d.GetKnownPathList(id) + ps := d.GetKnownPathList(id, as) if len(ps) > 0 { numD += 1 numP += len(ps) diff --git a/table/table_manager.go b/table/table_manager.go index 7341df17..0e980404 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -255,7 +255,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(GLOBAL_RIB_NAME, []bgp.RouteFamily{bgp.RF_EVPN}) { + for _, path2 := range manager.GetPathList(GLOBAL_RIB_NAME, 0, []bgp.RouteFamily{bgp.RF_EVPN}) { if !path2.IsLocal() || path2.GetNlri().(*bgp.EVPNNLRI).RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT { continue } @@ -307,14 +307,14 @@ func (manager *TableManager) getDestinationCount(rfList []bgp.RouteFamily) int { return count } -func (manager *TableManager) GetBestPathList(id string, rfList []bgp.RouteFamily) []*Path { +func (manager *TableManager) GetBestPathList(id string, as uint32, rfList []bgp.RouteFamily) []*Path { if SelectionOptions.DisableBestPathSelection { // Note: If best path selection disabled, there is no best path. return nil } paths := make([]*Path, 0, manager.getDestinationCount(rfList)) for _, t := range manager.tables(rfList...) { - paths = append(paths, t.Bests(id)...) + paths = append(paths, t.Bests(id, as)...) } return paths } @@ -332,10 +332,10 @@ func (manager *TableManager) GetBestMultiPathList(id string, rfList []bgp.RouteF return paths } -func (manager *TableManager) GetPathList(id string, rfList []bgp.RouteFamily) []*Path { +func (manager *TableManager) GetPathList(id string, as uint32, rfList []bgp.RouteFamily) []*Path { paths := make([]*Path, 0, manager.getDestinationCount(rfList)) for _, t := range manager.tables(rfList...) { - paths = append(paths, t.GetKnownPathList(id)...) + paths = append(paths, t.GetKnownPathList(id, as)...) } return paths } @@ -344,7 +344,7 @@ func (manager *TableManager) GetPathListWithNexthop(id string, rfList []bgp.Rout paths := make([]*Path, 0, manager.getDestinationCount(rfList)) for _, rf := range rfList { if t, ok := manager.Tables[rf]; ok { - for _, path := range t.GetKnownPathList(id) { + for _, path := range t.GetKnownPathList(id, 0) { if path.GetNexthop().Equal(nexthop) { paths = append(paths, path) } @@ -366,10 +366,10 @@ func (manager *TableManager) GetDestination(path *Path) *Destination { return t.GetDestination(path.getPrefix()) } -func (manager *TableManager) TableInfo(id string, family bgp.RouteFamily) (*TableInfo, error) { +func (manager *TableManager) TableInfo(id string, as uint32, family bgp.RouteFamily) (*TableInfo, error) { t, ok := manager.Tables[family] if !ok { return nil, fmt.Errorf("address family %s is not configured", family) } - return t.Info(id), nil + return t.Info(id, as), nil } diff --git a/table/table_manager_test.go b/table/table_manager_test.go index cde35a4f..3e2d1e74 100644 --- a/table/table_manager_test.go +++ b/table/table_manager_test.go @@ -32,7 +32,7 @@ import ( func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) { pathList := make([]*Path, 0) for _, d := range manager.ProcessPaths(ProcessMessage(message, fromPeer, time.Now())) { - b, _, _ := d.GetChanges(GLOBAL_RIB_NAME, false) + b, _, _ := d.GetChanges(GLOBAL_RIB_NAME, 0, false) pathList = append(pathList, b) } return pathList, nil diff --git a/test/scenario_test/route_server_ipv4_v6_test.py b/test/scenario_test/route_server_ipv4_v6_test.py index 07f77e4a..ce17e18c 100644 --- a/test/scenario_test/route_server_ipv4_v6_test.py +++ b/test/scenario_test/route_server_ipv4_v6_test.py @@ -143,7 +143,7 @@ class GoBGPIPv6Test(unittest.TestCase): def test_04_add_in_policy_to_reject_all(self): for q in self.gobgp.peers.itervalues(): - self.gobgp.local('gobgp neighbor {0} policy in set default reject'.format(q['neigh_addr'].split('/')[0])) + self.gobgp.local('gobgp neighbor {0} policy import set default reject'.format(q['neigh_addr'].split('/')[0])) def test_05_check_ipv4_peer_rib(self): self.check_gobgp_local_rib(self.ipv4s, 'ipv4') @@ -159,12 +159,10 @@ class GoBGPIPv6Test(unittest.TestCase): def test_08_check_rib(self): for q in self.ipv4s.itervalues(): - self.assertTrue(all(p['filtered'] for p in self.gobgp.get_adj_rib_in(q))) self.assertTrue(len(self.gobgp.get_adj_rib_out(q)) == 0) self.assertTrue(len(q.get_global_rib()) == len(q.routes)) for q in self.ipv6s.itervalues(): - self.assertTrue(all(p['filtered'] for p in self.gobgp.get_adj_rib_in(q, rf='ipv6'))) self.assertTrue(len(self.gobgp.get_adj_rib_out(q, rf='ipv6')) == 0) self.assertTrue(len(q.get_global_rib(rf='ipv6')) == len(q.routes)) diff --git a/test/scenario_test/route_server_policy_grpc_test.py b/test/scenario_test/route_server_policy_grpc_test.py index 41114d11..63ec6558 100644 --- a/test/scenario_test/route_server_policy_grpc_test.py +++ b/test/scenario_test/route_server_policy_grpc_test.py @@ -2119,205 +2119,6 @@ class ExportPolicyMedSub(object): lookup_scenario("ExportPolicyMedSub").check2(env) -@register_scenario -class InPolicyReject(object): - """ - No.31 in-policy reject test - ---------------- - e1 ->r1(community=65100:10) -> x | -> q1-rib -> | -> r2 --> q1 - r2(192.168.10.0/24) -> o | | - | -> q2-rib -> | -> r2 --> q2 - ---------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - - g1.local('gobgp policy community add cs0 65100:10') - g1.local('gobgp policy statement st0 add condition community cs0') - g1.local('gobgp policy statement st0 add action reject') - g1.local('gobgp policy add policy0 st0') - g1.local('gobgp neighbor {0} policy in add policy0'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) - - e1.add_route('192.168.100.0/24', community=['65100:10']) - e1.add_route('192.168.10.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 2) - wait_for(lambda: len(g1.get_local_rib(q1)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) - wait_for(lambda: len(q1.get_global_rib()) == 1) - wait_for(lambda: len(g1.get_local_rib(q2)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) - wait_for(lambda: len(q2.get_global_rib()) == 1) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyReject").boot(env) - lookup_scenario("InPolicyReject").setup(env) - lookup_scenario("InPolicyReject").check(env) - - -@register_scenario -class InPolicyAccept(object): - """ - No.32 in-policy accept test - ---------------- - e1 ->r1(community=65100:10) -> x | -> q1-rib -> | -> r2 --> q1 - r2(192.168.10.0/24) -> o | | - | -> q2-rib -> | -> r2 --> q2 - ---------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - - g1.local('gobgp policy community add cs0 65100:10') - g1.local('gobgp policy statement st0 add condition community cs0') - g1.local('gobgp policy statement st0 add action accept') - g1.local('gobgp policy add policy0 st0') - g1.local('gobgp neighbor {0} policy in add policy0 default reject'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) - - e1.add_route('192.168.100.0/24', community=['65100:10']) - e1.add_route('192.168.10.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - lookup_scenario('InPolicyReject').check(env) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyAccept").boot(env) - lookup_scenario("InPolicyAccept").setup(env) - lookup_scenario("InPolicyAccept").check(env) - - -@register_scenario -class InPolicyUpdate(object): - """ - No.35 in-policy update test - r1:192.168.2.0 - r2:192.168.20.0 - r3:192.168.200.0 - ------------------------------------- - | q1 | - e1 ->(r1,r2,r3)-> | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q1 - | | - | q2 | - | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 - ------------------------------------- - | - update distribute policy - | - V - ------------------------------------------- - | q1 | - e1 ->(r1,r2,r3)-> | ->(r1,r2)-> rib ->(r1,r2)-> adj-rib-out | ->(r1,r2)-> q1 - | | - | q2 | - | ->(r1,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 - ------------------------------------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - - g1.local('gobgp policy prefix add ps0 192.168.20.0/24') - g1.local('gobgp policy prefix add ps0 192.168.200.0/24') - g1.local('gobgp policy neighbor add ns0 {0}'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) - g1.local('gobgp policy statement st0 add condition prefix ps0') - g1.local('gobgp policy statement st0 add condition neighbor ns0') - g1.local('gobgp policy statement st0 add action reject') - g1.local('gobgp policy add policy0 st0') - g1.local('gobgp neighbor {0} policy in add policy0'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) - - e1.add_route('192.168.2.0/24') - e1.add_route('192.168.20.0/24') - e1.add_route('192.168.200.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3) - wait_for(lambda: len(g1.get_local_rib(q1)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) - wait_for(lambda: len(q1.get_global_rib()) == 1) - wait_for(lambda: len(g1.get_local_rib(q2)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) - wait_for(lambda: len(q2.get_global_rib()) == 1) - - @staticmethod - def setup2(env): - g1 = env.g1 - e1 = env.e1 - # q1 = env.q1 - # q2 = env.q2 - g1.clear_policy() - - g1.local('gobgp policy prefix del ps0 192.168.200.0/24') - g1.softreset(e1) - - @staticmethod - def check2(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3) - wait_for(lambda: len(g1.get_local_rib(q1)) == 2) - wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) - wait_for(lambda: len(q1.get_global_rib()) == 2) - wait_for(lambda: len(g1.get_local_rib(q2)) == 2) - wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) - wait_for(lambda: len(q2.get_global_rib()) == 2) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyUpdate").boot(env) - lookup_scenario("InPolicyUpdate").setup(env) - lookup_scenario("InPolicyUpdate").check(env) - lookup_scenario("InPolicyUpdate").setup2(env) - lookup_scenario("InPolicyUpdate").check2(env) - - @register_scenario class ExportPolicyAsPathPrepend(object): """ @@ -2623,52 +2424,6 @@ class ImportPolicyExCommunityTargetCondition(object): lookup_scenario("ImportPolicyExCommunityTargetCondition").check(env) -@register_scenario -class InPolicyPrefixCondition(object): - """ - No.42 prefix only condition accept in - ----------------- - e1 ->r1(192.168.100.0/24) -> o | -> q1-rib -> | -> r2 --> q1 - r2(192.168.10.0/24) -> x | | - | -> q2-rib -> | -> r2 --> q2 - ----------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - - g1.local('gobgp policy prefix add ps0 192.168.10.0/24') - g1.local('gobgp policy statement st0 add condition prefix ps0') - g1.local('gobgp policy statement st0 add action reject') - g1.local('gobgp policy add policy0 st0') - g1.local('gobgp neighbor {0} policy in add policy0'.format(g1.peers[e1]['neigh_addr'].split('/')[0])) - - # this will be blocked - e1.add_route('192.168.100.0/24') - # this will pass - e1.add_route('192.168.10.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - lookup_scenario('InPolicyReject').check(env) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyPrefixCondition").boot(env) - lookup_scenario("InPolicyPrefixCondition").setup(env) - lookup_scenario("InPolicyPrefixCondition").check(env) - - def ext_community_exists(path, extcomm): typ = extcomm.split(':')[0] value = ':'.join(extcomm.split(':')[1:]) diff --git a/test/scenario_test/route_server_policy_test.py b/test/scenario_test/route_server_policy_test.py index bc3637aa..3c6297d4 100644 --- a/test/scenario_test/route_server_policy_test.py +++ b/test/scenario_test/route_server_policy_test.py @@ -2316,245 +2316,6 @@ class ExportPolicyMedSub(object): lookup_scenario("ExportPolicyMedSub").check2(env) -@register_scenario -class InPolicyReject(object): - """ - No.31 in-policy reject test - ---------------- - e1 ->r1(community=65100:10) -> x | -> q1-rib -> | -> r2 --> q1 - r2(192.168.10.0/24) -> o | | - | -> q2-rib -> | -> r2 --> q2 - ---------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - cs0 = {'community-sets': [{'community-set-name': 'cs0', 'community-list': ['65100:10']}]} - - g1.set_bgp_defined_set(cs0) - - st0 = {'name': 'st0', - 'conditions': {'bgp-conditions': {'match-community-set': {'community-set': 'cs0'}}}, - 'actions': {'route-disposition': 'reject-route'}} - - policy = {'name': 'policy0', - 'statements': [st0]} - g1.add_policy(policy, e1, 'in') - - e1.add_route('192.168.100.0/24', community=['65100:10']) - e1.add_route('192.168.10.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 2) - wait_for(lambda: len(g1.get_local_rib(q1)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) - wait_for(lambda: len(q1.get_global_rib()) == 1) - wait_for(lambda: len(g1.get_local_rib(q2)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) - wait_for(lambda: len(q2.get_global_rib()) == 1) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyReject").boot(env) - lookup_scenario("InPolicyReject").setup(env) - lookup_scenario("InPolicyReject").check(env) - - -@register_scenario -class InPolicyAccept(object): - """ - No.32 in-policy accept test - ---------------- - e1 ->r1(community=65100:10) -> x | -> q1-rib -> | -> r2 --> q1 - r2(192.168.10.0/24) -> o | | - | -> q2-rib -> | -> r2 --> q2 - ---------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - cs0 = {'community-sets': [{'community-set-name': 'cs0', 'community-list': ['65100:10']}]} - - g1.set_bgp_defined_set(cs0) - - st0 = {'name': 'st0', - 'conditions': {'bgp-conditions': {'match-community-set': {'community-set': 'cs0'}}}, - 'actions': {'route-disposition': 'accept-route'}} - - policy = {'name': 'policy0', - 'statements': [st0]} - g1.add_policy(policy, e1, 'in', 'reject') - - e1.add_route('192.168.100.0/24', community=['65100:10']) - e1.add_route('192.168.10.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - lookup_scenario('InPolicyReject').check(env) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyAccept").boot(env) - lookup_scenario("InPolicyAccept").setup(env) - lookup_scenario("InPolicyAccept").check(env) - - -@register_scenario -class InPolicyUpdate(object): - """ - No.35 in-policy update test - r1:192.168.2.0 - r2:192.168.20.0 - r3:192.168.200.0 - ------------------------------------- - | q1 | - e1 ->(r1,r2,r3)-> | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q1 - | | - | q2 | - | ->(r1)-> rib ->(r1)-> adj-rib-out | ->(r1)-> q2 - ------------------------------------- - | - update distribute policy - | - V - ------------------------------------------- - | q1 | - e1 ->(r1,r2,r3)-> | ->(r1,r2)-> rib ->(r1,r2)-> adj-rib-out | ->(r1,r2)-> q1 - | | - | q2 | - | ->(r1,r3)-> rib ->(r1,r3)-> adj-rib-out | ->(r1,r3)-> q2 - ------------------------------------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - - p0 = {'ip-prefix': '192.168.20.0/24'} - p1 = {'ip-prefix': '192.168.200.0/24'} - - ps0 = {'prefix-set-name': 'ps0', - 'prefix-list': [p0, p1]} - g1.set_prefix_set(ps0) - - ns0 = {'neighbor-set-name': 'ns0', - 'neighbor-info-list': [g1.peers[e1]['neigh_addr'].split('/')[0]]} - g1.set_neighbor_set(ns0) - - st0 = {'name': 'st0', - 'conditions': { - 'match-prefix-set': {'prefix-set': ps0['prefix-set-name']}, - 'match-neighbor-set': {'neighbor-set': ns0['neighbor-set-name']}}, - 'actions': {'route-disposition': 'reject-route'}} - - policy = {'name': 'policy0', - 'statements': [st0]} - g1.add_policy(policy, e1, 'in') - - e1.add_route('192.168.2.0/24') - e1.add_route('192.168.20.0/24') - e1.add_route('192.168.200.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3) - wait_for(lambda: len(g1.get_local_rib(q1)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 1) - wait_for(lambda: len(q1.get_global_rib()) == 1) - wait_for(lambda: len(g1.get_local_rib(q2)) == 1) - wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 1) - wait_for(lambda: len(q2.get_global_rib()) == 1) - - @staticmethod - def setup2(env): - g1 = env.g1 - e1 = env.e1 - # q1 = env.q1 - # q2 = env.q2 - g1.clear_policy() - - p0 = {'ip-prefix': '192.168.20.0/24'} - - ps0 = {'prefix-set-name': 'ps0', - 'prefix-list': [p0]} - g1.set_prefix_set(ps0) - - ns0 = {'neighbor-set-name': 'ns0', - 'neighbor-info-list': [g1.peers[e1]['neigh_addr'].split('/')[0]]} - g1.set_neighbor_set(ns0) - - st0 = {'name': 'st0', - 'conditions': { - 'match-prefix-set': {'prefix-set': ps0['prefix-set-name']}, - 'match-neighbor-set': {'neighbor-set': ns0['neighbor-set-name']}}, - 'actions': {'route-disposition': 'reject-route'}} - - policy = {'name': 'policy0', - 'statements': [st0]} - g1.add_policy(policy, e1, 'in') - g1.softreset(e1) - - @staticmethod - def check2(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - wait_for(lambda: len(g1.get_adj_rib_in(e1)) == 3) - wait_for(lambda: len(g1.get_local_rib(q1)) == 2) - wait_for(lambda: len(g1.get_adj_rib_out(q1)) == 2) - wait_for(lambda: len(q1.get_global_rib()) == 2) - wait_for(lambda: len(g1.get_local_rib(q2)) == 2) - wait_for(lambda: len(g1.get_adj_rib_out(q2)) == 2) - wait_for(lambda: len(q2.get_global_rib()) == 2) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyUpdate").boot(env) - lookup_scenario("InPolicyUpdate").setup(env) - lookup_scenario("InPolicyUpdate").check(env) - lookup_scenario("InPolicyUpdate").setup2(env) - lookup_scenario("InPolicyUpdate").check2(env) - - @register_scenario class ExportPolicyAsPathPrepend(object): """ @@ -2898,60 +2659,6 @@ class ImportPolicyExCommunityTargetCondition(object): lookup_scenario("ImportPolicyExCommunityTargetCondition").check(env) -@register_scenario -class InPolicyPrefixCondition(object): - """ - No.42 prefix only condition accept in - ----------------- - e1 ->r1(192.168.100.0/24) -> o | -> q1-rib -> | -> r2 --> q1 - r2(192.168.10.0/24) -> x | | - | -> q2-rib -> | -> r2 --> q2 - ----------------- - """ - @staticmethod - def boot(env): - lookup_scenario('ImportPolicy').boot(env) - - @staticmethod - def setup(env): - g1 = env.g1 - e1 = env.e1 - q1 = env.q1 - q2 = env.q2 - - p0 = {'ip-prefix': '192.168.10.0/24'} - - ps0 = {'prefix-set-name': 'ps0', - 'prefix-list': [p0]} - g1.set_prefix_set(ps0) - - st0 = {'name': 'st0', - 'conditions': {'match-prefix-set': {'prefix-set': ps0['prefix-set-name']}}, - 'actions': {'route-disposition': 'reject-route'}} - - policy = {'name': 'policy0', - 'statements': [st0]} - g1.add_policy(policy, e1, 'in') - - # this will be blocked - e1.add_route('192.168.100.0/24') - # this will pass - e1.add_route('192.168.10.0/24') - - for c in [e1, q1, q2]: - g1.wait_for(BGP_FSM_ESTABLISHED, c) - - @staticmethod - def check(env): - lookup_scenario('InPolicyReject').check(env) - - @staticmethod - def executor(env): - lookup_scenario("InPolicyPrefixCondition").boot(env) - lookup_scenario("InPolicyPrefixCondition").setup(env) - lookup_scenario("InPolicyPrefixCondition").check(env) - - def ext_community_exists(path, extcomm): typ = extcomm.split(':')[0] value = ':'.join(extcomm.split(':')[1:]) diff --git a/test/scenario_test/route_server_softreset_test.py b/test/scenario_test/route_server_softreset_test.py index ad608837..23f646eb 100644 --- a/test/scenario_test/route_server_softreset_test.py +++ b/test/scenario_test/route_server_softreset_test.py @@ -88,7 +88,7 @@ class GoBGPTestBase(unittest.TestCase): pol0 = {'name': 'pol0', 'statements': [st0]} - _filename = g1.add_policy(pol0, g3, 'in', 'reject') + _filename = g1.add_policy(pol0, g3, 'import', 'reject') g3.add_route('10.0.10.0/24') g3.add_route('10.0.20.0/24') -- cgit v1.2.3