summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go156
-rw-r--r--api/gobgp.proto81
-rw-r--r--gobgp/cmd/common.go56
-rw-r--r--gobgp/cmd/neighbor.go8
-rw-r--r--gobgp/cmd/policy.go569
-rw-r--r--packet/bgp.go14
-rw-r--r--server/grpc_server.go6
-rw-r--r--server/peer.go9
-rw-r--r--server/server.go264
-rw-r--r--table/path.go11
-rw-r--r--table/policy.go2796
-rw-r--r--table/policy_test.go503
-rw-r--r--test/scenario_test/route_server_policy_test.py8
13 files changed, 1964 insertions, 2517 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 80a4d789..819be3ad 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -22,15 +22,12 @@ It has these top-level messages:
Peer
Prefix
PrefixSet
- Neighbor
- NeighborSet
AsPathLength
- AsPathSet
- CommunitySet
- ExtCommunitySet
+ MatchSet
Conditions
CommunityAction
AsPrependAction
+ MedAction
Actions
Statement
PolicyDefinition
@@ -399,144 +396,100 @@ func (m *Prefix) String() string { return proto.CompactTextString(m) }
func (*Prefix) ProtoMessage() {}
type PrefixSet struct {
- PrefixSetName string `protobuf:"bytes,1,opt,name=prefix_set_name" json:"prefix_set_name,omitempty"`
- PrefixList []*Prefix `protobuf:"bytes,2,rep,name=prefix_list" json:"prefix_list,omitempty"`
- MatchSetOptions string `protobuf:"bytes,3,opt,name=match_set_options" json:"match_set_options,omitempty"`
+ Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ List []*Prefix `protobuf:"bytes,2,rep,name=list" json:"list,omitempty"`
+ Option int32 `protobuf:"varint,3,opt,name=option" json:"option,omitempty"`
}
func (m *PrefixSet) Reset() { *m = PrefixSet{} }
func (m *PrefixSet) String() string { return proto.CompactTextString(m) }
func (*PrefixSet) ProtoMessage() {}
-func (m *PrefixSet) GetPrefixList() []*Prefix {
+func (m *PrefixSet) GetList() []*Prefix {
if m != nil {
- return m.PrefixList
- }
- return nil
-}
-
-type Neighbor struct {
- Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
-}
-
-func (m *Neighbor) Reset() { *m = Neighbor{} }
-func (m *Neighbor) String() string { return proto.CompactTextString(m) }
-func (*Neighbor) ProtoMessage() {}
-
-type NeighborSet struct {
- NeighborSetName string `protobuf:"bytes,1,opt,name=neighbor_set_name" json:"neighbor_set_name,omitempty"`
- NeighborList []*Neighbor `protobuf:"bytes,2,rep,name=neighbor_list" json:"neighbor_list,omitempty"`
- MatchSetOptions string `protobuf:"bytes,3,opt,name=match_set_options" json:"match_set_options,omitempty"`
-}
-
-func (m *NeighborSet) Reset() { *m = NeighborSet{} }
-func (m *NeighborSet) String() string { return proto.CompactTextString(m) }
-func (*NeighborSet) ProtoMessage() {}
-
-func (m *NeighborSet) GetNeighborList() []*Neighbor {
- if m != nil {
- return m.NeighborList
+ return m.List
}
return nil
}
type AsPathLength struct {
- Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
- Operator string `protobuf:"bytes,2,opt,name=operator" json:"operator,omitempty"`
+ Length uint32 `protobuf:"varint,1,opt,name=length" json:"length,omitempty"`
+ Type int32 `protobuf:"varint,2,opt,name=type" json:"type,omitempty"`
}
func (m *AsPathLength) Reset() { *m = AsPathLength{} }
func (m *AsPathLength) String() string { return proto.CompactTextString(m) }
func (*AsPathLength) ProtoMessage() {}
-type AsPathSet struct {
- AsPathSetName string `protobuf:"bytes,1,opt,name=as_path_set_name" json:"as_path_set_name,omitempty"`
- AsPathMembers []string `protobuf:"bytes,2,rep,name=as_path_members" json:"as_path_members,omitempty"`
- MatchSetOptions string `protobuf:"bytes,3,opt,name=match_set_options" json:"match_set_options,omitempty"`
-}
-
-func (m *AsPathSet) Reset() { *m = AsPathSet{} }
-func (m *AsPathSet) String() string { return proto.CompactTextString(m) }
-func (*AsPathSet) ProtoMessage() {}
-
-type CommunitySet struct {
- CommunitySetName string `protobuf:"bytes,1,opt,name=community_set_name" json:"community_set_name,omitempty"`
- CommunityMembers []string `protobuf:"bytes,2,rep,name=community_members" json:"community_members,omitempty"`
- MatchSetOptions string `protobuf:"bytes,3,opt,name=match_set_options" json:"match_set_options,omitempty"`
+type MatchSet struct {
+ Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ List []string `protobuf:"bytes,2,rep,name=list" json:"list,omitempty"`
+ Option int32 `protobuf:"varint,3,opt,name=option" json:"option,omitempty"`
}
-func (m *CommunitySet) Reset() { *m = CommunitySet{} }
-func (m *CommunitySet) String() string { return proto.CompactTextString(m) }
-func (*CommunitySet) ProtoMessage() {}
-
-type ExtCommunitySet struct {
- ExtCommunitySetName string `protobuf:"bytes,1,opt,name=ext_community_set_name" json:"ext_community_set_name,omitempty"`
- ExtCommunityMembers []string `protobuf:"bytes,2,rep,name=ext_community_members" json:"ext_community_members,omitempty"`
- MatchSetOptions string `protobuf:"bytes,3,opt,name=match_set_options" json:"match_set_options,omitempty"`
-}
-
-func (m *ExtCommunitySet) Reset() { *m = ExtCommunitySet{} }
-func (m *ExtCommunitySet) String() string { return proto.CompactTextString(m) }
-func (*ExtCommunitySet) ProtoMessage() {}
+func (m *MatchSet) Reset() { *m = MatchSet{} }
+func (m *MatchSet) String() string { return proto.CompactTextString(m) }
+func (*MatchSet) ProtoMessage() {}
type Conditions struct {
- MatchPrefixSet *PrefixSet `protobuf:"bytes,1,opt,name=match_prefix_set" json:"match_prefix_set,omitempty"`
- MatchNeighborSet *NeighborSet `protobuf:"bytes,2,opt,name=match_neighbor_set" json:"match_neighbor_set,omitempty"`
- MatchAsPathLength *AsPathLength `protobuf:"bytes,3,opt,name=match_as_path_length" json:"match_as_path_length,omitempty"`
- MatchAsPathSet *AsPathSet `protobuf:"bytes,4,opt,name=match_as_path_set" json:"match_as_path_set,omitempty"`
- MatchCommunitySet *CommunitySet `protobuf:"bytes,5,opt,name=match_community_set" json:"match_community_set,omitempty"`
- MatchExtCommunitySet *ExtCommunitySet `protobuf:"bytes,6,opt,name=match_ext_community_set" json:"match_ext_community_set,omitempty"`
+ PrefixSet *PrefixSet `protobuf:"bytes,1,opt,name=prefix_set" json:"prefix_set,omitempty"`
+ NeighborSet *MatchSet `protobuf:"bytes,2,opt,name=neighbor_set" json:"neighbor_set,omitempty"`
+ AsPathLength *AsPathLength `protobuf:"bytes,3,opt,name=as_path_length" json:"as_path_length,omitempty"`
+ AsPathSet *MatchSet `protobuf:"bytes,4,opt,name=as_path_set" json:"as_path_set,omitempty"`
+ CommunitySet *MatchSet `protobuf:"bytes,5,opt,name=community_set" json:"community_set,omitempty"`
+ ExtCommunitySet *MatchSet `protobuf:"bytes,6,opt,name=ext_community_set" json:"ext_community_set,omitempty"`
+ RpkiResult int32 `protobuf:"varint,7,opt,name=rpki_result" json:"rpki_result,omitempty"`
}
func (m *Conditions) Reset() { *m = Conditions{} }
func (m *Conditions) String() string { return proto.CompactTextString(m) }
func (*Conditions) ProtoMessage() {}
-func (m *Conditions) GetMatchPrefixSet() *PrefixSet {
+func (m *Conditions) GetPrefixSet() *PrefixSet {
if m != nil {
- return m.MatchPrefixSet
+ return m.PrefixSet
}
return nil
}
-func (m *Conditions) GetMatchNeighborSet() *NeighborSet {
+func (m *Conditions) GetNeighborSet() *MatchSet {
if m != nil {
- return m.MatchNeighborSet
+ return m.NeighborSet
}
return nil
}
-func (m *Conditions) GetMatchAsPathLength() *AsPathLength {
+func (m *Conditions) GetAsPathLength() *AsPathLength {
if m != nil {
- return m.MatchAsPathLength
+ return m.AsPathLength
}
return nil
}
-func (m *Conditions) GetMatchAsPathSet() *AsPathSet {
+func (m *Conditions) GetAsPathSet() *MatchSet {
if m != nil {
- return m.MatchAsPathSet
+ return m.AsPathSet
}
return nil
}
-func (m *Conditions) GetMatchCommunitySet() *CommunitySet {
+func (m *Conditions) GetCommunitySet() *MatchSet {
if m != nil {
- return m.MatchCommunitySet
+ return m.CommunitySet
}
return nil
}
-func (m *Conditions) GetMatchExtCommunitySet() *ExtCommunitySet {
+func (m *Conditions) GetExtCommunitySet() *MatchSet {
if m != nil {
- return m.MatchExtCommunitySet
+ return m.ExtCommunitySet
}
return nil
}
type CommunityAction struct {
Communities []string `protobuf:"bytes,1,rep,name=communities" json:"communities,omitempty"`
- Options string `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"`
+ Option int32 `protobuf:"varint,2,opt,name=option" json:"option,omitempty"`
}
func (m *CommunityAction) Reset() { *m = CommunityAction{} }
@@ -544,18 +497,28 @@ func (m *CommunityAction) String() string { return proto.CompactTextString(m) }
func (*CommunityAction) ProtoMessage() {}
type AsPrependAction struct {
- As string `protobuf:"bytes,1,opt,name=as" json:"as,omitempty"`
- Repeatn uint32 `protobuf:"varint,2,opt,name=repeatn" json:"repeatn,omitempty"`
+ Asn uint32 `protobuf:"varint,1,opt,name=asn" json:"asn,omitempty"`
+ Repeat uint32 `protobuf:"varint,2,opt,name=repeat" json:"repeat,omitempty"`
+ UseLeftMost bool `protobuf:"varint,3,opt,name=use_left_most" json:"use_left_most,omitempty"`
}
func (m *AsPrependAction) Reset() { *m = AsPrependAction{} }
func (m *AsPrependAction) String() string { return proto.CompactTextString(m) }
func (*AsPrependAction) ProtoMessage() {}
+type MedAction struct {
+ Type int32 `protobuf:"varint,1,opt,name=type" json:"type,omitempty"`
+ Value int64 `protobuf:"varint,2,opt,name=value" json:"value,omitempty"`
+}
+
+func (m *MedAction) Reset() { *m = MedAction{} }
+func (m *MedAction) String() string { return proto.CompactTextString(m) }
+func (*MedAction) ProtoMessage() {}
+
type Actions struct {
RouteAction RouteAction `protobuf:"varint,1,opt,name=route_action,enum=gobgpapi.RouteAction" json:"route_action,omitempty"`
Community *CommunityAction `protobuf:"bytes,2,opt,name=community" json:"community,omitempty"`
- Med string `protobuf:"bytes,3,opt,name=med" json:"med,omitempty"`
+ Med *MedAction `protobuf:"bytes,3,opt,name=med" json:"med,omitempty"`
AsPrepend *AsPrependAction `protobuf:"bytes,4,opt,name=as_prepend" json:"as_prepend,omitempty"`
ExtCommunity *CommunityAction `protobuf:"bytes,5,opt,name=ext_community" json:"ext_community,omitempty"`
}
@@ -571,6 +534,13 @@ func (m *Actions) GetCommunity() *CommunityAction {
return nil
}
+func (m *Actions) GetMed() *MedAction {
+ if m != nil {
+ return m.Med
+ }
+ return nil
+}
+
func (m *Actions) GetAsPrepend() *AsPrependAction {
if m != nil {
return m.AsPrepend
@@ -586,9 +556,9 @@ func (m *Actions) GetExtCommunity() *CommunityAction {
}
type Statement struct {
- StatementNeme string `protobuf:"bytes,1,opt,name=statement_neme" json:"statement_neme,omitempty"`
- Conditions *Conditions `protobuf:"bytes,2,opt,name=conditions" json:"conditions,omitempty"`
- Actions *Actions `protobuf:"bytes,3,opt,name=actions" json:"actions,omitempty"`
+ Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ Conditions *Conditions `protobuf:"bytes,2,opt,name=conditions" json:"conditions,omitempty"`
+ Actions *Actions `protobuf:"bytes,3,opt,name=actions" json:"actions,omitempty"`
}
func (m *Statement) Reset() { *m = Statement{} }
@@ -610,17 +580,17 @@ func (m *Statement) GetActions() *Actions {
}
type PolicyDefinition struct {
- PolicyDefinitionName string `protobuf:"bytes,1,opt,name=policy_definition_name" json:"policy_definition_name,omitempty"`
- StatementList []*Statement `protobuf:"bytes,2,rep,name=statement_list" json:"statement_list,omitempty"`
+ Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+ Statements []*Statement `protobuf:"bytes,2,rep,name=statements" json:"statements,omitempty"`
}
func (m *PolicyDefinition) Reset() { *m = PolicyDefinition{} }
func (m *PolicyDefinition) String() string { return proto.CompactTextString(m) }
func (*PolicyDefinition) ProtoMessage() {}
-func (m *PolicyDefinition) GetStatementList() []*Statement {
+func (m *PolicyDefinition) GetStatements() []*Statement {
if m != nil {
- return m.StatementList
+ return m.Statements
}
return nil
}
diff --git a/api/gobgp.proto b/api/gobgp.proto
index f575d139..c3f36061 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -177,86 +177,71 @@ message Prefix {
}
message PrefixSet {
- string prefix_set_name = 1;
- repeated Prefix prefix_list = 2;
- string match_set_options = 3;
-}
-
-message Neighbor {
- string address = 1;
-}
-
-message NeighborSet {
- string neighbor_set_name = 1;
- repeated Neighbor neighbor_list = 2;
- string match_set_options = 3;
+ string name = 1;
+ repeated Prefix list = 2;
+ int32 option = 3;
}
message AsPathLength {
- string value = 1;
- string operator = 2;
+ uint32 length = 1;
+ int32 type = 2;
}
-message AsPathSet {
- string as_path_set_name = 1;
- repeated string as_path_members = 2;
- string match_set_options = 3;
-}
-
-message CommunitySet {
- string community_set_name = 1;
- repeated string community_members = 2;
- string match_set_options = 3;
+message MatchSet {
+ string name = 1;
+ repeated string list = 2;
+ int32 option = 3;
}
-message ExtCommunitySet {
- string ext_community_set_name = 1;
- repeated string ext_community_members = 2;
- string match_set_options = 3;
+message Conditions {
+ PrefixSet prefix_set = 1;
+ MatchSet neighbor_set = 2;
+ AsPathLength as_path_length = 3;
+ MatchSet as_path_set = 4;
+ MatchSet community_set = 5;
+ MatchSet ext_community_set = 6;
+ int32 rpki_result = 7;
}
-message Conditions {
- PrefixSet match_prefix_set = 1;
- NeighborSet match_neighbor_set = 2;
- AsPathLength match_as_path_length = 3;
- AsPathSet match_as_path_set = 4;
- CommunitySet match_community_set = 5;
- ExtCommunitySet match_ext_community_set = 6;
+enum RouteAction {
+ NONE = 0;
+ ACCEPT = 1;
+ REJECT = 2;
}
message CommunityAction {
repeated string communities = 1;
- string options = 2;
+ int32 option = 2;
}
-message AsPrependAction {
- string as = 1;
- uint32 repeatn = 2;
+message MedAction {
+ int32 type = 1;
+ int64 value = 2;
}
-enum RouteAction {
- NONE = 0;
- ACCEPT = 1;
- REJECT = 2;
+message AsPrependAction {
+ uint32 asn = 1;
+ uint32 repeat = 2;
+ bool use_left_most = 3;
}
message Actions {
RouteAction route_action = 1;
CommunityAction community = 2;
- string med = 3;
+ MedAction med = 3;
AsPrependAction as_prepend = 4;
CommunityAction ext_community = 5;
}
message Statement {
- string statement_neme = 1;
+ string name = 1;
Conditions conditions = 2;
Actions actions = 3;
}
message PolicyDefinition {
- string policy_definition_name = 1;
- repeated Statement statement_list = 2;
+ string name = 1;
+ repeated Statement statements = 2;
}
enum PolicyType {
diff --git a/gobgp/cmd/common.go b/gobgp/cmd/common.go
index bbe26ea5..197b58cf 100644
--- a/gobgp/cmd/common.go
+++ b/gobgp/cmd/common.go
@@ -321,63 +321,21 @@ func (p prefixes) Swap(i, j int) {
}
func (p prefixes) Less(i, j int) bool {
- return p[i].PrefixSetName < p[j].PrefixSetName
+ return p[i].Name < p[j].Name
}
-type neighbors []*gobgpapi.NeighborSet
+type sets []*gobgpapi.MatchSet
-func (n neighbors) Len() int {
+func (n sets) Len() int {
return len(n)
}
-func (n neighbors) Swap(i, j int) {
+func (n sets) Swap(i, j int) {
n[i], n[j] = n[j], n[i]
}
-func (n neighbors) Less(i, j int) bool {
- return n[i].NeighborSetName < n[j].NeighborSetName
-}
-
-type aspaths []*gobgpapi.AsPathSet
-
-func (a aspaths) Len() int {
- return len(a)
-}
-
-func (a aspaths) Swap(i, j int) {
- a[i], a[j] = a[j], a[i]
-}
-
-func (a aspaths) Less(i, j int) bool {
- return a[i].AsPathSetName < a[j].AsPathSetName
-}
-
-type communities []*gobgpapi.CommunitySet
-
-func (c communities) Len() int {
- return len(c)
-}
-
-func (c communities) Swap(i, j int) {
- c[i], c[j] = c[j], c[i]
-}
-
-func (c communities) Less(i, j int) bool {
- return c[i].CommunitySetName < c[j].CommunitySetName
-}
-
-type extcommunities []*gobgpapi.ExtCommunitySet
-
-func (e extcommunities) Len() int {
- return len(e)
-}
-
-func (e extcommunities) Swap(i, j int) {
- e[i], e[j] = e[j], e[i]
-}
-
-func (e extcommunities) Less(i, j int) bool {
- return e[i].ExtCommunitySetName < e[j].ExtCommunitySetName
+func (n sets) Less(i, j int) bool {
+ return n[i].Name < n[j].Name
}
type policyDefinitions []*gobgpapi.PolicyDefinition
@@ -391,7 +349,7 @@ func (p policyDefinitions) Swap(i, j int) {
}
func (p policyDefinitions) Less(i, j int) bool {
- return p[i].PolicyDefinitionName < p[j].PolicyDefinitionName
+ return p[i].Name < p[j].Name
}
type roas []*gobgpapi.ROA
diff --git a/gobgp/cmd/neighbor.go b/gobgp/cmd/neighbor.go
index ca3640fd..0efa6840 100644
--- a/gobgp/cmd/neighbor.go
+++ b/gobgp/cmd/neighbor.go
@@ -641,9 +641,9 @@ func showNeighborPolicy(remoteIP net.IP, policyType string) error {
}
fmt.Printf("Default: %s\n", ap.Default)
- for _, inPolicy := range ap.Policies {
- fmt.Printf(" PolicyName %s:\n", inPolicy.PolicyDefinitionName)
- showPolicyStatement(2, inPolicy)
+ for _, p := range ap.Policies {
+ fmt.Printf(" PolicyName %s:\n", p.Name)
+ showPolicyStatement(2, p)
}
return nil
}
@@ -654,7 +654,7 @@ func parsePolicy(pNames string) []*api.PolicyDefinition {
for _, p := range pList {
if p != "" {
policy := &api.PolicyDefinition{
- PolicyDefinitionName: p,
+ Name: p,
}
policyList = append(policyList, policy)
}
diff --git a/gobgp/cmd/policy.go b/gobgp/cmd/policy.go
index 6445b9d6..4f9d1f0f 100644
--- a/gobgp/cmd/policy.go
+++ b/gobgp/cmd/policy.go
@@ -20,6 +20,7 @@ import (
"encoding/json"
"fmt"
api "github.com/osrg/gobgp/api"
+ "github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/table"
"github.com/spf13/cobra"
"golang.org/x/net/context"
@@ -38,10 +39,10 @@ func formatPolicyPrefix(head bool, indent int, psl []*api.PrefixSet) string {
maxPrefixLen := 0
maxRangeLen := 0
for _, ps := range psl {
- if len(ps.PrefixSetName) > maxNameLen {
- maxNameLen = len(ps.PrefixSetName)
+ if len(ps.Name) > maxNameLen {
+ maxNameLen = len(ps.Name)
}
- for _, p := range ps.PrefixList {
+ for _, p := range ps.List {
if len(p.IpPrefix) > maxPrefixLen {
maxPrefixLen = len(p.IpPrefix)
}
@@ -68,10 +69,10 @@ func formatPolicyPrefix(head bool, indent int, psl []*api.PrefixSet) string {
buff.WriteString(fmt.Sprintf(format, "Name", "Address", "MaskRange"))
}
for _, ps := range psl {
- for i, p := range ps.PrefixList {
+ for i, p := range ps.List {
prefix := fmt.Sprintf("%s", p.IpPrefix)
if i == 0 {
- buff.WriteString(fmt.Sprintf(format, ps.PrefixSetName, prefix, p.MaskLengthRange))
+ buff.WriteString(fmt.Sprintf(format, ps.Name, prefix, p.MaskLengthRange))
} else {
buff.WriteString(fmt.Sprintf(sIndent))
buff.WriteString(fmt.Sprintf(format, "", prefix, p.MaskLengthRange))
@@ -97,7 +98,7 @@ func showPolicyPrefixes() error {
} else if e != nil {
return e
}
- m = append(m, p.StatementList[0].Conditions.MatchPrefixSet)
+ m = append(m, p.Statements[0].Conditions.PrefixSet)
}
if globalOpts.Json {
@@ -108,7 +109,7 @@ func showPolicyPrefixes() error {
if globalOpts.Quiet {
for _, p := range m {
- fmt.Println(p.PrefixSetName)
+ fmt.Println(p.Name)
}
return nil
}
@@ -129,14 +130,14 @@ func showPolicyPrefix(args []string) error {
if e != nil {
return e
}
- ps := pd.StatementList[0].Conditions.MatchPrefixSet
+ ps := pd.Statements[0].Conditions.PrefixSet
if globalOpts.Json {
j, _ := json.Marshal(ps)
fmt.Println(string(j))
return nil
}
if globalOpts.Quiet {
- for _, p := range ps.PrefixList {
+ for _, p := range ps.List {
fmt.Printf("%s %s\n", p.IpPrefix, p.MaskLengthRange)
}
return nil
@@ -189,8 +190,8 @@ func parsePrefixSet(eArgs []string) (*api.PrefixSet, error) {
}
prefixList := []*api.Prefix{prefix}
prefixSet := &api.PrefixSet{
- PrefixSetName: eArgs[0],
- PrefixList: prefixList,
+ Name: eArgs[0],
+ List: prefixList,
}
return prefixSet, nil
}
@@ -200,17 +201,17 @@ func modPolicy(resource api.Resource, op api.Operation, data interface{}) error
co := &api.Conditions{}
switch resource {
case api.Resource_POLICY_PREFIX:
- co.MatchPrefixSet = data.(*api.PrefixSet)
+ co.PrefixSet = data.(*api.PrefixSet)
case api.Resource_POLICY_NEIGHBOR:
- co.MatchNeighborSet = data.(*api.NeighborSet)
+ co.NeighborSet = data.(*api.MatchSet)
case api.Resource_POLICY_ASPATH:
- co.MatchAsPathSet = data.(*api.AsPathSet)
+ co.AsPathSet = data.(*api.MatchSet)
case api.Resource_POLICY_COMMUNITY:
- co.MatchCommunitySet = data.(*api.CommunitySet)
+ co.CommunitySet = data.(*api.MatchSet)
case api.Resource_POLICY_EXTCOMMUNITY:
- co.MatchExtCommunitySet = data.(*api.ExtCommunitySet)
+ co.ExtCommunitySet = data.(*api.MatchSet)
}
- pd.StatementList = []*api.Statement{{Conditions: co}}
+ pd.Statements = []*api.Statement{{Conditions: co}}
} else {
pd = data.(*api.PolicyDefinition)
}
@@ -258,8 +259,7 @@ func modPolicyPrefix(modtype string, eArgs []string) error {
return fmt.Errorf("usage: policy prefix del <prefix set name> [<prefix> [<mask length renge>]]")
} else if len(eArgs) == 1 {
prefixSet = &api.PrefixSet{
- PrefixSetName: eArgs[0],
- PrefixList: nil,
+ Name: eArgs[0],
}
} else {
if prefixSet, e = parsePrefixSet(eArgs); e != nil {
@@ -281,18 +281,18 @@ func modPolicyPrefix(modtype string, eArgs []string) error {
return nil
}
-func formatPolicyNeighbor(head bool, indent int, nsl []*api.NeighborSet) string {
+func formatPolicyNeighbor(head bool, indent int, nsl []*api.MatchSet) string {
buff := bytes.NewBuffer(make([]byte, 0, 64))
sIndent := strings.Repeat(" ", indent)
maxNameLen := 0
maxAddressLen := 0
for _, ns := range nsl {
- if len(ns.NeighborSetName) > maxNameLen {
- maxNameLen = len(ns.NeighborSetName)
+ if len(ns.Name) > maxNameLen {
+ maxNameLen = len(ns.Name)
}
- for _, n := range ns.NeighborList {
- if len(n.Address) > maxAddressLen {
- maxAddressLen = len(n.Address)
+ for _, n := range ns.List {
+ if len(n) > maxAddressLen {
+ maxAddressLen = len(n)
}
}
}
@@ -311,12 +311,12 @@ func formatPolicyNeighbor(head bool, indent int, nsl []*api.NeighborSet) string
buff.WriteString(fmt.Sprintf(format, "Name", "Address"))
}
for _, ns := range nsl {
- for i, n := range ns.NeighborList {
+ for i, n := range ns.List {
if i == 0 {
- buff.WriteString(fmt.Sprintf(format, ns.NeighborSetName, n.Address))
+ buff.WriteString(fmt.Sprintf(format, ns.Name, n))
} else {
buff.WriteString(fmt.Sprintf(sIndent))
- buff.WriteString(fmt.Sprintf(format, "", n.Address))
+ buff.WriteString(fmt.Sprintf(format, "", n))
}
}
}
@@ -331,7 +331,7 @@ func showPolicyNeighbors() error {
if e != nil {
return e
}
- m := neighbors{}
+ m := sets{}
for {
p, e := stream.Recv()
if e == io.EOF {
@@ -339,7 +339,7 @@ func showPolicyNeighbors() error {
} else if e != nil {
return e
}
- m = append(m, p.StatementList[0].Conditions.MatchNeighborSet)
+ m = append(m, p.Statements[0].Conditions.NeighborSet)
}
if globalOpts.Json {
@@ -350,7 +350,7 @@ func showPolicyNeighbors() error {
if globalOpts.Quiet {
for _, n := range m {
- fmt.Println(n.NeighborSetName)
+ fmt.Println(n.Name)
}
return nil
}
@@ -370,24 +370,24 @@ func showPolicyNeighbor(args []string) error {
if e != nil {
return e
}
- ns := pd.StatementList[0].Conditions.MatchNeighborSet
+ ns := pd.Statements[0].Conditions.NeighborSet
if globalOpts.Json {
j, _ := json.Marshal(ns)
fmt.Println(string(j))
return nil
}
if globalOpts.Quiet {
- for _, n := range ns.NeighborList {
- fmt.Println(n.Address)
+ for _, n := range ns.List {
+ fmt.Println(n)
}
return nil
}
- output := formatPolicyNeighbor(true, 0, []*api.NeighborSet{ns})
+ output := formatPolicyNeighbor(true, 0, []*api.MatchSet{ns})
fmt.Print(output)
return nil
}
-func parseNeighborSet(eArgs []string) (*api.NeighborSet, error) {
+func parseNeighborSet(eArgs []string) (*api.MatchSet, error) {
address := net.ParseIP(eArgs[1])
if address.To4() == nil {
if address.To16() == nil {
@@ -395,19 +395,15 @@ func parseNeighborSet(eArgs []string) (*api.NeighborSet, error) {
}
}
- neighbor := &api.Neighbor{
- Address: address.String(),
- }
- neighborList := []*api.Neighbor{neighbor}
- neighborSet := &api.NeighborSet{
- NeighborSetName: eArgs[0],
- NeighborList: neighborList,
+ neighborSet := &api.MatchSet{
+ Name: eArgs[0],
+ List: []string{address.String()},
}
return neighborSet, nil
}
func modPolicyNeighbor(modtype string, eArgs []string) error {
- neighborSet := &api.NeighborSet{}
+ neighborSet := &api.MatchSet{}
var e error
var operation api.Operation
@@ -424,9 +420,8 @@ func modPolicyNeighbor(modtype string, eArgs []string) error {
if len(eArgs) == 0 {
return fmt.Errorf("usage: policy neighbor del <neighbor set name> [<address>]")
} else if len(eArgs) == 1 {
- neighborSet = &api.NeighborSet{
- NeighborSetName: eArgs[0],
- NeighborList: nil,
+ neighborSet = &api.MatchSet{
+ Name: eArgs[0],
}
} else {
if neighborSet, e = parseNeighborSet(eArgs); e != nil {
@@ -448,16 +443,16 @@ func modPolicyNeighbor(modtype string, eArgs []string) error {
return nil
}
-func formatPolicyAsPath(haed bool, indent int, apsl []*api.AsPathSet) string {
+func formatPolicyAsPath(haed bool, indent int, apsl []*api.MatchSet) string {
buff := bytes.NewBuffer(make([]byte, 0, 64))
sIndent := strings.Repeat(" ", indent)
maxNameLen := 0
maxPathLen := 0
for _, aps := range apsl {
- if len(aps.AsPathSetName) > maxNameLen {
- maxNameLen = len(aps.AsPathSetName)
+ if len(aps.Name) > maxNameLen {
+ maxNameLen = len(aps.Name)
}
- for _, m := range aps.AsPathMembers {
+ for _, m := range aps.List {
if len(m) > maxPathLen {
maxPathLen = len(m)
}
@@ -478,9 +473,9 @@ func formatPolicyAsPath(haed bool, indent int, apsl []*api.AsPathSet) string {
buff.WriteString(fmt.Sprintf(format, "Name", "AsPath"))
}
for _, aps := range apsl {
- for i, a := range aps.AsPathMembers {
+ for i, a := range aps.List {
if i == 0 {
- buff.WriteString(fmt.Sprintf(format, aps.AsPathSetName, a))
+ buff.WriteString(fmt.Sprintf(format, aps.Name, a))
} else {
buff.WriteString(fmt.Sprintf(sIndent))
buff.WriteString(fmt.Sprintf(format, "", a))
@@ -498,7 +493,7 @@ func showPolicyAsPaths() error {
if e != nil {
return e
}
- m := aspaths{}
+ m := sets{}
for {
a, e := stream.Recv()
if e == io.EOF {
@@ -506,7 +501,7 @@ func showPolicyAsPaths() error {
} else if e != nil {
return e
}
- m = append(m, a.StatementList[0].Conditions.MatchAsPathSet)
+ m = append(m, a.Statements[0].Conditions.AsPathSet)
}
if globalOpts.Json {
j, _ := json.Marshal(m)
@@ -515,7 +510,7 @@ func showPolicyAsPaths() error {
}
if globalOpts.Quiet {
for _, a := range m {
- fmt.Println(a.AsPathSetName)
+ fmt.Println(a.Name)
}
return nil
}
@@ -535,24 +530,24 @@ func showPolicyAsPath(args []string) error {
if e != nil {
return e
}
- as := pd.StatementList[0].Conditions.MatchAsPathSet
+ as := pd.Statements[0].Conditions.AsPathSet
if globalOpts.Json {
j, _ := json.Marshal(as)
fmt.Println(string(j))
return nil
}
if globalOpts.Quiet {
- for _, a := range as.AsPathMembers {
+ for _, a := range as.List {
fmt.Println(a)
}
return nil
}
- output := formatPolicyAsPath(true, 0, []*api.AsPathSet{as})
+ output := formatPolicyAsPath(true, 0, []*api.MatchSet{as})
fmt.Print(output)
return nil
}
-func parseAsPathSet(eArgs []string) (*api.AsPathSet, error) {
+func parseAsPathSet(eArgs []string) (*api.MatchSet, error) {
as := eArgs[1]
isTop := as[:1] == "^"
if isTop {
@@ -573,15 +568,15 @@ func parseAsPathSet(eArgs []string) (*api.AsPathSet, error) {
"can not comple aspath values to regular expressions.", eArgs[1])
}
}
- asPathSet := &api.AsPathSet{
- AsPathSetName: eArgs[0],
- AsPathMembers: []string{eArgs[1]},
+ asPathSet := &api.MatchSet{
+ Name: eArgs[0],
+ List: []string{eArgs[1]},
}
return asPathSet, nil
}
func modPolicyAsPath(modtype string, eArgs []string) error {
- asPathSet := &api.AsPathSet{}
+ asPathSet := &api.MatchSet{}
var e error
var operation api.Operation
@@ -598,9 +593,8 @@ func modPolicyAsPath(modtype string, eArgs []string) error {
if len(eArgs) == 0 {
return fmt.Errorf("usage: policy aspath del <aspath set name> [<aspath>]")
} else if len(eArgs) == 1 {
- asPathSet = &api.AsPathSet{
- AsPathSetName: eArgs[0],
- AsPathMembers: nil,
+ asPathSet = &api.MatchSet{
+ Name: eArgs[0],
}
} else {
if asPathSet, e = parseAsPathSet(eArgs); e != nil {
@@ -622,16 +616,16 @@ func modPolicyAsPath(modtype string, eArgs []string) error {
return nil
}
-func formatPolicyCommunity(head bool, indent int, csl []*api.CommunitySet) string {
+func formatPolicyCommunity(head bool, indent int, csl []*api.MatchSet) string {
buff := bytes.NewBuffer(make([]byte, 0, 64))
sIndent := strings.Repeat(" ", indent)
maxNameLen := 0
maxCommunityLen := 0
for _, cs := range csl {
- if len(cs.CommunitySetName) > maxNameLen {
- maxNameLen = len(cs.CommunitySetName)
+ if len(cs.Name) > maxNameLen {
+ maxNameLen = len(cs.Name)
}
- for _, m := range cs.CommunityMembers {
+ for _, m := range cs.List {
if len(m) > maxCommunityLen {
maxCommunityLen = len(m)
}
@@ -652,9 +646,9 @@ func formatPolicyCommunity(head bool, indent int, csl []*api.CommunitySet) strin
buff.WriteString(fmt.Sprintf(format, "Name", "Community"))
}
for _, cs := range csl {
- for i, c := range cs.CommunityMembers {
+ for i, c := range cs.List {
if i == 0 {
- buff.WriteString(fmt.Sprintf(format, cs.CommunitySetName, c))
+ buff.WriteString(fmt.Sprintf(format, cs.Name, c))
} else {
buff.WriteString(fmt.Sprintf(sIndent))
buff.WriteString(fmt.Sprintf(format, "", c))
@@ -672,7 +666,7 @@ func showPolicyCommunities() error {
if e != nil {
return e
}
- m := communities{}
+ m := sets{}
for {
a, e := stream.Recv()
if e == io.EOF {
@@ -680,7 +674,7 @@ func showPolicyCommunities() error {
} else if e != nil {
return e
}
- m = append(m, a.StatementList[0].Conditions.MatchCommunitySet)
+ m = append(m, a.Statements[0].Conditions.CommunitySet)
}
if globalOpts.Json {
j, _ := json.Marshal(m)
@@ -689,7 +683,7 @@ func showPolicyCommunities() error {
}
if globalOpts.Quiet {
for _, c := range m {
- fmt.Println(c.CommunitySetName)
+ fmt.Println(c.Name)
}
return nil
}
@@ -709,53 +703,46 @@ func showPolicyCommunity(args []string) error {
if e != nil {
return e
}
- cs := pd.StatementList[0].Conditions.GetMatchCommunitySet()
+ cs := pd.Statements[0].Conditions.GetCommunitySet()
if globalOpts.Json {
j, _ := json.Marshal(cs)
fmt.Println(string(j))
return nil
}
if globalOpts.Quiet {
- for _, c := range cs.CommunityMembers {
+ for _, c := range cs.List {
fmt.Println(c)
}
return nil
}
- output := formatPolicyCommunity(true, 0, []*api.CommunitySet{cs})
+ output := formatPolicyCommunity(true, 0, []*api.MatchSet{cs})
fmt.Print(output)
return nil
}
func checkCommunityFormat(comStr string) bool {
- // community regexp
- regUint, _ := regexp.Compile("^([0-9]+)$")
- regString, _ := regexp.Compile("([0-9]+):([0-9]+)")
- regWellKnown, _ := regexp.Compile("^(" +
- table.COMMUNITY_INTERNET + "|" +
- table.COMMUNITY_NO_EXPORT + "|" +
- table.COMMUNITY_NO_ADVERTISE + "|" +
- table.COMMUNITY_NO_EXPORT_SUBCONFED + ")$")
- if regUint.MatchString(comStr) || regString.MatchString(comStr) || regWellKnown.MatchString(comStr) {
+ _, e := table.ParseCommunity(comStr)
+ if e == nil {
return true
}
return false
}
-func parseCommunitySet(eArgs []string) (*api.CommunitySet, error) {
+func parseCommunitySet(eArgs []string) (*api.MatchSet, error) {
if !checkCommunityFormat(eArgs[1]) {
if _, err := regexp.Compile(eArgs[1]); err != nil {
return nil, fmt.Errorf("invalid community: %s\nplease enter community format", eArgs[1])
}
}
- communitySet := &api.CommunitySet{
- CommunitySetName: eArgs[0],
- CommunityMembers: []string{eArgs[1]},
+ communitySet := &api.MatchSet{
+ Name: eArgs[0],
+ List: []string{eArgs[1]},
}
return communitySet, nil
}
func modPolicyCommunity(modtype string, eArgs []string) error {
- communitySet := &api.CommunitySet{}
+ communitySet := &api.MatchSet{}
var e error
var operation api.Operation
@@ -772,9 +759,8 @@ func modPolicyCommunity(modtype string, eArgs []string) error {
if len(eArgs) == 0 {
return fmt.Errorf("usage: policy community add <community set name> [<community>]")
} else if len(eArgs) == 1 {
- communitySet = &api.CommunitySet{
- CommunitySetName: eArgs[0],
- CommunityMembers: nil,
+ communitySet = &api.MatchSet{
+ Name: eArgs[0],
}
} else {
if communitySet, e = parseCommunitySet(eArgs); e != nil {
@@ -796,16 +782,16 @@ func modPolicyCommunity(modtype string, eArgs []string) error {
return nil
}
-func formatPolicyExtCommunity(head bool, indent int, ecsl []*api.ExtCommunitySet) string {
+func formatPolicyExtCommunity(head bool, indent int, ecsl []*api.MatchSet) string {
buff := bytes.NewBuffer(make([]byte, 0, 64))
sIndent := strings.Repeat(" ", indent)
maxNameLen := 0
maxCommunityLen := 0
for _, es := range ecsl {
- if len(es.ExtCommunitySetName) > maxNameLen {
- maxNameLen = len(es.ExtCommunitySetName)
+ if len(es.Name) > maxNameLen {
+ maxNameLen = len(es.Name)
}
- for _, m := range es.ExtCommunityMembers {
+ for _, m := range es.List {
if len(m) > maxCommunityLen {
maxCommunityLen = len(m)
}
@@ -826,9 +812,9 @@ func formatPolicyExtCommunity(head bool, indent int, ecsl []*api.ExtCommunitySet
buff.WriteString(fmt.Sprintf(format, "Name", "ExtCommunity"))
}
for _, ecs := range ecsl {
- for i, ec := range ecs.ExtCommunityMembers {
+ for i, ec := range ecs.List {
if i == 0 {
- buff.WriteString(fmt.Sprintf(format, ecs.ExtCommunitySetName, ec))
+ buff.WriteString(fmt.Sprintf(format, ecs.Name, ec))
} else {
buff.WriteString(fmt.Sprintf(sIndent))
buff.WriteString(fmt.Sprintf(format, "", ec))
@@ -846,7 +832,7 @@ func showPolicyExtCommunities() error {
if e != nil {
return e
}
- m := extcommunities{}
+ m := sets{}
for {
a, e := stream.Recv()
if e == io.EOF {
@@ -854,7 +840,7 @@ func showPolicyExtCommunities() error {
} else if e != nil {
return e
}
- m = append(m, a.StatementList[0].Conditions.MatchExtCommunitySet)
+ m = append(m, a.Statements[0].Conditions.ExtCommunitySet)
}
if globalOpts.Json {
j, _ := json.Marshal(m)
@@ -863,7 +849,7 @@ func showPolicyExtCommunities() error {
}
if globalOpts.Quiet {
for _, e := range m {
- fmt.Println(e.ExtCommunitySetName)
+ fmt.Println(e.Name)
}
return nil
}
@@ -883,19 +869,19 @@ func showPolicyExtCommunity(args []string) error {
if e != nil {
return e
}
- ecs := pd.StatementList[0].Conditions.GetMatchExtCommunitySet()
+ ecs := pd.Statements[0].Conditions.GetExtCommunitySet()
if globalOpts.Json {
j, _ := json.Marshal(ecs)
fmt.Println(string(j))
return nil
}
if globalOpts.Quiet {
- for _, ec := range ecs.ExtCommunityMembers {
+ for _, ec := range ecs.List {
fmt.Println(ec)
}
return nil
}
- output := formatPolicyExtCommunity(true, 0, []*api.ExtCommunitySet{ecs})
+ output := formatPolicyExtCommunity(true, 0, []*api.MatchSet{ecs})
fmt.Print(output)
return nil
}
@@ -945,19 +931,18 @@ func checkExtCommunityFormat(eComStr string) bool {
return false
}
-func parseExtCommunitySet(eArgs []string) (*api.ExtCommunitySet, error) {
+func parseExtCommunitySet(eArgs []string) (*api.MatchSet, error) {
if !checkExtCommunityFormat(eArgs[1]) {
return nil, fmt.Errorf("invalid extended community: %s\nplease enter extended community format", eArgs[1])
}
- extCommunitySet := &api.ExtCommunitySet{
- ExtCommunitySetName: eArgs[0],
- ExtCommunityMembers: []string{eArgs[1]},
- }
- return extCommunitySet, nil
+ return &api.MatchSet{
+ Name: eArgs[0],
+ List: []string{eArgs[1]},
+ }, nil
}
func modPolicyExtCommunity(modtype string, eArgs []string) error {
- extCommunitySet := &api.ExtCommunitySet{}
+ extCommunitySet := &api.MatchSet{}
var e error
var operation api.Operation
@@ -974,9 +959,8 @@ func modPolicyExtCommunity(modtype string, eArgs []string) error {
if len(eArgs) == 0 {
return fmt.Errorf("usage: policy extcommunity add <community set name> [<community>]")
} else if len(eArgs) == 1 {
- extCommunitySet = &api.ExtCommunitySet{
- ExtCommunitySetName: eArgs[0],
- ExtCommunityMembers: nil,
+ extCommunitySet = &api.MatchSet{
+ Name: eArgs[0],
}
} else {
if extCommunitySet, e = parseExtCommunitySet(eArgs); e != nil {
@@ -1003,73 +987,93 @@ func showPolicyStatement(indent int, pd *api.PolicyDefinition) {
return strings.Repeat(" ", indent)
}
baseIndent := 28
- for _, st := range pd.StatementList {
- fmt.Printf("%sStatementName %s:\n", sIndent(indent), st.StatementNeme)
+ for _, st := range pd.Statements {
+ fmt.Printf("%sStatementName %s:\n", sIndent(indent), st.Name)
fmt.Printf("%sConditions:\n", sIndent(indent+2))
- ps := st.Conditions.MatchPrefixSet
- fmt.Printf("%sPrefixSet: %-6s ", sIndent(indent+4), ps.MatchSetOptions)
- if out := formatPolicyPrefix(false, baseIndent+indent, []*api.PrefixSet{ps}); out != "" {
- fmt.Print(out)
- } else {
- fmt.Printf("\n")
+ ps := st.Conditions.PrefixSet
+ if ps != nil {
+ fmt.Printf("%sPrefixSet: %-6s ", sIndent(indent+4), table.MatchOption(ps.Option))
+ if out := formatPolicyPrefix(false, baseIndent+indent, []*api.PrefixSet{ps}); out != "" {
+ fmt.Print(out)
+ } else {
+ fmt.Printf("\n")
+ }
}
- ns := st.Conditions.MatchNeighborSet
- fmt.Printf("%sNeighborSet: %-6s ", sIndent(indent+4), ns.MatchSetOptions)
- if out := formatPolicyNeighbor(false, baseIndent+indent, []*api.NeighborSet{ns}); out != "" {
- fmt.Print(out)
- } else {
- fmt.Printf("\n")
+ ns := st.Conditions.NeighborSet
+ if ns != nil {
+ fmt.Printf("%sNeighborSet: %-6s ", sIndent(indent+4), table.MatchOption(ns.Option))
+ if out := formatPolicyNeighbor(false, baseIndent+indent, []*api.MatchSet{ns}); out != "" {
+ fmt.Print(out)
+ } else {
+ fmt.Printf("\n")
+ }
}
- aps := st.Conditions.MatchAsPathSet
- fmt.Printf("%sAsPathSet: %-6s ", sIndent(indent+4), aps.MatchSetOptions)
- if out := formatPolicyAsPath(false, baseIndent+indent, []*api.AsPathSet{aps}); out != "" {
- fmt.Print(out)
- } else {
- fmt.Printf("\n")
+ aps := st.Conditions.AsPathSet
+ if aps != nil {
+ fmt.Printf("%sAsPathSet: %-6s ", sIndent(indent+4), aps.Option)
+ if out := formatPolicyAsPath(false, baseIndent+indent, []*api.MatchSet{aps}); out != "" {
+ fmt.Print(out)
+ } else {
+ fmt.Printf("\n")
+ }
}
- cs := st.Conditions.MatchCommunitySet
- fmt.Printf("%sCommunitySet: %-6s ", sIndent(indent+4), cs.MatchSetOptions)
- if out := formatPolicyCommunity(false, baseIndent+indent, []*api.CommunitySet{cs}); out != "" {
- fmt.Print(out)
- } else {
- fmt.Printf("\n")
+ cs := st.Conditions.CommunitySet
+ if cs != nil {
+ fmt.Printf("%sCommunitySet: %-6s ", sIndent(indent+4), cs.Option)
+ if out := formatPolicyCommunity(false, baseIndent+indent, []*api.MatchSet{cs}); out != "" {
+ fmt.Print(out)
+ } else {
+ fmt.Printf("\n")
+ }
}
- ecs := st.Conditions.MatchExtCommunitySet
- fmt.Printf("%sExtCommunitySet: %-6s ", sIndent(indent+4), ecs.MatchSetOptions)
- if out := formatPolicyExtCommunity(false, baseIndent+indent, []*api.ExtCommunitySet{ecs}); out != "" {
- fmt.Print(out)
- } else {
- fmt.Printf("\n")
+ ecs := st.Conditions.ExtCommunitySet
+ if ecs != nil {
+ fmt.Printf("%sExtCommunitySet: %-6s ", sIndent(indent+4), ecs.Option)
+ if out := formatPolicyExtCommunity(false, baseIndent+indent, []*api.MatchSet{ecs}); out != "" {
+ fmt.Print(out)
+ } else {
+ fmt.Printf("\n")
+ }
}
- asPathLentgh := st.Conditions.MatchAsPathLength
- fmt.Printf("%sAsPathLength: %-6s %s\n", sIndent(indent+4), asPathLentgh.Operator, asPathLentgh.Value)
+ asPathLentgh := st.Conditions.AsPathLength
+ if asPathLentgh != nil {
+ fmt.Printf("%sAsPathLength: %-6s %s\n", sIndent(indent+4), asPathLentgh.Type, asPathLentgh.Length)
+ }
fmt.Printf("%sActions:\n", sIndent(indent+2))
formatComAction := func(c *api.CommunityAction) string {
- communityAction := c.Options
- if len(c.Communities) != 0 || c.Options == "NULL" {
+ option := table.CommunityOptionNameMap[config.BgpSetCommunityOptionType(c.Option)]
+ if len(c.Communities) != 0 {
communities := strings.Join(c.Communities, ",")
- communityAction = fmt.Sprintf("%s[%s]", c.Options, communities)
+ option = fmt.Sprintf("%s[%s]", option, communities)
}
- return communityAction
+ return option
+ }
+ if st.Actions.Community != nil {
+ fmt.Printf("%sCommunity: %s\n", sIndent(indent+4), formatComAction(st.Actions.Community))
}
- fmt.Printf("%sCommunity: %s\n", sIndent(indent+4), formatComAction(st.Actions.Community))
- fmt.Printf("%sExtCommunity: %s\n", sIndent(indent+4), formatComAction(st.Actions.ExtCommunity))
- fmt.Printf("%sMed: %s\n", sIndent(indent+4), st.Actions.Med)
+ if st.Actions.ExtCommunity != nil {
+ fmt.Printf("%sExtCommunity: %s\n", sIndent(indent+4), formatComAction(st.Actions.ExtCommunity))
+ }
+ if st.Actions.Med != nil {
+ fmt.Printf("%sMed: %s\n", sIndent(indent+4), st.Actions.Med.Value)
+ }
+ if st.Actions.AsPrepend != nil {
+ var asn string
+ if st.Actions.AsPrepend.UseLeftMost {
+ asn = "left-most"
+ } else {
+ asn = fmt.Sprintf("%d", st.Actions.AsPrepend.Asn)
+ }
- asn := ""
- repeat := ""
- if st.Actions.AsPrepend.As != "" {
- asn = st.Actions.AsPrepend.As
- repeat = fmt.Sprintf("%d", st.Actions.AsPrepend.Repeatn)
+ fmt.Printf("%sAsPrepend: %s %d\n", sIndent(indent+4), asn, st.Actions.AsPrepend.Repeat)
}
- fmt.Printf("%sAsPrepend: %s %s\n", sIndent(indent+4), asn, repeat)
fmt.Printf("%s%s\n", sIndent(indent+4), st.Actions.RouteAction)
}
@@ -1101,14 +1105,14 @@ func showPolicyRoutePolicies() error {
}
if globalOpts.Quiet {
for _, p := range m {
- fmt.Println(p.PolicyDefinitionName)
+ fmt.Println(p.Name)
}
return nil
}
sort.Sort(m)
for _, pd := range m {
- fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName)
+ fmt.Printf("PolicyName %s:\n", pd.Name)
showPolicyStatement(4, pd)
}
return nil
@@ -1131,102 +1135,120 @@ func showPolicyRoutePolicy(args []string) error {
}
if globalOpts.Quiet {
- for _, st := range pd.StatementList {
- fmt.Println(st.StatementNeme)
+ for _, st := range pd.Statements {
+ fmt.Println(st.Name)
}
return nil
}
- fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName)
+ fmt.Printf("PolicyName %s:\n", pd.Name)
showPolicyStatement(2, pd)
return nil
}
func parseConditions() (*api.Conditions, error) {
- checkFormat := func(option string, isRestricted bool) ([]string, error) {
+ checkFormat := func(option string, isRestricted bool) (int32, string, error) {
regStr, _ := regexp.Compile("^(.*)\\[(.*)\\]$")
isMatched := regStr.MatchString(option)
+ var op int32
+ var name string
if !isMatched {
- return nil, fmt.Errorf("Please enter the <match option>[condition name]")
+ return op, name, fmt.Errorf("Please enter the <match option>[condition name]")
}
group := regStr.FindStringSubmatch(option)
- if isRestricted {
- if group[1] != "ANY" && group[1] != "INVERT" {
- return nil, fmt.Errorf("Please enter the <ANY|INVERT>[condition name]")
- }
- } else {
- if group[1] != "ANY" && group[1] != "ALL" && group[1] != "INVERT" {
- return nil, fmt.Errorf("Please enter the <ANY|ALL|INVERT>[condition name]")
+ switch strings.ToLower(group[1]) {
+ case "any":
+ op = int32(table.MATCH_OPTION_ANY)
+ case "invert":
+ op = int32(table.MATCH_OPTION_INVERT)
+ case "all":
+ if isRestricted {
+ return op, name, fmt.Errorf("can't use 'all' for the condition option")
}
+ op = int32(table.MATCH_OPTION_ALL)
+ default:
+ return op, name, fmt.Errorf("unknown condition option")
}
- return group, nil
+ name = group[2]
+ return op, name, nil
}
conditions := &api.Conditions{}
if conditionOpts.Prefix != "" {
- op, err := checkFormat(conditionOpts.Prefix, true)
+ op, name, err := checkFormat(conditionOpts.Prefix, true)
if err != nil {
return nil, fmt.Errorf("invalid prefix option format\n%s", err)
}
- conditions.MatchPrefixSet = &api.PrefixSet{
- PrefixSetName: op[2],
- MatchSetOptions: op[1],
+ conditions.PrefixSet = &api.PrefixSet{
+ Name: name,
+ Option: op,
}
}
if conditionOpts.Neighbor != "" {
- op, err := checkFormat(conditionOpts.Neighbor, true)
+ op, name, err := checkFormat(conditionOpts.Neighbor, true)
if err != nil {
return nil, fmt.Errorf("invalid neighbor option format\n%s", err)
}
- conditions.MatchNeighborSet = &api.NeighborSet{
- NeighborSetName: op[2],
- MatchSetOptions: op[1],
+ conditions.NeighborSet = &api.MatchSet{
+ Name: name,
+ Option: op,
}
}
if conditionOpts.AsPath != "" {
- op, err := checkFormat(conditionOpts.AsPath, false)
+ op, name, err := checkFormat(conditionOpts.AsPath, false)
if err != nil {
return nil, fmt.Errorf("invalid aspath option format\n%s", err)
}
- conditions.MatchAsPathSet = &api.AsPathSet{
- AsPathSetName: op[2],
- MatchSetOptions: op[1],
+ conditions.AsPathSet = &api.MatchSet{
+ Name: name,
+ Option: op,
}
}
if conditionOpts.Community != "" {
- op, err := checkFormat(conditionOpts.Community, false)
+ op, name, err := checkFormat(conditionOpts.Community, false)
if err != nil {
return nil, fmt.Errorf("invalid community option format\n%s", err)
}
- conditions.MatchCommunitySet = &api.CommunitySet{
- CommunitySetName: op[2],
- MatchSetOptions: op[1],
+ conditions.CommunitySet = &api.MatchSet{
+ Name: name,
+ Option: op,
}
}
if conditionOpts.ExtCommunity != "" {
- op, err := checkFormat(conditionOpts.ExtCommunity, false)
+ op, name, err := checkFormat(conditionOpts.ExtCommunity, false)
if err != nil {
return nil, fmt.Errorf("invalid extended community option format\n%s", err)
}
- conditions.MatchExtCommunitySet = &api.ExtCommunitySet{
- ExtCommunitySetName: op[2],
- MatchSetOptions: op[1],
+ conditions.ExtCommunitySet = &api.MatchSet{
+ Name: name,
+ Option: op,
}
}
if conditionOpts.AsPathLength != "" {
asPathLen := conditionOpts.AsPathLength
- idx := strings.Index(asPathLen, ",")
- if idx == -1 {
+ elems := strings.Split(asPathLen, ",")
+ if len(elems) != 2 {
return nil, fmt.Errorf("invalid as path length: %s\nPlease enter the <value>,<operator>", asPathLen)
}
- operator := asPathLen[:idx]
- value := asPathLen[idx+1:]
- if _, err := strconv.ParseUint(value, 10, 32); err != nil {
- return nil, fmt.Errorf("invalid as path length: %s\nPlease enter a numeric", value)
+ var typ int32
+ switch strings.ToLower(elems[0]) {
+ case "eq":
+ typ = int32(table.ATTRIBUTE_EQ)
+ case "ge":
+ typ = int32(table.ATTRIBUTE_GE)
+ case "le":
+ typ = int32(table.ATTRIBUTE_LE)
+ default:
+ return nil, fmt.Errorf("invalid aspath length action type")
+
+ }
+ length, err := strconv.Atoi(elems[1])
+ if err != nil {
+ return nil, fmt.Errorf("invalid as path length: %s\nPlease enter a numeric", elems[1])
}
- conditions.MatchAsPathLength = &api.AsPathLength{
- Value: value,
- Operator: operator,
+ conditions.AsPathLength = &api.AsPathLength{
+ Type: typ,
+ Length: uint32(length),
}
}
return conditions, nil
@@ -1245,84 +1267,68 @@ func parseRouteAction(rType string) (api.RouteAction, error) {
}
func parseCommunityAction(communityStr string) (*api.CommunityAction, error) {
- regStr, _ := regexp.Compile("^(.*)\\[(.*)\\]$")
- var communities, option string
- communityList := make([]string, 0)
- if regStr.MatchString(communityStr) {
- group := regStr.FindStringSubmatch(communityStr)
- option = group[1]
- communities = group[2]
-
- // check options
- communityActionTypes := table.COMMUNITY_ACTION_ADD + "|" +
- table.COMMUNITY_ACTION_REPLACE + "|" +
- table.COMMUNITY_ACTION_REMOVE + "|" +
- table.COMMUNITY_ACTION_NULL
- regOption, _ := regexp.Compile(fmt.Sprintf("^(%s)$", communityActionTypes))
- if !regOption.MatchString(option) {
- e := fmt.Sprintf("invalid Option: %s\n", option)
- e += fmt.Sprintf("please enter the (%s)", communityActionTypes)
- return nil, fmt.Errorf("%s", e)
- }
- // check the relationship between the community and the option
- if option == "NULL" && communities != "" {
- e := "invalid relationship between community and option\n"
- e += "When the option is NULL, community should not be input"
- return nil, fmt.Errorf("%s", e)
- } else if !(communities == "" && option == "NULL") {
- // check communities
- communityList = strings.Split(communities, ",")
- for _, community := range communityList {
- if !checkCommunityFormat(community) {
- return nil, fmt.Errorf("invalid Community %s:", community)
- }
- }
- }
- } else {
+ exp := regexp.MustCompile("^(.*)\\[(.*)\\]$")
+ elems := exp.FindStringSubmatch(communityStr)
+ if len(elems) != 3 {
e := fmt.Sprintf("invalid format: %s\n", communityStr)
e += "please enter the <option>[<comunity>,<comunity>,...]"
return nil, fmt.Errorf("%s", e)
}
- communityAction := &api.CommunityAction{
- Communities: communityList,
- Options: option,
+
+ var op int32
+ switch strings.ToLower(elems[1]) {
+ case "add":
+ op = int32(config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD)
+ case "remove":
+ op = int32(config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE)
+ case "replace":
+ op = int32(config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE)
+ default:
+ return nil, fmt.Errorf("invalid community action option")
}
- return communityAction, nil
+ return &api.CommunityAction{
+ Communities: strings.Split(elems[2], ","),
+ Option: op,
+ }, nil
}
func parseAsPrependAction(communityStr string) (*api.AsPrependAction, error) {
- regStr, _ := regexp.Compile("^([0-9]+|last-as),([0-9]+)$")
- group := regStr.FindStringSubmatch(communityStr)
-
- as := group[1]
- if as != "last-as" {
- _, e := strconv.ParseUint(as, 10, 32)
- if e != nil {
- return nil, fmt.Errorf("%s", "invalid as number")
- }
+ exp := regexp.MustCompile("^([0-9]+|last-as),([0-9]+)$")
+ elems := exp.FindStringSubmatch(communityStr)
+ if len(elems) != 3 {
+ return nil, fmt.Errorf("invalid asprepend action format")
}
-
- repeatn, e := strconv.ParseUint(group[2], 10, 8)
- if e != nil {
- return nil, fmt.Errorf("%s", "invalid repeat count")
+ asn, err := strconv.Atoi(elems[1])
+ var lastAs bool
+ if err != nil {
+ lastAs = true
}
-
- asprependAction := &api.AsPrependAction{
- As: as,
- Repeatn: uint32(repeatn),
+ repeat, err := strconv.Atoi(elems[2])
+ if err != nil {
+ return nil, fmt.Errorf("%s", "invalid repeat count")
}
-
- return asprependAction, nil
+ return &api.AsPrependAction{
+ Asn: uint32(asn),
+ Repeat: uint32(repeat),
+ UseLeftMost: lastAs,
+ }, nil
}
-func checkMedAction(medStr string) error {
- regMed, _ := regexp.Compile("^(\\+|\\-)?([0-9]+)$")
- if !regMed.MatchString(medStr) {
- e := fmt.Sprintf("invalid format: %s\n", medStr)
- e += "please enter the [+|-]<med>"
- return fmt.Errorf("%s", e)
- }
- return nil
+func parseMedAction(arg string) (*api.MedAction, error) {
+ exp := regexp.MustCompile("^(\\+|\\-)?([0-9]+)$")
+ elems := exp.FindStringSubmatch(arg)
+ if len(elems) != 3 {
+ return nil, fmt.Errorf("invalid med action format")
+ }
+ typ := int32(table.MED_ACTION_MOD)
+ if elems[1] == "" {
+ typ = int32(table.MED_ACTION_REPLACE)
+ }
+ value, _ := strconv.Atoi(elems[2])
+ return &api.MedAction{
+ Type: typ,
+ Value: int64(value),
+ }, nil
}
func checkAsPrependAction(asStr string) error {
@@ -1349,15 +1355,14 @@ func parseActions() (*api.Actions, error) {
if e != nil {
return nil, e
}
-
actions.Community = community
}
if actionOpts.MedAction != "" {
- e := checkMedAction(actionOpts.MedAction)
+ med, e := parseMedAction(actionOpts.MedAction)
if e != nil {
return nil, e
}
- actions.Med = actionOpts.MedAction
+ actions.Med = med
}
if actionOpts.AsPathPrependAction != "" {
@@ -1380,7 +1385,7 @@ func modPolicyRoutePolicy(modtype string, eArgs []string) error {
var operation api.Operation
pd := &api.PolicyDefinition{}
if len(eArgs) > 0 {
- pd.PolicyDefinitionName = eArgs[0]
+ pd.Name = eArgs[0]
}
switch modtype {
@@ -1389,7 +1394,7 @@ func modPolicyRoutePolicy(modtype string, eArgs []string) error {
return fmt.Errorf("usage: gobgp policy routepoilcy add <route policy name> <statement name>")
}
stmt := &api.Statement{
- StatementNeme: eArgs[1],
+ Name: eArgs[1],
}
conditions, err := parseConditions()
if err != nil {
@@ -1402,7 +1407,7 @@ func modPolicyRoutePolicy(modtype string, eArgs []string) error {
stmt.Conditions = conditions
stmt.Actions = actions
- pd.StatementList = []*api.Statement{stmt}
+ pd.Statements = []*api.Statement{stmt}
operation = api.Operation_ADD
case CMD_DEL:
@@ -1412,9 +1417,9 @@ func modPolicyRoutePolicy(modtype string, eArgs []string) error {
operation = api.Operation_DEL
} else if len(eArgs) == 2 {
stmt := &api.Statement{
- StatementNeme: eArgs[1],
+ Name: eArgs[1],
}
- pd.StatementList = []*api.Statement{stmt}
+ pd.Statements = []*api.Statement{stmt}
operation = api.Operation_DEL
}
case CMD_ALL:
diff --git a/packet/bgp.go b/packet/bgp.go
index 3687d817..2d049543 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -4473,8 +4473,8 @@ func NewFourOctetAsSpecificExtended(subtype ExtendedCommunityAttrSubType, as uin
}
}
-func ParseRouteTarget(rt string) (ExtendedCommunityInterface, error) {
- elems, err := parseRdAndRt(rt)
+func ParseExtendedCommunity(subtype ExtendedCommunityAttrSubType, com string) (ExtendedCommunityInterface, error) {
+ elems, err := parseRdAndRt(com)
if err != nil {
return nil, err
}
@@ -4483,18 +4483,22 @@ func ParseRouteTarget(rt string) (ExtendedCommunityInterface, error) {
isTransitive := true
switch {
case ip.To4() != nil:
- return NewIPv4AddressSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, elems[1], uint16(localAdmin), isTransitive), nil
+ return NewIPv4AddressSpecificExtended(subtype, elems[1], uint16(localAdmin), isTransitive), nil
case elems[6] == "" && elems[7] == "":
asn, _ := strconv.Atoi(elems[8])
- return NewTwoOctetAsSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, uint16(asn), uint32(localAdmin), isTransitive), nil
+ return NewTwoOctetAsSpecificExtended(subtype, uint16(asn), uint32(localAdmin), isTransitive), nil
default:
fst, _ := strconv.Atoi(elems[7])
snd, _ := strconv.Atoi(elems[8])
asn := fst<<16 | snd
- return NewFourOctetAsSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, uint32(asn), uint16(localAdmin), isTransitive), nil
+ return NewFourOctetAsSpecificExtended(subtype, uint32(asn), uint16(localAdmin), isTransitive), nil
}
}
+func ParseRouteTarget(rt string) (ExtendedCommunityInterface, error) {
+ return ParseExtendedCommunity(EC_SUBTYPE_ROUTE_TARGET, rt)
+}
+
type OpaqueExtendedValueInterface interface {
Serialize() ([]byte, error)
String() string
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 59d1819c..16b501ec 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -269,7 +269,7 @@ func (s *Server) GetNeighborPolicy(ctx context.Context, arg *api.PolicyArguments
switch arg.Resource {
case api.Resource_GLOBAL:
r = REQ_GLOBAL_POLICY
- case api.Resource_POLICY_NEIGHBOR:
+ case api.Resource_LOCAL:
r = REQ_NEIGHBOR_POLICY
default:
return nil, fmt.Errorf("unsupported resource: %s", arg.Resource)
@@ -421,7 +421,7 @@ func (s *Server) GetPolicyRoutePolicies(arg *api.PolicyArguments, stream api.Gob
default:
return fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
- req := NewGrpcRequest(reqType, "", rf, nil)
+ req := NewGrpcRequest(reqType, "", rf, arg)
s.bgpServerCh <- req
return handleMultipleResponses(req, func(res *GrpcResponse) error {
return stream.Send(res.Data.(*api.PolicyDefinition))
@@ -447,7 +447,7 @@ func (s *Server) GetPolicyRoutePolicy(ctx context.Context, arg *api.PolicyArgume
default:
return nil, fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
- req := NewGrpcRequest(reqType, "", rf, arg.Name)
+ req := NewGrpcRequest(reqType, "", rf, arg)
s.bgpServerCh <- req
res := <-req.ResponseCh
diff --git a/server/peer.go b/server/peer.go
index dde83b6c..71d07c25 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -381,7 +381,7 @@ func (peer *Peer) ToApiStruct() *api.Peer {
}
}
-func (peer *Peer) setPolicy(policyMap map[string]*table.Policy) {
+func (peer *Peer) setPolicy(policy map[string]*table.Policy) {
policyConf := peer.conf.ApplyPolicy
inPolicies := make([]*table.Policy, 0)
for _, policyName := range policyConf.ApplyPolicyConfig.InPolicy {
@@ -390,15 +390,16 @@ func (peer *Peer) setPolicy(policyMap map[string]*table.Policy) {
"Key": peer.conf.NeighborConfig.NeighborAddress,
"PolicyName": policyName,
}).Info("in-policy installed")
- if pol, ok := policyMap[policyName]; ok {
+ if pol, ok := policy[policyName]; ok {
log.Debug("in policy : ", pol)
inPolicies = append(inPolicies, pol)
}
}
peer.inPolicies = inPolicies
peer.defaultInPolicy = policyConf.ApplyPolicyConfig.DefaultInPolicy
-
- peer.localRib.SetPolicy(policyConf, policyMap)
+ if peer.localRib != nil {
+ peer.localRib.SetPolicy(policyConf, policy)
+ }
}
func (peer *Peer) GetPolicy(d table.PolicyDirection) []*table.Policy {
diff --git a/server/server.go b/server/server.go
index d09d0da1..9f9b70d8 100644
--- a/server/server.go
+++ b/server/server.go
@@ -87,8 +87,7 @@ type BgpServer struct {
GrpcReqCh chan *GrpcRequest
listenPort int
policyUpdateCh chan config.RoutingPolicy
- policyMap map[string]*table.Policy
- routingPolicy config.RoutingPolicy
+ policy *table.RoutingPolicy
broadcastReqs []*GrpcRequest
broadcastMsgs []broadcastMsg
neighborMap map[string]*Peer
@@ -354,7 +353,6 @@ func (server *BgpServer) Serve() {
peer := NewPeer(g, config)
if peer.isRouteServerClient() {
- peer.setPolicy(server.policyMap)
pathList := make([]*table.Path, 0)
rfList := peer.configuredRFlist()
for _, p := range server.neighborMap {
@@ -400,7 +398,7 @@ func (server *BgpServer) Serve() {
peer := server.neighborMap[addr]
if peer.isRouteServerClient() {
peer.conf.ApplyPolicy = config.ApplyPolicy
- peer.setPolicy(server.policyMap)
+ peer.setPolicy(server.policy.PolicyMap)
}
case e := <-incoming:
peer, found := server.neighborMap[e.MsgSrc]
@@ -865,15 +863,19 @@ func (server *BgpServer) UpdatePolicy(policy config.RoutingPolicy) {
server.policyUpdateCh <- policy
}
-func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) {
- pMap := make(map[string]*table.Policy)
- df := pl.DefinedSets
- for _, p := range pl.PolicyDefinitions.PolicyDefinitionList {
- pMap[p.Name] = table.NewPolicy(p, df)
+func (server *BgpServer) SetPolicy(pl config.RoutingPolicy) error {
+ p, err := table.NewRoutingPolicy(pl)
+ if err != nil {
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ }).Debugf("failed to create routing policy: %s", err)
+ return err
}
- server.policyMap = pMap
- server.routingPolicy = pl
- server.globalRib.SetPolicy(server.bgpConfig.Global.ApplyPolicy, server.policyMap)
+ server.policy = p
+ if server.globalRib != nil {
+ server.globalRib.SetPolicy(server.bgpConfig.Global.ApplyPolicy, server.policy.PolicyMap)
+ }
+ return nil
}
func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) {
@@ -883,7 +885,7 @@ func (server *BgpServer) handlePolicy(pl config.RoutingPolicy) {
"Topic": "Peer",
"Key": peer.conf.NeighborConfig.NeighborAddress,
}).Info("call set policy")
- peer.setPolicy(server.policyMap)
+ peer.setPolicy(server.policy.PolicyMap)
}
}
@@ -1555,12 +1557,11 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
case REQ_NEIGHBOR_POLICY:
peer, err := server.checkNeighborRequest(grpcReq)
if err != nil {
- break
+ return msgs
}
applyPolicy = peer.conf.ApplyPolicy
case REQ_GLOBAL_RIB:
applyPolicy = server.bgpConfig.Global.ApplyPolicy
- default:
}
switch arg.ApplyPolicy.Type {
case api.PolicyType_IMPORT:
@@ -1580,21 +1581,16 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
}
policies := make([]*api.PolicyDefinition, 0, len(names))
-
- pdList := server.routingPolicy.PolicyDefinitions.PolicyDefinitionList
- df := server.routingPolicy.DefinedSets
for _, name := range names {
- match := false
- for _, pd := range pdList {
- if name == pd.Name {
- match = true
- policies = append(policies, table.PolicyDefinitionToApiStruct(pd, df))
- break
- }
- }
- if !match {
- policies = append(policies, &api.PolicyDefinition{PolicyDefinitionName: name})
+ p, ok := server.policy.PolicyMap[name]
+ if !ok {
+ log.WithFields(log.Fields{
+ "Topic": "Peer",
+ "Name": name,
+ }).Error("can't find policy which is applied")
+ continue
}
+ policies = append(policies, p.ToApiStruct())
}
result := &GrpcResponse{
@@ -1613,7 +1609,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
}
result := &GrpcResponse{}
arg := grpcReq.Data.(*api.PolicyArguments)
- reqPolicyMap := server.policyMap
applyPolicy := peer.conf.ApplyPolicy.ApplyPolicyConfig
def := config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE
switch arg.Operation {
@@ -1645,15 +1640,14 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
applyPolicy.InPolicy = []string{}
}
}
- peer.setPolicy(reqPolicyMap)
+ peer.setPolicy(server.policy.PolicyMap)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ASPATHS,
- REQ_POLICY_COMMUNITIES, REQ_POLICY_EXTCOMMUNITIES, REQ_POLICY_ROUTEPOLICIES:
- server.handleGrpcShowPolicies(grpcReq)
- case REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH,
+ REQ_POLICY_COMMUNITIES, REQ_POLICY_EXTCOMMUNITIES, REQ_POLICY_ROUTEPOLICIES,
+ REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH,
REQ_POLICY_COMMUNITY, REQ_POLICY_EXTCOMMUNITY, REQ_POLICY_ROUTEPOLICY:
server.handleGrpcShowPolicy(grpcReq)
case REQ_MONITOR_GLOBAL_BEST_CHANGED, REQ_MONITOR_NEIGHBOR_PEER_STATE:
@@ -1678,100 +1672,137 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
return msgs
}
-func (server *BgpServer) handleGrpcShowPolicies(grpcReq *GrpcRequest) {
+func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
result := &GrpcResponse{}
- switch grpcReq.RequestType {
- case REQ_POLICY_PREFIXES:
- info := server.routingPolicy.DefinedSets.PrefixSets.PrefixSetList
+ typ := grpcReq.RequestType
+ arg := grpcReq.Data.(*api.PolicyArguments)
+ switch typ {
+ case REQ_POLICY_PREFIX, REQ_POLICY_PREFIXES:
+ info := server.policy.DefinedSetMap[table.DEFINED_TYPE_PREFIX]
if len(info) > 0 {
for _, ps := range info {
- resPrefixSet := table.PrefixSetToApiStruct(ps)
+ if typ == REQ_POLICY_PREFIX && ps.Name() != arg.Name {
+ continue
+ }
+ resPrefixSet := ps.(*table.PrefixSet).ToApiStruct()
pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchPrefixSet: resPrefixSet}}}
+ pd.Statements = []*api.Statement{{Conditions: &api.Conditions{PrefixSet: resPrefixSet}}}
result = &GrpcResponse{
Data: pd,
}
grpcReq.ResponseCh <- result
+ if typ == REQ_POLICY_PREFIX {
+ break
+ }
}
} else {
result.ResponseErr = fmt.Errorf("Policy prefix doesn't exist.")
grpcReq.ResponseCh <- result
}
- case REQ_POLICY_NEIGHBORS:
- info := server.routingPolicy.DefinedSets.NeighborSets.NeighborSetList
+ case REQ_POLICY_NEIGHBOR, REQ_POLICY_NEIGHBORS:
+ info := server.policy.DefinedSetMap[table.DEFINED_TYPE_NEIGHBOR]
if len(info) > 0 {
for _, ns := range info {
- resNeighborSet := table.NeighborSetToApiStruct(ns)
+ if typ == REQ_POLICY_NEIGHBOR && ns.Name() != arg.Name {
+ continue
+ }
+ resNeighborSet := ns.(*table.NeighborSet).ToApiStruct()
pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchNeighborSet: resNeighborSet}}}
+ pd.Statements = []*api.Statement{{Conditions: &api.Conditions{NeighborSet: resNeighborSet}}}
result = &GrpcResponse{
Data: pd,
}
grpcReq.ResponseCh <- result
+ if typ == REQ_POLICY_NEIGHBOR {
+ break
+ }
}
} else {
result.ResponseErr = fmt.Errorf("Policy neighbor doesn't exist.")
grpcReq.ResponseCh <- result
}
- case REQ_POLICY_ASPATHS:
- info := server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSets.AsPathSetList
+ case REQ_POLICY_ASPATH, REQ_POLICY_ASPATHS:
+ info := server.policy.DefinedSetMap[table.DEFINED_TYPE_AS_PATH]
if len(info) > 0 {
for _, as := range info {
- resAsPathSet := table.AsPathSetToApiStruct(as)
+ if typ == REQ_POLICY_ASPATH && as.Name() != arg.Name {
+ continue
+ }
+ resAsPathSet := as.(*table.AsPathSet).ToApiStruct()
pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchAsPathSet: resAsPathSet}}}
+ pd.Statements = []*api.Statement{{Conditions: &api.Conditions{AsPathSet: resAsPathSet}}}
result = &GrpcResponse{
Data: pd,
}
grpcReq.ResponseCh <- result
+ if typ == REQ_POLICY_ASPATH {
+ break
+ }
}
} else {
result.ResponseErr = fmt.Errorf("Policy aspath doesn't exist.")
grpcReq.ResponseCh <- result
}
- case REQ_POLICY_COMMUNITIES:
- info := server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySets.CommunitySetList
+ case REQ_POLICY_COMMUNITY, REQ_POLICY_COMMUNITIES:
+ info := server.policy.DefinedSetMap[table.DEFINED_TYPE_COMMUNITY]
if len(info) > 0 {
for _, cs := range info {
- resCommunitySet := table.CommunitySetToApiStruct(cs)
+ if typ == REQ_POLICY_COMMUNITY && cs.Name() != arg.Name {
+ continue
+ }
+ resCommunitySet := cs.(*table.CommunitySet).ToApiStruct()
pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchCommunitySet: resCommunitySet}}}
+ pd.Statements = []*api.Statement{{Conditions: &api.Conditions{CommunitySet: resCommunitySet}}}
result = &GrpcResponse{
Data: pd,
}
grpcReq.ResponseCh <- result
+ if typ == REQ_POLICY_COMMUNITY {
+ break
+ }
}
} else {
result.ResponseErr = fmt.Errorf("Policy community doesn't exist.")
grpcReq.ResponseCh <- result
}
- case REQ_POLICY_EXTCOMMUNITIES:
- info := server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySets.ExtCommunitySetList
+ case REQ_POLICY_EXTCOMMUNITY, REQ_POLICY_EXTCOMMUNITIES:
+ info := server.policy.DefinedSetMap[table.DEFINED_TYPE_EXT_COMMUNITY]
if len(info) > 0 {
for _, es := range info {
- resExtcommunitySet := table.ExtCommunitySetToApiStruct(es)
+ if typ == REQ_POLICY_EXTCOMMUNITY && es.Name() != arg.Name {
+ continue
+ }
+ resExtcommunitySet := es.(*table.ExtCommunitySet).ToApiStruct()
pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchExtCommunitySet: resExtcommunitySet}}}
+ pd.Statements = []*api.Statement{{Conditions: &api.Conditions{ExtCommunitySet: resExtcommunitySet}}}
result = &GrpcResponse{
Data: pd,
}
grpcReq.ResponseCh <- result
+ if typ == REQ_POLICY_EXTCOMMUNITY {
+ break
+ }
}
} else {
result.ResponseErr = fmt.Errorf("Policy extended community doesn't exist.")
grpcReq.ResponseCh <- result
}
- case REQ_POLICY_ROUTEPOLICIES:
- info := server.routingPolicy.PolicyDefinitions.PolicyDefinitionList
- df := server.routingPolicy.DefinedSets
+ case REQ_POLICY_ROUTEPOLICY, REQ_POLICY_ROUTEPOLICIES:
+ info := server.policy.PolicyMap
result := &GrpcResponse{}
if len(info) > 0 {
for _, pd := range info {
- resPolicyDefinition := table.PolicyDefinitionToApiStruct(pd, df)
+ if typ == REQ_POLICY_ROUTEPOLICY && pd.Name() != arg.Name {
+ continue
+ }
+ resPolicyDefinition := pd.ToApiStruct()
result = &GrpcResponse{
Data: resPolicyDefinition,
}
grpcReq.ResponseCh <- result
+ if typ == REQ_POLICY_ROUTEPOLICY {
+ break
+ }
}
} else {
result.ResponseErr = fmt.Errorf("Route Policy doesn't exist.")
@@ -1780,121 +1811,6 @@ func (server *BgpServer) handleGrpcShowPolicies(grpcReq *GrpcRequest) {
}
close(grpcReq.ResponseCh)
}
-func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
- name := grpcReq.Data.(string)
- result := &GrpcResponse{}
- switch grpcReq.RequestType {
- case REQ_POLICY_PREFIX:
- info := server.routingPolicy.DefinedSets.PrefixSets.PrefixSetList
- resPrefixSet := &api.PrefixSet{}
- for _, ps := range info {
- if ps.PrefixSetName == name {
- resPrefixSet = table.PrefixSetToApiStruct(ps)
- break
- }
- }
- if len(resPrefixSet.PrefixList) > 0 {
- pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchPrefixSet: resPrefixSet}}}
- result = &GrpcResponse{
- Data: pd,
- }
- } else {
- result.ResponseErr = fmt.Errorf("policy prefix that has %v doesn't exist.", name)
- }
- case REQ_POLICY_NEIGHBOR:
- info := server.routingPolicy.DefinedSets.NeighborSets.NeighborSetList
- resNeighborSet := &api.NeighborSet{}
- for _, ns := range info {
- if ns.NeighborSetName == name {
- resNeighborSet = table.NeighborSetToApiStruct(ns)
- break
- }
- }
- if len(resNeighborSet.NeighborList) > 0 {
- pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchNeighborSet: resNeighborSet}}}
- result = &GrpcResponse{
- Data: pd,
- }
- } else {
- result.ResponseErr = fmt.Errorf("policy neighbor that has %v doesn't exist.", name)
- }
- case REQ_POLICY_ASPATH:
- info := server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSets.AsPathSetList
- resAsPathSet := &api.AsPathSet{}
- for _, as := range info {
- if as.AsPathSetName == name {
- resAsPathSet = table.AsPathSetToApiStruct(as)
- break
- }
- }
- if len(resAsPathSet.AsPathMembers) > 0 {
- pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchAsPathSet: resAsPathSet}}}
- result = &GrpcResponse{
- Data: pd,
- }
- } else {
- result.ResponseErr = fmt.Errorf("policy aspath that has %v doesn't exist.", name)
- }
- case REQ_POLICY_COMMUNITY:
- info := server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySets.CommunitySetList
- resCommunitySet := &api.CommunitySet{}
- for _, cs := range info {
- if cs.CommunitySetName == name {
- resCommunitySet = table.CommunitySetToApiStruct(cs)
- break
- }
- }
- if len(resCommunitySet.CommunityMembers) > 0 {
- pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchCommunitySet: resCommunitySet}}}
- result = &GrpcResponse{
- Data: pd,
- }
- } else {
- result.ResponseErr = fmt.Errorf("policy community that has %v doesn't exist.", name)
- }
- case REQ_POLICY_EXTCOMMUNITY:
- info := server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySets.ExtCommunitySetList
- resExtCommunitySet := &api.ExtCommunitySet{}
- for _, es := range info {
- if es.ExtCommunitySetName == name {
- resExtCommunitySet = table.ExtCommunitySetToApiStruct(es)
- break
- }
- }
- if len(resExtCommunitySet.ExtCommunityMembers) > 0 {
- pd := &api.PolicyDefinition{}
- pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchExtCommunitySet: resExtCommunitySet}}}
- result = &GrpcResponse{
- Data: pd,
- }
- } else {
- result.ResponseErr = fmt.Errorf("policy extended community that has %v doesn't exist.", name)
- }
- case REQ_POLICY_ROUTEPOLICY:
- info := server.routingPolicy.PolicyDefinitions.PolicyDefinitionList
- df := server.routingPolicy.DefinedSets
- resPolicyDefinition := &api.PolicyDefinition{}
- for _, pd := range info {
- if pd.Name == name {
- resPolicyDefinition = table.PolicyDefinitionToApiStruct(pd, df)
- break
- }
- }
- if len(resPolicyDefinition.StatementList) > 0 {
- result = &GrpcResponse{
- Data: resPolicyDefinition,
- }
- } else {
- result.ResponseErr = fmt.Errorf("Route Policy that has %v doesn't exist.", name)
- }
- }
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
-}
func (server *BgpServer) handleMrt(grpcReq *GrpcRequest) {
now := uint32(time.Now().Unix())
diff --git a/table/path.go b/table/path.go
index b45b7f68..bcf5b4ce 100644
--- a/table/path.go
+++ b/table/path.go
@@ -556,16 +556,7 @@ 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:]
- }
+func (path *Path) SetExtCommunities(exts []bgp.ExtendedCommunityInterface, doReplace bool) {
idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES)
if attr != nil {
l := attr.(*bgp.PathAttributeExtendedCommunities).Value
diff --git a/table/policy.go b/table/policy.go
index bec56e07..6d33a35f 100644
--- a/table/policy.go
+++ b/table/policy.go
@@ -24,11 +24,22 @@ import (
"strings"
log "github.com/Sirupsen/logrus"
- "github.com/osrg/gobgp/api"
+ api "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet"
)
+type DefinedType int
+
+const (
+ DEFINED_TYPE_PREFIX DefinedType = iota
+ DEFINED_TYPE_NEIGHBOR
+ DEFINED_TYPE_TAG
+ DEFINED_TYPE_AS_PATH
+ DEFINED_TYPE_COMMUNITY
+ DEFINED_TYPE_EXT_COMMUNITY
+)
+
type RouteType int
const (
@@ -37,38 +48,76 @@ const (
ROUTE_TYPE_REJECT
)
-func (t RouteType) String() string {
- switch t {
- case ROUTE_TYPE_NONE:
- return "NONE"
- case ROUTE_TYPE_ACCEPT:
- return "ACCEPT"
- case ROUTE_TYPE_REJECT:
- return "REJECT"
- default:
- return fmt.Sprintf("Unknown(%d)", t)
- }
-}
+type PolicyDirection int
+
+const (
+ POLICY_DIRECTION_IMPORT PolicyDirection = iota
+ POLICY_DIRECTION_EXPORT
+ POLICY_DIRECTION_IN
+)
-func (t RouteType) ToApiStruct() gobgpapi.RouteAction {
- switch t {
- case ROUTE_TYPE_ACCEPT:
- return gobgpapi.RouteAction_ACCEPT
- case ROUTE_TYPE_REJECT:
- return gobgpapi.RouteAction_REJECT
+type MatchOption int
+
+const (
+ MATCH_OPTION_ANY MatchOption = iota
+ MATCH_OPTION_ALL
+ MATCH_OPTION_INVERT
+)
+
+func (o MatchOption) String() string {
+ switch o {
+ case MATCH_OPTION_ANY:
+ return "any"
+ case MATCH_OPTION_ALL:
+ return "all"
+ case MATCH_OPTION_INVERT:
+ return "invert"
default:
- return gobgpapi.RouteAction_NONE
+ return fmt.Sprintf("MatchOption(%d)", o)
}
}
-type PolicyDirection int
+type MedActionType int
const (
- POLICY_DIRECTION_IN = iota
- POLICY_DIRECTION_IMPORT = iota
- POLICY_DIRECTION_EXPORT
+ MED_ACTION_MOD MedActionType = iota
+ MED_ACTION_REPLACE
)
+var CommunityOptionNameMap = map[config.BgpSetCommunityOptionType]string{
+ config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD: "add",
+ config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE: "remove",
+ config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE: "replace",
+}
+
+var CommunityOptionValueMap = map[string]config.BgpSetCommunityOptionType{
+ CommunityOptionNameMap[config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD]: config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD,
+ CommunityOptionNameMap[config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE]: config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE,
+ CommunityOptionNameMap[config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE]: config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE,
+}
+
+func NewMatchOption(c interface{}) (MatchOption, error) {
+ switch c.(type) {
+ case config.MatchSetOptionsType:
+ switch c.(config.MatchSetOptionsType) {
+ case config.MATCH_SET_OPTIONS_TYPE_ANY:
+ return MATCH_OPTION_ANY, nil
+ case config.MATCH_SET_OPTIONS_TYPE_ALL:
+ return MATCH_OPTION_ALL, nil
+ case config.MATCH_SET_OPTIONS_TYPE_INVERT:
+ return MATCH_OPTION_INVERT, nil
+ }
+ case config.MatchSetOptionsRestrictedType:
+ switch c.(config.MatchSetOptionsRestrictedType) {
+ case config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY:
+ return MATCH_OPTION_ANY, nil
+ case config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT:
+ return MATCH_OPTION_INVERT, nil
+ }
+ }
+ return MATCH_OPTION_ANY, fmt.Errorf("invalid argument to create match option: %v", c)
+}
+
type AttributeComparison int
const (
@@ -80,196 +129,411 @@ const (
ATTRIBUTE_LE
)
-type Policy struct {
- Name string
- Statements []*Statement
+const (
+ ASPATH_REGEXP_MAGIC = "(^|[,{}() ]|$)"
+)
+
+type DefinedSet interface {
+ Type() DefinedType
+ Name() string
+}
+
+type DefinedSetMap map[DefinedType]map[string]DefinedSet
+
+type Prefix struct {
+ Prefix *net.IPNet
+ AddressFamily bgp.RouteFamily
+ MasklengthRangeMax uint8
+ MasklengthRangeMin uint8
}
-func NewPolicy(pd config.PolicyDefinition, ds config.DefinedSets) *Policy {
- stmtList := pd.Statements.StatementList
- st := make([]*Statement, 0)
- p := &Policy{
- Name: pd.Name,
+func (p *Prefix) Match(path *Path) bool {
+ rf := path.GetRouteFamily()
+ if rf != p.AddressFamily {
+ return false
}
- for _, statement := range stmtList {
- conditions := make([]Condition, 0)
+ var pAddr net.IP
+ var pMasklen uint8
+ switch rf {
+ case bgp.RF_IPv4_UC:
+ pAddr = path.GetNlri().(*bgp.IPAddrPrefix).Prefix
+ pMasklen = path.GetNlri().(*bgp.IPAddrPrefix).Length
+ case bgp.RF_IPv6_UC:
+ pAddr = path.GetNlri().(*bgp.IPv6AddrPrefix).Prefix
+ pMasklen = path.GetNlri().(*bgp.IPv6AddrPrefix).Length
+ default:
+ return false
+ }
- // prefix match
- pc := NewPrefixCondition(statement.Conditions.MatchPrefixSet, ds.PrefixSets.PrefixSetList)
- if pc != nil {
- conditions = append(conditions, pc)
- }
+ return (p.MasklengthRangeMin <= pMasklen && pMasklen <= p.MasklengthRangeMax) && p.Prefix.Contains(pAddr)
+}
- // neighbor match
- nc := NewNeighborCondition(statement.Conditions.MatchNeighborSet, ds.NeighborSets.NeighborSetList)
- if nc != nil {
- conditions = append(conditions, nc)
- }
+func (p *Prefix) ToApiStruct() *api.Prefix {
+ return &api.Prefix{
+ IpPrefix: p.Prefix.String(),
+ MaskLengthRange: fmt.Sprintf("%d..%d", p.MasklengthRangeMin, p.MasklengthRangeMax),
+ }
+}
- // AsPathLengthCondition
- c := statement.Conditions.BgpConditions.AsPathLength
- ac := NewAsPathLengthCondition(c)
- if ac != nil {
- conditions = append(conditions, ac)
- }
+func NewPrefix(c config.Prefix) (*Prefix, error) {
+ addr, prefix, err := net.ParseCIDR(c.IpPrefix)
+ if err != nil {
+ return nil, err
+ }
- if statement.Conditions.BgpConditions.RpkiValidationResult != config.RPKI_VALIDATION_RESULT_TYPE_NONE {
- conditions = append(conditions, NewRPKIValidationCondition(statement.Conditions.BgpConditions.RpkiValidationResult))
+ rf := bgp.RF_IPv4_UC
+ if addr.To4() == nil {
+ rf = bgp.RF_IPv6_UC
+ }
+ p := &Prefix{
+ Prefix: prefix,
+ AddressFamily: rf,
+ }
+ maskRange := c.MasklengthRange
+ if maskRange == "" {
+ l, _ := prefix.Mask.Size()
+ maskLength := uint8(l)
+ p.MasklengthRangeMax = maskLength
+ p.MasklengthRangeMin = maskLength
+ } else {
+ exp := regexp.MustCompile("(\\d+)\\.\\.(\\d+)")
+ elems := exp.FindStringSubmatch(maskRange)
+ if len(elems) != 3 {
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Type": "Prefix",
+ "MaskRangeFormat": maskRange,
+ }).Warn("mask length range format is invalid.")
+ return nil, fmt.Errorf("mask length range format is invalid")
}
+ // we've already checked the range is sane by regexp
+ min, _ := strconv.Atoi(elems[1])
+ max, _ := strconv.Atoi(elems[2])
+ p.MasklengthRangeMin = uint8(min)
+ p.MasklengthRangeMax = uint8(max)
+ }
+ return p, nil
+}
- bgpDefset := &ds.BgpDefinedSets
- bgpConditions := &statement.Conditions.BgpConditions
- // AsPathCondition
- asc := NewAsPathCondition(bgpConditions.MatchAsPathSet, bgpDefset.AsPathSets.AsPathSetList)
- if asc != nil {
- conditions = append(conditions, asc)
- }
+type PrefixSet struct {
+ name string
+ list []*Prefix
+}
- // CommunityCondition
- cc := NewCommunityCondition(bgpConditions.MatchCommunitySet, bgpDefset.CommunitySets.CommunitySetList)
- if cc != nil {
- conditions = append(conditions, cc)
- }
+func (s *PrefixSet) Name() string {
+ return s.name
+}
- // ExtendedCommunityCondition
- ecc := NewExtCommunityCondition(bgpConditions.MatchExtCommunitySet, bgpDefset.ExtCommunitySets.ExtCommunitySetList)
- if ecc != nil {
- conditions = append(conditions, ecc)
- }
+func (s *PrefixSet) Type() DefinedType {
+ return DEFINED_TYPE_PREFIX
+}
- // routing action
- ra := NewRoutingAction(statement.Actions)
+func (s *PrefixSet) ToApiStruct() *api.PrefixSet {
+ list := make([]*api.Prefix, 0, len(s.list))
+ for _, p := range s.list {
+ list = append(list, p.ToApiStruct())
+ }
+ return &api.PrefixSet{
+ Name: s.name,
+ List: list,
+ }
+}
- // Community action
- mda := make([]Action, 0)
- com := NewCommunityAction(statement.Actions.BgpActions.SetCommunity)
- if com != nil {
- mda = append(mda, com)
+func NewPrefixSet(c config.PrefixSet) (*PrefixSet, error) {
+ name := c.PrefixSetName
+ if name == "" {
+ if len(c.PrefixList) == 0 {
+ return nil, nil
}
-
- ext := NewExtCommunityAction(statement.Actions.BgpActions.SetExtCommunity)
- if ext != nil {
- mda = append(mda, ext)
+ return nil, fmt.Errorf("empty prefix set name")
+ }
+ list := make([]*Prefix, 0, len(c.PrefixList))
+ for _, x := range c.PrefixList {
+ y, err := NewPrefix(x)
+ if err != nil {
+ return nil, err
}
+ list = append(list, y)
+ }
+ return &PrefixSet{
+ name: name,
+ list: list,
+ }, nil
+}
- // Med Action
- med := NewMedAction(statement.Actions.BgpActions.SetMed)
- if med != nil {
- mda = append(mda, med)
- }
+type NeighborSet struct {
+ name string
+ list []net.IP
+}
- //AsPathPrependAction
- ppa := NewAsPathPrependAction(statement.Actions.BgpActions.SetAsPathPrepend)
- if ppa != nil {
- mda = append(mda, ppa)
- }
+func (s *NeighborSet) Name() string {
+ return s.name
+}
+
+func (s *NeighborSet) Type() DefinedType {
+ return DEFINED_TYPE_NEIGHBOR
+}
+
+func (s *NeighborSet) ToApiStruct() *api.MatchSet {
+ list := make([]string, 0, len(s.list))
+ for _, n := range s.list {
+ list = append(list, n.String())
+ }
+ return &api.MatchSet{
+ Name: s.name,
+ List: list,
+ }
+}
- s := &Statement{
- Name: statement.Name,
- Conditions: conditions,
- routingAction: ra,
- modificationActions: mda,
+func NewNeighborSet(c config.NeighborSet) (*NeighborSet, error) {
+ name := c.NeighborSetName
+ if name == "" {
+ if len(c.NeighborInfoList) == 0 {
+ return nil, nil
}
+ return nil, fmt.Errorf("empty neighbor set name")
+ }
+ list := make([]net.IP, 0, len(c.NeighborInfoList))
+ for _, x := range c.NeighborInfoList {
+ list = append(list, x.Address)
+ }
+ return &NeighborSet{
+ name: name,
+ list: list,
+ }, nil
+}
- st = append(st, s)
+type regExpSet struct {
+ name string
+ list []*regexp.Regexp
+}
+
+func (s *regExpSet) Name() string {
+ return s.name
+}
+
+func (s *regExpSet) ToApiStruct() *api.MatchSet {
+ list := make([]string, 0, len(s.list))
+ for _, exp := range s.list {
+ list = append(list, exp.String())
+ }
+ return &api.MatchSet{
+ Name: s.name,
+ List: list,
}
- p.Statements = st
- return p
}
-type Statement struct {
- Name string
- Conditions []Condition
- routingAction *RoutingAction
- modificationActions []Action
+type AsPathSet struct {
+ regExpSet
}
-// evaluate each condition in the statement according to MatchSetOptions
-func (s *Statement) evaluate(p *Path) bool {
+func (s *AsPathSet) Type() DefinedType {
+ return DEFINED_TYPE_AS_PATH
+}
- for _, condition := range s.Conditions {
- r := condition.evaluate(p)
- if !r {
- return false
+func NewAsPathSet(c config.AsPathSet) (*AsPathSet, error) {
+ name := c.AsPathSetName
+ if name == "" {
+ if len(c.AsPathList) == 0 {
+ return nil, nil
}
+ return nil, fmt.Errorf("empty as-path set name")
}
- return true
+ list := make([]*regexp.Regexp, 0, len(c.AsPathList))
+ for _, x := range c.AsPathList {
+ exp, err := regexp.Compile(strings.Replace(x.AsPath, "_", ASPATH_REGEXP_MAGIC, -1))
+ if err != nil {
+ return nil, fmt.Errorf("invalid regular expression: %s", x)
+ }
+ list = append(list, exp)
+ }
+ return &AsPathSet{
+ regExpSet: regExpSet{
+ name: name,
+ list: list,
+ },
+ }, nil
}
-type Condition interface {
- evaluate(*Path) bool
+type CommunitySet struct {
+ regExpSet
+}
+
+func (s *CommunitySet) Type() DefinedType {
+ return DEFINED_TYPE_COMMUNITY
}
-type DefaultCondition struct {
- CallPolicy string
+func ParseCommunity(arg string) (uint32, error) {
+ i, err := strconv.Atoi(arg)
+ if err == nil {
+ return uint32(i), nil
+ }
+ exp := regexp.MustCompile("(\\d+):(\\d+)")
+ elems := exp.FindStringSubmatch(arg)
+ if len(elems) == 3 {
+ fst, _ := strconv.Atoi(elems[1])
+ snd, _ := strconv.Atoi(elems[2])
+ return uint32(fst<<16 | snd), nil
+ }
+ for i, v := range bgp.WellKnownCommunityNameMap {
+ if arg == v {
+ return uint32(i), nil
+ }
+ }
+ return 0, fmt.Errorf("failed to parse %s as community", arg)
}
-func (c *DefaultCondition) evaluate(path *Path) bool {
- return false
+func parseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) {
+ var subtype bgp.ExtendedCommunityAttrSubType
+ elems := strings.SplitN(arg, ":", 2)
+ if len(elems) < 2 {
+ return nil, fmt.Errorf("invalid ext-community format([rt|soo]:<value>)")
+ }
+ switch strings.ToLower(elems[0]) {
+ case "rt":
+ subtype = bgp.EC_SUBTYPE_ROUTE_TARGET
+ case "soo":
+ subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN
+ default:
+ return nil, fmt.Errorf("unknown ext-community subtype. rt, soo is supported")
+ }
+ return bgp.ParseExtendedCommunity(subtype, elems[1])
}
-type PrefixCondition struct {
- DefaultCondition
- PrefixConditionName string
- PrefixList []Prefix
- MatchOption config.MatchSetOptionsRestrictedType
-}
-
-func NewPrefixCondition(matchPref config.MatchPrefixSet, defPrefixList []config.PrefixSet) *PrefixCondition {
-
- prefixSetName := matchPref.PrefixSet
- options := matchPref.MatchSetOptions
-
- prefixList := make([]Prefix, 0)
- for _, ps := range defPrefixList {
- if ps.PrefixSetName == prefixSetName {
- for _, prefix := range ps.PrefixList {
- prefix, e := NewPrefix(prefix.IpPrefix, prefix.MasklengthRange)
- if e != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "prefix": prefix,
- "msg": e,
- }).Error("failed to generate a NewPrefix from configration.")
- } else {
- prefixList = append(prefixList, prefix)
- }
- }
+func parseCommunityRegexp(arg string) (*regexp.Regexp, error) {
+ i, err := strconv.Atoi(arg)
+ if err == nil {
+ return regexp.MustCompile(fmt.Sprintf("^%d:%d$", i>>16, i&0x0000ffff)), nil
+ }
+ if regexp.MustCompile("(\\d+.)*\\d+:\\d+").MatchString(arg) {
+ return regexp.MustCompile(fmt.Sprintf("^%s$", arg)), nil
+ }
+ for i, v := range bgp.WellKnownCommunityNameMap {
+ if strings.Replace(strings.ToLower(arg), "_", "-", -1) == v {
+ return regexp.MustCompile(fmt.Sprintf("^%d:%d$", i>>16, i&0x0000ffff)), nil
}
}
+ exp, err := regexp.Compile(arg)
+ if err != nil {
+ return nil, fmt.Errorf("invalid community format: %s", arg)
+ }
+ return exp, nil
+}
+
+func parseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *regexp.Regexp, error) {
+ var subtype bgp.ExtendedCommunityAttrSubType
+ elems := strings.SplitN(arg, ":", 2)
+ if len(elems) < 2 {
+ return subtype, nil, fmt.Errorf("invalid ext-community format([rt|soo]:<value>)")
+ }
+ switch strings.ToLower(elems[0]) {
+ case "rt":
+ subtype = bgp.EC_SUBTYPE_ROUTE_TARGET
+ case "soo":
+ subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN
+ default:
+ return subtype, nil, fmt.Errorf("unknown ext-community subtype. rt, soo is supported")
+ }
+ exp, err := parseCommunityRegexp(elems[1])
+ return subtype, exp, err
+}
- if len(prefixList) == 0 {
- return nil
+func NewCommunitySet(c config.CommunitySet) (*CommunitySet, error) {
+ name := c.CommunitySetName
+ if name == "" {
+ if len(c.CommunityList) == 0 {
+ return nil, nil
+ }
+ return nil, fmt.Errorf("empty community set name")
}
+ list := make([]*regexp.Regexp, 0, len(c.CommunityList))
+ for _, x := range c.CommunityList {
+ exp, err := parseCommunityRegexp(x.Community)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, exp)
+ }
+ return &CommunitySet{
+ regExpSet: regExpSet{
+ name: name,
+ list: list,
+ },
+ }, nil
+}
+
+type ExtCommunitySet struct {
+ regExpSet
+ subtypeList []bgp.ExtendedCommunityAttrSubType
+}
- pc := &PrefixCondition{
- PrefixConditionName: prefixSetName,
- PrefixList: prefixList,
- MatchOption: options,
+func (s *ExtCommunitySet) Type() DefinedType {
+ return DEFINED_TYPE_EXT_COMMUNITY
+}
+
+func NewExtCommunitySet(c config.ExtCommunitySet) (*ExtCommunitySet, error) {
+ name := c.ExtCommunitySetName
+ if name == "" {
+ if len(c.ExtCommunityList) == 0 {
+ return nil, nil
+ }
+ return nil, fmt.Errorf("empty ext-community set name")
+ }
+ list := make([]*regexp.Regexp, 0, len(c.ExtCommunityList))
+ subtypeList := make([]bgp.ExtendedCommunityAttrSubType, 0, len(c.ExtCommunityList))
+ for _, x := range c.ExtCommunityList {
+ subtype, exp, err := parseExtCommunityRegexp(x.ExtCommunity)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, exp)
+ subtypeList = append(subtypeList, subtype)
}
+ return &ExtCommunitySet{
+ regExpSet: regExpSet{
+ name: name,
+ list: list,
+ },
+ subtypeList: subtypeList,
+ }, nil
+}
+
+type Condition interface {
+ Evaluate(*Path) bool
+}
+
+type PrefixCondition struct {
+ set *PrefixSet
+ option MatchOption
+}
+
+func (c *PrefixCondition) Set() DefinedSet {
+ return c.set
+}
- return pc
+func (c *PrefixCondition) Option() MatchOption {
+ return c.option
}
// 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 *PrefixCondition) evaluate(path *Path) bool {
+func (c *PrefixCondition) Evaluate(path *Path) bool {
- if len(c.PrefixList) == 0 {
+ if len(c.set.list) == 0 {
log.Debug("PrefixList doesn't have elements")
return true
}
result := false
- for _, cp := range c.PrefixList {
- if ipPrefixCalculate(path, cp) {
+ for _, p := range c.set.list {
+ if p.Match(path) {
result = true
break
}
}
- if c.MatchOption == config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT {
+ if c.option == MATCH_OPTION_INVERT {
result = !result
}
@@ -278,51 +542,58 @@ func (c *PrefixCondition) evaluate(path *Path) bool {
"Condition": "prefix",
"Path": path,
"Matched": result,
- }).Debug("evaluate prefix")
+ }).Debug("evaluation result")
return result
}
-type NeighborCondition struct {
- DefaultCondition
- NeighborConditionName string
- NeighborList []net.IP
- MatchOption config.MatchSetOptionsRestrictedType
+func (c *PrefixCondition) ToApiStruct() *api.PrefixSet {
+ s := c.set.ToApiStruct()
+ s.Option = int32(c.option)
+ return s
}
-func NewNeighborCondition(matchNeighborSet config.MatchNeighborSet, defNeighborSetList []config.NeighborSet) *NeighborCondition {
-
- neighborSetName := matchNeighborSet.NeighborSet
- options := matchNeighborSet.MatchSetOptions
-
- neighborList := make([]net.IP, 0)
- for _, neighborSet := range defNeighborSetList {
- if neighborSet.NeighborSetName == neighborSetName {
- for _, nl := range neighborSet.NeighborInfoList {
- neighborList = append(neighborList, nl.Address)
- }
- }
+func NewPrefixCondition(c config.MatchPrefixSet, m map[string]DefinedSet) (*PrefixCondition, error) {
+ if c.PrefixSet == "" {
+ return nil, nil
}
-
- if len(neighborList) == 0 {
- return nil
+ i, ok := m[c.PrefixSet]
+ if !ok {
+ return nil, fmt.Errorf("not found prefix set %s", c.PrefixSet)
}
-
- nc := &NeighborCondition{
- NeighborConditionName: neighborSetName,
- NeighborList: neighborList,
- MatchOption: options,
+ 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,
+ option: o,
+ }, nil
+}
+
+type NeighborCondition struct {
+ set *NeighborSet
+ option MatchOption
+}
+
+func (c *NeighborCondition) Set() DefinedSet {
+ return c.set
+}
- return nc
+func (c *NeighborCondition) Option() MatchOption {
+ return c.option
}
// 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 *NeighborCondition) evaluate(path *Path) bool {
+func (c *NeighborCondition) Evaluate(path *Path) bool {
- if len(c.NeighborList) == 0 {
+ if len(c.set.list) == 0 {
log.Debug("NeighborList doesn't have elements")
return true
}
@@ -331,14 +602,14 @@ func (c *NeighborCondition) evaluate(path *Path) bool {
return false
}
result := false
- for _, neighbor := range c.NeighborList {
- if path.Owner.Equal(neighbor) {
+ for _, n := range c.set.list {
+ if path.Owner.Equal(n) {
result = true
break
}
}
- if c.MatchOption == config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT {
+ if c.option == MATCH_OPTION_INVERT {
result = !result
}
@@ -347,774 +618,370 @@ func (c *NeighborCondition) evaluate(path *Path) bool {
"Condition": "neighbor",
"NeighborAddress": path.Owner,
"Matched": result,
- }).Debug("evaluate neighbor")
+ }).Debug("evaluation result")
return result
}
-type AsPathLengthCondition struct {
- DefaultCondition
- Value uint32
- Operator AttributeComparison
+func (c *NeighborCondition) ToApiStruct() *api.MatchSet {
+ s := c.set.ToApiStruct()
+ s.Option = int32(c.option)
+ return s
}
-// create AsPathLengthCondition object
-func NewAsPathLengthCondition(defAsPathLength config.AsPathLength) *AsPathLengthCondition {
-
- value := defAsPathLength.Value
- var op AttributeComparison
-
- switch defAsPathLength.Operator {
- case "eq":
- op = ATTRIBUTE_EQ
-
- case "ge":
- op = ATTRIBUTE_GE
-
- case "le":
- op = ATTRIBUTE_LE
- default:
- return nil
+func NewNeighborCondition(c config.MatchNeighborSet, m map[string]DefinedSet) (*NeighborCondition, error) {
+ if c.NeighborSet == "" {
+ return nil, nil
}
-
- ac := &AsPathLengthCondition{
- Value: value,
- Operator: op,
+ i, ok := m[c.NeighborSet]
+ if !ok {
+ return nil, fmt.Errorf("not found neighbor set %s", c.NeighborSet)
}
-
- return ac
-}
-
-// compare AS_PATH length in the message's AS_PATH attribute with
-// the one in condition.
-func (c *AsPathLengthCondition) evaluate(path *Path) bool {
-
- length := uint32(path.GetAsPathLen())
- result := false
-
- switch c.Operator {
- case ATTRIBUTE_EQ:
- result = c.Value == length
-
- case ATTRIBUTE_GE:
- result = c.Value <= length
-
- case ATTRIBUTE_LE:
- result = c.Value >= length
- default:
- result = false
+ s, ok := i.(*NeighborSet)
+ if !ok {
+ return nil, fmt.Errorf("type assert from DefinedSet to *NeighborSet failed")
}
-
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Condition": "aspath length",
- "Reason": c.Operator,
- "Matched": result,
- }).Debug("evaluate aspath length")
-
- return result
+ o, err := NewMatchOption(c.MatchSetOptions)
+ if err != nil {
+ return nil, err
+ }
+ return &NeighborCondition{
+ set: s,
+ option: o,
+ }, nil
}
type AsPathCondition struct {
- DefaultCondition
- AsRegExpList []*regexp.Regexp
- MatchOption config.MatchSetOptionsType
+ set *AsPathSet
+ option MatchOption
}
-const (
- ASPATH_REGEXP_MAGIC = "(^|[,{}() ]|$)"
-)
-
-func NewAsPathCondition(matchSet config.MatchAsPathSet, defAsPathSetList []config.AsPathSet) *AsPathCondition {
- asPathSetName := matchSet.AsPathSet
- options := matchSet.MatchSetOptions
-
- 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 {
- 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
- }
-
- 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{
- AsRegExpList: asRegExpList,
- MatchOption: options,
- }
- return c
- }
- }
- return nil
+func (c *AsPathCondition) Set() *AsPathSet {
+ return c.set
}
-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",
- "AS": aspathStr,
- "ASN": r,
- }).Debug("aspath condition matched")
-
- if !checkAll {
- return true
- }
- } else {
- if checkAll {
- return false
- }
- }
- }
- return checkAll
+func (c *AsPathCondition) Option() MatchOption {
+ return c.option
}
-// compare AS_PATH in the message's AS_PATH attribute with
-// the one in condition.
-func (c *AsPathCondition) evaluate(path *Path) bool {
-
- aspathStr := path.GetAsString()
+func (c *AsPathCondition) ToApiStruct() *api.MatchSet {
+ s := c.set.ToApiStruct()
+ s.Option = int32(c.option)
+ return s
+}
+func (c *AsPathCondition) Evaluate(path *Path) bool {
+ aspath := path.GetAsString()
result := false
- if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ALL {
- result = c.checkMembers(aspathStr, true)
- } else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ANY {
- result = c.checkMembers(aspathStr, false)
- } else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_INVERT {
- result = !c.checkMembers(aspathStr, false)
+ for _, r := range c.set.list {
+ result = false
+ if r.MatchString(aspath) {
+ result = true
+ }
+ if c.option == MATCH_OPTION_ALL && !result {
+ break
+ }
+ if c.option == MATCH_OPTION_ANY && result {
+ break
+ }
+ }
+ if c.option == MATCH_OPTION_INVERT {
+ result = !result
}
-
log.WithFields(log.Fields{
"Topic": "Policy",
"Condition": "aspath",
- "MatchOption": c.MatchOption,
+ "MatchOption": c.option,
"Matched": result,
- }).Debug("evaluate aspath")
-
+ }).Debug("evaluation result")
return result
}
-type CommunityCondition struct {
- DefaultCondition
- CommunityList []*CommunityElement
- MatchOption config.MatchSetOptionsType
+func NewAsPathCondition(c config.MatchAsPathSet, m map[string]DefinedSet) (*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,
+ option: o,
+ }, nil
}
-const (
- COMMUNITY_INTERNET string = "INTERNET"
- COMMUNITY_NO_EXPORT string = "NO_EXPORT"
- COMMUNITY_NO_ADVERTISE string = "NO_ADVERTISE"
- COMMUNITY_NO_EXPORT_SUBCONFED string = "NO_EXPORT_SUBCONFED"
-)
+type CommunityCondition struct {
+ set *CommunitySet
+ option MatchOption
+}
-const (
- COMMUNITY_INTERNET_VAL uint32 = 0x00000000
- COMMUNITY_NO_EXPORT_VAL = 0xFFFFFF01
- COMMUNITY_NO_ADVERTISE_VAL = 0xFFFFFF02
- COMMUNITY_NO_EXPORT_SUBCONFED_VAL = 0xFFFFFF03
-)
+func (c *CommunityCondition) Set() *CommunitySet {
+ return c.set
+}
-type CommunityElement struct {
- community uint32
- communityStr string
- isRegExp bool
- communityRegExp *regexp.Regexp
-}
-
-// create CommunityCondition object
-// CommunityCondition supports uint and string like 65000:100
-// and also supports regular expressions that are available in golang.
-// if GoBGP can't parse the regular expression, it return nil and an error message is logged.
-func NewCommunityCondition(matchSet config.MatchCommunitySet, defCommunitySetList []config.CommunitySet) *CommunityCondition {
-
- communitySetName := matchSet.CommunitySet
- options := matchSet.MatchSetOptions
-
- communityList := make([]*CommunityElement, 0)
- for _, communitySet := range defCommunitySetList {
- if communitySet.CommunitySetName == communitySetName {
- for _, community := range communitySet.CommunityList {
- c := community.Community
- e := &CommunityElement{
- isRegExp: false,
- communityStr: c,
- }
-
- if matched, v := getCommunityValue(c); matched {
- e.community = v
- } else {
- // specified by regular expression
- e.isRegExp = true
- reg, err := regexp.Compile(c)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Community Condition",
- }).Error("Regular expression can't be compiled.")
- return nil
- }
- e.communityRegExp = reg
- }
- communityList = append(communityList, e)
- }
+func (c *CommunityCondition) Option() MatchOption {
+ return c.option
+}
- c := &CommunityCondition{
- CommunityList: communityList,
- MatchOption: options,
- }
- return c
- }
- }
- return nil
+func (c *CommunityCondition) ToApiStruct() *api.MatchSet {
+ s := c.set.ToApiStruct()
+ s.Option = int32(c.option)
+ return s
}
-// getCommunityValue returns uint32 community value converted from the string.
-// if the string doesn't match a number or string like "65000:1000" or well known
-// community name, it returns false and 0, otherwise returns true and its uint32 value.
-func getCommunityValue(comStr string) (bool, uint32) {
- // community regexp
- regUint, _ := regexp.Compile("^([0-9]+)$")
- regString, _ := regexp.Compile("([0-9]+):([0-9]+)")
- regWellKnown, _ := regexp.Compile("^(" +
- COMMUNITY_INTERNET + "|" +
- COMMUNITY_NO_EXPORT + "|" +
- COMMUNITY_NO_ADVERTISE + "|" +
- COMMUNITY_NO_EXPORT_SUBCONFED + ")$")
-
- if regUint.MatchString(comStr) {
- // specified by Uint
- community, err := strconv.ParseUint(comStr, 10, 32)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Community Condition",
- }).Error("failed to parse the community value.")
+func (c *CommunityCondition) Evaluate(path *Path) bool {
+ cs := path.GetCommunities()
+ result := false
+ for _, x := range cs {
+ result = false
+ for _, y := range c.set.list {
+ if y.MatchString(fmt.Sprintf("%d:%d", x>>16, x&0x0000ffff)) {
+ result = true
+ break
+ }
}
- return true, uint32(community)
-
- } else if regString.MatchString(comStr) {
- // specified by string containing ":"
- group := regString.FindStringSubmatch(comStr)
- asn, errAsn := strconv.ParseUint(group[1], 10, 16)
- val, errVal := strconv.ParseUint(group[2], 10, 16)
-
- if errAsn != nil || errVal != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Community Condition",
- }).Error("failed to parser as number or community value.")
+ if c.option == MATCH_OPTION_ALL && !result {
+ break
}
- community := uint32(asn<<16 | val)
- return true, community
-
- } else if regWellKnown.MatchString(comStr) {
- // specified by well known community name
- var community uint32
- switch comStr {
- case COMMUNITY_INTERNET:
- community = COMMUNITY_INTERNET_VAL
- case COMMUNITY_NO_EXPORT:
- community = COMMUNITY_NO_EXPORT_VAL
- case COMMUNITY_NO_ADVERTISE:
- community = COMMUNITY_NO_ADVERTISE_VAL
- case COMMUNITY_NO_EXPORT_SUBCONFED:
- community = COMMUNITY_NO_EXPORT_SUBCONFED_VAL
+ if c.option == MATCH_OPTION_ANY && result {
+ break
}
- return true, community
}
- return false, 0
+ if c.option == MATCH_OPTION_INVERT {
+ result = !result
+ }
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Condition": "community",
+ "MatchOption": c.option,
+ "Matched": result,
+ }).Debug("evaluation result")
+ return result
}
-func (c *CommunityCondition) checkMembers(communities []uint32, checkAll bool) bool {
-
- result := false
- if checkAll {
- result = true
+func NewCommunityCondition(c config.MatchCommunitySet, m map[string]DefinedSet) (*CommunityCondition, error) {
+ if c.CommunitySet == "" {
+ return nil, nil
}
-
- makeStr := func(c uint32) string {
- upper := strconv.FormatUint(uint64(c&0xFFFF0000>>16), 10)
- lower := strconv.FormatUint(uint64(c&0x0000FFFF), 10)
- return upper + ":" + lower
+ 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,
+ option: o,
+ }, nil
+}
- var strCommunities []string = nil
- matched := false
- idx := -1
- for _, member := range c.CommunityList {
- if member.isRegExp {
-
- if strCommunities == nil {
- // create community string.
- strCommunities = make([]string, len(communities))
- for i, c := range communities {
- strCommunities[i] = makeStr(c)
- }
- }
+type ExtCommunityCondition struct {
+ set *ExtCommunitySet
+ option MatchOption
+}
- for i, c := range strCommunities {
- if member.communityRegExp.MatchString(c) {
- matched = true
- idx = i
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "RegExp": member.communityRegExp.String(),
- }).Debug("community regexp used")
- break
- }
- }
+func (c *ExtCommunityCondition) Set() *ExtCommunitySet {
+ return c.set
+}
- } else {
- for i, c := range communities {
- if c == member.community {
- matched = true
- idx = i
- break
- }
- }
- }
+func (c *ExtCommunityCondition) Option() MatchOption {
+ return c.option
+}
- if matched {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Condition": "Community",
- "Community": makeStr(communities[idx]),
- }).Debug("condition matched")
+func (c *ExtCommunityCondition) ToApiStruct() *api.MatchSet {
+ s := c.set.ToApiStruct()
+ s.Option = int32(c.option)
+ return s
+}
- if !checkAll {
+func (c *ExtCommunityCondition) Evaluate(path *Path) bool {
+ es := path.GetExtCommunities()
+ result := false
+ for _, x := range es {
+ result = false
+ typ, subtype := x.GetTypes()
+ // match only with transitive community. see RFC7153
+ if typ >= 0x3f {
+ continue
+ }
+ for idx, y := range c.set.list {
+ if subtype == c.set.subtypeList[idx] && y.MatchString(x.String()) {
result = true
break
}
-
- } else {
- if checkAll {
- result = false
- break
- }
+ }
+ if c.option == MATCH_OPTION_ALL && !result {
+ break
+ }
+ if c.option == MATCH_OPTION_ANY && result {
+ break
}
}
-
- return result
-
-}
-
-// compare community in the message's attribute with
-// the one in the condition.
-func (c *CommunityCondition) evaluate(path *Path) bool {
-
- communities := path.GetCommunities()
-
- if len(communities) == 0 {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Condition": "community",
- "MatchOption": c.MatchOption,
- "Matched": false,
- }).Debug("community length is zero")
- return false
- }
-
- result := false
- if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ALL {
- result = c.checkMembers(communities, true)
- } else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ANY {
- result = c.checkMembers(communities, false)
- } else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_INVERT {
- result = !c.checkMembers(communities, false)
+ if c.option == MATCH_OPTION_INVERT {
+ result = !result
}
log.WithFields(log.Fields{
"Topic": "Policy",
"Condition": "community",
- "MatchOption": c.MatchOption,
+ "MatchOption": c.option,
"Matched": result,
- }).Debug("evaluate community")
-
+ }).Debug("evaluation result")
return result
}
-type ExtCommunityCondition struct {
- DefaultCondition
- ExtCommunityList []*ExtCommunityElement
- MatchOption config.MatchSetOptionsType
-}
-
-type ExtCommunityElement struct {
- ecType bgp.ExtendedCommunityAttrType
- ecSubType bgp.ExtendedCommunityAttrSubType
- globalAdmin interface{}
- localAdmin uint32
- comStr string
- isRegExp bool
- regExp *regexp.Regexp
-}
-
-func NewExtCommunityCondition(matchSet config.MatchExtCommunitySet, defExtComSetList []config.ExtCommunitySet) *ExtCommunityCondition {
-
- extComSetName := matchSet.ExtCommunitySet
- option := matchSet.MatchSetOptions
-
- extCommunityElemList := make([]*ExtCommunityElement, 0)
- for _, extComSet := range defExtComSetList {
- if extComSet.ExtCommunitySetName == extComSetName {
- for _, ecommunity := range extComSet.ExtCommunityList {
- matchAll := false
- ec := ecommunity.ExtCommunity
- e := &ExtCommunityElement{
- isRegExp: false,
- comStr: ec,
- }
- matchType, val := getECommunitySubType(ec)
- if !matchType {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Extended Community Condition",
- }).Error("failed to parse the sub type %s.", ec)
- return nil
- }
- switch val[1] {
- case "RT":
- e.ecSubType = bgp.EC_SUBTYPE_ROUTE_TARGET
- case "SoO":
- e.ecSubType = bgp.EC_SUBTYPE_ROUTE_ORIGIN
- default:
- e.ecSubType = bgp.ExtendedCommunityAttrSubType(0xFF)
- }
-
- if matchVal, elem := getECommunityValue(val[2]); matchVal {
- if matchElem, ecType, gAdmin := getECommunityElem(elem[1]); matchElem {
- e.ecType = ecType
- e.globalAdmin = gAdmin
- lAdmin, err := strconv.ParseUint(elem[2], 10, 32)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Extended Community Condition",
- }).Errorf("failed to parse the local administrator %d.", elem[2])
- return nil
- }
- e.localAdmin = uint32(lAdmin)
- matchAll = true
- }
- }
- if !matchAll {
- e.isRegExp = true
- reg, err := regexp.Compile(ec)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Extended Community Condition",
- }).Errorf("Regular expression can't be compiled %s.", val[2])
- return nil
- }
- e.regExp = reg
- }
- extCommunityElemList = append(extCommunityElemList, e)
- }
- ce := &ExtCommunityCondition{
- ExtCommunityList: extCommunityElemList,
- MatchOption: option,
- }
- return ce
- }
+func NewExtCommunityCondition(c config.MatchExtCommunitySet, m map[string]DefinedSet) (*ExtCommunityCondition, error) {
+ if c.ExtCommunitySet == "" {
+ return nil, nil
}
- return nil
-}
-
-func getECommunitySubType(eComStr string) (bool, []string) {
- regSubType, _ := regexp.Compile("^(RT|SoO):(.*)$")
- if regSubType.MatchString(eComStr) {
- eComVal := regSubType.FindStringSubmatch(eComStr)
- return true, eComVal
+ i, ok := m[c.ExtCommunitySet]
+ if !ok {
+ return nil, fmt.Errorf("not found ext-community set %s", c.ExtCommunitySet)
}
- return false, nil
-}
-
-func getECommunityValue(eComVal string) (bool, []string) {
- regVal, _ := regexp.Compile("^([0-9\\.]+):([0-9]+)$")
- if regVal.MatchString(eComVal) {
- eComElem := regVal.FindStringSubmatch(eComVal)
- return true, eComElem
+ s, ok := i.(*ExtCommunitySet)
+ if !ok {
+ return nil, fmt.Errorf("type assert from DefinedSet to *ExtCommunitySet failed")
}
- return false, nil
+ o, err := NewMatchOption(c.MatchSetOptions)
+ if err != nil {
+ return nil, err
+ }
+ return &ExtCommunityCondition{
+ set: s,
+ option: o,
+ }, nil
}
-func getECommunityElem(gAdmin string) (bool, bgp.ExtendedCommunityAttrType, interface{}) {
- addr := net.ParseIP(gAdmin)
- if addr.To4() != nil {
- return true, bgp.EC_TYPE_TRANSITIVE_IP4_SPECIFIC, addr
- }
- regAs, _ := regexp.Compile("^([0-9]+)$")
- if regAs.MatchString(gAdmin) {
- as, err := strconv.ParseUint(gAdmin, 10, 16)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Extended Community Condition",
- }).Errorf("failed to parse the global administrator %d.", gAdmin)
- }
- return true, bgp.EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC, uint16(as)
- }
- regAs4, _ := regexp.Compile("^([0-9]+).([0-9]+)$")
- if regAs4.MatchString(gAdmin) {
- as4Elem := regAs4.FindStringSubmatch(gAdmin)
- highAs, errHigh := strconv.ParseUint(as4Elem[1], 10, 16)
- lowAs, errLow := strconv.ParseUint(as4Elem[2], 10, 16)
- if errHigh != nil || errLow != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Extended Community Condition",
- }).Errorf("failed to parse the global administrator %d.", gAdmin)
- }
- return true, bgp.EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC, uint32(highAs<<16 | lowAs)
- }
- return false, bgp.ExtendedCommunityAttrType(0xFF), nil
+type AsPathLengthCondition struct {
+ length uint32
+ operator AttributeComparison
}
-func (c *ExtCommunityCondition) checkMembers(eCommunities []bgp.ExtendedCommunityInterface, checkAll bool) bool {
+// compare AS_PATH length in the message's AS_PATH attribute with
+// the one in condition.
+func (c *AsPathLengthCondition) Evaluate(path *Path) bool {
+ length := uint32(path.GetAsPathLen())
result := false
- if checkAll {
- result = true
- }
-
- makeAs4Str := func(ec *ExtCommunityElement) string {
- t := ec.ecType
- str := fmt.Sprintf("%d", ec.localAdmin)
- switch t {
- case bgp.EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC:
- str = fmt.Sprintf("%d:%s", ec.globalAdmin.(uint16), str)
- case bgp.EC_TYPE_TRANSITIVE_IP4_SPECIFIC:
- str = fmt.Sprintf("%s:%s", ec.globalAdmin.(net.IP).String(), str)
- case bgp.EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC:
- ga := ec.globalAdmin.(uint32)
- upper := strconv.FormatUint(uint64(ga&0xFFFF0000>>16), 10)
- lower := strconv.FormatUint(uint64(ga&0x0000FFFF), 10)
- str = fmt.Sprintf("%s.%s:%s", upper, lower, str)
- }
- return str
+ switch c.operator {
+ case ATTRIBUTE_EQ:
+ result = c.length == length
+ case ATTRIBUTE_GE:
+ result = c.length <= length
+ case ATTRIBUTE_LE:
+ result = c.length >= length
}
- makeTypeSubStr := func(st bgp.ExtendedCommunityAttrSubType) string {
- subStr := ""
- switch st {
- case bgp.EC_SUBTYPE_ROUTE_TARGET:
- subStr = "RT"
- case bgp.EC_SUBTYPE_ROUTE_ORIGIN:
- subStr = "SoO"
- }
- return subStr
- }
-
- matched := false
- matchStr := ""
- for _, member := range c.ExtCommunityList {
- for _, ec := range eCommunities {
- t, st := ec.GetTypes()
- if member.isRegExp {
- ecString := fmt.Sprintf("%s:%s", makeTypeSubStr(st), ec.String())
- if member.regExp.MatchString(ecString) {
- matched = true
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "RegExp": member.regExp.String(),
- }).Debug("extended community regexp used")
- matchStr = ec.String()
- break
- }
- } else if member.ecType == t && member.ecSubType == st {
- if makeAs4Str(member) == ec.String() {
- matched = true
- matchStr = ec.String()
- break
- }
-
- }
- }
- if matched {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Condition": "Extended Community",
- "Extended Community": matchStr,
- }).Debug("condition matched")
-
- if !checkAll {
- result = true
- break
- }
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Condition": "aspath length",
+ "Reason": c.operator,
+ "Matched": result,
+ }).Debug("evaluation result")
- } else {
- if checkAll {
- result = false
- break
- }
- }
- }
return result
}
-// compare extended community in the message's attribute with
-// the one in the condition.
-func (c *ExtCommunityCondition) evaluate(path *Path) bool {
-
- eCommunities := path.GetExtCommunities()
- if len(eCommunities) == 0 {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Condition": "extended community",
- "Matched": false,
- "Path": path,
- }).Debug("extended community length is zero")
- return false
+func (c *AsPathLengthCondition) ToApiStruct() *api.AsPathLength {
+ return &api.AsPathLength{
+ Length: c.length,
+ Type: int32(c.operator),
}
+}
- result := false
- if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ALL {
- result = c.checkMembers(eCommunities, true)
- } else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_ANY {
- result = c.checkMembers(eCommunities, false)
- } else if c.MatchOption == config.MATCH_SET_OPTIONS_TYPE_INVERT {
- result = !c.checkMembers(eCommunities, false)
+func NewAsPathLengthCondition(c config.AsPathLength) (*AsPathLengthCondition, error) {
+ if c.Value == 0 && c.Operator == "" {
+ return nil, nil
}
-
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Condition": "extended community",
- "MatchOption": c.MatchOption,
- "Matched": result,
- "Path": path,
- }).Debug("evaluate extended community")
-
- return result
+ var op AttributeComparison
+ switch strings.ToLower(c.Operator) {
+ case "eq":
+ op = ATTRIBUTE_EQ
+ case "ge":
+ op = ATTRIBUTE_GE
+ case "le":
+ op = ATTRIBUTE_LE
+ default:
+ return nil, fmt.Errorf("invalid as path length operator: %s", c.Operator)
+ }
+ return &AsPathLengthCondition{
+ length: c.Value,
+ operator: op,
+ }, nil
}
-type RPKIValidationCondition struct {
+type RpkiValidationCondition struct {
result config.RpkiValidationResultType
}
-func NewRPKIValidationCondition(result config.RpkiValidationResultType) *RPKIValidationCondition {
- return &RPKIValidationCondition{
- result: result,
- }
+func (c *RpkiValidationCondition) Evaluate(path *Path) bool {
+ return c.result == path.Validation
}
-func (c *RPKIValidationCondition) evaluate(path *Path) bool {
- return c.result == path.Validation
+func NewRpkiValidationCondition(c config.RpkiValidationResultType) (*RpkiValidationCondition, error) {
+ if c == config.RPKI_VALIDATION_RESULT_TYPE_NONE {
+ return nil, nil
+ }
+ return &RpkiValidationCondition{
+ result: c,
+ }, nil
}
type Action interface {
- apply(*Path) *Path
+ Apply(*Path) *Path
}
type RoutingAction struct {
AcceptRoute bool
}
-func NewRoutingAction(action config.Actions) *RoutingAction {
- return &RoutingAction{
- AcceptRoute: action.RouteDisposition.AcceptRoute,
- }
-}
-
-func (r *RoutingAction) apply(path *Path) *Path {
- if r.AcceptRoute {
+func (a *RoutingAction) Apply(path *Path) *Path {
+ if a.AcceptRoute {
return path
}
return nil
}
-type CommunityAction struct {
- Values []uint32
- ext []byte
- action config.BgpSetCommunityOptionType
- RegexpValues []*regexp.Regexp
-}
-
-const (
- COMMUNITY_ACTION_ADD string = "ADD"
- COMMUNITY_ACTION_REPLACE = "REPLACE"
- COMMUNITY_ACTION_REMOVE = "REMOVE"
- COMMUNITY_ACTION_NULL = "NULL"
-)
-
-// NewCommunityAction creates CommunityAction object.
-// If it cannot parse community string, then return nil.
-// Similarly, if option string is invalid, return nil.
-func NewCommunityAction(action config.SetCommunity) *CommunityAction {
-
- m := &CommunityAction{}
- communities := action.SetCommunityMethod.Communities
- if len(communities) == 0 && action.Options != COMMUNITY_ACTION_REPLACE {
- return nil
+func (a *RoutingAction) ToApiStruct() api.RouteAction {
+ if a.AcceptRoute {
+ return api.RouteAction_ACCEPT
+ } else {
+ return api.RouteAction_REJECT
}
+}
- values := make([]uint32, 0, len(communities))
- regexpValues := make([]*regexp.Regexp, 0, len(communities))
-
- for _, com := range communities {
- matched, value := getCommunityValue(com)
- if matched {
- values = append(values, value)
- continue
- }
-
- exp, err := regexp.Compile(com)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Community Action",
- }).Errorf("community string invalid")
- return nil
- }
- regexpValues = append(regexpValues, exp)
+func NewRoutingAction(c config.RouteDisposition) (*RoutingAction, error) {
+ if c.AcceptRoute == c.RejectRoute && c.AcceptRoute {
+ return nil, fmt.Errorf("invalid route disposition")
}
- 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
+ accept := false
+ if c.AcceptRoute && !c.RejectRoute {
+ accept = true
}
+ return &RoutingAction{
+ AcceptRoute: accept,
+ }, nil
+}
- switch action.Options {
- case COMMUNITY_ACTION_ADD:
- m.action = config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD
- case COMMUNITY_ACTION_REMOVE:
- m.action = config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE
- case COMMUNITY_ACTION_REPLACE:
- m.action = config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE
- default:
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Community Action",
- }).Error("action string should be ADD or REMOVE or REPLACE or NULL.")
- return nil
- }
- return m
+type CommunityAction struct {
+ action config.BgpSetCommunityOptionType
+ list []uint32
+ removeList []*regexp.Regexp
}
func RegexpRemoveCommunities(path *Path, exps []*regexp.Regexp) {
@@ -1136,150 +1003,198 @@ func RegexpRemoveCommunities(path *Path, exps []*regexp.Regexp) {
path.SetCommunities(newComms, true)
}
-func (a *CommunityAction) apply(path *Path) *Path {
- if len(a.ext) > 0 {
- return a.extApply(path)
+func RegexpRemoveExtCommunities(path *Path, exps []*regexp.Regexp, subtypes []bgp.ExtendedCommunityAttrSubType) {
+ comms := path.GetExtCommunities()
+ newComms := make([]bgp.ExtendedCommunityInterface, 0, len(comms))
+ for _, comm := range comms {
+ match := false
+ typ, subtype := comm.GetTypes()
+ // match only with transitive community. see RFC7153
+ if typ >= 0x3f {
+ continue
+ }
+ for idx, exp := range exps {
+ if subtype == subtypes[idx] && exp.MatchString(comm.String()) {
+ match = true
+ break
+ }
+ }
+ if match == false {
+ newComms = append(newComms, comm)
+ }
}
- list := a.Values
+ path.SetExtCommunities(newComms, true)
+}
+
+func (a *CommunityAction) Apply(path *Path) *Path {
switch a.action {
case config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD:
- path.SetCommunities(list, false)
+ path.SetCommunities(a.list, false)
case config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE:
- path.RemoveCommunities(list)
- if len(a.RegexpValues) > 0 {
- RegexpRemoveCommunities(path, a.RegexpValues)
- }
+ RegexpRemoveCommunities(path, a.removeList)
case config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE:
- path.SetCommunities(list, true)
+ path.SetCommunities(a.list, true)
}
-
log.WithFields(log.Fields{
"Topic": "Policy",
"Action": "community",
- "Values": list,
+ "Values": a.list,
"Method": a.action,
}).Debug("community action applied")
-
- return path
-}
-
-func (a *CommunityAction) extApply(path *Path) *Path {
- path.SetExtCommunities(a.ext, false)
-
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Action": "extended community",
- "Values": a.ext,
- "Method": a.action,
- }).Debug("extended community action applied")
-
return path
}
-func NewExtCommunityAction(action config.SetExtCommunity) *CommunityAction {
- communities := action.SetExtCommunityMethod.Communities
- if len(communities) == 0 {
- return nil
+func (a *CommunityAction) ToApiStruct() *api.CommunityAction {
+ cs := make([]string, 0, len(a.list)+len(a.removeList))
+ for _, comm := range a.list {
+ c := fmt.Sprintf("%d:%d", comm>>16, comm&0x0000ffff)
+ cs = append(cs, c)
}
+ for _, exp := range a.removeList {
+ cs = append(cs, exp.String())
+ }
+ return &api.CommunityAction{
+ Communities: cs,
+ Option: int32(a.action),
+ }
+}
- b := make([]byte, len(communities)*8)
- for i, c := range communities {
- l := strings.Split(c, ":")
- if len(l) != 8 {
- goto E
+func NewCommunityAction(c config.SetCommunity) (*CommunityAction, error) {
+ a, ok := CommunityOptionValueMap[strings.ToLower(c.Options)]
+ if !ok {
+ if len(c.SetCommunityMethod.Communities) == 0 {
+ return nil, nil
}
- for j, v := range l {
- v, err := strconv.ParseInt(v, 0, 32)
+ return nil, fmt.Errorf("invalid option name: %s", c.Options)
+ }
+ var list []uint32
+ var removeList []*regexp.Regexp
+ if a == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ removeList = make([]*regexp.Regexp, 0, len(c.SetCommunityMethod.Communities))
+ } else {
+ list = make([]uint32, 0, len(c.SetCommunityMethod.Communities))
+ }
+ for _, x := range c.SetCommunityMethod.Communities {
+ if a == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ exp, err := parseCommunityRegexp(x)
if err != nil {
- goto E
+ return nil, err
}
- b[j+i*8] = uint8(v)
+ removeList = append(removeList, exp)
+ } else {
+ comm, err := ParseCommunity(x)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, comm)
}
}
return &CommunityAction{
- ext: b,
- }
-E:
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Action": "ExtCommunity",
- "Values": communities,
- }).Error("invalid extended community action")
- return nil
+ action: a,
+ list: list,
+ removeList: removeList,
+ }, nil
}
-type ActionType int
-
-type MedAction struct {
- Value int64
- action ActionType
+type ExtCommunityAction struct {
+ action config.BgpSetCommunityOptionType
+ list []bgp.ExtendedCommunityInterface
+ removeList []*regexp.Regexp
+ subtypeList []bgp.ExtendedCommunityAttrSubType
}
-const (
- MED_ACTION_NONE ActionType = iota
- MED_ACTION_REPLACE
- MED_ACTION_ADD
- MED_ACTION_SUB
-)
-
-// NewMedAction creates MedAction object.
-// If it cannot parse med string, then return nil.
-func NewMedAction(med config.BgpSetMedType) *MedAction {
-
- if med == "" {
- return nil
+func (a *ExtCommunityAction) Apply(path *Path) *Path {
+ switch a.action {
+ case config.BGP_SET_COMMUNITY_OPTION_TYPE_ADD:
+ path.SetExtCommunities(a.list, false)
+ case config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE:
+ RegexpRemoveExtCommunities(path, a.removeList, a.subtypeList)
+ case config.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE:
+ path.SetExtCommunities(a.list, true)
}
+ return path
+}
- m := &MedAction{}
+func (a *ExtCommunityAction) ToApiStruct() *api.CommunityAction {
+ cs := make([]string, 0, len(a.list)+len(a.removeList))
+ f := func(idx int, arg string) string {
+ switch a.subtypeList[idx] {
+ case bgp.EC_SUBTYPE_ROUTE_TARGET:
+ return fmt.Sprintf("rt:%s", arg)
+ case bgp.EC_SUBTYPE_ROUTE_ORIGIN:
+ return fmt.Sprintf("soo:%s", arg)
+ default:
+ return fmt.Sprintf("%d:%s", a.subtypeList[idx])
+ }
+ }
+ for idx, c := range a.list {
+ cs = append(cs, f(idx, c.String()))
+ }
+ for idx, exp := range a.removeList {
+ cs = append(cs, f(idx, exp.String()))
+ }
+ return &api.CommunityAction{
+ Communities: cs,
+ Option: int32(a.action),
+ }
+}
- matched, value, action := getMedValue(fmt.Sprintf("%s", med))
- if !matched {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Med Action",
- }).Error("med string invalid.")
- return nil
- }
- m.Value = value
- m.action = action
- return m
-}
-
-// getMedValue returns uint32 med value and action type (+ or -).
-// if the string doesn't match a number or operator,
-// it returns false and 0.
-func getMedValue(medStr string) (bool, int64, ActionType) {
- regMed, _ := regexp.Compile("^(\\+|\\-)?([0-9]+)$")
- if regMed.MatchString(medStr) {
- group := regMed.FindStringSubmatch(medStr)
- action := MED_ACTION_REPLACE
- if group[1] == "+" {
- action = MED_ACTION_ADD
- } else if group[1] == "-" {
- action = MED_ACTION_SUB
+func NewExtCommunityAction(c config.SetExtCommunity) (*ExtCommunityAction, error) {
+ a, ok := CommunityOptionValueMap[strings.ToLower(c.Options)]
+ if !ok {
+ if len(c.SetExtCommunityMethod.Communities) == 0 {
+ return nil, nil
}
- val, err := strconv.ParseInt(medStr, 10, 64)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Med Action",
- }).Error("failed to parser as number or med value.")
+ return nil, fmt.Errorf("invalid option name: %s", c.Options)
+ }
+ var list []bgp.ExtendedCommunityInterface
+ var removeList []*regexp.Regexp
+ subtypeList := make([]bgp.ExtendedCommunityAttrSubType, 0, len(c.SetExtCommunityMethod.Communities))
+ if a == config.BGP_SET_COMMUNITY_OPTION_TYPE_REMOVE {
+ removeList = make([]*regexp.Regexp, 0, len(c.SetExtCommunityMethod.Communities))
+ } else {
+ list = make([]bgp.ExtendedCommunityInterface, 0, len(c.SetExtCommunityMethod.Communities))
+ }
+ for _, x := range c.SetExtCommunityMethod.Communities {
+ if a == 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 true, int64(val), action
}
- return false, int64(0), MED_ACTION_NONE
+ return &ExtCommunityAction{
+ action: a,
+ list: list,
+ removeList: removeList,
+ subtypeList: subtypeList,
+ }, nil
}
-func (a *MedAction) apply(path *Path) *Path {
+type MedAction struct {
+ value int
+ action MedActionType
+}
+
+func (a *MedAction) Apply(path *Path) *Path {
var err error
switch a.action {
+ case MED_ACTION_MOD:
+ err = path.SetMed(int64(a.value), false)
case MED_ACTION_REPLACE:
- err = path.SetMed(a.Value, true)
- case MED_ACTION_ADD:
- err = path.SetMed(a.Value, false)
- case MED_ACTION_SUB:
- err = path.SetMed(a.Value, false)
+ err = path.SetMed(int64(a.value), true)
}
+
if err != nil {
log.WithFields(log.Fields{
"Topic": "Policy",
@@ -1289,7 +1204,7 @@ func (a *MedAction) apply(path *Path) *Path {
log.WithFields(log.Fields{
"Topic": "Policy",
"Action": "med",
- "Value": a.Value,
+ "Value": a.value,
"ActionType": a.action,
}).Debug("med action applied")
}
@@ -1297,43 +1212,41 @@ func (a *MedAction) apply(path *Path) *Path {
return path
}
-type AsPathPrependAction struct {
- asn uint32
- useLeftMost bool
- repeat uint8
+func (a *MedAction) ToApiStruct() *api.MedAction {
+ return &api.MedAction{
+ Type: int32(a.action),
+ Value: int64(a.value),
+ }
}
-// NewAsPathPrependAction creates AsPathPrependAction object.
-// If ASN cannot be parsed, nil will be returned.
-func NewAsPathPrependAction(action config.SetAsPathPrepend) *AsPathPrependAction {
-
- a := &AsPathPrependAction{}
-
- if action.As == "" {
- return nil
+func NewMedAction(c config.BgpSetMedType) (*MedAction, error) {
+ if string(c) == "" {
+ return nil, nil
}
-
- if action.As == "last-as" {
- a.useLeftMost = true
- } else {
- asn, err := strconv.ParseUint(action.As, 10, 32)
- if err != nil {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "AsPathPrepend Action",
- "Value": action.As,
- }).Error("As number string invalid.")
- return nil
- }
- a.asn = uint32(asn)
+ exp := regexp.MustCompile("^(\\+|\\-)?(\\d+)$")
+ elems := exp.FindStringSubmatch(string(c))
+ if len(elems) != 3 {
+ return nil, fmt.Errorf("invalid med action format")
}
- a.repeat = action.RepeatN
-
- return a
+ action := MED_ACTION_REPLACE
+ switch elems[1] {
+ case "+", "-":
+ action = MED_ACTION_MOD
+ }
+ value, _ := strconv.Atoi(string(c))
+ return &MedAction{
+ value: value,
+ action: action,
+ }, nil
}
-func (a *AsPathPrependAction) apply(path *Path) *Path {
+type AsPathPrependAction struct {
+ asn uint32
+ useLeftMost bool
+ repeat uint8
+}
+func (a *AsPathPrependAction) Apply(path *Path) *Path {
var asn uint32
if a.useLeftMost {
asns := path.GetAsSeqList()
@@ -1341,7 +1254,7 @@ func (a *AsPathPrependAction) apply(path *Path) *Path {
log.WithFields(log.Fields{
"Topic": "Policy",
"Type": "AsPathPrepend Action",
- }).Error("aspath length is zero.")
+ }).Errorf("aspath length is zero.")
return path
}
asn = asns[0]
@@ -1367,680 +1280,324 @@ func (a *AsPathPrependAction) apply(path *Path) *Path {
return path
}
-type Prefix struct {
- Prefix *net.IPNet
- AddressFamily bgp.RouteFamily
- MasklengthRangeMax uint8
- MasklengthRangeMin uint8
-}
-
-func NewPrefix(prefixStr string, maskRange string) (Prefix, error) {
- p := Prefix{}
- addr, ipPref, e := net.ParseCIDR(prefixStr)
- if e != nil {
- return p, e
+func (a *AsPathPrependAction) ToApiStruct() *api.AsPrependAction {
+ return &api.AsPrependAction{
+ Asn: a.asn,
+ Repeat: uint32(a.repeat),
+ UseLeftMost: a.useLeftMost,
}
-
- if ipv4Family := addr.To4(); ipv4Family != nil {
- p.AddressFamily, _ = bgp.GetRouteFamily("ipv4-unicast")
- } else if ipv6Family := addr.To16(); ipv6Family != nil {
- p.AddressFamily, _ = bgp.GetRouteFamily("ipv6-unicast")
- } else {
- return p, fmt.Errorf("can not determine the address family.")
- }
-
- p.Prefix = ipPref
-
- if maskRange == "" {
- l, _ := ipPref.Mask.Size()
- maskLength := uint8(l)
- p.MasklengthRangeMax = maskLength
- p.MasklengthRangeMin = maskLength
- } else {
- exp := regexp.MustCompile("(\\d+)\\.\\.(\\d+)")
- elems := exp.FindStringSubmatch(maskRange)
- if len(elems) != 3 {
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Type": "Prefix",
- "MaskRangeFormat": maskRange,
- }).Warn("mask length range format is invalid.")
- return p, fmt.Errorf("mask length range format is invalid")
- }
- // we've already checked the range is sane by regexp
- min, _ := strconv.Atoi(elems[1])
- max, _ := strconv.Atoi(elems[2])
- p.MasklengthRangeMin = uint8(min)
- p.MasklengthRangeMax = uint8(max)
- }
- return p, nil
-}
-
-// 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.
-func (p *Policy) Apply(path *Path) (RouteType, *Path) {
- for _, statement := range p.Statements {
-
- result := statement.evaluate(path)
- log.WithFields(log.Fields{
- "Topic": "Policy",
- "Path": path,
- "PolicyName": p.Name,
- }).Debug("statement evaluate : ", result)
-
- if result {
- //Routing action
- p := statement.routingAction.apply(path)
- if p == nil {
- return ROUTE_TYPE_REJECT, path
- }
- if len(statement.modificationActions) == 0 {
- return ROUTE_TYPE_ACCEPT, path
- }
- // apply all modification actions
- cloned := path.Clone(p.Owner, p.IsWithdraw)
- for _, action := range statement.modificationActions {
- cloned = action.apply(cloned)
- }
- return ROUTE_TYPE_ACCEPT, cloned
- }
- }
- return ROUTE_TYPE_NONE, path
-}
-
-func ipPrefixCalculate(path *Path, cPrefix Prefix) bool {
- rf := path.GetRouteFamily()
- log.Debug("path routefamily : ", rf.String())
- var pAddr net.IP
- var pMasklen uint8
-
- if rf != cPrefix.AddressFamily {
- return false
- }
-
- switch rf {
- case bgp.RF_IPv4_UC:
- pAddr = path.GetNlri().(*bgp.IPAddrPrefix).Prefix
- pMasklen = path.GetNlri().(*bgp.IPAddrPrefix).Length
- case bgp.RF_IPv6_UC:
- pAddr = path.GetNlri().(*bgp.IPv6AddrPrefix).Prefix
- pMasklen = path.GetNlri().(*bgp.IPv6AddrPrefix).Length
- default:
- return false
- }
-
- return (cPrefix.MasklengthRangeMin <= pMasklen && pMasklen <= cPrefix.MasklengthRangeMax) && cPrefix.Prefix.Contains(pAddr)
-}
-
-const (
- OPTIONS_ANY string = "ANY"
- OPTIONS_ALL = "ALL"
- OPTIONS_INVERT = "INVERT"
-)
-
-func MatchSetOptionToString(option config.MatchSetOptionsType) string {
- op := OPTIONS_ANY
- switch option {
- case config.MATCH_SET_OPTIONS_TYPE_ALL:
- op = OPTIONS_ALL
- case config.MATCH_SET_OPTIONS_TYPE_INVERT:
- op = OPTIONS_INVERT
- }
- return op
-}
-
-func MatchSetOptionsRestrictedToString(option config.MatchSetOptionsRestrictedType) string {
- op := OPTIONS_ANY
- if option == config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT {
- op = OPTIONS_INVERT
- }
- return op
-}
-
-func MatchSetOptionsToType(option string) config.MatchSetOptionsType {
- op := config.MATCH_SET_OPTIONS_TYPE_ANY
- switch option {
- case OPTIONS_ALL:
- op = config.MATCH_SET_OPTIONS_TYPE_ALL
- case OPTIONS_INVERT:
- op = config.MATCH_SET_OPTIONS_TYPE_INVERT
- }
- return op
-}
-
-func MatchSetOptionsRestrictedToType(option string) config.MatchSetOptionsRestrictedType {
- op := config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_ANY
- if option == OPTIONS_INVERT {
- op = config.MATCH_SET_OPTIONS_RESTRICTED_TYPE_INVERT
- }
- return op
-}
-
-// find index PrefixSet of request from PrefixSet of configuration file.
-// Return the idxPrefixSet of the location where the name of PrefixSet matches,
-// and idxPrefix of the location where element of PrefixSet matches
-func IndexOfPrefixSet(conPrefixSetList []config.PrefixSet, reqPrefixSet config.PrefixSet) (int, int) {
- idxPrefixSet := -1
- idxPrefix := -1
- for i, conPrefixSet := range conPrefixSetList {
- if conPrefixSet.PrefixSetName == reqPrefixSet.PrefixSetName {
- idxPrefixSet = i
- if reqPrefixSet.PrefixList == nil {
- return idxPrefixSet, idxPrefix
- }
- for j, conPrefix := range conPrefixSet.PrefixList {
- if reflect.DeepEqual(conPrefix.IpPrefix, reqPrefixSet.PrefixList[0].IpPrefix) &&
- conPrefix.MasklengthRange == reqPrefixSet.PrefixList[0].MasklengthRange {
- idxPrefix = j
- return idxPrefixSet, idxPrefix
- }
- }
- }
- }
- return idxPrefixSet, idxPrefix
}
-// find index NeighborSet of request from NeighborSet of configuration file.
-// Return the idxNeighborSet of the location where the name of NeighborSet matches,
-// and idxNeighbor of the location where element of NeighborSet matches
-func IndexOfNeighborSet(conNeighborSetList []config.NeighborSet, reqNeighborSet config.NeighborSet) (int, int) {
- idxNeighborSet := -1
- idxNeighbor := -1
- for i, conNeighborSet := range conNeighborSetList {
- if conNeighborSet.NeighborSetName == reqNeighborSet.NeighborSetName {
- idxNeighborSet = i
- if reqNeighborSet.NeighborInfoList == nil {
- return idxNeighborSet, idxNeighbor
- }
- for j, conNeighbor := range conNeighborSet.NeighborInfoList {
- if reflect.DeepEqual(conNeighbor.Address, reqNeighborSet.NeighborInfoList[0].Address) {
- idxNeighbor = j
- return idxNeighborSet, idxNeighbor
- }
- }
- }
+// NewAsPathPrependAction creates AsPathPrependAction object.
+// If ASN cannot be parsed, nil will be returned.
+func NewAsPathPrependAction(action config.SetAsPathPrepend) (*AsPathPrependAction, error) {
+ a := &AsPathPrependAction{
+ repeat: action.RepeatN,
}
- return idxNeighborSet, idxNeighbor
-}
-
-// find index AsPathSet of request from AsPathSet of configuration file.
-// Return the idxAsPathSet of the location where the name of AsPathSet matches,
-// and idxAsPath of the location where element of AsPathSet matches
-func IndexOfAsPathSet(conAsPathSetList []config.AsPathSet, reqAsPathSet config.AsPathSet) (int, int) {
- idxAsPathSet := -1
- idxAsPath := -1
- for i, conAsPathSet := range conAsPathSetList {
- if conAsPathSet.AsPathSetName == reqAsPathSet.AsPathSetName {
- idxAsPathSet = i
- if len(reqAsPathSet.AsPathList) == 0 {
- return idxAsPathSet, idxAsPath
- }
- for j, conAsPath := range conAsPathSet.AsPathList {
- if conAsPath == reqAsPathSet.AsPathList[0] {
- idxAsPath = j
- return idxAsPathSet, idxAsPath
- }
- }
+ switch action.As {
+ case "":
+ if a.repeat == 0 {
+ return nil, nil
}
- }
- return idxAsPathSet, idxAsPath
-}
-
-// find index CommunitySet of request from CommunitySet of configuration file.
-// Return the idxCommunitySet of the location where the name of CommunitySet matches,
-// and idxCommunity of the location where element of CommunitySet matches
-func IndexOfCommunitySet(conCommunitySetList []config.CommunitySet, reqCommunitySet config.CommunitySet) (int, int) {
- idxCommunitySet := -1
- idxCommunity := -1
- for i, conCommunitySet := range conCommunitySetList {
- if conCommunitySet.CommunitySetName == reqCommunitySet.CommunitySetName {
- idxCommunitySet = i
- if len(reqCommunitySet.CommunityList) == 0 {
- return idxCommunitySet, idxCommunity
- }
- for j, conCommunity := range conCommunitySet.CommunityList {
- if conCommunity == reqCommunitySet.CommunityList[0] {
- idxCommunity = j
- return idxCommunitySet, idxCommunity
- }
- }
+ return nil, fmt.Errorf("specify as to prepend")
+ case "last-as":
+ a.useLeftMost = true
+ default:
+ asn, err := strconv.Atoi(action.As)
+ if err != nil {
+ return nil, fmt.Errorf("As number string invalid")
}
+ a.asn = uint32(asn)
}
- return idxCommunitySet, idxCommunity
+ return a, nil
}
-// find index ExtCommunitySet of request from ExtCommunitySet of configuration file.
-// Return the idxExtCommunitySet of the location where the name of ExtCommunitySet matches,
-// and idxExtCommunity of the location where element of ExtCommunitySet matches
-func IndexOfExtCommunitySet(conExtCommunitySetList []config.ExtCommunitySet, reqExtCommunitySet config.ExtCommunitySet) (int, int) {
- idxExtCommunitySet := -1
- idxExtCommunity := -1
- for i, conExtCommunitySet := range conExtCommunitySetList {
- if conExtCommunitySet.ExtCommunitySetName == reqExtCommunitySet.ExtCommunitySetName {
- idxExtCommunitySet = i
- if len(reqExtCommunitySet.ExtCommunityList) == 0 {
- return idxExtCommunitySet, idxExtCommunity
- }
- for j, conExtCommunity := range conExtCommunitySet.ExtCommunityList {
- if conExtCommunity == reqExtCommunitySet.ExtCommunityList[0] {
- idxExtCommunity = j
- return idxExtCommunitySet, idxExtCommunity
- }
- }
- }
- }
- return idxExtCommunitySet, idxExtCommunity
+type Statement struct {
+ Name string
+ Conditions []Condition
+ RouteAction Action
+ ModActions []Action
}
-// find index PolicyDefinition of request from PolicyDefinition of configuration file.
-// Return the idxPolicyDefinition of the location where the name of PolicyDefinition matches,
-// and idxStatement of the location where Statement of PolicyDefinition matches
-func IndexOfPolicyDefinition(conPolicyList []config.PolicyDefinition, reqPolicy config.PolicyDefinition) (int, int) {
- idxPolicyDefinition := -1
- idxStatement := -1
- for i, conPolicy := range conPolicyList {
- if conPolicy.Name == reqPolicy.Name {
- idxPolicyDefinition = i
- if reqPolicy.Statements.StatementList == nil {
- return idxPolicyDefinition, idxStatement
- }
- for j, conStatement := range conPolicy.Statements.StatementList {
- if conStatement.Name == reqPolicy.Statements.StatementList[0].Name {
- idxStatement = j
- return idxPolicyDefinition, idxStatement
- }
- }
+// evaluate each condition in the statement according to MatchSetOptions
+func (s *Statement) Evaluate(p *Path) bool {
+ for _, c := range s.Conditions {
+ fmt.Printf("%v, %t\n", c, c)
+ if !c.Evaluate(p) {
+ return false
}
}
- return idxPolicyDefinition, idxStatement
+ return true
}
-func PrefixSetToApiStruct(ps config.PrefixSet) *gobgpapi.PrefixSet {
- resPrefixList := make([]*gobgpapi.Prefix, 0)
- for _, p := range ps.PrefixList {
- resPrefix := &gobgpapi.Prefix{
- IpPrefix: p.IpPrefix,
- MaskLengthRange: p.MasklengthRange,
- }
- resPrefixList = append(resPrefixList, resPrefix)
- }
- resPrefixSet := &gobgpapi.PrefixSet{
- PrefixSetName: ps.PrefixSetName,
- PrefixList: resPrefixList,
+func (s *Statement) Apply(path *Path) (RouteType, *Path) {
+ result := s.Evaluate(path)
+ log.WithFields(log.Fields{
+ "Topic": "Policy",
+ "Path": path,
+ "PolicyName": s.Name,
+ }).Debug("statement evaluate : ", result)
+ if result {
+ //Routing action
+ p := s.RouteAction.Apply(path)
+ if p == nil {
+ return ROUTE_TYPE_REJECT, path
+ }
+ if len(s.ModActions) == 0 {
+ return ROUTE_TYPE_ACCEPT, path
+ }
+ // apply all modification actions
+ cloned := path.Clone(p.Owner, p.IsWithdraw)
+ for _, action := range s.ModActions {
+ cloned = action.Apply(cloned)
+ }
+ return ROUTE_TYPE_ACCEPT, cloned
}
-
- return resPrefixSet
+ return ROUTE_TYPE_NONE, path
}
-func PrefixSetToConfigStruct(reqPrefixSet *gobgpapi.PrefixSet) (bool, config.PrefixSet) {
- var prefix config.Prefix
- var prefixSet config.PrefixSet
- isReqPrefixSet := true
- if reqPrefixSet.PrefixList != nil {
- prefix = config.Prefix{
- IpPrefix: reqPrefixSet.PrefixList[0].IpPrefix,
- MasklengthRange: reqPrefixSet.PrefixList[0].MaskLengthRange,
- }
- prefixList := []config.Prefix{prefix}
-
- prefixSet = config.PrefixSet{
- PrefixSetName: reqPrefixSet.PrefixSetName,
- PrefixList: prefixList,
- }
- } else {
- isReqPrefixSet = false
- prefixSet = config.PrefixSet{
- PrefixSetName: reqPrefixSet.PrefixSetName,
- PrefixList: nil,
+func (s *Statement) ToApiStruct() *api.Statement {
+ cs := &api.Conditions{}
+ for _, c := range s.Conditions {
+ switch c.(type) {
+ case *PrefixCondition:
+ cs.PrefixSet = c.(*PrefixCondition).ToApiStruct()
+ case *NeighborCondition:
+ cs.NeighborSet = c.(*NeighborCondition).ToApiStruct()
+ case *AsPathLengthCondition:
+ cs.AsPathLength = c.(*AsPathLengthCondition).ToApiStruct()
+ case *AsPathCondition:
+ cs.AsPathSet = c.(*AsPathCondition).ToApiStruct()
+ case *CommunityCondition:
+ cs.CommunitySet = c.(*CommunityCondition).ToApiStruct()
+ case *ExtCommunityCondition:
+ cs.ExtCommunitySet = c.(*ExtCommunityCondition).ToApiStruct()
+ case *RpkiValidationCondition:
+ cs.RpkiResult = int32(c.(*RpkiValidationCondition).result)
+ }
+ }
+ as := &api.Actions{}
+ as.RouteAction = s.RouteAction.(*RoutingAction).ToApiStruct()
+ for _, a := range s.ModActions {
+ switch a.(type) {
+ case *CommunityAction:
+ as.Community = a.(*CommunityAction).ToApiStruct()
+ case *MedAction:
+ as.Med = a.(*MedAction).ToApiStruct()
+ case *AsPathPrependAction:
+ as.AsPrepend = a.(*AsPathPrependAction).ToApiStruct()
+ case *ExtCommunityAction:
+ as.ExtCommunity = a.(*ExtCommunityAction).ToApiStruct()
+ }
+ }
+ return &api.Statement{
+ Name: s.Name,
+ Conditions: cs,
+ Actions: as,
+ }
+}
+
+func NewStatement(c config.Statement, dmap DefinedSetMap) (*Statement, error) {
+ if c.Name == "" {
+ return nil, fmt.Errorf("empty statement name")
+ }
+ var ra Action
+ var as []Action
+ var cs []Condition
+ var err error
+ cfs := []func() (Condition, error){
+ func() (Condition, error) {
+ return NewPrefixCondition(c.Conditions.MatchPrefixSet, dmap[DEFINED_TYPE_PREFIX])
+ },
+ func() (Condition, error) {
+ return NewNeighborCondition(c.Conditions.MatchNeighborSet, dmap[DEFINED_TYPE_NEIGHBOR])
+ },
+ func() (Condition, error) {
+ return NewAsPathLengthCondition(c.Conditions.BgpConditions.AsPathLength)
+ },
+ func() (Condition, error) {
+ return NewRpkiValidationCondition(c.Conditions.BgpConditions.RpkiValidationResult)
+ },
+ func() (Condition, error) {
+ return NewAsPathCondition(c.Conditions.BgpConditions.MatchAsPathSet, dmap[DEFINED_TYPE_AS_PATH])
+ },
+ func() (Condition, error) {
+ return NewCommunityCondition(c.Conditions.BgpConditions.MatchCommunitySet, dmap[DEFINED_TYPE_COMMUNITY])
+ },
+ func() (Condition, error) {
+ return NewExtCommunityCondition(c.Conditions.BgpConditions.MatchExtCommunitySet, dmap[DEFINED_TYPE_EXT_COMMUNITY])
+ },
+ }
+ cs = make([]Condition, 0, len(cfs))
+ for _, f := range cfs {
+ c, err := f()
+ if err != nil {
+ return nil, err
}
- }
- return isReqPrefixSet, prefixSet
-}
-
-func NeighborSetToApiStruct(ns config.NeighborSet) *gobgpapi.NeighborSet {
- resNeighborList := make([]*gobgpapi.Neighbor, 0)
- for _, n := range ns.NeighborInfoList {
- resNeighbor := &gobgpapi.Neighbor{
- Address: n.Address.String(),
+ if !reflect.ValueOf(c).IsNil() {
+ cs = append(cs, c)
}
- resNeighborList = append(resNeighborList, resNeighbor)
- }
- resNeighborSet := &gobgpapi.NeighborSet{
- NeighborSetName: ns.NeighborSetName,
- NeighborList: resNeighborList,
}
- return resNeighborSet
-}
-
-func NeighborSetToConfigStruct(reqNeighborSet *gobgpapi.NeighborSet) (bool, config.NeighborSet) {
- var neighbor config.NeighborInfo
- var neighborSet config.NeighborSet
- isReqNeighborSet := true
- if reqNeighborSet.NeighborList != nil {
- neighbor = config.NeighborInfo{
- Address: net.ParseIP(reqNeighborSet.NeighborList[0].Address),
- }
- neighborList := []config.NeighborInfo{neighbor}
-
- neighborSet = config.NeighborSet{
- NeighborSetName: reqNeighborSet.NeighborSetName,
- NeighborInfoList: neighborList,
+ ra, err = NewRoutingAction(c.Actions.RouteDisposition)
+ if err != nil {
+ return nil, err
+ }
+ afs := []func() (Action, error){
+ func() (Action, error) {
+ return NewCommunityAction(c.Actions.BgpActions.SetCommunity)
+ },
+ func() (Action, error) {
+ return NewExtCommunityAction(c.Actions.BgpActions.SetExtCommunity)
+ },
+ func() (Action, error) {
+ return NewMedAction(c.Actions.BgpActions.SetMed)
+ },
+ func() (Action, error) {
+ return NewAsPathPrependAction(c.Actions.BgpActions.SetAsPathPrepend)
+ },
+ }
+ as = make([]Action, 0, len(afs))
+ for _, f := range afs {
+ a, err := f()
+ if err != nil {
+ return nil, err
}
- } else {
- isReqNeighborSet = false
- neighborSet = config.NeighborSet{
- NeighborSetName: reqNeighborSet.NeighborSetName,
- NeighborInfoList: nil,
+ if !reflect.ValueOf(a).IsNil() {
+ as = append(as, a)
}
}
- return isReqNeighborSet, neighborSet
-}
-
-func AsPathSetToApiStruct(as config.AsPathSet) *gobgpapi.AsPathSet {
- resAsPathMembers := make([]string, 0)
- for _, a := range as.AsPathList {
- resAsPathMembers = append(resAsPathMembers, a.AsPath)
- }
- resAsPathSet := &gobgpapi.AsPathSet{
- AsPathSetName: as.AsPathSetName,
- AsPathMembers: resAsPathMembers,
- }
- return resAsPathSet
-}
-
-func AsPathSetToConfigStruct(reqAsPathSet *gobgpapi.AsPathSet) (bool, config.AsPathSet) {
- isAsPathSetSet := true
- if len(reqAsPathSet.AsPathMembers) == 0 {
- isAsPathSetSet = false
- }
- asPathList := make([]config.AsPath, 0)
- for _, a := range reqAsPathSet.AsPathMembers {
- asPathList = append(asPathList, config.AsPath{AsPath: a})
- }
- asPathSet := config.AsPathSet{
- AsPathSetName: reqAsPathSet.AsPathSetName,
- AsPathList: asPathList,
- }
- return isAsPathSetSet, asPathSet
-}
-
-func CommunitySetToApiStruct(cs config.CommunitySet) *gobgpapi.CommunitySet {
- resCommunityMembers := make([]string, 0)
- for _, c := range cs.CommunityList {
- resCommunityMembers = append(resCommunityMembers, c.Community)
- }
- resCommunitySet := &gobgpapi.CommunitySet{
- CommunitySetName: cs.CommunitySetName,
- CommunityMembers: resCommunityMembers,
- }
- return resCommunitySet
-}
-
-func CommunitySetToConfigStruct(reqCommunitySet *gobgpapi.CommunitySet) (bool, config.CommunitySet) {
- isCommunitySet := true
- if len(reqCommunitySet.CommunityMembers) == 0 {
- isCommunitySet = false
- }
- communityList := make([]config.Community, 0)
- for _, c := range reqCommunitySet.CommunityMembers {
- communityList = append(communityList, config.Community{Community: c})
- }
- communitySet := config.CommunitySet{
- CommunitySetName: reqCommunitySet.CommunitySetName,
- CommunityList: communityList,
- }
- return isCommunitySet, communitySet
-}
-
-func ExtCommunitySetToApiStruct(es config.ExtCommunitySet) *gobgpapi.ExtCommunitySet {
- resExtCommunityMembers := make([]string, 0)
- for _, ec := range es.ExtCommunityList {
- resExtCommunityMembers = append(resExtCommunityMembers, ec.ExtCommunity)
- }
- resExtCommunitySet := &gobgpapi.ExtCommunitySet{
- ExtCommunitySetName: es.ExtCommunitySetName,
- ExtCommunityMembers: resExtCommunityMembers,
- }
- return resExtCommunitySet
-}
-
-func ExtCommunitySetToConfigStruct(reqExtCommunitySet *gobgpapi.ExtCommunitySet) (bool, config.ExtCommunitySet) {
- isExtCommunitySet := true
- if len(reqExtCommunitySet.ExtCommunityMembers) == 0 {
- isExtCommunitySet = false
- }
- extCommunityList := make([]config.ExtCommunity, 0)
- for _, ec := range reqExtCommunitySet.ExtCommunityMembers {
- extCommunityList = append(extCommunityList, config.ExtCommunity{ExtCommunity: ec})
- }
- ExtCommunitySet := config.ExtCommunitySet{
- ExtCommunitySetName: reqExtCommunitySet.ExtCommunitySetName,
- ExtCommunityList: extCommunityList,
- }
- return isExtCommunitySet, ExtCommunitySet
+ return &Statement{
+ Name: c.Name,
+ Conditions: cs,
+ RouteAction: ra,
+ ModActions: as,
+ }, nil
}
-func AsPathLengthToApiStruct(asPathLength config.AsPathLength) *gobgpapi.AsPathLength {
- value := ""
- if asPathLength.Operator != "" {
- value = fmt.Sprintf("%d", asPathLength.Value)
- }
- resAsPathLength := &gobgpapi.AsPathLength{
- Value: value,
- Operator: asPathLength.Operator,
- }
- return resAsPathLength
+type Policy struct {
+ name string
+ Statements []*Statement
}
-func AsPathLengthToConfigStruct(reqAsPathLength *gobgpapi.AsPathLength) config.AsPathLength {
- operator := reqAsPathLength.Operator
- value := reqAsPathLength.Value
- valueUint, _ := strconv.ParseUint(value, 10, 32)
- asPathLength := config.AsPathLength{
- Operator: operator,
- Value: uint32(valueUint),
- }
- return asPathLength
+func (p *Policy) Name() string {
+ return p.name
}
-func ConditionsToConfigStruct(reqConditions *gobgpapi.Conditions) config.Conditions {
- conditions := config.Conditions{}
- if reqConditions == nil {
- return conditions
- }
- if reqConditions.MatchPrefixSet != nil {
- conditions.MatchPrefixSet.PrefixSet = reqConditions.MatchPrefixSet.PrefixSetName
- conditions.MatchPrefixSet.MatchSetOptions =
- MatchSetOptionsRestrictedToType(reqConditions.MatchPrefixSet.MatchSetOptions)
- }
- if reqConditions.MatchNeighborSet != nil {
- conditions.MatchNeighborSet.NeighborSet = reqConditions.MatchNeighborSet.NeighborSetName
- conditions.MatchNeighborSet.MatchSetOptions =
- MatchSetOptionsRestrictedToType(reqConditions.MatchNeighborSet.MatchSetOptions)
- }
- if reqConditions.MatchAsPathSet != nil {
- conditions.BgpConditions.MatchAsPathSet.AsPathSet = reqConditions.MatchAsPathSet.AsPathSetName
- conditions.BgpConditions.MatchAsPathSet.MatchSetOptions =
- MatchSetOptionsToType(reqConditions.MatchAsPathSet.MatchSetOptions)
- }
- if reqConditions.MatchCommunitySet != nil {
- conditions.BgpConditions.MatchCommunitySet.CommunitySet = reqConditions.MatchCommunitySet.CommunitySetName
- conditions.BgpConditions.MatchCommunitySet.MatchSetOptions =
- MatchSetOptionsToType(reqConditions.MatchCommunitySet.MatchSetOptions)
- }
- if reqConditions.MatchExtCommunitySet != nil {
- conditions.BgpConditions.MatchExtCommunitySet.ExtCommunitySet = reqConditions.MatchExtCommunitySet.ExtCommunitySetName
- conditions.BgpConditions.MatchExtCommunitySet.MatchSetOptions =
- MatchSetOptionsToType(reqConditions.MatchExtCommunitySet.MatchSetOptions)
- }
- if reqConditions.MatchAsPathLength != nil {
- conditions.BgpConditions.AsPathLength =
- AsPathLengthToConfigStruct(reqConditions.MatchAsPathLength)
+// 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.
+func (p *Policy) Apply(path *Path) (RouteType, *Path) {
+ for _, stmt := range p.Statements {
+ result, path := stmt.Apply(path)
+ if result != ROUTE_TYPE_NONE {
+ return result, path
+ }
}
- return conditions
+ return ROUTE_TYPE_NONE, path
}
-func ActionsToApiStruct(conActions config.Actions) *gobgpapi.Actions {
- action := gobgpapi.RouteAction_REJECT
- if conActions.RouteDisposition.AcceptRoute {
- action = gobgpapi.RouteAction_ACCEPT
- }
-
- //TODO: support CommunitySetRef
- communityAction := &gobgpapi.CommunityAction{
- Communities: conActions.BgpActions.SetCommunity.SetCommunityMethod.Communities,
- Options: conActions.BgpActions.SetCommunity.Options,
- }
- medAction := fmt.Sprintf("%s", conActions.BgpActions.SetMed)
- asprependAction := &gobgpapi.AsPrependAction{
- conActions.BgpActions.SetAsPathPrepend.As,
- uint32(conActions.BgpActions.SetAsPathPrepend.RepeatN),
- }
- extCommunityAction := &gobgpapi.CommunityAction{
- Communities: conActions.BgpActions.SetExtCommunity.SetExtCommunityMethod.Communities,
- Options: conActions.BgpActions.SetExtCommunity.Options,
+func (p *Policy) ToApiStruct() *api.PolicyDefinition {
+ ss := make([]*api.Statement, 0, len(p.Statements))
+ for _, s := range p.Statements {
+ ss = append(ss, s.ToApiStruct())
}
-
- resActions := &gobgpapi.Actions{
- RouteAction: action,
- Community: communityAction,
- Med: medAction,
- AsPrepend: asprependAction,
- ExtCommunity: extCommunityAction,
+ return &api.PolicyDefinition{
+ Name: p.name,
+ Statements: ss,
}
- return resActions
}
-func ActionsToConfigStruct(reqActions *gobgpapi.Actions) config.Actions {
- actions := config.Actions{}
- if reqActions == nil {
- return actions
- }
- if reqActions.Community != nil {
- actions.BgpActions.SetCommunity.SetCommunityMethod.Communities = reqActions.Community.Communities
- actions.BgpActions.SetCommunity.Options = reqActions.Community.Options
- }
- if reqActions.Med != "" {
- actions.BgpActions.SetMed = config.BgpSetMedType(reqActions.Med)
+func NewPolicy(c config.PolicyDefinition, dmap DefinedSetMap) (*Policy, error) {
+ if c.Name == "" {
+ return nil, fmt.Errorf("empty policy name")
}
- if reqActions.AsPrepend != nil {
- actions.BgpActions.SetAsPathPrepend.As = reqActions.AsPrepend.As
- actions.BgpActions.SetAsPathPrepend.RepeatN = uint8(reqActions.AsPrepend.Repeatn)
- }
-
- switch reqActions.RouteAction {
- case gobgpapi.RouteAction_ACCEPT:
- actions.RouteDisposition.AcceptRoute = true
- case gobgpapi.RouteAction_REJECT:
- actions.RouteDisposition.RejectRoute = true
+ var st []*Statement
+ stmts := c.Statements.StatementList
+ if len(stmts) != 0 {
+ st = make([]*Statement, 0, len(stmts))
+ for _, stmt := range stmts {
+ s, err := NewStatement(stmt, dmap)
+ if err != nil {
+ return nil, err
+ }
+ st = append(st, s)
+ }
}
- return actions
+ return &Policy{
+ name: c.Name,
+ Statements: st,
+ }, nil
}
-func StatementToConfigStruct(reqStatement *gobgpapi.Statement) config.Statement {
- statement := config.Statement{
- Name: reqStatement.StatementNeme,
- Conditions: ConditionsToConfigStruct(reqStatement.Conditions),
- Actions: ActionsToConfigStruct(reqStatement.Actions),
- }
- return statement
+type RoutingPolicy struct {
+ DefinedSetMap DefinedSetMap
+ PolicyMap map[string]*Policy
}
-func PolicyDefinitionToConfigStruct(reqPolicy *gobgpapi.PolicyDefinition) (bool, config.PolicyDefinition) {
- isReqStatement := true
- policy := config.PolicyDefinition{
- Name: reqPolicy.PolicyDefinitionName,
- }
- if reqPolicy.StatementList != nil {
- statement := StatementToConfigStruct(reqPolicy.StatementList[0])
- policy.Statements.StatementList = []config.Statement{statement}
- } else {
- isReqStatement = false
- }
- return isReqStatement, policy
-}
-
-func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSets) *gobgpapi.PolicyDefinition {
- conPrefixSetList := df.PrefixSets.PrefixSetList
- conNeighborSetList := df.NeighborSets.NeighborSetList
- conAsPathSetList := df.BgpDefinedSets.AsPathSets.AsPathSetList
- conCommunitySetList := df.BgpDefinedSets.CommunitySets.CommunitySetList
- conExtCommunitySetList := df.BgpDefinedSets.ExtCommunitySets.ExtCommunitySetList
- resStatementList := make([]*gobgpapi.Statement, 0)
- for _, st := range pd.Statements.StatementList {
- co := st.Conditions
- bco := co.BgpConditions
- ac := st.Actions
-
- prefixSet := &gobgpapi.PrefixSet{PrefixSetName: co.MatchPrefixSet.PrefixSet}
- conPrefixSet := config.PrefixSet{PrefixSetName: co.MatchPrefixSet.PrefixSet}
- idxPrefixSet, _ := IndexOfPrefixSet(conPrefixSetList, conPrefixSet)
- if idxPrefixSet != -1 {
- prefixSet = PrefixSetToApiStruct(conPrefixSetList[idxPrefixSet])
- prefixSet.MatchSetOptions = MatchSetOptionsRestrictedToString(st.Conditions.MatchPrefixSet.MatchSetOptions)
- }
- neighborSet := &gobgpapi.NeighborSet{NeighborSetName: co.MatchNeighborSet.NeighborSet}
- conNeighborSet := config.NeighborSet{NeighborSetName: co.MatchNeighborSet.NeighborSet}
- idxNeighborSet, _ := IndexOfNeighborSet(conNeighborSetList, conNeighborSet)
- if idxNeighborSet != -1 {
- neighborSet = NeighborSetToApiStruct(conNeighborSetList[idxNeighborSet])
- neighborSet.MatchSetOptions = MatchSetOptionsRestrictedToString(st.Conditions.MatchNeighborSet.MatchSetOptions)
- }
-
- asPathSet := &gobgpapi.AsPathSet{AsPathSetName: bco.MatchAsPathSet.AsPathSet}
- conAsPathSet := config.AsPathSet{AsPathSetName: bco.MatchAsPathSet.AsPathSet}
- idxAsPathSet, _ := IndexOfAsPathSet(conAsPathSetList, conAsPathSet)
- if idxAsPathSet != -1 {
- asPathSet = AsPathSetToApiStruct(conAsPathSetList[idxAsPathSet])
- asPathSet.MatchSetOptions = MatchSetOptionToString(bco.MatchAsPathSet.MatchSetOptions)
- }
-
- communitySet := &gobgpapi.CommunitySet{CommunitySetName: bco.MatchCommunitySet.CommunitySet}
- conCommunitySet := config.CommunitySet{CommunitySetName: bco.MatchCommunitySet.CommunitySet}
- idxCommunitySet, _ := IndexOfCommunitySet(conCommunitySetList, conCommunitySet)
- if idxCommunitySet != -1 {
- communitySet = CommunitySetToApiStruct(conCommunitySetList[idxCommunitySet])
- communitySet.MatchSetOptions = MatchSetOptionToString(bco.MatchCommunitySet.MatchSetOptions)
- }
-
- extCommunitySet := &gobgpapi.ExtCommunitySet{ExtCommunitySetName: bco.MatchExtCommunitySet.ExtCommunitySet}
- conExtCommunitySet := config.ExtCommunitySet{ExtCommunitySetName: bco.MatchExtCommunitySet.ExtCommunitySet}
- idxExtCommunitySet, _ := IndexOfExtCommunitySet(conExtCommunitySetList, conExtCommunitySet)
- if idxExtCommunitySet != -1 {
- extCommunitySet = ExtCommunitySetToApiStruct(conExtCommunitySetList[idxExtCommunitySet])
- extCommunitySet.MatchSetOptions = MatchSetOptionToString(bco.MatchExtCommunitySet.MatchSetOptions)
+func NewRoutingPolicy(c config.RoutingPolicy) (*RoutingPolicy, error) {
+ dmap := make(map[DefinedType]map[string]DefinedSet)
+ dmap[DEFINED_TYPE_PREFIX] = make(map[string]DefinedSet)
+ d := c.DefinedSets
+ for _, x := range d.PrefixSets.PrefixSetList {
+ y, err := NewPrefixSet(x)
+ if err != nil {
+ return nil, err
}
-
- resConditions := &gobgpapi.Conditions{
- MatchPrefixSet: prefixSet,
- MatchNeighborSet: neighborSet,
- MatchAsPathSet: asPathSet,
- MatchCommunitySet: communitySet,
- MatchExtCommunitySet: extCommunitySet,
- MatchAsPathLength: AsPathLengthToApiStruct(st.Conditions.BgpConditions.AsPathLength),
+ dmap[DEFINED_TYPE_PREFIX][y.Name()] = y
+ }
+ dmap[DEFINED_TYPE_NEIGHBOR] = make(map[string]DefinedSet)
+ for _, x := range d.NeighborSets.NeighborSetList {
+ y, err := NewNeighborSet(x)
+ if err != nil {
+ return nil, err
+ }
+ dmap[DEFINED_TYPE_NEIGHBOR][y.Name()] = y
+ }
+ // dmap[DEFINED_TYPE_TAG] = make(map[string]DefinedSet)
+ // for _, x := range c.DefinedSets.TagSets.TagSetList {
+ // y, err := NewTagSet(x)
+ // if err != nil {
+ // return nil, err
+ // }
+ // dmap[DEFINED_TYPE_TAG][y.Name()] = y
+ // }
+ bd := c.DefinedSets.BgpDefinedSets
+ dmap[DEFINED_TYPE_AS_PATH] = make(map[string]DefinedSet)
+ for _, x := range bd.AsPathSets.AsPathSetList {
+ y, err := NewAsPathSet(x)
+ if err != nil {
+ return nil, err
}
- resActions := ActionsToApiStruct(ac)
- resStatement := &gobgpapi.Statement{
- StatementNeme: st.Name,
- Conditions: resConditions,
- Actions: resActions,
+ dmap[DEFINED_TYPE_AS_PATH][y.Name()] = y
+ }
+ dmap[DEFINED_TYPE_COMMUNITY] = make(map[string]DefinedSet)
+ for _, x := range bd.CommunitySets.CommunitySetList {
+ y, err := NewCommunitySet(x)
+ if err != nil {
+ return nil, err
}
- resStatementList = append(resStatementList, resStatement)
+ dmap[DEFINED_TYPE_COMMUNITY][y.Name()] = y
}
- resPolicyDefinition := &gobgpapi.PolicyDefinition{
- PolicyDefinitionName: pd.Name,
- StatementList: resStatementList,
+ dmap[DEFINED_TYPE_EXT_COMMUNITY] = make(map[string]DefinedSet)
+ for _, x := range bd.ExtCommunitySets.ExtCommunitySetList {
+ y, err := NewExtCommunitySet(x)
+ if err != nil {
+ return nil, err
+ }
+ dmap[DEFINED_TYPE_EXT_COMMUNITY][y.Name()] = y
}
- return resPolicyDefinition
-}
-
-func PoliciesToString(reqPolicies []*gobgpapi.PolicyDefinition) []string {
- policies := make([]string, 0)
- for _, reqPolicy := range reqPolicies {
- policies = append(policies, reqPolicy.PolicyDefinitionName)
+ pmap := make(map[string]*Policy)
+ for _, x := range c.PolicyDefinitions.PolicyDefinitionList {
+ y, err := NewPolicy(x, dmap)
+ if err != nil {
+ return nil, err
+ }
+ pmap[y.Name()] = y
}
- return policies
+ return &RoutingPolicy{
+ DefinedSetMap: dmap,
+ PolicyMap: pmap,
+ }, nil
}
func CanImportToVrf(v *Vrf, path *Path) bool {
@@ -2053,13 +1610,22 @@ func CanImportToVrf(v *Vrf, path *Path) bool {
}
return ret
}
- set := config.ExtCommunitySet{
+ set, _ := NewExtCommunitySet(config.ExtCommunitySet{
ExtCommunitySetName: v.Name,
ExtCommunityList: f(v.ImportRt),
- }
+ })
matchSet := config.MatchExtCommunitySet{
ExtCommunitySet: v.Name,
MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY,
}
- return NewExtCommunityCondition(matchSet, []config.ExtCommunitySet{set}).evaluate(path)
+ c, _ := NewExtCommunityCondition(matchSet, map[string]DefinedSet{v.Name: set})
+ return c.Evaluate(path)
+}
+
+func PoliciesToString(ps []*api.PolicyDefinition) []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 a60c9cc7..9f9e1d17 100644
--- a/table/policy_test.go
+++ b/table/policy_test.go
@@ -23,7 +23,6 @@ import (
"github.com/stretchr/testify/assert"
"math"
"net"
- "regexp"
"strconv"
"strings"
"testing"
@@ -48,14 +47,14 @@ func TestPrefixCalcurateNoRange(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("10.10.0.0/24", "")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"10.10.0.0/24", ""})
+ match1 := pl1.Match(path)
assert.Equal(t, true, match1)
- pl2, _ := NewPrefix("10.10.0.0/23", "")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"10.10.0.0/23", ""})
+ match2 := pl2.Match(path)
assert.Equal(t, false, match2)
- pl3, _ := NewPrefix("10.10.0.0/16", "21..24")
- match3 := ipPrefixCalculate(path, pl3)
+ pl3, _ := NewPrefix(config.Prefix{"10.10.0.0/16", "21..24"})
+ match3 := pl3.Match(path)
assert.Equal(t, true, match3)
}
@@ -72,11 +71,11 @@ func TestPrefixCalcurateAddress(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("10.11.0.0/16", "21..24")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"10.11.0.0/16", "21..24"})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("10.10.0.0/16", "21..24")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"10.10.0.0/16", "21..24"})
+ match2 := pl2.Match(path)
assert.Equal(t, true, match2)
}
@@ -93,11 +92,11 @@ func TestPrefixCalcurateLength(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("10.10.64.0/24", "21..24")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"10.10.64.0/24", "21..24"})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("10.10.64.0/16", "21..24")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"10.10.64.0/16", "21..24"})
+ match2 := pl2.Match(path)
assert.Equal(t, true, match2)
}
@@ -114,14 +113,14 @@ func TestPrefixCalcurateLengthRange(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("10.10.0.0/16", "21..23")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"10.10.0.0/16", "21..23"})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("10.10.0.0/16", "25..26")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"10.10.0.0/16", "25..26"})
+ match2 := pl2.Match(path)
assert.Equal(t, false, match2)
- pl3, _ := NewPrefix("10.10.0.0/16", "21..24")
- match3 := ipPrefixCalculate(path, pl3)
+ pl3, _ := NewPrefix(config.Prefix{"10.10.0.0/16", "21..24"})
+ match3 := pl3.Match(path)
assert.Equal(t, true, match3)
}
@@ -139,14 +138,14 @@ func TestPrefixCalcurateNoRangeIPv6(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("2001:123:123::/48", "")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"2001:123:123::/48", ""})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("2001:123:123:1::/64", "")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"2001:123:123:1::/64", ""})
+ match2 := pl2.Match(path)
assert.Equal(t, true, match2)
- pl3, _ := NewPrefix("2001:123:123::/48", "64..80")
- match3 := ipPrefixCalculate(path, pl3)
+ pl3, _ := NewPrefix(config.Prefix{"2001:123:123::/48", "64..80"})
+ match3 := pl3.Match(path)
assert.Equal(t, true, match3)
}
@@ -163,11 +162,11 @@ func TestPrefixCalcurateAddressIPv6(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("2001:123:128::/48", "64..80")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"2001:123:128::/48", "64..80"})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("2001:123:123::/48", "64..80")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"2001:123:123::/48", "64..80"})
+ match2 := pl2.Match(path)
assert.Equal(t, true, match2)
}
@@ -184,11 +183,11 @@ func TestPrefixCalcurateLengthIPv6(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("2001:123:123:64::/64", "64..80")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"2001:123:123:64::/64", "64..80"})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("2001:123:123:64::/48", "64..80")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"2001:123:123:64::/48", "64..80"})
+ match2 := pl2.Match(path)
assert.Equal(t, true, match2)
}
@@ -205,14 +204,14 @@ func TestPrefixCalcurateLengthRangeIPv6(t *testing.T) {
updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
path := ProcessMessage(updateMsg, peer)[0]
// test
- pl1, _ := NewPrefix("2001:123:123::/48", "62..63")
- match1 := ipPrefixCalculate(path, pl1)
+ pl1, _ := NewPrefix(config.Prefix{"2001:123:123::/48", "62..63"})
+ match1 := pl1.Match(path)
assert.Equal(t, false, match1)
- pl2, _ := NewPrefix("2001:123:123::/48", "65..66")
- match2 := ipPrefixCalculate(path, pl2)
+ pl2, _ := NewPrefix(config.Prefix{"2001:123:123::/48", "65..66"})
+ match2 := pl2.Match(path)
assert.Equal(t, false, match2)
- pl3, _ := NewPrefix("2001:123:123::/48", "63..65")
- match3 := ipPrefixCalculate(path, pl3)
+ pl3, _ := NewPrefix(config.Prefix{"2001:123:123::/48", "63..65"})
+ match3 := pl3.Match(path)
assert.Equal(t, true, match3)
}
@@ -239,10 +238,9 @@ func TestPolicyNotMatch(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
- //test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
- pType, newPath := p.Apply(path)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ pType, newPath := r.PolicyMap["pd1"].Apply(path)
assert.Equal(t, ROUTE_TYPE_NONE, pType)
assert.Equal(t, newPath, path)
}
@@ -270,10 +268,9 @@ func TestPolicyMatchAndReject(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
- //test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
- pType, newPath := p.Apply(path)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ pType, newPath := r.PolicyMap["pd1"].Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
}
@@ -302,9 +299,9 @@ func TestPolicyMatchAndAccept(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
- pType, newPath := p.Apply(path)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ pType, newPath := r.PolicyMap["pd1"].Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
assert.Equal(t, path, newPath)
}
@@ -338,13 +335,14 @@ func TestPolicyRejectOnlyPrefixSet(t *testing.T) {
ds := config.DefinedSets{}
ds.PrefixSets.PrefixSetList = []config.PrefixSet{ps}
- s := createStatement("statement1", "ps1", "ns1", false)
+ s := createStatement("statement1", "ps1", "", false)
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path1)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path1)
@@ -383,18 +381,18 @@ func TestPolicyRejectOnlyNeighborSet(t *testing.T) {
ds := config.DefinedSets{}
ds.NeighborSets.NeighborSetList = []config.NeighborSet{ns}
- s := createStatement("statement1", "ps1", "ns1", false)
+ s := createStatement("statement1", "", "ns1", false)
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
- pType, newPath := p.Apply(path1)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ pType, newPath := r.PolicyMap["pd1"].Apply(path1)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path1)
- pType2, newPath2 := p.Apply(path2)
+ pType2, newPath2 := r.PolicyMap["pd1"].Apply(path2)
assert.Equal(t, ROUTE_TYPE_NONE, pType2)
assert.Equal(t, newPath2, path2)
}
@@ -440,8 +438,9 @@ func TestPolicyDifferentRoutefamilyOfPathAndPolicy(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType1, newPath1 := p.Apply(pathIPv4)
assert.Equal(t, ROUTE_TYPE_REJECT, pType1)
assert.Equal(t, newPath1, pathIPv4)
@@ -474,30 +473,30 @@ func TestAsPathLengthConditionEvaluate(t *testing.T) {
Operator: "eq",
Value: 5,
}
- c := NewAsPathLengthCondition(asPathLength)
+ c, _ := NewAsPathLengthCondition(asPathLength)
// test
- assert.Equal(t, true, c.evaluate(path))
+ assert.Equal(t, true, c.Evaluate(path))
// create match condition
asPathLength = config.AsPathLength{
Operator: "ge",
Value: 3,
}
- c = NewAsPathLengthCondition(asPathLength)
+ c, _ = NewAsPathLengthCondition(asPathLength)
// test
- assert.Equal(t, true, c.evaluate(path))
+ assert.Equal(t, true, c.Evaluate(path))
// create match condition
asPathLength = config.AsPathLength{
Operator: "le",
Value: 3,
}
- c = NewAsPathLengthCondition(asPathLength)
+ c, _ = NewAsPathLengthCondition(asPathLength)
// test
- assert.Equal(t, false, c.evaluate(path))
+ assert.Equal(t, false, c.Evaluate(path))
}
func TestAsPathLengthConditionWithOtherCondition(t *testing.T) {
@@ -538,8 +537,9 @@ func TestAsPathLengthConditionWithOtherCondition(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -579,30 +579,30 @@ func TestAs4PathLengthConditionEvaluate(t *testing.T) {
Operator: "eq",
Value: 5,
}
- c := NewAsPathLengthCondition(asPathLength)
+ c, _ := NewAsPathLengthCondition(asPathLength)
// test
- assert.Equal(t, true, c.evaluate(path))
+ assert.Equal(t, true, c.Evaluate(path))
// create match condition
asPathLength = config.AsPathLength{
Operator: "ge",
Value: 3,
}
- c = NewAsPathLengthCondition(asPathLength)
+ c, _ = NewAsPathLengthCondition(asPathLength)
// test
- assert.Equal(t, true, c.evaluate(path))
+ assert.Equal(t, true, c.Evaluate(path))
// create match condition
asPathLength = config.AsPathLength{
Operator: "le",
Value: 3,
}
- c = NewAsPathLengthCondition(asPathLength)
+ c, _ = NewAsPathLengthCondition(asPathLength)
// test
- assert.Equal(t, false, c.evaluate(path))
+ assert.Equal(t, false, c.Evaluate(path))
}
func TestAs4PathLengthConditionWithOtherCondition(t *testing.T) {
@@ -654,8 +654,8 @@ func TestAs4PathLengthConditionWithOtherCondition(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, _ := NewRoutingPolicy(pl)
+ p, _ := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], r.DefinedSetMap)
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -733,14 +733,18 @@ func TestAsPathConditionEvaluate(t *testing.T) {
},
}
- asPathSetList := []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
- asPathSet4, asPathSet5, asPathSet6}
+ m := make(map[string]DefinedSet)
+ for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
+ asPathSet4, asPathSet5, asPathSet6} {
+ a, _ := NewAsPathSet(s)
+ m[s.AsPathSetName] = a
+ }
createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p := NewAsPathCondition(matchSet, asPathSetList)
+ p, _ := NewAsPathCondition(matchSet, m)
return p
}
@@ -750,22 +754,19 @@ func TestAsPathConditionEvaluate(t *testing.T) {
p4 := createAspathC("asset4", config.MATCH_SET_OPTIONS_TYPE_ANY)
p5 := createAspathC("asset5", config.MATCH_SET_OPTIONS_TYPE_ANY)
p6 := createAspathC("asset6", config.MATCH_SET_OPTIONS_TYPE_ANY)
-
- //TODO: add ALL and INVERT cases.
p7 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_ALL)
p8 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_INVERT)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, false, p4.evaluate(path1))
- assert.Equal(t, true, p5.evaluate(path1))
- assert.Equal(t, false, p6.evaluate(path1))
- assert.Equal(t, true, p6.evaluate(path2))
-
- assert.Equal(t, true, p7.evaluate(path1))
- assert.Equal(t, true, p8.evaluate(path2))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, false, p4.Evaluate(path1))
+ assert.Equal(t, true, p5.Evaluate(path1))
+ assert.Equal(t, false, p6.Evaluate(path1))
+ assert.Equal(t, true, p6.Evaluate(path2))
+ assert.Equal(t, true, p7.Evaluate(path1))
+ assert.Equal(t, true, p8.Evaluate(path2))
}
func TestMultipleAsPathConditionEvaluate(t *testing.T) {
@@ -850,14 +851,18 @@ func TestMultipleAsPathConditionEvaluate(t *testing.T) {
},
}
- asPathSetList := []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
- asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9}
+ m := make(map[string]DefinedSet)
+ for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
+ asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9} {
+ a, _ := NewAsPathSet(s)
+ m[s.AsPathSetName] = a
+ }
createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p := NewAsPathCondition(matchSet, asPathSetList)
+ p, _ := NewAsPathCondition(matchSet, m)
return p
}
@@ -872,15 +877,15 @@ func TestMultipleAsPathConditionEvaluate(t *testing.T) {
p9 := createAspathC("asset9", config.MATCH_SET_OPTIONS_TYPE_ANY)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, true, p4.evaluate(path1))
- assert.Equal(t, true, p5.evaluate(path1))
- assert.Equal(t, true, p6.evaluate(path1))
- assert.Equal(t, true, p7.evaluate(path1))
- assert.Equal(t, true, p8.evaluate(path1))
- assert.Equal(t, false, p9.evaluate(path1))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, true, p4.Evaluate(path1))
+ assert.Equal(t, true, p5.Evaluate(path1))
+ assert.Equal(t, true, p6.Evaluate(path1))
+ assert.Equal(t, true, p7.Evaluate(path1))
+ assert.Equal(t, true, p8.Evaluate(path1))
+ assert.Equal(t, false, p9.Evaluate(path1))
}
func TestAsPathCondition(t *testing.T) {
@@ -930,17 +935,19 @@ func TestAsPathCondition(t *testing.T) {
}
for k, v := range tests {
- r, _ := regexp.Compile(strings.Replace(k, "_", ASPATH_REGEXP_MAGIC, -1))
- c := &AsPathCondition{
- AsRegExpList: []*regexp.Regexp{r},
- MatchOption: config.MATCH_SET_OPTIONS_TYPE_ANY,
- }
+ s, _ := NewAsPathSet(config.AsPathSet{
+ AsPathSetName: k,
+ AsPathList: []config.AsPath{config.AsPath{k}},
+ })
+ c, _ := NewAsPathCondition(config.MatchAsPathSet{
+ AsPathSet: k,
+ MatchSetOptions: config.MATCH_SET_OPTIONS_TYPE_ANY,
+ }, map[string]DefinedSet{k: s})
for _, a := range v {
- result := c.evaluate(a.path)
+ result := c.Evaluate(a.path)
if a.result != result {
log.WithFields(log.Fields{
"EXP": k,
- "ASN": r,
"ASSTR": a.path.GetAsString(),
"Expected": a.result,
"Result": result,
@@ -990,8 +997,9 @@ func TestAsPathConditionWithOtherCondition(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -1077,14 +1085,18 @@ func TestAs4PathConditionEvaluate(t *testing.T) {
},
}
- asPathSetList := []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
- asPathSet4, asPathSet5, asPathSet6}
+ m := make(map[string]DefinedSet)
+ for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
+ asPathSet4, asPathSet5, asPathSet6} {
+ a, _ := NewAsPathSet(s)
+ m[s.AsPathSetName] = a
+ }
createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p := NewAsPathCondition(matchSet, asPathSetList)
+ p, _ := NewAsPathCondition(matchSet, m)
return p
}
@@ -1099,16 +1111,16 @@ func TestAs4PathConditionEvaluate(t *testing.T) {
p8 := createAspathC("asset3", config.MATCH_SET_OPTIONS_TYPE_INVERT)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, false, p4.evaluate(path1))
- assert.Equal(t, true, p5.evaluate(path1))
- assert.Equal(t, false, p6.evaluate(path1))
- assert.Equal(t, true, p6.evaluate(path2))
-
- assert.Equal(t, true, p7.evaluate(path1))
- assert.Equal(t, true, p8.evaluate(path2))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, false, p4.Evaluate(path1))
+ assert.Equal(t, true, p5.Evaluate(path1))
+ assert.Equal(t, false, p6.Evaluate(path1))
+ assert.Equal(t, true, p6.Evaluate(path2))
+
+ assert.Equal(t, true, p7.Evaluate(path1))
+ assert.Equal(t, true, p8.Evaluate(path2))
}
func TestMultipleAs4PathConditionEvaluate(t *testing.T) {
@@ -1200,14 +1212,18 @@ func TestMultipleAs4PathConditionEvaluate(t *testing.T) {
},
}
- asPathSetList := []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
- asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9}
+ m := make(map[string]DefinedSet)
+ for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
+ asPathSet4, asPathSet5, asPathSet6, asPathSet7, asPathSet8, asPathSet9} {
+ a, _ := NewAsPathSet(s)
+ m[s.AsPathSetName] = a
+ }
createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p := NewAsPathCondition(matchSet, asPathSetList)
+ p, _ := NewAsPathCondition(matchSet, m)
return p
}
@@ -1222,15 +1238,15 @@ func TestMultipleAs4PathConditionEvaluate(t *testing.T) {
p9 := createAspathC("asset9", config.MATCH_SET_OPTIONS_TYPE_ANY)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, true, p4.evaluate(path1))
- assert.Equal(t, true, p5.evaluate(path1))
- assert.Equal(t, true, p6.evaluate(path1))
- assert.Equal(t, true, p7.evaluate(path1))
- assert.Equal(t, true, p8.evaluate(path1))
- assert.Equal(t, false, p9.evaluate(path1))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, true, p4.Evaluate(path1))
+ assert.Equal(t, true, p5.Evaluate(path1))
+ assert.Equal(t, true, p6.Evaluate(path1))
+ assert.Equal(t, true, p7.Evaluate(path1))
+ assert.Equal(t, true, p8.Evaluate(path1))
+ assert.Equal(t, false, p9.Evaluate(path1))
}
func TestAs4PathConditionWithOtherCondition(t *testing.T) {
@@ -1286,8 +1302,8 @@ func TestAs4PathConditionWithOtherCondition(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, _ := NewRoutingPolicy(pl)
+ p, _ := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], r.DefinedSetMap)
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -1373,14 +1389,18 @@ func TestAs4PathConditionEvaluateMixedWith2byteAS(t *testing.T) {
},
}
- asPathSetList := []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
- asPathSet4, asPathSet5, asPathSet6, asPathSet7}
+ m := make(map[string]DefinedSet)
+ for _, s := range []config.AsPathSet{asPathSet1, asPathSet2, asPathSet3,
+ asPathSet4, asPathSet5, asPathSet6, asPathSet7} {
+ a, _ := NewAsPathSet(s)
+ m[s.AsPathSetName] = a
+ }
createAspathC := func(name string, option config.MatchSetOptionsType) *AsPathCondition {
matchSet := config.MatchAsPathSet{}
matchSet.AsPathSet = name
matchSet.MatchSetOptions = option
- p := NewAsPathCondition(matchSet, asPathSetList)
+ p, _ := NewAsPathCondition(matchSet, m)
return p
}
@@ -1393,13 +1413,13 @@ func TestAs4PathConditionEvaluateMixedWith2byteAS(t *testing.T) {
p7 := createAspathC("asset7", config.MATCH_SET_OPTIONS_TYPE_ANY)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, true, p4.evaluate(path1))
- assert.Equal(t, true, p5.evaluate(path1))
- assert.Equal(t, false, p6.evaluate(path1))
- assert.Equal(t, true, p7.evaluate(path1))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, true, p4.Evaluate(path1))
+ assert.Equal(t, true, p5.Evaluate(path1))
+ assert.Equal(t, false, p6.Evaluate(path1))
+ assert.Equal(t, true, p7.Evaluate(path1))
}
@@ -1434,6 +1454,17 @@ func TestCommunityConditionEvaluate(t *testing.T) {
UpdatePathAttrs4ByteAs(updateMsg1.Body.(*bgp.BGPUpdate))
path1 := ProcessMessage(updateMsg1, peer)[0]
+ communities2 := bgp.NewPathAttributeCommunities([]uint32{
+ stringToCommunityValue("65001:100"),
+ stringToCommunityValue("65001:200"),
+ stringToCommunityValue("65001:300"),
+ stringToCommunityValue("65001:400")})
+
+ pathAttributes2 := []bgp.PathAttributeInterface{origin, aspath, nexthop, med, communities2}
+ updateMsg2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri)
+ UpdatePathAttrs4ByteAs(updateMsg2.Body.(*bgp.BGPUpdate))
+ path2 := ProcessMessage(updateMsg2, peer)[0]
+
// create match condition
comSet1 := config.CommunitySet{
CommunitySetName: "comset1",
@@ -1496,9 +1527,8 @@ func TestCommunityConditionEvaluate(t *testing.T) {
comSet9 := config.CommunitySet{
CommunitySetName: "comset9",
CommunityList: []config.Community{
- config.Community{"65001:100"},
- config.Community{"65001:200"},
- config.Community{"65001:300"},
+ config.Community{"65001:\\d+"},
+ config.Community{"\\d+:\\d00"},
},
}
@@ -1511,14 +1541,19 @@ func TestCommunityConditionEvaluate(t *testing.T) {
},
}
- comSetList := []config.CommunitySet{comSet1, comSet2, comSet3,
- comSet4, comSet5, comSet6, comSet7, comSet8, comSet9, comSet10}
+ m := make(map[string]DefinedSet)
+
+ for _, c := range []config.CommunitySet{comSet1, comSet2, comSet3,
+ comSet4, comSet5, comSet6, comSet7, comSet8, comSet9, comSet10} {
+ s, _ := NewCommunitySet(c)
+ m[c.CommunitySetName] = s
+ }
createCommunityC := func(name string, option config.MatchSetOptionsType) *CommunityCondition {
matchSet := config.MatchCommunitySet{}
matchSet.CommunitySet = name
matchSet.MatchSetOptions = option
- c := NewCommunityCondition(matchSet, comSetList)
+ c, _ := NewCommunityCondition(matchSet, m)
return c
}
@@ -1539,16 +1574,16 @@ func TestCommunityConditionEvaluate(t *testing.T) {
p10 := createCommunityC("comset10", config.MATCH_SET_OPTIONS_TYPE_INVERT)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, true, p4.evaluate(path1))
- assert.Equal(t, true, p5.evaluate(path1))
- assert.Equal(t, true, p6.evaluate(path1))
- assert.Equal(t, true, p7.evaluate(path1))
- assert.Equal(t, true, p8.evaluate(path1))
- assert.Equal(t, true, p9.evaluate(path1))
- assert.Equal(t, true, p10.evaluate(path1))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, true, p4.Evaluate(path1))
+ assert.Equal(t, true, p5.Evaluate(path1))
+ assert.Equal(t, true, p6.Evaluate(path1))
+ assert.Equal(t, true, p7.Evaluate(path1))
+ assert.Equal(t, true, p8.Evaluate(path1))
+ assert.Equal(t, true, p9.Evaluate(path2))
+ assert.Equal(t, true, p10.Evaluate(path1))
}
@@ -1626,14 +1661,14 @@ func TestCommunityConditionEvaluateWithOtherCondition(t *testing.T) {
pl := createRoutingPolicy(ds, pd1, pd2)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
- df = pl.DefinedSets
- p = NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[1], df)
+ p = r.PolicyMap["pd2"]
pType, newPath = p.Apply(path)
assert.Equal(t, ROUTE_TYPE_NONE, pType)
assert.Equal(t, newPath, path)
@@ -1670,8 +1705,9 @@ func TestPolicyMatchAndAddCommunities(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -1713,8 +1749,9 @@ func TestPolicyMatchAndReplaceCommunities(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -1756,8 +1793,9 @@ func TestPolicyMatchAndRemoveCommunities(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
assert.NotEqual(t, nil, newPath)
@@ -1800,8 +1838,9 @@ func TestPolicyMatchAndRemoveCommunitiesRegexp(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
assert.NotEqual(t, nil, newPath)
@@ -1844,8 +1883,9 @@ func TestPolicyMatchAndRemoveCommunitiesRegexp2(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
assert.NotEqual(t, nil, newPath)
@@ -1888,8 +1928,9 @@ func TestPolicyMatchAndClearCommunities(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -2041,9 +2082,8 @@ func TestExtCommunityConditionEvaluate(t *testing.T) {
ecomSet10 := config.ExtCommunitySet{
ExtCommunitySetName: "ecomSet10",
ExtCommunityList: []config.ExtCommunity{
- config.ExtCommunity{"RT:65001:200"},
- config.ExtCommunity{"RT:10.0.0.1:300"},
- config.ExtCommunity{"SoO:10.0.10.10:[0-9]+"},
+ config.ExtCommunity{"RT:.+:\\d00"},
+ config.ExtCommunity{"SoO:.+:\\d00"},
},
}
@@ -2051,19 +2091,22 @@ func TestExtCommunityConditionEvaluate(t *testing.T) {
ExtCommunitySetName: "ecomSet11",
ExtCommunityList: []config.ExtCommunity{
config.ExtCommunity{"RT:65001:2"},
- config.ExtCommunity{"RT:10.0.0.1:3"},
config.ExtCommunity{"SoO:11.0.10.10:[0-9]+"},
},
}
- comSetList := []config.ExtCommunitySet{ecomSet1, ecomSet2, ecomSet3, ecomSet4, ecomSet5, ecomSet6, ecomSet7,
- ecomSet8, ecomSet9, ecomSet10, ecomSet11}
+ m := make(map[string]DefinedSet)
+ for _, c := range []config.ExtCommunitySet{ecomSet1, ecomSet2, ecomSet3, ecomSet4, ecomSet5, ecomSet6, ecomSet7,
+ ecomSet8, ecomSet9, ecomSet10, ecomSet11} {
+ s, _ := NewExtCommunitySet(c)
+ m[s.Name()] = s
+ }
createExtCommunityC := func(name string, option config.MatchSetOptionsType) *ExtCommunityCondition {
matchSet := config.MatchExtCommunitySet{}
matchSet.ExtCommunitySet = name
matchSet.MatchSetOptions = option
- c := NewExtCommunityCondition(matchSet, comSetList)
+ c, _ := NewExtCommunityCondition(matchSet, m)
return c
}
@@ -2084,17 +2127,17 @@ func TestExtCommunityConditionEvaluate(t *testing.T) {
p11 := createExtCommunityC("ecomSet11", config.MATCH_SET_OPTIONS_TYPE_INVERT)
// test
- assert.Equal(t, true, p1.evaluate(path1))
- assert.Equal(t, true, p2.evaluate(path1))
- assert.Equal(t, true, p3.evaluate(path1))
- assert.Equal(t, false, p4.evaluate(path1))
- assert.Equal(t, false, p5.evaluate(path1))
- assert.Equal(t, false, p6.evaluate(path1))
- assert.Equal(t, true, p7.evaluate(path1))
- assert.Equal(t, true, p8.evaluate(path1))
- assert.Equal(t, true, p9.evaluate(path1))
- assert.Equal(t, true, p10.evaluate(path1))
- assert.Equal(t, true, p11.evaluate(path1))
+ assert.Equal(t, true, p1.Evaluate(path1))
+ assert.Equal(t, true, p2.Evaluate(path1))
+ assert.Equal(t, true, p3.Evaluate(path1))
+ assert.Equal(t, false, p4.Evaluate(path1))
+ assert.Equal(t, false, p5.Evaluate(path1))
+ assert.Equal(t, false, p6.Evaluate(path1))
+ assert.Equal(t, true, p7.Evaluate(path1))
+ assert.Equal(t, true, p8.Evaluate(path1))
+ assert.Equal(t, true, p9.Evaluate(path1))
+ assert.Equal(t, true, p10.Evaluate(path1))
+ assert.Equal(t, true, p11.Evaluate(path1))
}
@@ -2219,13 +2262,14 @@ func TestExtCommunityConditionEvaluateWithOtherCondition(t *testing.T) {
pd2 := createPolicyDefinition("pd2", s2)
pl := createRoutingPolicy(ds, pd1, pd2)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_NONE, pType)
assert.Equal(t, newPath, path)
- p = NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[1], df)
+ p = r.PolicyMap["pd2"]
pType, newPath = p.Apply(path)
assert.Equal(t, ROUTE_TYPE_REJECT, pType)
assert.Equal(t, newPath, path)
@@ -2262,8 +2306,9 @@ func TestPolicyMatchAndReplaceMed(t *testing.T) {
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -2304,8 +2349,9 @@ func TestPolicyMatchAndAddingMed(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
assert.NotEqual(t, nil, newPath)
@@ -2347,8 +2393,9 @@ func TestPolicyMatchAndAddingMedOverFlow(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -2391,8 +2438,9 @@ func TestPolicyMatchAndSubtractMed(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -2435,8 +2483,9 @@ func TestPolicyMatchAndSubtractMedUnderFlow(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
@@ -2476,14 +2525,15 @@ func TestPolicyMatchWhenPathHaveNotMed(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, err := NewRoutingPolicy(pl)
+ assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(t, ROUTE_TYPE_ACCEPT, pType)
assert.NotEqual(t, nil, newPath)
- _, err := newPath.GetMed()
+ _, err = newPath.GetMed()
assert.NotNil(t, err)
}
@@ -2522,8 +2572,9 @@ func TestPolicyAsPathPrepend(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, _ := NewRoutingPolicy(pl)
+ // assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(ROUTE_TYPE_ACCEPT, pType)
@@ -2565,8 +2616,9 @@ func TestPolicyAsPathPrependLastAs(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, _ := NewRoutingPolicy(pl)
+ // assert.Nil(t, err)
+ p := r.PolicyMap["pd1"]
pType, newPath := p.Apply(path)
assert.Equal(ROUTE_TYPE_ACCEPT, pType)
@@ -2614,8 +2666,8 @@ func TestPolicyAs4PathPrepend(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, _ := NewRoutingPolicy(pl)
+ p, _ := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], r.DefinedSetMap)
pType, newPath := p.Apply(path)
assert.Equal(ROUTE_TYPE_ACCEPT, pType)
@@ -2668,8 +2720,8 @@ func TestPolicyAs4PathPrependLastAs(t *testing.T) {
pd := createPolicyDefinition("pd1", s)
pl := createRoutingPolicy(ds, pd)
//test
- df := pl.DefinedSets
- p := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], df)
+ r, _ := NewRoutingPolicy(pl)
+ p, _ := NewPolicy(pl.PolicyDefinitions.PolicyDefinitionList[0], r.DefinedSetMap)
pType, newPath := p.Apply(path)
assert.Equal(ROUTE_TYPE_ACCEPT, pType)
@@ -2684,7 +2736,6 @@ func TestPolicyAs4PathPrependLastAs(t *testing.T) {
}
func createStatement(name, psname, nsname string, accept bool) config.Statement {
-
c := config.Conditions{
MatchPrefixSet: config.MatchPrefixSet{
PrefixSet: psname,
diff --git a/test/scenario_test/route_server_policy_test.py b/test/scenario_test/route_server_policy_test.py
index 1d372619..490d0173 100644
--- a/test/scenario_test/route_server_policy_test.py
+++ b/test/scenario_test/route_server_policy_test.py
@@ -2764,7 +2764,7 @@ class ImportPolicyExCommunityAdd(object):
'SetExtCommunity': {
'Options': 'ADD',
'SetExtCommunityMethod': {
- 'Communities': ['0:2:0xfd:0xe8:0:0:0:1']
+ 'Communities': ['rt:65000:1'],
}
},
}
@@ -2838,7 +2838,7 @@ class ImportPolicyExCommunityAdd2(object):
'SetExtCommunity': {
'Options': 'ADD',
'SetExtCommunityMethod': {
- 'Communities': ['0:2:0xfe:0x4c:0:0:0:0x64']
+ 'Communities': ['rt:65100:100'],
}
},
}
@@ -2917,7 +2917,7 @@ class ImportPolicyExCommunityMultipleAdd(object):
'SetExtCommunity': {
'Options': 'ADD',
'SetExtCommunityMethod': {
- 'Communities': ['0:2:0xfe:0x4c:0:0:0:0x64', '0:2:0:0x64:0:0:0:0x64']
+ 'Communities': ['rt:65100:100', 'rt:100:100'],
}
},
}
@@ -2996,7 +2996,7 @@ class ExportPolicyExCommunityAdd(object):
'SetExtCommunity': {
'Options': 'ADD',
'SetExtCommunityMethod': {
- 'Communities': ['0:2:0xfd:0xe8:0:0:0:1'],
+ 'Communities': ['rt:65000:1'],
}
},
}