summaryrefslogtreecommitdiffhomepage
path: root/table
diff options
context:
space:
mode:
Diffstat (limited to 'table')
-rw-r--r--table/policy.go620
-rw-r--r--table/policy_test.go59
2 files changed, 161 insertions, 518 deletions
diff --git a/table/policy.go b/table/policy.go
index 09c4ea19..37aa4355 100644
--- a/table/policy.go
+++ b/table/policy.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation.
+// Copyright (C) 2014-2016 Nippon Telegraph and Telephone Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/armon/go-radix"
- api "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet/bgp"
)
@@ -96,34 +95,6 @@ func (o MatchOption) String() string {
}
}
-func toConfigMatchSetOption(a api.MatchType) (config.MatchSetOptionsType, error) {
- var typ config.MatchSetOptionsType
- switch a {
- case api.MatchType_ANY:
- typ = config.MATCH_SET_OPTIONS_TYPE_ANY
- case api.MatchType_ALL:
- typ = config.MATCH_SET_OPTIONS_TYPE_ALL
- case api.MatchType_INVERT:
- typ = config.MATCH_SET_OPTIONS_TYPE_INVERT
- default:
- return typ, fmt.Errorf("invalid match type")
- }
- return typ, nil
-}
-
-func toConfigMatchSetOptionRestricted(a api.MatchType) (config.MatchSetOptionsRestrictedType, error) {
- var typ config.MatchSetOptionsRestrictedType
- switch a {
- case api.MatchType_ANY:
- typ = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY
- case api.MatchType_INVERT:
- typ = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT
- default:
- return typ, fmt.Errorf("invalid match type")
- }
- return typ, nil
-}
-
type MedActionType int
const (
@@ -255,23 +226,6 @@ func (lhs *Prefix) Equal(rhs *Prefix) bool {
return lhs.Prefix.String() == rhs.Prefix.String() && lhs.MasklengthRangeMin == rhs.MasklengthRangeMin && lhs.MasklengthRangeMax == rhs.MasklengthRangeMax
}
-func NewPrefixFromApiStruct(a *api.Prefix) (*Prefix, error) {
- addr, prefix, err := net.ParseCIDR(a.IpPrefix)
- if err != nil {
- return nil, err
- }
- rf := bgp.RF_IPv4_UC
- if addr.To4() == nil {
- rf = bgp.RF_IPv6_UC
- }
- return &Prefix{
- Prefix: prefix,
- AddressFamily: rf,
- MasklengthRangeMin: uint8(a.MaskLengthMin),
- MasklengthRangeMax: uint8(a.MaskLengthMax),
- }, nil
-}
-
func NewPrefix(c config.Prefix) (*Prefix, error) {
addr, prefix, err := net.ParseCIDR(c.IpPrefix)
if err != nil {
@@ -371,20 +325,16 @@ func (s *PrefixSet) ToConfig() *config.PrefixSet {
}
}
-func NewPrefixSetFromApiStruct(a *api.DefinedSet) (*PrefixSet, error) {
- if a.Name == "" {
+func NewPrefixSetFromApiStruct(name string, prefixes []*Prefix) (*PrefixSet, error) {
+ if name == "" {
return nil, fmt.Errorf("empty prefix set name")
}
tree := radix.New()
- for _, x := range a.Prefixes {
- y, err := NewPrefixFromApiStruct(x)
- if err != nil {
- return nil, err
- }
- tree.Insert(CidrToRadixkey(y.Prefix.String()), y)
+ for _, x := range prefixes {
+ tree.Insert(CidrToRadixkey(x.Prefix.String()), x)
}
return &PrefixSet{
- name: a.Name,
+ name: name,
tree: tree,
}, nil
}
@@ -475,20 +425,9 @@ func (s *NeighborSet) ToConfig() *config.NeighborSet {
}
}
-func NewNeighborSetFromApiStruct(a *api.DefinedSet) (*NeighborSet, error) {
- if a.Name == "" {
- return nil, fmt.Errorf("empty neighbor set name")
- }
- list := make([]net.IP, 0, len(a.List))
- for _, x := range a.List {
- addr := net.ParseIP(x)
- if addr == nil {
- return nil, fmt.Errorf("invalid ip address format: %s", x)
- }
- list = append(list, addr)
- }
+func NewNeighborSetFromApiStruct(name string, list []net.IP) (*NeighborSet, error) {
return &NeighborSet{
- name: a.Name,
+ name: name,
list: list,
}, nil
}
@@ -691,14 +630,6 @@ func (s *AsPathSet) ToConfig() *config.AsPathSet {
}
}
-func NewAsPathSetFromApiStruct(a *api.DefinedSet) (*AsPathSet, error) {
- c := config.AsPathSet{
- AsPathSetName: a.Name,
- AsPathList: a.List,
- }
- return NewAsPathSet(c)
-}
-
func NewAsPathSet(c config.AsPathSet) (*AsPathSet, error) {
name := c.AsPathSetName
if name == "" {
@@ -906,14 +837,6 @@ func ParseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *reg
return subtype, exp, err
}
-func NewCommunitySetFromApiStruct(a *api.DefinedSet) (*CommunitySet, error) {
- c := config.CommunitySet{
- CommunitySetName: a.Name,
- CommunityList: a.List,
- }
- return NewCommunitySet(c)
-}
-
func NewCommunitySet(c config.CommunitySet) (*CommunitySet, error) {
name := c.CommunitySetName
if name == "" {
@@ -967,14 +890,6 @@ func (s *ExtCommunitySet) ToConfig() *config.ExtCommunitySet {
}
}
-func NewExtCommunitySetFromApiStruct(a *api.DefinedSet) (*ExtCommunitySet, error) {
- c := config.ExtCommunitySet{
- ExtCommunitySetName: a.Name,
- ExtCommunityList: a.List,
- }
- return NewExtCommunitySet(c)
-}
-
func NewExtCommunitySet(c config.ExtCommunitySet) (*ExtCommunitySet, error) {
name := c.ExtCommunitySetName
if name == "" {
@@ -1003,30 +918,15 @@ 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 {
+ Name() string
Type() ConditionType
Evaluate(*Path, *PolicyOptions) bool
Set() DefinedSet
}
type PrefixCondition struct {
+ name string
set *PrefixSet
option MatchOption
}
@@ -1080,44 +980,24 @@ func (c *PrefixCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
return result
}
-func NewPrefixConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*PrefixCondition, error) {
- if a == nil {
- return nil, nil
- }
- typ, err := toConfigMatchSetOptionRestricted(a.Type)
- if err != nil {
- return nil, err
- }
- c := config.MatchPrefixSet{
- PrefixSet: a.Name,
- MatchSetOptions: typ,
- }
- return NewPrefixCondition(c, m)
-}
+func (c *PrefixCondition) Name() string { return c.name }
-func NewPrefixCondition(c config.MatchPrefixSet, m map[string]DefinedSet) (*PrefixCondition, error) {
+func NewPrefixCondition(c config.MatchPrefixSet) (*PrefixCondition, error) {
if c.PrefixSet == "" {
return nil, nil
}
- i, ok := m[c.PrefixSet]
- if !ok {
- return nil, fmt.Errorf("not found prefix set %s", c.PrefixSet)
- }
- s, ok := i.(*PrefixSet)
- if !ok {
- return nil, fmt.Errorf("type assert from DefinedSet to *PrefixSet failed")
- }
o, err := NewMatchOption(c.MatchSetOptions)
if err != nil {
return nil, err
}
return &PrefixCondition{
- set: s,
+ name: c.PrefixSet,
option: o,
}, nil
}
type NeighborCondition struct {
+ name string
set *NeighborSet
option MatchOption
}
@@ -1167,44 +1047,24 @@ func (c *NeighborCondition) Evaluate(path *Path, options *PolicyOptions) bool {
return result
}
-func NewNeighborConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*NeighborCondition, error) {
- if a == nil {
- return nil, nil
- }
- typ, err := toConfigMatchSetOptionRestricted(a.Type)
- if err != nil {
- return nil, err
- }
- c := config.MatchNeighborSet{
- NeighborSet: a.Name,
- MatchSetOptions: typ,
- }
- return NewNeighborCondition(c, m)
-}
+func (c *NeighborCondition) Name() string { return c.name }
-func NewNeighborCondition(c config.MatchNeighborSet, m map[string]DefinedSet) (*NeighborCondition, error) {
+func NewNeighborCondition(c config.MatchNeighborSet) (*NeighborCondition, error) {
if c.NeighborSet == "" {
return nil, nil
}
- i, ok := m[c.NeighborSet]
- if !ok {
- return nil, fmt.Errorf("not found neighbor set %s", c.NeighborSet)
- }
- s, ok := i.(*NeighborSet)
- if !ok {
- return nil, fmt.Errorf("type assert from DefinedSet to *NeighborSet failed")
- }
o, err := NewMatchOption(c.MatchSetOptions)
if err != nil {
return nil, err
}
return &NeighborCondition{
- set: s,
+ name: c.NeighborSet,
option: o,
}, nil
}
type AsPathCondition struct {
+ name string
set *AsPathSet
option MatchOption
}
@@ -1258,44 +1118,24 @@ func (c *AsPathCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
return true
}
-func NewAsPathConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*AsPathCondition, error) {
- if a == nil {
- return nil, nil
- }
- typ, err := toConfigMatchSetOption(a.Type)
- if err != nil {
- return nil, err
- }
- c := config.MatchAsPathSet{
- AsPathSet: a.Name,
- MatchSetOptions: typ,
- }
- return NewAsPathCondition(c, m)
-}
+func (c *AsPathCondition) Name() string { return c.name }
-func NewAsPathCondition(c config.MatchAsPathSet, m map[string]DefinedSet) (*AsPathCondition, error) {
+func NewAsPathCondition(c config.MatchAsPathSet) (*AsPathCondition, error) {
if c.AsPathSet == "" {
return nil, nil
}
- i, ok := m[c.AsPathSet]
- if !ok {
- return nil, fmt.Errorf("not found as path set %s", c.AsPathSet)
- }
- s, ok := i.(*AsPathSet)
- if !ok {
- return nil, fmt.Errorf("type assert from DefinedSet to *AsPathSet failed")
- }
o, err := NewMatchOption(c.MatchSetOptions)
if err != nil {
return nil, err
}
return &AsPathCondition{
- set: s,
+ name: c.AsPathSet,
option: o,
}, nil
}
type CommunityCondition struct {
+ name string
set *CommunitySet
option MatchOption
}
@@ -1336,44 +1176,24 @@ func (c *CommunityCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
return result
}
-func NewCommunityConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*CommunityCondition, error) {
- if a == nil {
- return nil, nil
- }
- typ, err := toConfigMatchSetOption(a.Type)
- if err != nil {
- return nil, err
- }
- c := config.MatchCommunitySet{
- CommunitySet: a.Name,
- MatchSetOptions: typ,
- }
- return NewCommunityCondition(c, m)
-}
+func (c *CommunityCondition) Name() string { return c.name }
-func NewCommunityCondition(c config.MatchCommunitySet, m map[string]DefinedSet) (*CommunityCondition, error) {
+func NewCommunityCondition(c config.MatchCommunitySet) (*CommunityCondition, error) {
if c.CommunitySet == "" {
return nil, nil
}
- i, ok := m[c.CommunitySet]
- if !ok {
- return nil, fmt.Errorf("not found community set %s", c.CommunitySet)
- }
- s, ok := i.(*CommunitySet)
- if !ok {
- return nil, fmt.Errorf("type assert from DefinedSet to *CommunitySet failed")
- }
o, err := NewMatchOption(c.MatchSetOptions)
if err != nil {
return nil, err
}
return &CommunityCondition{
- set: s,
+ name: c.CommunitySet,
option: o,
}, nil
}
type ExtCommunityCondition struct {
+ name string
set *ExtCommunitySet
option MatchOption
}
@@ -1419,39 +1239,18 @@ func (c *ExtCommunityCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
return result
}
-func NewExtCommunityConditionFromApiStruct(a *api.MatchSet, m map[string]DefinedSet) (*ExtCommunityCondition, error) {
- if a == nil {
- return nil, nil
- }
- typ, err := toConfigMatchSetOption(a.Type)
- if err != nil {
- return nil, err
- }
- c := config.MatchExtCommunitySet{
- ExtCommunitySet: a.Name,
- MatchSetOptions: typ,
- }
- return NewExtCommunityCondition(c, m)
-}
+func (c *ExtCommunityCondition) Name() string { return c.name }
-func NewExtCommunityCondition(c config.MatchExtCommunitySet, m map[string]DefinedSet) (*ExtCommunityCondition, error) {
+func NewExtCommunityCondition(c config.MatchExtCommunitySet) (*ExtCommunityCondition, error) {
if c.ExtCommunitySet == "" {
return nil, nil
}
- i, ok := m[c.ExtCommunitySet]
- if !ok {
- return nil, fmt.Errorf("not found ext-community set %s", c.ExtCommunitySet)
- }
- s, ok := i.(*ExtCommunitySet)
- if !ok {
- return nil, fmt.Errorf("type assert from DefinedSet to *ExtCommunitySet failed")
- }
o, err := NewMatchOption(c.MatchSetOptions)
if err != nil {
return nil, err
}
return &ExtCommunityCondition{
- set: s,
+ name: c.ExtCommunitySet,
option: o,
}, nil
}
@@ -1487,15 +1286,7 @@ func (c *AsPathLengthCondition) Set() DefinedSet {
return nil
}
-func NewAsPathLengthConditionFromApiStruct(a *api.AsPathLength) (*AsPathLengthCondition, error) {
- if a == nil {
- return nil, nil
- }
- return &AsPathLengthCondition{
- length: a.Length,
- operator: AttributeComparison(a.Type),
- }, nil
-}
+func (c *AsPathLengthCondition) Name() string { return "" }
func NewAsPathLengthCondition(c config.AsPathLength) (*AsPathLengthCondition, error) {
if c.Value == 0 && c.Operator == "" {
@@ -1531,12 +1322,7 @@ func (c *RpkiValidationCondition) Set() DefinedSet {
return nil
}
-func NewRpkiValidationConditionFromApiStruct(a int32) (*RpkiValidationCondition, error) {
- if a < 1 {
- return nil, nil
- }
- return NewRpkiValidationCondition(config.IntToRpkiValidationResultTypeMap[int(a)])
-}
+func (c *RpkiValidationCondition) Name() string { return "" }
func NewRpkiValidationCondition(c config.RpkiValidationResultType) (*RpkiValidationCondition, error) {
if c == config.RPKI_VALIDATION_RESULT_TYPE_NONE {
@@ -1567,19 +1353,6 @@ func (a *RoutingAction) Apply(path *Path, _ *PolicyOptions) *Path {
return nil
}
-func NewRoutingActionFromApiStruct(a api.RouteAction) (*RoutingAction, error) {
- if a == api.RouteAction_NONE {
- return nil, nil
- }
- accept := false
- if a == api.RouteAction_ACCEPT {
- accept = true
- }
- return &RoutingAction{
- AcceptRoute: accept,
- }, nil
-}
-
func NewRoutingAction(c config.RouteDisposition) (*RoutingAction, error) {
if c.AcceptRoute == c.RejectRoute && c.AcceptRoute {
return nil, fmt.Errorf("invalid route disposition")
@@ -1672,40 +1445,6 @@ func (a *CommunityAction) ToConfig() *config.SetCommunity {
}
}
-func NewCommunityActionFromApiStruct(a *api.CommunityAction) (*CommunityAction, error) {
- if a == nil {
- return nil, nil
- }
- var list []uint32
- var removeList []*regexp.Regexp
- op := config.IntToBgpSetCommunityOptionTypeMap[int(a.Type)]
- if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
- removeList = make([]*regexp.Regexp, 0, len(a.Communities))
- } else {
- list = make([]uint32, 0, len(a.Communities))
- }
- for _, x := range a.Communities {
- if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
- exp, err := ParseCommunityRegexp(x)
- if err != nil {
- return nil, err
- }
- removeList = append(removeList, exp)
- } else {
- comm, err := ParseCommunity(x)
- if err != nil {
- return nil, err
- }
- list = append(list, comm)
- }
- }
- return &CommunityAction{
- action: op,
- list: list,
- removeList: removeList,
- }, nil
-}
-
func NewCommunityAction(c config.SetCommunity) (*CommunityAction, error) {
a, ok := CommunityOptionValueMap[strings.ToLower(c.Options)]
if !ok {
@@ -1794,45 +1533,6 @@ func (a *ExtCommunityAction) ToConfig() *config.SetExtCommunity {
}
}
-func NewExtCommunityActionFromApiStruct(a *api.CommunityAction) (*ExtCommunityAction, error) {
- if a == nil {
- return nil, nil
- }
- var list []bgp.ExtendedCommunityInterface
- var removeList []*regexp.Regexp
- subtypeList := make([]bgp.ExtendedCommunityAttrSubType, 0, len(a.Communities))
- op := config.IntToBgpSetCommunityOptionTypeMap[int(a.Type)]
- if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
- removeList = make([]*regexp.Regexp, 0, len(a.Communities))
- } else {
- list = make([]bgp.ExtendedCommunityInterface, 0, len(a.Communities))
- }
- for _, x := range a.Communities {
- if op == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
- subtype, exp, err := ParseExtCommunityRegexp(x)
- if err != nil {
- return nil, err
- }
- removeList = append(removeList, exp)
- subtypeList = append(subtypeList, subtype)
- } else {
- comm, err := ParseExtCommunity(x)
- if err != nil {
- return nil, err
- }
- list = append(list, comm)
- _, subtype := comm.GetTypes()
- subtypeList = append(subtypeList, subtype)
- }
- }
- return &ExtCommunityAction{
- action: op,
- list: list,
- removeList: removeList,
- subtypeList: subtypeList,
- }, nil
-}
-
func NewExtCommunityAction(c config.SetExtCommunity) (*ExtCommunityAction, error) {
a, ok := CommunityOptionValueMap[strings.ToLower(c.Options)]
if !ok {
@@ -1909,16 +1609,6 @@ func (a *MedAction) ToConfig() config.BgpSetMedType {
return config.BgpSetMedType(fmt.Sprintf("%d", a.value))
}
-func NewMedActionFromApiStruct(a *api.MedAction) (*MedAction, error) {
- if a == nil {
- return nil, nil
- }
- return &MedAction{
- action: MedActionType(a.Type),
- value: int(a.Value),
- }, nil
-}
-
func NewMedAction(c config.BgpSetMedType) (*MedAction, error) {
if string(c) == "" {
return nil, nil
@@ -1940,6 +1630,10 @@ func NewMedAction(c config.BgpSetMedType) (*MedAction, error) {
}, nil
}
+func NewMedActionFromApiStruct(action MedActionType, value int) *MedAction {
+ return &MedAction{action: action, value: value}
+}
+
type LocalPrefAction struct {
value uint32
}
@@ -1957,15 +1651,6 @@ func (a *LocalPrefAction) ToConfig() uint32 {
return a.value
}
-func NewLocalPrefActionFromApiStruct(a *api.LocalPrefAction) (*LocalPrefAction, error) {
- if a == nil || a.Value == 0 {
- return nil, nil
- }
- return &LocalPrefAction{
- value: a.Value,
- }, nil
-}
-
func NewLocalPrefAction(value uint32) (*LocalPrefAction, error) {
if value == 0 {
return nil, nil
@@ -2025,17 +1710,6 @@ func (a *AsPathPrependAction) ToConfig() *config.SetAsPathPrepend {
}
}
-func NewAsPathPrependActionFromApiStruct(a *api.AsPrependAction) (*AsPathPrependAction, error) {
- if a == nil {
- return nil, nil
- }
- return &AsPathPrependAction{
- asn: a.Asn,
- useLeftMost: a.UseLeftMost,
- repeat: uint8(a.Repeat),
- }, nil
-}
-
// NewAsPathPrependAction creates AsPathPrependAction object.
// If ASN cannot be parsed, nil will be returned.
func NewAsPathPrependAction(action config.SetAsPathPrepend) (*AsPathPrependAction, error) {
@@ -2087,16 +1761,6 @@ func (a *NexthopAction) ToConfig() config.BgpNextHopType {
return config.BgpNextHopType(a.value.String())
}
-func NewNexthopActionFromApiStruct(a *api.NexthopAction) (*NexthopAction, error) {
- if a == nil {
- return nil, nil
- }
- return &NexthopAction{
- value: net.ParseIP(a.Address),
- self: a.Self,
- }, nil
-}
-
func NewNexthopAction(c config.BgpNextHopType) (*NexthopAction, error) {
switch string(c) {
case "":
@@ -2338,94 +2002,7 @@ func (lhs *Statement) Replace(rhs *Statement) error {
return lhs.mod(REPLACE, rhs)
}
-func NewStatementFromApiStruct(a *api.Statement, dmap DefinedSetMap) (*Statement, error) {
- if a.Name == "" {
- return nil, fmt.Errorf("empty statement name")
- }
- var ra Action
- var as []Action
- var cs []Condition
- var err error
- if a.Conditions != nil {
- cfs := []func() (Condition, error){
- func() (Condition, error) {
- return NewPrefixConditionFromApiStruct(a.Conditions.PrefixSet, dmap[DEFINED_TYPE_PREFIX])
- },
- func() (Condition, error) {
- return NewNeighborConditionFromApiStruct(a.Conditions.NeighborSet, dmap[DEFINED_TYPE_NEIGHBOR])
- },
- func() (Condition, error) {
- return NewAsPathLengthConditionFromApiStruct(a.Conditions.AsPathLength)
- },
- func() (Condition, error) {
- return NewRpkiValidationConditionFromApiStruct(a.Conditions.RpkiResult)
- },
- func() (Condition, error) {
- return NewAsPathConditionFromApiStruct(a.Conditions.AsPathSet, dmap[DEFINED_TYPE_AS_PATH])
- },
- func() (Condition, error) {
- return NewCommunityConditionFromApiStruct(a.Conditions.CommunitySet, dmap[DEFINED_TYPE_COMMUNITY])
- },
- func() (Condition, error) {
- return NewExtCommunityConditionFromApiStruct(a.Conditions.ExtCommunitySet, dmap[DEFINED_TYPE_EXT_COMMUNITY])
- },
- }
- cs = make([]Condition, 0, len(cfs))
- for _, f := range cfs {
- c, err := f()
- if err != nil {
- return nil, err
- }
- if !reflect.ValueOf(c).IsNil() {
- cs = append(cs, c)
- }
- }
- }
- if a.Actions != nil {
- ra, err = NewRoutingActionFromApiStruct(a.Actions.RouteAction)
- if err != nil {
- return nil, err
- }
- afs := []func() (Action, error){
- func() (Action, error) {
- return NewCommunityActionFromApiStruct(a.Actions.Community)
- },
- func() (Action, error) {
- return NewExtCommunityActionFromApiStruct(a.Actions.ExtCommunity)
- },
- func() (Action, error) {
- return NewMedActionFromApiStruct(a.Actions.Med)
- },
- func() (Action, error) {
- return NewLocalPrefActionFromApiStruct(a.Actions.LocalPref)
- },
- func() (Action, error) {
- return NewAsPathPrependActionFromApiStruct(a.Actions.AsPrepend)
- },
- func() (Action, error) {
- return NewNexthopActionFromApiStruct(a.Actions.Nexthop)
- },
- }
- as = make([]Action, 0, len(afs))
- for _, f := range afs {
- a, err := f()
- if err != nil {
- return nil, err
- }
- if !reflect.ValueOf(a).IsNil() {
- as = append(as, a)
- }
- }
- }
- return &Statement{
- Name: a.Name,
- Conditions: cs,
- RouteAction: ra,
- ModActions: as,
- }, nil
-}
-
-func NewStatement(c config.Statement, dmap DefinedSetMap) (*Statement, error) {
+func NewStatement(c config.Statement) (*Statement, error) {
if c.Name == "" {
return nil, fmt.Errorf("empty statement name")
}
@@ -2435,10 +2012,10 @@ func NewStatement(c config.Statement, dmap DefinedSetMap) (*Statement, error) {
var err error
cfs := []func() (Condition, error){
func() (Condition, error) {
- return NewPrefixCondition(c.Conditions.MatchPrefixSet, dmap[DEFINED_TYPE_PREFIX])
+ return NewPrefixCondition(c.Conditions.MatchPrefixSet)
},
func() (Condition, error) {
- return NewNeighborCondition(c.Conditions.MatchNeighborSet, dmap[DEFINED_TYPE_NEIGHBOR])
+ return NewNeighborCondition(c.Conditions.MatchNeighborSet)
},
func() (Condition, error) {
return NewAsPathLengthCondition(c.Conditions.BgpConditions.AsPathLength)
@@ -2447,13 +2024,13 @@ func NewStatement(c config.Statement, dmap DefinedSetMap) (*Statement, error) {
return NewRpkiValidationCondition(c.Conditions.BgpConditions.RpkiValidationResult)
},
func() (Condition, error) {
- return NewAsPathCondition(c.Conditions.BgpConditions.MatchAsPathSet, dmap[DEFINED_TYPE_AS_PATH])
+ return NewAsPathCondition(c.Conditions.BgpConditions.MatchAsPathSet)
},
func() (Condition, error) {
- return NewCommunityCondition(c.Conditions.BgpConditions.MatchCommunitySet, dmap[DEFINED_TYPE_COMMUNITY])
+ return NewCommunityCondition(c.Conditions.BgpConditions.MatchCommunitySet)
},
func() (Condition, error) {
- return NewExtCommunityCondition(c.Conditions.BgpConditions.MatchExtCommunitySet, dmap[DEFINED_TYPE_EXT_COMMUNITY])
+ return NewExtCommunityCondition(c.Conditions.BgpConditions.MatchExtCommunitySet)
},
}
cs = make([]Condition, 0, len(cfs))
@@ -2509,14 +2086,10 @@ func NewStatement(c config.Statement, dmap DefinedSetMap) (*Statement, error) {
}
type Policy struct {
- name string
+ Name string
Statements []*Statement
}
-func (p *Policy) Name() string {
- return p.name
-}
-
// Compare path with a policy's condition in stored order in the policy.
// If a condition match, then this function stops evaluation and
// subsequent conditions are skipped.
@@ -2537,7 +2110,7 @@ func (p *Policy) ToConfig() *config.PolicyDefinition {
ss = append(ss, *s.ToConfig())
}
return &config.PolicyDefinition{
- Name: p.name,
+ Name: p.Name,
Statements: ss,
}
}
@@ -2583,28 +2156,7 @@ func (lhs *Policy) Replace(rhs *Policy) error {
return nil
}
-func NewPolicyFromApiStruct(a *api.Policy, dmap DefinedSetMap) (*Policy, error) {
- if a.Name == "" {
- return nil, fmt.Errorf("empty policy name")
- }
- stmts := make([]*Statement, 0, len(a.Statements))
- for idx, x := range a.Statements {
- if x.Name == "" {
- x.Name = fmt.Sprintf("%s_stmt%d", a.Name, idx)
- }
- y, err := NewStatementFromApiStruct(x, dmap)
- if err != nil {
- return nil, err
- }
- stmts = append(stmts, y)
- }
- return &Policy{
- name: a.Name,
- Statements: stmts,
- }, nil
-}
-
-func NewPolicy(c config.PolicyDefinition, dmap DefinedSetMap) (*Policy, error) {
+func NewPolicy(c config.PolicyDefinition) (*Policy, error) {
if c.Name == "" {
return nil, fmt.Errorf("empty policy name")
}
@@ -2616,7 +2168,7 @@ func NewPolicy(c config.PolicyDefinition, dmap DefinedSetMap) (*Policy, error) {
if stmt.Name == "" {
stmt.Name = fmt.Sprintf("%s_stmt%d", c.Name, idx)
}
- s, err := NewStatement(stmt, dmap)
+ s, err := NewStatement(stmt)
if err != nil {
return nil, err
}
@@ -2624,7 +2176,7 @@ func NewPolicy(c config.PolicyDefinition, dmap DefinedSetMap) (*Policy, error) {
}
}
return &Policy{
- name: c.Name,
+ Name: c.Name,
Statements: st,
}, nil
}
@@ -2780,6 +2332,54 @@ func (r *RoutingPolicy) GetAssignmentFromConfig(dir PolicyDirection, a config.Ap
return ps, def, nil
}
+func (r *RoutingPolicy) ValidateCondition(v Condition) (err error) {
+ switch v.Type() {
+ case CONDITION_PREFIX:
+ m := r.DefinedSetMap[DEFINED_TYPE_PREFIX]
+ if i, ok := m[v.Name()]; !ok {
+ return fmt.Errorf("not found prefix set %s", v.Name())
+ } else {
+ c := v.(*PrefixCondition)
+ c.set = i.(*PrefixSet)
+ }
+ case CONDITION_NEIGHBOR:
+ m := r.DefinedSetMap[DEFINED_TYPE_NEIGHBOR]
+ if i, ok := m[v.Name()]; !ok {
+ return fmt.Errorf("not found neighbor set %s", v.Name())
+ } else {
+ c := v.(*NeighborCondition)
+ c.set = i.(*NeighborSet)
+ }
+ case CONDITION_AS_PATH:
+ m := r.DefinedSetMap[DEFINED_TYPE_AS_PATH]
+ if i, ok := m[v.Name()]; !ok {
+ return fmt.Errorf("not found as path set %s", v.Name())
+ } else {
+ c := v.(*AsPathCondition)
+ c.set = i.(*AsPathSet)
+ }
+ case CONDITION_COMMUNITY:
+ m := r.DefinedSetMap[DEFINED_TYPE_COMMUNITY]
+ if i, ok := m[v.Name()]; !ok {
+ return fmt.Errorf("not found community set %s", v.Name())
+ } else {
+ c := v.(*CommunityCondition)
+ c.set = i.(*CommunitySet)
+ }
+ case CONDITION_EXT_COMMUNITY:
+ m := r.DefinedSetMap[DEFINED_TYPE_EXT_COMMUNITY]
+ if i, ok := m[v.Name()]; !ok {
+ return fmt.Errorf("not found ext-community set %s", v.Name())
+ } else {
+ c := v.(*ExtCommunityCondition)
+ c.set = i.(*ExtCommunitySet)
+ }
+ case CONDITION_AS_PATH_LENGTH:
+ case CONDITION_RPKI:
+ }
+ return nil
+}
+
func (r *RoutingPolicy) InUse(d DefinedSet) bool {
name := d.Name()
for _, p := range r.PolicyMap {
@@ -2875,14 +2475,14 @@ func (r *RoutingPolicy) Reload(c config.RoutingPolicy) error {
pmap := make(map[string]*Policy)
smap := make(map[string]*Statement)
for _, x := range c.PolicyDefinitions {
- y, err := NewPolicy(x, dmap)
+ y, err := NewPolicy(x)
if err != nil {
return err
}
- if _, ok := pmap[y.Name()]; ok {
+ if _, ok := pmap[y.Name]; ok {
return fmt.Errorf("duplicated policy name. policy name must be unique.")
}
- pmap[y.Name()] = y
+ pmap[y.Name] = y
for _, s := range y.Statements {
_, ok := smap[s.Name]
if ok {
@@ -2891,6 +2491,21 @@ func (r *RoutingPolicy) Reload(c config.RoutingPolicy) error {
smap[s.Name] = s
}
}
+
+ // hacky
+ oldMap := r.DefinedSetMap
+ r.DefinedSetMap = dmap
+ for _, y := range pmap {
+ for _, s := range y.Statements {
+ for _, c := range s.Conditions {
+ if err := r.ValidateCondition(c); err != nil {
+ r.DefinedSetMap = oldMap
+ return err
+ }
+ }
+ }
+ }
+
r.DefinedSetMap = dmap
r.PolicyMap = pmap
r.StatementMap = smap
@@ -2923,14 +2538,7 @@ func CanImportToVrf(v *Vrf, path *Path) bool {
ExtCommunitySet: v.Name,
MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY,
}
- c, _ := NewExtCommunityCondition(matchSet, map[string]DefinedSet{v.Name: set})
+ c, _ := NewExtCommunityCondition(matchSet)
+ c.set = set
return c.Evaluate(path, nil)
}
-
-func PoliciesToString(ps []*api.Policy) []string {
- names := make([]string, 0, len(ps))
- for _, p := range ps {
- names = append(names, p.Name)
- }
- return names
-}
diff --git a/table/policy_test.go b/table/policy_test.go
index e5bc52c9..ff52e3c7 100644
--- a/table/policy_test.go
+++ b/table/policy_test.go
@@ -612,6 +612,14 @@ func TestAs4PathLengthConditionEvaluate(t *testing.T) {
assert.Equal(t, false, c.Evaluate(path, nil))
}
+func addPolicy(r *RoutingPolicy, x *Policy) {
+ for _, s := range x.Statements {
+ for _, c := range s.Conditions {
+ r.ValidateCondition(c)
+ }
+ }
+}
+
func TestAs4PathLengthConditionWithOtherCondition(t *testing.T) {
// setup
// create path
@@ -663,7 +671,8 @@ func TestAs4PathLengthConditionWithOtherCondition(t *testing.T) {
//test
r := NewRoutingPolicy()
r.Reload(pl)
- p, _ := NewPolicy(pl.PolicyDefinitions[0], r.DefinedSetMap)
+ p, _ := NewPolicy(pl.PolicyDefinitions[0])
+ addPolicy(r, p)
pType, newPath := p.Apply(path, nil)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -739,7 +748,10 @@ func TestAsPathConditionEvaluate(t *testing.T) {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p, _ := NewAsPathCondition(matchSet, m)
+ p, _ := NewAsPathCondition(matchSet)
+ if v, ok := m[name]; ok {
+ p.set = v.(*AsPathSet)
+ }
return p
}
@@ -839,7 +851,10 @@ func TestMultipleAsPathConditionEvaluate(t *testing.T) {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p, _ := NewAsPathCondition(matchSet, m)
+ p, _ := NewAsPathCondition(matchSet)
+ if v, ok := m[name]; ok {
+ p.set = v.(*AsPathSet)
+ }
return p
}
@@ -931,7 +946,8 @@ func TestAsPathCondition(t *testing.T) {
c, _ := NewAsPathCondition(config.MatchAsPathSet{
AsPathSet: k,
MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY,
- }, map[string]DefinedSet{k: s})
+ })
+ c.set = s
for _, a := range v {
result := c.Evaluate(a.path, nil)
if a.result != result {
@@ -1082,7 +1098,10 @@ func TestAs4PathConditionEvaluate(t *testing.T) {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p, _ := NewAsPathCondition(matchSet, m)
+ p, _ := NewAsPathCondition(matchSet)
+ if v, ok := m[name]; ok {
+ p.set = v.(*AsPathSet)
+ }
return p
}
@@ -1203,7 +1222,10 @@ func TestMultipleAs4PathConditionEvaluate(t *testing.T) {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p, _ := NewAsPathCondition(matchSet, m)
+ p, _ := NewAsPathCondition(matchSet)
+ if v, ok := m[name]; ok {
+ p.set = v.(*AsPathSet)
+ }
return p
}
@@ -1282,7 +1304,8 @@ func TestAs4PathConditionWithOtherCondition(t *testing.T) {
//test
r := NewRoutingPolicy()
r.Reload(pl)
- p, _ := NewPolicy(pl.PolicyDefinitions[0], r.DefinedSetMap)
+ p, _ := NewPolicy(pl.PolicyDefinitions[0])
+ addPolicy(r, p)
pType, newPath := p.Apply(path, nil)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -1364,7 +1387,10 @@ func TestAs4PathConditionEvaluateMixedWith2byteAS(t *testing.T) {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p, _ := NewAsPathCondition(matchSet, m)
+ p, _ := NewAsPathCondition(matchSet)
+ if v, ok := m[name]; ok {
+ p.set = v.(*AsPathSet)
+ }
return p
}
@@ -1499,7 +1525,10 @@ func TestCommunityConditionEvaluate(t *testing.T) {
matchSet := config.MatchCommunitySet{}
matchSet.CommunitySet = name
matchSet.MatchSetOptions = option
- c, _ := NewCommunityCondition(matchSet, m)
+ c, _ := NewCommunityCondition(matchSet)
+ if v, ok := m[name]; ok {
+ c.set = v.(*CommunitySet)
+ }
return c
}
@@ -2027,7 +2056,11 @@ func TestExtCommunityConditionEvaluate(t *testing.T) {
matchSet := config.MatchExtCommunitySet{}
matchSet.ExtCommunitySet = name
matchSet.MatchSetOptions = option
- c, _ := NewExtCommunityCondition(matchSet, m)
+ c, _ := NewExtCommunityCondition(matchSet)
+ if v, ok := m[name]; ok {
+ c.set = v.(*ExtCommunitySet)
+ }
+
return c
}
@@ -2590,7 +2623,8 @@ func TestPolicyAs4PathPrepend(t *testing.T) {
//test
r := NewRoutingPolicy()
r.Reload(pl)
- p, _ := NewPolicy(pl.PolicyDefinitions[0], r.DefinedSetMap)
+ p, _ := NewPolicy(pl.PolicyDefinitions[0])
+ addPolicy(r, p)
pType, newPath := p.Apply(path, nil)
assert.Equal(ROUTE_TYPE_ACCEPT, pType)
@@ -2645,7 +2679,8 @@ func TestPolicyAs4PathPrependLastAs(t *testing.T) {
//test
r := NewRoutingPolicy()
r.Reload(pl)
- p, _ := NewPolicy(pl.PolicyDefinitions[0], r.DefinedSetMap)
+ p, _ := NewPolicy(pl.PolicyDefinitions[0])
+ addPolicy(r, p)
pType, newPath := p.Apply(path, nil)
assert.Equal(ROUTE_TYPE_ACCEPT, pType)