diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2015-12-02 16:01:47 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-12-02 16:02:21 +0900 |
commit | a36c84c510bd7cde344e6cbabd043153e4a0196c (patch) | |
tree | c9a529ea365def97af86cd5aba6d315aed6671ab /table | |
parent | b83d3cc802cdaa69b8c77b6db54aa8fe4e472ba7 (diff) |
make adj-rib implementation more clear and efficient
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'table')
-rw-r--r-- | table/adj.go | 114 | ||||
-rw-r--r-- | table/table_manager.go | 118 | ||||
-rw-r--r-- | table/table_manager_test.go | 17 |
3 files changed, 126 insertions, 123 deletions
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) } |