diff options
author | Wataru Ishida <ishida.wataru@lab.ntt.co.jp> | 2016-10-09 13:21:22 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-10-09 21:57:31 -0700 |
commit | 2cd0de0139cb47edac0c418f4efd4e5c6d185f63 (patch) | |
tree | 2a7221aa96ddaef91390aaf4091605ddf5c71d67 /table/policy.go | |
parent | 614746ca1159fe421047df04c5af6f07c38b2e65 (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.go | 73 |
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 { |