diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-05-18 13:01:43 +0000 |
---|---|---|
committer | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2016-05-19 00:44:47 +0000 |
commit | b281f7f4ffc965b8a88b0a85b5315b97ca512f68 (patch) | |
tree | b3a7a793de7532a860d3718174725300cf378681 /server | |
parent | c2bb04d5efa1c7586500832e16524e13596dbe29 (diff) |
server: return flowspec routes in rfc compliant manner
The order of the flowspec routes matters because they will be used
as ACL rules and what rule will be applied depends on the order.
RFC5575 specifies how flowspec routes should be sorted.
This commit implements what it says.
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r-- | server/server.go | 97 |
1 files changed, 37 insertions, 60 deletions
diff --git a/server/server.go b/server/server.go index 81d678b9..df25e91b 100644 --- a/server/server.go +++ b/server/server.go @@ -1704,23 +1704,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { return []*Peer{peer}, err } - sortedDsts := func(id string, t *table.Table) []*api.Destination { - results := make([]*api.Destination, 0, len(t.GetDestinations())) - - r := radix.New() - for _, dst := range t.GetDestinations() { - if d := dst.ToApiStruct(id); d != nil { - r.Insert(dst.RadixKey, d) - } - } - r.Walk(func(s string, v interface{}) bool { - results = append(results, v.(*api.Destination)) - return false - }) - - return results - } - if server.bgpConfig.Global.Config.As == 0 && grpcReq.RequestType != REQ_START_SERVER { grpcReq.ResponseCh <- &GrpcResponse{ ResponseErr: fmt.Errorf("bgpd main loop is not started yet"), @@ -1788,59 +1771,53 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg { goto ERROR } - switch af { - case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC: - if len(arg.Table.Destinations) > 0 { - dsts := []*api.Destination{} - f := func(id, cidr string) (bool, error) { - _, prefix, err := net.ParseCIDR(cidr) - if err != nil { - return false, err - } - if dst := rib.Tables[af].GetDestination(prefix.String()); dst != nil { - if d := dst.ToApiStruct(id); d != nil { - dsts = append(dsts, d) - } - return true, nil - } else { - return false, nil + dsts := make([]*api.Destination, 0, len(rib.Tables[af].GetDestinations())) + 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) + if err != nil { + return false, err + } + if dst := rib.Tables[af].GetDestination(prefix.String()); dst != nil { + if d := dst.ToApiStruct(id); d != nil { + dsts = append(dsts, d) } + return true, nil + } else { + return false, nil } - for _, dst := range arg.Table.Destinations { - key := dst.Prefix - if _, err := f(id, key); err != nil { - if host := net.ParseIP(key); host != nil { - masklen := 32 - if af == bgp.RF_IPv6_UC { - masklen = 128 - } - for i := masklen; i > 0; i-- { - if y, _ := f(id, fmt.Sprintf("%s/%d", key, i)); y { - break - } - } + } + for _, dst := range arg.Table.Destinations { + key := dst.Prefix + if _, err := f(id, key); err != nil { + if host := net.ParseIP(key); host != nil { + masklen := 32 + if af == bgp.RF_IPv6_UC { + masklen = 128 } - } else if dst.LongerPrefixes { - _, prefix, _ := net.ParseCIDR(key) - ones, bits := prefix.Mask.Size() - for i := ones + 1; i <= bits; i++ { - prefix.Mask = net.CIDRMask(i, bits) - f(id, prefix.String()) + for i := masklen; i > 0; i-- { + if y, _ := f(id, fmt.Sprintf("%s/%d", key, i)); y { + break + } } } + } else if dst.LongerPrefixes { + _, prefix, _ := net.ParseCIDR(key) + ones, bits := prefix.Mask.Size() + for i := ones + 1; i <= bits; i++ { + prefix.Mask = net.CIDRMask(i, bits) + f(id, prefix.String()) + } } - d.Destinations = dsts - } else { - d.Destinations = sortedDsts(id, rib.Tables[af]) } - default: - d.Destinations = make([]*api.Destination, 0, len(rib.Tables[af].GetDestinations())) - for _, dst := range rib.Tables[af].GetDestinations() { - if s := dst.ToApiStruct(id); s != nil { - d.Destinations = append(d.Destinations, s) + } else { + for _, dst := range rib.Tables[af].GetSortedDestinations() { + if d := dst.ToApiStruct(id); d != nil { + dsts = append(dsts, d) } } } + d.Destinations = dsts grpcReq.ResponseCh <- &GrpcResponse{ Data: &api.GetRibResponse{Table: d}, } |