summaryrefslogtreecommitdiffhomepage
path: root/policy/policy.go
diff options
context:
space:
mode:
Diffstat (limited to 'policy/policy.go')
-rw-r--r--policy/policy.go166
1 files changed, 30 insertions, 136 deletions
diff --git a/policy/policy.go b/policy/policy.go
index 5d0dc631..21bae110 100644
--- a/policy/policy.go
+++ b/policy/policy.go
@@ -383,8 +383,8 @@ func (c *AsPathLengthCondition) evaluate(path *table.Path) bool {
type AsPathCondition struct {
DefaultCondition
- AsPathList []*AsPathElement
- MatchOption config.MatchSetOptionsType
+ AsRegExpList []*regexp.Regexp
+ MatchOption config.MatchSetOptionsType
}
type AsnPos int
@@ -396,89 +396,43 @@ const (
AS_ONLY
)
-type AsPathElement struct {
- postiion AsnPos
- asStr string
- asRegExps []*regexp.Regexp
-}
+const (
+ ASPATH_REGEXP_MAGIC = "(^|[,{}() ]|$)"
+)
-// create AsPathCondition object
-// AsPathCondition supports only following regexp:
-// - ^100 (from as100)
-// - ^100$ (from as100 and originated by as100)
-// - 100$ (originated by as100)
-// - 100 (from or through or originated by as100)
func NewAsPathCondition(matchSet config.MatchAsPathSet, defAsPathSetList []config.AsPathSet) *AsPathCondition {
-
asPathSetName := matchSet.AsPathSet
options := matchSet.MatchSetOptions
- asPathList := make([]*AsPathElement, 0)
+ asRegExpList := make([]*regexp.Regexp, 0)
for _, asPathSet := range defAsPathSetList {
if asPathSet.AsPathSetName == asPathSetName {
for _, aspath := range asPathSet.AsPathList {
a := aspath.AsPath
if len(a) != 0 {
- isTop := a[:1] == "^"
- if isTop {
- a = a[1:]
- }
- isEnd := a[len(a)-1:] == "$"
- if isEnd {
- a = a[:len(a)-1]
- }
- elems := strings.Split(a, "_")
- asRegExps := make([]*regexp.Regexp, 0)
- for _, el := range elems {
- if len(el) == 0 {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "AsPath Condition",
- "Value": aspath.AsPath,
- "Elem": el,
- }).Error("invalid element. do not enter a blank.")
- return nil
- }
- regElem, err := regexp.Compile(el)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "AsPath Condition",
- "Value": aspath.AsPath,
- "Elem": el,
- "Error": err,
- }).Error("can not comple AS_PATH values to Regular expressions.")
- return nil
- }
- asRegExps = append(asRegExps, regElem)
- }
-
- e := &AsPathElement{}
- e.asRegExps = asRegExps
- e.asStr = a
- if isTop && isEnd {
- e.postiion = AS_ONLY
- } else if isTop && !isEnd {
- e.postiion = AS_FROM
- } else if !isTop && isEnd {
- e.postiion = AS_ORIGIN
- } else {
- e.postiion = AS_ANY
+ r, err := regexp.Compile(strings.Replace(a, "_", ASPATH_REGEXP_MAGIC, -1))
+ if err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Type": "AsPath Condition",
+ "Value": aspath.AsPath,
+ "Error": err,
+ }).Error("can not comple AS_PATH values to Regular expressions.")
+ return nil
}
- asPathList = append(asPathList, e)
+ asRegExpList = append(asRegExpList, r)
} else {
log.WithFields(log.Fields{
"Topic": "Policy",
"Type": "AsPath Condition",
}).Error("does not parse AS_PATH condition value.")
-
return nil
}
}
c := &AsPathCondition{
- AsPathList: asPathList,
- MatchOption: options,
+ AsRegExpList: asRegExpList,
+ MatchOption: options,
}
return c
}
@@ -486,101 +440,41 @@ func NewAsPathCondition(matchSet config.MatchAsPathSet, defAsPathSetList []confi
return nil
}
-func (c *AsPathCondition) checkMembers(aspath []uint32, checkAll bool) bool {
-
- checkElem := func(checkType AsnPos, regElems []*regexp.Regexp) bool {
- aslen := len(aspath)
- reglen := len(regElems)
-
- if aslen < reglen {
- return false
- }
-
- switch checkType {
- case AS_ONLY:
- if aslen != reglen {
- return false
- }
- fallthrough
- case AS_FROM:
- for i := 0; i < reglen; i++ {
- if !regElems[i].MatchString(fmt.Sprintf("%d", aspath[i])) {
- return false
- }
- }
- case AS_ORIGIN:
- for i := 0; i < reglen; i++ {
- if !regElems[reglen-i-1].MatchString(fmt.Sprintf("%d", aspath[aslen-i-1])) {
- return false
- }
- }
- case AS_ANY:
- for i := 0; i < aslen; i++ {
- eMatched := true
- if aslen < i+reglen {
- break
- }
- for j := 0; j < reglen; j++ {
- if !regElems[j].MatchString(fmt.Sprintf("%d", aspath[i+j])) {
- eMatched = false
- break
- }
- }
- if eMatched {
- return true
- }
- }
- return false
- }
- return true
- }
-
- result := false
- if checkAll {
- result = true
- }
- for _, member := range c.AsPathList {
- if checkElem(member.postiion, member.asRegExps) {
+func (c *AsPathCondition) checkMembers(aspathStr string, checkAll bool) bool {
+ for _, r := range c.AsRegExpList {
+ if r.MatchString(aspathStr) {
log.WithFields(log.Fields{
"Topic": "Policy",
"Condition": "aspath length",
- "ASN": member.asStr,
- "Position": member.postiion,
+ "AS": aspathStr,
+ "ASN": r,
}).Debug("aspath condition matched")
if !checkAll {
- result = true
- break
+ return true
}
-
} else {
if checkAll {
- result = false
- break
+ return false
}
}
}
-
- return result
+ return checkAll
}
// compare AS_PATH in the message's AS_PATH attribute with
// the one in condition.
func (c *AsPathCondition) evaluate(path *table.Path) bool {
- aspath := path.GetAsSeqList()
-
- if c == nil || len(aspath) == 0 {
- return false
- }
+ aspathStr := path.GetAsString()
result := false
if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ALL {
- result = c.checkMembers(aspath, true)
+ result = c.checkMembers(aspathStr, true)
} else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ANY {
- result = c.checkMembers(aspath, false)
+ result = c.checkMembers(aspathStr, false)
} else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_INVERT {
- result = !c.checkMembers(aspath, false)
+ result = !c.checkMembers(aspathStr, false)
}
log.WithFields(log.Fields{