summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--config/util.go18
-rw-r--r--server/peer.go61
-rw-r--r--server/server.go23
-rw-r--r--table/adj.go114
-rw-r--r--table/table_manager.go118
-rw-r--r--table/table_manager_test.go17
6 files changed, 174 insertions, 177 deletions
diff --git a/config/util.go b/config/util.go
index a3606682..50d1b833 100644
--- a/config/util.go
+++ b/config/util.go
@@ -34,11 +34,23 @@ func IsEBGPPeer(g *Global, p *Neighbor) bool {
return p.NeighborConfig.PeerAs != g.GlobalConfig.As
}
+func (c AfiSafis) ToRfList() ([]bgp.RouteFamily, error) {
+ rfs := make([]bgp.RouteFamily, 0, len(c.AfiSafiList))
+ for _, rf := range c.AfiSafiList {
+ k, err := bgp.GetRouteFamily(rf.AfiSafiName)
+ if err != nil {
+ return nil, err
+ }
+ rfs = append(rfs, k)
+ }
+ return rfs, nil
+}
+
func CreateRfMap(p *Neighbor) map[bgp.RouteFamily]bool {
+ rfs, _ := p.AfiSafis.ToRfList()
rfMap := make(map[bgp.RouteFamily]bool)
- for _, rf := range p.AfiSafis.AfiSafiList {
- k, _ := bgp.GetRouteFamily(rf.AfiSafiName)
- rfMap[k] = true
+ for _, rf := range rfs {
+ rfMap[rf] = true
}
return rfMap
}
diff --git a/server/peer.go b/server/peer.go
index ac3c2409..8f43299e 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -37,28 +37,29 @@ type Peer struct {
fsm *FSM
rfMap map[bgp.RouteFamily]bool
capMap map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface
- adjRib *table.AdjRib
+ adjRibIn *table.AdjRib
+ adjRibOut *table.AdjRib
outgoing chan *bgp.BGPMessage
inPolicies []*table.Policy
defaultInPolicy table.RouteType
- accepted uint32
- staleAccepted bool
recvOpen *bgp.BGPMessage
localRib *table.TableManager
}
func NewPeer(g config.Global, conf config.Neighbor, loc *table.TableManager) *Peer {
+ rfs, _ := conf.AfiSafis.ToRfList()
peer := &Peer{
- gConf: g,
- conf: conf,
- rfMap: make(map[bgp.RouteFamily]bool),
- capMap: make(map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface),
- outgoing: make(chan *bgp.BGPMessage, 128),
- localRib: loc,
+ gConf: g,
+ conf: conf,
+ rfMap: make(map[bgp.RouteFamily]bool),
+ capMap: make(map[bgp.BGPCapabilityCode][]bgp.ParameterCapabilityInterface),
+ outgoing: make(chan *bgp.BGPMessage, 128),
+ adjRibIn: table.NewAdjRib(rfs),
+ adjRibOut: table.NewAdjRib(rfs),
+ localRib: loc,
}
conf.NeighborState.SessionState = uint32(bgp.BGP_FSM_IDLE)
conf.Timers.TimersState.Downtime = time.Now().Unix()
- peer.adjRib = table.NewAdjRib(peer.configuredRFlist())
peer.fsm = NewFSM(&g, &conf, peer)
return peer
}
@@ -84,22 +85,12 @@ func (peer *Peer) isRouteReflectorClient() bool {
}
func (peer *Peer) configuredRFlist() []bgp.RouteFamily {
- return peer.localRib.GetRFlist()
-}
-
-func (peer *Peer) updateAccepted(accepted uint32) {
- peer.accepted = accepted
- peer.staleAccepted = false
+ rfs, _ := peer.conf.AfiSafis.ToRfList()
+ return rfs
}
func (peer *Peer) getAccepted(rfList []bgp.RouteFamily) []*table.Path {
- var pathList []*table.Path
- for _, path := range peer.adjRib.GetInPathList(rfList) {
- if path.Filtered == false {
- pathList = append(pathList, path)
- }
- }
- return pathList
+ return peer.adjRibIn.PathList(rfList, true)
}
func (peer *Peer) getBestFromLocal(rfList []bgp.RouteFamily) ([]*table.Path, []*table.Path) {
@@ -184,9 +175,9 @@ func (peer *Peer) handleBGPmessage(e *FsmMsg) ([]*table.Path, bool, []*bgp.BGPMe
}
if _, ok := peer.capMap[bgp.BGP_CAP_ROUTE_REFRESH]; ok {
rfList := []bgp.RouteFamily{rf}
- peer.adjRib.DropOut(rfList)
+ peer.adjRibOut.Drop(rfList)
accepted, filtered := peer.getBestFromLocal(rfList)
- peer.adjRib.UpdateOut(accepted)
+ peer.adjRibOut.Update(accepted)
pathList = append(pathList, accepted...)
for _, path := range filtered {
path.IsWithdraw = true
@@ -203,9 +194,8 @@ func (peer *Peer) handleBGPmessage(e *FsmMsg) ([]*table.Path, bool, []*bgp.BGPMe
update = true
peer.conf.Timers.TimersState.UpdateRecvTime = time.Now().Unix()
if len(e.PathList) > 0 {
+ peer.adjRibIn.Update(e.PathList)
pathList = e.PathList
- peer.staleAccepted = true
- peer.adjRib.UpdateIn(pathList)
}
case bgp.BGP_MSG_NOTIFICATION:
body := m.Body.(*bgp.BGPNotification)
@@ -284,14 +274,9 @@ func (peer *Peer) ToApiStruct() *api.Peer {
accepted := uint32(0)
if f.state == bgp.BGP_FSM_ESTABLISHED {
rfList := peer.configuredRFlist()
- advertized = uint32(peer.adjRib.GetOutCount(rfList))
- received = uint32(peer.adjRib.GetInCount(rfList))
- if peer.staleAccepted {
- accepted = uint32(len(peer.getAccepted(rfList)))
- peer.updateAccepted(accepted)
- } else {
- accepted = peer.accepted
- }
+ advertized = uint32(peer.adjRibOut.Count(rfList))
+ received = uint32(peer.adjRibIn.Count(rfList))
+ accepted = uint32(peer.adjRibIn.Accepted(rfList))
}
uptime := int64(0)
@@ -448,8 +433,6 @@ func (peer *Peer) ApplyPolicy(d table.PolicyDirection, paths []*table.Path) ([]*
}
func (peer *Peer) DropAll(rfList []bgp.RouteFamily) {
- peer.adjRib.DropIn(rfList)
- peer.adjRib.DropOut(rfList)
- peer.staleAccepted = false
- peer.accepted = 0
+ peer.adjRibIn.Drop(rfList)
+ peer.adjRibOut.Drop(rfList)
}
diff --git a/server/server.go b/server/server.go
index 3bd4b448..a09b7d02 100644
--- a/server/server.go
+++ b/server/server.go
@@ -329,7 +329,7 @@ func (server *BgpServer) Serve() {
if targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED {
continue
}
- for _, p := range targetPeer.adjRib.GetInPathList(targetPeer.configuredRFlist()) {
+ for _, p := range targetPeer.adjRibIn.PathList(targetPeer.configuredRFlist(), false) {
// avoid to merge for timestamp
u := table.CreateUpdateMsgFromPaths([]*table.Path{p})
buf, _ := u[0].Serialize()
@@ -560,7 +560,7 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer) []*SenderMsg {
}
msgList := table.CreateUpdateMsgFromPaths(pathList)
msgs = append(msgs, newSenderMsg(targetPeer, msgList))
- targetPeer.adjRib.UpdateOut(pathList)
+ targetPeer.adjRibOut.Update(pathList)
}
} else {
rib := server.globalRib
@@ -579,7 +579,7 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer) []*SenderMsg {
if _, ok := targetPeer.rfMap[rf]; !ok {
continue
}
- targetPeer.adjRib.UpdateOut(pathList)
+ targetPeer.adjRibOut.Update(pathList)
msgs = append(msgs, newSenderMsg(targetPeer, msgList))
}
}
@@ -678,7 +678,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
continue
}
msgList := table.CreateUpdateMsgFromPaths(sendPathList)
- targetPeer.adjRib.UpdateOut(sendPathList)
+ targetPeer.adjRibOut.Update(sendPathList)
msgs = append(msgs, newSenderMsg(targetPeer, msgList))
}
} else {
@@ -702,9 +702,8 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
for _, path := range f {
path.UpdatePathAttrs(&server.bgpConfig.Global, &targetPeer.conf)
}
- targetPeer.adjRib.UpdateOut(f)
+ targetPeer.adjRibOut.Update(f)
msgList := table.CreateUpdateMsgFromPaths(f)
-
msgs = append(msgs, newSenderMsg(targetPeer, msgList))
}
}
@@ -755,7 +754,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg, incoming chan *
}
pathList, _ := peer.getBestFromLocal(peer.configuredRFlist())
if len(pathList) > 0 {
- peer.adjRib.UpdateOut(pathList)
+ peer.adjRibOut.Update(pathList)
msgs = append(msgs, newSenderMsg(peer, table.CreateUpdateMsgFromPaths(pathList)))
}
} else {
@@ -1517,10 +1516,10 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
rf := bgp.RouteFamily(arg.Family)
var paths []*table.Path
if grpcReq.RequestType == REQ_ADJ_RIB_IN {
- paths = peer.adjRib.GetInPathList([]bgp.RouteFamily{rf})
+ paths = peer.adjRibIn.PathList([]bgp.RouteFamily{rf}, false)
log.Debugf("RouteFamily=%v adj-rib-in found : %d", rf.String(), len(paths))
} else {
- paths = peer.adjRib.GetOutPathList([]bgp.RouteFamily{rf})
+ paths = peer.adjRibOut.PathList([]bgp.RouteFamily{rf}, false)
log.Debugf("RouteFamily=%v adj-rib-out found : %d", rf.String(), len(paths))
}
@@ -1602,7 +1601,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
for _, peer := range peers {
- pathList := peer.adjRib.GetInPathList([]bgp.RouteFamily{grpcReq.RouteFamily})
+ pathList := peer.adjRibIn.PathList([]bgp.RouteFamily{grpcReq.RouteFamily}, false)
if peer.isRouteServerClient() {
pathList, _ = peer.ApplyPolicy(table.POLICY_DIRECTION_IN, pathList)
}
@@ -1625,10 +1624,10 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
for _, peer := range peers {
rfList := peer.configuredRFlist()
- peer.adjRib.DropOut(rfList)
+ peer.adjRibOut.Drop(rfList)
pathList, filtered := peer.getBestFromLocal(rfList)
if len(pathList) > 0 {
- peer.adjRib.UpdateOut(pathList)
+ peer.adjRibOut.Update(pathList)
msgs = append(msgs, newSenderMsg(peer, table.CreateUpdateMsgFromPaths(pathList)))
}
if len(filtered) > 0 {
diff --git a/table/adj.go b/table/adj.go
new file mode 100644
index 00000000..019ad3c8
--- /dev/null
+++ b/table/adj.go
@@ -0,0 +1,114 @@
+// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package table
+
+import (
+ "github.com/osrg/gobgp/packet"
+ "reflect"
+)
+
+type AdjRib struct {
+ accepted map[bgp.RouteFamily]int
+ table map[bgp.RouteFamily]map[string]*Path
+}
+
+func NewAdjRib(rfList []bgp.RouteFamily) *AdjRib {
+ table := make(map[bgp.RouteFamily]map[string]*Path)
+ for _, rf := range rfList {
+ table[rf] = make(map[string]*Path)
+ }
+ return &AdjRib{
+ table: table,
+ accepted: make(map[bgp.RouteFamily]int),
+ }
+}
+
+func (adj *AdjRib) Update(pathList []*Path) {
+ for _, path := range pathList {
+ if path == nil {
+ continue
+ }
+ rf := path.GetRouteFamily()
+ key := path.getPrefix()
+ old, found := adj.table[rf][key]
+ if path.IsWithdraw {
+ if found {
+ delete(adj.table[rf], key)
+ if !old.Filtered {
+ adj.accepted[rf]--
+ }
+ }
+ } else {
+ if found {
+ if old.Filtered && !path.Filtered {
+ adj.accepted[rf]++
+ } else if !old.Filtered && path.Filtered {
+ adj.accepted[rf]--
+ }
+ } else {
+ if !path.Filtered {
+ adj.accepted[rf]++
+ }
+ }
+ if found && reflect.DeepEqual(old.GetPathAttrs(), path.GetPathAttrs()) {
+ path.setTimestamp(old.GetTimestamp())
+ }
+ adj.table[rf][key] = path
+ }
+ }
+}
+
+func (adj *AdjRib) PathList(rfList []bgp.RouteFamily, accepted bool) []*Path {
+ pathList := make([]*Path, 0, adj.Count(rfList))
+ for _, rf := range rfList {
+ for _, rr := range adj.table[rf] {
+ if accepted && rr.Filtered {
+ continue
+ }
+ pathList = append(pathList, rr)
+ }
+ }
+ return pathList
+}
+
+func (adj *AdjRib) Count(rfList []bgp.RouteFamily) int {
+ count := 0
+ for _, rf := range rfList {
+ if table, ok := adj.table[rf]; ok {
+ count += len(table)
+ }
+ }
+ return count
+}
+
+func (adj *AdjRib) Accepted(rfList []bgp.RouteFamily) int {
+ count := 0
+ for _, rf := range rfList {
+ if n, ok := adj.accepted[rf]; ok {
+ count += n
+ }
+ }
+ return count
+}
+
+func (adj *AdjRib) Drop(rfList []bgp.RouteFamily) {
+ for _, rf := range rfList {
+ if _, ok := adj.table[rf]; ok {
+ adj.table[rf] = make(map[string]*Path)
+ adj.accepted[rf] = 0
+ }
+ }
+}
diff --git a/table/table_manager.go b/table/table_manager.go
index 03d8ed83..637299b9 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -21,7 +21,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/osrg/gobgp/packet"
"net"
- "reflect"
"time"
)
@@ -489,120 +488,3 @@ func (manager *TableManager) GetBestPathList(rfList []bgp.RouteFamily) []*Path {
}
return paths
}
-
-// process BGPUpdate message
-// this function processes only BGPUpdate
-func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) {
- // check msg's type if it's BGPUpdate
- if message.Header.Type != bgp.BGP_MSG_UPDATE {
- log.WithFields(log.Fields{
- "Topic": "table",
- "Owner": manager.owner,
- "key": fromPeer.Address.String(),
- "Type": message.Header.Type,
- }).Warn("message is not BGPUpdate")
- return []*Path{}, nil
- }
-
- return manager.ProcessPaths(ProcessMessage(message, fromPeer, time.Now()))
-}
-
-type AdjRib struct {
- adjRibIn map[bgp.RouteFamily]map[string]*Path
- adjRibOut map[bgp.RouteFamily]map[string]*Path
-}
-
-func NewAdjRib(rfList []bgp.RouteFamily) *AdjRib {
- r := &AdjRib{
- adjRibIn: make(map[bgp.RouteFamily]map[string]*Path),
- adjRibOut: make(map[bgp.RouteFamily]map[string]*Path),
- }
- for _, rf := range rfList {
- r.adjRibIn[rf] = make(map[string]*Path)
- r.adjRibOut[rf] = make(map[string]*Path)
- }
- return r
-}
-
-func (adj *AdjRib) update(rib map[bgp.RouteFamily]map[string]*Path, pathList []*Path) {
- for _, path := range pathList {
- rf := path.GetRouteFamily()
- key := path.getPrefix()
- old, found := rib[rf][key]
- if path.IsWithdraw {
- if found {
- delete(rib[rf], key)
- }
- } else {
- if found && reflect.DeepEqual(old.GetPathAttrs(), path.GetPathAttrs()) {
- path.setTimestamp(old.GetTimestamp())
- }
- rib[rf][key] = path
- }
- }
-}
-
-func (adj *AdjRib) UpdateIn(pathList []*Path) {
- adj.update(adj.adjRibIn, pathList)
-}
-
-func (adj *AdjRib) UpdateOut(pathList []*Path) {
- adj.update(adj.adjRibOut, pathList)
-}
-
-func (adj *AdjRib) GetInPathList(rfList []bgp.RouteFamily) []*Path {
- pathList := make([]*Path, 0, adj.GetInCount(rfList))
- for _, rf := range rfList {
- for _, rr := range adj.adjRibIn[rf] {
- pathList = append(pathList, rr)
- }
- }
- return pathList
-}
-
-func (adj *AdjRib) GetOutPathList(rfList []bgp.RouteFamily) []*Path {
- pathList := make([]*Path, 0, adj.GetOutCount(rfList))
- for _, rf := range rfList {
- for _, rr := range adj.adjRibOut[rf] {
- pathList = append(pathList, rr)
- }
- }
- return pathList
-}
-
-func (adj *AdjRib) GetInCount(rfList []bgp.RouteFamily) int {
- count := 0
- for _, rf := range rfList {
- if _, ok := adj.adjRibIn[rf]; ok {
- count += len(adj.adjRibIn[rf])
-
- }
- }
- return count
-}
-
-func (adj *AdjRib) GetOutCount(rfList []bgp.RouteFamily) int {
- count := 0
- for _, rf := range rfList {
- if _, ok := adj.adjRibOut[rf]; ok {
- count += len(adj.adjRibOut[rf])
- }
- }
- return count
-}
-
-func (adj *AdjRib) DropIn(rfList []bgp.RouteFamily) {
- for _, rf := range rfList {
- if _, ok := adj.adjRibIn[rf]; ok {
- adj.adjRibIn[rf] = make(map[string]*Path)
- }
- }
-}
-
-func (adj *AdjRib) DropOut(rfList []bgp.RouteFamily) {
- for _, rf := range rfList {
- if _, ok := adj.adjRibIn[rf]; ok {
- adj.adjRibOut[rf] = make(map[string]*Path)
- }
- }
-}
diff --git a/table/table_manager_test.go b/table/table_manager_test.go
index 8a4f67f9..f0e465b2 100644
--- a/table/table_manager_test.go
+++ b/table/table_manager_test.go
@@ -26,6 +26,13 @@ import (
"time"
)
+// process BGPUpdate message
+// this function processes only BGPUpdate
+func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) {
+ paths := ProcessMessage(message, fromPeer, time.Now())
+ return manager.ProcessPaths(paths)
+}
+
func getLogger(lv log.Level) *log.Logger {
var l *log.Logger = &log.Logger{
Out: os.Stderr,
@@ -2147,15 +2154,15 @@ func TestProcessBGPUpdate_Timestamp(t *testing.T) {
pList1 := ProcessMessage(m1, peer, time.Now())
path1 := pList1[0]
t1 := path1.timestamp
- adjRib.UpdateIn(pList1)
+ adjRib.Update(pList1)
m2 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
pList2 := ProcessMessage(m2, peer, time.Now())
//path2 := pList2[0].(*IPv4Path)
//t2 = path2.timestamp
- adjRib.UpdateIn(pList2)
+ adjRib.Update(pList2)
- inList := adjRib.GetInPathList([]bgp.RouteFamily{bgp.RF_IPv4_UC})
+ inList := adjRib.PathList([]bgp.RouteFamily{bgp.RF_IPv4_UC}, false)
assert.Equal(t, len(inList), 1)
assert.Equal(t, inList[0].GetTimestamp(), t1)
@@ -2170,9 +2177,9 @@ func TestProcessBGPUpdate_Timestamp(t *testing.T) {
m3 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri)
pList3 := ProcessMessage(m3, peer, time.Now())
t3 := pList3[0].GetTimestamp()
- adjRib.UpdateIn(pList3)
+ adjRib.Update(pList3)
- inList = adjRib.GetInPathList([]bgp.RouteFamily{bgp.RF_IPv4_UC})
+ inList = adjRib.PathList([]bgp.RouteFamily{bgp.RF_IPv4_UC}, false)
assert.Equal(t, len(inList), 1)
assert.Equal(t, inList[0].GetTimestamp(), t3)
}