summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-06-26 13:10:15 +0900
committerISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-06-26 13:10:15 +0900
commit69b36e90ba70131bf67127968e6bb8fa80460161 (patch)
treefd60319600f9963aa4a29edc4f113eb3a4e38d03
parentdd11fa616a9b22d63669d65712552ef94c85e7ef (diff)
cli: add support of route filtering in show commands
$ gobgp global rib Network Next Hop AS_PATH Age Attrs *> 10.0.0.0/24 0.0.0.0 65000 00:10:17 [{Origin: IGP}] *> 10.0.0.0/25 0.0.0.0 65000 00:10:16 [{Origin: IGP}] *> 10.0.0.0/26 0.0.0.0 65000 00:10:15 [{Origin: IGP}] *> 10.0.1.0/24 0.0.0.0 65000 00:10:21 [{Origin: IGP}] *> 10.0.2.0/24 0.0.0.0 65000 00:10:20 [{Origin: IGP}] $ gobgp global rib 10.0.0.0/24 Network Next Hop AS_PATH Age Attrs *> 10.0.0.0/24 0.0.0.0 65000 00:10:54 [{Origin: IGP}] $ gobgp global rib 10.0.0.10 Network Next Hop AS_PATH Age Attrs *> 10.0.0.0/26 0.0.0.0 65000 00:11:16 [{Origin: IGP}] Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
-rw-r--r--docs/sources/cli-command-syntax.md11
-rw-r--r--gobgp/global.go53
-rw-r--r--gobgp/neighbor.go70
3 files changed, 75 insertions, 59 deletions
diff --git a/docs/sources/cli-command-syntax.md b/docs/sources/cli-command-syntax.md
index f183d281..fa7747dd 100644
--- a/docs/sources/cli-command-syntax.md
+++ b/docs/sources/cli-command-syntax.md
@@ -26,6 +26,8 @@ Note: Currently gobgp supports only **global** and **neighbor** subcommand.
% gobgp global rib del <prefix> [-a <address family>]
# show all Route information
% gobgp global rib [-a <address family>]
+# show a specific route information
+% gobgp global rib [<prefix>|<host>] [-a <address family>]
```
- **Option**
- \-a , \-\-address-family: specify the ipv4, ipv6, evpn, encap, or rtc
@@ -58,9 +60,10 @@ Note: Currently gobgp supports only **global** and **neighbor** subcommand.
### Show Rib - local-rib/adj-rib-in/adj-rib-out -
```shell
-% gobgp neighbor <neighbor address> local [-a <address family>]
-% gobgp neighbor <neighbor address> adj-in [-a <address family>]
-% gobgp neighbor <neighbor address> adj-out [-a <address family>]
+# 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>]
```
- **Option**
- \-a , \-\-address-family: specify the ipv4 or ipv6
@@ -167,4 +170,4 @@ Note: Currently gobgp supports only **global** and **neighbor** subcommand.
Specify the options of action when you use the routepolicy add subcommand.
- \-\-a-route : specify the action(accept, reject) of the route that match to the conditions
- - \-\-a-community : specify the community operation of the route that match to the conditions \ No newline at end of file
+ - \-\-a-community : specify the community operation of the route that match to the conditions
diff --git a/gobgp/global.go b/gobgp/global.go
index 93bd1fde..00b0da6c 100644
--- a/gobgp/global.go
+++ b/gobgp/global.go
@@ -16,62 +16,17 @@
package main
import (
- "encoding/json"
"fmt"
"github.com/osrg/gobgp/api"
"github.com/spf13/cobra"
"golang.org/x/net/context"
- "io"
"net"
- "sort"
"strconv"
)
-func showGlobalRib() error {
- rt, err := checkAddressFamily(net.IP{})
- if err != nil {
- return err
- }
- arg := &api.Arguments{
- Resource: api.Resource_GLOBAL,
- Af: rt,
- }
-
- stream, e := client.GetRib(context.Background(), arg)
- if e != nil {
- return e
- }
- ds := []*api.Destination{}
- for {
- d, e := stream.Recv()
- if e == io.EOF {
- break
- } else if e != nil {
- return e
- }
- ds = append(ds, d)
- }
-
- if globalOpts.Json {
- j, _ := json.Marshal(ds)
- fmt.Println(string(j))
- return nil
- }
-
- ps := paths{}
- for _, d := range ds {
- for idx, p := range d.Paths {
- if idx == int(d.BestPathIdx) {
- p.Best = true
- }
- ps = append(ps, p)
- }
- }
-
- sort.Sort(ps)
-
- showRoute(ps, true, true, false)
- return nil
+func showGlobalRib(args []string) error {
+ bogusIp := net.IP{}
+ return showNeighborRib(CMD_GLOBAL, bogusIp, args)
}
func modPath(modtype string, eArgs []string) error {
@@ -208,7 +163,7 @@ func NewGlobalCmd() *cobra.Command {
ribCmd := &cobra.Command{
Use: CMD_RIB,
Run: func(cmd *cobra.Command, args []string) {
- showGlobalRib()
+ showGlobalRib(args)
},
}
diff --git a/gobgp/neighbor.go b/gobgp/neighbor.go
index c478f7a1..a3d8c27b 100644
--- a/gobgp/neighbor.go
+++ b/gobgp/neighbor.go
@@ -381,9 +381,11 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool, isMonitor bool
}
}
-func showNeighborRib(r string, remoteIP net.IP) error {
+func showNeighborRib(r string, remoteIP net.IP, args []string) error {
var resource api.Resource
switch r {
+ case CMD_GLOBAL:
+ resource = api.Resource_GLOBAL
case CMD_LOCAL:
resource = api.Resource_LOCAL
case CMD_ADJ_IN:
@@ -395,6 +397,24 @@ func showNeighborRib(r string, remoteIP net.IP) error {
if err != nil {
return err
}
+
+ var prefix string
+ var host net.IP
+ if len(args) > 0 {
+ if rt != api.AF_IPV4_UC && rt != api.AF_IPV6_UC {
+ return fmt.Errorf("route filtering is only supported for IPv4/IPv6 unicast routes")
+ }
+ _, p, err := net.ParseCIDR(args[0])
+ if err != nil {
+ host = net.ParseIP(args[0])
+ if host == nil {
+ return err
+ }
+ } else {
+ prefix = p.String()
+ }
+ }
+
arg := &api.Arguments{
Resource: resource,
Af: rt,
@@ -405,7 +425,7 @@ func showNeighborRib(r string, remoteIP net.IP) error {
showBest := false
showAge := true
switch resource {
- case api.Resource_LOCAL:
+ case api.Resource_LOCAL, api.Resource_GLOBAL:
showBest = true
stream, e := client.GetRib(context.Background(), arg)
if e != nil {
@@ -413,6 +433,7 @@ func showNeighborRib(r string, remoteIP net.IP) error {
}
ds := []*api.Destination{}
+ maxOnes := 0
for {
d, e := stream.Recv()
if e == io.EOF {
@@ -420,6 +441,19 @@ func showNeighborRib(r string, remoteIP net.IP) error {
} else if e != nil {
return e
}
+ if prefix != "" && prefix != d.Prefix {
+ continue
+ }
+ if host != nil {
+ _, prefix, _ := net.ParseCIDR(d.Prefix)
+ ones, _ := prefix.Mask.Size()
+ if maxOnes < ones && prefix.Contains(host) {
+ ds = []*api.Destination{}
+ maxOnes = ones
+ } else {
+ continue
+ }
+ }
ds = append(ds, d)
}
@@ -445,6 +479,7 @@ func showNeighborRib(r string, remoteIP net.IP) error {
if e != nil {
return e
}
+ maxOnes := 0
for {
p, e := stream.Recv()
if e == io.EOF {
@@ -452,6 +487,24 @@ func showNeighborRib(r string, remoteIP net.IP) error {
} else if e != nil {
return e
}
+ if prefix != "" && prefix != p.Nlri.Prefix {
+ continue
+ }
+ if host != nil {
+ _, prefix, _ := net.ParseCIDR(p.Nlri.Prefix)
+ ones, _ := prefix.Mask.Size()
+ if prefix.Contains(host) {
+ if maxOnes < ones {
+ ps = paths{}
+ maxOnes = ones
+ } else if maxOnes > ones {
+ continue
+ }
+ } else {
+ continue
+ }
+ }
+
ps = append(ps, p)
}
if globalOpts.Json {
@@ -461,12 +514,17 @@ func showNeighborRib(r string, remoteIP net.IP) error {
}
}
+ if len(ps) == 0 {
+ fmt.Println("Network not in table")
+ return nil
+ }
+
sort.Sort(ps)
showRoute(ps, showAge, showBest, false)
return nil
}
-func resetNeighbor(cmd string, remoteIP net.IP) error {
+func resetNeighbor(cmd string, remoteIP net.IP, args []string) error {
rt, err := checkAddressFamily(remoteIP)
if err != nil {
return err
@@ -488,7 +546,7 @@ func resetNeighbor(cmd string, remoteIP net.IP) error {
return nil
}
-func stateChangeNeighbor(cmd string, remoteIP net.IP) error {
+func stateChangeNeighbor(cmd string, remoteIP net.IP, args []string) error {
arg := &api.Arguments{
Af: api.AF_IPV4_UC,
RouterId: remoteIP.String(),
@@ -615,7 +673,7 @@ func NewNeighborCmd() *cobra.Command {
type cmds struct {
names []string
- f func(string, net.IP) error
+ f func(string, net.IP, []string) error
}
c := make([]cmds, 0, 3)
@@ -634,7 +692,7 @@ func NewNeighborCmd() *cobra.Command {
fmt.Println("invalid ip address:", args[len(args)-1])
os.Exit(1)
}
- err := f(cmd.Use, remoteIP)
+ err := f(cmd.Use, remoteIP, args[:len(args)-1])
if err != nil {
fmt.Println(err)
os.Exit(1)