diff options
-rw-r--r-- | api/grpc_server.go | 2 | ||||
-rw-r--r-- | server/server.go | 12 | ||||
-rw-r--r-- | server/server_test.go | 2 | ||||
-rw-r--r-- | server/zclient.go | 2 | ||||
-rw-r--r-- | table/destination.go | 18 | ||||
-rw-r--r-- | table/table.go | 11 | ||||
-rw-r--r-- | table/table_manager.go | 53 |
7 files changed, 77 insertions, 23 deletions
diff --git a/api/grpc_server.go b/api/grpc_server.go index 8f75c1c1..8fbe53a2 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -347,7 +347,7 @@ func (s *Server) MonitorRib(arg *Table, stream GobgpApi_MonitorRibServer) error w, err := func() (*server.Watcher, error) { switch arg.Type { case Resource_GLOBAL: - return s.bgpServer.Watch(server.WatchBestPath()), nil + return s.bgpServer.Watch(server.WatchBestPath(false)), nil case Resource_ADJ_IN: if arg.PostPolicy { return s.bgpServer.Watch(server.WatchPostUpdate(false)), nil diff --git a/server/server.go b/server/server.go index 435c9f72..ba30f578 100644 --- a/server/server.go +++ b/server/server.go @@ -2133,6 +2133,7 @@ type watchOptions struct { preUpdate bool postUpdate bool peerState bool + initBest bool initUpdate bool initPostUpdate bool initPeerState bool @@ -2141,9 +2142,12 @@ type watchOptions struct { type WatchOption func(*watchOptions) -func WatchBestPath() WatchOption { +func WatchBestPath(current bool) WatchOption { return func(o *watchOptions) { o.bestpath = true + if current { + o.initBest = true + } } } @@ -2319,6 +2323,12 @@ func (s *BgpServer) Watch(opts ...WatchOption) (w *Watcher) { w.notify(createWatchEventPeerState(peer)) } } + if w.opts.initBest { + w.notify(&WatchEventBestPath{ + PathList: s.globalRib.GetBestPathList(table.GLOBAL_RIB_NAME, nil), + MultiPathList: s.globalRib.GetBestMultiPathList(table.GLOBAL_RIB_NAME, nil), + }) + } if w.opts.initUpdate { for _, peer := range s.neighborMap { if peer.fsm.state != bgp.BGP_FSM_ESTABLISHED { diff --git a/server/server_test.go b/server/server_test.go index 73eadb0a..5e0dc5e0 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -113,7 +113,7 @@ func TestMonitor(test *testing.T) { } } - w := s.Watch(WatchBestPath()) + w := s.Watch(WatchBestPath(false)) attrs := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(0), diff --git a/server/zclient.go b/server/zclient.go index df92f038..5f81cfcf 100644 --- a/server/zclient.go +++ b/server/zclient.go @@ -177,7 +177,7 @@ func (z *zebraClient) stop() { } func (z *zebraClient) loop() { - w := z.server.Watch(WatchBestPath()) + w := z.server.Watch(WatchBestPath(true)) defer func() { w.Stop() }() for { diff --git a/table/destination.go b/table/destination.go index ac3ef0c8..1ded7962 100644 --- a/table/destination.go +++ b/table/destination.go @@ -182,6 +182,24 @@ func (dd *Destination) GetBestPath(id string) *Path { return nil } +func (dd *Destination) GetMultiBestPath(id string) []*Path { + list := make([]*Path, 0, len(dd.knownPathList)) + var best *Path + for _, p := range dd.knownPathList { + if p.Filtered(id) == POLICY_DIRECTION_NONE { + if best == nil { + best = p + list = append(list, p) + } else if best.Compare(p) == 0 { + list = append(list, p) + } else { + return list + } + } + } + return nil +} + func (dd *Destination) AddWithdraw(withdraw *Path) { dd.validatePath(withdraw) dd.withdrawList = append(dd.withdrawList, withdraw) diff --git a/table/table.go b/table/table.go index 08637522..c3b48812 100644 --- a/table/table.go +++ b/table/table.go @@ -303,6 +303,17 @@ func (t *Table) Bests(id string) []*Path { return paths } +func (t *Table) MultiBests(id string) [][]*Path { + paths := make([][]*Path, 0, len(t.destinations)) + for _, dst := range t.destinations { + path := dst.GetMultiBestPath(id) + if path != nil { + paths = append(paths, path) + } + } + return paths +} + func (t *Table) GetKnownPathList(id string) []*Path { paths := make([]*Path, 0, len(t.destinations)) for _, dst := range t.destinations { diff --git a/table/table_manager.go b/table/table_manager.go index ae00d3ce..15caa924 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -299,38 +299,53 @@ func (manager *TableManager) handleMacMobility(path *Path) []*Destination { return dsts } +func (manager *TableManager) tables(list ...bgp.RouteFamily) []*Table { + l := make([]*Table, 0, len(manager.Tables)) + if len(list) == 0 { + for _, v := range manager.Tables { + l = append(l, v) + } + return l + } + for _, f := range list { + if t, ok := manager.Tables[f]; ok { + l = append(l, t) + } + } + return l +} + func (manager *TableManager) getDestinationCount(rfList []bgp.RouteFamily) int { count := 0 - for _, rf := range rfList { - if _, ok := manager.Tables[rf]; ok { - count += len(manager.Tables[rf].GetDestinations()) - } + for _, t := range manager.tables(rfList...) { + count += len(t.GetDestinations()) } return count } func (manager *TableManager) GetBestPathList(id string, rfList []bgp.RouteFamily) []*Path { paths := make([]*Path, 0, manager.getDestinationCount(rfList)) - for _, rf := range rfList { - if t, ok := manager.Tables[rf]; ok { - paths = append(paths, t.Bests(id)...) - } + for _, t := range manager.tables(rfList...) { + paths = append(paths, t.Bests(id)...) } return paths } -func (manager *TableManager) GetPathList(id string, rfList []bgp.RouteFamily) []*Path { - c := 0 - for _, rf := range rfList { - if t, ok := manager.Tables[rf]; ok { - c += len(t.destinations) - } +func (manager *TableManager) GetBestMultiPathList(id string, rfList []bgp.RouteFamily) [][]*Path { + if !UseMultiplePaths.Enabled { + return nil } - paths := make([]*Path, 0, c) - for _, rf := range rfList { - if t, ok := manager.Tables[rf]; ok { - paths = append(paths, t.GetKnownPathList(id)...) - } + paths := make([][]*Path, 0, manager.getDestinationCount(rfList)) + for _, t := range manager.tables(rfList...) { + paths = append(paths, t.MultiBests(id)...) + } + return paths +} + +func (manager *TableManager) GetPathList(id string, rfList []bgp.RouteFamily) []*Path { + paths := make([]*Path, 0, manager.getDestinationCount(rfList)) + for _, t := range manager.tables(rfList...) { + paths = append(paths, t.GetKnownPathList(id)...) } return paths } |