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
This commit is contained in:
Naoto Hanaue
2015-05-19 16:33:16 +09:00
committed by FUJITA Tomonori
parent 772dbed046
commit 8d0eb0a06b
5 changed files with 364 additions and 14 deletions
+138 -14
View File
@@ -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,
},
},
}
+14
View File
@@ -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;
}
+139
View File
@@ -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"`
+21
View File
@@ -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
+52
View File
@@ -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
}