From d405c203ad8070298f256856605edb6d5480ba04 Mon Sep 17 00:00:00 2001 From: ISHIDA Wataru Date: Fri, 10 Apr 2015 15:38:46 +0000 Subject: table: sort peers/routes at client side instead of bgpd side peer/route sorting is for pretty priting. do it at the client side. Signed-off-by: ISHIDA Wataru --- gobgp/main.go | 73 ++++++++++++++++++++++++++++++++++++++-- server/server.go | 33 +----------------- table/table.go | 90 -------------------------------------------------- table/table_manager.go | 13 ++------ 4 files changed, 73 insertions(+), 136 deletions(-) diff --git a/gobgp/main.go b/gobgp/main.go index fcc16b17..3028073c 100644 --- a/gobgp/main.go +++ b/gobgp/main.go @@ -52,6 +52,66 @@ func formatTimedelta(d int64) string { } } +func cidr2prefix(cidr string) string { + _, n, err := net.ParseCIDR(cidr) + if err != nil { + return cidr + } + var buffer bytes.Buffer + for i := 0; i < len(n.IP); i++ { + buffer.WriteString(fmt.Sprintf("%08b", n.IP[i])) + } + ones, _ := n.Mask.Size() + return buffer.String()[:ones] +} + +type paths []*api.Path + +func (p paths) Len() int { + return len(p) +} + +func (p paths) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} + +func (p paths) Less(i, j int) bool { + if p[i].Nlri.Prefix == p[j].Nlri.Prefix { + if p[i].Best { + return true + } + } + strings := sort.StringSlice{cidr2prefix(p[i].Nlri.Prefix), + cidr2prefix(p[j].Nlri.Prefix)} + return strings.Less(0, 1) +} + +type peers []*api.Peer + +func (p peers) Len() int { + return len(p) +} + +func (p peers) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} + +func (p peers) Less(i, j int) bool { + p1 := net.ParseIP(p[i].Conf.RemoteIp) + p2 := net.ParseIP(p[j].Conf.RemoteIp) + p1Isv4 := p1.To4() != nil + p2Isv4 := p2.To4() != nil + if p1Isv4 != p2Isv4 { + if p1Isv4 { + return true + } + return false + } + strings := sort.StringSlice{cidr2prefix(fmt.Sprintf("%s/32", p1.String())), + cidr2prefix(fmt.Sprintf("%s/32", p2.String()))} + return strings.Less(0, 1) +} + var client api.GrpcClient type ShowNeighborCommand struct { @@ -283,7 +343,7 @@ func (x *ShowNeighborRibCommand) Execute(args []string) error { RouterId: x.remoteIP.String(), } - ps := []*api.Path{} + ps := paths{} showBest := false showAge := true @@ -344,6 +404,8 @@ func (x *ShowNeighborRibCommand) Execute(args []string) error { } } + sort.Sort(ps) + showRoute(ps, showAge, showBest) return nil } @@ -365,7 +427,7 @@ func (x *ShowNeighborsCommand) Execute(args []string) error { fmt.Println(e) return e } - m := []*api.Peer{} + m := peers{} for { p, e := stream.Recv() if e == io.EOF { @@ -392,6 +454,9 @@ func (x *ShowNeighborsCommand) Execute(args []string) error { maxaslen := 0 maxtimelen := len("Up/Down") timedelta := []string{} + + sort.Sort(m) + for _, p := range m { if len(p.Conf.RemoteIp) > maxaddrlen { maxaddrlen = len(p.Conf.RemoteIp) @@ -491,7 +556,7 @@ func (x *ShowGlobalCommand) Execute(args []string) error { return nil } - ps := []*api.Path{} + ps := paths{} for _, d := range ds { for idx, p := range d.Paths { if idx == int(d.BestPathIdx) { @@ -501,6 +566,8 @@ func (x *ShowGlobalCommand) Execute(args []string) error { } } + sort.Sort(ps) + showRoute(ps, true, true) return nil } diff --git a/server/server.go b/server/server.go index c83c48df..5492cb1c 100644 --- a/server/server.go +++ b/server/server.go @@ -22,7 +22,6 @@ import ( "github.com/osrg/gobgp/policy" "net" "os" - "sort" "strconv" ) @@ -267,42 +266,12 @@ func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) { server.policyMap = pMap } -type peers []*Peer - -func (p peers) Len() int { - return len(p) -} - -func (p peers) Swap(i, j int) { - p[i], p[j] = p[j], p[i] -} - -func (p peers) Less(i, j int) bool { - p1 := p[i].peerConfig.NeighborAddress - p2 := p[j].peerConfig.NeighborAddress - p1Isv4 := p1.To4() != nil - p2Isv4 := p2.To4() != nil - if p1Isv4 != p2Isv4 { - if p1Isv4 == true { - return true - } - return false - } - strings := sort.StringSlice{p1.String(), p2.String()} - return strings.Less(0, 1) -} - func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { switch grpcReq.RequestType { case REQ_NEIGHBORS: - peerList := peers{} for _, info := range server.peerMap { - peerList = append(peerList, info.peer) - } - sort.Sort(peerList) - for _, peer := range peerList { result := &GrpcResponse{ - Data: peer.ToApiStruct(), + Data: info.peer.ToApiStruct(), } grpcReq.ResponseCh <- result } diff --git a/table/table.go b/table/table.go index d9c14144..4739b292 100644 --- a/table/table.go +++ b/table/table.go @@ -16,16 +16,9 @@ package table import ( - "bytes" - "encoding/json" - "fmt" log "github.com/Sirupsen/logrus" "github.com/osrg/gobgp/packet" - "github.com/tchap/go-patricia/patricia" - "net" "reflect" - "strconv" - "strings" ) type Table interface { @@ -38,7 +31,6 @@ type Table interface { validatePath(path Path) validateNlri(nlri bgp.AddrPrefixInterface) DeleteDestByPeer(*PeerInfo) []Destination - MarshalJSON() ([]byte, error) } type TableDefault struct { @@ -55,39 +47,6 @@ func NewTableDefault(scope_id int) *TableDefault { } -func cidr2prefix(cidr string) patricia.Prefix { - _, n, err := net.ParseCIDR(cidr) - if err != nil { - return patricia.Prefix(cidr) - } - var buffer bytes.Buffer - for i := 0; i < len(n.IP); i++ { - buffer.WriteString(fmt.Sprintf("%08b", n.IP[i])) - } - ones, _ := n.Mask.Size() - return patricia.Prefix(buffer.String()[:ones]) -} - -func (td *TableDefault) MarshalJSON() ([]byte, error) { - trie := patricia.NewTrie() - for key, dest := range td.destinations { - trie.Insert(cidr2prefix(key), dest) - } - - destList := make([]Destination, 0) - trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error { - dest, _ := item.(Destination) - destList = append(destList, dest) - return nil - }) - - return json.Marshal(struct { - Destinations []Destination - }{ - Destinations: destList, - }) -} - func (td *TableDefault) GetRoutefamily() bgp.RouteFamily { return td.ROUTE_FAMILY } @@ -349,42 +308,6 @@ func (ipv4vpnt *IPv4VPNTable) tableKey(nlri bgp.AddrPrefixInterface) string { } -func ParseLabbelledVpnPrefix(key string) patricia.Prefix { - vpnaddrprefix := strings.Split(key, "/") - length, _ := strconv.ParseInt(vpnaddrprefix[1], 10, 0) - _, n, _ := net.ParseCIDR(vpnaddrprefix[0] + "/" + strconv.FormatInt((int64(length)-88), 10)) - - var buffer bytes.Buffer - for i := 0; i < len(n.IP); i++ { - buffer.WriteString(fmt.Sprintf("%08b", n.IP[i])) - } - ones, _ := n.Mask.Size() - return patricia.Prefix(buffer.String()[:ones]) - -} - -func (ipv4vpnt *IPv4VPNTable) MarshalJSON() ([]byte, error) { - - trie := patricia.NewTrie() - for key, dest := range ipv4vpnt.destinations { - trie.Insert(ParseLabbelledVpnPrefix(key), dest) - } - - destList := make([]Destination, 0) - trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error { - dest, _ := item.(Destination) - destList = append(destList, dest) - return nil - }) - - return json.Marshal(struct { - Destinations []Destination - }{ - Destinations: destList, - }) - -} - type EVPNTable struct { *TableDefault //need structure @@ -411,16 +334,3 @@ func (ipv4vpnt *EVPNTable) tableKey(nlri bgp.AddrPrefixInterface) string { addrPrefix := nlri.(*bgp.EVPNNLRI) return addrPrefix.String() } - -func ParseEVPNPrefix(key string) patricia.Prefix { - vpnaddrprefix := strings.Split(key, "/") - length, _ := strconv.ParseInt(vpnaddrprefix[1], 10, 0) - _, n, _ := net.ParseCIDR(vpnaddrprefix[0] + "/" + strconv.FormatInt((int64(length)-88), 10)) - - var buffer bytes.Buffer - for i := 0; i < len(n.IP); i++ { - buffer.WriteString(fmt.Sprintf("%08b", n.IP[i])) - } - ones, _ := n.Mask.Size() - return patricia.Prefix(buffer.String()[:ones]) -} diff --git a/table/table_manager.go b/table/table_manager.go index 679b684c..df89a2eb 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -18,7 +18,6 @@ package table import ( log "github.com/Sirupsen/logrus" "github.com/osrg/gobgp/packet" - "github.com/tchap/go-patricia/patricia" "reflect" "time" ) @@ -341,18 +340,10 @@ func (adj *AdjRib) UpdateOut(pathList []Path) { } func (adj *AdjRib) getPathList(rib map[string]*ReceivedRoute) []Path { - trie := patricia.NewTrie() + pathList := make([]Path, 0, len(rib)) for _, rr := range rib { - key := rr.path.GetNlri().String() - trie.Insert(cidr2prefix(key), rr.path) + pathList = append(pathList, rr.path) } - - pathList := []Path{} - trie.Visit(func(prefix patricia.Prefix, item patricia.Item) error { - path, _ := item.(Path) - pathList = append(pathList, path) - return nil - }) return pathList } -- cgit v1.2.3