summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp>2015-04-28 10:48:46 +0900
committerHiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp>2015-04-30 15:52:05 +0900
commitf9577fe75336776c6113ae065062a2455193c798 (patch)
treef2eb1e636d9bc7c65313683c2e3e944f214b1b03
parent4e376c8ca5885910b48282fd10b500b5cba6637b (diff)
policy: refactor match condition codes
-rw-r--r--policy/policy.go204
-rw-r--r--policy/policy_test.go94
2 files changed, 182 insertions, 116 deletions
diff --git a/policy/policy.go b/policy/policy.go
index 9dc3632e..5a683e36 100644
--- a/policy/policy.go
+++ b/policy/policy.go
@@ -43,62 +43,45 @@ const (
type Policy struct {
Name string
- Statements []Statement
+ Statements []*Statement
}
func NewPolicy(name string, pd config.PolicyDefinition, ds config.DefinedSets) *Policy {
stmtList := pd.StatementList
- st := make([]Statement, 0)
+ st := make([]*Statement, 0)
p := &Policy{
Name: name,
}
+
for _, statement := range stmtList {
- prefixSetName := statement.Conditions.MatchPrefixSet
- prefixList := make([]Prefix, 0)
- for _, ps := range ds.PrefixSetList {
- if ps.PrefixSetName == prefixSetName {
- for _, pl := range ps.PrefixList {
- prefix, e := NewPrefix(pl.Address, pl.Masklength, pl.MasklengthRange)
- if e != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "prefix": prefix,
- "msg": e,
- }).Warn("failed to generate a NewPrefix from configration.")
- }
- prefixList = append(prefixList, prefix)
- }
- }
- }
+ conditions := make([]Condition,0)
+
+ // prefix match
+ prefixSetName := statement.Conditions.MatchPrefixSet
+ pc := NewPrefixCondition(prefixSetName, ds.PrefixSetList)
+ conditions = append(conditions, pc)
+ // neighbor match
neighborSetName := statement.Conditions.MatchNeighborSet
- neighborList := make([]net.IP, 0)
- for _, neighborSet := range ds.NeighborSetList {
- if neighborSet.NeighborSetName == neighborSetName {
- for _, nl := range neighborSet.NeighborInfoList {
- neighborList = append(neighborList, nl.Address)
- }
- }
- }
- con := &PrefixConditions{
- PrefixList: prefixList,
- NeighborList: neighborList,
- MatchSetOptions: statement.Conditions.MatchSetOptions,
- }
+ nc := NewNeighborCondition(neighborSetName, ds.NeighborSetList)
+ conditions = append(conditions, nc)
- act := &RoutingActions{
+ action := &RoutingActions{
AcceptRoute: false,
}
+
if statement.Actions.AcceptRoute {
- act.AcceptRoute = true
+ action.AcceptRoute = true
}
- s := Statement{
+ s := &Statement{
Name: statement.Name,
- Conditions: con,
- Actions: act,
+ Conditions: conditions,
+ Actions: action,
+ MatchSetOptions: statement.Conditions.MatchSetOptions,
}
+
st = append(st, s)
}
p.Statements = st
@@ -106,56 +89,109 @@ func NewPolicy(name string, pd config.PolicyDefinition, ds config.DefinedSets) *
}
type Statement struct {
- Name string
- Conditions Conditions
- Actions Actions
+ Name string
+ Conditions []Condition
+ Actions Actions
+ MatchSetOptions config.MatchSetOptionsType
+}
+
+// evaluate each condition in the statement according to MatchSetOptions
+func (s *Statement) evaluate(p table.Path) bool {
+
+ optionType := s.MatchSetOptions
+
+ result := false
+ if optionType == config.MATCH_SET_OPTIONS_TYPE_ALL {
+ result = true
+ }
+
+ for _, condition := range s.Conditions {
+
+ r := condition.evaluate(p)
+
+ switch optionType {
+ case config.MATCH_SET_OPTIONS_TYPE_ALL:
+ result = result && r
+ if !result {
+ return false
+ }
+
+ case config.MATCH_SET_OPTIONS_TYPE_ANY:
+ result = result || r
+ if result {
+ return true
+ }
+
+ case config.MATCH_SET_OPTIONS_TYPE_INVERT:
+ result = result || r
+ if result {
+ return false
+ }
+
+ default:
+ return false
+ }
+ }
+
+ if optionType == config.MATCH_SET_OPTIONS_TYPE_INVERT {
+ return !result
+ } else {
+ return result
+ }
}
-type Conditions interface {
+type Condition interface {
evaluate(table.Path) bool
}
-type DefaultConditions struct {
+type DefaultCondition struct {
CallPolicy string
}
-func (c *DefaultConditions) evaluate(path table.Path) bool {
+func (c *DefaultCondition) evaluate(path table.Path) bool {
return false
}
-type PrefixConditions struct {
- DefaultConditions
- PrefixList []Prefix
- NeighborList []net.IP
- MatchSetOptions config.MatchSetOptionsType
+type PrefixCondition struct {
+ DefaultCondition
+ PrefixList []Prefix
}
-// evaluate path's prefix and neighbor's address with conditions
-// return value depends on MatchSetOptions
-func (c *PrefixConditions) evaluate(path table.Path) bool {
- pref := c.evaluatePrefix(path)
- log.Debug("evaluate prefix : ", pref)
- neigh := c.evaluateNeighbor(path)
- log.Debug("evaluate neighbor : ", neigh)
-
- switch c.MatchSetOptions {
- case config.MATCH_SET_OPTIONS_TYPE_ALL:
- return pref && neigh
- case config.MATCH_SET_OPTIONS_TYPE_ANY:
- return pref || neigh
- case config.MATCH_SET_OPTIONS_TYPE_INVERT:
- return !(pref || neigh)
- default:
- return false
+func NewPrefixCondition(prefixSetName string, defPrefixList []config.PrefixSet) *PrefixCondition {
+
+ prefixList := make([]Prefix, 0)
+ for _, ps := range defPrefixList {
+ if ps.PrefixSetName == prefixSetName {
+ for _, pl := range ps.PrefixList {
+ prefix, e := NewPrefix(pl.Address, pl.Masklength, pl.MasklengthRange)
+ if e != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "prefix": prefix,
+ "msg": e,
+ }).Warn("failed to generate a NewPrefix from configration.")
+ } else {
+ prefixList = append(prefixList, prefix)
+ }
+ }
+ }
+ }
+
+ pc := &PrefixCondition{
+ PrefixList: prefixList,
}
+
+ return pc
+
}
// compare prefixes in this condition and nlri of path and
// subsequent comparison is skipped if that matches the conditions.
// If PrefixList's length is zero, return true.
-func (c *PrefixConditions) evaluatePrefix(path table.Path) bool {
+func (c *PrefixCondition) evaluate(path table.Path) bool {
if len(c.PrefixList) == 0 {
+ log.Debug("PrefixList doesn't have elements")
return true
}
@@ -168,12 +204,36 @@ func (c *PrefixConditions) evaluatePrefix(path table.Path) bool {
return false
}
+type NeighborCondition struct {
+ DefaultCondition
+ NeighborList []net.IP
+}
+
+func NewNeighborCondition(neighborSetName string, defNeighborSetList []config.NeighborSet) *NeighborCondition {
+
+ neighborList := make([]net.IP, 0)
+ for _, neighborSet := range defNeighborSetList {
+ if neighborSet.NeighborSetName == neighborSetName {
+ for _, nl := range neighborSet.NeighborInfoList {
+ neighborList = append(neighborList, nl.Address)
+ }
+ }
+ }
+
+ nc := &NeighborCondition{
+ NeighborList: neighborList,
+ }
+
+ return nc
+}
+
// compare neighbor ipaddress of this condition and source address of path
// and, subsequent comparisons are skipped if that matches the conditions.
// If NeighborList's length is zero, return true.
-func (c *PrefixConditions) evaluateNeighbor(path table.Path) bool {
+func (c *NeighborCondition) evaluate(path table.Path) bool {
if len(c.NeighborList) == 0 {
+ log.Debug("NeighborList doesn't have elements")
return true
}
@@ -244,8 +304,14 @@ func NewPrefix(addr net.IP, maskLen uint8, maskRange string) (Prefix, error) {
idx := strings.Index(maskRange, "..")
if idx == -1 {
- return p, fmt.Errorf("mask length range of condition is invalid format. mask length is not defined.")
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Type": "Prefix",
+ "MaskRangeFormat": maskRange,
+ }).Warn("mask length range format is invalid. mask range was skipped.")
+ return p, nil
}
+
if idx != 0 {
min, e := strconv.ParseUint(maskRange[:idx], 10, 8)
if e != nil {
@@ -269,7 +335,7 @@ func NewPrefix(addr net.IP, maskLen uint8, maskRange string) (Prefix, error) {
func (p *Policy) Apply(path table.Path) (bool, RouteType, table.Path) {
for _, statement := range p.Statements {
- result := statement.Conditions.evaluate(path)
+ result := statement.evaluate(path)
log.WithFields(log.Fields{
"Topic": "Policy",
"Path": path,
diff --git a/policy/policy_test.go b/policy/policy_test.go
index ac2c930b..335f1a66 100644
--- a/policy/policy_test.go
+++ b/policy/policy_test.go
@@ -42,13 +42,13 @@ func TestPrefixCalcurateNoRange(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("10.10.0.0"), 24, "")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("10.10.0.101"), 24, "")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, true)
+ assert.Equal(t, true, match2)
pl3, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
match3 := IpPrefixCalculate(path, pl3)
- assert.Equal(t, match3, true)
+ assert.Equal(t, true, match3)
}
func TestPrefixCalcurateAddress(t *testing.T) {
@@ -67,10 +67,10 @@ func TestPrefixCalcurateAddress(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("10.11.0.0"), 16, "21..24")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, true)
+ assert.Equal(t, true, match2)
}
func TestPrefixCalcurateLength(t *testing.T) {
@@ -89,10 +89,10 @@ func TestPrefixCalcurateLength(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("10.10.64.0"), 24, "21..24")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("10.10.64.0"), 16, "21..24")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, true)
+ assert.Equal(t, true, match2)
}
func TestPrefixCalcurateLengthRange(t *testing.T) {
@@ -111,13 +111,13 @@ func TestPrefixCalcurateLengthRange(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..23")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "25..26")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, false)
+ assert.Equal(t, false, match2)
pl3, _ := NewPrefix(net.ParseIP("10.10.0.0"), 16, "21..24")
match3 := IpPrefixCalculate(path, pl3)
- assert.Equal(t, match3, true)
+ assert.Equal(t, true, match3)
}
func TestPrefixCalcurateNoRangeIPv6(t *testing.T) {
@@ -138,13 +138,13 @@ func TestPrefixCalcurateNoRangeIPv6(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("2001:123:123:1::"), 64, "")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, true)
+ assert.Equal(t, true, match2)
pl3, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "64..80")
match3 := IpPrefixCalculate(path, pl3)
- assert.Equal(t, match3, true)
+ assert.Equal(t, true, match3)
}
func TestPrefixCalcurateAddressIPv6(t *testing.T) {
@@ -164,10 +164,10 @@ func TestPrefixCalcurateAddressIPv6(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("2001:123:128::"), 48, "64..80")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "64..80")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, true)
+ assert.Equal(t, true, match2)
}
func TestPrefixCalcurateLengthIPv6(t *testing.T) {
@@ -187,10 +187,10 @@ func TestPrefixCalcurateLengthIPv6(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("2001:123:123:64::"), 64, "64..80")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("2001:123:123:64::"), 48, "64..80")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, true)
+ assert.Equal(t, true, match2)
}
func TestPrefixCalcurateLengthRangeIPv6(t *testing.T) {
@@ -210,13 +210,13 @@ func TestPrefixCalcurateLengthRangeIPv6(t *testing.T) {
// test
pl1, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "62..63")
match1 := IpPrefixCalculate(path, pl1)
- assert.Equal(t, match1, false)
+ assert.Equal(t, false, match1)
pl2, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "65..66")
match2 := IpPrefixCalculate(path, pl2)
- assert.Equal(t, match2, false)
+ assert.Equal(t, false, match2)
pl3, _ := NewPrefix(net.ParseIP("2001:123:123::"), 48, "63..65")
match3 := IpPrefixCalculate(path, pl3)
- assert.Equal(t, match3, true)
+ assert.Equal(t, true, match3)
}
func TestPolicyNotMatch(t *testing.T) {
@@ -272,9 +272,9 @@ func TestPolicyNotMatch(t *testing.T) {
df := pl.DefinedSets
p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
match, pType, newPath := p.Apply(path)
- assert.Equal(t, match, false)
- assert.Equal(t, pType, ROUTE_TYPE_NONE)
- assert.Equal(t, newPath, nil)
+ assert.Equal(t, false, match)
+ assert.Equal(t, ROUTE_TYPE_NONE, pType)
+ assert.Equal(t, nil, newPath)
}
func TestPolicyMatchAndReject(t *testing.T) {
@@ -330,9 +330,9 @@ func TestPolicyMatchAndReject(t *testing.T) {
df := pl.DefinedSets
p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
match, pType, newPath := p.Apply(path)
- assert.Equal(t, match, true)
- assert.Equal(t, pType, ROUTE_TYPE_REJECT)
- assert.Equal(t, newPath, nil)
+ assert.Equal(t, true, match)
+ assert.Equal(t, ROUTE_TYPE_REJECT, pType)
+ assert.Equal(t, nil, newPath)
}
func TestPolicyMatchAndAccept(t *testing.T) {
@@ -388,9 +388,9 @@ func TestPolicyMatchAndAccept(t *testing.T) {
df := pl.DefinedSets
p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
match, pType, newPath := p.Apply(path)
- assert.Equal(t, match, true)
- assert.Equal(t, pType, ROUTE_TYPE_ACCEPT)
- assert.Equal(t, newPath, path)
+ assert.Equal(t, true, match)
+ assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
+ assert.Equal(t, path, newPath)
}
func TestPolicyRejectOnlyPrefixSet(t *testing.T) {
@@ -452,14 +452,14 @@ func TestPolicyRejectOnlyPrefixSet(t *testing.T) {
df := pl.DefinedSets
p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
match, pType, newPath := p.Apply(path1)
- assert.Equal(t, match, true)
- assert.Equal(t, pType, ROUTE_TYPE_REJECT)
- assert.Equal(t, newPath, nil)
+ assert.Equal(t, true, match)
+ assert.Equal(t, ROUTE_TYPE_REJECT, pType)
+ assert.Equal(t, nil, newPath)
match2, pType2, newPath2 := p.Apply(path2)
- assert.Equal(t, match2, false)
- assert.Equal(t, pType2, ROUTE_TYPE_NONE)
- assert.Equal(t, newPath2, nil)
+ assert.Equal(t, false, match2)
+ assert.Equal(t, ROUTE_TYPE_NONE, pType2)
+ assert.Equal(t, nil, newPath2)
}
func TestPolicyRejectOnlyNeighborSet(t *testing.T) {
@@ -519,14 +519,14 @@ func TestPolicyRejectOnlyNeighborSet(t *testing.T) {
df := pl.DefinedSets
p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
match, pType, newPath := p.Apply(path1)
- assert.Equal(t, match, true)
- assert.Equal(t, pType, ROUTE_TYPE_REJECT)
- assert.Equal(t, newPath, nil)
+ assert.Equal(t, true, match)
+ assert.Equal(t, ROUTE_TYPE_REJECT, pType)
+ assert.Equal(t, nil, newPath)
match2, pType2, newPath2 := p.Apply(path2)
- assert.Equal(t, match2, false)
- assert.Equal(t, pType2, ROUTE_TYPE_NONE)
- assert.Equal(t, newPath2, nil)
+ assert.Equal(t, false, match2)
+ assert.Equal(t, ROUTE_TYPE_NONE, pType2)
+ assert.Equal(t, nil, newPath2)
}
func TestPolicyDifferentRoutefamilyOfPathAndPolicy(t *testing.T) {
@@ -623,12 +623,12 @@ func TestPolicyDifferentRoutefamilyOfPathAndPolicy(t *testing.T) {
df := pl.DefinedSets
p := NewPolicy(pName, pl.PolicyDefinitionList[0], df)
match1, pType1, newPath1 := p.Apply(pathIPv4)
- assert.Equal(t, match1, true)
- assert.Equal(t, pType1, ROUTE_TYPE_REJECT)
- assert.Equal(t, newPath1, nil)
+ assert.Equal(t, true, match1)
+ assert.Equal(t, ROUTE_TYPE_REJECT, pType1)
+ assert.Equal(t, nil, newPath1)
match2, pType2, newPath2 := p.Apply(pathIPv6)
- assert.Equal(t, match2, true)
- assert.Equal(t, pType2, ROUTE_TYPE_REJECT)
- assert.Equal(t, newPath2, nil)
+ assert.Equal(t, true, match2)
+ assert.Equal(t, ROUTE_TYPE_REJECT, pType2)
+ assert.Equal(t, nil, newPath2)
}