summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go29
-rw-r--r--api/gobgp.proto11
-rw-r--r--gobgp/common.go16
-rw-r--r--gobgp/policy.go179
-rw-r--r--policy/policy.go78
-rw-r--r--server/grpc_server.go20
-rw-r--r--server/server.go100
7 files changed, 412 insertions, 21 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 78a9b6a3..32ace22d 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -37,6 +37,7 @@ It has these top-level messages:
Neighbor
NeighborSet
AsPathLength
+ AsPathSet
Conditions
Actions
Statement
@@ -68,7 +69,8 @@ const (
Resource_ADJ_OUT Resource = 3
Resource_POLICY_PREFIX Resource = 4
Resource_POLICY_NEIGHBOR Resource = 5
- Resource_POLICY_ROUTEPOLICY Resource = 6
+ Resource_POLICY_ASPATH Resource = 6
+ Resource_POLICY_ROUTEPOLICY Resource = 7
)
var Resource_name = map[int32]string{
@@ -78,7 +80,8 @@ var Resource_name = map[int32]string{
3: "ADJ_OUT",
4: "POLICY_PREFIX",
5: "POLICY_NEIGHBOR",
- 6: "POLICY_ROUTEPOLICY",
+ 6: "POLICY_ASPATH",
+ 7: "POLICY_ROUTEPOLICY",
}
var Resource_value = map[string]int32{
"GLOBAL": 0,
@@ -87,7 +90,8 @@ var Resource_value = map[string]int32{
"ADJ_OUT": 3,
"POLICY_PREFIX": 4,
"POLICY_NEIGHBOR": 5,
- "POLICY_ROUTEPOLICY": 6,
+ "POLICY_ASPATH": 6,
+ "POLICY_ROUTEPOLICY": 7,
}
func (x Resource) String() string {
@@ -994,11 +998,21 @@ func (m *AsPathLength) Reset() { *m = AsPathLength{} }
func (m *AsPathLength) String() string { return proto.CompactTextString(m) }
func (*AsPathLength) ProtoMessage() {}
+type AsPathSet struct {
+ AsPathSetName string `protobuf:"bytes,1,opt,name=as_path_set_name" json:"as_path_set_name,omitempty"`
+ AsPathMembers []string `protobuf:"bytes,2,rep,name=as_path_members" json:"as_path_members,omitempty"`
+}
+
+func (m *AsPathSet) Reset() { *m = AsPathSet{} }
+func (m *AsPathSet) String() string { return proto.CompactTextString(m) }
+func (*AsPathSet) 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"`
- MatchSetOptions string `protobuf:"bytes,4,opt,name=match_set_options" json:"match_set_options,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"`
}
func (m *Conditions) Reset() { *m = Conditions{} }
@@ -1026,6 +1040,13 @@ func (m *Conditions) GetMatchAsPathLength() *AsPathLength {
return nil
}
+func (m *Conditions) GetMatchAsPathSet() *AsPathSet {
+ if m != nil {
+ return m.MatchAsPathSet
+ }
+ return nil
+}
+
type Actions struct {
RouteAction string `protobuf:"bytes,1,opt,name=route_action" json:"route_action,omitempty"`
}
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 29038ea8..e61c2243 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -75,7 +75,8 @@ enum Resource {
ADJ_OUT = 3;
POLICY_PREFIX = 4;
POLICY_NEIGHBOR = 5;
- POLICY_ROUTEPOLICY = 6;
+ POLICY_ASPATH = 6;
+ POLICY_ROUTEPOLICY = 7;
}
enum Operation {
@@ -373,11 +374,17 @@ message AsPathLength {
string operator = 2;
}
+message AsPathSet {
+ string as_path_set_name = 1;
+ repeated string as_path_members = 2;
+}
+
message Conditions {
PrefixSet match_prefix_set = 1;
NeighborSet match_neighbor_set = 2;
AsPathLength match_as_path_length = 3;
- string match_set_options = 4;
+ AsPathSet match_as_path_set = 4;
+ string match_set_options = 5;
}
message Actions {
diff --git a/gobgp/common.go b/gobgp/common.go
index f50be075..1d47ea1e 100644
--- a/gobgp/common.go
+++ b/gobgp/common.go
@@ -45,6 +45,7 @@ const (
CMD_ENABLE = "enable"
CMD_DISABLE = "disable"
CMD_PREFIX = "prefix"
+ CMD_ASPATH = "aspath"
CMD_ROUTEPOLICY = "routepolicy"
CMD_CONDITIONS = "conditions"
CMD_ACTIONS = "actions"
@@ -63,6 +64,7 @@ var neighborsOpts struct {
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"`
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)"`
}
@@ -197,6 +199,20 @@ func (n neighbors) Less(i, j int) bool {
return n[i].NeighborSetName < n[j].NeighborSetName
}
+type aspaths []*api.AsPathSet
+
+func (a aspaths) Len() int {
+ return len(a)
+}
+
+func (a aspaths) Swap(i, j int) {
+ a[i], a[j] = a[j], a[i]
+}
+
+func (a aspaths) Less(i, j int) bool {
+ return a[i].AsPathSetName < a[j].AsPathSetName
+}
+
type policyDefinitions []*api.PolicyDefinition
func (p policyDefinitions) Len() int {
diff --git a/gobgp/policy.go b/gobgp/policy.go
index 86f9e691..1939a12d 100644
--- a/gobgp/policy.go
+++ b/gobgp/policy.go
@@ -27,6 +27,7 @@ import (
"sort"
"strconv"
"strings"
+ "regexp"
)
func formatPolicyPrefix(prefixSetList []*api.PrefixSet) (string, string) {
@@ -192,6 +193,8 @@ func modPolicy(resource api.Resource, op api.Operation, data interface{}) error
co.MatchPrefixSet = data.(*api.PrefixSet)
case api.Resource_POLICY_NEIGHBOR:
co.MatchNeighborSet = data.(*api.NeighborSet)
+ case api.Resource_POLICY_ASPATH:
+ co.MatchAsPathSet = data.(*api.AsPathSet)
}
pd.StatementList = []*api.Statement{{Conditions: co}}
} else {
@@ -423,6 +426,156 @@ func modPolicyNeighbor(modtype string, eArgs []string) error {
return nil
}
+func formatPolicyAsPath(asPathSetList []*api.AsPathSet) string {
+ maxNameLen := len("Name")
+ maxPathLen := len("AsPath")
+ for _, as := range asPathSetList {
+ if len(as.AsPathSetName) > maxNameLen {
+ maxNameLen = len(as.AsPathSetName)
+ }
+ for _, m := range as.AsPathMembers {
+ if len(m) > maxPathLen {
+ maxPathLen = len(m)
+ }
+ }
+ }
+ format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxPathLen) + "s\n"
+ return format
+}
+
+
+func showPolicyAsPaths() error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_ASPATH,
+ }
+ stream, e := client.GetPolicyRoutePolicies(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+ m := aspaths{}
+ for {
+ a, e := stream.Recv()
+ if e == io.EOF {
+ break
+ } else if e != nil {
+ return e
+ }
+ m = append(m, a.StatementList[0].Conditions.MatchAsPathSet)
+ }
+ if globalOpts.Json {
+ j, _ := json.Marshal(m)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, a := range m {
+ fmt.Println(a.AsPathSetName)
+ }
+ return nil
+ }
+ sort.Sort(m)
+
+ format := formatPolicyAsPath(m)
+ fmt.Printf(format, "Name", "AsPath")
+ for _, as := range m {
+ for i, m := range as.AsPathMembers {
+ if i == 0 {
+ fmt.Printf(format, as.AsPathSetName, m)
+ } else {
+ fmt.Printf(format, "", m)
+ }
+ }
+ }
+ return nil
+}
+
+func showPolicyAsPath(args []string) error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_ASPATH,
+ Name: args[0],
+ }
+ pd, e := client.GetPolicyRoutePolicy(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+ as := pd.StatementList[0].Conditions.MatchAsPathSet
+ if globalOpts.Json {
+ j, _ := json.Marshal(as)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, a := range as.AsPathMembers {
+ fmt.Println(a)
+ }
+ return nil
+ }
+ format := formatPolicyAsPath([]*api.AsPathSet{as})
+ fmt.Printf(format, "Name", "AsPath")
+ for i, m := range as.AsPathMembers {
+ if i == 0 {
+ fmt.Printf(format, as.AsPathSetName, m)
+ } else {
+ fmt.Printf(format, "", m)
+ }
+ }
+ return nil
+}
+
+func parseAsPathSet(eArgs []string) (*api.AsPathSet, error) {
+ regAsn, _ := regexp.Compile("^(\\^?)([0-9]+)(\\$?)$")
+ if !regAsn.MatchString(eArgs[1]) {
+ return nil, fmt.Errorf("invalid aspath: %s\nplease enter aspath format", eArgs[1])
+ }
+ asPathSet := &api.AsPathSet{
+ AsPathSetName: eArgs[0],
+ AsPathMembers: []string{eArgs[1]},
+ }
+ return asPathSet, nil
+}
+
+func modPolicyAsPath(modtype string, eArgs []string) error {
+ asPathSet := &api.AsPathSet{}
+ var e error
+ var operation api.Operation
+
+ switch modtype {
+ case CMD_ADD:
+ if len(eArgs) < 2 {
+ return fmt.Errorf("usage: policy aspath add <aspath set name> <aspath>")
+ }
+ if asPathSet, e = parseAsPathSet(eArgs); e != nil {
+ return e
+ }
+ operation = api.Operation_ADD
+ case CMD_DEL:
+ if len(eArgs) == 0 {
+ return fmt.Errorf("usage: policy aspath del <aspath set name> [<aspath>]")
+ } else if len(eArgs) == 1 {
+ asPathSet = &api.AsPathSet{
+ AsPathSetName: eArgs[0],
+ AsPathMembers: nil,
+ }
+ } else {
+ if asPathSet, e = parseAsPathSet(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_ASPATH, operation, asPathSet); 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)
@@ -457,6 +610,20 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) {
} else {
fmt.Print("\n")
}
+ asPathSet := st.Conditions.MatchAsPathSet
+ 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(nameFormat, "")
+ }
+ fmt.Println(asPath)
+ }
+ } 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)
@@ -545,6 +712,11 @@ func parseConditions() (*api.Conditions, error) {
NeighborSetName: conditionOpts.Neighbor,
}
}
+ if conditionOpts.AsPath != "" {
+ conditions.MatchAsPathSet = &api.AsPathSet{
+ AsPathSetName: conditionOpts.AsPath,
+ }
+ }
if conditionOpts.AsPathLength != "" {
asPathLen := conditionOpts.AsPathLength
idx := strings.Index(asPathLen, ",")
@@ -656,6 +828,7 @@ 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.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)")
@@ -693,7 +866,7 @@ func NewPolicyCmd() *cobra.Command {
Use: CMD_POLICY,
}
- for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ROUTEPOLICY} {
+ for _, v := range []string{CMD_PREFIX, CMD_NEIGHBOR, CMD_ASPATH, CMD_ROUTEPOLICY} {
var showAll func() error
var showOne func([]string) error
var mod func(string, []string) error
@@ -706,6 +879,10 @@ func NewPolicyCmd() *cobra.Command {
showAll = showPolicyNeighbors
showOne = showPolicyNeighbor
mod = modPolicyNeighbor
+ case CMD_ASPATH:
+ showAll = showPolicyAsPaths
+ showOne = showPolicyAsPath
+ mod = modPolicyAsPath
case CMD_ROUTEPOLICY:
showAll = showPolicyRoutePolicies
showOne = showPolicyRoutePolicy
diff --git a/policy/policy.go b/policy/policy.go
index cff79aae..27dc3c53 100644
--- a/policy/policy.go
+++ b/policy/policy.go
@@ -986,6 +986,29 @@ func IndexOfNeighborSet(conNeighborSetList []config.NeighborSet, reqNeighborSet
return idxNeighborSet, idxNeighbor
}
+// find index AsPathSet of request from AsPathSet of configuration file.
+// Return the idxAsPathSet of the location where the name of AsPathSet matches,
+// and idxAsPath of the location where element of AsPathSet matches
+func IndexOfAsPathSet(conAsPathSetList []config.AsPathSet, reqAsPathSet config.AsPathSet) (int, int) {
+ idxAsPathSet := -1
+ idxAsPath := -1
+ for i, conAsPathSet := range conAsPathSetList {
+ if conAsPathSet.AsPathSetName == reqAsPathSet.AsPathSetName {
+ idxAsPathSet = i
+ if len(reqAsPathSet.AsPathSetMembers) == 0 {
+ return idxAsPathSet, idxAsPath
+ }
+ for j, conAsPath := range conAsPathSet.AsPathSetMembers {
+ if conAsPath == reqAsPathSet.AsPathSetMembers[0] {
+ idxAsPath = j
+ return idxAsPathSet, idxAsPath
+ }
+ }
+ }
+ }
+ return idxAsPathSet, idxAsPath
+}
+
// 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
@@ -1091,15 +1114,28 @@ func NeighborSetToConfigStruct(reqNeighborSet *api.NeighborSet) (bool, config.Ne
return isReqNeighborSet, neighborSet
}
-func AsPathLengthToConfigStruct(reqAsPathLength *api.AsPathLength) config.AsPathLength {
- operator := reqAsPathLength.Operator
- value := reqAsPathLength.Value
- valueUint, _ := strconv.ParseUint(value, 10, 32)
- asPathLength := config.AsPathLength{
- Operator: operator,
- Value: uint32(valueUint),
+func AsPathSetToApiStruct(as config.AsPathSet) *api.AsPathSet {
+ resAsPathMembers := make([]string, 0)
+ for _, m := range as.AsPathSetMembers {
+ resAsPathMembers = append(resAsPathMembers, m)
}
- return asPathLength
+ resAsPathSet := &api.AsPathSet{
+ AsPathSetName: as.AsPathSetName,
+ AsPathMembers: resAsPathMembers,
+ }
+ return resAsPathSet
+}
+
+func AsPathSetToConfigStruct(reqAsPathSet *api.AsPathSet) (bool, config.AsPathSet) {
+ isAsPathSetSet := true
+ if len(reqAsPathSet.AsPathMembers) == 0 {
+ isAsPathSetSet = false
+ }
+ asPathSet := config.AsPathSet{
+ AsPathSetName: reqAsPathSet.AsPathSetName,
+ AsPathSetMembers: reqAsPathSet.AsPathMembers,
+ }
+ return isAsPathSetSet, asPathSet
}
func AsPathLengthToApiStruct(asPathLength config.AsPathLength) *api.AsPathLength {
@@ -1114,6 +1150,17 @@ func AsPathLengthToApiStruct(asPathLength config.AsPathLength) *api.AsPathLength
return resAsPathLength
}
+func AsPathLengthToConfigStruct(reqAsPathLength *api.AsPathLength) config.AsPathLength {
+ operator := reqAsPathLength.Operator
+ value := reqAsPathLength.Value
+ valueUint, _ := strconv.ParseUint(value, 10, 32)
+ asPathLength := config.AsPathLength{
+ Operator: operator,
+ Value: uint32(valueUint),
+ }
+ return asPathLength
+}
+
func ConditionsToConfigStruct(reqConditions *api.Conditions) config.Conditions {
conditions := config.Conditions{}
if reqConditions.MatchPrefixSet != nil {
@@ -1122,6 +1169,9 @@ func ConditionsToConfigStruct(reqConditions *api.Conditions) config.Conditions {
if reqConditions.MatchNeighborSet != nil {
conditions.MatchNeighborSet = reqConditions.MatchNeighborSet.NeighborSetName
}
+ if reqConditions.MatchAsPathSet != nil {
+ conditions.BgpConditions.MatchAsPathSet = reqConditions.MatchAsPathSet.AsPathSetName
+ }
if reqConditions.MatchAsPathLength != nil {
conditions.BgpConditions.AsPathLength =
AsPathLengthToConfigStruct(reqConditions.MatchAsPathLength)
@@ -1180,6 +1230,7 @@ func PolicyDefinitionToConfigStruct(reqPolicy *api.PolicyDefinition) (bool, conf
func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSets) *api.PolicyDefinition {
conPrefixSetList := df.PrefixSetList
conNeighborSetList := df.NeighborSetList
+ conAsPathSetList := df.BgpDefinedSets.AsPathSetList
resStatementList := make([]*api.Statement, 0)
for _, st := range pd.StatementList {
conditions := st.Conditions
@@ -1191,20 +1242,29 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe
neighborSet := &api.NeighborSet{
NeighborSetName: conditions.MatchNeighborSet,
}
+ asPathSet := &api.AsPathSet{
+ AsPathSetName: conditions.BgpConditions.MatchAsPathSet,
+ }
+ // consider later whether treatment of here need
_, conPrefixSet := PrefixSetToConfigStruct(prefixSet)
_, conNeighborSet := NeighborSetToConfigStruct(neighborSet)
+ _, conAsPathSet := AsPathSetToConfigStruct(asPathSet)
idxPrefixSet, _ := IndexOfPrefixSet(conPrefixSetList, conPrefixSet)
idxNeighborSet, _ := IndexOfNeighborSet(conNeighborSetList, conNeighborSet)
-
+ idxAsPathSet, _ := IndexOfAsPathSet(conAsPathSetList, conAsPathSet)
if idxPrefixSet != -1 {
prefixSet = PrefixSetToApiStruct(conPrefixSetList[idxPrefixSet])
}
if idxNeighborSet != -1 {
neighborSet = NeighborSetToApiStruct(conNeighborSetList[idxNeighborSet])
}
+ if idxAsPathSet != -1 {
+ asPathSet = AsPathSetToApiStruct(conAsPathSetList[idxAsPathSet])
+ }
resConditions := &api.Conditions{
MatchPrefixSet: prefixSet,
MatchNeighborSet: neighborSet,
+ MatchAsPathSet: asPathSet,
MatchAsPathLength: AsPathLengthToApiStruct(st.Conditions.BgpConditions.AsPathLength),
MatchSetOptions: MatchSetOptionToString(conditions.MatchSetOptions),
}
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 618344fd..8f2ca497 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -58,6 +58,11 @@ const (
REQ_POLICY_NEIGHBOR_ADD
REQ_POLICY_NEIGHBOR_DELETE
REQ_POLICY_NEIGHBORS_DELETE
+ REQ_POLICY_ASPATH
+ REQ_POLICY_ASPATHS
+ REQ_POLICY_ASPATH_ADD
+ REQ_POLICY_ASPATH_DELETE
+ REQ_POLICY_ASPATHS_DELETE
REQ_POLICY_ROUTEPOLICIES
REQ_POLICY_ROUTEPOLICY
REQ_POLICY_ROUTEPOLICY_ADD
@@ -373,6 +378,17 @@ func (s *Server) modPolicy(arg *api.PolicyArguments, stream interface{}) error {
default:
return fmt.Errorf("unsupported operation: %s", arg.Operation)
}
+ case api.Resource_POLICY_ASPATH:
+ switch arg.Operation {
+ case api.Operation_ADD:
+ reqType = REQ_POLICY_ASPATH_ADD
+ case api.Operation_DEL:
+ reqType = REQ_POLICY_ASPATH_DELETE
+ case api.Operation_DEL_ALL:
+ reqType = REQ_POLICY_ASPATHS_DELETE
+ default:
+ return fmt.Errorf("unsupported operation: %s", arg.Operation)
+ }
case api.Resource_POLICY_ROUTEPOLICY:
switch arg.Operation {
case api.Operation_ADD:
@@ -410,6 +426,8 @@ func (s *Server) GetPolicyRoutePolicies(arg *api.PolicyArguments, stream api.Grp
reqType = REQ_POLICY_PREFIXES
case api.Resource_POLICY_NEIGHBOR:
reqType = REQ_POLICY_NEIGHBORS
+ case api.Resource_POLICY_ASPATH:
+ reqType = REQ_POLICY_ASPATHS
case api.Resource_POLICY_ROUTEPOLICY:
reqType = REQ_POLICY_ROUTEPOLICIES
default:
@@ -437,6 +455,8 @@ func (s *Server) GetPolicyRoutePolicy(ctx context.Context, arg *api.PolicyArgume
reqType = REQ_POLICY_PREFIX
case api.Resource_POLICY_NEIGHBOR:
reqType = REQ_POLICY_NEIGHBOR
+ case api.Resource_POLICY_ASPATH:
+ reqType = REQ_POLICY_ASPATH
case api.Resource_POLICY_ROUTEPOLICY:
reqType = REQ_POLICY_ROUTEPOLICY
default:
diff --git a/server/server.go b/server/server.go
index 3ff104d5..78cd5c8f 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1048,15 +1048,15 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) []*SenderMsg {
grpcReq.ResponseCh <- &GrpcResponse{}
close(grpcReq.ResponseCh)
- case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ROUTEPOLICIES:
+ case REQ_POLICY_PREFIXES, REQ_POLICY_NEIGHBORS, REQ_POLICY_ASPATHS, REQ_POLICY_ROUTEPOLICIES:
server.handleGrpcShowPolicies(grpcReq)
- case REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ROUTEPOLICY:
+ case REQ_POLICY_PREFIX, REQ_POLICY_NEIGHBOR, REQ_POLICY_ASPATH, REQ_POLICY_ROUTEPOLICY:
server.handleGrpcShowPolicy(grpcReq)
- case REQ_POLICY_PREFIX_ADD, REQ_POLICY_NEIGHBOR_ADD, REQ_POLICY_ROUTEPOLICY_ADD:
+ case REQ_POLICY_PREFIX_ADD, REQ_POLICY_NEIGHBOR_ADD, REQ_POLICY_ASPATH_ADD, REQ_POLICY_ROUTEPOLICY_ADD:
server.handleGrpcAddPolicy(grpcReq)
- case REQ_POLICY_PREFIX_DELETE, REQ_POLICY_NEIGHBOR_DELETE, REQ_POLICY_ROUTEPOLICY_DELETE:
+ case REQ_POLICY_PREFIX_DELETE, REQ_POLICY_NEIGHBOR_DELETE, REQ_POLICY_ASPATH_DELETE, REQ_POLICY_ROUTEPOLICY_DELETE:
server.handleGrpcDelPolicy(grpcReq)
- case REQ_POLICY_PREFIXES_DELETE, REQ_POLICY_NEIGHBORS_DELETE, REQ_POLICY_ROUTEPOLICIES_DELETE:
+ case REQ_POLICY_PREFIXES_DELETE, REQ_POLICY_NEIGHBORS_DELETE, REQ_POLICY_ASPATHS_DELETE, REQ_POLICY_ROUTEPOLICIES_DELETE:
server.handleGrpcDelPolicies(grpcReq)
default:
errmsg := "Unknown request type"
@@ -1104,6 +1104,22 @@ func (server *BgpServer) handleGrpcShowPolicies(grpcReq *GrpcRequest) {
result.ResponseErr = fmt.Errorf("Policy neighbor doesn't exist.")
grpcReq.ResponseCh <- result
}
+ case REQ_POLICY_ASPATHS:
+ info := server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList
+ if len(info) > 0 {
+ for _, as := range info {
+ resAsPathSet := policy.AsPathSetToApiStruct(as)
+ pd := &api.PolicyDefinition{}
+ pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchAsPathSet: resAsPathSet}}}
+ result = &GrpcResponse{
+ Data: pd,
+ }
+ grpcReq.ResponseCh <- result
+ }
+ } else {
+ result.ResponseErr = fmt.Errorf("Policy aspath doesn't exist.")
+ grpcReq.ResponseCh <- result
+ }
case REQ_POLICY_ROUTEPOLICIES:
info := server.routingPolicy.PolicyDefinitionList
df := server.routingPolicy.DefinedSets
@@ -1163,6 +1179,24 @@ func (server *BgpServer) handleGrpcShowPolicy(grpcReq *GrpcRequest) {
} else {
result.ResponseErr = fmt.Errorf("policy neighbor that has %v doesn't exist.", name)
}
+ case REQ_POLICY_ASPATH:
+ info := server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList
+ resAsPathSet := &api.AsPathSet{}
+ for _, as := range info {
+ if as.AsPathSetName == name {
+ resAsPathSet = policy.AsPathSetToApiStruct(as)
+ break
+ }
+ }
+ if len(resAsPathSet.AsPathMembers) > 0 {
+ pd := &api.PolicyDefinition{}
+ pd.StatementList = []*api.Statement{{Conditions: &api.Conditions{MatchAsPathSet: resAsPathSet}}}
+ result = &GrpcResponse{
+ Data: pd,
+ }
+ } else {
+ result.ResponseErr = fmt.Errorf("policy aspath that has %v doesn't exist.", name)
+ }
case REQ_POLICY_ROUTEPOLICY:
log.Error("IN RoutePolicy")
info := server.routingPolicy.PolicyDefinitionList
@@ -1232,6 +1266,27 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
}
}
server.routingPolicy.DefinedSets.NeighborSetList = conNeighborSetList
+ case REQ_POLICY_ASPATH_ADD:
+ reqAsPathSet := grpcReq.Data.(*api.PolicyDefinition).StatementList[0].Conditions.MatchAsPathSet
+ conAsPathSetList := server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList
+ isReqAsPathSet, asPathSet := policy.AsPathSetToConfigStruct(reqAsPathSet)
+ if !isReqAsPathSet {
+ result.ResponseErr = fmt.Errorf("doesn't reqest of policy aspath.")
+ 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
+ idxAsPathSet, idxAsPath := policy.IndexOfAsPathSet(conAsPathSetList, asPathSet)
+ if idxAsPathSet == -1 {
+ conAsPathSetList = append(conAsPathSetList, asPathSet)
+ } else {
+ if idxAsPath == -1 {
+ conAsPathSetList[idxAsPathSet].AsPathSetMembers =
+ append(conAsPathSetList[idxAsPathSet].AsPathSetMembers, asPathSet.AsPathSetMembers[0])
+ }
+ }
+ server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList = conAsPathSetList
case REQ_POLICY_ROUTEPOLICY_ADD:
reqPolicy := grpcReq.Data.(*api.PolicyDefinition)
reqConditions := reqPolicy.StatementList[0].Conditions
@@ -1258,6 +1313,9 @@ func (server *BgpServer) handleGrpcAddPolicy(grpcReq *GrpcRequest) {
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
}
@@ -1353,6 +1411,36 @@ func (server *BgpServer) handleGrpcDelPolicy(grpcReq *GrpcRequest) {
}
}
server.routingPolicy.DefinedSets.NeighborSetList = conNeighborSetList
+ case REQ_POLICY_ASPATH_DELETE:
+ reqAsPathSet := grpcReq.Data.(*api.PolicyDefinition).StatementList[0].Conditions.MatchAsPathSet
+ 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.
+ idxAsPathSet, idxAsPath := policy.IndexOfAsPathSet(conAsPathSetList, asPathSet)
+ if isReqAsPathSet {
+ if idxAsPathSet == -1 {
+ result.ResponseErr = fmt.Errorf("Policy aspath that has %v %v doesn't exist.", asPathSet.AsPathSetName,
+ asPathSet.AsPathSetMembers[0])
+ } else {
+ if idxAsPath == -1 {
+ result.ResponseErr = fmt.Errorf("Policy aspath that has %v %v doesn't exist.", asPathSet.AsPathSetName,
+ asPathSet.AsPathSetMembers[0])
+ } else {
+ conAsPathSetList[idxAsPathSet].AsPathSetMembers =
+ append(conAsPathSetList[idxAsPathSet].AsPathSetMembers[:idxAsPath],
+ conAsPathSetList[idxAsPathSet].AsPathSetMembers[idxAsPath+1:]...)
+ }
+ }
+ } else {
+ if idxAsPathSet == -1 {
+ result.ResponseErr = fmt.Errorf("Policy aspath %v doesn't exist.", asPathSet.AsPathSetName)
+ } else {
+ conAsPathSetList = append(conAsPathSetList[:idxAsPathSet], conAsPathSetList[idxAsPathSet+1:]...)
+ }
+ }
+ server.routingPolicy.DefinedSets.BgpDefinedSets.AsPathSetList = conAsPathSetList
case REQ_POLICY_ROUTEPOLICY_DELETE:
reqPolicy := grpcReq.Data.(*api.PolicyDefinition)
conPolicyList := server.routingPolicy.PolicyDefinitionList
@@ -1398,6 +1486,8 @@ func (server *BgpServer) handleGrpcDelPolicies(grpcReq *GrpcRequest) {
server.routingPolicy.DefinedSets.PrefixSetList = make([]config.PrefixSet, 0)
case REQ_POLICY_NEIGHBORS_DELETE:
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_ROUTEPOLICIES_DELETE:
server.routingPolicy.PolicyDefinitionList = make([]config.PolicyDefinition, 0)
}