diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-06-26 13:10:15 +0900 |
---|---|---|
committer | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-06-26 13:10:15 +0900 |
commit | 69b36e90ba70131bf67127968e6bb8fa80460161 (patch) | |
tree | fd60319600f9963aa4a29edc4f113eb3a4e38d03 | |
parent | dd11fa616a9b22d63669d65712552ef94c85e7ef (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.md | 11 | ||||
-rw-r--r-- | gobgp/global.go | 53 | ||||
-rw-r--r-- | gobgp/neighbor.go | 70 |
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) |