summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNaoto Hanaue <hanaue.naoto@po.ntts.co.jp>2015-05-12 01:06:59 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-05-19 16:33:16 +0900
commit77eaf6a051f7272a3217ab199f53aa3fc9d546a6 (patch)
treea6ff0b0d39ceb3989f82b783bbe6601401e7a962
parent8d0eb0a06bbdfaa47b4979dffed28a7f38b16680 (diff)
cli: add the show command for the routing policy
% gobgp -u 10.0.255.1 policy routepolicy PolicyName policy0: StatementName st0: Conditions: PrefixSet: ps0 192.168.0.0/16 16..24 NeighborSet: ns0 10.0.0.2 MatchOption: ALL Actions: REJECT PolicyName policy1: StatementName st1: Conditions: PrefixSet: ps1 192.168.20.0/24 192.168.200.0/24 NeighborSet: ns0 10.0.0.2 MatchOption: ALL Actions: REJECT % 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 MatchOption: ALL Actions: REJECT
-rw-r--r--api/gobgp.pb.go225
-rw-r--r--api/gobgp.proto29
-rw-r--r--gobgp/main.go291
-rw-r--r--server/grpc_server.go21
-rw-r--r--server/server.go161
5 files changed, 629 insertions, 98 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 809e8d50..8a54a2c7 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -35,6 +35,11 @@ It has these top-level messages:
PrefixSet
Neighbor
NeighborSet
+ Conditions
+ Actions
+ Statement
+ PolicyDefinition
+ RoutingPolicy
*/
package api
@@ -55,12 +60,13 @@ var _ = proto.Marshal
type Resource int32
const (
- Resource_GLOBAL Resource = 0
- Resource_LOCAL Resource = 1
- Resource_ADJ_IN Resource = 2
- Resource_ADJ_OUT Resource = 3
- Resource_POLICY_PREFIX Resource = 4
- Resource_POLICY_NEIGHBOR Resource = 5
+ Resource_GLOBAL Resource = 0
+ Resource_LOCAL Resource = 1
+ Resource_ADJ_IN Resource = 2
+ Resource_ADJ_OUT Resource = 3
+ Resource_POLICY_PREFIX Resource = 4
+ Resource_POLICY_NEIGHBOR Resource = 5
+ Resource_POLICY_ROUTEPOLICY Resource = 6
)
var Resource_name = map[int32]string{
@@ -70,14 +76,16 @@ var Resource_name = map[int32]string{
3: "ADJ_OUT",
4: "POLICY_PREFIX",
5: "POLICY_NEIGHBOR",
+ 6: "POLICY_ROUTEPOLICY",
}
var Resource_value = map[string]int32{
- "GLOBAL": 0,
- "LOCAL": 1,
- "ADJ_IN": 2,
- "ADJ_OUT": 3,
- "POLICY_PREFIX": 4,
- "POLICY_NEIGHBOR": 5,
+ "GLOBAL": 0,
+ "LOCAL": 1,
+ "ADJ_IN": 2,
+ "ADJ_OUT": 3,
+ "POLICY_PREFIX": 4,
+ "POLICY_NEIGHBOR": 5,
+ "POLICY_ROUTEPOLICY": 6,
}
func (x Resource) String() string {
@@ -511,11 +519,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"`
+ 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"`
}
func (m *PolicyArguments) Reset() { *m = PolicyArguments{} }
@@ -536,6 +545,13 @@ func (m *PolicyArguments) GetNeighborSet() *NeighborSet {
return nil
}
+func (m *PolicyArguments) GetPolicyDifinition() *PolicyDefinition {
+ if m != nil {
+ return m.PolicyDifinition
+ }
+ 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"`
@@ -958,6 +974,94 @@ func (m *NeighborSet) GetNeighborList() []*Neighbor {
return nil
}
+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"`
+}
+
+func (m *Conditions) Reset() { *m = Conditions{} }
+func (m *Conditions) String() string { return proto.CompactTextString(m) }
+func (*Conditions) ProtoMessage() {}
+
+func (m *Conditions) GetMatchPrefixSet() *PrefixSet {
+ if m != nil {
+ return m.MatchPrefixSet
+ }
+ return nil
+}
+
+func (m *Conditions) GetMatchNeighborSet() *NeighborSet {
+ if m != nil {
+ return m.MatchNeighborSet
+ }
+ 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"`
+}
+
+func (m *Actions) Reset() { *m = Actions{} }
+func (m *Actions) String() string { return proto.CompactTextString(m) }
+func (*Actions) ProtoMessage() {}
+
+type Statement struct {
+ StatementNeme string `protobuf:"bytes,1,opt,name=statement_neme" json:"statement_neme,omitempty"`
+ Conditions *Conditions `protobuf:"bytes,2,opt,name=conditions" json:"conditions,omitempty"`
+ Actions *Actions `protobuf:"bytes,3,opt,name=actions" json:"actions,omitempty"`
+}
+
+func (m *Statement) Reset() { *m = Statement{} }
+func (m *Statement) String() string { return proto.CompactTextString(m) }
+func (*Statement) ProtoMessage() {}
+
+func (m *Statement) GetConditions() *Conditions {
+ if m != nil {
+ return m.Conditions
+ }
+ return nil
+}
+
+func (m *Statement) GetActions() *Actions {
+ if m != nil {
+ return m.Actions
+ }
+ return nil
+}
+
+type PolicyDefinition struct {
+ PolicyDefinitionName string `protobuf:"bytes,1,opt,name=policy_definition_name" json:"policy_definition_name,omitempty"`
+ StatementList []*Statement `protobuf:"bytes,2,rep,name=statement_list" json:"statement_list,omitempty"`
+}
+
+func (m *PolicyDefinition) Reset() { *m = PolicyDefinition{} }
+func (m *PolicyDefinition) String() string { return proto.CompactTextString(m) }
+func (*PolicyDefinition) ProtoMessage() {}
+
+func (m *PolicyDefinition) GetStatementList() []*Statement {
+ if m != nil {
+ return m.StatementList
+ }
+ return nil
+}
+
+type RoutingPolicy struct {
+ PolicyDifinition []*PolicyDefinition `protobuf:"bytes,1,rep,name=policy_difinition" json:"policy_difinition,omitempty"`
+}
+
+func (m *RoutingPolicy) Reset() { *m = RoutingPolicy{} }
+func (m *RoutingPolicy) String() string { return proto.CompactTextString(m) }
+func (*RoutingPolicy) ProtoMessage() {}
+
+func (m *RoutingPolicy) GetPolicyDifinition() []*PolicyDefinition {
+ if m != nil {
+ return m.PolicyDifinition
+ }
+ return nil
+}
+
func init() {
proto.RegisterEnum("api.Resource", Resource_name, Resource_value)
proto.RegisterEnum("api.Operation", Operation_name, Operation_value)
@@ -994,6 +1098,8 @@ type GrpcClient interface {
ModPolicyPrefix(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPolicyPrefixClient, error)
GetPolicyNeighbors(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyNeighborsClient, error)
GetPolicyNeighbor(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (*NeighborSet, error)
+ GetPolicyRoutePolicies(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyRoutePoliciesClient, error)
+ GetPolicyRoutePolicy(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (*PolicyDefinition, error)
}
type grpcClient struct {
@@ -1316,6 +1422,47 @@ func (c *grpcClient) GetPolicyNeighbor(ctx context.Context, in *PolicyArguments,
return out, nil
}
+func (c *grpcClient) GetPolicyRoutePolicies(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyRoutePoliciesClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[7], c.cc, "/api.Grpc/GetPolicyRoutePolicies", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcGetPolicyRoutePoliciesClient{stream}
+ if err := x.ClientStream.SendMsg(in); err != nil {
+ return nil, err
+ }
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+type Grpc_GetPolicyRoutePoliciesClient interface {
+ Recv() (*PolicyDefinition, error)
+ grpc.ClientStream
+}
+
+type grpcGetPolicyRoutePoliciesClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcGetPolicyRoutePoliciesClient) Recv() (*PolicyDefinition, error) {
+ m := new(PolicyDefinition)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *grpcClient) GetPolicyRoutePolicy(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (*PolicyDefinition, error) {
+ out := new(PolicyDefinition)
+ err := grpc.Invoke(ctx, "/api.Grpc/GetPolicyRoutePolicy", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// Server API for Grpc service
type GrpcServer interface {
@@ -1336,6 +1483,8 @@ type GrpcServer interface {
ModPolicyPrefix(Grpc_ModPolicyPrefixServer) error
GetPolicyNeighbors(*PolicyArguments, Grpc_GetPolicyNeighborsServer) error
GetPolicyNeighbor(context.Context, *PolicyArguments) (*NeighborSet, error)
+ GetPolicyRoutePolicies(*PolicyArguments, Grpc_GetPolicyRoutePoliciesServer) error
+ GetPolicyRoutePolicy(context.Context, *PolicyArguments) (*PolicyDefinition, error)
}
func RegisterGrpcServer(s *grpc.Server, srv GrpcServer) {
@@ -1619,6 +1768,39 @@ func _Grpc_GetPolicyNeighbor_Handler(srv interface{}, ctx context.Context, codec
return out, nil
}
+func _Grpc_GetPolicyRoutePolicies_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(PolicyArguments)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(GrpcServer).GetPolicyRoutePolicies(m, &grpcGetPolicyRoutePoliciesServer{stream})
+}
+
+type Grpc_GetPolicyRoutePoliciesServer interface {
+ Send(*PolicyDefinition) error
+ grpc.ServerStream
+}
+
+type grpcGetPolicyRoutePoliciesServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcGetPolicyRoutePoliciesServer) Send(m *PolicyDefinition) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _Grpc_GetPolicyRoutePolicy_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) {
+ in := new(PolicyArguments)
+ if err := codec.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).GetPolicyRoutePolicy(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
var _Grpc_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.Grpc",
HandlerType: (*GrpcServer)(nil),
@@ -1663,6 +1845,10 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{
MethodName: "GetPolicyNeighbor",
Handler: _Grpc_GetPolicyNeighbor_Handler,
},
+ {
+ MethodName: "GetPolicyRoutePolicy",
+ Handler: _Grpc_GetPolicyRoutePolicy_Handler,
+ },
},
Streams: []grpc.StreamDesc{
{
@@ -1702,5 +1888,10 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{
Handler: _Grpc_GetPolicyNeighbors_Handler,
ServerStreams: true,
},
+ {
+ StreamName: "GetPolicyRoutePolicies",
+ Handler: _Grpc_GetPolicyRoutePolicies_Handler,
+ ServerStreams: true,
+ },
},
}
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 7ee47965..98a72228 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -37,6 +37,8 @@ service Grpc {
rpc ModPolicyPrefix(stream PolicyArguments) returns (stream Error) {}
rpc GetPolicyNeighbors(PolicyArguments) returns (stream NeighborSet) {}
rpc GetPolicyNeighbor(PolicyArguments) returns (NeighborSet) {}
+ rpc GetPolicyRoutePolicies(PolicyArguments) returns (stream PolicyDefinition) {}
+ rpc GetPolicyRoutePolicy(PolicyArguments) returns (PolicyDefinition) {}
}
message Error {
@@ -65,6 +67,7 @@ message PolicyArguments {
string name = 3;
PrefixSet prefix_set = 4;
NeighborSet neighbor_set = 5;
+ PolicyDefinition policy_difinition = 6;
}
enum Resource {
@@ -74,6 +77,7 @@ enum Resource {
ADJ_OUT = 3;
POLICY_PREFIX = 4;
POLICY_NEIGHBOR = 5;
+ POLICY_ROUTEPOLICY = 6;
}
enum Operation {
@@ -361,3 +365,28 @@ message NeighborSet {
repeated Neighbor neighbor_list = 2;
}
+message Conditions {
+ PrefixSet match_prefix_set = 1;
+ NeighborSet match_neighbor_set = 2;
+ int64 match_set_options = 3;
+}
+
+message Actions {
+ bool accept_route = 1;
+ bool reject_route = 2;
+}
+
+message Statement {
+ string statement_neme = 1;
+ Conditions conditions = 2;
+ Actions actions = 3;
+}
+
+message PolicyDefinition{
+ string policy_definition_name = 1;
+ repeated Statement statement_list = 2;
+}
+
+message RoutingPolicy {
+ repeated PolicyDefinition policy_difinition = 1;
+}
diff --git a/gobgp/main.go b/gobgp/main.go
index 434cd68f..9a89e4db 100644
--- a/gobgp/main.go
+++ b/gobgp/main.go
@@ -39,6 +39,7 @@ const (
CMD_RIB = "rib"
CMD_ADD = "add"
CMD_DEL = "del"
+ CMD_ALL = "all"
CMD_LOCAL = "local"
CMD_ADJ_IN = "adj-in"
CMD_ADJ_OUT = "adj-out"
@@ -50,7 +51,7 @@ const (
CMD_ENABLE = "enable"
CMD_DISABLE = "disable"
CMD_PREFIX = "prefix"
- CMD_ALL = "all"
+ CMD_ROUTEPOLICY = "routepolicy"
)
func formatTimedelta(d int64) string {
@@ -165,6 +166,20 @@ func (n neighbors) Less(i, j int) bool {
return n[i].NeighborSetName < n[j].NeighborSetName
}
+type policyDefinitions []*api.PolicyDefinition
+
+func (p policyDefinitions) Len() int {
+ return len(p)
+}
+
+func (p policyDefinitions) Swap(i, j int) {
+ p[i], p[j] = p[j], p[i]
+}
+
+func (p policyDefinitions) Less(i, j int) bool {
+ return p[i].PolicyDefinitionName < p[j].PolicyDefinitionName
+}
+
func connGrpc() *grpc.ClientConn {
timeout := grpc.WithTimeout(time.Second)
@@ -237,6 +252,12 @@ func requestGrpc(cmd string, eArgs []string, remoteIP net.IP) error {
} else {
return showPolicyNeighbor(eArgs)
}
+ case CMD_POLICY + "_" + CMD_ROUTEPOLICY:
+ if len(eArgs) == 0 {
+ return showPolicyRoutePolicies()
+ } else {
+ return showPolicyRoutePolicy(eArgs)
+ }
}
return nil
}
@@ -1112,6 +1133,7 @@ func (x *PolicyCommand) Execute(args []string) error {
parser.Usage = "policy"
parser.AddCommand(CMD_PREFIX, "subcommand for prefix of policy", "", &PolicyPrefixCommand{})
parser.AddCommand(CMD_NEIGHBOR, "subcommand for prefix of neighbor", "", &PolicyNeighborCommand{})
+ parser.AddCommand(CMD_ROUTEPOLICY, "subcommand for prefix of routepolicy", "", &PolicyRoutePolicyCommand{})
if _, err := parser.ParseArgs(eArgs); err != nil {
os.Exit(1)
}
@@ -1120,6 +1142,27 @@ func (x *PolicyCommand) Execute(args []string) error {
type PolicyPrefixCommand struct{}
+func formatPolicyPrefix(prefixSetList []*api.PrefixSet) string {
+ maxNameLen := len("Name")
+ maxPrefixLen := len("Prefix")
+ maxRangeLen := len("MaskRange")
+ for _, ps := range prefixSetList {
+ if len(ps.PrefixSetName) > maxNameLen {
+ maxNameLen = len(ps.PrefixSetName)
+ }
+ for _, p := range ps.PrefixList {
+ if len(p.Address)+len(fmt.Sprint(p.MaskLength))+1 > maxPrefixLen {
+ maxPrefixLen = len(p.Address) + len(fmt.Sprint(p.MaskLength)) + 1
+ }
+ if len(p.MaskLengthRange) > maxRangeLen {
+ maxRangeLen = len(p.MaskLengthRange)
+ }
+ }
+ }
+ format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxPrefixLen) + "s %-" + fmt.Sprint(maxRangeLen) + "s\n"
+ return format
+}
+
func showPolicyPrefixes() error {
arg := &api.PolicyArguments{
Resource: api.Resource_POLICY_PREFIX,
@@ -1152,27 +1195,9 @@ func showPolicyPrefixes() error {
}
return nil
}
- maxnamelen := len("Name")
- maxprefixlen := len("Prefix")
- maxrangelen := len("MaskRange")
-
sort.Sort(m)
- for _, ps := range m {
- if len(ps.PrefixSetName) > maxnamelen {
- maxnamelen = len(ps.PrefixSetName)
- }
- for _, p := range ps.PrefixList {
- if len(p.Address)+len(fmt.Sprint(p.MaskLength)) > maxprefixlen {
- maxprefixlen = len(p.Address) + len(fmt.Sprint(p.MaskLength))
- }
- if len(p.MaskLengthRange) > maxrangelen {
- maxrangelen = len(p.MaskLengthRange)
- }
- }
- }
- var format string
- format = "%" + fmt.Sprint(maxnamelen) + "s %-" + fmt.Sprint(maxprefixlen) + "s %-" + fmt.Sprint(maxrangelen) + "s\n"
+ format := formatPolicyPrefix(m)
fmt.Printf(format, "Name", "Prefix", "MaskRange")
for _, ps := range m {
for i, p := range ps.PrefixList {
@@ -1203,24 +1228,15 @@ func showPolicyPrefix(args []string) error {
return nil
}
- maxprefixlen := len("Prefix")
- maxrangelen := len("MaskRange")
-
- for _, p := range ps.PrefixList {
- if len(p.Address)+len(fmt.Sprint(p.MaskLength)) > maxprefixlen {
- maxprefixlen = len(p.Address) + len(fmt.Sprint(p.MaskLength))
- }
- if len(p.MaskLengthRange) > maxrangelen {
- maxrangelen = len(p.MaskLengthRange)
- }
- }
- var format string
- format = "%-" + fmt.Sprint(maxprefixlen) + "s %-" + fmt.Sprint(maxrangelen) + "s\n"
- fmt.Printf(format, "Prefix", "MaskRange")
-
- for _, p := range ps.PrefixList {
+ format := formatPolicyPrefix([]*api.PrefixSet{ps})
+ fmt.Printf(format, "Name", "Prefix", "MaskRange")
+ for i, p := range ps.PrefixList {
prefix := fmt.Sprintf("%s/%d", p.Address, p.MaskLength)
- fmt.Printf(format, prefix, p.MaskLengthRange)
+ if i == 0 {
+ fmt.Printf(format, ps.PrefixSetName, prefix, p.MaskLengthRange)
+ } else {
+ fmt.Printf(format, "", prefix, p.MaskLengthRange)
+ }
}
return nil
}
@@ -1410,6 +1426,23 @@ func (x *PolicyPrefixDelAllCommand) Execute(args []string) error {
type PolicyNeighborCommand struct{}
+func formatPolicyNeighbor(neighborSetList []*api.NeighborSet) string {
+ maxNameLen := len("Name")
+ maxAddressLen := len("Address")
+ for _, ns := range neighborSetList {
+ if len(ns.NeighborSetName) > maxNameLen {
+ maxNameLen = len(ns.NeighborSetName)
+ }
+ for _, n := range ns.NeighborList {
+ if len(n.Address) > maxAddressLen {
+ maxAddressLen = len(n.Address)
+ }
+ }
+ }
+ format := "%-" + fmt.Sprint(maxNameLen) + "s %-" + fmt.Sprint(maxAddressLen) + "s\n"
+ return format
+}
+
func showPolicyNeighbors() error {
arg := &api.PolicyArguments{
Resource: api.Resource_POLICY_NEIGHBOR,
@@ -1442,23 +1475,9 @@ func showPolicyNeighbors() error {
}
return nil
}
- maxnamelen := len("Name")
- maxaddresslen := len("Address")
-
sort.Sort(m)
- for _, ns := range m {
- if len(ns.NeighborSetName) > maxnamelen {
- maxnamelen = len(ns.NeighborSetName)
- }
- for _, n := range ns.NeighborList {
- if len(n.Address) > maxaddresslen {
- maxaddresslen = len(n.Address)
- }
- }
- }
- var format string
- format = "%" + fmt.Sprint(maxnamelen) + "s %-" + fmt.Sprint(maxaddresslen) + "s\n"
+ format := formatPolicyNeighbor(m)
fmt.Printf(format, "Name", "Address")
for _, ns := range m {
for i, n := range ns.NeighborList {
@@ -1488,20 +1507,16 @@ func showPolicyNeighbor(args []string) error {
return nil
}
- maxaddresslen := len("Address")
+ format := formatPolicyNeighbor([]*api.NeighborSet{ns})
+ fmt.Printf(format, "Name", "Address")
+ for i, n := range ns.NeighborList {
+ if i == 0 {
+ fmt.Printf(format, ns.NeighborSetName, n.Address)
+ } else {
+ fmt.Printf(format, "", n.Address)
- for _, n := range ns.NeighborList {
- if len(n.Address) > maxaddresslen {
- maxaddresslen = len(n.Address)
}
}
- var format string
- format = "%-" + fmt.Sprint(maxaddresslen) + "s\n"
- fmt.Printf(format, "Address")
-
- for _, n := range ns.NeighborList {
- fmt.Printf(format, n.Address)
- }
return nil
}
@@ -1520,8 +1535,148 @@ 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 route to policy neighbor", "", &PolicyNeighborAddCommand{})
- //parser.AddCommand(CMD_DEL, "subcommand for delete route from policy neighbor", "", &PolicyNeighborDelCommand{})
+ //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
+}
+
+type PolicyRoutePolicyCommand struct{}
+
+func showPolicyStatement(pd *api.PolicyDefinition) {
+ for _, st := range pd.StatementList {
+ fmt.Printf(" StatementName %s:\n", st.StatementNeme)
+ fmt.Println(" Conditions:")
+ prefixSet := st.Conditions.MatchPrefixSet
+ fmt.Print(" PrefixSet: ")
+ if len(prefixSet.PrefixList) != 0 {
+ format := formatPolicyPrefix([]*api.PrefixSet{st.Conditions.MatchPrefixSet})
+ for i, prefix := range prefixSet.PrefixList {
+ p := fmt.Sprintf("%s/%d", prefix.Address, prefix.MaskLength)
+ if i == 0 {
+ fmt.Printf(format, prefixSet.PrefixSetName, p, prefix.MaskLengthRange)
+ } else {
+ fmt.Print(" ")
+ fmt.Printf(format, "", p, prefix.MaskLengthRange)
+ }
+
+ }
+ } else {
+ fmt.Print("\n")
+ }
+ neighborSet := st.Conditions.MatchNeighborSet
+ fmt.Print(" NeighborSet: ")
+ 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.Print(" ")
+ fmt.Printf(format, "", neighbor.Address)
+ }
+
+ }
+ } else {
+ fmt.Print("\n")
+ }
+ var option string
+ switch st.Conditions.MatchSetOptions {
+ case 0:
+ option = "ANY"
+ case 1:
+ option = "ALL"
+ case 2:
+ option = "INVERT"
+ }
+ fmt.Printf(" MatchOption: %s\n", option)
+ fmt.Println(" Actions:")
+ action := "REJECT"
+ if st.Actions.AcceptRoute {
+ action = "ACCEPT"
+ }
+ fmt.Printf(" %s\n", action)
+ }
+
+}
+
+func showPolicyRoutePolicies() error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_ROUTEPOLICY,
+ }
+ stream, e := client.GetPolicyRoutePolicies(context.Background(), arg)
+ if e != nil {
+ fmt.Println(e)
+ return e
+ }
+ m := policyDefinitions{}
+ for {
+ n, e := stream.Recv()
+ if e == io.EOF {
+ break
+ } else if e != nil {
+ return e
+ }
+ m = append(m, n)
+ }
+
+ if globalOpts.Json {
+ j, _ := json.Marshal(m)
+ fmt.Println(string(j))
+ return nil
+ }
+ if globalOpts.Quiet {
+ for _, p := range m {
+ fmt.Println(p.PolicyDefinitionName)
+ }
+ return nil
+ }
+ sort.Sort(m)
+
+ for _, pd := range m {
+ fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName)
+ showPolicyStatement(pd)
+ }
+ return nil
+}
+
+func showPolicyRoutePolicy(args []string) error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_ROUTEPOLICY,
+ Name: args[0],
+ }
+ pd, e := client.GetPolicyRoutePolicy(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+
+ if globalOpts.Json {
+ j, _ := json.Marshal(pd)
+ fmt.Println(string(j))
+ return nil
+ }
+ fmt.Printf("PolicyName %s:\n", pd.PolicyDefinitionName)
+ showPolicyStatement(pd)
+ return nil
+}
+
+func (x *PolicyRoutePolicyCommand) Execute(args []string) error {
+ eArgs := extractArgs(CMD_ROUTEPOLICY)
+ if len(eArgs) == 0 {
+ if err := requestGrpc(CMD_POLICY+"_"+CMD_ROUTEPOLICY, eArgs, nil); err != nil {
+ return err
+ }
+ return nil
+ } else if len(eArgs) == 1 && !(eArgs[0] == "-h" || eArgs[0] == "--help" || eArgs[0] == "add" || eArgs[0] == "del") {
+ 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 policy of routepolicy", "", &PolicyRoutePolicyAddCommand{})
+ //parser.AddCommand(CMD_DEL, "subcommand for delete policy of routepolicy", "", &PolicyRoutePolicyDelCommand{})
parser.ParseArgs(eArgs)
return nil
}
@@ -1543,9 +1698,9 @@ var neighborsOpts struct {
}
func main() {
- cmds = []string{CMD_GLOBAL, CMD_NEIGHBOR, CMD_POLICY, CMD_RIB, CMD_ADD, CMD_DEL, 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_ALL}
+ 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}
eArgs := extractArgs("")
parser := flags.NewParser(&globalOpts, flags.Default)
diff --git a/server/grpc_server.go b/server/grpc_server.go
index 2965d647..3fd45b83 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -50,6 +50,8 @@ const (
REQ_POLICY_PREFIXES_DELETE
REQ_POLICY_NEIGHBOR
REQ_POLICY_NEIGHBORS
+ REQ_POLICY_ROUTEPOLICIES
+ REQ_POLICY_ROUTEPOLICY
)
const GRPC_PORT = 8080
@@ -281,6 +283,8 @@ func (s *Server) getPolicies(reqType int, arg *api.PolicyArguments, stream inter
err = stream.(api.Grpc_GetPolicyPrefixesServer).Send(res.Data.(*api.PrefixSet))
case api.Resource_POLICY_NEIGHBOR:
err = stream.(api.Grpc_GetPolicyNeighborsServer).Send(res.Data.(*api.NeighborSet))
+ case api.Resource_POLICY_ROUTEPOLICY:
+ err = stream.(api.Grpc_GetPolicyRoutePoliciesServer).Send(res.Data.(*api.PolicyDefinition))
default:
return fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
@@ -299,6 +303,8 @@ func (s *Server) getPolicy(arg *api.PolicyArguments) (interface{}, error) {
reqType = REQ_POLICY_PREFIX
case api.Resource_POLICY_NEIGHBOR:
reqType = REQ_POLICY_NEIGHBOR
+ case api.Resource_POLICY_ROUTEPOLICY:
+ reqType = REQ_POLICY_ROUTEPOLICY
default:
return nil, fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
@@ -396,6 +402,21 @@ func (s *Server) GetPolicyNeighbor(ctx context.Context, arg *api.PolicyArguments
return data.(*api.NeighborSet), nil
}
+func (s *Server) GetPolicyRoutePolicies(arg *api.PolicyArguments, stream api.Grpc_GetPolicyRoutePoliciesServer) error {
+ if err := s.getPolicies(REQ_POLICY_ROUTEPOLICIES, arg, stream); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (s *Server) GetPolicyRoutePolicy(ctx context.Context, arg *api.PolicyArguments) (*api.PolicyDefinition, error) {
+ data, err := s.getPolicy(arg)
+ if err != nil {
+ return nil, err
+ }
+ return data.(*api.PolicyDefinition), nil
+}
+
type GrpcRequest struct {
RequestType int
RemoteAddr string
diff --git a/server/server.go b/server/server.go
index 5a847045..d2a82a85 100644
--- a/server/server.go
+++ b/server/server.go
@@ -338,7 +338,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
}
} else {
- result.ResponseErr = fmt.Errorf("Policy Prefix is not exist.")
+ result.ResponseErr = fmt.Errorf("Prefix is not exist.")
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
@@ -359,7 +359,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
}
grpcReq.ResponseCh <- result
} else {
- result.ResponseErr = fmt.Errorf("Policy Prefix that has %v does not exist.", name)
+ result.ResponseErr = fmt.Errorf("Prefix that has %v does not exist.", name)
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
@@ -373,7 +373,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
}
- idxPrefixSet, idxPrefix := findPrefixSet(conPrefixSetList, reqPrefixSet, prefixSet)
+ idxPrefixSet, idxPrefix := findPrefixSet(conPrefixSetList, prefixSet)
if idxPrefixSet == -1 {
conPrefixSetList = append(conPrefixSetList, prefixSet)
} else {
@@ -391,13 +391,13 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
result := &GrpcResponse{}
isReqPrefixSet, prefixSet := prefixToConfigStruct(reqPrefixSet)
if isReqPrefixSet {
- idxPrefixSet, idxPrefix := findPrefixSet(conPrefixSetList, reqPrefixSet, prefixSet)
+ idxPrefixSet, idxPrefix := findPrefixSet(conPrefixSetList, prefixSet)
if idxPrefixSet == -1 {
- result.ResponseErr = fmt.Errorf("Policy Prefix %v %v/%v %v does not exist.", prefixSet.PrefixSetName,
+ result.ResponseErr = fmt.Errorf("Prefix %v %v/%v %v does not exist.", prefixSet.PrefixSetName,
prefixSet.PrefixList[0].Address, prefixSet.PrefixList[0].Masklength, prefixSet.PrefixList[0].MasklengthRange)
} else {
if idxPrefix == -1 {
- result.ResponseErr = fmt.Errorf("Policy Prefix %v %v/%v %v does not exist.", prefixSet.PrefixSetName,
+ result.ResponseErr = fmt.Errorf("Prefix %v %v/%v %v does not exist.", prefixSet.PrefixSetName,
prefixSet.PrefixList[0].Address, prefixSet.PrefixList[0].Masklength, prefixSet.PrefixList[0].MasklengthRange)
} else {
copy(conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix:], conPrefixSetList[idxPrefixSet].PrefixList[idxPrefix+1:])
@@ -413,7 +413,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
}
}
if idxPrefixSet == -1 {
- result.ResponseErr = fmt.Errorf("Policy Prefix %v does not exist.", prefixSet.PrefixSetName)
+ result.ResponseErr = fmt.Errorf("Prefix %v does not exist.", prefixSet.PrefixSetName)
} else {
copy(conPrefixSetList[idxPrefixSet:], conPrefixSetList[idxPrefixSet+1:])
conPrefixSetList = conPrefixSetList[:len(conPrefixSetList)-1]
@@ -441,7 +441,7 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
grpcReq.ResponseCh <- result
}
} else {
- result.ResponseErr = fmt.Errorf("Policy Neighbor is not exist.")
+ result.ResponseErr = fmt.Errorf("Neighbor is not exist.")
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
@@ -462,24 +462,66 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
}
grpcReq.ResponseCh <- result
} else {
- result.ResponseErr = fmt.Errorf("Policy Neighbor that has %v does not exist.", name)
+ result.ResponseErr = fmt.Errorf("Neighbor that has %v does not exist.", name)
+ grpcReq.ResponseCh <- result
+ }
+ close(grpcReq.ResponseCh)
+ case REQ_POLICY_ROUTEPOLICIES:
+ info := server.routingPolicy.PolicyDefinitionList
+ df := server.routingPolicy.DefinedSets
+ result := &GrpcResponse{}
+ if len(info) > 0 {
+ for _, pd := range info {
+ resPolicyDefinition := policyDefinitionToApiStruct(pd, df)
+ result = &GrpcResponse{
+ Data: resPolicyDefinition,
+ }
+ grpcReq.ResponseCh <- result
+ }
+ } else {
+ result.ResponseErr = fmt.Errorf("Route Policy is not exist.")
+ grpcReq.ResponseCh <- result
+ }
+ close(grpcReq.ResponseCh)
+ case REQ_POLICY_ROUTEPOLICY:
+ name := grpcReq.Data.(string)
+ info := server.routingPolicy.PolicyDefinitionList
+ df := server.routingPolicy.DefinedSets
+ result := &GrpcResponse{}
+ resPolicyDefinition := &api.PolicyDefinition{}
+ for _, pd := range info {
+ if pd.Name == name {
+ resPolicyDefinition = policyDefinitionToApiStruct(pd, df)
+ break
+ }
+ }
+ if len(resPolicyDefinition.StatementList) > 0 {
+ result = &GrpcResponse{
+ Data: resPolicyDefinition,
+ }
+ grpcReq.ResponseCh <- result
+ } else {
+ result.ResponseErr = fmt.Errorf("Route Policy that has %v does not exist.", name)
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
}
}
-func findPrefixSet(conPrefixSetList []config.PrefixSet, reqPrefixSet *api.PrefixSet, prefixSet config.PrefixSet) (int, int) {
+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, prefixSet.PrefixList[0].Address) && conPrefix.Masklength == prefixSet.PrefixList[0].Masklength &&
- conPrefix.MasklengthRange == prefixSet.PrefixList[0].MasklengthRange {
+ if reflect.DeepEqual(conPrefix.Address, reqPrefixSet.PrefixList[0].Address) && conPrefix.Masklength == reqPrefixSet.PrefixList[0].Masklength &&
+ conPrefix.MasklengthRange == reqPrefixSet.PrefixList[0].MasklengthRange {
idxPrefix = j
- break
+ return idxPrefixSet, idxPrefix
}
}
}
@@ -487,6 +529,26 @@ func findPrefixSet(conPrefixSetList []config.PrefixSet, reqPrefixSet *api.Prefix
return idxPrefixSet, idxPrefix
}
+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 {
@@ -544,3 +606,76 @@ func neighborToApiStruct(ns config.NeighborSet) *api.NeighborSet {
}
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
+}