summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNaoto Hanaue <hanaue.naoto@po.ntts.co.jp>2015-06-16 19:55:34 +0900
committerNaoto Hanaue <hanaue.naoto@po.ntts.co.jp>2015-06-17 13:41:31 +0900
commit3f845ad08fbc24e2db2eb8572a2955091853e3bf (patch)
tree7a1fbef89611621ab864f0b840961eb7013d3833
parent4db834afe35306ede35a73aeb4486844da264920 (diff)
cli: add community subcommand to policy conditions and actions
-rw-r--r--api/gobgp.pb.go49
-rw-r--r--api/gobgp.proto17
-rw-r--r--gobgp/common.go19
-rw-r--r--gobgp/neighbor.go12
-rw-r--r--gobgp/policy.go280
-rw-r--r--policy/policy.go111
-rw-r--r--server/grpc_server.go22
-rw-r--r--server/server.go166
8 files changed, 591 insertions, 85 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 32ace22d..060aaa68 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -38,7 +38,9 @@ It has these top-level messages:
NeighborSet
AsPathLength
AsPathSet
+ CommunitySet
Conditions
+ CommunityAction
Actions
Statement
PolicyDefinition
@@ -70,7 +72,8 @@ const (
Resource_POLICY_PREFIX Resource = 4
Resource_POLICY_NEIGHBOR Resource = 5
Resource_POLICY_ASPATH Resource = 6
- Resource_POLICY_ROUTEPOLICY Resource = 7
+ Resource_POLICY_COMMUNITY Resource = 7
+ Resource_POLICY_ROUTEPOLICY Resource = 8
)
var Resource_name = map[int32]string{
@@ -81,7 +84,8 @@ var Resource_name = map[int32]string{
4: "POLICY_PREFIX",
5: "POLICY_NEIGHBOR",
6: "POLICY_ASPATH",
- 7: "POLICY_ROUTEPOLICY",
+ 7: "POLICY_COMMUNITY",
+ 8: "POLICY_ROUTEPOLICY",
}
var Resource_value = map[string]int32{
"GLOBAL": 0,
@@ -91,7 +95,8 @@ var Resource_value = map[string]int32{
"POLICY_PREFIX": 4,
"POLICY_NEIGHBOR": 5,
"POLICY_ASPATH": 6,
- "POLICY_ROUTEPOLICY": 7,
+ "POLICY_COMMUNITY": 7,
+ "POLICY_ROUTEPOLICY": 8,
}
func (x Resource) String() string {
@@ -1007,12 +1012,22 @@ 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"`
+}
+
+func (m *CommunitySet) Reset() { *m = CommunitySet{} }
+func (m *CommunitySet) String() string { return proto.CompactTextString(m) }
+func (*CommunitySet) 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"`
- MatchSetOptions string `protobuf:"bytes,5,opt,name=match_set_options" json:"match_set_options,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"`
}
func (m *Conditions) Reset() { *m = Conditions{} }
@@ -1047,14 +1062,38 @@ func (m *Conditions) GetMatchAsPathSet() *AsPathSet {
return nil
}
+func (m *Conditions) GetMatchCommunitySet() *CommunitySet {
+ if m != nil {
+ return m.MatchCommunitySet
+ }
+ 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"`
+}
+
+func (m *CommunityAction) Reset() { *m = CommunityAction{} }
+func (m *CommunityAction) String() string { return proto.CompactTextString(m) }
+func (*CommunityAction) ProtoMessage() {}
+
type Actions struct {
- RouteAction string `protobuf:"bytes,1,opt,name=route_action" json:"route_action,omitempty"`
+ RouteAction string `protobuf:"bytes,1,opt,name=route_action" json:"route_action,omitempty"`
+ Community *CommunityAction `protobuf:"bytes,2,opt,name=community" json:"community,omitempty"`
}
func (m *Actions) Reset() { *m = Actions{} }
func (m *Actions) String() string { return proto.CompactTextString(m) }
func (*Actions) ProtoMessage() {}
+func (m *Actions) GetCommunity() *CommunityAction {
+ if m != nil {
+ return m.Community
+ }
+ return nil
+}
+
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"`
diff --git a/api/gobgp.proto b/api/gobgp.proto
index e61c2243..b4beb1c2 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -76,7 +76,8 @@ enum Resource {
POLICY_PREFIX = 4;
POLICY_NEIGHBOR = 5;
POLICY_ASPATH = 6;
- POLICY_ROUTEPOLICY = 7;
+ POLICY_COMMUNITY = 7;
+ POLICY_ROUTEPOLICY = 8;
}
enum Operation {
@@ -379,16 +380,28 @@ message AsPathSet {
repeated string as_path_members = 2;
}
+message CommunitySet {
+ string community_set_name = 1;
+ repeated string community_members = 2;
+}
+
message Conditions {
PrefixSet match_prefix_set = 1;
NeighborSet match_neighbor_set = 2;
AsPathLength match_as_path_length = 3;
AsPathSet match_as_path_set = 4;
- string match_set_options = 5;
+ CommunitySet match_community_set = 5;
+ string match_set_options = 6;
+}
+
+message CommunityAction {
+ repeated string communities = 1;
+ string options = 2;
}
message Actions {
string route_action = 1;
+ CommunityAction community = 2;
}
message Statement {
diff --git a/gobgp/common.go b/gobgp/common.go
index 1d47ea1e..d7d9e2c4 100644
--- a/gobgp/common.go
+++ b/gobgp/common.go
@@ -46,6 +46,7 @@ const (
CMD_DISABLE = "disable"
CMD_PREFIX = "prefix"
CMD_ASPATH = "aspath"
+ CMD_COMMUNITY = "community"
CMD_ROUTEPOLICY = "routepolicy"
CMD_CONDITIONS = "conditions"
CMD_ACTIONS = "actions"
@@ -65,12 +66,14 @@ var conditionOpts struct {
Prefix string `long:"prefix" description:"specifying a prefix set name of policy"`
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"`
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)"`
}
var actionOpts struct {
- RouteAction string `long:"route-action" description:"specifying a route action of policy (accept | reject)"`
+ RouteAction string `long:"route-action" description:"specifying a route action of policy (accept | reject)"`
+ CommunityAction string `long:"community" description:"specifying a community action of policy"`
}
func formatTimedelta(d int64) string {
@@ -213,6 +216,20 @@ func (a aspaths) Less(i, j int) bool {
return a[i].AsPathSetName < a[j].AsPathSetName
}
+type communities []*api.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 policyDefinitions []*api.PolicyDefinition
func (p policyDefinitions) Len() int {
diff --git a/gobgp/neighbor.go b/gobgp/neighbor.go
index ed060fd2..8d311f9b 100644
--- a/gobgp/neighbor.go
+++ b/gobgp/neighbor.go
@@ -535,18 +535,6 @@ func showNeighborPolicy(remoteIP net.IP) error {
return nil
}
-func parseRouteAction(rType string) (string, error) {
- routeActionUpper := strings.ToUpper(rType)
- var routeAction string
- switch routeActionUpper {
- case policy.ROUTE_ACCEPT, policy.ROUTE_REJECT:
- routeAction = routeActionUpper
- default:
- return "", fmt.Errorf("invalid route action: %s\nPlease enter the accept or reject", rType)
- }
- return routeAction, nil
-}
-
func parsePolicy(pNames string) []*api.PolicyDefinition {
pList := strings.Split(pNames, ",")
policyList := make([]*api.PolicyDefinition, 0, len(pList))
diff --git a/gobgp/policy.go b/gobgp/policy.go
index 1939a12d..1c76edbd 100644
--- a/gobgp/policy.go
+++ b/gobgp/policy.go
@@ -24,10 +24,10 @@ import (
"golang.org/x/net/context"
"io"
"net"
+ "regexp"
"sort"
"strconv"
"strings"
- "regexp"
)
func formatPolicyPrefix(prefixSetList []*api.PrefixSet) (string, string) {
@@ -195,6 +195,8 @@ func modPolicy(resource api.Resource, op api.Operation, data interface{}) error
co.MatchNeighborSet = data.(*api.NeighborSet)
case api.Resource_POLICY_ASPATH:
co.MatchAsPathSet = data.(*api.AsPathSet)
+ case api.Resource_POLICY_COMMUNITY:
+ co.MatchCommunitySet = data.(*api.CommunitySet)
}
pd.StatementList = []*api.Statement{{Conditions: co}}
} else {
@@ -443,7 +445,6 @@ func formatPolicyAsPath(asPathSetList []*api.AsPathSet) string {
return format
}
-
func showPolicyAsPaths() error {
arg := &api.PolicyArguments{
Resource: api.Resource_POLICY_ASPATH,
@@ -576,6 +577,171 @@ func modPolicyAsPath(modtype string, eArgs []string) error {
return nil
}
+func formatPolicyCommunity(CommunitySetList []*api.CommunitySet) string {
+ maxNameLen := len("Name")
+ maxCommunityLen := len("Community")
+ for _, cs := range CommunitySetList {
+ if len(cs.CommunitySetName) > maxNameLen {
+ maxNameLen = len(cs.CommunitySetName)
+ }
+ for _, m := range cs.CommunityMembers {
+ if len(m) > maxCommunityLen {
+ maxCommunityLen = len(m)
+ }
+ }
+ }
+ format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxCommunityLen) + "s\n"
+ return format
+}
+
+func showPolicyCommunities() error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_COMMUNITY,
+ }
+ stream, e := client.GetPolicyRoutePolicies(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+ m := communities{}
+ for {
+ a, e := stream.Recv()
+ if e == io.EOF {
+ break
+ } else if e != nil {
+ return e
+ }
+ m = append(m, a.StatementList[0].Conditions.MatchCommunitySet)
+ }
+ if globalOpts.Json {
+ j, _ := json.Marshal(m)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, c := range m {
+ fmt.Println(c.CommunitySetName)
+ }
+ return nil
+ }
+ sort.Sort(m)
+
+ format := formatPolicyCommunity(m)
+ fmt.Printf(format, "Name", "Community")
+ for _, cs := range m {
+ for i, m := range cs.CommunityMembers {
+ if i == 0 {
+ fmt.Printf(format, cs.CommunitySetName, m)
+ } else {
+ fmt.Printf(format, "", m)
+ }
+ }
+ }
+ return nil
+}
+
+func showPolicyCommunity(args []string) error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_COMMUNITY,
+ Name: args[0],
+ }
+ pd, e := client.GetPolicyRoutePolicy(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+ cs := pd.StatementList[0].Conditions.GetMatchCommunitySet()
+ if globalOpts.Json {
+ j, _ := json.Marshal(cs)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, c := range cs.CommunityMembers {
+ fmt.Println(c)
+ }
+ return nil
+ }
+ format := formatPolicyCommunity([]*api.CommunitySet{cs})
+ fmt.Printf(format, "Name", "Community")
+ for i, m := range cs.CommunityMembers {
+ if i == 0 {
+ fmt.Printf(format, cs.CommunitySetName, m)
+ } else {
+ fmt.Printf(format, "", m)
+ }
+ }
+ return nil
+}
+
+func checkCommunityFormat(comStr string) bool {
+ // community regexp
+ regUint, _ := regexp.Compile("^([0-9]+)$")
+ regString, _ := regexp.Compile("([0-9]+):([0-9]+)")
+ regWellKnown, _ := regexp.Compile("^(" +
+ policy.COMMUNITY_INTERNET + "|" +
+ policy.COMMUNITY_NO_EXPORT + "|" +
+ policy.COMMUNITY_NO_ADVERTISE + "|" +
+ policy.COMMUNITY_NO_EXPORT_SUBCONFED + ")$")
+ if regUint.MatchString(comStr) || regString.MatchString(comStr) || regWellKnown.MatchString(comStr) {
+ return true
+ }
+ return false
+}
+
+func parseCommunitySet(eArgs []string) (*api.CommunitySet, 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]},
+ }
+ return communitySet, nil
+}
+
+func modPolicyCommunity(modtype string, eArgs []string) error {
+ communitySet := &api.CommunitySet{}
+ var e error
+ var operation api.Operation
+
+ switch modtype {
+ case CMD_ADD:
+ if len(eArgs) < 2 {
+ return fmt.Errorf("usage: policy community add <community set name> <community>")
+ }
+ if communitySet, e = parseCommunitySet(eArgs); e != nil {
+ return e
+ }
+ operation = api.Operation_ADD
+ case CMD_DEL:
+ 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,
+ }
+ } else {
+ if communitySet, e = parseCommunitySet(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_COMMUNITY, operation, communitySet); 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)
@@ -624,10 +790,31 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
} else {
fmt.Print("\n")
}
+ communitySet := st.Conditions.MatchCommunitySet
+ 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(nameFormat, "")
+ }
+ fmt.Println(community)
+ }
+ } 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 Actions:\n", head)
+
+ communityAction := st.Actions.Community.Options
+ if len(st.Actions.Community.Communities) != 0 || st.Actions.Community.Options == "NULL" {
+ 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 %s\n", head, st.Actions.RouteAction)
}
@@ -717,6 +904,11 @@ func parseConditions() (*api.Conditions, error) {
AsPathSetName: conditionOpts.AsPath,
}
}
+ if conditionOpts.Community != "" {
+ conditions.MatchCommunitySet = &api.CommunitySet{
+ CommunitySetName: conditionOpts.Community,
+ }
+ }
if conditionOpts.AsPathLength != "" {
asPathLen := conditionOpts.AsPathLength
idx := strings.Index(asPathLen, ",")
@@ -748,6 +940,64 @@ func parseConditions() (*api.Conditions, error) {
return conditions, nil
}
+func parseRouteAction(rType string) (string, error) {
+ routeActionUpper := strings.ToUpper(rType)
+ var routeAction string
+ switch routeActionUpper {
+ case policy.ROUTE_ACCEPT, policy.ROUTE_REJECT:
+ routeAction = routeActionUpper
+ default:
+ return "", fmt.Errorf("invalid route action: %s\nPlease enter the accept or reject", rType)
+ }
+ return routeAction, nil
+}
+
+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 := policy.COMMUNITY_ACTION_ADD + "|" +
+ policy.COMMUNITY_ACTION_REPLACE + "|" +
+ policy.COMMUNITY_ACTION_REMOVE + "|" +
+ policy.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 {
+ 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,
+ }
+ return communityAction, nil
+}
+
func parseActions() (*api.Actions, error) {
actions := &api.Actions{}
if actionOpts.RouteAction != "" {
@@ -757,6 +1007,14 @@ func parseActions() (*api.Actions, error) {
}
actions.RouteAction = routeAction
}
+ if actionOpts.CommunityAction != "" {
+ community, e := parseCommunityAction(actionOpts.CommunityAction)
+ if e != nil {
+ return nil, e
+ }
+
+ actions.Community = community
+ }
return actions, nil
}
@@ -772,18 +1030,18 @@ func modPolicyRoutePolicy(modtype string, eArgs []string) error {
if len(eArgs) != 2 {
return fmt.Errorf("usage: gobgp policy routepoilcy add <route policy name> <statement name>")
}
- stmt := &api.Statement{}
+ stmt := &api.Statement{
+ StatementNeme: eArgs[1],
+ }
conditions, err := parseConditions()
if err != nil {
return err
}
- stmt.Conditions = conditions
-
actions, err := parseActions()
if err != nil {
return err
}
- stmt.StatementNeme = eArgs[1]
+ stmt.Conditions = conditions
stmt.Actions = actions
pd.StatementList = []*api.Statement{stmt}
@@ -828,10 +1086,12 @@ func NewPolicyAddCmd(v string, mod func(string, []string) error) *cobra.Command
if v == CMD_ROUTEPOLICY {
policyAddCmd.Flags().StringVarP(&conditionOpts.Prefix, "c-prefix", "", "", "a prefix set name of policy condition")
policyAddCmd.Flags().StringVarP(&conditionOpts.Neighbor, "c-neighbor", "", "", "a neighbor set name of policy condition")
- policyAddCmd.Flags().StringVarP(&conditionOpts.Neighbor, "c-aspath", "", "", "as 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.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)")
+ policyAddCmd.Flags().StringVarP(&actionOpts.CommunityAction, "a-community", "", "", "a community of policy action")
}
return policyAddCmd
@@ -866,7 +1126,7 @@ func NewPolicyCmd() *cobra.Command {
Use: CMD_POLICY,
}
- for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ASPATH, CMD_ROUTEPOLICY} {
+ for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ASPATH, CMD_COMMUNITY, CMD_ROUTEPOLICY} {
var showAll func() error
var showOne func([]string) error
var mod func(string, []string) error
@@ -883,6 +1143,10 @@ func NewPolicyCmd() *cobra.Command {
showAll = showPolicyAsPaths
showOne = showPolicyAsPath
mod = modPolicyAsPath
+ case CMD_COMMUNITY:
+ showAll = showPolicyCommunities
+ showOne = showPolicyCommunity
+ mod = modPolicyCommunity
case CMD_ROUTEPOLICY:
showAll = showPolicyRoutePolicies
showOne = showPolicyRoutePolicy
diff --git a/policy/policy.go b/policy/policy.go
index 27dc3c53..942aa70f 100644
--- a/policy/policy.go
+++ b/policy/policy.go
@@ -353,9 +353,9 @@ func (c *AsPathLengthCondition) evaluate(path table.Path) bool {
if result {
log.WithFields(log.Fields{
- "Topic": "Policy",
+ "Topic": "Policy",
"Condition": "aspath length",
- "Reason": c.Operator,
+ "Reason": c.Operator,
}).Debug("condition matched")
}
@@ -473,10 +473,10 @@ func (c *AsPathCondition) evaluate(path table.Path) bool {
if matched {
log.WithFields(log.Fields{
- "Topic": "Policy",
+ "Topic": "Policy",
"Condition": "aspath length",
- "ASN": member.asn,
- "Position": member.postiion,
+ "ASN": member.asn,
+ "Position": member.postiion,
}).Debug("condition matched")
return true
}
@@ -665,7 +665,7 @@ func (c *CommunityCondition) evaluate(path table.Path) bool {
if matched {
log.WithFields(log.Fields{
- "Topic": "Policy",
+ "Topic": "Policy",
"Condition": "Community",
"Community": makeStr(communities[idx]),
}).Debug("condition matched")
@@ -729,7 +729,7 @@ func NewCommunityAction(action config.SetCommunity) *CommunityAction {
m := &CommunityAction{}
- if len(action.Communities) == 0 && action.Options != COMMUNITY_ACTION_NULL{
+ if len(action.Communities) == 0 && action.Options != COMMUNITY_ACTION_NULL {
return nil
}
@@ -1009,6 +1009,29 @@ func IndexOfAsPathSet(conAsPathSetList []config.AsPathSet, reqAsPathSet config.A
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.CommunityMembers) == 0 {
+ return idxCommunitySet, idxCommunity
+ }
+ for j, conCommunity := range conCommunitySet.CommunityMembers {
+ if conCommunity == reqCommunitySet.CommunityMembers[0] {
+ idxCommunity = j
+ return idxCommunitySet, idxCommunity
+ }
+ }
+ }
+ }
+ return idxCommunitySet, idxCommunity
+}
+
// 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
@@ -1138,6 +1161,30 @@ func AsPathSetToConfigStruct(reqAsPathSet *api.AsPathSet) (bool, config.AsPathSe
return isAsPathSetSet, asPathSet
}
+func CommunitySetToApiStruct(cs config.CommunitySet) *api.CommunitySet {
+ resCommunityMembers := make([]string, 0)
+ for _, m := range cs.CommunityMembers {
+ resCommunityMembers = append(resCommunityMembers, m)
+ }
+ resCommunitySet := &api.CommunitySet{
+ CommunitySetName: cs.CommunitySetName,
+ CommunityMembers: resCommunityMembers,
+ }
+ return resCommunitySet
+}
+
+func CommunitySetToConfigStruct(reqCommunitySet *api.CommunitySet) (bool, config.CommunitySet) {
+ isCommunitySet := true
+ if len(reqCommunitySet.CommunityMembers) == 0 {
+ isCommunitySet = false
+ }
+ communitySet := config.CommunitySet{
+ CommunitySetName: reqCommunitySet.CommunitySetName,
+ CommunityMembers: reqCommunitySet.CommunityMembers,
+ }
+ return isCommunitySet, communitySet
+}
+
func AsPathLengthToApiStruct(asPathLength config.AsPathLength) *api.AsPathLength {
value := ""
if asPathLength.Operator != "" {
@@ -1172,6 +1219,9 @@ func ConditionsToConfigStruct(reqConditions *api.Conditions) config.Conditions {
if reqConditions.MatchAsPathSet != nil {
conditions.BgpConditions.MatchAsPathSet = reqConditions.MatchAsPathSet.AsPathSetName
}
+ if reqConditions.MatchCommunitySet != nil {
+ conditions.BgpConditions.MatchCommunitySet = reqConditions.MatchCommunitySet.CommunitySetName
+ }
if reqConditions.MatchAsPathLength != nil {
conditions.BgpConditions.AsPathLength =
AsPathLengthToConfigStruct(reqConditions.MatchAsPathLength)
@@ -1189,8 +1239,28 @@ func ConditionsToConfigStruct(reqConditions *api.Conditions) config.Conditions {
return conditions
}
+func ActionsToApiStruct(conActions config.Actions) *api.Actions {
+ action := ROUTE_REJECT
+ if conActions.AcceptRoute {
+ action = ROUTE_ACCEPT
+ }
+ communityAction := &api.CommunityAction{
+ Communities: conActions.BgpActions.SetCommunity.Communities,
+ Options: conActions.BgpActions.SetCommunity.Options,
+ }
+ resActions := &api.Actions{
+ RouteAction: action,
+ Community: communityAction,
+ }
+ return resActions
+}
+
func ActionsToConfigStruct(reqActions *api.Actions) config.Actions {
actions := config.Actions{}
+ if reqActions.Community != nil {
+ actions.BgpActions.SetCommunity.Communities = reqActions.Community.Communities
+ actions.BgpActions.SetCommunity.Options = reqActions.Community.Options
+ }
switch reqActions.RouteAction {
case ROUTE_ACCEPT:
actions.AcceptRoute = true
@@ -1202,13 +1272,9 @@ func ActionsToConfigStruct(reqActions *api.Actions) config.Actions {
func StatementToConfigStruct(reqStatement *api.Statement) config.Statement {
statement := config.Statement{
- Name: reqStatement.StatementNeme,
- }
- if reqStatement.Conditions != nil {
- statement.Conditions = ConditionsToConfigStruct(reqStatement.Conditions)
- }
- if reqStatement.Actions != nil {
- statement.Actions = ActionsToConfigStruct(reqStatement.Actions)
+ Name: reqStatement.StatementNeme,
+ Conditions: ConditionsToConfigStruct(reqStatement.Conditions),
+ Actions: ActionsToConfigStruct(reqStatement.Actions),
}
return statement
}
@@ -1231,6 +1297,7 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
conPrefixSetList := df.PrefixSetList
conNeighborSetList := df.NeighborSetList
conAsPathSetList := df.BgpDefinedSets.AsPathSetList
+ conCommunitySetList := df.BgpDefinedSets.CommunitySetList
resStatementList := make([]*api.Statement, 0)
for _, st := range pd.StatementList {
conditions := st.Conditions
@@ -1245,13 +1312,18 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
asPathSet := &api.AsPathSet{
AsPathSetName: conditions.BgpConditions.MatchAsPathSet,
}
+ communitySet := &api.CommunitySet{
+ CommunitySetName: conditions.BgpConditions.MatchCommunitySet,
+ }
// consider later whether treatment of here need
_, conPrefixSet := PrefixSetToConfigStruct(prefixSet)
_, conNeighborSet := NeighborSetToConfigStruct(neighborSet)
_, conAsPathSet := AsPathSetToConfigStruct(asPathSet)
+ _, conCommunitySet := CommunitySetToConfigStruct(communitySet)
idxPrefixSet, _ := IndexOfPrefixSet(conPrefixSetList, conPrefixSet)
idxNeighborSet, _ := IndexOfNeighborSet(conNeighborSetList, conNeighborSet)
idxAsPathSet, _ := IndexOfAsPathSet(conAsPathSetList, conAsPathSet)
+ idxCommunitySet, _ := IndexOfCommunitySet(conCommunitySetList, conCommunitySet)
if idxPrefixSet != -1 {
prefixSet = PrefixSetToApiStruct(conPrefixSetList[idxPrefixSet])
}
@@ -1261,19 +1333,18 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
if idxAsPathSet != -1 {
asPathSet = AsPathSetToApiStruct(conAsPathSetList[idxAsPathSet])
}
+ if idxCommunitySet != -1 {
+ communitySet = CommunitySetToApiStruct(conCommunitySetList[idxCommunitySet])
+ }
resConditions := &api.Conditions{
MatchPrefixSet: prefixSet,
MatchNeighborSet: neighborSet,
MatchAsPathSet: asPathSet,
+ MatchCommunitySet: communitySet,
MatchAsPathLength: AsPathLengthToApiStruct(st.Conditions.BgpConditions.AsPathLength),
MatchSetOptions: MatchSetOptionToString(conditions.MatchSetOptions),
}
- resActions := &api.Actions{
- RouteAction: ROUTE_REJECT,
- }
- if actions.AcceptRoute {
- resActions.RouteAction = ROUTE_ACCEPT
- }
+ resActions := ActionsToApiStruct(actions)
resStatement := &api.Statement{
StatementNeme: st.Name,
Conditions: resConditions,
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 8f2ca497..ef850dbf 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -68,6 +68,11 @@ const (
REQ_POLICY_ROUTEPOLICY_ADD
REQ_POLICY_ROUTEPOLICY_DELETE
REQ_POLICY_ROUTEPOLICIES_DELETE
+ REQ_POLICY_COMMUNITY
+ REQ_POLICY_COMMUNITIES
+ REQ_POLICY_COMMUNITY_ADD
+ REQ_POLICY_COMMUNITY_DELETE
+ REQ_POLICY_COMMUNITIES_DELETE
)
const GRPC_PORT = 8080
@@ -389,6 +394,17 @@ func (s *Server) modPolicy(arg *api.PolicyArguments, stream interface{}) error {
default:
return fmt.Errorf("unsupported operation: %s", arg.Operation)
}
+ case api.Resource_POLICY_COMMUNITY:
+ switch arg.Operation {
+ case api.Operation_ADD:
+ reqType = REQ_POLICY_COMMUNITY_ADD
+ case api.Operation_DEL:
+ reqType = REQ_POLICY_COMMUNITY_DELETE
+ case api.Operation_DEL_ALL:
+ reqType = REQ_POLICY_COMMUNITIES_DELETE
+ default:
+ return fmt.Errorf("unsupported operation: %s", arg.Operation)
+ }
case api.Resource_POLICY_ROUTEPOLICY:
switch arg.Operation {
case api.Operation_ADD:
@@ -400,6 +416,8 @@ func (s *Server) modPolicy(arg *api.PolicyArguments, stream interface{}) error {
default:
return fmt.Errorf("unsupported operation: %s", arg.Operation)
}
+ default:
+ return fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
req := NewGrpcRequest(reqType, "", rf, arg.PolicyDefinition)
s.bgpServerCh <- req
@@ -428,6 +446,8 @@ func (s *Server) GetPolicyRoutePolicies(arg *api.PolicyArguments, stream api.Grp
reqType = REQ_POLICY_NEIGHBORS
case api.Resource_POLICY_ASPATH:
reqType = REQ_POLICY_ASPATHS
+ case api.Resource_POLICY_COMMUNITY:
+ reqType = REQ_POLICY_COMMUNITIES
case api.Resource_POLICY_ROUTEPOLICY:
reqType = REQ_POLICY_ROUTEPOLICIES
default:
@@ -457,6 +477,8 @@ func (s *Server) GetPolicyRoutePolicy(ctx context.Context, arg *api.PolicyArgume
reqType = REQ_POLICY_NEIGHBOR
case api.Resource_POLICY_ASPATH:
reqType = REQ_POLICY_ASPATH
+ case api.Resource_POLICY_COMMUNITY:
+ reqType = REQ_POLICY_COMMUNITY
case api.Resource_POLICY_ROUTEPOLICY:
reqType = REQ_POLICY_ROUTEPOLICY
default:
diff --git a/server/server.go b/server/server.go
index 78cd5c8f..9a300a98 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1048,20 +1048,25 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
grpcReq.ResponseCh <- &GrpcResponse{}
close(grpcReq.ResponseCh)
- case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ASPATHS, REQ_POLICY_ROUTEPOLICIES:
+ case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ASPATHS,
+ REQ_POLICY_COMMUNITIES, REQ_POLICY_ROUTEPOLICIES:
server.handleGrpcShowPolicies(grpcReq)
- case REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH, REQ_POLICY_ROUTEPOLICY:
+ case REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH,
+ REQ_POLICY_COMMUNITY, REQ_POLICY_ROUTEPOLICY:
server.handleGrpcShowPolicy(grpcReq)
- case REQ_POLICY_PREFIX_ADD, REQ_POLICY_NEIGHBOR_ADD, REQ_POLICY_ASPATH_ADD, REQ_POLICY_ROUTEPOLICY_ADD:
+ case REQ_POLICY_PREFIX_ADD, REQ_POLICY_NEIGHBOR_ADD, REQ_POLICY_ASPATH_ADD,
+ REQ_POLICY_COMMUNITY_ADD, REQ_POLICY_ROUTEPOLICY_ADD:
server.handleGrpcAddPolicy(grpcReq)
- case REQ_POLICY_PREFIX_DELETE, REQ_POLICY_NEIGHBOR_DELETE, REQ_POLICY_ASPATH_DELETE, REQ_POLICY_ROUTEPOLICY_DELETE:
+ case REQ_POLICY_PREFIX_DELETE, REQ_POLICY_NEIGHBOR_DELETE, REQ_POLICY_ASPATH_DELETE,
+ REQ_POLICY_COMMUNITY_DELETE, REQ_POLICY_ROUTEPOLICY_DELETE:
server.handleGrpcDelPolicy(grpcReq)
- case REQ_POLICY_PREFIXES_DELETE, REQ_POLICY_NEIGHBORS_DELETE, REQ_POLICY_ASPATHS_DELETE, REQ_POLICY_ROUTEPOLICIES_DELETE:
+ case REQ_POLICY_PREFIXES_DELETE, REQ_POLICY_NEIGHBORS_DELETE, REQ_POLICY_ASPATHS_DELETE,
+ REQ_POLICY_COMMUNITIES_DELETE, REQ_POLICY_ROUTEPOLICIES_DELETE:
server.handleGrpcDelPolicies(grpcReq)
default:
- errmsg := "Unknown request type"
+ errmsg := fmt.Errorf("Unknown request type: %v", grpcReq.RequestType)
result := &GrpcResponse{
- ResponseErr: fmt.Errorf(errmsg),
+ ResponseErr: errmsg,
}
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
@@ -1120,6 +1125,22 @@ func (server *BgpServer) handleGrpcShowPolicies(grpcReq *GrpcRequest) {
result.ResponseErr = fmt.Errorf("Policy aspath doesn't exist.")
grpcReq.ResponseCh <- result
}
+ case REQ_POLICY_COMMUNITIES:
+ info := server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList
+ if len(info) > 0 {
+ for _, cs := range info {
+ resCommunitySet := policy.CommunitySetToApiStruct(cs)
+ pd := &api.PolicyDefinition{}
+ pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchCommunitySet: resCommunitySet}}}
+ result = &GrpcResponse{
+ Data: pd,
+ }
+ grpcReq.ResponseCh <- result
+ }
+ } else {
+ result.ResponseErr = fmt.Errorf("Policy community doesn't exist.")
+ grpcReq.ResponseCh <- result
+ }
case REQ_POLICY_ROUTEPOLICIES:
info := server.routingPolicy.PolicyDefinitionList
df := server.routingPolicy.DefinedSets
@@ -1197,6 +1218,24 @@ func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
} else {
result.ResponseErr = fmt.Errorf("policy aspath that has %v doesn't exist.", name)
}
+ case REQ_POLICY_COMMUNITY:
+ info := server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList
+ resCommunitySet := &api.CommunitySet{}
+ for _, cs := range info {
+ if cs.CommunitySetName == name {
+ resCommunitySet = policy.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_ROUTEPOLICY:
log.Error("IN RoutePolicy")
info := server.routingPolicy.PolicyDefinitionList
@@ -1208,7 +1247,7 @@ func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
break
}
}
- log.Error("IN RoutePolicy: ",len(resPolicyDefinition.StatementList))
+ log.Error("IN RoutePolicy: ", len(resPolicyDefinition.StatementList))
if len(resPolicyDefinition.StatementList) > 0 {
result = &GrpcResponse{
Data: resPolicyDefinition,
@@ -1241,7 +1280,7 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
} else {
if idxPrefix == -1 {
conPrefixSetList[idxPrefixSet].PrefixList =
- append(conPrefixSetList[idxPrefixSet].PrefixList, prefixSet.PrefixList[0])
+ append(conPrefixSetList[idxPrefixSet].PrefixList, prefixSet.PrefixList[0])
}
}
server.routingPolicy.DefinedSets.PrefixSetList = conPrefixSetList
@@ -1262,7 +1301,7 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
} else {
if idxNeighbor == -1 {
conNeighborSetList[idxNeighborSet].NeighborInfoList =
- append(conNeighborSetList[idxNeighborSet].NeighborInfoList, neighborSet.NeighborInfoList[0])
+ append(conNeighborSetList[idxNeighborSet].NeighborInfoList, neighborSet.NeighborInfoList[0])
}
}
server.routingPolicy.DefinedSets.NeighborSetList = conNeighborSetList
@@ -1287,6 +1326,27 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
}
}
server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList = conAsPathSetList
+ case REQ_POLICY_COMMUNITY_ADD:
+ reqCommunitySet := grpcReq.Data.(*api.PolicyDefinition).StatementList[0].Conditions.MatchCommunitySet
+ conCommunitySetList := server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList
+ isReqCommunitySet, communitySet := policy.CommunitySetToConfigStruct(reqCommunitySet)
+ if !isReqCommunitySet {
+ result.ResponseErr = fmt.Errorf("doesn't reqest of policy community.")
+ 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
+ idxCommunitySet, idxCommunity := policy.IndexOfCommunitySet(conCommunitySetList, communitySet)
+ if idxCommunitySet == -1 {
+ conCommunitySetList = append(conCommunitySetList, communitySet)
+ } else {
+ if idxCommunity == -1 {
+ conCommunitySetList[idxCommunitySet].CommunityMembers =
+ append(conCommunitySetList[idxCommunitySet].CommunityMembers, communitySet.CommunityMembers[0])
+ }
+ }
+ server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList = conCommunitySetList
case REQ_POLICY_ROUTEPOLICY_ADD:
reqPolicy := grpcReq.Data.(*api.PolicyDefinition)
reqConditions := reqPolicy.StatementList[0].Conditions
@@ -1300,32 +1360,33 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
statement := policyDef.StatementList[0]
if idxStatement == -1 {
conPolicyList[idxPolicy].StatementList =
- append(conPolicyList[idxPolicy].StatementList, statement)
+ append(conPolicyList[idxPolicy].StatementList, statement)
} else {
conStatement := &conPolicyList[idxPolicy].StatementList[idxStatement]
- if reqConditions != nil {
- if reqConditions.MatchPrefixSet != nil {
- conStatement.Conditions.MatchPrefixSet = statement.Conditions.MatchPrefixSet
- }
- if reqConditions.MatchNeighborSet != nil {
- conStatement.Conditions.MatchNeighborSet = statement.Conditions.MatchNeighborSet
- }
- if reqConditions.MatchSetOptions != "" {
- conStatement.Conditions.MatchSetOptions = statement.Conditions.MatchSetOptions
- }
- if reqConditions.MatchAsPathSet != nil {
- conStatement.Conditions.BgpConditions.MatchAsPathSet = statement.Conditions.BgpConditions.MatchAsPathSet
- }
- if reqConditions.MatchAsPathLength != nil {
- conStatement.Conditions.BgpConditions.AsPathLength = statement.Conditions.BgpConditions.AsPathLength
- }
+ if reqConditions.MatchPrefixSet != nil {
+ conStatement.Conditions.MatchPrefixSet = statement.Conditions.MatchPrefixSet
}
- if reqActions != nil {
- if reqActions.RouteAction != "" {
- conStatement.Actions.AcceptRoute = statement.Actions.AcceptRoute
- conStatement.Actions.RejectRoute = statement.Actions.RejectRoute
- }
- conStatement.Actions = statement.Actions
+ if reqConditions.MatchNeighborSet != nil {
+ conStatement.Conditions.MatchNeighborSet = statement.Conditions.MatchNeighborSet
+ }
+ if reqConditions.MatchSetOptions != "" {
+ conStatement.Conditions.MatchSetOptions = statement.Conditions.MatchSetOptions
+ }
+ if reqConditions.MatchAsPathSet != nil {
+ conStatement.Conditions.BgpConditions.MatchAsPathSet = statement.Conditions.BgpConditions.MatchAsPathSet
+ }
+ if reqConditions.MatchCommunitySet != nil {
+ conStatement.Conditions.BgpConditions.MatchCommunitySet = statement.Conditions.BgpConditions.MatchCommunitySet
+ }
+ if reqConditions.MatchAsPathLength != nil {
+ conStatement.Conditions.BgpConditions.AsPathLength = statement.Conditions.BgpConditions.AsPathLength
+ }
+ if reqActions.RouteAction != "" {
+ conStatement.Actions.AcceptRoute = statement.Actions.AcceptRoute
+ conStatement.Actions.RejectRoute = statement.Actions.RejectRoute
+ }
+ if reqActions.Community != nil {
+ conStatement.Actions.BgpActions.SetCommunity = statement.Actions.BgpActions.SetCommunity
}
}
}
@@ -1357,7 +1418,7 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
prefix.Address, prefix.Masklength, prefix.MasklengthRange)
} else {
conPrefixSetList[idxPrefixSet].PrefixList =
- append(conPrefixSetList[idxPrefixSet].PrefixList[:idxPrefix], conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix+1:]...)
+ append(conPrefixSetList[idxPrefixSet].PrefixList[:idxPrefix], conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix+1:]...)
}
}
} else {
@@ -1392,8 +1453,8 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
neighborSet.NeighborInfoList[0].Address)
} else {
conNeighborSetList[idxNeighborSet].NeighborInfoList =
- append(conNeighborSetList[idxNeighborSet].NeighborInfoList[:idxNeighbor],
- conNeighborSetList[idxNeighborSet].NeighborInfoList[idxNeighbor+1:]...)
+ append(conNeighborSetList[idxNeighborSet].NeighborInfoList[:idxNeighbor],
+ conNeighborSetList[idxNeighborSet].NeighborInfoList[idxNeighbor+1:]...)
}
}
} else {
@@ -1441,6 +1502,35 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
}
}
server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList = conAsPathSetList
+ case REQ_POLICY_COMMUNITY_DELETE:
+ 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.
+ 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,
+ CommunitySet.CommunityMembers[0])
+ } else {
+ if idxCommunity == -1 {
+ result.ResponseErr = fmt.Errorf("Policy aspath that has %v %v doesn't exist.", CommunitySet.CommunitySetName,
+ CommunitySet.CommunityMembers[0])
+ } else {
+ conCommunitySetList[idxCommunitySet].CommunityMembers =
+ append(conCommunitySetList[idxCommunitySet].CommunityMembers[:idxCommunity],
+ conCommunitySetList[idxCommunitySet].CommunityMembers[idxCommunity+1:]...)
+ }
+ }
+ } else {
+ if idxCommunitySet == -1 {
+ result.ResponseErr = fmt.Errorf("Policy aspath %v doesn't exist.", CommunitySet.CommunitySetName)
+ } else {
+ conCommunitySetList = append(conCommunitySetList[:idxCommunitySet], conCommunitySetList[idxCommunitySet+1:]...)
+ }
+ }
+ server.routingPolicy.DefinedSets.BgpDefinedSets.CommunitySetList = conCommunitySetList
case REQ_POLICY_ROUTEPOLICY_DELETE:
reqPolicy := grpcReq.Data.(*api.PolicyDefinition)
conPolicyList := server.routingPolicy.PolicyDefinitionList
@@ -1455,7 +1545,7 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
result.ResponseErr = fmt.Errorf("Policy Statment that has %v doesn't exist.", policyDef.StatementList[0].Name)
} else {
conPolicyList[idxPolicy].StatementList =
- append(conPolicyList[idxPolicy].StatementList[:idxStatement], conPolicyList[idxPolicy].StatementList[idxStatement+1:]...)
+ append(conPolicyList[idxPolicy].StatementList[:idxStatement], conPolicyList[idxPolicy].StatementList[idxStatement+1:]...)
}
}
} else {
@@ -1488,6 +1578,8 @@ func (server *BgpServer) handleGrpcDelPolicies(grpcReq *GrpcRequest) {
server.routingPolicy.DefinedSets.NeighborSetList = make([]config.NeighborSet, 0)
case REQ_POLICY_ASPATHS_DELETE:
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_ROUTEPOLICIES_DELETE:
server.routingPolicy.PolicyDefinitionList = make([]config.PolicyDefinition, 0)
}