diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-12-26 19:24:46 -0800 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-12-26 19:24:46 -0800 |
commit | 7a2b3951160804c6895714621099168e8e56aa74 (patch) | |
tree | f847e72ac7fc6064774f5de1afca77c712d5809d /server | |
parent | 01157e466a510a9d7c7290c26a131734e7566261 (diff) |
add MOD_PATH API
Handle only one route unlike MOD_PATHS API. When the API returns an
uuid when a route is created. The uuid can be used to remove the route
later.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r-- | server/grpc_server.go | 9 | ||||
-rw-r--r-- | server/server.go | 61 |
2 files changed, 68 insertions, 2 deletions
diff --git a/server/grpc_server.go b/server/grpc_server.go index e2c1a0b5..776f64da 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -55,6 +55,7 @@ const ( REQ_VRF REQ_VRFS REQ_VRF_MOD + REQ_MOD_PATH REQ_MOD_PATHS REQ_DEFINED_SET REQ_MOD_DEFINED_SET @@ -211,6 +212,14 @@ func (s *Server) Disable(ctx context.Context, arg *api.Arguments) (*api.Error, e return s.neighbor(REQ_NEIGHBOR_DISABLE, arg) } +func (s *Server) ModPath(ctx context.Context, arg *api.ModPathArguments) (*api.ModPathResponse, error) { + d, err := s.get(REQ_MOD_PATH, arg) + if err != nil { + return nil, err + } + return d.(*api.ModPathResponse), nil +} + func (s *Server) ModPaths(stream api.GobgpApi_ModPathsServer) error { for { arg, err := stream.Recv() diff --git a/server/server.go b/server/server.go index 893229c2..670deee4 100644 --- a/server/server.go +++ b/server/server.go @@ -26,6 +26,7 @@ import ( "github.com/osrg/gobgp/packet" "github.com/osrg/gobgp/table" "github.com/osrg/gobgp/zebra" + "github.com/satori/go.uuid" "net" "os" "strconv" @@ -1204,6 +1205,58 @@ func (server *BgpServer) Api2PathList(resource api.Resource, name string, ApiPat func (server *BgpServer) handleModPathRequest(grpcReq *GrpcRequest) []*table.Path { var err error + var uuidBytes []byte + paths := make([]*table.Path, 0, 1) + arg, ok := grpcReq.Data.(*api.ModPathArguments) + if !ok { + err = fmt.Errorf("type assertion failed") + } + + if err == nil { + switch arg.Operation { + case api.Operation_DEL: + if len(arg.Uuid) > 0 { + path := func() *table.Path { + for _, rf := range server.globalRib.GetRFlist() { + for _, path := range server.globalRib.GetPathList(table.GLOBAL_RIB_NAME, rf) { + if len(path.Uuid) > 0 && bytes.Equal(path.Uuid, arg.Uuid) { + return path + } + } + } + return nil + }() + if path != nil { + paths = append(paths, path.Clone(path.Owner, true)) + } else { + err = fmt.Errorf("Can't find a specified path") + } + break + } + arg.Path.IsWithdraw = true + fallthrough + case api.Operation_ADD: + paths, err = server.Api2PathList(arg.Resource, arg.Name, []*api.Path{arg.Path}) + if err == nil { + u := uuid.NewV4() + uuidBytes = u.Bytes() + paths[0].Uuid = uuidBytes + } + } + } + result := &GrpcResponse{ + ResponseErr: err, + Data: &api.ModPathResponse{ + Uuid: uuidBytes, + }, + } + grpcReq.ResponseCh <- result + close(grpcReq.ResponseCh) + return paths +} + +func (server *BgpServer) handleModPathsRequest(grpcReq *GrpcRequest) []*table.Path { + var err error var paths []*table.Path arg, ok := grpcReq.Data.(*api.ModPathsArguments) if !ok { @@ -1531,14 +1584,18 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { Data: d, } close(grpcReq.ResponseCh) - case REQ_MOD_PATHS: + case REQ_MOD_PATH: pathList := server.handleModPathRequest(grpcReq) if len(pathList) > 0 { msgs, _ = server.propagateUpdate(nil, pathList) + } + case REQ_MOD_PATHS: + pathList := server.handleModPathsRequest(grpcReq) + if len(pathList) > 0 { + msgs, _ = server.propagateUpdate(nil, pathList) grpcReq.ResponseCh <- &GrpcResponse{} close(grpcReq.ResponseCh) } - case REQ_NEIGHBORS: results := make([]*GrpcResponse, len(server.neighborMap)) i := 0 |