summaryrefslogtreecommitdiffhomepage
path: root/table/adj.go
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-12-02 16:01:47 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-12-02 16:02:21 +0900
commita36c84c510bd7cde344e6cbabd043153e4a0196c (patch)
treec9a529ea365def97af86cd5aba6d315aed6671ab /table/adj.go
parentb83d3cc802cdaa69b8c77b6db54aa8fe4e472ba7 (diff)
make adj-rib implementation more clear and efficient
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'table/adj.go')
-rw-r--r--table/adj.go114
1 files changed, 114 insertions, 0 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
+ }
+ }
+}