diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-13 16:16:15 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-13 18:12:59 +0900 |
commit | af0c03bbec611fca01374eb47da6b8524023b78f (patch) | |
tree | 24350b79a5e56d0423c76bda47000568b0ac419c | |
parent | 69aceacaecde3adda0ed9627ecbff3922225433d (diff) |
policy: support adding extCommunity action
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | policy/policy.go | 47 | ||||
-rw-r--r-- | table/path.go | 19 |
2 files changed, 65 insertions, 1 deletions
diff --git a/policy/policy.go b/policy/policy.go index ab1d2b1a..4755860a 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -125,6 +125,11 @@ func NewPolicy(pd config.PolicyDefinition, ds config.DefinedSets) *Policy { mda = append(mda, com) } + ext := NewExtCommunityAction(statement.Actions.BgpActions.SetExtCommunity) + if ext != nil { + mda = append(mda, ext) + } + // Med Action med := NewMedAction(statement.Actions.BgpActions.SetMed) if med != nil { @@ -1024,6 +1029,7 @@ func (r *RoutingAction) apply(path *table.Path) *table.Path { type CommunityAction struct { DefaultAction Values []uint32 + ext []byte action config.BgpSetCommunityOptionType } @@ -1078,7 +1084,9 @@ func NewCommunityAction(action config.SetCommunity) *CommunityAction { } func (a *CommunityAction) apply(path *table.Path) *table.Path { - + if len(a.ext) > 0 { + return a.extApply(path) + } list := a.Values switch a.action { case config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD: @@ -1099,6 +1107,43 @@ func (a *CommunityAction) apply(path *table.Path) *table.Path { return path } +func (a *CommunityAction) extApply(path *table.Path) *table.Path { + path.SetExtCommunities(a.ext, false) + return path +} + +func NewExtCommunityAction(action config.SetExtCommunity) *CommunityAction { + communities := action.SetExtCommunityMethod.Communities + if len(communities) == 0 { + return nil + } + + b := make([]byte, len(communities)*8) + for i, c := range communities { + l := strings.Split(c, ":") + if len(l) != 8 { + goto E + } + for j, v := range l { + v, err := strconv.ParseInt(v, 0, 32) + if err != nil { + goto E + } + b[j+i*8] = uint8(v) + } + } + return &CommunityAction{ + ext: b, + } +E: + log.WithFields(log.Fields{ + "Topic": "Policy", + "Action": "ExtCommunity", + "Values": communities, + }).Error("invalid extended community action") + return nil +} + type ActionType int type MedAction struct { diff --git a/table/path.go b/table/path.go index 8025a63a..7e131185 100644 --- a/table/path.go +++ b/table/path.go @@ -514,6 +514,25 @@ func (path *Path) GetExtCommunities() []bgp.ExtendedCommunityInterface { return eCommunityList } +func (path *Path) SetExtCommunities(values []byte, doReplace bool) { + exts := []bgp.ExtendedCommunityInterface{} + for len(values) >= 8 { + e := &bgp.UnknownExtended{ + Type: bgp.BGPAttrType(values[0]), + Value: values[1:8], + } + exts = append(exts, e) + values = values[8:] + } + _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) + if attr != nil { + l := attr.(*bgp.PathAttributeExtendedCommunities).Value + l = append(l, exts...) + } else { + path.pathAttrs = append(path.pathAttrs, bgp.NewPathAttributeExtendedCommunities(exts)) + } +} + func (path *Path) GetMed() (uint32, error) { _, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) if attr == nil { |