summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-12-04 10:54:00 +0900
committerISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-12-04 11:01:07 +0900
commit7ff862f3eefceb3a58ca8be09ead21336d5cb504 (patch)
tree83f99e8d3af9e7ca170d0d5d934bfd0e4dd50315
parenta36c84c510bd7cde344e6cbabd043153e4a0196c (diff)
api/cli: support showing longer-prefix
$ gobgp global rib Network Next Hop AS_PATH Age Attrs *> 10.0.0.0/24 0.0.0.0 00:00:01 [{Origin: ?}] $ gobgp global rib 10.0.0.0/20 Network not in table $ gobgp global rib 10.0.0.0/20 longer-prefix Network Next Hop AS_PATH Age Attrs *> 10.0.0.0/24 0.0.0.0 00:00:01 [{Origin: ?}] Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--api/gobgp.pb.go43
-rw-r--r--api/gobgp.proto1
-rw-r--r--docs/sources/cli-command-syntax.md4
-rw-r--r--gobgp/cmd/neighbor.go10
-rw-r--r--server/server.go14
5 files changed, 46 insertions, 26 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index c3956e92..d59a11da 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -22,9 +22,9 @@ It has these top-level messages:
ModPolicyArguments
ModPolicyAssignmentArguments
ModGlobalConfigArguments
- Table
Path
Destination
+ Table
Peer
AddPaths
AfiSafis
@@ -518,24 +518,6 @@ func (m *ModGlobalConfigArguments) GetGlobal() *Global {
return nil
}
-type Table struct {
- Type Resource `protobuf:"varint,1,opt,name=type,enum=gobgpapi.Resource" json:"type,omitempty"`
- Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
- Family uint32 `protobuf:"varint,3,opt,name=family" json:"family,omitempty"`
- Destinations []*Destination `protobuf:"bytes,4,rep,name=destinations" json:"destinations,omitempty"`
-}
-
-func (m *Table) Reset() { *m = Table{} }
-func (m *Table) String() string { return proto.CompactTextString(m) }
-func (*Table) ProtoMessage() {}
-
-func (m *Table) GetDestinations() []*Destination {
- if m != nil {
- return m.Destinations
- }
- return nil
-}
-
type Path struct {
Nlri []byte `protobuf:"bytes,1,opt,name=nlri,proto3" json:"nlri,omitempty"`
Pattrs [][]byte `protobuf:"bytes,2,rep,name=pattrs,proto3" json:"pattrs,omitempty"`
@@ -555,8 +537,9 @@ func (m *Path) String() string { return proto.CompactTextString(m) }
func (*Path) ProtoMessage() {}
type Destination struct {
- Prefix string `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"`
- Paths []*Path `protobuf:"bytes,2,rep,name=paths" json:"paths,omitempty"`
+ Prefix string `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"`
+ Paths []*Path `protobuf:"bytes,2,rep,name=paths" json:"paths,omitempty"`
+ LongerPrefix bool `protobuf:"varint,3,opt,name=longer_prefix" json:"longer_prefix,omitempty"`
}
func (m *Destination) Reset() { *m = Destination{} }
@@ -570,6 +553,24 @@ func (m *Destination) GetPaths() []*Path {
return nil
}
+type Table struct {
+ Type Resource `protobuf:"varint,1,opt,name=type,enum=gobgpapi.Resource" json:"type,omitempty"`
+ Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
+ Family uint32 `protobuf:"varint,3,opt,name=family" json:"family,omitempty"`
+ Destinations []*Destination `protobuf:"bytes,4,rep,name=destinations" json:"destinations,omitempty"`
+}
+
+func (m *Table) Reset() { *m = Table{} }
+func (m *Table) String() string { return proto.CompactTextString(m) }
+func (*Table) ProtoMessage() {}
+
+func (m *Table) GetDestinations() []*Destination {
+ if m != nil {
+ return m.Destinations
+ }
+ return nil
+}
+
type Peer struct {
Addpaths *AddPaths `protobuf:"bytes,1,opt,name=addpaths" json:"addpaths,omitempty"`
Afisafis *AfiSafis `protobuf:"bytes,2,opt,name=afisafis" json:"afisafis,omitempty"`
diff --git a/api/gobgp.proto b/api/gobgp.proto
index ab9e0d2d..b78020bb 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -170,6 +170,7 @@ message Path {
message Destination {
string prefix = 1;
repeated Path paths = 2;
+ bool longer_prefix = 3;
}
message Table {
diff --git a/docs/sources/cli-command-syntax.md b/docs/sources/cli-command-syntax.md
index 90c3c5dd..01ddbf6a 100644
--- a/docs/sources/cli-command-syntax.md
+++ b/docs/sources/cli-command-syntax.md
@@ -27,7 +27,7 @@ gobgp has six subcommands.
# show all Route information
% gobgp global rib [-a <address family>]
# show a specific route information
-% gobgp global rib [<prefix>|<host>] [-a <address family>]
+% gobgp global rib [<prefix>|<host>] [longer-prefix] [-a <address family>]
```
#### - example
@@ -84,7 +84,7 @@ The following options can be specified in the global subcommand:
# show all routes in [local|adj-in|adj-out] table
% gobgp neighbor <neighbor address> [local|adj-in|adj-out] [-a <address family>]
# show a specific route in [local|adj-in|adj-out] table
-% gobgp neighbor <neighbor address> [local|adj-in|adj-out] [<prefix>|<host>] [-a <address family>]
+% gobgp neighbor <neighbor address> [local|adj-in|adj-out] [<prefix>|<host>] [longer-prefix] [-a <address family>]
```
#### - example
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index 55aaa959..41b7579e 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -410,9 +410,17 @@ func showNeighborRib(r string, name string, args []string) error {
if rf != bgp.RF_IPv4_UC && rf != bgp.RF_IPv6_UC {
return fmt.Errorf("route filtering is only supported for IPv4/IPv6 unicast routes")
}
+ longerPrefix := false
+ if len(args) > 1 {
+ if args[1] != "longer-prefix" {
+ return fmt.Errorf("invalid format for route filtering")
+ }
+ longerPrefix = true
+ }
arg.Destinations = []*api.Destination{
&api.Destination{
- Prefix: args[0],
+ Prefix: args[0],
+ LongerPrefix: longerPrefix,
},
}
}
diff --git a/server/server.go b/server/server.go
index a09b7d02..089d8e0a 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1441,18 +1441,28 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
for _, dst := range arg.Destinations {
key := dst.Prefix
- if _, err := f(key); err != nil {
+ y, err := f(key)
+ if 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(fmt.Sprintf("%s/%d", key, i)); y {
+ if y, _ = f(fmt.Sprintf("%s/%d", key, i)); y {
break
}
}
}
+ } else if !y && dst.LongerPrefix {
+ _, prefix, _ := net.ParseCIDR(key)
+ ones, bits := prefix.Mask.Size()
+ for i := ones + 1; i <= bits; i++ {
+ prefix.Mask = net.CIDRMask(i, bits)
+ if y, _ = f(prefix.String()); y {
+ break
+ }
+ }
}
}
d.Destinations = dsts