diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-12-01 14:57:51 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-12-02 08:53:04 +0900 |
commit | ff26d4e93bf728b4fb312a2f66b1becbd2675c9f (patch) | |
tree | c0128bcba14072fbd41885ff437252d4d008a23d /server | |
parent | 3dfb941b336dc72bcd6fcadfd7b55f7c67ffcc4e (diff) |
api/server: refine GetRib API
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r-- | server/grpc_server.go | 18 | ||||
-rw-r--r-- | server/server.go | 175 |
2 files changed, 97 insertions, 96 deletions
diff --git a/server/grpc_server.go b/server/grpc_server.go index 68d0e72b..07ff4e94 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -121,9 +121,9 @@ func (s *Server) GetNeighbors(_ *api.Arguments, stream api.GobgpApi_GetNeighbors }) } -func (s *Server) GetRib(arg *api.Arguments, stream api.GobgpApi_GetRibServer) error { +func (s *Server) GetRib(ctx context.Context, arg *api.Table) (*api.Table, error) { var reqType int - switch arg.Resource { + switch arg.Type { case api.Resource_LOCAL: reqType = REQ_LOCAL_RIB case api.Resource_GLOBAL: @@ -135,15 +135,13 @@ func (s *Server) GetRib(arg *api.Arguments, stream api.GobgpApi_GetRibServer) er case api.Resource_VRF: reqType = REQ_VRF default: - return fmt.Errorf("unsupported resource type: %v", arg.Resource) + return nil, fmt.Errorf("unsupported resource type: %v", arg.Type) } - - req := NewGrpcRequest(reqType, arg.Name, bgp.RouteFamily(arg.Rf), nil) - s.bgpServerCh <- req - - return handleMultipleResponses(req, func(res *GrpcResponse) error { - return stream.Send(res.Data.(*api.Destination)) - }) + d, err := s.get(reqType, arg) + if err != nil { + return nil, err + } + return d.(*api.Table), nil } func (s *Server) MonitorBestChanged(arg *api.Arguments, stream api.GobgpApi_MonitorBestChangedServer) error { diff --git a/server/server.go b/server/server.go index e3ff1a3b..7b6ffb3b 100644 --- a/server/server.go +++ b/server/server.go @@ -1237,7 +1237,8 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path { switch req.RequestType { case REQ_VRF: - name := req.Name + arg := req.Data.(*api.Table) + name := arg.Name rib := server.globalRib vrfs := rib.Vrfs if _, ok := vrfs[name]; !ok { @@ -1245,7 +1246,7 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path { break } var rf bgp.RouteFamily - switch req.RouteFamily { + switch bgp.RouteFamily(arg.Family) { case bgp.RF_IPv4_UC: rf = bgp.RF_IPv4_VPN case bgp.RF_IPv6_UC: @@ -1253,20 +1254,27 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path { case bgp.RF_EVPN: rf = bgp.RF_EVPN default: - result.ResponseErr = fmt.Errorf("unsupported route family: %s", req.RouteFamily) + result.ResponseErr = fmt.Errorf("unsupported route family: %s", bgp.RouteFamily(arg.Family)) break } - for _, path := range rib.GetPathList(rf) { + paths := rib.GetPathList(rf) + dsts := make([]*api.Destination, 0, len(paths)) + for _, path := range paths { ok := table.CanImportToVrf(vrfs[name], path) if !ok { continue } - req.ResponseCh <- &GrpcResponse{ - Data: &api.Destination{ - Prefix: path.GetNlri().String(), - Paths: []*api.Path{path.ToApiStruct()}, - }, - } + dsts = append(dsts, &api.Destination{ + Prefix: path.GetNlri().String(), + Paths: []*api.Path{path.ToApiStruct()}, + }) + } + req.ResponseCh <- &GrpcResponse{ + Data: &api.Table{ + Type: arg.Type, + Family: arg.Family, + Destinations: dsts, + }, } goto END case REQ_VRFS: @@ -1350,20 +1358,15 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { return []*Peer{peer}, err } - sortedDsts := func(t *table.Table) []*GrpcResponse { - results := make([]*GrpcResponse, len(t.GetDestinations())) + sortedDsts := func(t *table.Table) []*api.Destination { + results := make([]*api.Destination, 0, len(t.GetDestinations())) r := radix.New() for _, dst := range t.GetDestinations() { - result := &GrpcResponse{} - result.Data = dst.ToApiStruct() - r.Insert(dst.RadixKey, result) + r.Insert(dst.RadixKey, dst.ToApiStruct()) } - i := 0 r.Walk(func(s string, v interface{}) bool { - r, _ := v.(*GrpcResponse) - results[i] = r - i++ + results = append(results, v.(*api.Destination)) return false }) @@ -1378,6 +1381,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { return nil } + var err error + switch grpcReq.RequestType { case REQ_GLOBAL_CONFIG: result := &GrpcResponse{ @@ -1394,25 +1399,41 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { ResponseErr: err, } close(grpcReq.ResponseCh) - case REQ_GLOBAL_RIB: - var results []*GrpcResponse - if t, ok := server.globalRib.Tables[grpcReq.RouteFamily]; ok { - results = make([]*GrpcResponse, len(t.GetDestinations())) - switch grpcReq.RouteFamily { + case REQ_GLOBAL_RIB, REQ_LOCAL_RIB: + arg := grpcReq.Data.(*api.Table) + d := &api.Table{ + Type: arg.Type, + Family: arg.Family, + } + rib := server.globalRib + if grpcReq.RequestType == REQ_LOCAL_RIB { + peer, ok := server.neighborMap[arg.Name] + if !ok { + err = fmt.Errorf("Neighbor that has %v doesn't exist.", arg.Name) + goto ERROR + } + if !peer.isRouteServerClient() { + err = fmt.Errorf("Neighbor %v doesn't have local rib", arg.Name) + goto ERROR + } + rib = peer.localRib + } + rf := bgp.RouteFamily(arg.Family) + if t, ok := rib.Tables[rf]; ok { + switch rf { case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC: - results = sortedDsts(server.globalRib.Tables[grpcReq.RouteFamily]) + d.Destinations = sortedDsts(rib.Tables[rf]) default: - i := 0 + d.Destinations = make([]*api.Destination, 0, len(t.GetDestinations())) for _, dst := range t.GetDestinations() { - result := &GrpcResponse{} - result.Data = dst.ToApiStruct() - results[i] = result - i++ + d.Destinations = append(d.Destinations, dst.ToApiStruct()) } } } - go sendMultipleResponses(grpcReq, results) - + grpcReq.ResponseCh <- &GrpcResponse{ + Data: d, + } + close(grpcReq.ResponseCh) case REQ_MOD_PATH: pathList := server.handleModPathRequest(grpcReq) if len(pathList) > 0 { @@ -1444,39 +1465,21 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) - case REQ_LOCAL_RIB: - peer, err := server.checkNeighborRequest(grpcReq) - if err != nil { - break - } - var results []*GrpcResponse - if peer.isRouteServerClient() && peer.fsm.adminState != ADMIN_STATE_DOWN { - if t, ok := peer.localRib.Tables[grpcReq.RouteFamily]; ok { - results = make([]*GrpcResponse, len(t.GetDestinations())) - switch grpcReq.RouteFamily { - case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC: - results = sortedDsts(peer.localRib.Tables[grpcReq.RouteFamily]) - default: - i := 0 - for _, dst := range t.GetDestinations() { - result := &GrpcResponse{} - result.Data = dst.ToApiStruct() - results[i] = result - i++ - } - } - } + case REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT: + arg := grpcReq.Data.(*api.Table) + d := &api.Table{ + Type: arg.Type, + Family: arg.Family, } - go sendMultipleResponses(grpcReq, results) - case REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT: - peer, err := server.checkNeighborRequest(grpcReq) - if err != nil { - break + peer, ok := server.neighborMap[arg.Name] + if !ok { + err = fmt.Errorf("Neighbor that has %v doesn't exist.", arg.Name) + goto ERROR } - rf := grpcReq.RouteFamily - var paths []*table.Path + rf := bgp.RouteFamily(arg.Family) + var paths []*table.Path if grpcReq.RequestType == REQ_ADJ_RIB_IN { paths = peer.adjRib.GetInPathList([]bgp.RouteFamily{rf}) log.Debugf("RouteFamily=%v adj-rib-in found : %d", rf.String(), len(paths)) @@ -1485,36 +1488,34 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { log.Debugf("RouteFamily=%v adj-rib-out found : %d", rf.String(), len(paths)) } - toResult := func(p *table.Path) *GrpcResponse { - return &GrpcResponse{ - Data: &api.Destination{ - Prefix: p.GetNlri().String(), - Paths: []*api.Path{p.ToApiStruct()}, - }, - } - } - - results := make([]*GrpcResponse, len(paths)) + results := make([]*api.Destination, 0, len(paths)) switch rf { case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC: r := radix.New() for _, p := range paths { - r.Insert(table.CidrToRadixkey(p.GetNlri().String()), toResult(p)) + key := p.GetNlri().String() + r.Insert(table.CidrToRadixkey(key), &api.Destination{ + Prefix: key, + Paths: []*api.Path{p.ToApiStruct()}, + }) } - i := 0 r.Walk(func(s string, v interface{}) bool { - r, _ := v.(*GrpcResponse) - results[i] = r - i++ + results = append(results, v.(*api.Destination)) return false }) default: - for i, p := range paths { - results[i] = toResult(p) + for _, p := range paths { + results = append(results, &api.Destination{ + Prefix: p.GetNlri().String(), + Paths: []*api.Path{p.ToApiStruct()}, + }) } } - go sendMultipleResponses(grpcReq, results) - + d.Destinations = results + grpcReq.ResponseCh <- &GrpcResponse{ + Data: d, + } + close(grpcReq.ResponseCh) case REQ_NEIGHBOR_SHUTDOWN: peers, err := reqToPeers(grpcReq) if err != nil { @@ -1709,14 +1710,16 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { msgs = server.propagateUpdate(nil, pathList) } default: - errmsg := fmt.Errorf("Unknown request type: %v", grpcReq.RequestType) - result := &GrpcResponse{ - ResponseErr: errmsg, - } - grpcReq.ResponseCh <- result - close(grpcReq.ResponseCh) + err = fmt.Errorf("Unknown request type: %v", grpcReq.RequestType) + goto ERROR } return msgs +ERROR: + grpcReq.ResponseCh <- &GrpcResponse{ + ResponseErr: err, + } + close(grpcReq.ResponseCh) + return msgs } func (server *BgpServer) handleGrpcGetDefinedSet(grpcReq *GrpcRequest) error { |