diff options
author | Naoto Hanaue <hanaue.naoto@po.ntts.co.jp> | 2015-07-15 19:19:42 +0900 |
---|---|---|
committer | Naoto Hanaue <hanaue.naoto@po.ntts.co.jp> | 2015-07-15 19:37:21 +0900 |
commit | 3cfce356e43e5f9c4e2f2429ed2a3971b863f1a6 (patch) | |
tree | b5bb473789cdf0c19dae08817652182ce030c8cb | |
parent | b56ddd477bccd5ae0bd830b95de977ba516f066b (diff) |
cli: support extended community
-rw-r--r-- | api/gobgp.pb.go | 69 | ||||
-rw-r--r-- | api/gobgp.proto | 7 | ||||
-rw-r--r-- | gobgp/common.go | 16 | ||||
-rw-r--r-- | gobgp/policy.go | 247 | ||||
-rw-r--r-- | policy/policy.go | 68 | ||||
-rw-r--r-- | server/grpc_server.go | 20 | ||||
-rw-r--r-- | server/server.go | 128 | ||||
-rw-r--r-- | test/scenario_test/policy/policy_generator.go | 4 |
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]+"}, } |