diff options
Diffstat (limited to 'policy/policy.go')
-rw-r--r-- | policy/policy.go | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/policy/policy.go b/policy/policy.go index 62a667af..06921eab 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -1009,9 +1009,10 @@ func (r *RoutingAction) apply(path *table.Path) *table.Path { } type CommunityAction struct { - Values []uint32 - ext []byte - action config.BgpSetCommunityOptionType + Values []uint32 + ext []byte + action config.BgpSetCommunityOptionType + RegexpValues []*regexp.Regexp } const ( @@ -1032,20 +1033,39 @@ func NewCommunityAction(action config.SetCommunity) *CommunityAction { return nil } - values := make([]uint32, len(communities)) - for i, com := range communities { + values := make([]uint32, 0, len(communities)) + regexpValues := make([]*regexp.Regexp, 0, len(communities)) + + for _, com := range communities { matched, value := getCommunityValue(com) if matched { - values[i] = value - } else { + values = append(values, value) + continue + } + + exp, err := regexp.Compile(com) + if err != nil { log.WithFields(log.Fields{ "Topic": "Policy", "Type": "Community Action", - }).Error("community string invalid.") + }).Errorf("community string invalid") return nil } + regexpValues = append(regexpValues, exp) + } + if len(values) > 0 { + m.Values = values + } + if len(regexpValues) > 0 { + if action.Options != COMMUNITY_ACTION_REMOVE { + log.WithFields(log.Fields{ + "Topic": "Policy", + "Type": "Community Action", + }).Error("regexp values can only be used for remove action") + return nil + } + m.RegexpValues = regexpValues } - m.Values = values switch action.Options { case COMMUNITY_ACTION_ADD: @@ -1064,6 +1084,21 @@ func NewCommunityAction(action config.SetCommunity) *CommunityAction { return m } +func RegexpRemoveCommunities(path *table.Path, exps []*regexp.Regexp) { + comms := path.GetCommunities() + newComms := make([]uint32, 0, len(comms)) + for _, comm := range comms { + c := fmt.Sprintf("%d:%d", comm>>16, comm&0x0000ffff) + for _, exp := range exps { + if !exp.MatchString(c) { + newComms = append(newComms, comm) + break + } + } + } + path.SetCommunities(newComms, true) +} + func (a *CommunityAction) apply(path *table.Path) *table.Path { if len(a.ext) > 0 { return a.extApply(path) @@ -1074,6 +1109,9 @@ func (a *CommunityAction) apply(path *table.Path) *table.Path { path.SetCommunities(list, false) case config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE: path.RemoveCommunities(list) + if len(a.RegexpValues) > 0 { + RegexpRemoveCommunities(path, a.RegexpValues) + } case config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE: path.SetCommunities(list, true) } |