summaryrefslogtreecommitdiffhomepage
path: root/table
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-02-06 14:19:43 -0800
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-02-06 15:07:36 -0800
commitd280168106c9ef9ed68ad117b913f52e6bae1827 (patch)
tree37d67be13c26c19a366e2c1d5621eff74a8984b4 /table
parentfa6c8fe58b7ef9aca401262be8677bb4526c3fcd (diff)
add route collector feature support
like openbgp's route collector, sends all updates (not only best). Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'table')
-rw-r--r--table/adj.go73
-rw-r--r--table/table_manager.go19
2 files changed, 68 insertions, 24 deletions
diff --git a/table/adj.go b/table/adj.go
index 65d9d161..ee9cf549 100644
--- a/table/adj.go
+++ b/table/adj.go
@@ -20,16 +20,20 @@ import (
"reflect"
)
+type Dest struct {
+ pathList []*Path
+}
+
type AdjRib struct {
id string
accepted map[bgp.RouteFamily]int
- table map[bgp.RouteFamily]map[string]*Path
+ table map[bgp.RouteFamily]map[string]*Dest
}
func NewAdjRib(id string, rfList []bgp.RouteFamily) *AdjRib {
- table := make(map[bgp.RouteFamily]map[string]*Path)
+ table := make(map[bgp.RouteFamily]map[string]*Dest)
for _, rf := range rfList {
- table[rf] = make(map[string]*Path)
+ table[rf] = make(map[string]*Dest)
}
return &AdjRib{
id: id,
@@ -45,17 +49,35 @@ func (adj *AdjRib) Update(pathList []*Path) {
}
rf := path.GetRouteFamily()
key := path.getPrefix()
- old, found := adj.table[rf][key]
+ dst := adj.table[rf][key]
+ var old *Path
+ oldIdx := 0
+ if dst == nil {
+ dst = &Dest{}
+ dst.pathList = make([]*Path, 0)
+ adj.table[rf][key] = dst
+ } else {
+ for i, known := range dst.pathList {
+ if known.GetSource() == path.GetSource() {
+ old = known
+ oldIdx = i
+ }
+ }
+ }
if path.IsWithdraw {
- if found {
- delete(adj.table[rf], key)
+ if old != nil {
+ dst.pathList = append(dst.pathList[:oldIdx], dst.pathList[oldIdx+1:]...)
+ if len(dst.pathList) == 0 {
+ delete(adj.table[rf], key)
+ }
+
if old.Filtered(adj.id) == POLICY_DIRECTION_NONE {
adj.accepted[rf]--
}
}
} else {
n := path.Filtered(adj.id)
- if found {
+ if old != nil {
o := old.Filtered(adj.id)
if o == POLICY_DIRECTION_IN && n == POLICY_DIRECTION_NONE {
adj.accepted[rf]++
@@ -67,10 +89,17 @@ func (adj *AdjRib) Update(pathList []*Path) {
adj.accepted[rf]++
}
}
- if found && reflect.DeepEqual(old.GetPathAttrs(), path.GetPathAttrs()) {
- path.setTimestamp(old.GetTimestamp())
+ if old != nil {
+ dst.pathList[oldIdx] = path
+ // avoid updating timestamp for the
+ // exact same message due to soft
+ // reset, etc
+ if reflect.DeepEqual(old.GetPathAttrs(), path.GetPathAttrs()) {
+ path.setTimestamp(old.GetTimestamp())
+ }
+ } else {
+ dst.pathList = append(dst.pathList, path)
}
- adj.table[rf][key] = path
}
}
}
@@ -78,9 +107,11 @@ func (adj *AdjRib) Update(pathList []*Path) {
func (adj *AdjRib) RefreshAcceptedNumber(rfList []bgp.RouteFamily) {
for _, rf := range rfList {
adj.accepted[rf] = 0
- for _, p := range adj.table[rf] {
- if p.Filtered(adj.id) != POLICY_DIRECTION_IN {
- adj.accepted[rf]++
+ for _, d := range adj.table[rf] {
+ for _, p := range d.pathList {
+ if p.Filtered(adj.id) != POLICY_DIRECTION_IN {
+ adj.accepted[rf]++
+ }
}
}
}
@@ -89,11 +120,13 @@ func (adj *AdjRib) RefreshAcceptedNumber(rfList []bgp.RouteFamily) {
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(adj.id) > POLICY_DIRECTION_NONE {
- continue
+ for _, d := range adj.table[rf] {
+ for _, p := range d.pathList {
+ if accepted && p.Filtered(adj.id) > POLICY_DIRECTION_NONE {
+ continue
+ }
+ pathList = append(pathList, p)
}
- pathList = append(pathList, rr)
}
}
return pathList
@@ -103,7 +136,9 @@ func (adj *AdjRib) Count(rfList []bgp.RouteFamily) int {
count := 0
for _, rf := range rfList {
if table, ok := adj.table[rf]; ok {
- count += len(table)
+ for _, d := range table {
+ count += len(d.pathList)
+ }
}
}
return count
@@ -122,7 +157,7 @@ func (adj *AdjRib) Accepted(rfList []bgp.RouteFamily) int {
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.table[rf] = make(map[string]*Dest)
adj.accepted[rf] = 0
}
}
diff --git a/table/table_manager.go b/table/table_manager.go
index f21acef0..ebfd0beb 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -276,7 +276,7 @@ func (manager *TableManager) handleMacMobility(path *Path) []*Destination {
if path.IsWithdraw || path.IsLocal() || nlri.RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT {
return nil
}
- for _, path2 := range manager.GetPathList(GLOBAL_RIB_NAME, bgp.RF_EVPN) {
+ for _, path2 := range manager.GetPathList(GLOBAL_RIB_NAME, []bgp.RouteFamily{bgp.RF_EVPN}) {
if !path2.IsLocal() || path2.GetNlri().(*bgp.EVPNNLRI).RouteType != bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT {
continue
}
@@ -323,9 +323,18 @@ func (manager *TableManager) GetBestPathList(id string, rfList []bgp.RouteFamily
return paths
}
-func (manager *TableManager) GetPathList(id string, rf bgp.RouteFamily) []*Path {
- if t, ok := manager.Tables[rf]; ok {
- return t.GetKnownPathList(id)
+func (manager *TableManager) GetPathList(id string, rfList []bgp.RouteFamily) []*Path {
+ c := 0
+ for _, rf := range rfList {
+ if t, ok := manager.Tables[rf]; ok {
+ c += len(t.destinations)
+ }
}
- return nil
+ paths := make([]*Path, 0, c)
+ for _, rf := range rfList {
+ if t, ok := manager.Tables[rf]; ok {
+ paths = append(paths, t.GetKnownPathList(id)...)
+ }
+ }
+ return paths
}