summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNaoto Hanaue <hanaue.naoto@po.ntts.co.jp>2015-05-11 20:34:56 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-05-19 16:33:16 +0900
commit8d0eb0a06bbdfaa47b4979dffed28a7f38b16680 (patch)
tree02075c54997b45ec543e09e2310b6201afd070ec
parent772dbed046cc75891cc37d7a34a85d94d6e40e8b (diff)
cli: add the show command for the neighbor conditions
% gobgp -u 10.0.255.1 policy neighbor Name Address ns0 10.0.0.2 ns1 2001::192:168:0:2 % gobgp -u 10.0.255.1 policy neighbor ns0 Name Address ns0 10.0.0.2
-rw-r--r--api/gobgp.pb.go152
-rw-r--r--api/gobgp.proto14
-rw-r--r--gobgp/main.go139
-rw-r--r--server/grpc_server.go21
-rw-r--r--server/server.go52
5 files changed, 364 insertions, 14 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index a67af8f7..809e8d50 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -33,6 +33,8 @@ It has these top-level messages:
Peer
Prefix
PrefixSet
+ Neighbor
+ NeighborSet
*/
package api
@@ -53,11 +55,12 @@ 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_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
)
var Resource_name = map[int32]string{
@@ -66,13 +69,15 @@ var Resource_name = map[int32]string{
2: "ADJ_IN",
3: "ADJ_OUT",
4: "POLICY_PREFIX",
+ 5: "POLICY_NEIGHBOR",
}
var Resource_value = map[string]int32{
- "GLOBAL": 0,
- "LOCAL": 1,
- "ADJ_IN": 2,
- "ADJ_OUT": 3,
- "POLICY_PREFIX": 4,
+ "GLOBAL": 0,
+ "LOCAL": 1,
+ "ADJ_IN": 2,
+ "ADJ_OUT": 3,
+ "POLICY_PREFIX": 4,
+ "POLICY_NEIGHBOR": 5,
}
func (x Resource) String() string {
@@ -506,10 +511,11 @@ 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"`
+ 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"`
}
func (m *PolicyArguments) Reset() { *m = PolicyArguments{} }
@@ -523,6 +529,13 @@ func (m *PolicyArguments) GetPrefixSet() *PrefixSet {
return nil
}
+func (m *PolicyArguments) GetNeighborSet() *NeighborSet {
+ if m != nil {
+ return m.NeighborSet
+ }
+ 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"`
@@ -921,6 +934,30 @@ func (m *PrefixSet) GetPrefixList() []*Prefix {
return nil
}
+type Neighbor struct {
+ Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
+}
+
+func (m *Neighbor) Reset() { *m = Neighbor{} }
+func (m *Neighbor) String() string { return proto.CompactTextString(m) }
+func (*Neighbor) ProtoMessage() {}
+
+type NeighborSet struct {
+ NeighborSetName string `protobuf:"bytes,1,opt,name=neighbor_set_name" json:"neighbor_set_name,omitempty"`
+ NeighborList []*Neighbor `protobuf:"bytes,2,rep,name=neighbor_list" json:"neighbor_list,omitempty"`
+}
+
+func (m *NeighborSet) Reset() { *m = NeighborSet{} }
+func (m *NeighborSet) String() string { return proto.CompactTextString(m) }
+func (*NeighborSet) ProtoMessage() {}
+
+func (m *NeighborSet) GetNeighborList() []*Neighbor {
+ if m != nil {
+ return m.NeighborList
+ }
+ return nil
+}
+
func init() {
proto.RegisterEnum("api.Resource", Resource_name, Resource_value)
proto.RegisterEnum("api.Operation", Operation_name, Operation_value)
@@ -955,6 +992,8 @@ type GrpcClient interface {
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)
+ GetPolicyNeighbors(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (Grpc_GetPolicyNeighborsClient, error)
+ GetPolicyNeighbor(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (*NeighborSet, error)
}
type grpcClient struct {
@@ -1236,6 +1275,47 @@ func (x *grpcModPolicyPrefixClient) Recv() (*Error, error) {
return m, nil
}
+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...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcGetPolicyNeighborsClient{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_GetPolicyNeighborsClient interface {
+ Recv() (*NeighborSet, error)
+ grpc.ClientStream
+}
+
+type grpcGetPolicyNeighborsClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcGetPolicyNeighborsClient) Recv() (*NeighborSet, error) {
+ m := new(NeighborSet)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *grpcClient) GetPolicyNeighbor(ctx context.Context, in *PolicyArguments, opts ...grpc.CallOption) (*NeighborSet, error) {
+ out := new(NeighborSet)
+ err := grpc.Invoke(ctx, "/api.Grpc/GetPolicyNeighbor", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// Server API for Grpc service
type GrpcServer interface {
@@ -1254,6 +1334,8 @@ type GrpcServer interface {
GetPolicyPrefixes(*PolicyArguments, Grpc_GetPolicyPrefixesServer) error
GetPolicyPrefix(context.Context, *PolicyArguments) (*PrefixSet, error)
ModPolicyPrefix(Grpc_ModPolicyPrefixServer) error
+ GetPolicyNeighbors(*PolicyArguments, Grpc_GetPolicyNeighborsServer) error
+ GetPolicyNeighbor(context.Context, *PolicyArguments) (*NeighborSet, error)
}
func RegisterGrpcServer(s *grpc.Server, srv GrpcServer) {
@@ -1504,6 +1586,39 @@ func (x *grpcModPolicyPrefixServer) Recv() (*PolicyArguments, error) {
return m, nil
}
+func _Grpc_GetPolicyNeighbors_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(PolicyArguments)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(GrpcServer).GetPolicyNeighbors(m, &grpcGetPolicyNeighborsServer{stream})
+}
+
+type Grpc_GetPolicyNeighborsServer interface {
+ Send(*NeighborSet) error
+ grpc.ServerStream
+}
+
+type grpcGetPolicyNeighborsServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcGetPolicyNeighborsServer) Send(m *NeighborSet) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _Grpc_GetPolicyNeighbor_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).GetPolicyNeighbor(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
var _Grpc_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.Grpc",
HandlerType: (*GrpcServer)(nil),
@@ -1544,6 +1659,10 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{
MethodName: "GetPolicyPrefix",
Handler: _Grpc_GetPolicyPrefix_Handler,
},
+ {
+ MethodName: "GetPolicyNeighbor",
+ Handler: _Grpc_GetPolicyNeighbor_Handler,
+ },
},
Streams: []grpc.StreamDesc{
{
@@ -1578,5 +1697,10 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{
ServerStreams: true,
ClientStreams: true,
},
+ {
+ StreamName: "GetPolicyNeighbors",
+ Handler: _Grpc_GetPolicyNeighbors_Handler,
+ ServerStreams: true,
+ },
},
}
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 6a2e3844..7ee47965 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -35,6 +35,8 @@ service Grpc {
rpc GetPolicyPrefixes(PolicyArguments) returns (stream PrefixSet) {}
rpc GetPolicyPrefix(PolicyArguments) returns (PrefixSet) {}
rpc ModPolicyPrefix(stream PolicyArguments) returns (stream Error) {}
+ rpc GetPolicyNeighbors(PolicyArguments) returns (stream NeighborSet) {}
+ rpc GetPolicyNeighbor(PolicyArguments) returns (NeighborSet) {}
}
message Error {
@@ -62,6 +64,7 @@ message PolicyArguments {
Operation operation = 2;
string name = 3;
PrefixSet prefix_set = 4;
+ NeighborSet neighbor_set = 5;
}
enum Resource {
@@ -70,6 +73,7 @@ enum Resource {
ADJ_IN = 2;
ADJ_OUT = 3;
POLICY_PREFIX = 4;
+ POLICY_NEIGHBOR = 5;
}
enum Operation {
@@ -347,3 +351,13 @@ message PrefixSet {
string prefix_set_name = 1;
repeated Prefix prefix_list = 2;
}
+
+message Neighbor {
+ string address = 1;
+}
+
+message NeighborSet {
+ string neighbor_set_name = 1;
+ repeated Neighbor neighbor_list = 2;
+}
+
diff --git a/gobgp/main.go b/gobgp/main.go
index 4f5a3052..434cd68f 100644
--- a/gobgp/main.go
+++ b/gobgp/main.go
@@ -151,6 +151,20 @@ func (p prefixes) Less(i, j int) bool {
return p[i].PrefixSetName < p[j].PrefixSetName
}
+type neighbors []*api.NeighborSet
+
+func (n neighbors) Len() int {
+ return len(n)
+}
+
+func (n neighbors) Swap(i, j int) {
+ n[i], n[j] = n[j], n[i]
+}
+
+func (n neighbors) Less(i, j int) bool {
+ return n[i].NeighborSetName < n[j].NeighborSetName
+}
+
func connGrpc() *grpc.ClientConn {
timeout := grpc.WithTimeout(time.Second)
@@ -217,6 +231,12 @@ func requestGrpc(cmd string, eArgs []string, remoteIP net.IP) error {
return modPolicyPrefix(CMD_ADD, eArgs)
case CMD_POLICY + "_" + CMD_PREFIX + "_" + CMD_DEL:
return modPolicyPrefix(CMD_DEL, eArgs)
+ case CMD_POLICY + "_" + CMD_NEIGHBOR:
+ if len(eArgs) == 0 {
+ return showPolicyNeighbors()
+ } else {
+ return showPolicyNeighbor(eArgs)
+ }
}
return nil
}
@@ -1091,6 +1111,7 @@ func (x *PolicyCommand) Execute(args []string) error {
parser := flags.NewParser(nil, flags.Default)
parser.Usage = "policy"
parser.AddCommand(CMD_PREFIX, "subcommand for prefix of policy", "", &PolicyPrefixCommand{})
+ parser.AddCommand(CMD_NEIGHBOR, "subcommand for prefix of neighbor", "", &PolicyNeighborCommand{})
if _, err := parser.ParseArgs(eArgs); err != nil {
os.Exit(1)
}
@@ -1387,6 +1408,124 @@ func (x *PolicyPrefixDelAllCommand) Execute(args []string) error {
return nil
}
+type PolicyNeighborCommand struct{}
+
+func showPolicyNeighbors() error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_NEIGHBOR,
+ }
+ stream, e := client.GetPolicyNeighbors(context.Background(), arg)
+ if e != nil {
+ fmt.Println(e)
+ return e
+ }
+ m := neighbors{}
+ 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 _, n := range m {
+ fmt.Println(n.NeighborSetName)
+ }
+ 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"
+ fmt.Printf(format, "Name", "Address")
+ for _, ns := range m {
+ for i, n := range ns.NeighborList {
+ if i == 0 {
+ fmt.Printf(format, ns.NeighborSetName, n.Address)
+ } else {
+ fmt.Printf(format, "", n.Address)
+ }
+ }
+ }
+ return nil
+}
+
+func showPolicyNeighbor(args []string) error {
+ arg := &api.PolicyArguments{
+ Resource: api.Resource_POLICY_NEIGHBOR,
+ Name: args[0],
+ }
+ ns, e := client.GetPolicyNeighbor(context.Background(), arg)
+ if e != nil {
+ return e
+ }
+
+ if globalOpts.Json {
+ j, _ := json.Marshal(ns)
+ fmt.Println(string(j))
+ return nil
+ }
+
+ maxaddresslen := len("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
+}
+
+func (x *PolicyNeighborCommand) Execute(args []string) error {
+ eArgs := extractArgs(CMD_NEIGHBOR)
+ if len(eArgs) == 0 {
+ if err := requestGrpc(CMD_POLICY+"_"+CMD_NEIGHBOR, 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_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 route to policy neighbor", "", &PolicyNeighborAddCommand{})
+ //parser.AddCommand(CMD_DEL, "subcommand for delete route from policy neighbor", "", &PolicyNeighborDelCommand{})
+ parser.ParseArgs(eArgs)
+ return nil
+}
+
var globalOpts struct {
Host string `short:"u" long:"url" description:"specifying an url" default:"127.0.0.1"`
Port int `short:"p" long:"port" description:"specifying a port" default:"8080"`
diff --git a/server/grpc_server.go b/server/grpc_server.go
index cc0a0e16..2965d647 100644
--- a/server/grpc_server.go
+++ b/server/grpc_server.go
@@ -48,6 +48,8 @@ const (
REQ_POLICY_PREFIX_ADD
REQ_POLICY_PREFIX_DELETE
REQ_POLICY_PREFIXES_DELETE
+ REQ_POLICY_NEIGHBOR
+ REQ_POLICY_NEIGHBORS
)
const GRPC_PORT = 8080
@@ -277,6 +279,8 @@ func (s *Server) getPolicies(reqType int, arg *api.PolicyArguments, stream inter
switch arg.Resource {
case api.Resource_POLICY_PREFIX:
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))
default:
return fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
@@ -293,6 +297,8 @@ func (s *Server) getPolicy(arg *api.PolicyArguments) (interface{}, error) {
switch arg.Resource {
case api.Resource_POLICY_PREFIX:
reqType = REQ_POLICY_PREFIX
+ case api.Resource_POLICY_NEIGHBOR:
+ reqType = REQ_POLICY_NEIGHBOR
default:
return nil, fmt.Errorf("unsupported resource type: %v", arg.Resource)
}
@@ -375,6 +381,21 @@ func (s *Server) ModPolicyPrefix(stream api.Grpc_ModPolicyPrefixServer) error {
}
}
+func (s *Server) GetPolicyNeighbors(arg *api.PolicyArguments, stream api.Grpc_GetPolicyNeighborsServer) error {
+ if err := s.getPolicies(REQ_POLICY_NEIGHBORS, arg, stream); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (s *Server) GetPolicyNeighbor(ctx context.Context, arg *api.PolicyArguments) (*api.NeighborSet, error) {
+ data, err := s.getPolicy(arg)
+ if err != nil {
+ return nil, err
+ }
+ return data.(*api.NeighborSet), nil
+}
+
type GrpcRequest struct {
RequestType int
RemoteAddr string
diff --git a/server/server.go b/server/server.go
index 443a4ba2..5a847045 100644
--- a/server/server.go
+++ b/server/server.go
@@ -429,6 +429,43 @@ func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
server.handlePolicy(pl)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
+ case REQ_POLICY_NEIGHBORS:
+ info := server.routingPolicy.DefinedSets.NeighborSetList
+ result := &GrpcResponse{}
+ if len(info) > 0 {
+ for _, ns := range info {
+ resNeighborSet := neighborToApiStruct(ns)
+ result = &GrpcResponse{
+ Data: resNeighborSet,
+ }
+ grpcReq.ResponseCh <- result
+ }
+ } else {
+ result.ResponseErr = fmt.Errorf("Policy Neighbor is not exist.")
+ grpcReq.ResponseCh <- result
+ }
+ close(grpcReq.ResponseCh)
+ case REQ_POLICY_NEIGHBOR:
+ name := grpcReq.Data.(string)
+ info := server.routingPolicy.DefinedSets.NeighborSetList
+ result := &GrpcResponse{}
+ resNeighborSet := &api.NeighborSet{}
+ for _, ns := range info {
+ if ns.NeighborSetName == name {
+ resNeighborSet = neighborToApiStruct(ns)
+ break
+ }
+ }
+ if len(resNeighborSet.NeighborList) > 0 {
+ result = &GrpcResponse{
+ Data: resNeighborSet,
+ }
+ grpcReq.ResponseCh <- result
+ } else {
+ result.ResponseErr = fmt.Errorf("Policy Neighbor that has %v does not exist.", name)
+ grpcReq.ResponseCh <- result
+ }
+ close(grpcReq.ResponseCh)
}
}
@@ -492,3 +529,18 @@ func prefixToConfigStruct(reqPrefixSet *api.PrefixSet) (bool, config.PrefixSet)
}
return isReqPrefixSet, prefixSet
}
+
+func neighborToApiStruct(ns config.NeighborSet) *api.NeighborSet {
+ resNeighborList := make([]*api.Neighbor, 0)
+ for _, n := range ns.NeighborInfoList {
+ resNeighbor := &api.Neighbor{
+ Address: n.Address.String(),
+ }
+ resNeighborList = append(resNeighborList, resNeighbor)
+ }
+ resNeighborSet := &api.NeighborSet{
+ NeighborSetName: ns.NeighborSetName,
+ NeighborList: resNeighborList,
+ }
+ return resNeighborSet
+}