summaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
authorIWASE Yusuke <iwase.yusuke0@gmail.com>2017-09-21 14:07:26 +0900
committerIWASE Yusuke <iwase.yusuke0@gmail.com>2017-09-25 15:30:16 +0900
commit9b278ba79ba2d12598405d1109b0b90b42e68357 (patch)
tree45100d0bfa136c547ab116361c827f18ca4411cf /client
parentce258f05d2fd9c3f66b831cae1e40bc9958cef1f (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.go63
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) {