diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-09-21 14:07:26 +0900 |
---|---|---|
committer | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2017-09-25 15:30:16 +0900 |
commit | 9b278ba79ba2d12598405d1109b0b90b42e68357 (patch) | |
tree | 45100d0bfa136c547ab116361c827f18ca4411cf /client | |
parent | ce258f05d2fd9c3f66b831cae1e40bc9958cef1f (diff) |
api: GetPath API alternative to GetRib
With the extremely large RIBs, GetRib gRPC API hits the limits of each
message size, because this API is using simple request/response RPC.
This patch introduces a new API GetPath which using streaming RPC and
can retrieve RIBs even if extremely large.
Note: GetRib can be replaced with GetPath and obsoleted in the future.
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Diffstat (limited to 'client')
-rw-r--r-- | client/client.go | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/client/client.go b/client/client.go index 2730dd1f..90de1c60 100644 --- a/client/client.go +++ b/client/client.go @@ -18,6 +18,7 @@ package client import ( "fmt" + "io" "net" "strconv" "time" @@ -241,34 +242,54 @@ func (cli *Client) SoftReset(addr string, family bgp.RouteFamily) error { } func (cli *Client) getRIB(resource api.Resource, name string, family bgp.RouteFamily, prefixes []*table.LookupPrefix) (*table.Table, error) { - dsts := make([]*api.Destination, 0, len(prefixes)) + prefixList := make([]*api.TableLookupPrefix, 0, len(prefixes)) for _, p := range prefixes { - longer := false - shorter := false - if p.LookupOption&table.LOOKUP_LONGER > 0 { - longer = true - } - if p.LookupOption&table.LOOKUP_SHORTER > 0 { - shorter = true - } - dsts = append(dsts, &api.Destination{ - Prefix: p.Prefix, - LongerPrefixes: longer, - ShorterPrefixes: shorter, + prefixList = append(prefixList, &api.TableLookupPrefix{ + Prefix: p.Prefix, + LookupOption: api.TableLookupOption(p.LookupOption), }) } - res, err := cli.cli.GetRib(context.Background(), &api.GetRibRequest{ - Table: &api.Table{ - Type: resource, - Family: uint32(family), - Name: name, - Destinations: dsts, - }, + stream, err := cli.cli.GetPath(context.Background(), &api.GetPathRequest{ + Type: resource, + Family: uint32(family), + Name: name, + Prefixes: prefixList, }) if err != nil { return nil, err } - return res.Table.ToNativeTable() + pathMap := make(map[string][]*table.Path) + for { + p, err := stream.Recv() + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + nlri, err := p.GetNativeNlri() + if err != nil { + return nil, err + } + var path *table.Path + if p.Identifier > 0 { + path, err = p.ToNativePath() + } else { + path, err = p.ToNativePath(api.ToNativeOption{ + NLRI: nlri, + }) + } + if err != nil { + return nil, err + } + nlriStr := nlri.String() + pathMap[nlriStr] = append(pathMap[nlriStr], path) + } + dstList := make([]*table.Destination, 0, len(pathMap)) + for _, pathList := range pathMap { + dstList = append(dstList, table.NewDestination(pathList[0].GetNlri(), 0, pathList...)) + } + return table.NewTable(family, dstList...), nil } func (cli *Client) GetRIB(family bgp.RouteFamily, prefixes []*table.LookupPrefix) (*table.Table, error) { |