summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go69
-rw-r--r--api/gobgp.proto7
-rw-r--r--gobgp/common.go16
-rw-r--r--gobgp/policy.go247
-rw-r--r--policy/policy.go68
-rw-r--r--server/grpc_server.go20
-rw-r--r--server/server.go128
-rw-r--r--test/scenario_test/policy/policy_generator.go4
8 files changed, 495 insertions, 64 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index cd935f84..fd8882e7 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -43,6 +43,7 @@ It has these top-level messages:
AsPathLength
AsPathSet
CommunitySet
+ ExtCommunitySet
Conditions
CommunityAction
AsPrependAction
@@ -70,15 +71,16 @@ var _ = proto.Marshal
type Resource int32
const (
- Resource_GLOBAL Resource = 0
- Resource_LOCAL Resource = 1
- Resource_ADJ_IN Resource = 2
- Resource_ADJ_OUT Resource = 3
- Resource_POLICY_PREFIX Resource = 4
- Resource_POLICY_NEIGHBOR Resource = 5
- Resource_POLICY_ASPATH Resource = 6
- Resource_POLICY_COMMUNITY Resource = 7
- Resource_POLICY_ROUTEPOLICY Resource = 8
+ Resource_GLOBAL Resource = 0
+ Resource_LOCAL Resource = 1
+ Resource_ADJ_IN Resource = 2
+ Resource_ADJ_OUT Resource = 3
+ Resource_POLICY_PREFIX Resource = 4
+ Resource_POLICY_NEIGHBOR Resource = 5
+ Resource_POLICY_ASPATH Resource = 6
+ Resource_POLICY_COMMUNITY Resource = 7
+ Resource_POLICY_ROUTEPOLICY Resource = 8
+ Resource_POLICY_EXTCOMMUNITY Resource = 9
)
var Resource_name = map[int32]string{
@@ -91,17 +93,19 @@ var Resource_name = map[int32]string{
6: "POLICY_ASPATH",
7: "POLICY_COMMUNITY",
8: "POLICY_ROUTEPOLICY",
+ 9: "POLICY_EXTCOMMUNITY",
}
var Resource_value = map[string]int32{
- "GLOBAL": 0,
- "LOCAL": 1,
- "ADJ_IN": 2,
- "ADJ_OUT": 3,
- "POLICY_PREFIX": 4,
- "POLICY_NEIGHBOR": 5,
- "POLICY_ASPATH": 6,
- "POLICY_COMMUNITY": 7,
- "POLICY_ROUTEPOLICY": 8,
+ "GLOBAL": 0,
+ "LOCAL": 1,
+ "ADJ_IN": 2,
+ "ADJ_OUT": 3,
+ "POLICY_PREFIX": 4,
+ "POLICY_NEIGHBOR": 5,
+ "POLICY_ASPATH": 6,
+ "POLICY_COMMUNITY": 7,
+ "POLICY_ROUTEPOLICY": 8,
+ "POLICY_EXTCOMMUNITY": 9,
}
func (x Resource) String() string {
@@ -1164,13 +1168,23 @@ 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"`
+}
+
+func (m *ExtCommunitySet) Reset() { *m = ExtCommunitySet{} }
+func (m *ExtCommunitySet) String() string { return proto.CompactTextString(m) }
+func (*ExtCommunitySet) 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"`
- MatchSetOptions string `protobuf:"bytes,6,opt,name=match_set_options" json:"match_set_options,omitempty"`
+ 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"`
+ MatchSetOptions string `protobuf:"bytes,6,opt,name=match_set_options" json:"match_set_options,omitempty"`
+ MatchExtCommunitySet *ExtCommunitySet `protobuf:"bytes,7,opt,name=match_ext_community_set" json:"match_ext_community_set,omitempty"`
}
func (m *Conditions) Reset() { *m = Conditions{} }
@@ -1212,6 +1226,13 @@ func (m *Conditions) GetMatchCommunitySet() *CommunitySet {
return nil
}
+func (m *Conditions) GetMatchExtCommunitySet() *ExtCommunitySet {
+ if m != nil {
+ return m.MatchExtCommunitySet
+ }
+ 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"`
diff --git a/api/gobgp.proto b/api/gobgp.proto
index b0fa4714..c97e446a 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -80,6 +80,7 @@ enum Resource {
POLICY_ASPATH = 6;
POLICY_COMMUNITY = 7;
POLICY_ROUTEPOLICY = 8;
+ POLICY_EXTCOMMUNITY = 9;
}
enum Operation {
@@ -434,6 +435,11 @@ message CommunitySet {
repeated string community_members = 2;
}
+message ExtCommunitySet {
+ string ext_community_set_name = 1;
+ repeated string ext_community_members = 2;
+}
+
message Conditions {
PrefixSet match_prefix_set = 1;
NeighborSet match_neighbor_set = 2;
@@ -441,6 +447,7 @@ message Conditions {
AsPathSet match_as_path_set = 4;
CommunitySet match_community_set = 5;
string match_set_options = 6;
+ ExtCommunitySet match_ext_community_set = 7;
}
message CommunityAction {
diff --git a/gobgp/common.go b/gobgp/common.go
index 2f17faa3..ce03c8f2 100644
--- a/gobgp/common.go
+++ b/gobgp/common.go
@@ -47,6 +47,7 @@ const (
CMD_PREFIX = "prefix"
CMD_ASPATH = "aspath"
CMD_COMMUNITY = "community"
+ CMD_EXTCOMMUNITY = "extcommunity"
CMD_ROUTEPOLICY = "routepolicy"
CMD_CONDITIONS = "conditions"
CMD_ACTIONS = "actions"
@@ -69,6 +70,7 @@ var conditionOpts struct {
Neighbor string `long:"neighbor" description:"specifying a neighbor set name of policy"`
AsPath string `long:"aspath" description:"specifying an as set name of policy"`
Community string `long:"community" description:"specifying a community set name of policy"`
+ ExtCommunity string `long:"extcommunity" description:"specifying a extended community set name of policy"`
AsPathLength string `long:"aspath-len" description:"specifying an as path length of policy (<operator>,<numeric>)"`
Option string `long:"option" description:"specifying an option of policy (any | all | invert)"`
}
@@ -234,6 +236,20 @@ func (c communities) Less(i, j int) bool {
return c[i].CommunitySetName < c[j].CommunitySetName
}
+type extcommunities []*api.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
+}
+
type policyDefinitions []*api.PolicyDefinition
func (p policyDefinitions) Len() int {
diff --git a/gobgp/policy.go b/gobgp/policy.go
index 61298748..e7adc5c4 100644
--- a/gobgp/policy.go
+++ b/gobgp/policy.go
@@ -197,6 +197,8 @@ func modPolicy(resource api.Resource, op api.Operation, data interface{}) error
co.MatchAsPathSet = data.(*api.AsPathSet)
case api.Resource_POLICY_COMMUNITY:
co.MatchCommunitySet = data.(*api.CommunitySet)
+ case api.Resource_POLICY_EXTCOMMUNITY:
+ co.MatchExtCommunitySet = data.(*api.ExtCommunitySet)
}
pd.StatementList = []*api.Statement{{Conditions: co}}
} else {
@@ -742,19 +744,212 @@ func modPolicyCommunity(modtype string, eArgs []string) error {
return nil
}
+func formatPolicyExtCommunity(ExtCommunitySetList []*api.ExtCommunitySet) string {
+ maxNameLen := len("Name")
+ maxCommunityLen := len("ExtCommunity")
+ for _, es := range ExtCommunitySetList {
+ if len(es.ExtCommunitySetName) > maxNameLen {
+ maxNameLen = len(es.ExtCommunitySetName)
+ }
+ for _, m := range es.ExtCommunityMembers {
+ if len(m) > maxCommunityLen {
+ maxCommunityLen = len(m)
+ }
+ }
+ }
+ format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxCommunityLen) + "s\n"
+ return format
+}
+
+func showPolicyExtCommunities() error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_EXTCOMMUNITY,
+ }
+ stream, e := client.GetPolicyRoutePolicies(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+ m := extcommunities{}
+ for {
+ a, e := stream.Recv()
+ if e == io.EOF {
+ break
+ } else if e != nil {
+ return e
+ }
+ m = append(m, a.StatementList[0].Conditions.MatchExtCommunitySet)
+ }
+ if globalOpts.Json {
+ j, _ := json.Marshal(m)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, e := range m {
+ fmt.Println(e.ExtCommunitySetName)
+ }
+ return nil
+ }
+ sort.Sort(m)
+
+ format := formatPolicyExtCommunity(m)
+ fmt.Printf(format, "Name", "ExtCommunity")
+ for _, es := range m {
+ for i, m := range es.ExtCommunityMembers {
+ if i == 0 {
+ fmt.Printf(format, es.ExtCommunitySetName, m)
+ } else {
+ fmt.Printf(format, "", m)
+ }
+ }
+ }
+ return nil
+}
+
+func showPolicyExtCommunity(args []string) error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_EXTCOMMUNITY,
+ Name: args[0],
+ }
+ pd, e := client.GetPolicyRoutePolicy(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+ es := pd.StatementList[0].Conditions.GetMatchExtCommunitySet()
+ if globalOpts.Json {
+ j, _ := json.Marshal(es)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, e := range es.ExtCommunityMembers {
+ fmt.Println(e)
+ }
+ return nil
+ }
+ format := formatPolicyExtCommunity([]*api.ExtCommunitySet{es})
+ fmt.Printf(format, "Name", "ExtCommunity")
+ for i, m := range es.ExtCommunityMembers {
+ if i == 0 {
+ fmt.Printf(format, es.ExtCommunitySetName, m)
+ } else {
+ fmt.Printf(format, "", m)
+ }
+ }
+ return nil
+}
+
+func checkExtCommunityFormat(eComStr string) bool {
+ // extended community regexp
+ checkSubType := func(eComStr string) (bool, string) {
+ regSubType, _ := regexp.Compile("^(RT|SoO):(.*)$")
+ if regSubType.MatchString(eComStr) {
+ regResult := regSubType.FindStringSubmatch(eComStr)
+ return true, regResult[2]
+ }
+ return false, ""
+ }
+ checkValue := func(eComVal string) (bool, string) {
+ regVal, _ := regexp.Compile("^([0-9\\.]+):([0-9]+)$")
+ if regVal.MatchString(eComVal) {
+ regResult := regVal.FindStringSubmatch(eComVal)
+ return true, regResult[1]
+ }
+ return false, ""
+ }
+ checkElem := func(gAdmin string) bool {
+ addr := net.ParseIP(gAdmin)
+ if addr.To4() != nil {
+ return true
+ }
+ regAs, _ := regexp.Compile("^([0-9]+)$")
+ regAs4, _ := regexp.Compile("^([0-9]+).([0-9]+)$")
+ if regAs.MatchString(gAdmin) || regAs4.MatchString(gAdmin) {
+ return true
+ }
+ return false
+ }
+
+ if subTypeOk, eComVal := checkSubType(eComStr); subTypeOk {
+ if valOk, gAdmin := checkValue(eComVal); valOk {
+ if checkElem(gAdmin) {
+ return true
+ }
+ }
+ _, err := regexp.Compile(eComVal)
+ if err == nil {
+ return true
+ }
+ }
+ return false
+}
+
+func parseExtCommunitySet(eArgs []string) (*api.ExtCommunitySet, 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
+}
+
+func modPolicyExtCommunity(modtype string, eArgs []string) error {
+ extCommunitySet := &api.ExtCommunitySet{}
+ var e error
+ var operation api.Operation
+
+ switch modtype {
+ case CMD_ADD:
+ if len(eArgs) < 2 {
+ return fmt.Errorf("usage: policy extcommunity add <community set name> <community>")
+ }
+ if extCommunitySet, e = parseExtCommunitySet(eArgs); e != nil {
+ return e
+ }
+ operation = api.Operation_ADD
+ case CMD_DEL:
+ 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,
+ }
+ } else {
+ if extCommunitySet, e = parseExtCommunitySet(eArgs); e != nil {
+ return e
+ }
+ }
+ operation = api.Operation_DEL
+ case CMD_ALL:
+ if len(eArgs) > 0 {
+ return fmt.Errorf("Argument can not be entered: %s", eArgs[0:])
+ }
+ operation = api.Operation_DEL_ALL
+ default:
+ return fmt.Errorf("invalid modType %s", modtype)
+ }
+ if e = modPolicy(api.Resource_POLICY_EXTCOMMUNITY, operation, extCommunitySet); e != nil {
+ return e
+ }
+ return nil
+}
+
func showPolicyStatement(head string, pd *api.PolicyDefinition) {
for _, st := range pd.StatementList {
fmt.Printf("%s StatementName %s:\n", head, st.StatementNeme)
fmt.Printf("%s Conditions:\n", head)
prefixSet := st.Conditions.MatchPrefixSet
- fmt.Printf("%s PrefixSet: %s ", head, prefixSet.PrefixSetName)
+ fmt.Printf("%s PrefixSet: %s ", head, prefixSet.PrefixSetName)
if len(prefixSet.PrefixList) != 0 {
nameFormat := "%-" + fmt.Sprint(len(prefixSet.PrefixSetName)+2) + "s"
_, format := formatPolicyPrefix([]*api.PrefixSet{st.Conditions.MatchPrefixSet})
for i, prefix := range prefixSet.PrefixList {
p := fmt.Sprintf("%s/%d", prefix.Address, prefix.MaskLength)
if i != 0 {
- fmt.Printf("%s ", head)
+ fmt.Printf("%s ", head)
fmt.Printf(nameFormat, "")
}
fmt.Printf(format, p, prefix.MaskLengthRange)
@@ -763,12 +958,12 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
fmt.Print("\n")
}
neighborSet := st.Conditions.MatchNeighborSet
- fmt.Printf("%s NeighborSet: %s ", head, neighborSet.NeighborSetName)
+ fmt.Printf("%s NeighborSet: %s ", head, neighborSet.NeighborSetName)
if len(neighborSet.NeighborList) != 0 {
nameFormat := "%-" + fmt.Sprint(len(neighborSet.NeighborSetName)+2) + "s"
for i, neighbor := range neighborSet.NeighborList {
if i != 0 {
- fmt.Printf("%s ", head)
+ fmt.Printf("%s ", head)
fmt.Printf(nameFormat, "")
}
fmt.Println(neighbor.Address)
@@ -777,12 +972,12 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
fmt.Print("\n")
}
asPathSet := st.Conditions.MatchAsPathSet
- fmt.Printf("%s AsPathSet: %s ", head, asPathSet.AsPathSetName)
+ fmt.Printf("%s AsPathSet: %s ", head, asPathSet.AsPathSetName)
if len(asPathSet.AsPathMembers) != 0 {
nameFormat := "%-" + fmt.Sprint(len(asPathSet.AsPathSetName)+2) + "s"
for i, asPath := range asPathSet.AsPathMembers {
if i != 0 {
- fmt.Printf("%s ", head)
+ fmt.Printf("%s ", head)
fmt.Printf(nameFormat, "")
}
fmt.Println(asPath)
@@ -791,12 +986,12 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
fmt.Print("\n")
}
communitySet := st.Conditions.MatchCommunitySet
- fmt.Printf("%s CommunitySet: %s ", head, communitySet.CommunitySetName)
+ fmt.Printf("%s CommunitySet: %s ", head, communitySet.CommunitySetName)
if len(communitySet.CommunityMembers) != 0 {
nameFormat := "%-" + fmt.Sprint(len(communitySet.CommunitySetName)+2) + "s"
for i, community := range communitySet.CommunityMembers {
if i != 0 {
- fmt.Printf("%s ", head)
+ fmt.Printf("%s ", head)
fmt.Printf(nameFormat, "")
}
fmt.Println(community)
@@ -804,9 +999,23 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
} else {
fmt.Print("\n")
}
+ extCommunitySet := st.Conditions.MatchExtCommunitySet
+ fmt.Printf("%s ExtCommunitySet: %s ", head, extCommunitySet.ExtCommunitySetName)
+ if len(extCommunitySet.ExtCommunityMembers) != 0 {
+ nameFormat := "%-" + fmt.Sprint(len(extCommunitySet.ExtCommunitySetName)+2) + "s"
+ for i, ecommunity := range extCommunitySet.ExtCommunityMembers {
+ if i != 0 {
+ fmt.Printf("%s ", head)
+ fmt.Printf(nameFormat, "")
+ }
+ fmt.Println(ecommunity)
+ }
+ } else {
+ fmt.Print("\n")
+ }
asPathLentgh := st.Conditions.MatchAsPathLength
- fmt.Printf("%s AsPathLength: %s %s\n", head, asPathLentgh.Operator, asPathLentgh.Value)
- fmt.Printf("%s MatchOption: %s\n", head, st.Conditions.MatchSetOptions)
+ fmt.Printf("%s AsPathLength: %s %s\n", head, asPathLentgh.Operator, asPathLentgh.Value)
+ fmt.Printf("%s MatchOption: %s\n", head, st.Conditions.MatchSetOptions)
fmt.Printf("%s Actions:\n", head)
communityAction := st.Actions.Community.Options
@@ -814,8 +1023,8 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
communities := strings.Join(st.Actions.Community.Communities, ",")
communityAction = fmt.Sprintf("%s[%s]", st.Actions.Community.Options, communities)
}
- fmt.Printf("%s Community: %s\n", head, communityAction)
- fmt.Printf("%s Med: %s\n", head, st.Actions.Med)
+ fmt.Printf("%s Community: %s\n", head, communityAction)
+ fmt.Printf("%s Med: %s\n", head, st.Actions.Med)
asn := ""
repeat := ""
@@ -823,7 +1032,7 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
asn = st.Actions.AsPrepend.As
repeat = fmt.Sprintf("%d", st.Actions.AsPrepend.Repeatn)
}
- fmt.Printf("%s AsPrepend: %s %s\n", head, asn, repeat)
+ fmt.Printf("%s AsPrepend: %s %s\n", head, asn, repeat)
fmt.Printf("%s %s\n", head, st.Actions.RouteAction)
}
@@ -918,6 +1127,11 @@ func parseConditions() (*api.Conditions, error) {
CommunitySetName: conditionOpts.Community,
}
}
+ if conditionOpts.ExtCommunity != "" {
+ conditions.MatchExtCommunitySet = &api.ExtCommunitySet{
+ ExtCommunitySetName: conditionOpts.ExtCommunity,
+ }
+ }
if conditionOpts.AsPathLength != "" {
asPathLen := conditionOpts.AsPathLength
idx := strings.Index(asPathLen, ",")
@@ -1163,6 +1377,7 @@ func NewPolicyAddCmd(v string, mod func(string, []string) error) *cobra.Command
policyAddCmd.Flags().StringVarP(&conditionOpts.Neighbor, "c-neighbor", "", "", "a neighbor set name of policy condition")
policyAddCmd.Flags().StringVarP(&conditionOpts.AsPath, "c-aspath", "", "", "an as path set name of policy condition")
policyAddCmd.Flags().StringVarP(&conditionOpts.Community, "c-community", "", "", "a community set name of policy condition")
+ policyAddCmd.Flags().StringVarP(&conditionOpts.ExtCommunity, "c-extcommunity", "", "", "a extended community set name of policy condition")
policyAddCmd.Flags().StringVarP(&conditionOpts.AsPathLength, "c-aslen", "", "", "an as path length of policy condition (<operator>,<numeric>)")
policyAddCmd.Flags().StringVarP(&conditionOpts.Option, "c-option", "", "", "an option of policy condition")
policyAddCmd.Flags().StringVarP(&actionOpts.RouteAction, "a-route", "", "", "a route action of policy action (accept | reject)")
@@ -1203,7 +1418,7 @@ func NewPolicyCmd() *cobra.Command {
Use: CMD_POLICY,
}
- for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ASPATH, CMD_COMMUNITY, CMD_ROUTEPOLICY} {
+ for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ASPATH, CMD_COMMUNITY, CMD_EXTCOMMUNITY, CMD_ROUTEPOLICY} {
var showAll func() error
var showOne func([]string) error
var mod func(string, []string) error
@@ -1224,6 +1439,10 @@ func NewPolicyCmd() *cobra.Command {
showAll = showPolicyCommunities
showOne = showPolicyCommunity
mod = modPolicyCommunity
+ case CMD_EXTCOMMUNITY:
+ showAll = showPolicyExtCommunities
+ showOne = showPolicyExtCommunity
+ mod = modPolicyExtCommunity
case CMD_ROUTEPOLICY:
showAll = showPolicyRoutePolicies
showOne = showPolicyRoutePolicy
diff --git a/policy/policy.go b/policy/policy.go
index 5f97e12e..0a8af9b8 100644
--- a/policy/policy.go
+++ b/policy/policy.go
@@ -725,7 +725,7 @@ func NewExtCommunityCondition(extComSetName string, defExtComSetList []config.Ex
if !matchType {
log.WithFields(log.Fields{
"Topic": "Policy",
- "Type": "Community Condition",
+ "Type": "Extended Community Condition",
}).Error("failed to parse the sub type %s.", c)
return nil
}
@@ -760,7 +760,7 @@ func NewExtCommunityCondition(extComSetName string, defExtComSetList []config.Ex
if err != nil {
log.WithFields(log.Fields{
"Topic": "Policy",
- "Type": "Community Condition",
+ "Type": "Extended Community Condition",
}).Errorf("Regular expression can't be compiled %s.", val[2])
return nil
}
@@ -891,8 +891,8 @@ func (c *ExtCommunityCondition) evaluate(path *table.Path) bool {
if matched {
log.WithFields(log.Fields{
"Topic": "Policy",
- "Condition": "Community",
- "Community": matchStr,
+ "Condition": "Extended Community",
+ "Extended Community": matchStr,
}).Debug("condition matched")
return true
@@ -1401,6 +1401,29 @@ func IndexOfCommunitySet(conCommunitySetList []config.CommunitySet, reqCommunity
return idxCommunitySet, idxCommunity
}
+// 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.ExtCommunityMembers) == 0 {
+ return idxExtCommunitySet, idxExtCommunity
+ }
+ for j, conExtCommunity := range conExtCommunitySet.ExtCommunityMembers {
+ if conExtCommunity == reqExtCommunitySet.ExtCommunityMembers[0] {
+ idxExtCommunity = j
+ return idxExtCommunitySet, idxExtCommunity
+ }
+ }
+ }
+ }
+ return idxExtCommunitySet, idxExtCommunity
+}
+
// 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
@@ -1554,6 +1577,30 @@ func CommunitySetToConfigStruct(reqCommunitySet *api.CommunitySet) (bool, config
return isCommunitySet, communitySet
}
+func ExtCommunitySetToApiStruct(es config.ExtCommunitySet) *api.ExtCommunitySet {
+ resExtCommunityMembers := make([]string, 0)
+ for _, m := range es.ExtCommunityMembers {
+ resExtCommunityMembers = append(resExtCommunityMembers, m)
+ }
+ resExtCommunitySet := &api.ExtCommunitySet{
+ ExtCommunitySetName: es.ExtCommunitySetName,
+ ExtCommunityMembers: resExtCommunityMembers,
+ }
+ return resExtCommunitySet
+}
+
+func ExtCommunitySetToConfigStruct(reqExtCommunitySet *api.ExtCommunitySet) (bool, config.ExtCommunitySet) {
+ isExtCommunitySet := true
+ if len(reqExtCommunitySet.ExtCommunityMembers) == 0 {
+ isExtCommunitySet = false
+ }
+ ExtCommunitySet := config.ExtCommunitySet{
+ ExtCommunitySetName: reqExtCommunitySet.ExtCommunitySetName,
+ ExtCommunityMembers: reqExtCommunitySet.ExtCommunityMembers,
+ }
+ return isExtCommunitySet, ExtCommunitySet
+}
+
func AsPathLengthToApiStruct(asPathLength config.AsPathLength) *api.AsPathLength {
value := ""
if asPathLength.Operator != "" {
@@ -1594,6 +1641,9 @@ func ConditionsToConfigStruct(reqConditions *api.Conditions) config.Conditions {
if reqConditions.MatchCommunitySet != nil {
conditions.BgpConditions.MatchCommunitySet = reqConditions.MatchCommunitySet.CommunitySetName
}
+ if reqConditions.MatchExtCommunitySet != nil {
+ conditions.BgpConditions.MatchExtCommunitySet = reqConditions.MatchExtCommunitySet.ExtCommunitySetName
+ }
if reqConditions.MatchAsPathLength != nil {
conditions.BgpConditions.AsPathLength =
AsPathLengthToConfigStruct(reqConditions.MatchAsPathLength)
@@ -1689,6 +1739,7 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
conNeighborSetList := df.NeighborSetList
conAsPathSetList := df.BgpDefinedSets.AsPathSetList
conCommunitySetList := df.BgpDefinedSets.CommunitySetList
+ conExtCommunitySetList := df.BgpDefinedSets.ExtCommunitySetList
resStatementList := make([]*api.Statement, 0)
for _, st := range pd.StatementList {
conditions := st.Conditions
@@ -1706,15 +1757,20 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
communitySet := &api.CommunitySet{
CommunitySetName: conditions.BgpConditions.MatchCommunitySet,
}
+ extCommunitySet := &api.ExtCommunitySet{
+ ExtCommunitySetName: conditions.BgpConditions.MatchExtCommunitySet,
+ }
// consider later whether treatment of here need
_, conPrefixSet := PrefixSetToConfigStruct(prefixSet)
_, conNeighborSet := NeighborSetToConfigStruct(neighborSet)
_, conAsPathSet := AsPathSetToConfigStruct(asPathSet)
_, conCommunitySet := CommunitySetToConfigStruct(communitySet)
+ _, conExtCommunitySet := ExtCommunitySetToConfigStruct(extCommunitySet)
idxPrefixSet, _ := IndexOfPrefixSet(conPrefixSetList, conPrefixSet)
idxNeighborSet, _ := IndexOfNeighborSet(conNeighborSetList, conNeighborSet)
idxAsPathSet, _ := IndexOfAsPathSet(conAsPathSetList, conAsPathSet)
idxCommunitySet, _ := IndexOfCommunitySet(conCommunitySetList, conCommunitySet)
+ idxExtCommunitySet, _ := IndexOfExtCommunitySet(conExtCommunitySetList, conExtCommunitySet)
if idxPrefixSet != -1 {
prefixSet = PrefixSetToApiStruct(conPrefixSetList[idxPrefixSet])
}
@@ -1727,11 +1783,15 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
if idxCommunitySet != -1 {
communitySet = CommunitySetToApiStruct(conCommunitySetList[idxCommunitySet])
}
+ if idxExtCommunitySet != -1 {
+ extCommunitySet = ExtCommunitySetToApiStruct(conExtCommunitySetList[idxExtCommunitySet])
+ }
resConditions := &api.Conditions{
MatchPrefixSet: prefixSet,
MatchNeighborSet: neighborSet,
MatchAsPathSet: asPathSet,
MatchCommunitySet: communitySet,
+ MatchExtCommunitySet: extCommunitySet,
MatchAsPathLength: AsPathLengthToApiStruct(st.Conditions.BgpConditions.AsPathLength),
MatchSetOptions: MatchSetOptionToString(conditions.MatchSetOptions),
}
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 1e81e3ce..a316ab19 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -75,6 +75,11 @@ const (
REQ_POLICY_COMMUNITY_ADD
REQ_POLICY_COMMUNITY_DELETE
REQ_POLICY_COMMUNITIES_DELETE
+ REQ_POLICY_EXTCOMMUNITY
+ REQ_POLICY_EXTCOMMUNITIES
+ REQ_POLICY_EXTCOMMUNITY_ADD
+ REQ_POLICY_EXTCOMMUNITY_DELETE
+ REQ_POLICY_EXTCOMMUNITIES_DELETE
REQ_MONITOR_GLOBAL_BEST_CHANGED
REQ_MONITOR_NEIGHBOR_PEER_STATE
)
@@ -466,6 +471,17 @@ func (s *Server) modPolicy(arg *api.PolicyArguments, stream interface{}) error {
default:
return fmt.Errorf("unsupported operation: %s", arg.Operation)
}
+ case api.Resource_POLICY_EXTCOMMUNITY:
+ switch arg.Operation {
+ case api.Operation_ADD:
+ reqType = REQ_POLICY_EXTCOMMUNITY_ADD
+ case api.Operation_DEL:
+ reqType = REQ_POLICY_EXTCOMMUNITY_DELETE
+ case api.Operation_DEL_ALL:
+ reqType = REQ_POLICY_EXTCOMMUNITIES_DELETE
+ default:
+ return fmt.Errorf("unsupported operation: %s", arg.Operation)
+ }
case api.Resource_POLICY_ROUTEPOLICY:
switch arg.Operation {
case api.Operation_ADD:
@@ -509,6 +525,8 @@ func (s *Server) GetPolicyRoutePolicies(arg *api.PolicyArguments, stream api.Grp
reqType = REQ_POLICY_ASPATHS
case api.Resource_POLICY_COMMUNITY:
reqType = REQ_POLICY_COMMUNITIES
+ case api.Resource_POLICY_EXTCOMMUNITY:
+ reqType = REQ_POLICY_EXTCOMMUNITIES
case api.Resource_POLICY_ROUTEPOLICY:
reqType = REQ_POLICY_ROUTEPOLICIES
default:
@@ -540,6 +558,8 @@ func (s *Server) GetPolicyRoutePolicy(ctx context.Context, arg *api.PolicyArgume
reqType = REQ_POLICY_ASPATH
case api.Resource_POLICY_COMMUNITY:
reqType = REQ_POLICY_COMMUNITY
+ case api.Resource_POLICY_EXTCOMMUNITY:
+ reqType = REQ_POLICY_EXTCOMMUNITY
case api.Resource_POLICY_ROUTEPOLICY:
reqType = REQ_POLICY_ROUTEPOLICY
default:
diff --git a/server/server.go b/server/server.go
index e0b0dcef..78dd3b80 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1219,19 +1219,19 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
close(grpcReq.ResponseCh)
case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ASPATHS,
- REQ_POLICY_COMMUNITIES, REQ_POLICY_ROUTEPOLICIES:
+ REQ_POLICY_COMMUNITIES, REQ_POLICY_EXTCOMMUNITIES, REQ_POLICY_ROUTEPOLICIES:
server.handleGrpcShowPolicies(grpcReq)
case REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH,
- REQ_POLICY_COMMUNITY, REQ_POLICY_ROUTEPOLICY:
+ REQ_POLICY_COMMUNITY, REQ_POLICY_EXTCOMMUNITY, REQ_POLICY_ROUTEPOLICY:
server.handleGrpcShowPolicy(grpcReq)
case REQ_POLICY_PREFIX_ADD, REQ_POLICY_NEIGHBOR_ADD, REQ_POLICY_ASPATH_ADD,
- REQ_POLICY_COMMUNITY_ADD, REQ_POLICY_ROUTEPOLICY_ADD:
+ REQ_POLICY_COMMUNITY_ADD, REQ_POLICY_EXTCOMMUNITY_ADD, REQ_POLICY_ROUTEPOLICY_ADD:
server.handleGrpcAddPolicy(grpcReq)
case REQ_POLICY_PREFIX_DELETE, REQ_POLICY_NEIGHBOR_DELETE, REQ_POLICY_ASPATH_DELETE,
- REQ_POLICY_COMMUNITY_DELETE, REQ_POLICY_ROUTEPOLICY_DELETE:
+ REQ_POLICY_COMMUNITY_DELETE, REQ_POLICY_EXTCOMMUNITY_DELETE, REQ_POLICY_ROUTEPOLICY_DELETE:
server.handleGrpcDelPolicy(grpcReq)
case REQ_POLICY_PREFIXES_DELETE, REQ_POLICY_NEIGHBORS_DELETE, REQ_POLICY_ASPATHS_DELETE,
- REQ_POLICY_COMMUNITIES_DELETE, REQ_POLICY_ROUTEPOLICIES_DELETE:
+ REQ_POLICY_COMMUNITIES_DELETE, REQ_POLICY_EXTCOMMUNITIES_DELETE, REQ_POLICY_ROUTEPOLICIES_DELETE:
server.handleGrpcDelPolicies(grpcReq)
case REQ_MONITOR_GLOBAL_BEST_CHANGED, REQ_MONITOR_NEIGHBOR_PEER_STATE:
server.broadcastReqs = append(server.broadcastReqs, grpcReq)
@@ -1313,6 +1313,22 @@ func (server *BgpServer) handleGrpcShowPolicies(grpcReq *GrpcRequest) {
result.ResponseErr = fmt.Errorf("Policy community doesn't exist.")
grpcReq.ResponseCh <- result
}
+ case REQ_POLICY_EXTCOMMUNITIES:
+ info := server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList
+ if len(info) > 0 {
+ for _, es := range info {
+ resExtcommunitySet := policy.ExtCommunitySetToApiStruct(es)
+ pd := &api.PolicyDefinition{}
+ pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchExtCommunitySet: resExtcommunitySet}}}
+ result = &GrpcResponse{
+ Data: pd,
+ }
+ grpcReq.ResponseCh <- result
+ }
+ } else {
+ result.ResponseErr = fmt.Errorf("Policy extended community doesn't exist.")
+ grpcReq.ResponseCh <- result
+ }
case REQ_POLICY_ROUTEPOLICIES:
info := server.routingPolicy.PolicyDefinitionList
df := server.routingPolicy.DefinedSets
@@ -1408,8 +1424,25 @@ func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
} else {
result.ResponseErr = fmt.Errorf("policy community that has %v doesn't exist.", name)
}
+ case REQ_POLICY_EXTCOMMUNITY:
+ info := server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList
+ resExtCommunitySet := &api.ExtCommunitySet{}
+ for _, es := range info {
+ if es.ExtCommunitySetName == name {
+ resExtCommunitySet = policy.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:
- log.Error("IN RoutePolicy")
info := server.routingPolicy.PolicyDefinitionList
df := server.routingPolicy.DefinedSets
resPolicyDefinition := &api.PolicyDefinition{}
@@ -1419,7 +1452,6 @@ func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
break
}
}
- log.Error("IN RoutePolicy: ", len(resPolicyDefinition.StatementList))
if len(resPolicyDefinition.StatementList) > 0 {
result = &GrpcResponse{
Data: resPolicyDefinition,
@@ -1486,8 +1518,8 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
}
- // If the same NeighborSet is not set, add NeighborSet of request to the end.
- // If only name of the NeighborSet is same, overwrite with NeighborSet of request
+ // If the same AsPathSet is not set, add AsPathSet of request to the end.
+ // If only name of the AsPathSet is same, overwrite with AsPathSet of request
idxAsPathSet, idxAsPath := policy.IndexOfAsPathSet(conAsPathSetList, asPathSet)
if idxAsPathSet == -1 {
conAsPathSetList = append(conAsPathSetList, asPathSet)
@@ -1507,8 +1539,8 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
}
- // If the same NeighborSet is not set, add NeighborSet of request to the end.
- // If only name of the NeighborSet is same, overwrite with NeighborSet of request
+ // If the same CommunitySet is not set, add CommunitySet of request to the end.
+ // If only name of the CommunitySet is same, overwrite with CommunitySet of request
idxCommunitySet, idxCommunity := policy.IndexOfCommunitySet(conCommunitySetList, communitySet)
if idxCommunitySet == -1 {
conCommunitySetList = append(conCommunitySetList, communitySet)
@@ -1519,6 +1551,27 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
}
}
server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList = conCommunitySetList
+ case REQ_POLICY_EXTCOMMUNITY_ADD:
+ reqExtCommunitySet := grpcReq.Data.(*api.PolicyDefinition).StatementList[0].Conditions.MatchExtCommunitySet
+ conExtCommunitySetList := server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList
+ isReqExtCommunitySet, extCommunitySet := policy.ExtCommunitySetToConfigStruct(reqExtCommunitySet)
+ if !isReqExtCommunitySet {
+ result.ResponseErr = fmt.Errorf("doesn't reqest of policy extended community.")
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ }
+ // If the same ExtCommunitySet is not set, add ExtCommunitySet of request to the end.
+ // If only name of the ExtCommunitySet is same, overwrite with ExtCommunitySet of request
+ idxExtCommunitySet, idxExtCommunity := policy.IndexOfExtCommunitySet(conExtCommunitySetList, extCommunitySet)
+ if idxExtCommunitySet == -1 {
+ conExtCommunitySetList = append(conExtCommunitySetList, extCommunitySet)
+ } else {
+ if idxExtCommunity == -1 {
+ conExtCommunitySetList[idxExtCommunitySet].ExtCommunityMembers =
+ append(conExtCommunitySetList[idxExtCommunitySet].ExtCommunityMembers, extCommunitySet.ExtCommunityMembers[0])
+ }
+ }
+ server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList = conExtCommunitySetList
case REQ_POLICY_ROUTEPOLICY_ADD:
reqPolicy := grpcReq.Data.(*api.PolicyDefinition)
reqConditions := reqPolicy.StatementList[0].Conditions
@@ -1550,6 +1603,9 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
if reqConditions.MatchCommunitySet != nil {
conStatement.Conditions.BgpConditions.MatchCommunitySet = statement.Conditions.BgpConditions.MatchCommunitySet
}
+ if reqConditions.MatchExtCommunitySet != nil {
+ conStatement.Conditions.BgpConditions.MatchExtCommunitySet = statement.Conditions.BgpConditions.MatchExtCommunitySet
+ }
if reqConditions.MatchAsPathLength != nil {
conStatement.Conditions.BgpConditions.AsPathLength = statement.Conditions.BgpConditions.AsPathLength
}
@@ -1563,7 +1619,7 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
if reqActions.Med != "" {
conStatement.Actions.BgpActions.SetMed = statement.Actions.BgpActions.SetMed
}
- if reqActions.AsPrepend.As != "" {
+ if reqActions.AsPrepend != nil {
conStatement.Actions.BgpActions.SetAsPathPrepend = statement.Actions.BgpActions.SetAsPathPrepend
}
}
@@ -1655,8 +1711,8 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
conAsPathSetList := server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList
result := &GrpcResponse{}
isReqAsPathSet, asPathSet := policy.AsPathSetToConfigStruct(reqAsPathSet)
- // If only name of the NeighborSet is same, delete all of the elements of the NeighborSet.
- // If the same element NeighborSet, delete the it's element from NeighborSet.
+ // If only name of the AsPathSet is same, delete all of the elements of the AsPathSet.
+ // If the same element AsPathSet, delete the it's element from AsPathSet.
idxAsPathSet, idxAsPath := policy.IndexOfAsPathSet(conAsPathSetList, asPathSet)
if isReqAsPathSet {
if idxAsPathSet == -1 {
@@ -1684,16 +1740,16 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
reqCommunitySet := grpcReq.Data.(*api.PolicyDefinition).StatementList[0].Conditions.MatchCommunitySet
conCommunitySetList := server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList
isReqCommunitySet, CommunitySet := policy.CommunitySetToConfigStruct(reqCommunitySet)
- // If only name of the NeighborSet is same, delete all of the elements of the NeighborSet.
- // If the same element NeighborSet, delete the it's element from NeighborSet.
+ // If only name of the CommunitySet is same, delete all of the elements of the CommunitySet.
+ // If the same element CommunitySet, delete the it's element from CommunitySet.
idxCommunitySet, idxCommunity := policy.IndexOfCommunitySet(conCommunitySetList, CommunitySet)
if isReqCommunitySet {
if idxCommunitySet == -1 {
- result.ResponseErr = fmt.Errorf("Policy aspath that has %v %v doesn't exist.", CommunitySet.CommunitySetName,
+ result.ResponseErr = fmt.Errorf("Policy community that has %v %v doesn't exist.", CommunitySet.CommunitySetName,
CommunitySet.CommunityMembers[0])
} else {
if idxCommunity == -1 {
- result.ResponseErr = fmt.Errorf("Policy aspath that has %v %v doesn't exist.", CommunitySet.CommunitySetName,
+ result.ResponseErr = fmt.Errorf("Policy community that has %v %v doesn't exist.", CommunitySet.CommunitySetName,
CommunitySet.CommunityMembers[0])
} else {
conCommunitySetList[idxCommunitySet].CommunityMembers =
@@ -1703,18 +1759,48 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
}
} else {
if idxCommunitySet == -1 {
- result.ResponseErr = fmt.Errorf("Policy aspath %v doesn't exist.", CommunitySet.CommunitySetName)
+ result.ResponseErr = fmt.Errorf("Policy community %v doesn't exist.", CommunitySet.CommunitySetName)
} else {
conCommunitySetList = append(conCommunitySetList[:idxCommunitySet], conCommunitySetList[idxCommunitySet+1:]...)
}
}
server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList = conCommunitySetList
+ case REQ_POLICY_EXTCOMMUNITY_DELETE:
+ reqExtCommunitySet := grpcReq.Data.(*api.PolicyDefinition).StatementList[0].Conditions.MatchExtCommunitySet
+ conExtCommunitySetList := server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList
+ isReqExtCommunitySet, ExtCommunitySet := policy.ExtCommunitySetToConfigStruct(reqExtCommunitySet)
+ // If only name of the ExtCommunitySet is same, delete all of the elements of the ExtCommunitySet.
+ // If the same element ExtCommunitySet, delete the it's element from ExtCommunitySet.
+ idxExtCommunitySet, idxExtCommunity := policy.IndexOfExtCommunitySet(conExtCommunitySetList, ExtCommunitySet)
+ if isReqExtCommunitySet {
+ if idxExtCommunitySet == -1 {
+ result.ResponseErr = fmt.Errorf("Policy extended community that has %v %v doesn't exist.",
+ ExtCommunitySet.ExtCommunitySetName, ExtCommunitySet.ExtCommunityMembers[0])
+ } else {
+ if idxExtCommunity == -1 {
+ result.ResponseErr = fmt.Errorf("Policy extended community that has %v %v doesn't exist.",
+ ExtCommunitySet.ExtCommunitySetName, ExtCommunitySet.ExtCommunityMembers[0])
+ } else {
+ conExtCommunitySetList[idxExtCommunitySet].ExtCommunityMembers =
+ append(conExtCommunitySetList[idxExtCommunitySet].ExtCommunityMembers[:idxExtCommunity],
+ conExtCommunitySetList[idxExtCommunitySet].ExtCommunityMembers[idxExtCommunity+1:]...)
+ }
+ }
+ } else {
+ if idxExtCommunitySet == -1 {
+ result.ResponseErr = fmt.Errorf("Policy extended community %v doesn't exist.",
+ ExtCommunitySet.ExtCommunitySetName)
+ } else {
+ conExtCommunitySetList =
+ append(conExtCommunitySetList[:idxExtCommunitySet], conExtCommunitySetList[idxExtCommunitySet+1:]...)
+ }
+ }
+ server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList = conExtCommunitySetList
case REQ_POLICY_ROUTEPOLICY_DELETE:
reqPolicy := grpcReq.Data.(*api.PolicyDefinition)
conPolicyList := server.routingPolicy.PolicyDefinitionList
isStatement, policyDef := policy.PolicyDefinitionToConfigStruct(reqPolicy)
idxPolicy, idxStatement := policy.IndexOfPolicyDefinition(conPolicyList, policyDef)
- log.Error(fmt.Sprintf("isStatament=%v, idxPolicy=%d, idxStatement=%d", isStatement, idxPolicy, idxStatement))
if isStatement {
if idxPolicy == -1 {
result.ResponseErr = fmt.Errorf("Policy that has %v doesn't exist.", policyDef.Name)
@@ -1758,6 +1844,8 @@ func (server *BgpServer) handleGrpcDelPolicies(grpcReq *GrpcRequest) {
server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList = make([]config.AsPathSet, 0)
case REQ_POLICY_COMMUNITIES_DELETE:
server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList = make([]config.CommunitySet, 0)
+ case REQ_POLICY_EXTCOMMUNITIES_DELETE:
+ server.routingPolicy.DefinedSets.BgpDefinedSets.ExtCommunitySetList = make([]config.ExtCommunitySet, 0)
case REQ_POLICY_ROUTEPOLICIES_DELETE:
server.routingPolicy.PolicyDefinitionList = make([]config.PolicyDefinition, 0)
}
diff --git a/test/scenario_test/policy/policy_generator.go b/test/scenario_test/policy/policy_generator.go
index 9b35c5aa..5e2308d4 100644
--- a/test/scenario_test/policy/policy_generator.go
+++ b/test/scenario_test/policy/policy_generator.go
@@ -208,11 +208,11 @@ func createPolicyConfig() *config.RoutingPolicy {
CommunityMembers: []string{"6[0-9]+:[0-9]+"},
}
eComOrigin := config.ExtCommunitySet{
- ExtCommunitySetName: "eComAS4",
+ ExtCommunitySetName: "eComOrigin",
ExtCommunityMembers: []string{"SoO:65001.65100:200"},
}
eComTarget := config.ExtCommunitySet{
- ExtCommunitySetName: "eComRegExp",
+ ExtCommunitySetName: "eComTarget",
ExtCommunityMembers: []string{"RT:6[0-9]+:3[0-9]+"},
}