summaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/grpc_server.go78
-rw-r--r--server/monitor.go2
-rw-r--r--server/server.go83
3 files changed, 114 insertions, 49 deletions
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: