summaryrefslogtreecommitdiffhomepage
path: root/api
diff options
context:
space:
mode:
authorISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>2015-04-04 23:46:01 +0000
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-04-14 08:10:28 +0900
commit75f835725deb42b00d5f746828f2738d15e3bc4f (patch)
tree5294cc59377f51896fd75a57cdb776f5e2f8bf54 /api
parent18bbb843d2e025af8e1ffd33b7c9a09d1a19c565 (diff)
api: use gRPC instead of REST
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Diffstat (limited to 'api')
-rw-r--r--api/gobgp.pb.go853
-rw-r--r--api/gobgp.proto145
-rw-r--r--api/grpc.go318
-rw-r--r--api/rest.go293
4 files changed, 1316 insertions, 293 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
new file mode 100644
index 00000000..3b91d6ea
--- /dev/null
+++ b/api/gobgp.pb.go
@@ -0,0 +1,853 @@
+// Code generated by protoc-gen-go.
+// source: gobgp.proto
+// DO NOT EDIT!
+
+/*
+Package api is a generated protocol buffer package.
+
+It is generated from these files:
+ gobgp.proto
+
+It has these top-level messages:
+ Error
+ Arguments
+ PathAttr
+ Path
+ Destination
+ PeerConf
+ PeerInfo
+ Peer
+*/
+package api
+
+import proto "github.com/golang/protobuf/proto"
+
+import (
+ context "golang.org/x/net/context"
+ grpc "google.golang.org/grpc"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// Reference imports to suppress errors if they are not otherwise used.
+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
+)
+
+var Resource_name = map[int32]string{
+ 0: "GLOBAL",
+ 1: "LOCAL",
+ 2: "ADJ_IN",
+ 3: "ADJ_OUT",
+}
+var Resource_value = map[string]int32{
+ "GLOBAL": 0,
+ "LOCAL": 1,
+ "ADJ_IN": 2,
+ "ADJ_OUT": 3,
+}
+
+func (x Resource) String() string {
+ return proto.EnumName(Resource_name, int32(x))
+}
+
+type AddressFamily int32
+
+const (
+ AddressFamily_IPV4 AddressFamily = 0
+ AddressFamily_IPV6 AddressFamily = 1
+ AddressFamily_EVPN AddressFamily = 2
+)
+
+var AddressFamily_name = map[int32]string{
+ 0: "IPV4",
+ 1: "IPV6",
+ 2: "EVPN",
+}
+var AddressFamily_value = map[string]int32{
+ "IPV4": 0,
+ "IPV6": 1,
+ "EVPN": 2,
+}
+
+func (x AddressFamily) String() string {
+ return proto.EnumName(AddressFamily_name, int32(x))
+}
+
+type Error_ErrorCode int32
+
+const (
+ Error_SUCCESS Error_ErrorCode = 0
+ Error_FAIL Error_ErrorCode = 1
+)
+
+var Error_ErrorCode_name = map[int32]string{
+ 0: "SUCCESS",
+ 1: "FAIL",
+}
+var Error_ErrorCode_value = map[string]int32{
+ "SUCCESS": 0,
+ "FAIL": 1,
+}
+
+func (x Error_ErrorCode) String() string {
+ return proto.EnumName(Error_ErrorCode_name, int32(x))
+}
+
+type PathAttr_Origin int32
+
+const (
+ PathAttr_IGP PathAttr_Origin = 0
+ PathAttr_EGP PathAttr_Origin = 1
+ PathAttr_INCOMPLETE PathAttr_Origin = 2
+)
+
+var PathAttr_Origin_name = map[int32]string{
+ 0: "IGP",
+ 1: "EGP",
+ 2: "INCOMPLETE",
+}
+var PathAttr_Origin_value = map[string]int32{
+ "IGP": 0,
+ "EGP": 1,
+ "INCOMPLETE": 2,
+}
+
+func (x PathAttr_Origin) String() string {
+ return proto.EnumName(PathAttr_Origin_name, int32(x))
+}
+
+type Error struct {
+ Code Error_ErrorCode `protobuf:"varint,1,opt,name=code,enum=api.Error_ErrorCode" json:"code,omitempty"`
+ Msg string `protobuf:"bytes,2,opt,name=msg" json:"msg,omitempty"`
+}
+
+func (m *Error) Reset() { *m = Error{} }
+func (m *Error) String() string { return proto.CompactTextString(m) }
+func (*Error) ProtoMessage() {}
+
+type Arguments struct {
+ Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"`
+ Af AddressFamily `protobuf:"varint,2,opt,name=af,enum=api.AddressFamily" json:"af,omitempty"`
+ RouterId string `protobuf:"bytes,3,opt,name=router_id" json:"router_id,omitempty"`
+ Prefix string `protobuf:"bytes,4,opt,name=prefix" json:"prefix,omitempty"`
+}
+
+func (m *Arguments) Reset() { *m = Arguments{} }
+func (m *Arguments) String() string { return proto.CompactTextString(m) }
+func (*Arguments) ProtoMessage() {}
+
+type PathAttr struct {
+ Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"`
+ Origin PathAttr_Origin `protobuf:"varint,2,opt,name=origin,enum=api.PathAttr_Origin" json:"origin,omitempty"`
+ AsPath []uint32 `protobuf:"varint,3,rep,name=as_path" json:"as_path,omitempty"`
+ Metric uint32 `protobuf:"varint,4,opt,name=metric" json:"metric,omitempty"`
+ Pref uint32 `protobuf:"varint,5,opt,name=pref" json:"pref,omitempty"`
+ Aggregator *PathAttr_Aggregator `protobuf:"bytes,6,opt,name=aggregator" json:"aggregator,omitempty"`
+ Communites []uint32 `protobuf:"varint,7,rep,name=communites" json:"communites,omitempty"`
+ Originator string `protobuf:"bytes,8,opt,name=originator" json:"originator,omitempty"`
+ Cluster string `protobuf:"bytes,9,opt,name=cluster" json:"cluster,omitempty"`
+ Value uint32 `protobuf:"varint,10,opt,name=value" json:"value,omitempty"`
+}
+
+func (m *PathAttr) Reset() { *m = PathAttr{} }
+func (m *PathAttr) String() string { return proto.CompactTextString(m) }
+func (*PathAttr) ProtoMessage() {}
+
+func (m *PathAttr) GetAggregator() *PathAttr_Aggregator {
+ if m != nil {
+ return m.Aggregator
+ }
+ return nil
+}
+
+type PathAttr_Aggregator struct {
+ As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"`
+ Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
+}
+
+func (m *PathAttr_Aggregator) Reset() { *m = PathAttr_Aggregator{} }
+func (m *PathAttr_Aggregator) String() string { return proto.CompactTextString(m) }
+func (*PathAttr_Aggregator) ProtoMessage() {}
+
+type Path struct {
+ Network string `protobuf:"bytes,1,opt,name=network" json:"network,omitempty"`
+ Nexthop string `protobuf:"bytes,2,opt,name=nexthop" json:"nexthop,omitempty"`
+ Age int64 `protobuf:"varint,3,opt,name=age" json:"age,omitempty"`
+ Attrs []*PathAttr `protobuf:"bytes,4,rep,name=attrs" json:"attrs,omitempty"`
+ Best bool `protobuf:"varint,5,opt,name=best" json:"best,omitempty"`
+}
+
+func (m *Path) Reset() { *m = Path{} }
+func (m *Path) String() string { return proto.CompactTextString(m) }
+func (*Path) ProtoMessage() {}
+
+func (m *Path) GetAttrs() []*PathAttr {
+ if m != nil {
+ return m.Attrs
+ }
+ return nil
+}
+
+type Destination struct {
+ Prefix string `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"`
+ Paths []*Path `protobuf:"bytes,2,rep,name=paths" json:"paths,omitempty"`
+ BestPathIdx int32 `protobuf:"varint,3,opt,name=best_path_idx" json:"best_path_idx,omitempty"`
+}
+
+func (m *Destination) Reset() { *m = Destination{} }
+func (m *Destination) String() string { return proto.CompactTextString(m) }
+func (*Destination) ProtoMessage() {}
+
+func (m *Destination) GetPaths() []*Path {
+ if m != nil {
+ return m.Paths
+ }
+ return nil
+}
+
+type PeerConf struct {
+ RemoteIp string `protobuf:"bytes,1,opt,name=remote_ip" json:"remote_ip,omitempty"`
+ Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"`
+ RemoteAs uint32 `protobuf:"varint,3,opt,name=remote_as" json:"remote_as,omitempty"`
+ CapRefresh bool `protobuf:"varint,4,opt,name=cap_refresh" json:"cap_refresh,omitempty"`
+ CapEnhancedRefresh bool `protobuf:"varint,5,opt,name=cap_enhanced_refresh" json:"cap_enhanced_refresh,omitempty"`
+ RemoteCap []int32 `protobuf:"varint,6,rep,name=remote_cap" json:"remote_cap,omitempty"`
+ LocalCap []int32 `protobuf:"varint,7,rep,name=local_cap" json:"local_cap,omitempty"`
+}
+
+func (m *PeerConf) Reset() { *m = PeerConf{} }
+func (m *PeerConf) String() string { return proto.CompactTextString(m) }
+func (*PeerConf) ProtoMessage() {}
+
+type PeerInfo struct {
+ BgpState string `protobuf:"bytes,1,opt,name=bgp_state" json:"bgp_state,omitempty"`
+ AdminState string `protobuf:"bytes,2,opt,name=admin_state" json:"admin_state,omitempty"`
+ FsmEstablishedTransitions uint32 `protobuf:"varint,3,opt,name=fsm_established_transitions" json:"fsm_established_transitions,omitempty"`
+ TotalMessageOut uint32 `protobuf:"varint,4,opt,name=total_message_out" json:"total_message_out,omitempty"`
+ TotalMessageIn uint32 `protobuf:"varint,5,opt,name=total_message_in" json:"total_message_in,omitempty"`
+ UpdateMessageOut uint32 `protobuf:"varint,6,opt,name=update_message_out" json:"update_message_out,omitempty"`
+ UpdateMessageIn uint32 `protobuf:"varint,7,opt,name=update_message_in" json:"update_message_in,omitempty"`
+ KeepAliveMessageOut uint32 `protobuf:"varint,8,opt,name=keep_alive_message_out" json:"keep_alive_message_out,omitempty"`
+ KeepAliveMessageIn uint32 `protobuf:"varint,9,opt,name=keep_alive_message_in" json:"keep_alive_message_in,omitempty"`
+ OpenMessageOut uint32 `protobuf:"varint,10,opt,name=open_message_out" json:"open_message_out,omitempty"`
+ OpenMessageIn uint32 `protobuf:"varint,11,opt,name=open_message_in" json:"open_message_in,omitempty"`
+ NotificationOut uint32 `protobuf:"varint,12,opt,name=notification_out" json:"notification_out,omitempty"`
+ NotificationIn uint32 `protobuf:"varint,13,opt,name=notification_in" json:"notification_in,omitempty"`
+ RefreshMessageOut uint32 `protobuf:"varint,14,opt,name=refresh_message_out" json:"refresh_message_out,omitempty"`
+ RefreshMessageIn uint32 `protobuf:"varint,15,opt,name=refresh_message_in" json:"refresh_message_in,omitempty"`
+ DiscardedOut uint32 `protobuf:"varint,16,opt,name=discarded_out" json:"discarded_out,omitempty"`
+ DiscardedIn uint32 `protobuf:"varint,17,opt,name=discarded_in" json:"discarded_in,omitempty"`
+ Uptime int64 `protobuf:"varint,18,opt,name=uptime" json:"uptime,omitempty"`
+ Downtime int64 `protobuf:"varint,19,opt,name=downtime" json:"downtime,omitempty"`
+ LastError string `protobuf:"bytes,20,opt,name=last_error" json:"last_error,omitempty"`
+ Received uint32 `protobuf:"varint,21,opt,name=received" json:"received,omitempty"`
+ Accepted uint32 `protobuf:"varint,22,opt,name=accepted" json:"accepted,omitempty"`
+ Advertized uint32 `protobuf:"varint,23,opt,name=advertized" json:"advertized,omitempty"`
+ OutQ uint32 `protobuf:"varint,24,opt,name=out_q" json:"out_q,omitempty"`
+ Flops uint32 `protobuf:"varint,25,opt,name=flops" json:"flops,omitempty"`
+}
+
+func (m *PeerInfo) Reset() { *m = PeerInfo{} }
+func (m *PeerInfo) String() string { return proto.CompactTextString(m) }
+func (*PeerInfo) ProtoMessage() {}
+
+type Peer struct {
+ Conf *PeerConf `protobuf:"bytes,1,opt,name=conf" json:"conf,omitempty"`
+ Info *PeerInfo `protobuf:"bytes,2,opt,name=info" json:"info,omitempty"`
+}
+
+func (m *Peer) Reset() { *m = Peer{} }
+func (m *Peer) String() string { return proto.CompactTextString(m) }
+func (*Peer) ProtoMessage() {}
+
+func (m *Peer) GetConf() *PeerConf {
+ if m != nil {
+ return m.Conf
+ }
+ return nil
+}
+
+func (m *Peer) GetInfo() *PeerInfo {
+ if m != nil {
+ return m.Info
+ }
+ return nil
+}
+
+func init() {
+ proto.RegisterEnum("api.Resource", Resource_name, Resource_value)
+ proto.RegisterEnum("api.AddressFamily", AddressFamily_name, AddressFamily_value)
+ proto.RegisterEnum("api.Error_ErrorCode", Error_ErrorCode_name, Error_ErrorCode_value)
+ proto.RegisterEnum("api.PathAttr_Origin", PathAttr_Origin_name, PathAttr_Origin_value)
+}
+
+// Client API for Grpc service
+
+type GrpcClient interface {
+ GetNeighbors(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetNeighborsClient, error)
+ GetNeighbor(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Peer, error)
+ GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetRibClient, error)
+ GetAdjRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetAdjRibClient, error)
+ Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ SoftReset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ SoftResetIn(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ SoftResetOut(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ Shutdown(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ Enable(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ Disable(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error)
+ AddPath(ctx context.Context, opts ...grpc.CallOption) (Grpc_AddPathClient, error)
+ DeletePath(ctx context.Context, opts ...grpc.CallOption) (Grpc_DeletePathClient, error)
+}
+
+type grpcClient struct {
+ cc *grpc.ClientConn
+}
+
+func NewGrpcClient(cc *grpc.ClientConn) GrpcClient {
+ return &grpcClient{cc}
+}
+
+func (c *grpcClient) GetNeighbors(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetNeighborsClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[0], c.cc, "/api.Grpc/GetNeighbors", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcGetNeighborsClient{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_GetNeighborsClient interface {
+ Recv() (*Peer, error)
+ grpc.ClientStream
+}
+
+type grpcGetNeighborsClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcGetNeighborsClient) Recv() (*Peer, error) {
+ m := new(Peer)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *grpcClient) GetNeighbor(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Peer, error) {
+ out := new(Peer)
+ err := grpc.Invoke(ctx, "/api.Grpc/GetNeighbor", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) GetRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetRibClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[1], c.cc, "/api.Grpc/GetRib", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcGetRibClient{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_GetRibClient interface {
+ Recv() (*Destination, error)
+ grpc.ClientStream
+}
+
+type grpcGetRibClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcGetRibClient) Recv() (*Destination, error) {
+ m := new(Destination)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *grpcClient) GetAdjRib(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (Grpc_GetAdjRibClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[2], c.cc, "/api.Grpc/GetAdjRib", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcGetAdjRibClient{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_GetAdjRibClient interface {
+ Recv() (*Path, error)
+ grpc.ClientStream
+}
+
+type grpcGetAdjRibClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcGetAdjRibClient) Recv() (*Path, error) {
+ m := new(Path)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *grpcClient) Reset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/Reset", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) SoftReset(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/SoftReset", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) SoftResetIn(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/SoftResetIn", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) SoftResetOut(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/SoftResetOut", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) Shutdown(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/Shutdown", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) Enable(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/Enable", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) Disable(ctx context.Context, in *Arguments, opts ...grpc.CallOption) (*Error, error) {
+ out := new(Error)
+ err := grpc.Invoke(ctx, "/api.Grpc/Disable", in, out, c.cc, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *grpcClient) AddPath(ctx context.Context, opts ...grpc.CallOption) (Grpc_AddPathClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[3], c.cc, "/api.Grpc/AddPath", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcAddPathClient{stream}
+ return x, nil
+}
+
+type Grpc_AddPathClient interface {
+ Send(*Arguments) error
+ CloseAndRecv() (*Error, error)
+ grpc.ClientStream
+}
+
+type grpcAddPathClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcAddPathClient) Send(m *Arguments) error {
+ return x.ClientStream.SendMsg(m)
+}
+
+func (x *grpcAddPathClient) CloseAndRecv() (*Error, error) {
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ m := new(Error)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (c *grpcClient) DeletePath(ctx context.Context, opts ...grpc.CallOption) (Grpc_DeletePathClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[4], c.cc, "/api.Grpc/DeletePath", opts...)
+ if err != nil {
+ return nil, err
+ }
+ x := &grpcDeletePathClient{stream}
+ return x, nil
+}
+
+type Grpc_DeletePathClient interface {
+ Send(*Arguments) error
+ CloseAndRecv() (*Error, error)
+ grpc.ClientStream
+}
+
+type grpcDeletePathClient struct {
+ grpc.ClientStream
+}
+
+func (x *grpcDeletePathClient) Send(m *Arguments) error {
+ return x.ClientStream.SendMsg(m)
+}
+
+func (x *grpcDeletePathClient) CloseAndRecv() (*Error, error) {
+ if err := x.ClientStream.CloseSend(); err != nil {
+ return nil, err
+ }
+ m := new(Error)
+ if err := x.ClientStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+// Server API for Grpc service
+
+type GrpcServer interface {
+ GetNeighbors(*Arguments, Grpc_GetNeighborsServer) error
+ GetNeighbor(context.Context, *Arguments) (*Peer, error)
+ GetRib(*Arguments, Grpc_GetRibServer) error
+ GetAdjRib(*Arguments, Grpc_GetAdjRibServer) error
+ Reset(context.Context, *Arguments) (*Error, error)
+ SoftReset(context.Context, *Arguments) (*Error, error)
+ SoftResetIn(context.Context, *Arguments) (*Error, error)
+ SoftResetOut(context.Context, *Arguments) (*Error, error)
+ Shutdown(context.Context, *Arguments) (*Error, error)
+ Enable(context.Context, *Arguments) (*Error, error)
+ Disable(context.Context, *Arguments) (*Error, error)
+ AddPath(Grpc_AddPathServer) error
+ DeletePath(Grpc_DeletePathServer) error
+}
+
+func RegisterGrpcServer(s *grpc.Server, srv GrpcServer) {
+ s.RegisterService(&_Grpc_serviceDesc, srv)
+}
+
+func _Grpc_GetNeighbors_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(Arguments)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(GrpcServer).GetNeighbors(m, &grpcGetNeighborsServer{stream})
+}
+
+type Grpc_GetNeighborsServer interface {
+ Send(*Peer) error
+ grpc.ServerStream
+}
+
+type grpcGetNeighborsServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcGetNeighborsServer) Send(m *Peer) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _Grpc_GetNeighbor_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).GetNeighbor(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_GetRib_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(Arguments)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(GrpcServer).GetRib(m, &grpcGetRibServer{stream})
+}
+
+type Grpc_GetRibServer interface {
+ Send(*Destination) error
+ grpc.ServerStream
+}
+
+type grpcGetRibServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcGetRibServer) Send(m *Destination) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _Grpc_GetAdjRib_Handler(srv interface{}, stream grpc.ServerStream) error {
+ m := new(Arguments)
+ if err := stream.RecvMsg(m); err != nil {
+ return err
+ }
+ return srv.(GrpcServer).GetAdjRib(m, &grpcGetAdjRibServer{stream})
+}
+
+type Grpc_GetAdjRibServer interface {
+ Send(*Path) error
+ grpc.ServerStream
+}
+
+type grpcGetAdjRibServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcGetAdjRibServer) Send(m *Path) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func _Grpc_Reset_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).Reset(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_SoftReset_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).SoftReset(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_SoftResetIn_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).SoftResetIn(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_SoftResetOut_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).SoftResetOut(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_Shutdown_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).Shutdown(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_Enable_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).Enable(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_Disable_Handler(srv interface{}, ctx context.Context, buf []byte) (interface{}, error) {
+ in := new(Arguments)
+ if err := proto.Unmarshal(buf, in); err != nil {
+ return nil, err
+ }
+ out, err := srv.(GrpcServer).Disable(ctx, in)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func _Grpc_AddPath_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(GrpcServer).AddPath(&grpcAddPathServer{stream})
+}
+
+type Grpc_AddPathServer interface {
+ SendAndClose(*Error) error
+ Recv() (*Arguments, error)
+ grpc.ServerStream
+}
+
+type grpcAddPathServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcAddPathServer) SendAndClose(m *Error) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func (x *grpcAddPathServer) Recv() (*Arguments, error) {
+ m := new(Arguments)
+ if err := x.ServerStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func _Grpc_DeletePath_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(GrpcServer).DeletePath(&grpcDeletePathServer{stream})
+}
+
+type Grpc_DeletePathServer interface {
+ SendAndClose(*Error) error
+ Recv() (*Arguments, error)
+ grpc.ServerStream
+}
+
+type grpcDeletePathServer struct {
+ grpc.ServerStream
+}
+
+func (x *grpcDeletePathServer) SendAndClose(m *Error) error {
+ return x.ServerStream.SendMsg(m)
+}
+
+func (x *grpcDeletePathServer) Recv() (*Arguments, error) {
+ m := new(Arguments)
+ if err := x.ServerStream.RecvMsg(m); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+var _Grpc_serviceDesc = grpc.ServiceDesc{
+ ServiceName: "api.Grpc",
+ HandlerType: (*GrpcServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "GetNeighbor",
+ Handler: _Grpc_GetNeighbor_Handler,
+ },
+ {
+ MethodName: "Reset",
+ Handler: _Grpc_Reset_Handler,
+ },
+ {
+ MethodName: "SoftReset",
+ Handler: _Grpc_SoftReset_Handler,
+ },
+ {
+ MethodName: "SoftResetIn",
+ Handler: _Grpc_SoftResetIn_Handler,
+ },
+ {
+ MethodName: "SoftResetOut",
+ Handler: _Grpc_SoftResetOut_Handler,
+ },
+ {
+ MethodName: "Shutdown",
+ Handler: _Grpc_Shutdown_Handler,
+ },
+ {
+ MethodName: "Enable",
+ Handler: _Grpc_Enable_Handler,
+ },
+ {
+ MethodName: "Disable",
+ Handler: _Grpc_Disable_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{
+ {
+ StreamName: "GetNeighbors",
+ Handler: _Grpc_GetNeighbors_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "GetRib",
+ Handler: _Grpc_GetRib_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "GetAdjRib",
+ Handler: _Grpc_GetAdjRib_Handler,
+ ServerStreams: true,
+ },
+ {
+ StreamName: "AddPath",
+ Handler: _Grpc_AddPath_Handler,
+ ClientStreams: true,
+ },
+ {
+ StreamName: "DeletePath",
+ Handler: _Grpc_DeletePath_Handler,
+ ClientStreams: true,
+ },
+ },
+}
diff --git a/api/gobgp.proto b/api/gobgp.proto
new file mode 100644
index 00000000..41832653
--- /dev/null
+++ b/api/gobgp.proto
@@ -0,0 +1,145 @@
+// Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package api;
+
+// Interface exported by the server.
+
+service Grpc {
+ rpc GetNeighbors(Arguments) returns (stream Peer) {}
+ rpc GetNeighbor(Arguments) returns (Peer) {}
+ rpc GetRib(Arguments) returns (stream Destination) {}
+ rpc GetAdjRib(Arguments) returns (stream Path) {}
+ rpc Reset(Arguments) returns (Error) {}
+ rpc SoftReset(Arguments) returns (Error) {}
+ rpc SoftResetIn(Arguments) returns (Error) {}
+ rpc SoftResetOut(Arguments) returns (Error) {}
+ rpc Shutdown(Arguments) returns (Error) {}
+ rpc Enable(Arguments) returns (Error) {}
+ rpc Disable(Arguments) returns (Error) {}
+ rpc AddPath(stream Arguments) returns (Error) {}
+ rpc DeletePath(stream Arguments) returns (Error) {}
+}
+
+message Error {
+ enum ErrorCode {
+ SUCCESS = 0;
+ FAIL = 1;
+ }
+ ErrorCode code = 1;
+ string msg = 2;
+}
+
+message Arguments {
+ Resource resource = 1;
+ AddressFamily af = 2;
+ string router_id = 3;
+ string prefix = 4;
+}
+
+enum Resource {
+ GLOBAL = 0;
+ LOCAL = 1;
+ ADJ_IN = 2;
+ ADJ_OUT = 3;
+}
+
+enum AddressFamily {
+ IPV4 = 0;
+ IPV6 = 1;
+ EVPN = 2;
+}
+
+message PathAttr {
+
+ string type = 1;
+ enum Origin {
+ IGP = 0;
+ EGP = 1;
+ INCOMPLETE = 2;
+ }
+ message Aggregator {
+ uint32 as = 1;
+ string address = 2;
+ }
+ Origin origin = 2;
+ repeated uint32 as_path = 3;
+ uint32 metric = 4;
+ uint32 pref = 5;
+ Aggregator aggregator = 6;
+ repeated uint32 communites = 7;
+ string originator = 8;
+ string cluster = 9;
+ uint32 value = 10;
+}
+
+message Path {
+ string network = 1;
+ string nexthop = 2;
+ int64 age = 3;
+ repeated PathAttr attrs = 4;
+ bool best = 5;
+}
+
+message Destination {
+ string prefix = 1;
+ repeated Path paths = 2;
+ int32 best_path_idx = 3;
+}
+
+message PeerConf {
+ string remote_ip = 1;
+ string id = 2;
+ uint32 remote_as = 3;
+ bool cap_refresh = 4;
+ bool cap_enhanced_refresh = 5;
+ repeated int32 remote_cap = 6;
+ repeated int32 local_cap = 7;
+}
+
+message PeerInfo {
+ string bgp_state = 1;
+ string admin_state = 2;
+ uint32 fsm_established_transitions = 3;
+ uint32 total_message_out = 4;
+ uint32 total_message_in = 5;
+ uint32 update_message_out = 6;
+ uint32 update_message_in = 7;
+ uint32 keep_alive_message_out = 8;
+ uint32 keep_alive_message_in = 9;
+ uint32 open_message_out = 10;
+ uint32 open_message_in = 11;
+ uint32 notification_out = 12;
+ uint32 notification_in = 13;
+ uint32 refresh_message_out = 14;
+ uint32 refresh_message_in = 15;
+ uint32 discarded_out = 16;
+ uint32 discarded_in = 17;
+ int64 uptime = 18;
+ int64 downtime = 19;
+ string last_error = 20;
+ uint32 received = 21;
+ uint32 accepted = 22;
+ uint32 advertized = 23;
+ uint32 out_q = 24;
+ uint32 flops = 25;
+}
+
+message Peer {
+ PeerConf conf = 1;
+ PeerInfo info = 2;
+}
diff --git a/api/grpc.go b/api/grpc.go
new file mode 100644
index 00000000..69e8d159
--- /dev/null
+++ b/api/grpc.go
@@ -0,0 +1,318 @@
+// Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package api
+
+import (
+ "fmt"
+ log "github.com/Sirupsen/logrus"
+ "github.com/osrg/gobgp/packet"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "io"
+ "net"
+)
+
+const (
+ _ = iota
+ REQ_NEIGHBOR
+ REQ_NEIGHBORS
+ REQ_ADJ_RIB_IN
+ REQ_ADJ_RIB_OUT
+ REQ_LOCAL_RIB
+ REQ_NEIGHBOR_SHUTDOWN
+ REQ_NEIGHBOR_RESET
+ REQ_NEIGHBOR_SOFT_RESET
+ REQ_NEIGHBOR_SOFT_RESET_IN
+ REQ_NEIGHBOR_SOFT_RESET_OUT
+ REQ_NEIGHBOR_ENABLE
+ REQ_NEIGHBOR_DISABLE
+ REQ_GLOBAL_RIB
+ REQ_GLOBAL_ADD
+ REQ_GLOBAL_DELETE
+)
+
+const GRPC_PORT = 8080
+
+type Server struct {
+ grpcServer *grpc.Server
+ bgpServerCh chan *GrpcRequest
+}
+
+func (s *Server) Serve() error {
+ lis, err := net.Listen("tcp", fmt.Sprintf(":%d", GRPC_PORT))
+ if err != nil {
+ return fmt.Errorf("failed to listen: %v", err)
+ }
+ s.grpcServer.Serve(lis)
+ return nil
+}
+
+func (s *Server) GetNeighbor(ctx context.Context, arg *Arguments) (*Peer, error) {
+ var rf bgp.RouteFamily
+ req := NewGrpcRequest(REQ_NEIGHBOR, arg.RouterId, rf, nil)
+ s.bgpServerCh <- req
+
+ res := <-req.ResponseCh
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return nil, err
+ }
+
+ return res.Data.(*Peer), nil
+}
+
+func (s *Server) GetNeighbors(_ *Arguments, stream Grpc_GetNeighborsServer) error {
+ var rf bgp.RouteFamily
+ req := NewGrpcRequest(REQ_NEIGHBORS, "", rf, nil)
+ s.bgpServerCh <- req
+
+ for res := range req.ResponseCh {
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return err
+ }
+ if err := stream.Send(res.Data.(*Peer)); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (s *Server) GetAdjRib(arg *Arguments, stream Grpc_GetAdjRibServer) error {
+ var reqType int
+ switch arg.Resource {
+ case Resource_ADJ_IN:
+ reqType = REQ_ADJ_RIB_IN
+ case Resource_ADJ_OUT:
+ reqType = REQ_ADJ_RIB_OUT
+ default:
+ return fmt.Errorf("unsupported resource type: %v", arg.Resource)
+ }
+
+ var rf bgp.RouteFamily
+ switch arg.Af {
+ case AddressFamily_IPV4:
+ rf = bgp.RF_IPv4_UC
+ case AddressFamily_IPV6:
+ rf = bgp.RF_IPv6_UC
+ case AddressFamily_EVPN:
+ rf = bgp.RF_EVPN
+ default:
+ return fmt.Errorf("unsupported resource type: %v", arg.Af)
+ }
+
+ req := NewGrpcRequest(reqType, arg.RouterId, rf, nil)
+ s.bgpServerCh <- req
+
+ for res := range req.ResponseCh {
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return err
+ }
+ if err := stream.Send(res.Data.(*Path)); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (s *Server) GetRib(arg *Arguments, stream Grpc_GetRibServer) error {
+ var reqType int
+ switch arg.Resource {
+ case Resource_LOCAL:
+ reqType = REQ_LOCAL_RIB
+ case Resource_GLOBAL:
+ reqType = REQ_GLOBAL_RIB
+ default:
+ return fmt.Errorf("unsupported resource type: %v", arg.Resource)
+ }
+
+ var rf bgp.RouteFamily
+ switch arg.Af {
+ case AddressFamily_IPV4:
+ rf = bgp.RF_IPv4_UC
+ case AddressFamily_IPV6:
+ rf = bgp.RF_IPv6_UC
+ case AddressFamily_EVPN:
+ rf = bgp.RF_EVPN
+ default:
+ return fmt.Errorf("unsupported resource type: %v", arg.Af)
+ }
+
+ req := NewGrpcRequest(reqType, arg.RouterId, rf, nil)
+ s.bgpServerCh <- req
+
+ for res := range req.ResponseCh {
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return err
+ }
+ if err := stream.Send(res.Data.(*Destination)); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (s *Server) neighbor(reqType int, arg *Arguments) (*Error, error) {
+ var rf bgp.RouteFamily
+ switch arg.Af {
+ case AddressFamily_IPV4:
+ rf = bgp.RF_IPv4_UC
+ case AddressFamily_IPV6:
+ rf = bgp.RF_IPv6_UC
+ case AddressFamily_EVPN:
+ rf = bgp.RF_EVPN
+ default:
+ return nil, fmt.Errorf("unsupported resource type: %v", arg.Af)
+ }
+
+ none := &Error{}
+ req := NewGrpcRequest(reqType, arg.RouterId, rf, nil)
+ s.bgpServerCh <- req
+
+ res := <-req.ResponseCh
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return nil, err
+ }
+ return none, nil
+}
+
+func (s *Server) Reset(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_RESET, arg)
+}
+
+func (s *Server) SoftReset(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_SOFT_RESET, arg)
+}
+
+func (s *Server) SoftResetIn(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_SOFT_RESET_IN, arg)
+}
+
+func (s *Server) SoftResetOut(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_SOFT_RESET_OUT, arg)
+}
+
+func (s *Server) Shutdown(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_SHUTDOWN, arg)
+}
+
+func (s *Server) Enable(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_ENABLE, arg)
+}
+
+func (s *Server) Disable(ctx context.Context, arg *Arguments) (*Error, error) {
+ return s.neighbor(REQ_NEIGHBOR_DISABLE, arg)
+}
+
+func (s *Server) modPath(reqType int, stream grpc.ServerStream) error {
+ for {
+ var err error
+ var arg *Arguments
+
+ if reqType == REQ_GLOBAL_ADD {
+ arg, err = stream.(Grpc_AddPathServer).Recv()
+ } else if reqType == REQ_GLOBAL_DELETE {
+ arg, err = stream.(Grpc_DeletePathServer).Recv()
+ } else {
+ return fmt.Errorf("unsupportd req: %d", reqType)
+ }
+
+ if err == io.EOF {
+ return nil
+ } else if err != nil {
+ return err
+ }
+
+ if arg.Resource != Resource_GLOBAL {
+ return fmt.Errorf("unsupported resource: %s", arg.Resource)
+ }
+ prefix := make(map[string]interface{}, 1)
+ prefix["prefix"] = arg.Prefix
+
+ var rf bgp.RouteFamily
+ switch arg.Af {
+ case AddressFamily_IPV4:
+ rf = bgp.RF_IPv4_UC
+ case AddressFamily_IPV6:
+ rf = bgp.RF_IPv6_UC
+ case AddressFamily_EVPN:
+ rf = bgp.RF_EVPN
+ default:
+ return fmt.Errorf("unsupported resource type: %v", arg.Af)
+ }
+
+ req := NewGrpcRequest(reqType, arg.RouterId, rf, prefix)
+ s.bgpServerCh <- req
+
+ res := <-req.ResponseCh
+ if err := res.Err(); err != nil {
+ log.Debug(err.Error())
+ return err
+ }
+ }
+}
+
+func (s *Server) AddPath(stream Grpc_AddPathServer) error {
+ return s.modPath(REQ_GLOBAL_ADD, stream)
+}
+
+func (s *Server) DeletePath(stream Grpc_DeletePathServer) error {
+ return s.modPath(REQ_GLOBAL_DELETE, stream)
+}
+
+type GrpcRequest struct {
+ RequestType int
+ RemoteAddr string
+ RouteFamily bgp.RouteFamily
+ ResponseCh chan *GrpcResponse
+ Err error
+ Data map[string]interface{}
+}
+
+func NewGrpcRequest(reqType int, remoteAddr string, rf bgp.RouteFamily, d map[string]interface{}) *GrpcRequest {
+ r := &GrpcRequest{
+ RequestType: reqType,
+ RouteFamily: rf,
+ RemoteAddr: remoteAddr,
+ ResponseCh: make(chan *GrpcResponse),
+ Data: d,
+ }
+ return r
+}
+
+type GrpcResponse struct {
+ ResponseErr error
+ Data interface{}
+}
+
+func (r *GrpcResponse) Err() error {
+ return r.ResponseErr
+}
+
+func NewGrpcServer(port int, bgpServerCh chan *GrpcRequest) *Server {
+ grpcServer := grpc.NewServer()
+ server := &Server{
+ grpcServer: grpcServer,
+ bgpServerCh: bgpServerCh,
+ }
+ RegisterGrpcServer(grpcServer, server)
+ return server
+}
diff --git a/api/rest.go b/api/rest.go
deleted file mode 100644
index fd57253d..00000000
--- a/api/rest.go
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright (C) 2014,2015 Nippon Telegraph and Telephone Corporation.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-// implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package api
-
-import (
- "bytes"
- log "github.com/Sirupsen/logrus"
- "github.com/fukata/golang-stats-api-handler"
- "github.com/gorilla/mux"
- "github.com/osrg/gobgp/packet"
- "net/http"
- "net/url"
- "strconv"
-)
-
-const (
- _ = iota
- REQ_NEIGHBOR
- REQ_NEIGHBORS
- REQ_ADJ_RIB_IN
- REQ_ADJ_RIB_OUT
- REQ_LOCAL_RIB
- REQ_NEIGHBOR_SHUTDOWN
- REQ_NEIGHBOR_RESET
- REQ_NEIGHBOR_SOFT_RESET
- REQ_NEIGHBOR_SOFT_RESET_IN
- REQ_NEIGHBOR_SOFT_RESET_OUT
- REQ_NEIGHBOR_ENABLE
- REQ_NEIGHBOR_DISABLE
- REQ_GLOBAL_RIB
- REQ_GLOBAL_ADD
- REQ_GLOBAL_DELETE
-)
-
-const (
- BASE_VERSION = "/v1"
- GLOBAL = "/bgp/global"
- NEIGHBOR = "/bgp/neighbor"
- NEIGHBORS = "/bgp/neighbors"
-
- PARAM_REMOTE_PEER_ADDR = "remotePeerAddr"
- PARAM_SHOW_OBJECT = "showObject"
- PARAM_OPERATION = "operation"
- PARAM_ROUTE_FAMILY = "routeFamily"
-
- STATS = "/stats"
-)
-
-const REST_PORT = 8080
-
-// trigger struct for exchanging information in the rest and peer.
-// rest and peer operated at different thread.
-
-type RestRequest struct {
- RequestType int
- RemoteAddr string
- RouteFamily bgp.RouteFamily
- ResponseCh chan *RestResponse
- Err error
- Data map[string]interface{}
-}
-
-func NewRestRequest(reqType int, remoteAddr string, rf bgp.RouteFamily, d map[string]interface{}) *RestRequest {
- r := &RestRequest{
- RequestType: reqType,
- RouteFamily: rf,
- RemoteAddr: remoteAddr,
- ResponseCh: make(chan *RestResponse),
- Data: d,
- }
- return r
-}
-
-type RestResponse struct {
- ResponseErr error
- Data []byte
-}
-
-func (r *RestResponse) Err() error {
- return r.ResponseErr
-}
-
-type RestServer struct {
- port int
- bgpServerCh chan *RestRequest
-}
-
-func NewRestServer(port int, bgpServerCh chan *RestRequest) *RestServer {
- rs := &RestServer{
- port: port,
- bgpServerCh: bgpServerCh}
- return rs
-}
-
-// Main thread of rest service.
-// URL than can receive.
-// get state of neighbors.
-// -- curl -i -X GET http://<ownIP>:8080/v1/bgp/neighbors
-// get state of neighbor.
-// -- curl -i -X GET http://<ownIP>:8080/v1/bgp/neighbor/<remote address of target neighbor>
-// get adj-rib-in of each neighbor.
-// -- curl -i -X GET http://<ownIP>:8080/v1/bgp/neighbor/<remote address of target neighbor>/adj-rib-in/<rf>
-// get adj-rib-out of each neighbor.
-// -- curl -i -X GET http://<ownIP>:8080/v1/bgp/neighbor/<remote address of target neighbor>/adj-rib-out/<rf>
-// get local-rib of each neighbor.
-// -- curl -i -X GET http://<ownIP>:8080/v1/bgp/neighbor/<remote address of target neighbor>/local-rib/<rf>
-func (rs *RestServer) Serve() {
- global := BASE_VERSION + GLOBAL
- neighbor := BASE_VERSION + NEIGHBOR
- neighbors := BASE_VERSION + NEIGHBORS
-
- r := mux.NewRouter()
- perPeerURL := "/{" + PARAM_REMOTE_PEER_ADDR + "}"
- showObjectURL := "/{" + PARAM_SHOW_OBJECT + "}"
- operationURL := "/{" + PARAM_OPERATION + "}"
- routeFamilyURL := "/{" + PARAM_ROUTE_FAMILY + "}"
- r.HandleFunc(global+showObjectURL+routeFamilyURL, rs.GlobalGET).Methods("GET")
- r.HandleFunc(global+routeFamilyURL, rs.GlobalPOST).Methods("POST")
- r.HandleFunc(global+routeFamilyURL, rs.GlobalDELETE).Methods("DELETE")
- r.HandleFunc(neighbors, rs.NeighborGET).Methods("GET")
- r.HandleFunc(neighbor+perPeerURL, rs.NeighborGET).Methods("GET")
- r.HandleFunc(neighbor+perPeerURL+showObjectURL+routeFamilyURL, rs.NeighborGET).Methods("GET")
- r.HandleFunc(neighbor+perPeerURL+operationURL, rs.NeighborPOST).Methods("POST")
- r.HandleFunc(neighbor+perPeerURL+operationURL+routeFamilyURL, rs.NeighborPOST).Methods("POST")
-
- // stats
- r.HandleFunc(STATS, stats_api.Handler).Methods("GET")
-
- // Handler when not found url
- r.NotFoundHandler = http.HandlerFunc(NotFoundHandler)
- http.Handle("/", r)
-
- http.ListenAndServe(":"+strconv.Itoa(rs.port), nil)
-
-}
-
-func (rs *RestServer) neighbor(w http.ResponseWriter, r *http.Request, reqType int) {
- params := mux.Vars(r)
- remoteAddr, _ := params[PARAM_REMOTE_PEER_ADDR]
- log.Debugf("Look up neighbor with the remote address : %v", remoteAddr)
- var rf bgp.RouteFamily
- routeFamily, ok := params[PARAM_ROUTE_FAMILY]
- if ok {
- switch routeFamily {
- case "ipv4":
- rf = bgp.RF_IPv4_UC
- case "ipv6":
- rf = bgp.RF_IPv6_UC
- case "evpn":
- rf = bgp.RF_EVPN
- default:
- NotFoundHandler(w, r)
- return
- }
- }
-
- //Send channel of request parameter.
- req := NewRestRequest(reqType, remoteAddr, rf, nil)
- rs.bgpServerCh <- req
-
- //Wait response
- res := <-req.ResponseCh
- if e := res.Err(); e != nil {
- log.Debug(e.Error())
- http.Error(w, e.Error(), http.StatusInternalServerError)
- return
- }
-
- w.Header().Set("Content-Type", "application/json; charset=utf-8")
- w.Write(res.Data)
-}
-
-func (rs *RestServer) NeighborPOST(w http.ResponseWriter, r *http.Request) {
- params := mux.Vars(r)
- switch params[PARAM_OPERATION] {
- case "shutdown":
- rs.neighbor(w, r, REQ_NEIGHBOR_SHUTDOWN)
- case "reset":
- rs.neighbor(w, r, REQ_NEIGHBOR_RESET)
- case "softreset":
- rs.neighbor(w, r, REQ_NEIGHBOR_SOFT_RESET)
- case "softresetin":
- rs.neighbor(w, r, REQ_NEIGHBOR_SOFT_RESET_IN)
- case "softresetout":
- rs.neighbor(w, r, REQ_NEIGHBOR_SOFT_RESET_OUT)
- case "enable":
- rs.neighbor(w, r, REQ_NEIGHBOR_ENABLE)
- case "disable":
- rs.neighbor(w, r, REQ_NEIGHBOR_DISABLE)
- default:
- NotFoundHandler(w, r)
- }
-}
-
-func (rs *RestServer) NeighborGET(w http.ResponseWriter, r *http.Request) {
- params := mux.Vars(r)
- if _, ok := params[PARAM_REMOTE_PEER_ADDR]; !ok {
- rs.neighbor(w, r, REQ_NEIGHBORS)
- return
- }
-
- if showObject, ok := params[PARAM_SHOW_OBJECT]; ok {
- switch showObject {
- case "local-rib":
- rs.neighbor(w, r, REQ_LOCAL_RIB)
- case "adj-rib-in":
- rs.neighbor(w, r, REQ_ADJ_RIB_IN)
- case "adj-rib-out":
- rs.neighbor(w, r, REQ_ADJ_RIB_OUT)
- default:
- NotFoundHandler(w, r)
- }
- } else {
- rs.neighbor(w, r, REQ_NEIGHBOR)
- }
-}
-
-func (rs *RestServer) GlobalGET(w http.ResponseWriter, r *http.Request) {
- params := mux.Vars(r)
- if showObject, ok := params[PARAM_SHOW_OBJECT]; ok {
- switch showObject {
- case "rib":
- rs.neighbor(w, r, REQ_GLOBAL_RIB)
- default:
- NotFoundHandler(w, r)
- }
- }
-
-}
-
-func (rs *RestServer) global(w http.ResponseWriter, r *http.Request, reqType int) {
- params := mux.Vars(r)
- var rf bgp.RouteFamily
- routeFamily, ok := params[PARAM_ROUTE_FAMILY]
- if ok {
- switch routeFamily {
- case "ipv4":
- rf = bgp.RF_IPv4_UC
- case "ipv6":
- rf = bgp.RF_IPv6_UC
- case "evpn":
- rf = bgp.RF_EVPN
- default:
- NotFoundHandler(w, r)
- return
- }
- }
- var buf bytes.Buffer
- buf.ReadFrom(r.Body)
- query, _ := url.ParseQuery(buf.String())
- d := make(map[string]interface{})
- for k, v := range query {
- d[k] = v
- }
- req := NewRestRequest(reqType, "", rf, d)
- rs.bgpServerCh <- req
-
- //Wait response
- res := <-req.ResponseCh
- if e := res.Err(); e != nil {
- log.Debug(e.Error())
- http.Error(w, e.Error(), http.StatusInternalServerError)
- return
- }
-
- w.Header().Set("Content-Type", "application/json; charset=utf-8")
- w.Write(res.Data)
-}
-
-func (rs *RestServer) GlobalPOST(w http.ResponseWriter, r *http.Request) {
- rs.global(w, r, REQ_GLOBAL_ADD)
-}
-
-func (rs *RestServer) GlobalDELETE(w http.ResponseWriter, r *http.Request) {
- rs.global(w, r, REQ_GLOBAL_DELETE)
-}
-
-func NotFoundHandler(w http.ResponseWriter, r *http.Request) {
- http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
-}