From 749df65ac97da627e8f35d91ea4e2fe585b88d5d Mon Sep 17 00:00:00 2001 From: Naoto Hanaue Date: Thu, 14 May 2015 16:51:18 +0900 Subject: cli: support the AsPathLength to display in routing policy % gobgp -u 10.0.255.1 policy routepolicy policy0 PolicyName policy0: StatementName st0: Conditions: PrefixSet: ps0 192.168.0.0/16 16..24 NeighborSet: ns0 10.0.0.2 AsPathLength: 10 eq MatchOption: ALL Actions: REJECT --- api/gobgp.pb.go | 24 ++++++- api/gobgp.proto | 8 ++- gobgp/main.go | 52 +++++++------- policy/policy.go | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- server/peer.go | 18 +++-- server/server.go | 204 ++++------------------------------------------------ 6 files changed, 289 insertions(+), 232 deletions(-) diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index 2d8767a8..bb93a7c4 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -35,6 +35,7 @@ It has these top-level messages: PrefixSet Neighbor NeighborSet + AsPathLength Conditions Actions Statement @@ -975,10 +976,20 @@ func (m *NeighborSet) GetNeighborList() []*Neighbor { return nil } +type AsPathLength struct { + Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"` + Operator string `protobuf:"bytes,2,opt,name=operator" json:"operator,omitempty"` +} + +func (m *AsPathLength) Reset() { *m = AsPathLength{} } +func (m *AsPathLength) String() string { return proto.CompactTextString(m) } +func (*AsPathLength) 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"` - MatchSetOptions int64 `protobuf:"varint,3,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"` + MatchSetOptions int64 `protobuf:"varint,4,opt,name=match_set_options" json:"match_set_options,omitempty"` } func (m *Conditions) Reset() { *m = Conditions{} } @@ -999,6 +1010,13 @@ func (m *Conditions) GetMatchNeighborSet() *NeighborSet { return nil } +func (m *Conditions) GetMatchAsPathLength() *AsPathLength { + if m != nil { + return m.MatchAsPathLength + } + return nil +} + type Actions struct { AcceptRoute bool `protobuf:"varint,1,opt,name=accept_route" json:"accept_route,omitempty"` RejectRoute bool `protobuf:"varint,2,opt,name=reject_route" json:"reject_route,omitempty"` diff --git a/api/gobgp.proto b/api/gobgp.proto index 362c619a..4feca48d 100644 --- a/api/gobgp.proto +++ b/api/gobgp.proto @@ -366,10 +366,16 @@ message NeighborSet { repeated Neighbor neighbor_list = 2; } +message AsPathLength { + string value = 1; + string operator = 2; +} + message Conditions { PrefixSet match_prefix_set = 1; NeighborSet match_neighbor_set = 2; - int64 match_set_options = 3; + AsPathLength match_as_path_length = 3; + int64 match_set_options = 4; } message Actions { diff --git a/gobgp/main.go b/gobgp/main.go index 094a6dcc..30218ef7 100644 --- a/gobgp/main.go +++ b/gobgp/main.go @@ -21,6 +21,8 @@ import ( "fmt" "github.com/jessevdk/go-flags" "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/config" + "github.com/osrg/gobgp/policy" "golang.org/x/net/context" "google.golang.org/grpc" "io" @@ -1160,30 +1162,30 @@ func showNeighborPolicy(remoteIP net.IP) error { } var defaultInPolicy, defaultOutPolicy string switch ap.DefaultImportPolicy { - case 0: + case int64(policy.ROUTE_TYPE_ACCEPT): defaultInPolicy = "ACCEPT" - case 1: + case int64(policy.ROUTE_TYPE_REJECT): defaultInPolicy = "REJECT" } switch ap.DefaultExportPolicy { - case 0: + case int64(policy.ROUTE_TYPE_ACCEPT): defaultOutPolicy = "ACCEPT" - case 1: + case int64(policy.ROUTE_TYPE_REJECT): defaultOutPolicy = "REJECT" } fmt.Printf("DefaultImportPolicy: %s\n", defaultInPolicy) fmt.Printf("DefaultImportPolicy: %s\n", defaultOutPolicy) fmt.Printf("ImportPolicies:\n") - space := " " + for _, inPolicy := range ap.ImportPolicies { - fmt.Printf("%sPolicyName %s:\n", space, inPolicy.PolicyDefinitionName) - showPolicyStatement(space, inPolicy) + fmt.Printf(" PolicyName %s:\n", inPolicy.PolicyDefinitionName) + showPolicyStatement(" ", inPolicy) } fmt.Printf("ExportPolicies:\n") for _, outPolicy := range ap.ExportPolicies { - fmt.Printf("%sPolicyName %s:\n", space, outPolicy.PolicyDefinitionName) - showPolicyStatement(space, outPolicy) + fmt.Printf(" PolicyName %s:\n", outPolicy.PolicyDefinitionName) + showPolicyStatement(" ", outPolicy) } return nil } @@ -1200,8 +1202,6 @@ func (x *NeighborPolicyCommand) Execute(args []string) error { } } else { parser.Usage = "neighbor [ ] policy \n gobgp neighbor [ ]" - //parser.AddCommand(CMD_ADD, "subcommand for add policy to neighbor", "", &NeighborPolicyAddCommand{}) - //parser.AddCommand(CMD_DEL, "subcommand for delete policy from neighbor", "", &NeighborPolicyDelCommand{}) if _, err := parser.ParseArgs(eArgs); err != nil { os.Exit(1) } @@ -1619,8 +1619,6 @@ func (x *PolicyNeighborCommand) Execute(args []string) error { } parser := flags.NewParser(nil, flags.Default) parser.Usage = "policy neighbor [OPTIONS]\n gobgp policy neighbor" - //parser.AddCommand(CMD_ADD, "subcommand for add policy of neighbor", "", &PolicyNeighborAddCommand{}) - //parser.AddCommand(CMD_DEL, "subcommand for delete policy of neighbor", "", &PolicyNeighborDelCommand{}) parser.ParseArgs(eArgs) return nil } @@ -1632,7 +1630,7 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) { fmt.Printf("%s StatementName %s:\n", head, st.StatementNeme) fmt.Printf("%s Conditions:\n", head) prefixSet := st.Conditions.MatchPrefixSet - fmt.Printf("%s PrefixSet: ", head) + fmt.Printf("%s PrefixSet: ", head) if len(prefixSet.PrefixList) != 0 { format := formatPolicyPrefix([]*api.PrefixSet{st.Conditions.MatchPrefixSet}) for i, prefix := range prefixSet.PrefixList { @@ -1640,7 +1638,7 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) { if i == 0 { fmt.Printf(format, prefixSet.PrefixSetName, p, prefix.MaskLengthRange) } else { - fmt.Printf("%s ", head) + fmt.Printf("%s ", head) fmt.Printf(format, "", p, prefix.MaskLengthRange) } @@ -1649,14 +1647,14 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) { fmt.Print("\n") } neighborSet := st.Conditions.MatchNeighborSet - fmt.Printf("%s NeighborSet: ", head) + fmt.Printf("%s NeighborSet: ", head) if len(neighborSet.NeighborList) != 0 { format := formatPolicyNeighbor([]*api.NeighborSet{st.Conditions.MatchNeighborSet}) for i, neighbor := range neighborSet.NeighborList { if i == 0 { fmt.Printf(format, neighborSet.NeighborSetName, neighbor.Address) } else { - fmt.Printf("%s ", head) + fmt.Printf("%s ", head) fmt.Printf(format, "", neighbor.Address) } @@ -1664,16 +1662,18 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) { } else { fmt.Print("\n") } + asPathLentgh := st.Conditions.MatchAsPathLength + fmt.Printf("%s AsPathLength: %s %s\n", head, asPathLentgh.Value, asPathLentgh.Operator) var option string switch st.Conditions.MatchSetOptions { - case 0: + case config.MATCH_SET_OPTIONS_TYPE_ANY: option = "ANY" - case 1: + case config.MATCH_SET_OPTIONS_TYPE_ALL: option = "ALL" - case 2: + case config.MATCH_SET_OPTIONS_TYPE_INVERT: option = "INVERT" } - fmt.Printf("%s MatchOption: %s\n", head, option) + fmt.Printf("%s MatchOption: %s\n", head, option) fmt.Printf("%s Actions:\n", head) action := "REJECT" if st.Actions.AcceptRoute { @@ -1716,10 +1716,10 @@ func showPolicyRoutePolicies() error { return nil } sort.Sort(m) - space := "" + for _, pd := range m { fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName) - showPolicyStatement(space, pd) + showPolicyStatement("", pd) } return nil } @@ -1739,9 +1739,9 @@ func showPolicyRoutePolicy(args []string) error { fmt.Println(string(j)) return nil } - space := "" + fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName) - showPolicyStatement(space, pd) + showPolicyStatement("", pd) return nil } @@ -1760,8 +1760,6 @@ func (x *PolicyRoutePolicyCommand) Execute(args []string) error { } parser := flags.NewParser(nil, flags.Default) parser.Usage = "policy routepolicy [OPTIONS]\n gobgp policy routepolicy" - //parser.AddCommand(CMD_ADD, "subcommand for add policy of routepolicy", "", &PolicyRoutePolicyAddCommand{}) - //parser.AddCommand(CMD_DEL, "subcommand for delete policy of routepolicy", "", &PolicyRoutePolicyDelCommand{}) parser.ParseArgs(eArgs) return nil } diff --git a/policy/policy.go b/policy/policy.go index 48b84c30..236ffa6d 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -486,6 +486,7 @@ func (p *Policy) ToApiStruct() *api.PolicyDefinition { for _, st := range p.Statements { resPrefixSet := &api.PrefixSet{} resNeighborSet := &api.NeighborSet{} + resAsPathLength := &api.AsPathLength{} for _, condition := range st.Conditions { switch reflect.TypeOf(condition) { case reflect.TypeOf(&PrefixCondition{}): @@ -522,12 +523,28 @@ func (p *Policy) ToApiStruct() *api.PolicyDefinition { NeighborSetName: neighborCondition.NeighborConditionName, NeighborList: resNeighborList, } + case reflect.TypeOf(&AsPathLengthCondition{}): + asPathLengthCondition := condition.(*AsPathLengthCondition) + var op string + switch asPathLengthCondition.Operator { + case ATTRIBUTE_EQ: + op = "eq" + case ATTRIBUTE_GE: + op = "ge" + case ATTRIBUTE_LE: + op = "le" + } + resAsPathLength = &api.AsPathLength{ + Value: fmt.Sprintf("%d", asPathLengthCondition.Value), + Operator: op, + } } } resCondition := &api.Conditions{ - MatchPrefixSet: resPrefixSet, - MatchNeighborSet: resNeighborSet, - MatchSetOptions: int64(st.MatchSetOptions), + MatchPrefixSet: resPrefixSet, + MatchNeighborSet: resNeighborSet, + MatchAsPathLength: resAsPathLength, + MatchSetOptions: int64(st.MatchSetOptions), } resAction := &api.Actions{ AcceptRoute: false, @@ -550,3 +567,195 @@ func (p *Policy) ToApiStruct() *api.PolicyDefinition { StatementList: resStatements, } } + +// find index PrefixSet of request from PrefixSet of configuration file. +// Return the idxPrefixSet of the location where the name of PrefixSet matches, +// and idxPrefix of the location where element of PrefixSet matches +func IndexOfPrefixSet(conPrefixSetList []config.PrefixSet, reqPrefixSet config.PrefixSet) (int, int) { + idxPrefixSet := -1 + idxPrefix := -1 + for i, conPrefixSet := range conPrefixSetList { + if conPrefixSet.PrefixSetName == reqPrefixSet.PrefixSetName { + idxPrefixSet = i + if reqPrefixSet.PrefixList == nil { + return idxPrefixSet, idxPrefix + } + for j, conPrefix := range conPrefixSet.PrefixList { + if reflect.DeepEqual(conPrefix.Address, reqPrefixSet.PrefixList[0].Address) && conPrefix.Masklength == reqPrefixSet.PrefixList[0].Masklength && + conPrefix.MasklengthRange == reqPrefixSet.PrefixList[0].MasklengthRange { + idxPrefix = j + return idxPrefixSet, idxPrefix + } + } + } + } + return idxPrefixSet, idxPrefix +} + +// find index NeighborSet of request from NeighborSet of configuration file. +// Return the idxNeighborSet of the location where the name of NeighborSet matches, +// and idxNeighbor of the location where element of NeighborSet matches +func IndexOfNeighborSet(conNeighborSetList []config.NeighborSet, reqNeighborSet config.NeighborSet) (int, int) { + idxNeighborSet := -1 + idxNeighbor := -1 + for i, conNeighborSet := range conNeighborSetList { + if conNeighborSet.NeighborSetName == reqNeighborSet.NeighborSetName { + idxNeighborSet = i + if reqNeighborSet.NeighborInfoList == nil { + return idxNeighborSet, idxNeighbor + } + for j, conNeighbor := range conNeighborSet.NeighborInfoList { + if reflect.DeepEqual(conNeighbor.Address, reqNeighborSet.NeighborInfoList[0].Address) { + idxNeighbor = j + return idxNeighborSet, idxNeighbor + } + } + } + } + return idxNeighborSet, idxNeighbor +} + +func PrefixSetToApiStruct(ps config.PrefixSet) *api.PrefixSet { + resPrefixList := make([]*api.Prefix, 0) + for _, p := range ps.PrefixList { + resPrefix := &api.Prefix{ + Address: p.Address.String(), + MaskLength: uint32(p.Masklength), + MaskLengthRange: p.MasklengthRange, + } + resPrefixList = append(resPrefixList, resPrefix) + } + resPrefixSet := &api.PrefixSet{ + PrefixSetName: ps.PrefixSetName, + PrefixList: resPrefixList, + } + return resPrefixSet +} + +func PrefixSetToConfigStruct(reqPrefixSet *api.PrefixSet) (bool, config.PrefixSet) { + var prefix config.Prefix + var prefixSet config.PrefixSet + isReqPrefixSet := true + if reqPrefixSet.PrefixList != nil { + prefix = config.Prefix{ + Address: net.ParseIP(reqPrefixSet.PrefixList[0].Address), + Masklength: uint8(reqPrefixSet.PrefixList[0].MaskLength), + MasklengthRange: reqPrefixSet.PrefixList[0].MaskLengthRange, + } + prefixList := []config.Prefix{prefix} + + prefixSet = config.PrefixSet{ + PrefixSetName: reqPrefixSet.PrefixSetName, + PrefixList: prefixList, + } + } else { + isReqPrefixSet = false + prefixSet = config.PrefixSet{ + PrefixSetName: reqPrefixSet.PrefixSetName, + PrefixList: nil, + } + } + return isReqPrefixSet, prefixSet +} + +func NeighborSetToApiStruct(ns config.NeighborSet) *api.NeighborSet { + resNeighborList := make([]*api.Neighbor, 0) + for _, n := range ns.NeighborInfoList { + resNeighbor := &api.Neighbor{ + Address: n.Address.String(), + } + resNeighborList = append(resNeighborList, resNeighbor) + } + resNeighborSet := &api.NeighborSet{ + NeighborSetName: ns.NeighborSetName, + NeighborList: resNeighborList, + } + return resNeighborSet +} + +func NeighborSetToConfigStruct(reqNeighborSet *api.NeighborSet) (bool, config.NeighborSet) { + var neighbor config.NeighborInfo + var neighborSet config.NeighborSet + isReqNeighborSet := true + if reqNeighborSet.NeighborList != nil { + neighbor = config.NeighborInfo{ + Address: net.ParseIP(reqNeighborSet.NeighborList[0].Address), + } + neighborList := []config.NeighborInfo{neighbor} + + neighborSet = config.NeighborSet{ + NeighborSetName: reqNeighborSet.NeighborSetName, + NeighborInfoList: neighborList, + } + } else { + isReqNeighborSet = false + neighborSet = config.NeighborSet{ + NeighborSetName: reqNeighborSet.NeighborSetName, + NeighborInfoList: nil, + } + } + return isReqNeighborSet, neighborSet +} + +func AsPathLengthToApiStruct(asPathLength config.AsPathLength) *api.AsPathLength { + value := "" + if asPathLength.Operator != "" { + value = fmt.Sprintf("%d", asPathLength.Value) + } + resAsPathLength := &api.AsPathLength{ + Value: value, + Operator: asPathLength.Operator, + } + return resAsPathLength +} + +func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSets) *api.PolicyDefinition { + conPrefixSetList := df.PrefixSetList + conNeighborSetList := df.NeighborSetList + resStatementList := make([]*api.Statement, 0) + for _, st := range pd.StatementList { + conditions := st.Conditions + actions := st.Actions + + prefixSet := &api.PrefixSet{ + PrefixSetName: conditions.MatchPrefixSet, + } + neighborSet := &api.NeighborSet{ + NeighborSetName: conditions.MatchNeighborSet, + } + _, conPrefixSet := PrefixSetToConfigStruct(prefixSet) + _, conNeighborSet := NeighborSetToConfigStruct(neighborSet) + idxPrefixSet, _ := IndexOfPrefixSet(conPrefixSetList, conPrefixSet) + idxNeighborSet, _ := IndexOfNeighborSet(conNeighborSetList, conNeighborSet) + + if idxPrefixSet != -1 { + prefixSet = PrefixSetToApiStruct(conPrefixSetList[idxPrefixSet]) + } + if idxNeighborSet != -1 { + neighborSet = NeighborSetToApiStruct(conNeighborSetList[idxNeighborSet]) + } + asPathLength := AsPathLengthToApiStruct(st.Conditions.BgpConditions.AsPathLength) + + resConditions := &api.Conditions{ + MatchPrefixSet: prefixSet, + MatchNeighborSet: neighborSet, + MatchAsPathLength: asPathLength, + MatchSetOptions: int64(conditions.MatchSetOptions), + } + resActions := &api.Actions{ + AcceptRoute: actions.AcceptRoute, + RejectRoute: actions.RejectRoute, + } + resStatement := &api.Statement{ + StatementNeme: st.Name, + Conditions: resConditions, + Actions: resActions, + } + resStatementList = append(resStatementList, resStatement) + } + resPolicyDefinition := &api.PolicyDefinition{ + PolicyDefinitionName: pd.Name, + StatementList: resStatementList, + } + return resPolicyDefinition +} diff --git a/server/peer.go b/server/peer.go index a89fb303..f83bbc3e 100644 --- a/server/peer.go +++ b/server/peer.go @@ -596,26 +596,32 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { // However, peer haven't target importpolicy when add PolicyDefinition of name only to the list. conInPolicyNames := peer.peerConfig.ApplyPolicy.ImportPolicies for _, conInPolicyName := range conInPolicyNames { + match := false for _, inPolicy := range peer.importPolicies { if conInPolicyName == inPolicy.Name { + match = true resInPolicies = append(resInPolicies, inPolicy.ToApiStruct()) - } else { - resInPolicies = append(resInPolicies, &api.PolicyDefinition{PolicyDefinitionName: conInPolicyName}) + break } - + } + if !match { + resInPolicies = append(resInPolicies, &api.PolicyDefinition{PolicyDefinitionName: conInPolicyName}) } } // Add importpolies that has been set in the configuration file to the list. // However, peer haven't target importpolicy when add PolicyDefinition of name only to the list. conOutPolicyNames := peer.peerConfig.ApplyPolicy.ExportPolicies for _, conOutPolicyName := range conOutPolicyNames { + match := false for _, outPolicy := range peer.exportPolicies { if conOutPolicyName == outPolicy.Name { + match = true resOutPolicies = append(resOutPolicies, outPolicy.ToApiStruct()) - } else { - resOutPolicies = append(resOutPolicies, &api.PolicyDefinition{PolicyDefinitionName: conOutPolicyName}) + break } - + } + if !match { + resOutPolicies = append(resOutPolicies, &api.PolicyDefinition{PolicyDefinitionName: conOutPolicyName}) } } result.Data = &api.ApplyPolicy{ diff --git a/server/server.go b/server/server.go index 882bb147..4f8bdfc6 100644 --- a/server/server.go +++ b/server/server.go @@ -23,7 +23,6 @@ import ( "github.com/osrg/gobgp/policy" "net" "os" - "reflect" "strconv" ) @@ -312,7 +311,6 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT, REQ_NEIGHBOR_ENABLE, REQ_NEIGHBOR_DISABLE, REQ_NEIGHBOR_POLICY: - log.Info("### in server") remoteAddr := grpcReq.RemoteAddr result := &GrpcResponse{} info, found := server.peerMap[remoteAddr] @@ -332,7 +330,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { result := &GrpcResponse{} if len(info) > 0 { for _, ps := range info { - resPrefixSet := prefixToApiStruct(ps) + resPrefixSet := policy.PrefixSetToApiStruct(ps) result = &GrpcResponse{ Data: resPrefixSet, } @@ -350,7 +348,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { resPrefixSet := &api.PrefixSet{} for _, ps := range info { if ps.PrefixSetName == name { - resPrefixSet = prefixToApiStruct(ps) + resPrefixSet = policy.PrefixSetToApiStruct(ps) break } } @@ -368,7 +366,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { reqPrefixSet := grpcReq.Data.(*api.PrefixSet) conPrefixSetList := server.routingPolicy.DefinedSets.PrefixSetList result := &GrpcResponse{} - isReqPrefixSet, prefixSet := prefixToConfigStruct(reqPrefixSet) + isReqPrefixSet, prefixSet := policy.PrefixSetToConfigStruct(reqPrefixSet) if !isReqPrefixSet { result.ResponseErr = fmt.Errorf("dose not reqest of policy prefix.") grpcReq.ResponseCh <- result @@ -376,8 +374,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { } // If the same PrefixSet is not set, add PrefixSet of request to the end. - // If only name of the PrefixSet is same, Overwrite with PrefixSet of request - idxPrefixSet, idxPrefix := findPrefixSet(conPrefixSetList, prefixSet) + // If only name of the PrefixSet is same, overwrite with PrefixSet of request + idxPrefixSet, idxPrefix := policy.IndexOfPrefixSet(conPrefixSetList, prefixSet) if idxPrefixSet == -1 { conPrefixSetList = append(conPrefixSetList, prefixSet) } else { @@ -393,12 +391,12 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { reqPrefixSet := grpcReq.Data.(*api.PrefixSet) conPrefixSetList := server.routingPolicy.DefinedSets.PrefixSetList result := &GrpcResponse{} - isReqPrefixSet, prefixSet := prefixToConfigStruct(reqPrefixSet) + isReqPrefixSet, prefixSet := policy.PrefixSetToConfigStruct(reqPrefixSet) if isReqPrefixSet { // If only name of the PrefixSet is same, delete all of the elements of the PrefixSet. - // If the same PrefixSet is not set, delete the elements in PrefixSet. - idxPrefixSet, idxPrefix := findPrefixSet(conPrefixSetList, prefixSet) + // If the same element PrefixSet, delete the it's element from PrefixSet. + idxPrefixSet, idxPrefix := policy.IndexOfPrefixSet(conPrefixSetList, prefixSet) if idxPrefixSet == -1 { result.ResponseErr = fmt.Errorf("Prefix %v %v/%v %v doesn't exist.", prefixSet.PrefixSetName, prefixSet.PrefixList[0].Address, prefixSet.PrefixList[0].Masklength, prefixSet.PrefixList[0].MasklengthRange) @@ -441,7 +439,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { result := &GrpcResponse{} if len(info) > 0 { for _, ns := range info { - resNeighborSet := neighborToApiStruct(ns) + resNeighborSet := policy.NeighborSetToApiStruct(ns) result = &GrpcResponse{ Data: resNeighborSet, } @@ -459,7 +457,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { resNeighborSet := &api.NeighborSet{} for _, ns := range info { if ns.NeighborSetName == name { - resNeighborSet = neighborToApiStruct(ns) + resNeighborSet = policy.NeighborSetToApiStruct(ns) break } } @@ -479,7 +477,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { result := &GrpcResponse{} if len(info) > 0 { for _, pd := range info { - resPolicyDefinition := policyDefinitionToApiStruct(pd, df) + resPolicyDefinition := policy.PolicyDefinitionToApiStruct(pd, df) result = &GrpcResponse{ Data: resPolicyDefinition, } @@ -498,7 +496,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { resPolicyDefinition := &api.PolicyDefinition{} for _, pd := range info { if pd.Name == name { - resPolicyDefinition = policyDefinitionToApiStruct(pd, df) + resPolicyDefinition = policy.PolicyDefinitionToApiStruct(pd, df) break } } @@ -514,181 +512,3 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { close(grpcReq.ResponseCh) } } - -// find PrefixSet of request from PrefixSet of configuration file. -// Return the idxPrefixSet of the location where the name of PrefixSet matches and, -// idxPrefix of the location where elements of PrefixSet matches -func findPrefixSet(conPrefixSetList []config.PrefixSet, reqPrefixSet config.PrefixSet) (int, int) { - idxPrefixSet := -1 - idxPrefix := -1 - for i, conPrefixSet := range conPrefixSetList { - if conPrefixSet.PrefixSetName == reqPrefixSet.PrefixSetName { - idxPrefixSet = i - if reqPrefixSet.PrefixList == nil { - return idxPrefixSet, idxPrefix - } - for j, conPrefix := range conPrefixSet.PrefixList { - if reflect.DeepEqual(conPrefix.Address, reqPrefixSet.PrefixList[0].Address) && conPrefix.Masklength == reqPrefixSet.PrefixList[0].Masklength && - conPrefix.MasklengthRange == reqPrefixSet.PrefixList[0].MasklengthRange { - idxPrefix = j - return idxPrefixSet, idxPrefix - } - } - } - } - return idxPrefixSet, idxPrefix -} - -// find NeighborSet of request from NeighborSet of configuration file. -// Return the idxNeighborSet of the location where the name of NeighborSet matches and, -// idxNeighbor of the location where elements of NeighborSet matches -func findNeighborSet(conNeighborSetList []config.NeighborSet, reqNeighborSet config.NeighborSet) (int, int) { - idxNeighborSet := -1 - idxNeighbor := -1 - for i, conNeighborSet := range conNeighborSetList { - if conNeighborSet.NeighborSetName == reqNeighborSet.NeighborSetName { - idxNeighborSet = i - if reqNeighborSet.NeighborInfoList == nil { - return idxNeighborSet, idxNeighbor - } - for j, conNeighbor := range conNeighborSet.NeighborInfoList { - if reflect.DeepEqual(conNeighbor.Address, reqNeighborSet.NeighborInfoList[0].Address) { - idxNeighbor = j - return idxNeighborSet, idxNeighbor - } - } - } - } - return idxNeighborSet, idxNeighbor -} - -func prefixToApiStruct(ps config.PrefixSet) *api.PrefixSet { - resPrefixList := make([]*api.Prefix, 0) - for _, p := range ps.PrefixList { - resPrefix := &api.Prefix{ - Address: p.Address.String(), - MaskLength: uint32(p.Masklength), - MaskLengthRange: p.MasklengthRange, - } - resPrefixList = append(resPrefixList, resPrefix) - } - resPrefixSet := &api.PrefixSet{ - PrefixSetName: ps.PrefixSetName, - PrefixList: resPrefixList, - } - return resPrefixSet -} - -func prefixToConfigStruct(reqPrefixSet *api.PrefixSet) (bool, config.PrefixSet) { - var prefix config.Prefix - var prefixSet config.PrefixSet - isReqPrefixSet := true - if reqPrefixSet.PrefixList != nil { - prefix = config.Prefix{ - Address: net.ParseIP(reqPrefixSet.PrefixList[0].Address), - Masklength: uint8(reqPrefixSet.PrefixList[0].MaskLength), - MasklengthRange: reqPrefixSet.PrefixList[0].MaskLengthRange, - } - prefixList := []config.Prefix{prefix} - - prefixSet = config.PrefixSet{ - PrefixSetName: reqPrefixSet.PrefixSetName, - PrefixList: prefixList, - } - } else { - isReqPrefixSet = false - prefixSet = config.PrefixSet{ - PrefixSetName: reqPrefixSet.PrefixSetName, - PrefixList: nil, - } - } - return isReqPrefixSet, prefixSet -} - -func neighborToApiStruct(ns config.NeighborSet) *api.NeighborSet { - resNeighborList := make([]*api.Neighbor, 0) - for _, n := range ns.NeighborInfoList { - resNeighbor := &api.Neighbor{ - Address: n.Address.String(), - } - resNeighborList = append(resNeighborList, resNeighbor) - } - resNeighborSet := &api.NeighborSet{ - NeighborSetName: ns.NeighborSetName, - NeighborList: resNeighborList, - } - return resNeighborSet -} - -func neighborToConfigStruct(reqNeighborSet *api.NeighborSet) (bool, config.NeighborSet) { - var neighbor config.NeighborInfo - var neighborSet config.NeighborSet - isReqNeighborSet := true - if reqNeighborSet.NeighborList != nil { - neighbor = config.NeighborInfo{ - Address: net.ParseIP(reqNeighborSet.NeighborList[0].Address), - } - neighborList := []config.NeighborInfo{neighbor} - - neighborSet = config.NeighborSet{ - NeighborSetName: reqNeighborSet.NeighborSetName, - NeighborInfoList: neighborList, - } - } else { - isReqNeighborSet = false - neighborSet = config.NeighborSet{ - NeighborSetName: reqNeighborSet.NeighborSetName, - NeighborInfoList: nil, - } - } - return isReqNeighborSet, neighborSet -} - -func policyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSets) *api.PolicyDefinition { - conPrefixSetList := df.PrefixSetList - conNeighborSetList := df.NeighborSetList - resStatementList := make([]*api.Statement, 0) - for _, st := range pd.StatementList { - conditions := st.Conditions - actions := st.Actions - - prefixSet := &api.PrefixSet{ - PrefixSetName: conditions.MatchPrefixSet, - } - neighborSet := &api.NeighborSet{ - NeighborSetName: conditions.MatchNeighborSet, - } - _, conPrefixSet := prefixToConfigStruct(prefixSet) - _, conNeighborSet := neighborToConfigStruct(neighborSet) - idxPrefixSet, _ := findPrefixSet(conPrefixSetList, conPrefixSet) - idxNeighborSet, _ := findNeighborSet(conNeighborSetList, conNeighborSet) - - if idxPrefixSet != -1 { - prefixSet = prefixToApiStruct(conPrefixSetList[idxPrefixSet]) - } - if idxNeighborSet != -1 { - neighborSet = neighborToApiStruct(conNeighborSetList[idxNeighborSet]) - } - - resConditions := &api.Conditions{ - MatchPrefixSet: prefixSet, - MatchNeighborSet: neighborSet, - MatchSetOptions: int64(conditions.MatchSetOptions), - } - resActions := &api.Actions{ - AcceptRoute: actions.AcceptRoute, - RejectRoute: actions.RejectRoute, - } - resStatement := &api.Statement{ - StatementNeme: st.Name, - Conditions: resConditions, - Actions: resActions, - } - resStatementList = append(resStatementList, resStatement) - } - resPolicyDefinition := &api.PolicyDefinition{ - PolicyDefinitionName: pd.Name, - StatementList: resStatementList, - } - return resPolicyDefinition -} -- cgit v1.2.3