diff options
Diffstat (limited to 'table')
-rw-r--r-- | table/policy.go | 179 |
1 files changed, 176 insertions, 3 deletions
diff --git a/table/policy.go b/table/policy.go index 843eb7d2..5fd406f4 100644 --- a/table/policy.go +++ b/table/policy.go @@ -137,6 +137,9 @@ type DefinedSet interface { Type() DefinedType Name() string ToApiStruct() *api.DefinedSet + Append(DefinedSet) error + Remove(DefinedSet) error + Replace(DefinedSet) error } type DefinedSetMap map[DefinedType]map[string]DefinedSet @@ -170,6 +173,16 @@ func (p *Prefix) Match(path *Path) bool { return (p.MasklengthRangeMin <= pMasklen && pMasklen <= p.MasklengthRangeMax) && p.Prefix.Contains(pAddr) } +func (lhs *Prefix) Equal(rhs *Prefix) bool { + if lhs == rhs { + return true + } + if rhs == nil { + return false + } + return lhs.Prefix.String() == rhs.Prefix.String() && lhs.MasklengthRangeMin == rhs.MasklengthRangeMin && lhs.MasklengthRangeMax == rhs.MasklengthRangeMax +} + func (p *Prefix) ToApiStruct() *api.Prefix { return &api.Prefix{ IpPrefix: p.Prefix.String(), @@ -248,6 +261,46 @@ func (s *PrefixSet) Type() DefinedType { return DEFINED_TYPE_PREFIX } +func (lhs *PrefixSet) Append(arg DefinedSet) error { + rhs, ok := arg.(*PrefixSet) + if !ok { + return fmt.Errorf("type cast failed") + } + lhs.list = append(lhs.list, rhs.list...) + return nil +} + +func (lhs *PrefixSet) Remove(arg DefinedSet) error { + rhs, ok := arg.(*PrefixSet) + if !ok { + return fmt.Errorf("type cast failed") + } + ps := make([]*Prefix, 0, len(lhs.list)) + for _, x := range lhs.list { + found := false + for _, y := range rhs.list { + if x.Equal(y) { + found = true + break + } + } + if !found { + ps = append(ps, x) + } + } + lhs.list = ps + return nil +} + +func (lhs *PrefixSet) Replace(arg DefinedSet) error { + rhs, ok := arg.(*PrefixSet) + if !ok { + return fmt.Errorf("type cast failed") + } + lhs.list = rhs.list + return nil +} + func (s *PrefixSet) ToApiStruct() *api.DefinedSet { list := make([]*api.Prefix, 0, len(s.list)) for _, p := range s.list { @@ -313,6 +366,46 @@ func (s *NeighborSet) Type() DefinedType { return DEFINED_TYPE_NEIGHBOR } +func (lhs *NeighborSet) Append(arg DefinedSet) error { + rhs, ok := arg.(*NeighborSet) + if !ok { + return fmt.Errorf("type cast failed") + } + lhs.list = append(lhs.list, rhs.list...) + return nil +} + +func (lhs *NeighborSet) Remove(arg DefinedSet) error { + rhs, ok := arg.(*NeighborSet) + if !ok { + return fmt.Errorf("type cast failed") + } + ps := make([]net.IP, 0, len(lhs.list)) + for _, x := range lhs.list { + found := false + for _, y := range rhs.list { + if x.Equal(y) { + found = true + break + } + } + if !found { + ps = append(ps, x) + } + } + lhs.list = ps + return nil +} + +func (lhs *NeighborSet) Replace(arg DefinedSet) error { + rhs, ok := arg.(*NeighborSet) + if !ok { + return fmt.Errorf("type cast failed") + } + lhs.list = rhs.list + return nil +} + func (s *NeighborSet) ToApiStruct() *api.DefinedSet { list := make([]string, 0, len(s.list)) for _, n := range s.list { @@ -375,6 +468,46 @@ func (s *regExpSet) Type() DefinedType { return s.typ } +func (lhs *regExpSet) Append(arg DefinedSet) error { + rhs, ok := arg.(*regExpSet) + if !ok { + return fmt.Errorf("type cast failed") + } + lhs.list = append(lhs.list, rhs.list...) + return nil +} + +func (lhs *regExpSet) Remove(arg DefinedSet) error { + rhs, ok := arg.(*regExpSet) + if !ok { + return fmt.Errorf("type cast failed") + } + ps := make([]*regexp.Regexp, 0, len(lhs.list)) + for _, x := range lhs.list { + found := false + for _, y := range rhs.list { + if x.String() == y.String() { + found = true + break + } + } + if !found { + ps = append(ps, x) + } + } + lhs.list = ps + return nil +} + +func (lhs *regExpSet) Replace(arg DefinedSet) error { + rhs, ok := arg.(*regExpSet) + if !ok { + return fmt.Errorf("type cast failed") + } + lhs.list = rhs.list + return nil +} + func (s *regExpSet) ToApiStruct() *api.DefinedSet { list := make([]string, 0, len(s.list)) for _, exp := range s.list { @@ -586,8 +719,26 @@ func NewExtCommunitySet(c config.ExtCommunitySet) (*ExtCommunitySet, error) { }, nil } +func NewDefinedSetFromApiStruct(a *api.DefinedSet) (DefinedSet, error) { + switch DefinedType(a.Type) { + case DEFINED_TYPE_PREFIX: + return NewPrefixSetFromApiStruct(a) + case DEFINED_TYPE_NEIGHBOR: + return NewNeighborSetFromApiStruct(a) + case DEFINED_TYPE_AS_PATH: + return NewAsPathSetFromApiStruct(a) + case DEFINED_TYPE_COMMUNITY: + return NewCommunitySetFromApiStruct(a) + case DEFINED_TYPE_EXT_COMMUNITY: + return NewExtCommunitySetFromApiStruct(a) + default: + return nil, fmt.Errorf("invalid defined type") + } +} + type Condition interface { Evaluate(*Path) bool + Set() DefinedSet } type PrefixCondition struct { @@ -761,7 +912,7 @@ type AsPathCondition struct { option MatchOption } -func (c *AsPathCondition) Set() *AsPathSet { +func (c *AsPathCondition) Set() DefinedSet { return c.set } @@ -838,7 +989,7 @@ type CommunityCondition struct { option MatchOption } -func (c *CommunityCondition) Set() *CommunitySet { +func (c *CommunityCondition) Set() DefinedSet { return c.set } @@ -918,7 +1069,7 @@ type ExtCommunityCondition struct { option MatchOption } -func (c *ExtCommunityCondition) Set() *ExtCommunitySet { +func (c *ExtCommunityCondition) Set() DefinedSet { return c.set } @@ -1029,6 +1180,10 @@ func (c *AsPathLengthCondition) Evaluate(path *Path) bool { return result } +func (c *AsPathLengthCondition) Set() DefinedSet { + return nil +} + func (c *AsPathLengthCondition) ToApiStruct() *api.AsPathLength { return &api.AsPathLength{ Length: c.length, @@ -1072,6 +1227,10 @@ func (c *RpkiValidationCondition) Evaluate(path *Path) bool { return c.result == path.Validation } +func (c *RpkiValidationCondition) Set() DefinedSet { + return nil +} + func NewRpkiValidationConditionFromApiStruct(a int32) (*RpkiValidationCondition, error) { typ := config.RpkiValidationResultType(a) return NewRpkiValidationCondition(typ) @@ -1854,6 +2013,20 @@ type RoutingPolicy struct { PolicyMap map[string]*Policy } +func (r *RoutingPolicy) InUse(d DefinedSet) bool { + name := d.Name() + for _, p := range r.PolicyMap { + for _, s := range p.Statements { + for _, c := range s.Conditions { + if c.Set().Name() == name { + return true + } + } + } + } + return false +} + func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) { dmap := make(map[DefinedType]map[string]DefinedSet) dmap[DEFINED_TYPE_PREFIX] = make(map[string]DefinedSet) |