summaryrefslogtreecommitdiffhomepage
path: root/server
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 /server
parent3dfb941b336dc72bcd6fcadfd7b55f7c67ffcc4e (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.go18
-rw-r--r--server/server.go175
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 {