summaryrefslogtreecommitdiffhomepage
path: root/table
diff options
context:
space:
mode:
authorWataru Ishida <ishida.wataru@lab.ntt.co.jp>2016-08-20 20:26:07 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-08-25 15:53:14 +0900
commitc8bb5752f6a08eb5d1aac9fd4d58571cf9d8e2f4 (patch)
tree56c53f4ee6a05dd08e1026e422d518124b03bdd5 /table
parent26c232f2c4c5e7e8707a00c418316a0218fcabff (diff)
table: add Best/MultiPath option to SelectOption
Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'table')
-rw-r--r--table/destination.go51
-rw-r--r--table/table.go15
2 files changed, 51 insertions, 15 deletions
diff --git a/table/destination.go b/table/destination.go
index 3a1c1c45..845c2ab2 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -852,9 +852,11 @@ func (dest *Destination) String() string {
}
type DestinationSelectOption struct {
- ID string
- VRF *Vrf
- adj bool
+ ID string
+ VRF *Vrf
+ adj bool
+ Best bool
+ MultiPath bool
}
func (d *Destination) MarshalJSON() ([]byte, error) {
@@ -865,6 +867,8 @@ func (old *Destination) Select(option ...DestinationSelectOption) *Destination {
id := GLOBAL_RIB_NAME
var vrf *Vrf
adj := false
+ best := false
+ mp := false
for _, o := range option {
if o.ID != "" {
id = o.ID
@@ -873,27 +877,50 @@ func (old *Destination) Select(option ...DestinationSelectOption) *Destination {
vrf = o.VRF
}
adj = o.adj
+ best = o.Best
+ mp = o.MultiPath
}
var paths []*Path
if adj {
paths = old.knownPathList
} else {
paths = old.GetKnownPathList(id)
+ if vrf != nil {
+ ps := make([]*Path, 0, len(paths))
+ for _, p := range paths {
+ if CanImportToVrf(vrf, p) {
+ ps = append(ps, p)
+ }
+ }
+ paths = ps
+ }
+ if len(paths) == 0 {
+ return nil
+ }
+ if best {
+ if !mp {
+ paths = []*Path{paths[0]}
+ } else {
+ ps := make([]*Path, 0, len(paths))
+ var best *Path
+ for _, p := range paths {
+ if best == nil {
+ best = p
+ ps = append(ps, p)
+ } else if best.Compare(p) == 0 {
+ ps = append(ps, p)
+ }
+ }
+ paths = ps
+ }
+ }
}
new := NewDestination(old.nlri)
- list := make([]*Path, 0, len(old.knownPathList))
for _, path := range paths {
- if vrf != nil && !CanImportToVrf(vrf, path) {
- continue
- }
p := path.Clone(path.IsWithdraw)
p.Filter("", path.Filtered(id))
- list = append(list, p)
- }
- if len(list) == 0 {
- return nil
+ new.knownPathList = append(new.knownPathList, p)
}
- new.knownPathList = list
return new
}
diff --git a/table/table.go b/table/table.go
index f89e8dff..143c4c53 100644
--- a/table/table.go
+++ b/table/table.go
@@ -43,6 +43,8 @@ type TableSelectOption struct {
LookupPrefixes []*LookupPrefix
VRF *Vrf
adj bool
+ Best bool
+ MultiPath bool
}
type Table struct {
@@ -314,6 +316,8 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) {
var vrf *Vrf
adj := false
prefixes := make([]*LookupPrefix, 0, len(option))
+ best := false
+ mp := false
for _, o := range option {
if o.ID != "" {
id = o.ID
@@ -323,12 +327,15 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) {
}
adj = o.adj
prefixes = append(prefixes, o.LookupPrefixes...)
+ best = o.Best
+ mp = o.MultiPath
}
+ dOption := DestinationSelectOption{ID: id, VRF: vrf, adj: adj, Best: best, MultiPath: mp}
dsts := make(map[string]*Destination)
if (t.routeFamily == bgp.RF_IPv4_UC || t.routeFamily == bgp.RF_IPv6_UC) && len(prefixes) > 0 {
f := func(id, key string) (bool, error) {
if dst := t.GetDestination(key); dst != nil {
- if d := dst.Select(DestinationSelectOption{ID: id, adj: adj}); d != nil {
+ if d := dst.Select(dOption); d != nil {
dsts[key] = d
return true, nil
}
@@ -344,7 +351,9 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) {
return nil, err
}
for _, dst := range ds {
- dsts[dst.GetNlri().String()] = dst.Select(DestinationSelectOption{ID: id, adj: adj})
+ if d := dst.Select(dOption); d != nil {
+ dsts[dst.GetNlri().String()] = d
+ }
}
case LOOKUP_SHORTER:
_, prefix, err := net.ParseCIDR(key)
@@ -374,7 +383,7 @@ func (t *Table) Select(option ...TableSelectOption) (*Table, error) {
}
} else {
for k, dst := range t.GetDestinations() {
- if d := dst.Select(DestinationSelectOption{ID: id, VRF: vrf, adj: adj}); d != nil {
+ if d := dst.Select(dOption); d != nil {
dsts[k] = d
}
}