summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-12-01 14:57:51 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-12-02 08:53:04 +0900
commitff26d4e93bf728b4fb312a2f66b1becbd2675c9f (patch)
treec0128bcba14072fbd41885ff437252d4d008a23d
parent3dfb941b336dc72bcd6fcadfd7b55f7c67ffcc4e (diff)
api/server: refine GetRib API
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--api/gobgp.pb.go110
-rw-r--r--api/gobgp.proto9
-rw-r--r--gobgp/cmd/neighbor.go18
-rw-r--r--server/grpc_server.go18
-rw-r--r--server/server.go175
5 files changed, 159 insertions, 171 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index d992a43b..c3956e92 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -22,6 +22,7 @@ It has these top-level messages:
ModPolicyArguments
ModPolicyAssignmentArguments
ModGlobalConfigArguments
+ Table
Path
Destination
Peer
@@ -517,6 +518,24 @@ func (m *ModGlobalConfigArguments) GetGlobal() *Global {
return nil
}
+type Table struct {
+ Type Resource `protobuf:"varint,1,opt,name=type,enum=gobgpapi.Resource" json:"type,omitempty"`
+ Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+ Family uint32 `protobuf:"varint,3,opt,name=family" json:"family,omitempty"`
+ Destinations []*Destination `protobuf:"bytes,4,rep,name=destinations" json:"destinations,omitempty"`
+}
+
+func (m *Table) Reset() { *m = Table{} }
+func (m *Table) String() string { return proto.CompactTextString(m) }
+func (*Table) ProtoMessage() {}
+
+func (m *Table) GetDestinations() []*Destination {
+ if m != nil {
+ return m.Destinations
+ }
+ return nil
+}
+
type Path struct {
Nlri []byte `protobuf:"bytes,1,opt,name=nlri,proto3" json:"nlri,omitempty"`
Pattrs [][]byte `protobuf:"bytes,2,rep,name=pattrs,proto3" json:"pattrs,omitempty"`
@@ -1527,7 +1546,7 @@ type GobgpApiClient interface {
GetNeighbors(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetNeighborsClient, error)
GetNeighbor(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Peer, error)
ModNeighbor(ctx context.Context, in *ModNeighborArguments, opts ...grpc.CallOption) (*Error, error)
- GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetRibClient, error)
+ GetRib(ctx context.Context, in *Table, opts ...grpc.CallOption) (*Table, error)
Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
SoftReset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
SoftResetIn(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
@@ -1634,36 +1653,13 @@ func (c *gobgpApiClient) ModNeighbor(ctx context.Context, in *ModNeighborArgumen
return out, nil
}
-func (c *gobgpApiClient) GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetRibClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[1], c.cc, "/gobgpapi.GobgpApi/GetRib", opts...)
+func (c *gobgpApiClient) GetRib(ctx context.Context, in *Table, opts ...grpc.CallOption) (*Table, error) {
+ out := new(Table)
+ err := grpc.Invoke(ctx, "/gobgpapi.GobgpApi/GetRib", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
- x := &gobgpApiGetRibClient{stream}
- if err := x.ClientStream.SendMsg(in); err != nil {
- return nil, err
- }
- if err := x.ClientStream.CloseSend(); err != nil {
- return nil, err
- }
- return x, nil
-}
-
-type GobgpApi_GetRibClient interface {
- Recv() (*Destination, error)
- grpc.ClientStream
-}
-
-type gobgpApiGetRibClient struct {
- grpc.ClientStream
-}
-
-func (x *gobgpApiGetRibClient) Recv() (*Destination, error) {
- m := new(Destination)
- if err := x.ClientStream.RecvMsg(m); err != nil {
- return nil, err
- }
- return m, nil
+ return out, nil
}
func (c *gobgpApiClient) Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
@@ -1730,7 +1726,7 @@ func (c *gobgpApiClient) Disable(ctx context.Context, in *Arguments, opts ...grp
}
func (c *gobgpApiClient) ModPath(ctx context.Context, opts ...grpc.CallOption) (GobgpApi_ModPathClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[2], c.cc, "/gobgpapi.GobgpApi/ModPath", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[1], c.cc, "/gobgpapi.GobgpApi/ModPath", opts...)
if err != nil {
return nil, err
}
@@ -1764,7 +1760,7 @@ func (x *gobgpApiModPathClient) CloseAndRecv() (*Error, error) {
}
func (c *gobgpApiClient) MonitorBestChanged(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_MonitorBestChangedClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[3], c.cc, "/gobgpapi.GobgpApi/MonitorBestChanged", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[2], c.cc, "/gobgpapi.GobgpApi/MonitorBestChanged", opts...)
if err != nil {
return nil, err
}
@@ -1796,7 +1792,7 @@ func (x *gobgpApiMonitorBestChangedClient) Recv() (*Destination, error) {
}
func (c *gobgpApiClient) MonitorPeerState(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_MonitorPeerStateClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[4], c.cc, "/gobgpapi.GobgpApi/MonitorPeerState", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[3], c.cc, "/gobgpapi.GobgpApi/MonitorPeerState", opts...)
if err != nil {
return nil, err
}
@@ -1828,7 +1824,7 @@ func (x *gobgpApiMonitorPeerStateClient) Recv() (*Peer, error) {
}
func (c *gobgpApiClient) GetMrt(ctx context.Context, in *MrtArguments, opts ...grpc.CallOption) (GobgpApi_GetMrtClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[5], c.cc, "/gobgpapi.GobgpApi/GetMrt", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[4], c.cc, "/gobgpapi.GobgpApi/GetMrt", opts...)
if err != nil {
return nil, err
}
@@ -1869,7 +1865,7 @@ func (c *gobgpApiClient) ModMrt(ctx context.Context, in *ModMrtArguments, opts .
}
func (c *gobgpApiClient) GetRPKI(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetRPKIClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[6], c.cc, "/gobgpapi.GobgpApi/GetRPKI", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[5], c.cc, "/gobgpapi.GobgpApi/GetRPKI", opts...)
if err != nil {
return nil, err
}
@@ -1910,7 +1906,7 @@ func (c *gobgpApiClient) ModRPKI(ctx context.Context, in *ModRpkiArguments, opts
}
func (c *gobgpApiClient) GetROA(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetROAClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[7], c.cc, "/gobgpapi.GobgpApi/GetROA", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[6], c.cc, "/gobgpapi.GobgpApi/GetROA", opts...)
if err != nil {
return nil, err
}
@@ -1942,7 +1938,7 @@ func (x *gobgpApiGetROAClient) Recv() (*ROA, error) {
}
func (c *gobgpApiClient) GetVrfs(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (GobgpApi_GetVrfsClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[8], c.cc, "/gobgpapi.GobgpApi/GetVrfs", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[7], c.cc, "/gobgpapi.GobgpApi/GetVrfs", opts...)
if err != nil {
return nil, err
}
@@ -1992,7 +1988,7 @@ func (c *gobgpApiClient) GetDefinedSet(ctx context.Context, in *DefinedSet, opts
}
func (c *gobgpApiClient) GetDefinedSets(ctx context.Context, in *DefinedSet, opts ...grpc.CallOption) (GobgpApi_GetDefinedSetsClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[9], c.cc, "/gobgpapi.GobgpApi/GetDefinedSets", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[8], c.cc, "/gobgpapi.GobgpApi/GetDefinedSets", opts...)
if err != nil {
return nil, err
}
@@ -2042,7 +2038,7 @@ func (c *gobgpApiClient) GetStatement(ctx context.Context, in *Statement, opts .
}
func (c *gobgpApiClient) GetStatements(ctx context.Context, in *Statement, opts ...grpc.CallOption) (GobgpApi_GetStatementsClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[10], c.cc, "/gobgpapi.GobgpApi/GetStatements", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[9], c.cc, "/gobgpapi.GobgpApi/GetStatements", opts...)
if err != nil {
return nil, err
}
@@ -2092,7 +2088,7 @@ func (c *gobgpApiClient) GetPolicy(ctx context.Context, in *Policy, opts ...grpc
}
func (c *gobgpApiClient) GetPolicies(ctx context.Context, in *Policy, opts ...grpc.CallOption) (GobgpApi_GetPoliciesClient, error) {
- stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[11], c.cc, "/gobgpapi.GobgpApi/GetPolicies", opts...)
+ stream, err := grpc.NewClientStream(ctx, &_GobgpApi_serviceDesc.Streams[10], c.cc, "/gobgpapi.GobgpApi/GetPolicies", opts...)
if err != nil {
return nil, err
}
@@ -2158,7 +2154,7 @@ type GobgpApiServer interface {
GetNeighbors(*Arguments, GobgpApi_GetNeighborsServer) error
GetNeighbor(context.Context, *Arguments) (*Peer, error)
ModNeighbor(context.Context, *ModNeighborArguments) (*Error, error)
- GetRib(*Arguments, GobgpApi_GetRibServer) error
+ GetRib(context.Context, *Table) (*Table, error)
Reset(context.Context, *Arguments) (*Error, error)
SoftReset(context.Context, *Arguments) (*Error, error)
SoftResetIn(context.Context, *Arguments) (*Error, error)
@@ -2262,25 +2258,16 @@ func _GobgpApi_ModNeighbor_Handler(srv interface{}, ctx context.Context, dec fun
return out, nil
}
-func _GobgpApi_GetRib_Handler(srv interface{}, stream grpc.ServerStream) error {
- m := new(Arguments)
- if err := stream.RecvMsg(m); err != nil {
- return err
+func _GobgpApi_GetRib_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
+ in := new(Table)
+ if err := dec(in); err != nil {
+ return nil, err
}
- return srv.(GobgpApiServer).GetRib(m, &gobgpApiGetRibServer{stream})
-}
-
-type GobgpApi_GetRibServer interface {
- Send(*Destination) error
- grpc.ServerStream
-}
-
-type gobgpApiGetRibServer struct {
- grpc.ServerStream
-}
-
-func (x *gobgpApiGetRibServer) Send(m *Destination) error {
- return x.ServerStream.SendMsg(m)
+ out, err := srv.(GobgpApiServer).GetRib(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
}
func _GobgpApi_Reset_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
@@ -2735,6 +2722,10 @@ var _GobgpApi_serviceDesc = grpc.ServiceDesc{
Handler: _GobgpApi_ModNeighbor_Handler,
},
{
+ MethodName: "GetRib",
+ Handler: _GobgpApi_GetRib_Handler,
+ },
+ {
MethodName: "Reset",
Handler: _GobgpApi_Reset_Handler,
},
@@ -2814,11 +2805,6 @@ var _GobgpApi_serviceDesc = grpc.ServiceDesc{
ServerStreams: true,
},
{
- StreamName: "GetRib",
- Handler: _GobgpApi_GetRib_Handler,
- ServerStreams: true,
- },
- {
StreamName: "ModPath",
Handler: _GobgpApi_ModPath_Handler,
ClientStreams: true,
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 2857cf45..ab9e0d2d 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -25,7 +25,7 @@ service GobgpApi {
rpc GetNeighbors(Arguments) returns (stream Peer) {}
rpc GetNeighbor(Arguments) returns (Peer) {}
rpc ModNeighbor(ModNeighborArguments) returns(Error) {}
- rpc GetRib(Arguments) returns (stream Destination) {}
+ rpc GetRib(Table) returns (Table) {}
rpc Reset(Arguments) returns (Error) {}
rpc SoftReset(Arguments) returns (Error) {}
rpc SoftResetIn(Arguments) returns (Error) {}
@@ -172,6 +172,13 @@ message Destination {
repeated Path paths = 2;
}
+message Table {
+ Resource type = 1;
+ string name = 2;
+ uint32 family = 3;
+ repeated Destination destinations = 4;
+}
+
message Peer {
AddPaths addpaths = 1;
AfiSafis afisafis = 2;
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index a3181ba0..d8079449 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -415,13 +415,13 @@ func showNeighborRib(r string, name string, args []string) error {
}
}
- arg := &api.Arguments{
- Resource: resource,
- Rf: uint32(rf),
- Name: name,
+ arg := &api.Table{
+ Type: resource,
+ Family: uint32(rf),
+ Name: name,
}
- stream, err := client.GetRib(context.Background(), arg)
+ rib, err := client.GetRib(context.Background(), arg)
if err != nil {
return err
}
@@ -437,13 +437,7 @@ func showNeighborRib(r string, name string, args []string) error {
dsts := []*Destination{}
maxOnes := 0
counter := 0
- for {
- d, e := stream.Recv()
- if e == io.EOF {
- break
- } else if e != nil {
- return e
- }
+ for _, d := range rib.Destinations {
if prefix != "" && prefix != d.Prefix {
continue
}
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 {