From f27afac154c955e1e2508d2443ef29ecfc62c6b8 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 11 Jul 2016 21:54:50 +0900 Subject: move gRPC-related code in path.go and destination.go to grpc_server.go Signed-off-by: FUJITA Tomonori --- server/grpc_server.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++ server/monitor.go | 2 +- server/server.go | 83 ++++++++++++++++++++++----------------------------- 3 files changed, 114 insertions(+), 49 deletions(-) (limited to 'server') diff --git a/server/grpc_server.go b/server/grpc_server.go index a47222c5..d0103736 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -253,6 +253,34 @@ func handleMultipleResponses(req *GrpcRequest, f func(*GrpcResponse) error) erro return nil } +func toPathApi(id string, path *table.Path) *api.Path { + nlri := path.GetNlri() + n, _ := nlri.Serialize() + family := uint32(bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI())) + pattrs := func(arg []bgp.PathAttributeInterface) [][]byte { + ret := make([][]byte, 0, len(arg)) + for _, a := range arg { + aa, _ := a.Serialize() + ret = append(ret, aa) + } + return ret + }(path.GetPathAttrs()) + return &api.Path{ + Nlri: n, + Pattrs: pattrs, + Age: path.GetTimestamp().Unix(), + IsWithdraw: path.IsWithdraw, + Validation: int32(path.Validation().ToInt()), + Filtered: path.Filtered(id) == table.POLICY_DIRECTION_IN, + Family: family, + SourceAsn: path.GetSource().AS, + SourceId: path.GetSource().ID.String(), + NeighborIp: path.GetSource().Address.String(), + Stale: path.IsStale(), + IsFromExternal: path.IsFromExternal(), + } +} + func (s *Server) GetRib(ctx context.Context, arg *api.GetRibRequest) (*api.GetRibResponse, error) { var reqType int switch arg.Table.Type { @@ -273,6 +301,56 @@ func (s *Server) GetRib(ctx context.Context, arg *api.GetRibRequest) (*api.GetRi if err != nil { return nil, err } + + switch reqType { + case REQ_LOCAL_RIB, REQ_GLOBAL_RIB: + dsts := make([]*api.Destination, 0, len(d.(map[string][]*table.Path))) + for k, v := range d.(map[string][]*table.Path) { + dsts = append(dsts, &api.Destination{ + Prefix: k, + Paths: func(paths []*table.Path) []*api.Path { + l := make([]*api.Path, 0, len(v)) + for i, p := range paths { + pp := toPathApi("", p) + if i == 0 { + pp.Best = true + } + l = append(l, pp) + } + return l + }(v), + }) + } + d := &api.Table{ + Type: arg.Table.Type, + Family: arg.Table.Family, + Destinations: dsts, + } + return &api.GetRibResponse{Table: d}, nil + case REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT, REQ_VRF: + dsts := make([]*api.Destination, 0, len(d.([]*table.Path))) + var prefix string + var dst *api.Destination + for _, path := range d.([]*table.Path) { + if path.GetNlri().String() != prefix { + prefix = path.GetNlri().String() + dst = &api.Destination{ + Prefix: prefix, + Paths: []*api.Path{toPathApi(arg.Table.Name, path)}, + } + } else { + dst.Paths = append(dst.Paths, toPathApi(arg.Table.Name, path)) + } + dsts = append(dsts, dst) + } + return &api.GetRibResponse{ + Table: &api.Table{ + Type: arg.Table.Type, + Family: arg.Table.Family, + Destinations: dsts, + }, + }, nil + } return d.(*api.GetRibResponse), nil } diff --git a/server/monitor.go b/server/monitor.go index 1f445c35..d8276c9e 100644 --- a/server/monitor.go +++ b/server/monitor.go @@ -83,7 +83,7 @@ func (w *grpcWatcher) loop() error { for _, dst := range dsts { paths := make([]*api.Path, 0, len(dst)) for _, path := range dst { - paths = append(paths, path.ToApiStruct(table.GLOBAL_RIB_NAME)) + paths = append(paths, toPathApi(table.GLOBAL_RIB_NAME, path)) } if len(paths) == 0 { continue diff --git a/server/server.go b/server/server.go index 76d214b8..23eba426 100644 --- a/server/server.go +++ b/server/server.go @@ -1357,26 +1357,17 @@ func (server *BgpServer) handleVrfRequest(req *GrpcRequest) []*table.Path { result.ResponseErr = fmt.Errorf("unsupported route family: %s", bgp.RouteFamily(arg.Table.Family)) break } - paths := rib.GetPathList(table.GLOBAL_RIB_NAME, []bgp.RouteFamily{rf}) - dsts := make([]*api.Destination, 0, len(paths)) - for _, path := range paths { + l := rib.GetPathList(table.GLOBAL_RIB_NAME, []bgp.RouteFamily{rf}) + paths := make([]*table.Path, 0, len(l)) + for _, path := range l { ok := table.CanImportToVrf(vrfs[name], path) if !ok { continue } - dsts = append(dsts, &api.Destination{ - Prefix: path.GetNlri().String(), - Paths: []*api.Path{path.ToApiStruct(table.GLOBAL_RIB_NAME)}, - }) + paths = append(paths, path) } req.ResponseCh <- &GrpcResponse{ - Data: &api.GetRibResponse{ - Table: &api.Table{ - Type: arg.Table.Type, - Family: arg.Table.Family, - Destinations: dsts, - }, - }, + Data: paths, } goto END case REQ_GET_VRF: @@ -1541,10 +1532,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { close(grpcReq.ResponseCh) case REQ_GLOBAL_RIB, REQ_LOCAL_RIB: arg := grpcReq.Data.(*api.GetRibRequest) - d := &api.Table{ - Type: arg.Table.Type, - Family: arg.Table.Family, - } rib := server.globalRib id := table.GLOBAL_RIB_NAME if grpcReq.RequestType == REQ_LOCAL_RIB { @@ -1565,7 +1552,15 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { goto ERROR } - dsts := make([]*api.Destination, 0, len(rib.Tables[af].GetDestinations())) + clone := func(pathList []*table.Path) []*table.Path { + l := make([]*table.Path, 0, len(pathList)) + for _, p := range pathList { + l = append(l, p.Clone(false)) + } + return l + } + + dsts := make(map[string][]*table.Path) if (af == bgp.RF_IPv4_UC || af == bgp.RF_IPv6_UC) && len(arg.Table.Destinations) > 0 { f := func(id, cidr string) (bool, error) { _, prefix, err := net.ParseCIDR(cidr) @@ -1573,8 +1568,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { return false, err } if dst := rib.Tables[af].GetDestination(prefix.String()); dst != nil { - if d := dst.ToApiStruct(id); d != nil { - dsts = append(dsts, d) + if paths := dst.GetKnownPathList(id); len(paths) > 0 { + dsts[dst.GetNlri().String()] = clone(paths) } return true, nil } else { @@ -1586,8 +1581,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { if dst.LongerPrefixes { _, prefix, _ := net.ParseCIDR(key) for _, dst := range rib.Tables[af].GetLongerPrefixDestinations(prefix.String()) { - if d := dst.ToApiStruct(id); d != nil { - dsts = append(dsts, d) + if paths := dst.GetKnownPathList(id); len(paths) > 0 { + dsts[dst.GetNlri().String()] = clone(paths) } } } else if dst.ShorterPrefixes { @@ -1613,14 +1608,13 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { } } else { for _, dst := range rib.Tables[af].GetSortedDestinations() { - if d := dst.ToApiStruct(id); d != nil { - dsts = append(dsts, d) + if paths := dst.GetKnownPathList(id); len(paths) > 0 { + dsts[dst.GetNlri().String()] = clone(paths) } } } - d.Destinations = dsts grpcReq.ResponseCh <- &GrpcResponse{ - Data: &api.GetRibResponse{Table: d}, + Data: dsts, } close(grpcReq.ResponseCh) case REQ_BMP_GLOBAL: @@ -1675,16 +1669,14 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { close(grpcReq.ResponseCh) case REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT: arg := grpcReq.Data.(*api.GetRibRequest) - d := &api.Table{ - Type: arg.Table.Type, - Family: arg.Table.Family, - } peer, ok := server.neighborMap[arg.Table.Name] if !ok { err = fmt.Errorf("Neighbor that has %v doesn't exist.", arg.Table.Name) goto ERROR } + // FIXME: temporary hack + arg.Table.Name = peer.TableID() rf := bgp.RouteFamily(arg.Table.Family) var paths []*table.Path @@ -1696,7 +1688,11 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { log.Debugf("RouteFamily=%v adj-rib-out found : %d", rf.String(), len(paths)) } - results := make([]*api.Destination, 0, len(paths)) + for i, p := range paths { + id := peer.TableID() + paths[i] = p.Clone(false) + paths[i].Filter(id, p.Filtered(id)) + } switch rf { case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC: r := radix.New() @@ -1714,31 +1710,22 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { if found { b, _ := r.Get(table.CidrToRadixkey(key)) if b == nil { - r.Insert(table.CidrToRadixkey(key), &api.Destination{ - Prefix: key, - Paths: []*api.Path{p.ToApiStruct(peer.TableID())}, - }) + r.Insert(table.CidrToRadixkey(key), []*table.Path{p}) } else { - d := b.(*api.Destination) - d.Paths = append(d.Paths, p.ToApiStruct(peer.TableID())) + l := b.([]*table.Path) + l = append(l, p) } } } + l := make([]*table.Path, 0, len(paths)) r.Walk(func(s string, v interface{}) bool { - results = append(results, v.(*api.Destination)) + l = append(l, v.([]*table.Path)...) return false }) - default: - for _, p := range paths { - results = append(results, &api.Destination{ - Prefix: p.GetNlri().String(), - Paths: []*api.Path{p.ToApiStruct(peer.TableID())}, - }) - } + paths = l } - d.Destinations = results grpcReq.ResponseCh <- &GrpcResponse{ - Data: &api.GetRibResponse{Table: d}, + Data: paths, } close(grpcReq.ResponseCh) case REQ_BMP_ADJ_IN: -- cgit v1.2.3