summaryrefslogtreecommitdiffhomepage
path: root/table/policy.go
diff options
context:
space:
mode:
authorWataru Ishida <ishida.wataru@lab.ntt.co.jp>2016-10-09 13:21:22 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-10-09 21:57:31 -0700
commit2cd0de0139cb47edac0c418f4efd4e5c6d185f63 (patch)
tree2a7221aa96ddaef91390aaf4091605ddf5c71d67 /table/policy.go
parent614746ca1159fe421047df04c5af6f07c38b2e65 (diff)
policy: fix bug of handling multiple prefix-match with same IP prefix.
fix handling of prefix-match configuration like below [[defined-sets.prefix-sets]] prefix-set-name = "ps1" [[defined-sets.prefix-sets.prefix-list]] ip-prefix = "0.0.0.0/0" masklength-range = "0..7" [[defined-sets.prefix-sets.prefix-list]] ip-prefix = "0.0.0.0/0" masklength-range = "25..32" Signed-off-by: Wataru Ishida <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'table/policy.go')
-rw-r--r--table/policy.go73
1 files changed, 62 insertions, 11 deletions
diff --git a/table/policy.go b/table/policy.go
index 74ced9e1..2122e508 100644
--- a/table/policy.go
+++ b/table/policy.go
@@ -286,8 +286,15 @@ func (lhs *PrefixSet) Append(arg DefinedSet) error {
if !ok {
return fmt.Errorf("type cast failed")
}
- rhs.tree.Walk(func(s string, v interface{}) bool {
- lhs.tree.Insert(s, v)
+ rhs.tree.Walk(func(key string, v interface{}) bool {
+ w, ok := lhs.tree.Get(key)
+ if ok {
+ r := v.([]*Prefix)
+ l := w.([]*Prefix)
+ lhs.tree.Insert(key, append(l, r...))
+ } else {
+ lhs.tree.Insert(key, v)
+ }
return false
})
return nil
@@ -298,8 +305,31 @@ func (lhs *PrefixSet) Remove(arg DefinedSet) error {
if !ok {
return fmt.Errorf("type cast failed")
}
- rhs.tree.Walk(func(s string, v interface{}) bool {
- lhs.tree.Delete(s)
+ rhs.tree.Walk(func(key string, v interface{}) bool {
+ w, ok := lhs.tree.Get(key)
+ if !ok {
+ return false
+ }
+ r := v.([]*Prefix)
+ l := w.([]*Prefix)
+ new := make([]*Prefix, 0, len(l))
+ for _, lp := range l {
+ delete := false
+ for _, rp := range r {
+ if lp.Equal(rp) {
+ delete = true
+ break
+ }
+ }
+ if !delete {
+ new = append(new, lp)
+ }
+ }
+ if len(new) == 0 {
+ lhs.tree.Delete(key)
+ } else {
+ lhs.tree.Insert(key, new)
+ }
return false
})
return nil
@@ -317,8 +347,10 @@ func (lhs *PrefixSet) Replace(arg DefinedSet) error {
func (s *PrefixSet) ToConfig() *config.PrefixSet {
list := make([]config.Prefix, 0, s.tree.Len())
s.tree.Walk(func(s string, v interface{}) bool {
- p := v.(*Prefix)
- list = append(list, config.Prefix{IpPrefix: p.Prefix.String(), MasklengthRange: fmt.Sprintf("%d..%d", p.MasklengthRangeMin, p.MasklengthRangeMax)})
+ ps := v.([]*Prefix)
+ for _, p := range ps {
+ list = append(list, config.Prefix{IpPrefix: p.Prefix.String(), MasklengthRange: fmt.Sprintf("%d..%d", p.MasklengthRangeMin, p.MasklengthRangeMax)})
+ }
return false
})
return &config.PrefixSet{
@@ -333,7 +365,14 @@ func NewPrefixSetFromApiStruct(name string, prefixes []*Prefix) (*PrefixSet, err
}
tree := radix.New()
for _, x := range prefixes {
- tree.Insert(CidrToRadixkey(x.Prefix.String()), x)
+ key := CidrToRadixkey(x.Prefix.String())
+ d, ok := tree.Get(key)
+ if ok {
+ ps := d.([]*Prefix)
+ tree.Insert(key, append(ps, x))
+ } else {
+ tree.Insert(key, []*Prefix{x})
+ }
}
return &PrefixSet{
name: name,
@@ -355,7 +394,14 @@ func NewPrefixSet(c config.PrefixSet) (*PrefixSet, error) {
if err != nil {
return nil, err
}
- tree.Insert(CidrToRadixkey(y.Prefix.String()), y)
+ key := CidrToRadixkey(y.Prefix.String())
+ d, ok := tree.Get(key)
+ if ok {
+ ps := d.([]*Prefix)
+ tree.Insert(key, append(ps, y))
+ } else {
+ tree.Insert(key, []*Prefix{y})
+ }
}
return &PrefixSet{
name: name,
@@ -970,9 +1016,14 @@ func (c *PrefixCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
}
result := false
- _, p, ok := c.set.tree.LongestPrefix(key)
- if ok && p.(*Prefix).MasklengthRangeMin <= masklen && masklen <= p.(*Prefix).MasklengthRangeMax {
- result = true
+ _, ps, ok := c.set.tree.LongestPrefix(key)
+ if ok {
+ for _, p := range ps.([]*Prefix) {
+ if p.MasklengthRangeMin <= masklen && masklen <= p.MasklengthRangeMax {
+ result = true
+ break
+ }
+ }
}
if c.option == MATCH_OPTION_INVERT {