diff options
author | Naoto Hanaue <hanaue.naoto@po.ntts.co.jp> | 2015-05-25 12:03:50 +0900 |
---|---|---|
committer | Naoto Hanaue <hanaue.naoto@po.ntts.co.jp> | 2015-05-26 17:31:58 +0900 |
commit | cdf36e2a7d01c4aa713a1c3883d15a7c59964879 (patch) | |
tree | 2317c24811b1f9f0faae8fd44c6471b1a91b09b5 | |
parent | fd4f6a91efb81646281ae8175433872627ec8611 (diff) |
cli: add the add/del commands to policy of neighbor
% gobgp -u 10.0.255.1 neighbor 10.0.0.3 policy
DefaultImportPolicy: ACCEPT
DefaultExportPolicy: ACCEPT
ImportPolicies:
PolicyName policy1:
StatementName st0:
Conditions:
PrefixSet: ps2 192.168.20.0/24
NeighborSet: ns0 10.0.0.2
10.0.0.3
AsPathLength: eq 5
MatchOption: ALL
Actions:
ACCEPT
ExportPolicies:
% gobgp -u 10.0.255.1 neighbor 10.0.0.3 policy add export policy0 reject
% gobgp -u 10.0.255.1 neighbor 10.0.0.3 policy del import
% gobgp -u 10.0.255.1 neighbor 10.0.0.3 policy
DefaultImportPolicy: ACCEPT
DefaultExportPolicy: REJECT
ImportPolicies:
ExportPolicies:
PolicyName policy0:
StatementName st0:
Conditions:
PrefixSet: ps0 192.168.0.0/16 16..24
NeighborSet: ns2 10.0.0.4
AsPathLength:
MatchOption: ALL
Actions:
REJECT
-rw-r--r-- | api/gobgp.pb.go | 94 | ||||
-rw-r--r-- | api/gobgp.proto | 13 | ||||
-rw-r--r-- | gobgp/main.go | 450 | ||||
-rw-r--r-- | policy/policy.go | 74 | ||||
-rw-r--r-- | server/grpc_server.go | 50 | ||||
-rw-r--r-- | server/peer.go | 46 | ||||
-rw-r--r-- | server/server.go | 68 |
7 files changed, 579 insertions, 216 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index 76443c48..5df8c325 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -523,10 +523,12 @@ func (m *ModPathArguments) GetPath() *Path { type PolicyArguments struct { Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"` Operation Operation `protobuf:"varint,2,opt,name=operation,enum=api.Operation" json:"operation,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` - PrefixSet *PrefixSet `protobuf:"bytes,4,opt,name=prefix_set" json:"prefix_set,omitempty"` - NeighborSet *NeighborSet `protobuf:"bytes,5,opt,name=neighbor_set" json:"neighbor_set,omitempty"` - PolicyDifinition *PolicyDefinition `protobuf:"bytes,6,opt,name=policy_difinition" json:"policy_difinition,omitempty"` + RouterId string `protobuf:"bytes,3,opt,name=router_id" json:"router_id,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` + PrefixSet *PrefixSet `protobuf:"bytes,5,opt,name=prefix_set" json:"prefix_set,omitempty"` + NeighborSet *NeighborSet `protobuf:"bytes,6,opt,name=neighbor_set" json:"neighbor_set,omitempty"` + PolicyDifinition *PolicyDefinition `protobuf:"bytes,7,opt,name=policy_difinition" json:"policy_difinition,omitempty"` + ApplyPolicy *ApplyPolicy `protobuf:"bytes,8,opt,name=apply_policy" json:"apply_policy,omitempty"` } func (m *PolicyArguments) Reset() { *m = PolicyArguments{} } @@ -554,6 +556,13 @@ func (m *PolicyArguments) GetPolicyDifinition() *PolicyDefinition { return nil } +func (m *PolicyArguments) GetApplyPolicy() *ApplyPolicy { + if m != nil { + return m.ApplyPolicy + } + return nil +} + type AddressFamily struct { Afi AFI `protobuf:"varint,1,opt,enum=api.AFI" json:"Afi,omitempty"` Safi SAFI `protobuf:"varint,2,opt,enum=api.SAFI" json:"Safi,omitempty"` @@ -1137,6 +1146,7 @@ type GrpcClient interface { Disable(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) ModPath(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPathClient, error) GetNeighborPolicy(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*ApplyPolicy, error) + ModNeighborPolicy(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModNeighborPolicyClient, error) GetPolicyPrefixes(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyPrefixesClient, error) GetPolicyPrefix(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (*PrefixSet, error) ModPolicyPrefix(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPolicyPrefixClient, error) @@ -1364,8 +1374,39 @@ func (c *grpcClient) GetNeighborPolicy(ctx context.Context, in *Arguments, opts return out, nil } +func (c *grpcClient) ModNeighborPolicy(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModNeighborPolicyClient, error) { + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[4], c.cc, "/api.Grpc/ModNeighborPolicy", opts...) + if err != nil { + return nil, err + } + x := &grpcModNeighborPolicyClient{stream} + return x, nil +} + +type Grpc_ModNeighborPolicyClient interface { + Send(*PolicyArguments) error + Recv() (*Error, error) + grpc.ClientStream +} + +type grpcModNeighborPolicyClient struct { + grpc.ClientStream +} + +func (x *grpcModNeighborPolicyClient) Send(m *PolicyArguments) error { + return x.ClientStream.SendMsg(m) +} + +func (x *grpcModNeighborPolicyClient) Recv() (*Error, error) { + m := new(Error) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *grpcClient) GetPolicyPrefixes(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyPrefixesClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[4], c.cc, "/api.Grpc/GetPolicyPrefixes", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[5], c.cc, "/api.Grpc/GetPolicyPrefixes", opts...) if err != nil { return nil, err } @@ -1406,7 +1447,7 @@ func (c *grpcClient) GetPolicyPrefix(ctx context.Context, in *PolicyArguments, o } func (c *grpcClient) ModPolicyPrefix(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPolicyPrefixClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[5], c.cc, "/api.Grpc/ModPolicyPrefix", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[6], c.cc, "/api.Grpc/ModPolicyPrefix", opts...) if err != nil { return nil, err } @@ -1437,7 +1478,7 @@ func (x *grpcModPolicyPrefixClient) Recv() (*Error, error) { } func (c *grpcClient) GetPolicyNeighbors(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyNeighborsClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[6], c.cc, "/api.Grpc/GetPolicyNeighbors", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[7], c.cc, "/api.Grpc/GetPolicyNeighbors", opts...) if err != nil { return nil, err } @@ -1478,7 +1519,7 @@ func (c *grpcClient) GetPolicyNeighbor(ctx context.Context, in *PolicyArguments, } func (c *grpcClient) ModPolicyNeighbor(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPolicyNeighborClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[7], c.cc, "/api.Grpc/ModPolicyNeighbor", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[8], c.cc, "/api.Grpc/ModPolicyNeighbor", opts...) if err != nil { return nil, err } @@ -1509,7 +1550,7 @@ func (x *grpcModPolicyNeighborClient) Recv() (*Error, error) { } func (c *grpcClient) GetPolicyRoutePolicies(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyRoutePoliciesClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[8], c.cc, "/api.Grpc/GetPolicyRoutePolicies", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[9], c.cc, "/api.Grpc/GetPolicyRoutePolicies", opts...) if err != nil { return nil, err } @@ -1550,7 +1591,7 @@ func (c *grpcClient) GetPolicyRoutePolicy(ctx context.Context, in *PolicyArgumen } func (c *grpcClient) ModPolicyRoutePolicy(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPolicyRoutePolicyClient, error) { - stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[9], c.cc, "/api.Grpc/ModPolicyRoutePolicy", opts...) + stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[10], c.cc, "/api.Grpc/ModPolicyRoutePolicy", opts...) if err != nil { return nil, err } @@ -1596,6 +1637,7 @@ type GrpcServer interface { Disable(context.Context, *Arguments) (*Error, error) ModPath(Grpc_ModPathServer) error GetNeighborPolicy(context.Context, *Arguments) (*ApplyPolicy, error) + ModNeighborPolicy(Grpc_ModNeighborPolicyServer) error GetPolicyPrefixes(*PolicyArguments, Grpc_GetPolicyPrefixesServer) error GetPolicyPrefix(context.Context, *PolicyArguments) (*PrefixSet, error) ModPolicyPrefix(Grpc_ModPolicyPrefixServer) error @@ -1808,6 +1850,32 @@ func _Grpc_GetNeighborPolicy_Handler(srv interface{}, ctx context.Context, codec return out, nil } +func _Grpc_ModNeighborPolicy_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(GrpcServer).ModNeighborPolicy(&grpcModNeighborPolicyServer{stream}) +} + +type Grpc_ModNeighborPolicyServer interface { + Send(*Error) error + Recv() (*PolicyArguments, error) + grpc.ServerStream +} + +type grpcModNeighborPolicyServer struct { + grpc.ServerStream +} + +func (x *grpcModNeighborPolicyServer) Send(m *Error) error { + return x.ServerStream.SendMsg(m) +} + +func (x *grpcModNeighborPolicyServer) Recv() (*PolicyArguments, error) { + m := new(PolicyArguments) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func _Grpc_GetPolicyPrefixes_Handler(srv interface{}, stream grpc.ServerStream) error { m := new(PolicyArguments) if err := stream.RecvMsg(m); err != nil { @@ -2061,6 +2129,12 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{ ClientStreams: true, }, { + StreamName: "ModNeighborPolicy", + Handler: _Grpc_ModNeighborPolicy_Handler, + ServerStreams: true, + ClientStreams: true, + }, + { StreamName: "GetPolicyPrefixes", Handler: _Grpc_GetPolicyPrefixes_Handler, ServerStreams: true, diff --git a/api/gobgp.proto b/api/gobgp.proto index dd6fc46d..9bb0075f 100644 --- a/api/gobgp.proto +++ b/api/gobgp.proto @@ -33,6 +33,7 @@ service Grpc { rpc Disable(Arguments) returns (Error) {} rpc ModPath(stream ModPathArguments) returns (stream Error) {} rpc GetNeighborPolicy(Arguments) returns (ApplyPolicy) {} + rpc ModNeighborPolicy(stream PolicyArguments) returns (stream Error) {} rpc GetPolicyPrefixes(PolicyArguments) returns (stream PrefixSet) {} rpc GetPolicyPrefix(PolicyArguments) returns (PrefixSet) {} rpc ModPolicyPrefix(stream PolicyArguments) returns (stream Error) {} @@ -66,11 +67,13 @@ message ModPathArguments { message PolicyArguments { Resource resource = 1; - Operation operation = 2; - string name = 3; - PrefixSet prefix_set = 4; - NeighborSet neighbor_set = 5; - PolicyDefinition policy_difinition = 6; + Operation operation = 2; + string router_id = 3; + string name = 4; + PrefixSet prefix_set = 5; + NeighborSet neighbor_set = 6; + PolicyDefinition policy_difinition = 7; + ApplyPolicy apply_policy = 8; } enum Resource { diff --git a/gobgp/main.go b/gobgp/main.go index 9b50e53f..96e47a72 100644 --- a/gobgp/main.go +++ b/gobgp/main.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/jessevdk/go-flags" "github.com/osrg/gobgp/api" + "github.com/osrg/gobgp/policy" "golang.org/x/net/context" "google.golang.org/grpc" "io" @@ -54,6 +55,8 @@ const ( CMD_ROUTEPOLICY = "routepolicy" CMD_CONDITIONS = "conditions" CMD_ACTIONS = "actions" + CMD_IMPORT = "import" + CMD_EXPORT = "export" ) func formatTimedelta(d int64) string { @@ -219,27 +222,31 @@ func requestGrpc(cmd string, eArgs []string, request interface{}) error { return showNeighbor(eArgs) } case CMD_NEIGHBOR + "_" + CMD_LOCAL: - return showNeighborRib(api.Resource_LOCAL, request.(*NeighborRibCommand).remoteIP) + return showNeighborRib(api.Resource_LOCAL, request.(*NeighborRibCommand)) case CMD_NEIGHBOR + "_" + CMD_ADJ_IN: - return showNeighborRib(api.Resource_ADJ_IN, request.(*NeighborRibCommand).remoteIP) + return showNeighborRib(api.Resource_ADJ_IN, request.(*NeighborRibCommand)) case CMD_NEIGHBOR + "_" + CMD_ADJ_OUT: - return showNeighborRib(api.Resource_ADJ_OUT, request.(*NeighborRibCommand).remoteIP) + return showNeighborRib(api.Resource_ADJ_OUT, request.(*NeighborRibCommand)) case CMD_NEIGHBOR + "_" + CMD_RESET: - return resetNeighbor(CMD_RESET, request.(*NeighborResetCommand).remoteIP) + return resetNeighbor(request.(*NeighborResetCommand)) case CMD_NEIGHBOR + "_" + CMD_SOFT_RESET: - return resetNeighbor(CMD_SOFT_RESET, request.(*NeighborResetCommand).remoteIP) + return resetNeighbor(request.(*NeighborResetCommand)) case CMD_NEIGHBOR + "_" + CMD_SOFT_RESET_IN: - return resetNeighbor(CMD_SOFT_RESET_IN, request.(*NeighborResetCommand).remoteIP) + return resetNeighbor(request.(*NeighborResetCommand)) case CMD_NEIGHBOR + "_" + CMD_SOFT_RESET_OUT: - return resetNeighbor(CMD_SOFT_RESET_OUT, request.(*NeighborResetCommand).remoteIP) + return resetNeighbor(request.(*NeighborResetCommand)) case CMD_NEIGHBOR + "_" + CMD_SHUTDOWN: - return stateChangeNeighbor(CMD_SHUTDOWN, request.(*NeighborChangeStateCommand).remoteIP) + return stateChangeNeighbor(request.(*NeighborChangeStateCommand)) case CMD_NEIGHBOR + "_" + CMD_ENABLE: - return stateChangeNeighbor(CMD_ENABLE, request.(*NeighborChangeStateCommand).remoteIP) + return stateChangeNeighbor(request.(*NeighborChangeStateCommand)) case CMD_NEIGHBOR + "_" + CMD_DISABLE: - return stateChangeNeighbor(CMD_DISABLE, request.(*NeighborChangeStateCommand).remoteIP) + return stateChangeNeighbor(request.(*NeighborChangeStateCommand)) case CMD_NEIGHBOR + "_" + CMD_POLICY: - return showNeighborPolicy(request.(*NeighborPolicyCommand).remoteIP) + return showNeighborPolicy(request.(*NeighborPolicyCommand)) + case CMD_NEIGHBOR + "_" + CMD_POLICY + "_" + CMD_ADD: + return modNeighborPolicy(eArgs, request.(*NeighborPolicyChangeCommand)) + case CMD_NEIGHBOR + "_" + CMD_POLICY + "_" + CMD_DEL: + return modNeighborPolicy(eArgs, request.(*NeighborPolicyChangeCommand)) case CMD_POLICY + "_" + CMD_PREFIX: if len(eArgs) == 0 { return showPolicyPrefixes() @@ -267,15 +274,11 @@ func requestGrpc(cmd string, eArgs []string, request interface{}) error { return showPolicyRoutePolicy(eArgs) } case CMD_POLICY + "_" + CMD_ROUTEPOLICY + "_" + CMD_ADD + "_" + CMD_CONDITIONS: - return modPolicyRoutePolicy(CMD_ADD, CMD_CONDITIONS, eArgs, - request.(*PolicyRoutePolicyAddConditionsCommand).policyName, - request.(*PolicyRoutePolicyAddConditionsCommand).statementName) + return modPolicyRoutePolicy(CMD_ADD, CMD_CONDITIONS, eArgs, request) case CMD_POLICY + "_" + CMD_ROUTEPOLICY + "_" + CMD_ADD + "_" + CMD_ACTIONS: - return modPolicyRoutePolicy(CMD_ADD, CMD_ACTIONS, eArgs, - request.(*PolicyRoutePolicyAddActionsCommand).policyName, - request.(*PolicyRoutePolicyAddActionsCommand).statementName) + return modPolicyRoutePolicy(CMD_ADD, CMD_ACTIONS, eArgs, request) case CMD_POLICY + "_" + CMD_ROUTEPOLICY + "_" + CMD_DEL: - return modPolicyRoutePolicy(CMD_DEL, "", eArgs, "", "") + return modPolicyRoutePolicy(CMD_DEL, "", eArgs, nil) } return nil } @@ -412,8 +415,8 @@ func (x *GlobalRibCommand) Execute(args []string) error { } } else { parser.Usage = "global rib [OPTIONS]\n gobgp global rib" - parser.AddCommand(CMD_ADD, "subcommand for add route to global rib", "", &GlobalRibAddCommand{}) - parser.AddCommand(CMD_DEL, "subcommand for delete route from global rib", "", &GlobalRibDelCommand{}) + parser.AddCommand(CMD_ADD, "subcommand to add route to global rib", "", &GlobalRibAddCommand{}) + parser.AddCommand(CMD_DEL, "subcommand to delete route from global rib", "", &GlobalRibDelCommand{}) if _, err := parser.ParseArgs(eArgs); err != nil { os.Exit(1) } @@ -971,7 +974,8 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool) { } } -func showNeighborRib(resource api.Resource, remoteIP net.IP) error { +func showNeighborRib(resource api.Resource, request *NeighborRibCommand) error { + remoteIP := request.remoteIP rt, err := checkAddressFamily(remoteIP) if err != nil { return err @@ -1073,7 +1077,9 @@ func NewNeighborResetCommand(addr string, cmd string) *NeighborResetCommand { } } -func resetNeighbor(cmd string, remoteIP net.IP) error { +func resetNeighbor(request *NeighborResetCommand) error { + remoteIP := request.remoteIP + cmd := request.command rt, err := checkAddressFamily(remoteIP) if err != nil { return err @@ -1121,7 +1127,9 @@ func NewNeighborChangeStateCommand(addr string, cmd string) *NeighborChangeState } } -func stateChangeNeighbor(cmd string, remoteIP net.IP) error { +func stateChangeNeighbor(request *NeighborChangeStateCommand) error { + remoteIP := request.remoteIP + cmd := request.command arg := &api.Arguments{ RouterId: remoteIP.String(), } @@ -1154,7 +1162,8 @@ func NewNeighborPolicyCommand(addr string) *NeighborPolicyCommand { } } -func showNeighborPolicy(remoteIP net.IP) error { +func showNeighborPolicy(request *NeighborPolicyCommand) error { + remoteIP := request.remoteIP rt, err := checkAddressFamily(net.IP{}) if err != nil { return err @@ -1176,7 +1185,7 @@ func showNeighborPolicy(remoteIP net.IP) error { } fmt.Printf("DefaultImportPolicy: %s\n", ap.DefaultImportPolicy) - fmt.Printf("DefaultImportPolicy: %s\n", ap.DefaultExportPolicy) + fmt.Printf("DefaultExportPolicy: %s\n", ap.DefaultExportPolicy) fmt.Printf("ImportPolicies:\n") for _, inPolicy := range ap.ImportPolicies { @@ -1202,7 +1211,9 @@ func (x *NeighborPolicyCommand) Execute(args []string) error { return err } } else { - parser.Usage = "neighbor [ <neighbor address> ] policy \n gobgp neighbor [ <neighbor address> ]" + parser.Usage = "neighbor <neighbor address> policy \n gobgp neighbor <neighbor address> policy" + parser.AddCommand(CMD_ADD, "subcommand to add routing policy", "", NewNeighborPolicyAddCommand(x.remoteIP)) + parser.AddCommand(CMD_DEL, "subcommand to delete routing policy", "", NewNeighborPolicyDelCommand(x.remoteIP)) if _, err := parser.ParseArgs(eArgs); err != nil { os.Exit(1) } @@ -1210,6 +1221,154 @@ func (x *NeighborPolicyCommand) Execute(args []string) error { return nil } +type NeighborPolicyAddCommand struct { + remoteIP net.IP +} + +func NewNeighborPolicyAddCommand(addr net.IP) *NeighborPolicyAddCommand { + return &NeighborPolicyAddCommand{ + remoteIP: addr, + } +} +func (x *NeighborPolicyAddCommand) Execute(args []string) error { + eArgs := extractArgs(CMD_ADD) + parser := flags.NewParser(nil, flags.Default) + parser.Usage = "neighbor <neighbor address> policy add" + parser.AddCommand(CMD_IMPORT, "subcommand to add import policies to neighbor", "", NewNeighborPolicyChangeCommand(CMD_ADD, CMD_IMPORT, x.remoteIP)) + parser.AddCommand(CMD_EXPORT, "subcommand to add export policies to neighbor", "", NewNeighborPolicyChangeCommand(CMD_ADD, CMD_EXPORT, x.remoteIP)) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } + return nil +} + +type NeighborPolicyDelCommand struct { + remoteIP net.IP +} + +func NewNeighborPolicyDelCommand(addr net.IP) *NeighborPolicyDelCommand { + return &NeighborPolicyDelCommand{ + remoteIP: addr, + } +} + +func (x *NeighborPolicyDelCommand) Execute(args []string) error { + eArgs := extractArgs(CMD_DEL) + parser := flags.NewParser(nil, flags.Default) + parser.Usage = "neighbor <neighbor address> policy del" + parser.AddCommand(CMD_IMPORT, "subcommand to delete import policies from neighbor", "", NewNeighborPolicyChangeCommand(CMD_DEL, CMD_IMPORT, x.remoteIP)) + parser.AddCommand(CMD_EXPORT, "subcommand to delete export policies from neighbor", "", NewNeighborPolicyChangeCommand(CMD_DEL, CMD_EXPORT, x.remoteIP)) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } + return nil +} + +type NeighborPolicyChangeCommand struct { + operation string + policyOperation string + remoteIP net.IP +} + +func NewNeighborPolicyChangeCommand(operation string, pOperation string, addr net.IP) *NeighborPolicyChangeCommand { + return &NeighborPolicyChangeCommand{ + operation: operation, + policyOperation: pOperation, + remoteIP: addr, + } +} + +func parseRouteAction(rType string) (string, error) { + routeActionUpper := strings.ToUpper(rType) + var routeAction string + switch routeActionUpper { + case policy.ROUTE_ACCEPT, policy.ROUTE_REJECT: + routeAction = routeActionUpper + default: + return "", fmt.Errorf("invalid route action: %s\nPlease enter the accept or reject", rType) + } + return routeAction, nil +} + +func parsePolicy(pNames string) []*api.PolicyDefinition { + pList := strings.Split(pNames, ",") + policyList := make([]*api.PolicyDefinition, 0) + for _, p := range pList { + if p != "" { + policy := &api.PolicyDefinition{ + PolicyDefinitionName: p, + } + policyList = append(policyList, policy) + } + } + return policyList +} + +func modNeighborPolicy(eArg []string, request *NeighborPolicyChangeCommand) error { + var operation api.Operation + pol := &api.ApplyPolicy{} + switch request.operation { + case CMD_ADD: + policies := parsePolicy(eArg[0]) + defaultPolicy, err := parseRouteAction(eArg[1]) + if err != nil { + return err + } + switch request.policyOperation { + case CMD_IMPORT: + pol.ImportPolicies = policies + pol.DefaultImportPolicy = defaultPolicy + case CMD_EXPORT: + pol.ExportPolicies = policies + pol.DefaultExportPolicy = defaultPolicy + } + operation = api.Operation_ADD + + case CMD_DEL: + operation = api.Operation_DEL + } + arg := &api.PolicyArguments{ + Resource: api.Resource_POLICY_ROUTEPOLICY, + Operation: operation, + RouterId: request.remoteIP.String(), + Name: request.policyOperation, + ApplyPolicy: pol, + } + stream, err := client.ModNeighborPolicy(context.Background()) + if err != nil { + return err + } + err = stream.Send(arg) + if err != nil { + return err + } + stream.CloseSend() + + res, e := stream.Recv() + if e != nil { + return e + } + if res.Code != api.Error_SUCCESS { + return fmt.Errorf("error: code: %d, msg: %s", res.Code, res.Msg) + } + return nil +} + +func (x *NeighborPolicyChangeCommand) Execute(args []string) error { + eArgs := extractArgs(x.policyOperation) + if x.operation == CMD_ADD && len(eArgs) != 2 { + return fmt.Errorf("usage: neighbor <neighbor address> policy %s %s <%s policy name> <default %s policy>", + x.operation, x.policyOperation, x.policyOperation, x.policyOperation) + } else if x.operation == CMD_DEL && len(eArgs) != 0 { + return fmt.Errorf("usage: neighbor <neighbor address> policy %s %s", x.operation, x.policyOperation) + } else { + if err := requestGrpc(CMD_NEIGHBOR+"_"+CMD_POLICY+"_"+x.operation, eArgs, x); err != nil { + return err + } + } + return nil +} + type PolicyCommand struct{} func (x *PolicyCommand) Execute(args []string) error { @@ -1313,7 +1472,12 @@ func showPolicyPrefix(args []string) error { fmt.Println(string(j)) return nil } - + if globalOpts.Quiet { + for _, p := range ps.PrefixList { + fmt.Printf("%s/%d %s\n", p.Address, p.MaskLength, p.MaskLengthRange) + } + return nil + } format, _ := formatPolicyPrefix([]*api.PrefixSet{ps}) fmt.Printf(format, "Name", "Prefix", "MaskRange") for i, p := range ps.PrefixList { @@ -1334,17 +1498,22 @@ func (x *PolicyPrefixCommand) Execute(args []string) error { return err } return nil - } else if len(eArgs) == 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == CMD_ADD || eArgs[0] == CMD_DEL) { + } else if len(eArgs) >= 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == CMD_ADD || eArgs[0] == CMD_DEL) { + if len(eArgs) != 1 { + return fmt.Errorf("Argument can not be entered: %s", eArgs[1:]) + } if err := requestGrpc(CMD_POLICY+"_"+CMD_PREFIX, eArgs, nil); err != nil { return err } return nil } parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy prefix [OPTIONS]\n gobgp policy prefix" - parser.AddCommand(CMD_ADD, "subcommand for add prefix condition to policy", "", &PolicyPrefixAddCommand{}) - parser.AddCommand(CMD_DEL, "subcommand for delete prefix condition from policy", "", &PolicyPrefixDelCommand{}) - parser.ParseArgs(eArgs) + parser.Usage = "policy prefix [<prefix set name>],\n gobgp policy prefix" + parser.AddCommand(CMD_ADD, "subcommand to add prefix condition to policy", "", &PolicyPrefixAddCommand{}) + parser.AddCommand(CMD_DEL, "subcommand to delete prefix condition from policy", "", &PolicyPrefixDelCommand{}) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -1389,7 +1558,7 @@ func parsePrefixSet(eArgs []string) (*api.PrefixSet, error) { } } if min >= max { - return nil, fmt.Errorf("invalid mask length range: %s\nTo a large value to the right from the left", maskRange) + return nil, fmt.Errorf("invalid mask length range: %s\nlarge value to the right from the left", maskRange) } prefix.MaskLengthRange = maskRange } @@ -1409,7 +1578,7 @@ func modPolicyPrefix(modtype string, eArgs []string) error { switch modtype { case CMD_ADD: if len(eArgs) < 2 { - return fmt.Errorf("policy prefix add <prefix set name> <prefix> [<mask length renge>]") + return fmt.Errorf("usage: policy prefix add <prefix set name> <prefix> [<mask length renge>]") } if prefixSet, e = parsePrefixSet(eArgs); e != nil { return e @@ -1460,16 +1629,12 @@ func modPolicyPrefix(modtype string, eArgs []string) error { func (x *PolicyPrefixAddCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ADD) if len(eArgs) == 0 || len(eArgs) > 3 { - return fmt.Errorf("policy prefix add <prefix set name> <prefix> [<mask length renge> ]") - } else if !(eArgs[0] == "-h" || eArgs[0] == "--help") { + return fmt.Errorf("usage: policy prefix add <prefix set name> <prefix> [<mask length renge> ]") + } else { if err := requestGrpc(CMD_POLICY+"_"+CMD_PREFIX+"_"+CMD_ADD, eArgs, nil); err != nil { return err } - return nil } - parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy prefix add <prefix set name> <prefix> [mask length renge]" - parser.ParseArgs(eArgs) return nil } @@ -1478,7 +1643,7 @@ type PolicyPrefixDelCommand struct{} func (x *PolicyPrefixDelCommand) Execute(args []string) error { eArgs := extractArgs(CMD_DEL) if len(eArgs) > 3 { - return fmt.Errorf("policy prefix del <prefix set name> [<prefix> [<mask length range>]] ") + return fmt.Errorf("usage: policy prefix del <prefix set name> [<prefix> [<mask length range>]] ") } else if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == "all") { if err := requestGrpc(CMD_POLICY+"_"+CMD_PREFIX+"_"+CMD_DEL, eArgs, nil); err != nil { return err @@ -1486,9 +1651,11 @@ func (x *PolicyPrefixDelCommand) Execute(args []string) error { return nil } parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy prefix del <prefix set name> [<prefix> [<mask length range>]]" - parser.AddCommand(CMD_ALL, "subcommand for delete all prefix condition from policy", "", &PolicyPrefixDelAllCommand{}) - parser.ParseArgs(eArgs) + parser.Usage = "policy prefix del <prefix set name> [<prefix> [<mask length range>]],\n gobgp policy prefix del" + parser.AddCommand(CMD_ALL, "subcommand to delete all prefix condition from policy", "", &PolicyPrefixDelAllCommand{}) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -1496,17 +1663,12 @@ type PolicyPrefixDelAllCommand struct{} func (x *PolicyPrefixDelAllCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ALL) - if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help") { - return fmt.Errorf("Argument can not be entered") - } else if len(eArgs) == 0 { - if err := requestGrpc(CMD_POLICY+"_"+CMD_PREFIX+"_"+CMD_DEL, eArgs, nil); err != nil { - return err - } + if len(eArgs) > 0 { + return fmt.Errorf("Argument can not be entered: %s", eArgs) + } + if err := requestGrpc(CMD_POLICY+"_"+CMD_PREFIX+"_"+CMD_DEL, eArgs, nil); err != nil { + return err } - - parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy prefix del all" - parser.ParseArgs(eArgs) return nil } @@ -1592,7 +1754,12 @@ func showPolicyNeighbor(args []string) error { fmt.Println(string(j)) return nil } - + if globalOpts.Quiet { + for _, n := range ns.NeighborList { + fmt.Println(n.Address) + } + return nil + } format := formatPolicyNeighbor([]*api.NeighborSet{ns}) fmt.Printf(format, "Name", "Address") for i, n := range ns.NeighborList { @@ -1613,17 +1780,22 @@ func (x *PolicyNeighborCommand) Execute(args []string) error { return err } return nil - } else if len(eArgs) == 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == CMD_ADD || eArgs[0] == CMD_DEL) { + } else if len(eArgs) >= 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == CMD_ADD || eArgs[0] == CMD_DEL) { + if len(eArgs) != 1 { + return fmt.Errorf("Argument can not be entered: %s", eArgs[1:]) + } if err := requestGrpc(CMD_POLICY+"_"+CMD_NEIGHBOR, eArgs, nil); err != nil { return err } return nil } parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy neighbor [OPTIONS]\n gobgp policy neighbor" - parser.AddCommand(CMD_ADD, "subcommand for add neighbor condition to policy", "", &PolicyNeighborAddCommand{}) - parser.AddCommand(CMD_DEL, "subcommand for delete neighbor condition from policy", "", &PolicyNeighborDelCommand{}) - parser.ParseArgs(eArgs) + parser.Usage = "policy neighbor [<neighbor set name>],\n gobgp policy neighbor" + parser.AddCommand(CMD_ADD, "subcommand to add neighbor condition to policy", "", &PolicyNeighborAddCommand{}) + parser.AddCommand(CMD_DEL, "subcommand to delete neighbor condition from policy", "", &PolicyNeighborDelCommand{}) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -1656,7 +1828,7 @@ func modPolicyNeighbor(modtype string, eArgs []string) error { switch modtype { case CMD_ADD: if len(eArgs) < 2 { - return fmt.Errorf("policy neighbor add <neighbor set name> <address>") + return fmt.Errorf("usage: policy neighbor add <neighbor set name> <address>") } if neighborSet, e = parseNeighborSet(eArgs); e != nil { return e @@ -1707,16 +1879,12 @@ func modPolicyNeighbor(modtype string, eArgs []string) error { func (x *PolicyNeighborAddCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ADD) if len(eArgs) == 0 || len(eArgs) > 2 { - return fmt.Errorf("policy neighbor add <neighbor set name> <address>") - } else if !(eArgs[0] == "-h" || eArgs[0] == "--help") { + return fmt.Errorf("usage: policy neighbor add <neighbor set name> <address>") + } else { if err := requestGrpc(CMD_POLICY+"_"+CMD_NEIGHBOR+"_"+CMD_ADD, eArgs, nil); err != nil { return err } - return nil } - parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy neighbor add <neighbor set name> <address>" - parser.ParseArgs(eArgs) return nil } @@ -1725,7 +1893,7 @@ type PolicyNeighborDelCommand struct{} func (x *PolicyNeighborDelCommand) Execute(args []string) error { eArgs := extractArgs(CMD_DEL) if len(eArgs) > 3 { - return fmt.Errorf("policy neighbor del [<neighbor set name> [<address>]] ") + return fmt.Errorf("usage: policy neighbor del [<neighbor set name> [<address>]]") } else if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == "all") { if err := requestGrpc(CMD_POLICY+"_"+CMD_NEIGHBOR+"_"+CMD_DEL, eArgs, nil); err != nil { return err @@ -1733,9 +1901,11 @@ func (x *PolicyNeighborDelCommand) Execute(args []string) error { return nil } parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy neighbor del [<neighbor set name> [<address>]]" - parser.AddCommand(CMD_ALL, "subcommand for delete all neighbor condition from policy", "", &PolicyNeighborDelAllCommand{}) - parser.ParseArgs(eArgs) + parser.Usage = "policy neighbor del [<neighbor set name> [<address>]],\n gobgp policy neighbor del" + parser.AddCommand(CMD_ALL, "subcommand to delete all neighbor condition from policy", "", &PolicyNeighborDelAllCommand{}) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -1743,17 +1913,12 @@ type PolicyNeighborDelAllCommand struct{} func (x *PolicyNeighborDelAllCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ALL) - if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help") { - return fmt.Errorf("Argument can not be entered") - } else if len(eArgs) == 0 { - if err := requestGrpc(CMD_POLICY+"_"+CMD_NEIGHBOR+"_"+CMD_DEL, eArgs, nil); err != nil { - return err - } + if len(eArgs) > 0 { + return fmt.Errorf("Argument can not be entered: %s", eArgs) + } + if err := requestGrpc(CMD_POLICY+"_"+CMD_NEIGHBOR+"_"+CMD_DEL, eArgs, nil); err != nil { + return err } - - parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy neighbor del all" - parser.ParseArgs(eArgs) return nil } @@ -1785,7 +1950,7 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) { 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) @@ -1794,7 +1959,7 @@ func showPolicyStatement(head string, pd *api.PolicyDefinition) { fmt.Print("\n") } asPathLentgh := st.Conditions.MatchAsPathLength - fmt.Printf("%s AsPathLength: %s %s\n", head, asPathLentgh.Value, asPathLentgh.Operator) + 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) fmt.Printf("%s %s\n", head, st.Actions.RouteAction) @@ -1858,6 +2023,13 @@ func showPolicyRoutePolicy(args []string) error { return nil } + if globalOpts.Quiet { + for _, st := range pd.StatementList { + fmt.Println(st.StatementNeme) + } + return nil + } + fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName) showPolicyStatement("", pd) return nil @@ -1870,17 +2042,22 @@ func (x *PolicyRoutePolicyCommand) Execute(args []string) error { return err } return nil - } else if len(eArgs) == 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == CMD_ADD || eArgs[0] == CMD_DEL) { + } else if len(eArgs) >= 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == CMD_ADD || eArgs[0] == CMD_DEL) { + if len(eArgs) != 1 { + return fmt.Errorf("Argument can not be entered: %s", eArgs[1:]) + } if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY, eArgs, nil); err != nil { return err } return nil } parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy routepolicy [OPTIONS]\n gobgp policy routepolicy" - parser.AddCommand(CMD_ADD, "subcommand for add routing policy", "", &PolicyRoutePolicyAddCommand{}) - parser.AddCommand(CMD_DEL, "subcommand for delete routing policy", "", &PolicyRoutePolicyDelCommand{}) - parser.ParseArgs(eArgs) + parser.Usage = "policy routepolicy [<policy name>],\n gobgp policy routepolicy" + parser.AddCommand(CMD_ADD, "subcommand to add routing policy", "", &PolicyRoutePolicyAddCommand{}) + parser.AddCommand(CMD_DEL, "subcommand to delete routing policy", "", &PolicyRoutePolicyDelCommand{}) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -1904,11 +2081,11 @@ func parseConditions() (*api.Conditions, error) { if idx == -1 { return nil, fmt.Errorf("invalid as path length: %s\nPlease enter the <value>,<operator>", asPathLen) } - value := asPathLen[:idx] + operator := asPathLen[:idx] + value := asPathLen[idx+1:] if _, err := strconv.ParseUint(value, 10, 32); err != nil { return nil, fmt.Errorf("invalid as path length: %s\nPlease enter a numeric", value) } - operator := asPathLen[idx+1:] conditions.MatchAsPathLength = &api.AsPathLength{ Value: value, Operator: operator, @@ -1918,7 +2095,7 @@ func parseConditions() (*api.Conditions, error) { optionUpper := strings.ToUpper(conditionOpts.Option) var option string switch optionUpper { - case "ANY", "ALL", "INVERT": + case policy.OPTIONS_ANY, policy.OPTIONS_ALL, policy.OPTIONS_INVERT: option = optionUpper default: return nil, fmt.Errorf("invalid condition option: %s\nPlease enter the any or all or invert", @@ -1931,46 +2108,41 @@ func parseConditions() (*api.Conditions, error) { func parseActions() (*api.Actions, error) { actions := &api.Actions{} - if actionOpts.RouteType != "" { - routeTypeUpper := strings.ToUpper(actionOpts.RouteType) - var routeType string - switch routeTypeUpper { - case "ACCEPT", "REJECT": - routeType = routeTypeUpper - default: - return nil, fmt.Errorf("invalid route type: %s\nPlease enter the accept or reject", - actionOpts.RouteType) + if actionOpts.RouteAction != "" { + routeAction, e := parseRouteAction(actionOpts.RouteAction) + if e != nil { + return nil, e } - actions.RouteAction = routeType + actions.RouteAction = routeAction } return actions, nil } -func modPolicyRoutePolicy(modtype string, stmtType string, eArgs []string, pName string, sName string) error { +func modPolicyRoutePolicy(modtype string, stmtType string, eArgs []string, request interface{}) error { var e error var operation api.Operation pd := &api.PolicyDefinition{} switch modtype { case CMD_ADD: - stmt := &api.Statement{ - StatementNeme: sName, - } + stmt := &api.Statement{} switch stmtType { case CMD_CONDITIONS: conditions, err := parseConditions() if err != nil { return err } + stmt.StatementNeme = request.(*PolicyRoutePolicyAddConditionsCommand).statementName stmt.Conditions = conditions + pd.PolicyDefinitionName = request.(*PolicyRoutePolicyAddConditionsCommand).policyName case CMD_ACTIONS: actions, err := parseActions() if err != nil { return err } + stmt.StatementNeme = request.(*PolicyRoutePolicyAddActionsCommand).statementName stmt.Actions = actions + pd.PolicyDefinitionName = request.(*PolicyRoutePolicyAddActionsCommand).policyName } - - pd.PolicyDefinitionName = pName pd.StatementList = []*api.Statement{stmt} operation = api.Operation_ADD @@ -2016,14 +2188,16 @@ func modPolicyRoutePolicy(modtype string, stmtType string, eArgs []string, pName func (x *PolicyRoutePolicyAddCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ADD) + parser := flags.NewParser(nil, flags.Default) if len(eArgs) < 2 { - return fmt.Errorf("policy routepolicy add <routing policy name> <statement name>") + return fmt.Errorf("usage: policy routepolicy add <routing policy name> <statement name>") } - parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy routepolicy add <routing policy name>" + parser.Usage = "policy routepolicy add <routing policy name> <statement name>" parser.AddCommand(CMD_CONDITIONS, "subcommand for routing policy conditions", "", NewPolicyRoutePolicyAddConditionsCommand(eArgs[0], eArgs[1])) parser.AddCommand(CMD_ACTIONS, "subcommand for routing policy actions", "", NewPolicyRoutePolicyAddActionsCommand(eArgs[0], eArgs[1])) - parser.ParseArgs(eArgs) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -2043,9 +2217,11 @@ func (x *PolicyRoutePolicyAddConditionsCommand) Execute(args []string) error { eArgs := extractArgs(CMD_CONDITIONS) parser := flags.NewParser(&conditionOpts, flags.Default) parser.Usage = "policy routepolicy add <routing policy name> <statement name> conditions [OPTIONS]" - parser.ParseArgs(eArgs) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } if len(eArgs) == 0 { - return fmt.Errorf("policy routepolicy add <routing policy name> <statement name> conditions [OPTIONS]") + return fmt.Errorf("usage: policy routepolicy add <routing policy name> <statement name> conditions [OPTIONS]") } else if !(eArgs[0] == "-h" || eArgs[0] == "--help") { if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY+"_"+CMD_ADD+"_"+CMD_CONDITIONS, eArgs, x); err != nil { return err @@ -2071,9 +2247,11 @@ func (x *PolicyRoutePolicyAddActionsCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ACTIONS) parser := flags.NewParser(&actionOpts, flags.Default) parser.Usage = "policy routepolicy add <routing policy name> <statement name> actions [OPTIONS]" - parser.ParseArgs(eArgs) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } if len(eArgs) == 0 { - return fmt.Errorf("policy routepolicy add <routing policy name> <statement name> actions [OPTIONS]") + return fmt.Errorf("usage: policy routepolicy add <routing policy name> <statement name> actions [OPTIONS]") } else if !(eArgs[0] == "-h" || eArgs[0] == "--help") { if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY+"_"+CMD_ADD+"_"+CMD_ACTIONS, eArgs, x); err != nil { return err @@ -2086,18 +2264,21 @@ type PolicyRoutePolicyDelCommand struct{} func (x *PolicyRoutePolicyDelCommand) Execute(args []string) error { eArgs := extractArgs(CMD_DEL) - if len(eArgs) > 2 { - return fmt.Errorf("policy routepolicy del <routing policy name> [<statement name>]") - } else if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == "all") { + if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == "all") { + if len(eArgs) > 2 { + return fmt.Errorf("Argument can not be entered: %s", eArgs[2:]) + } if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY+"_"+CMD_DEL, eArgs, nil); err != nil { return err } return nil } parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy routepolicy del <routing policy name> [<statement name>]" - parser.AddCommand(CMD_ALL, "subcommand for delete all routing policy", "", &PolicyRoutePolicyDelAllCommand{}) - parser.ParseArgs(eArgs) + parser.Usage = "policy routepolicy del <routing policy name> [<statement name>],\n gobgp policy routepolicy del" + parser.AddCommand(CMD_ALL, "subcommand to delete all routing policy", "", &PolicyRoutePolicyDelAllCommand{}) + if _, err := parser.ParseArgs(eArgs); err != nil { + os.Exit(1) + } return nil } @@ -2105,17 +2286,12 @@ type PolicyRoutePolicyDelAllCommand struct{} func (x *PolicyRoutePolicyDelAllCommand) Execute(args []string) error { eArgs := extractArgs(CMD_ALL) - if len(eArgs) > 0 && !(eArgs[0] == "-h" || eArgs[0] == "--help") { - return fmt.Errorf("Argument can not be entered") - } else if len(eArgs) == 0 { - if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY+"_"+CMD_DEL, eArgs, nil); err != nil { - return err - } + if len(eArgs) > 0 { + return fmt.Errorf("Argument can not be entered: %s", eArgs) + } + if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY+"_"+CMD_DEL, eArgs, nil); err != nil { + return err } - - parser := flags.NewParser(nil, flags.Default) - parser.Usage = "policy routepolicy del all" - parser.ParseArgs(eArgs) return nil } @@ -2136,20 +2312,20 @@ var neighborsOpts struct { } var conditionOpts struct { - Prefix string `short:"p" long:"prefix" description:"specifying a prefix set name of policy"` - Neighbor string `short:"n" long:"neighbor" description:"specifying a neighbor set name of policy"` - AsPathLength string `short:"a" long:"aspath-len" description:"specifying an as path length of policy"` - Option string `short:"o" long:"option" description:"specifying an option of policy"` + Prefix string `long:"prefix" description:"specifying a prefix set name of policy"` + Neighbor string `long:"neighbor" description:"specifying a neighbor set name of policy"` + AsPathLength string `long:"aspath-len" description:"specifying an as path length of policy (<operator>,<numeric>)"` + Option string `long:"option" description:"specifying an option of policy (any | all | invert)"` } var actionOpts struct { - RouteType string `short:"r" long:"route-type" description:"specifying a route type of policy (accept | reject)"` + RouteAction string `long:"route-action" description:"specifying a route action of policy (accept | reject)"` } func main() { cmds = []string{CMD_GLOBAL, CMD_NEIGHBOR, CMD_POLICY, CMD_RIB, CMD_ADD, CMD_DEL, CMD_ALL, CMD_LOCAL, CMD_ADJ_IN, CMD_ADJ_OUT, CMD_RESET, CMD_SOFT_RESET, CMD_SOFT_RESET_IN, CMD_SOFT_RESET_OUT, CMD_SHUTDOWN, CMD_ENABLE, - CMD_DISABLE, CMD_PREFIX, CMD_ROUTEPOLICY, CMD_CONDITIONS, CMD_ACTIONS} + CMD_DISABLE, CMD_PREFIX, CMD_ROUTEPOLICY, CMD_CONDITIONS, CMD_ACTIONS, CMD_IMPORT, CMD_EXPORT} eArgs := extractArgs("") parser := flags.NewParser(&globalOpts, flags.Default) diff --git a/policy/policy.go b/policy/policy.go index cf93d640..b97f055f 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -870,6 +870,30 @@ func ipPrefixCalculate(path table.Path, cPrefix Prefix) bool { return false } +const ( + ROUTE_ACCEPT string = "ACCEPT" + ROUTE_REJECT = "REJECT" +) + +const ( + OPTIONS_ALL string = "ALL" + OPTIONS_ANY = "ANY" + OPTIONS_INVERT = "INVERT" +) + +func MatchSetOptionToString(option config.MatchSetOptionsType) string { + var op string + switch option { + case config.MATCH_SET_OPTIONS_TYPE_ALL: + op = OPTIONS_ALL + case config.MATCH_SET_OPTIONS_TYPE_ANY: + op = OPTIONS_ANY + case config.MATCH_SET_OPTIONS_TYPE_INVERT: + op = OPTIONS_INVERT + } + return op +} + func (p *Policy) ToApiStruct() *api.PolicyDefinition { resStatements := make([]*api.Statement, 0) for _, st := range p.Statements { @@ -929,26 +953,17 @@ func (p *Policy) ToApiStruct() *api.PolicyDefinition { } } } - var op string - switch st.MatchSetOptions { - case config.MATCH_SET_OPTIONS_TYPE_ALL: - op = "ALL" - case config.MATCH_SET_OPTIONS_TYPE_ANY: - op = "ANY" - case config.MATCH_SET_OPTIONS_TYPE_INVERT: - op = "INVERT" - } resConditions := &api.Conditions{ MatchPrefixSet: resPrefixSet, MatchNeighborSet: resNeighborSet, MatchAsPathLength: resAsPathLength, - MatchSetOptions: op, + MatchSetOptions: MatchSetOptionToString(st.MatchSetOptions), } resActions := &api.Actions{ - RouteAction: "REJECT", + RouteAction: ROUTE_REJECT, } - if st.Actions.(*RoutingActions).AcceptRoute { - resActions.RouteAction = "ACCEPT" + if st.routingAction.AcceptRoute { + resActions.RouteAction = ROUTE_ACCEPT } resStatement := &api.Statement{ StatementNeme: st.Name, @@ -1156,11 +1171,11 @@ func ConditionsToConfigStruct(reqConditions *api.Conditions) config.Conditions { } var setOption config.MatchSetOptionsType switch reqConditions.MatchSetOptions { - case "ALL": + case OPTIONS_ALL: setOption = config.MATCH_SET_OPTIONS_TYPE_ALL - case "ANY": + case OPTIONS_ANY: setOption = config.MATCH_SET_OPTIONS_TYPE_ANY - case "INVERT": + case OPTIONS_INVERT: setOption = config.MATCH_SET_OPTIONS_TYPE_INVERT } conditions.MatchSetOptions = setOption @@ -1171,9 +1186,9 @@ func ActionsToConfigStruct(reqActions *api.Actions) config.Actions { acceptRoute := false rejectRoute := false switch reqActions.RouteAction { - case "ACCEPT": + case ROUTE_ACCEPT: acceptRoute = true - case "REJECT": + case ROUTE_REJECT: rejectRoute = true } actions := config.Actions{ @@ -1236,26 +1251,17 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe neighborSet = NeighborSetToApiStruct(conNeighborSetList[idxNeighborSet]) } asPathLength := AsPathLengthToApiStruct(st.Conditions.BgpConditions.AsPathLength) - var op string - switch conditions.MatchSetOptions { - case config.MATCH_SET_OPTIONS_TYPE_ALL: - op = "ALL" - case config.MATCH_SET_OPTIONS_TYPE_ANY: - op = "ANY" - case config.MATCH_SET_OPTIONS_TYPE_INVERT: - op = "INVERT" - } resConditions := &api.Conditions{ MatchPrefixSet: prefixSet, MatchNeighborSet: neighborSet, MatchAsPathLength: asPathLength, - MatchSetOptions: op, + MatchSetOptions: MatchSetOptionToString(conditions.MatchSetOptions), } resActions := &api.Actions{ - RouteAction: "REJECT", + RouteAction: ROUTE_REJECT, } if actions.AcceptRoute { - resActions.RouteAction = "ACCEPT" + resActions.RouteAction = ROUTE_ACCEPT } resStatement := &api.Statement{ StatementNeme: st.Name, @@ -1270,3 +1276,11 @@ func PolicyDefinitionToApiStruct(pd config.PolicyDefinition, df config.DefinedSe } return resPolicyDefinition } + +func PoliciesToString(reqPolicies []*api.PolicyDefinition) []string { + policies := make([]string, 0) + for _, reqPolicy := range reqPolicies { + policies = append(policies, reqPolicy.PolicyDefinitionName) + } + return policies +} diff --git a/server/grpc_server.go b/server/grpc_server.go index f1d040a2..79a3dc4d 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -41,6 +41,10 @@ const ( REQ_NEIGHBOR_ENABLE REQ_NEIGHBOR_DISABLE REQ_NEIGHBOR_POLICY + REQ_NEIGHBOR_POLICY_ADD_IMPORT + REQ_NEIGHBOR_POLICY_ADD_EXPORT + REQ_NEIGHBOR_POLICY_DEL_IMPORT + REQ_NEIGHBOR_POLICY_DEL_EXPORT REQ_GLOBAL_RIB REQ_GLOBAL_ADD REQ_GLOBAL_DELETE @@ -293,6 +297,52 @@ func (s *Server) GetNeighborPolicy(ctx context.Context, arg *api.Arguments) (*ap return res.Data.(*api.ApplyPolicy), nil } +func (s *Server) ModNeighborPolicy(stream api.Grpc_ModNeighborPolicyServer) error { + for { + arg, err := stream.Recv() + if err == io.EOF { + return nil + } else if err != nil { + return err + } + + if arg.Resource != api.Resource_POLICY_ROUTEPOLICY { + return fmt.Errorf("unsupported resource: %s", arg.Resource) + } + var rf bgp.RouteFamily + var reqType int + switch arg.Operation { + case api.Operation_ADD: + switch arg.Name { + case "import": + reqType = REQ_NEIGHBOR_POLICY_ADD_IMPORT + case "export": + reqType = REQ_NEIGHBOR_POLICY_ADD_EXPORT + } + case api.Operation_DEL: + switch arg.Name { + case "import": + reqType = REQ_NEIGHBOR_POLICY_DEL_IMPORT + case "export": + reqType = REQ_NEIGHBOR_POLICY_DEL_EXPORT + } + } + req := NewGrpcRequest(reqType, arg.RouterId, rf, arg.ApplyPolicy) + s.bgpServerCh <- req + res := <-req.ResponseCh + if err := res.Err(); err != nil { + log.Debug(err.Error()) + return err + } + err = stream.Send(&api.Error{ + Code: api.Error_SUCCESS, + }) + if err != nil { + return err + } + } +} + func (s *Server) getPolicies(reqType int, arg *api.PolicyArguments, stream interface{}) error { var rf bgp.RouteFamily req := NewGrpcRequest(reqType, "", rf, nil) diff --git a/server/peer.go b/server/peer.go index 02585e11..46db99a9 100644 --- a/server/peer.go +++ b/server/peer.go @@ -132,6 +132,7 @@ func (peer *Peer) setPolicy(policyMap map[string]*policy.Policy) { } } peer.importPolicies = inPolicies + peer.defaultImportPolicy = policyConfig.DefaultImportPolicy // configure export policy outPolicies := make([]*policy.Policy, 0) @@ -147,6 +148,7 @@ func (peer *Peer) setPolicy(policyMap map[string]*policy.Policy) { } } peer.exportPolicies = outPolicies + peer.defaultExportPolicy = policyConfig.DefaultExportPolicy } func (peer *Peer) configuredRFlist() []bgp.RouteFamily { @@ -588,10 +590,8 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { } result.Data = err case REQ_NEIGHBOR_POLICY: - result := &GrpcResponse{} resInPolicies := []*api.PolicyDefinition{} resOutPolicies := []*api.PolicyDefinition{} - // 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. conInPolicyNames := peer.peerConfig.ApplyPolicy.ImportPolicies @@ -624,13 +624,13 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { resOutPolicies = append(resOutPolicies, &api.PolicyDefinition{PolicyDefinitionName: conOutPolicyName}) } } - defaultInPolicy := "REJECT" - defaultOutPolicy := "REJECT" - if peer.defaultImportPolicy == 0 { - defaultInPolicy = "ACCEPT" + defaultInPolicy := policy.ROUTE_REJECT + defaultOutPolicy := policy.ROUTE_REJECT + if peer.defaultImportPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE { + defaultInPolicy = policy.ROUTE_ACCEPT } - if peer.defaultExportPolicy == 0 { - defaultOutPolicy = "ACCEPT" + if peer.defaultExportPolicy == config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE { + defaultOutPolicy = policy.ROUTE_ACCEPT } result.Data = &api.ApplyPolicy{ DefaultImportPolicy: defaultInPolicy, @@ -638,10 +638,32 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { DefaultExportPolicy: defaultOutPolicy, ExportPolicies: resOutPolicies, } - grpcReq.ResponseCh <- result - - close(grpcReq.ResponseCh) - return + case REQ_NEIGHBOR_POLICY_ADD_IMPORT, REQ_NEIGHBOR_POLICY_ADD_EXPORT, REQ_NEIGHBOR_POLICY_DEL_IMPORT, REQ_NEIGHBOR_POLICY_DEL_EXPORT: + data := grpcReq.Data.([]interface{}) + reqApplyPolicy := data[0].(*api.ApplyPolicy) + reqPolicyMap := data[1].(map[string]*policy.Policy) + applyPolicy := &peer.peerConfig.ApplyPolicy + var defInPolicy, defOutPolicy config.DefaultPolicyType + if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_ADD_IMPORT { + if reqApplyPolicy.DefaultImportPolicy != policy.ROUTE_ACCEPT { + defInPolicy = config.DEFAULT_POLICY_TYPE_REJECT_ROUTE + } + peer.peerConfig.ApplyPolicy.DefaultImportPolicy = defInPolicy + applyPolicy.ImportPolicies = policy.PoliciesToString(reqApplyPolicy.ImportPolicies) + } else if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_ADD_EXPORT { + if reqApplyPolicy.DefaultExportPolicy != policy.ROUTE_ACCEPT { + defOutPolicy = config.DEFAULT_POLICY_TYPE_REJECT_ROUTE + } + peer.peerConfig.ApplyPolicy.DefaultExportPolicy = defOutPolicy + applyPolicy.ExportPolicies = policy.PoliciesToString(reqApplyPolicy.ExportPolicies) + } else if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_DEL_IMPORT { + peer.peerConfig.ApplyPolicy.DefaultImportPolicy = config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE + peer.peerConfig.ApplyPolicy.ImportPolicies = make([]string, 0) + } else if grpcReq.RequestType == REQ_NEIGHBOR_POLICY_DEL_EXPORT { + peer.peerConfig.ApplyPolicy.DefaultExportPolicy = config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE + peer.peerConfig.ApplyPolicy.ExportPolicies = make([]string, 0) + } + peer.setPolicy(reqPolicyMap) } grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) diff --git a/server/server.go b/server/server.go index 88ff5a99..47166602 100644 --- a/server/server.go +++ b/server/server.go @@ -325,6 +325,23 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) } + case REQ_NEIGHBOR_POLICY_ADD_IMPORT, REQ_NEIGHBOR_POLICY_ADD_EXPORT, REQ_NEIGHBOR_POLICY_DEL_IMPORT, REQ_NEIGHBOR_POLICY_DEL_EXPORT: + remoteAddr := grpcReq.RemoteAddr + result := &GrpcResponse{} + info, found := server.peerMap[remoteAddr] + if found { + reqApplyPolicy := grpcReq.Data.(*api.ApplyPolicy) + grpcReq.Data = []interface{}{reqApplyPolicy, server.policyMap} + msg := &serverMsg{ + msgType: SRV_MSG_API, + msgData: grpcReq, + } + info.peer.serverMsgCh <- msg + } else { + result.ResponseErr = fmt.Errorf("Neighbor that has %v doesn't exist.", remoteAddr) + grpcReq.ResponseCh <- result + close(grpcReq.ResponseCh) + } case REQ_POLICY_PREFIXES: info := server.routingPolicy.DefinedSets.PrefixSetList result := &GrpcResponse{} @@ -395,16 +412,17 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { // If only name of the PrefixSet is same, delete all of the elements of the PrefixSet. // If the same element PrefixSet, delete the it's element from PrefixSet. idxPrefixSet, idxPrefix := policy.IndexOfPrefixSet(conPrefixSetList, prefixSet) + prefix := prefixSet.PrefixList[0] if idxPrefixSet == -1 { result.ResponseErr = fmt.Errorf("Policy prefix that has %v %v/%v %v doesn't exist.", prefixSet.PrefixSetName, - prefixSet.PrefixList[0].Address, prefixSet.PrefixList[0].Masklength, prefixSet.PrefixList[0].MasklengthRange) + prefix.Address, prefix.Masklength, prefix.MasklengthRange) } else { if idxPrefix == -1 { result.ResponseErr = fmt.Errorf("Policy prefix that has %v %v/%v %v doesn't exist.", prefixSet.PrefixSetName, - prefixSet.PrefixList[0].Address, prefixSet.PrefixList[0].Masklength, prefixSet.PrefixList[0].MasklengthRange) + prefix.Address, prefix.Masklength, prefix.MasklengthRange) } else { - copy(conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix:], conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix+1:]) - conPrefixSetList[idxPrefixSet].PrefixList = conPrefixSetList[idxPrefixSet].PrefixList[:len(conPrefixSetList[idxPrefixSet].PrefixList)-1] + conPrefixSetList[idxPrefixSet].PrefixList = + append(conPrefixSetList[idxPrefixSet].PrefixList[:idxPrefix], conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix+1:]...) } } } else { @@ -418,8 +436,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { if idxPrefixSet == -1 { result.ResponseErr = fmt.Errorf("Policy prefix that has %v doesn't exist.", prefixSet.PrefixSetName) } else { - copy(conPrefixSetList[idxPrefixSet:], conPrefixSetList[idxPrefixSet+1:]) - conPrefixSetList = conPrefixSetList[:len(conPrefixSetList)-1] + conPrefixSetList = append(conPrefixSetList[:idxPrefixSet], conPrefixSetList[idxPrefixSet+1:]...) } } server.routingPolicy.DefinedSets.PrefixSetList = conPrefixSetList @@ -511,10 +528,9 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { result.ResponseErr = fmt.Errorf("Policy neighbor that has %v %v doesn't exist.", neighborSet.NeighborSetName, neighborSet.NeighborInfoList[0].Address) } else { - copy(conNeighborSetList[idxNeighborSet].NeighborInfoList[idxNeighbor:], - conNeighborSetList[idxNeighborSet].NeighborInfoList[idxNeighbor+1:]) conNeighborSetList[idxNeighborSet].NeighborInfoList = - conNeighborSetList[idxNeighborSet].NeighborInfoList[:len(conNeighborSetList[idxNeighborSet].NeighborInfoList)-1] + append(conNeighborSetList[idxNeighborSet].NeighborInfoList[:idxNeighbor], + conNeighborSetList[idxNeighborSet].NeighborInfoList[idxNeighbor+1:]...) } } } else { @@ -528,8 +544,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { if idxNeighborSet == -1 { result.ResponseErr = fmt.Errorf("Policy neighbor %v doesn't exist.", neighborSet.NeighborSetName) } else { - copy(conNeighborSetList[idxNeighborSet:], conNeighborSetList[idxNeighborSet+1:]) - conNeighborSetList = conNeighborSetList[:len(conNeighborSetList)-1] + conNeighborSetList = append(conNeighborSetList[:idxNeighborSet], conNeighborSetList[idxNeighborSet+1:]...) } } server.routingPolicy.DefinedSets.NeighborSetList = conNeighborSetList @@ -583,6 +598,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { close(grpcReq.ResponseCh) case REQ_POLICY_ROUTEPOLICY_ADD: reqPolicy := grpcReq.Data.(*api.PolicyDefinition) + reqConditions := reqPolicy.StatementList[0].Conditions + reqActions := reqPolicy.StatementList[0].Actions conPolicyList := server.routingPolicy.PolicyDefinitionList result := &GrpcResponse{} _, policyDef := policy.PolicyDefinitionToConfigStruct(reqPolicy) @@ -595,13 +612,23 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { conPolicyList[idxPolicy].StatementList = append(conPolicyList[idxPolicy].StatementList, statement) } else { - if reqPolicy.StatementList[0].Conditions != nil { - conPolicyList[idxPolicy].StatementList[idxStatement].Conditions = - statement.Conditions + conStatement := &conPolicyList[idxPolicy].StatementList[idxStatement] + if reqConditions != nil { + if reqConditions.MatchPrefixSet != nil { + conStatement.Conditions.MatchPrefixSet = statement.Conditions.MatchPrefixSet + } + if reqConditions.MatchNeighborSet != nil { + conStatement.Conditions.MatchNeighborSet = statement.Conditions.MatchNeighborSet + } + if reqConditions.MatchSetOptions != "" { + conStatement.Conditions.MatchSetOptions = statement.Conditions.MatchSetOptions + } + if reqConditions.MatchAsPathLength != nil { + conStatement.Conditions.BgpConditions.AsPathLength = statement.Conditions.BgpConditions.AsPathLength + } } - if reqPolicy.StatementList[0].Actions != nil { - conPolicyList[idxPolicy].StatementList[idxStatement].Actions = - statement.Actions + if reqActions != nil { + conStatement.Actions = statement.Actions } } } @@ -623,10 +650,8 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { if idxStatement == -1 { result.ResponseErr = fmt.Errorf("Policy Statment that has %v doesn't exist.", policyDef.StatementList[0].Name) } else { - copy(conPolicyList[idxPolicy].StatementList[idxStatement:], - conPolicyList[idxPolicy].StatementList[idxStatement+1:]) conPolicyList[idxPolicy].StatementList = - conPolicyList[idxPolicy].StatementList[:len(conPolicyList[idxPolicy].StatementList)-1] + append(conPolicyList[idxPolicy].StatementList[:idxStatement], conPolicyList[idxPolicy].StatementList[idxStatement+1:]...) } } } else { @@ -640,8 +665,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) { if idxPolicy == -1 { result.ResponseErr = fmt.Errorf("Policy that has %v doesn't exist.", policyDef.Name) } else { - copy(conPolicyList[idxPolicy:], conPolicyList[idxPolicy+1:]) - conPolicyList = conPolicyList[:len(conPolicyList)-1] + conPolicyList = append(conPolicyList[:idxPolicy], conPolicyList[idxPolicy+1:]...) } } server.routingPolicy.PolicyDefinitionList = conPolicyList |