summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gobgp/monitor.go2
-rw-r--r--gobgp/neighbor.go29
-rw-r--r--server/server.go29
-rw-r--r--table/destination.go16
4 files changed, 64 insertions, 12 deletions
diff --git a/gobgp/monitor.go b/gobgp/monitor.go
index a093ac31..bd96622d 100644
--- a/gobgp/monitor.go
+++ b/gobgp/monitor.go
@@ -63,7 +63,7 @@ func NewMonitorCmd() *cobra.Command {
j, _ := json.Marshal(p)
fmt.Println(string(j))
} else {
- showRoute([]*Path{p}, false, false, true)
+ showRoute([]*Path{p}, false, false, true, true)
}
}
diff --git a/gobgp/neighbor.go b/gobgp/neighbor.go
index adc2b9fb..b8c60273 100644
--- a/gobgp/neighbor.go
+++ b/gobgp/neighbor.go
@@ -231,7 +231,7 @@ type AsPathFormat struct {
separator string
}
-func showRoute(pathList []*Path, showAge bool, showBest bool, isMonitor bool) {
+func showRoute(pathList []*Path, showAge bool, showBest bool, isMonitor, printHeader bool) {
var pathStrs [][]interface{}
maxPrefixLen := 20
@@ -349,10 +349,14 @@ func showRoute(pathList []*Path, showAge bool, showBest bool, isMonitor bool) {
format = "[%s] %s via %s aspath [%s] attrs %s\n"
} else if showAge {
format = fmt.Sprintf("%%-3s %%-%ds %%-%ds %%-%ds %%-10s %%-s\n", maxPrefixLen, maxNexthopLen, maxAsPathLen)
- fmt.Printf(format, "", "Network", "Next Hop", "AS_PATH", "Age", "Attrs")
+ if printHeader {
+ fmt.Printf(format, "", "Network", "Next Hop", "AS_PATH", "Age", "Attrs")
+ }
} else {
format = fmt.Sprintf("%%-3s %%-%ds %%-%ds %%-%ds %%-s\n", maxPrefixLen, maxNexthopLen, maxAsPathLen)
- fmt.Printf(format, "", "Network", "Next Hop", "AS_PATH", "Attrs")
+ if printHeader {
+ fmt.Printf(format, "", "Network", "Next Hop", "AS_PATH", "Attrs")
+ }
}
for _, pathStr := range pathStrs {
@@ -414,6 +418,7 @@ func showNeighborRib(r string, name string, args []string) error {
dsts := []*Destination{}
maxOnes := 0
+ counter := 0
for {
d, e := stream.Recv()
if e == io.EOF {
@@ -443,6 +448,17 @@ func showNeighborRib(r string, name string, args []string) error {
if err != nil {
return err
}
+ if rf == bgp.RF_IPv4_UC && !globalOpts.Json && len(dst.Paths) > 0 {
+ ps := paths{}
+ ps = append(ps, dst.Paths...)
+ sort.Sort(ps)
+ if counter == 0 {
+ showRoute(ps, showAge, showBest, false, true)
+ } else {
+ showRoute(ps, showAge, showBest, false, false)
+ }
+ counter++
+ }
dsts = append(dsts, dst)
}
@@ -452,6 +468,11 @@ func showNeighborRib(r string, name string, args []string) error {
return nil
}
+ if rf == bgp.RF_IPv4_UC && counter != 0 {
+ // we already showed
+ return nil
+ }
+
ps := paths{}
for _, dst := range dsts {
ps = append(ps, dst.Paths...)
@@ -463,7 +484,7 @@ func showNeighborRib(r string, name string, args []string) error {
}
sort.Sort(ps)
- showRoute(ps, showAge, showBest, false)
+ showRoute(ps, showAge, showBest, false, true)
return nil
}
diff --git a/server/server.go b/server/server.go
index 063431d6..78e9095f 100644
--- a/server/server.go
+++ b/server/server.go
@@ -19,6 +19,7 @@ import (
"bytes"
"fmt"
log "github.com/Sirupsen/logrus"
+ "github.com/armon/go-radix"
"github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet"
@@ -1089,12 +1090,28 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
case REQ_GLOBAL_RIB:
if t, ok := server.localRibMap[GLOBAL_RIB_NAME].rib.Tables[grpcReq.RouteFamily]; ok {
results := make([]*GrpcResponse, len(t.GetDestinations()))
- i := 0
- for _, dst := range t.GetDestinations() {
- result := &GrpcResponse{}
- result.Data = dst.ToApiStruct()
- results[i] = result
- i++
+ if grpcReq.RouteFamily == bgp.RF_IPv4_UC {
+ r := radix.New()
+ for _, dst := range t.GetDestinations() {
+ result := &GrpcResponse{}
+ result.Data = dst.ToApiStruct()
+ r.Insert(dst.RadixKey, result)
+ }
+ i := 0
+ r.Walk(func(s string, v interface{}) bool {
+ r, _ := v.(*GrpcResponse)
+ results[i] = r
+ i++
+ return false
+ })
+ } else {
+ i := 0
+ for _, dst := range t.GetDestinations() {
+ result := &GrpcResponse{}
+ result.Data = dst.ToApiStruct()
+ results[i] = result
+ i++
+ }
}
go sendMultipleResponses(grpcReq, results)
}
diff --git a/table/destination.go b/table/destination.go
index 75072732..f669cced 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -16,6 +16,7 @@
package table
import (
+ "bytes"
"encoding/binary"
"encoding/json"
"fmt"
@@ -71,16 +72,29 @@ type Destination struct {
newPathList []*Path
bestPath *Path
bestPathReason string
+ RadixKey string
}
func NewDestination(nlri bgp.AddrPrefixInterface) *Destination {
- return &Destination{
+ d := &Destination{
routeFamily: bgp.AfiSafiToRouteFamily(nlri.AFI(), nlri.SAFI()),
nlri: nlri,
knownPathList: make([]*Path, 0),
withdrawList: make([]*Path, 0),
newPathList: make([]*Path, 0),
}
+ if d.routeFamily == bgp.RF_IPv4_UC {
+ d.RadixKey = func(cidr string) string {
+ _, n, _ := net.ParseCIDR(cidr)
+ ones, _ := n.Mask.Size()
+ var buffer bytes.Buffer
+ for i := 0; i < len(n.IP) && i < ones; i++ {
+ buffer.WriteString(fmt.Sprintf("%08b", n.IP[i]))
+ }
+ return buffer.String()[:ones]
+ }(nlri.String())
+ }
+ return d
}
func (dd *Destination) MarshalJSON() ([]byte, error) {