summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--api/gobgp.pb.go490
-rw-r--r--api/gobgp.proto134
-rw-r--r--api/util.go24
-rw-r--r--gobgp/main.go147
-rw-r--r--gobgpd/main.go3
-rw-r--r--packet/bgp.go288
-rw-r--r--server/grpc_server.go (renamed from api/grpc.go)154
-rw-r--r--server/peer.go77
-rw-r--r--server/peer_test.go18
-rw-r--r--server/server.go39
-rw-r--r--table/destination.go33
-rw-r--r--table/path.go31
-rw-r--r--table/table.go8
-rw-r--r--table/table_manager.go2
-rw-r--r--table/table_manager_test.go4
-rw-r--r--table/table_test.go4
-rw-r--r--test/scenario_test/bgp_router_test.py5
-rw-r--r--test/scenario_test/gobgp_test.py16
-rw-r--r--test/scenario_test/route_server_policy_test.py149
-rw-r--r--test/scenario_test/route_server_test.py2
20 files changed, 1004 insertions, 624 deletions
diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go
index 3b91d6ea..f69432a0 100644
--- a/api/gobgp.pb.go
+++ b/api/gobgp.pb.go
@@ -11,6 +11,12 @@ It is generated from these files:
It has these top-level messages:
Error
Arguments
+ ModPathArguments
+ AddressFamily
+ Aggregator
+ EVPNNlri
+ EvpnMacIpAdvertisement
+ Nlri
PathAttr
Path
Destination
@@ -60,70 +66,205 @@ func (x Resource) String() string {
return proto.EnumName(Resource_name, int32(x))
}
-type AddressFamily int32
+type AFI int32
const (
- AddressFamily_IPV4 AddressFamily = 0
- AddressFamily_IPV6 AddressFamily = 1
- AddressFamily_EVPN AddressFamily = 2
+ AFI_UNKNOWN_AFI AFI = 0
+ AFI_IP AFI = 1
+ AFI_IP6 AFI = 2
+ AFI_L2VPN AFI = 25
)
-var AddressFamily_name = map[int32]string{
- 0: "IPV4",
- 1: "IPV6",
- 2: "EVPN",
+var AFI_name = map[int32]string{
+ 0: "UNKNOWN_AFI",
+ 1: "IP",
+ 2: "IP6",
+ 25: "L2VPN",
}
-var AddressFamily_value = map[string]int32{
- "IPV4": 0,
- "IPV6": 1,
- "EVPN": 2,
+var AFI_value = map[string]int32{
+ "UNKNOWN_AFI": 0,
+ "IP": 1,
+ "IP6": 2,
+ "L2VPN": 25,
}
-func (x AddressFamily) String() string {
- return proto.EnumName(AddressFamily_name, int32(x))
+func (x AFI) String() string {
+ return proto.EnumName(AFI_name, int32(x))
}
-type Error_ErrorCode int32
+type SAFI int32
const (
- Error_SUCCESS Error_ErrorCode = 0
- Error_FAIL Error_ErrorCode = 1
+ SAFI_UNKNOWN_SAFI SAFI = 0
+ SAFI_UNICAST SAFI = 1
+ SAFI_MULTICAST SAFI = 2
+ SAFI_MPLS_LABEL SAFI = 4
+ SAFI_VPLS SAFI = 65
+ SAFI_EVPN SAFI = 70
+ SAFI_MPLS_VPN SAFI = 128
+ SAFI_MPLS_VPN_MULTICAST SAFI = 129
+ SAFI_ROUTE_TARGET_CONSTRTAINS SAFI = 132
)
-var Error_ErrorCode_name = map[int32]string{
- 0: "SUCCESS",
- 1: "FAIL",
+var SAFI_name = map[int32]string{
+ 0: "UNKNOWN_SAFI",
+ 1: "UNICAST",
+ 2: "MULTICAST",
+ 4: "MPLS_LABEL",
+ 65: "VPLS",
+ 70: "EVPN",
+ 128: "MPLS_VPN",
+ 129: "MPLS_VPN_MULTICAST",
+ 132: "ROUTE_TARGET_CONSTRTAINS",
}
-var Error_ErrorCode_value = map[string]int32{
- "SUCCESS": 0,
- "FAIL": 1,
+var SAFI_value = map[string]int32{
+ "UNKNOWN_SAFI": 0,
+ "UNICAST": 1,
+ "MULTICAST": 2,
+ "MPLS_LABEL": 4,
+ "VPLS": 65,
+ "EVPN": 70,
+ "MPLS_VPN": 128,
+ "MPLS_VPN_MULTICAST": 129,
+ "ROUTE_TARGET_CONSTRTAINS": 132,
}
-func (x Error_ErrorCode) String() string {
- return proto.EnumName(Error_ErrorCode_name, int32(x))
+func (x SAFI) String() string {
+ return proto.EnumName(SAFI_name, int32(x))
}
-type PathAttr_Origin int32
+type Origin int32
const (
- PathAttr_IGP PathAttr_Origin = 0
- PathAttr_EGP PathAttr_Origin = 1
- PathAttr_INCOMPLETE PathAttr_Origin = 2
+ Origin_IGP Origin = 0
+ Origin_EGP Origin = 1
+ Origin_INCOMPLETE Origin = 2
)
-var PathAttr_Origin_name = map[int32]string{
+var Origin_name = map[int32]string{
0: "IGP",
1: "EGP",
2: "INCOMPLETE",
}
-var PathAttr_Origin_value = map[string]int32{
+var 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))
+func (x Origin) String() string {
+ return proto.EnumName(Origin_name, int32(x))
+}
+
+type EVPN_TYPE int32
+
+const (
+ EVPN_TYPE__ EVPN_TYPE = 0
+ EVPN_TYPE_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY EVPN_TYPE = 1
+ EVPN_TYPE_ROUTE_TYPE_MAC_IP_ADVERTISEMENT EVPN_TYPE = 2
+ EVPN_TYPE_INCLUSIVE_MULTICAST_ETHERNET_TAG EVPN_TYPE = 3
+ EVPN_TYPE_ETHERNET_SEGMENT_ROUTE EVPN_TYPE = 4
+)
+
+var EVPN_TYPE_name = map[int32]string{
+ 0: "_",
+ 1: "ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY",
+ 2: "ROUTE_TYPE_MAC_IP_ADVERTISEMENT",
+ 3: "INCLUSIVE_MULTICAST_ETHERNET_TAG",
+ 4: "ETHERNET_SEGMENT_ROUTE",
+}
+var EVPN_TYPE_value = map[string]int32{
+ "_": 0,
+ "ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY": 1,
+ "ROUTE_TYPE_MAC_IP_ADVERTISEMENT": 2,
+ "INCLUSIVE_MULTICAST_ETHERNET_TAG": 3,
+ "ETHERNET_SEGMENT_ROUTE": 4,
+}
+
+func (x EVPN_TYPE) String() string {
+ return proto.EnumName(EVPN_TYPE_name, int32(x))
+}
+
+type BGP_ATTR_TYPE int32
+
+const (
+ BGP_ATTR_TYPE_UNKNOWN_ATTR BGP_ATTR_TYPE = 0
+ BGP_ATTR_TYPE_ORIGIN BGP_ATTR_TYPE = 1
+ BGP_ATTR_TYPE_AS_PATH BGP_ATTR_TYPE = 2
+ BGP_ATTR_TYPE_NEXT_HOP BGP_ATTR_TYPE = 3
+ BGP_ATTR_TYPE_MULTI_EXIT_DISC BGP_ATTR_TYPE = 4
+ BGP_ATTR_TYPE_LOCAL_PREF BGP_ATTR_TYPE = 5
+ BGP_ATTR_TYPE_ATOMIC_AGGREGATE BGP_ATTR_TYPE = 6
+ BGP_ATTR_TYPE_AGGREGATOR BGP_ATTR_TYPE = 7
+ BGP_ATTR_TYPE_COMMUNITIES BGP_ATTR_TYPE = 8
+ BGP_ATTR_TYPE_ORIGINATOR_ID BGP_ATTR_TYPE = 9
+ BGP_ATTR_TYPE_CLUSTER_LIST BGP_ATTR_TYPE = 10
+ BGP_ATTR_TYPE_MP_REACH_NLRI BGP_ATTR_TYPE = 14
+ BGP_ATTR_TYPE_MP_UNREACH_NLRI BGP_ATTR_TYPE = 15
+ BGP_ATTR_TYPE_EXTENDED_COMMUNITIES BGP_ATTR_TYPE = 16
+ BGP_ATTR_TYPE_AS4_PATH BGP_ATTR_TYPE = 17
+ BGP_ATTR_TYPE_AS4_AGGREGATOR BGP_ATTR_TYPE = 18
+)
+
+var BGP_ATTR_TYPE_name = map[int32]string{
+ 0: "UNKNOWN_ATTR",
+ 1: "ORIGIN",
+ 2: "AS_PATH",
+ 3: "NEXT_HOP",
+ 4: "MULTI_EXIT_DISC",
+ 5: "LOCAL_PREF",
+ 6: "ATOMIC_AGGREGATE",
+ 7: "AGGREGATOR",
+ 8: "COMMUNITIES",
+ 9: "ORIGINATOR_ID",
+ 10: "CLUSTER_LIST",
+ 14: "MP_REACH_NLRI",
+ 15: "MP_UNREACH_NLRI",
+ 16: "EXTENDED_COMMUNITIES",
+ 17: "AS4_PATH",
+ 18: "AS4_AGGREGATOR",
+}
+var BGP_ATTR_TYPE_value = map[string]int32{
+ "UNKNOWN_ATTR": 0,
+ "ORIGIN": 1,
+ "AS_PATH": 2,
+ "NEXT_HOP": 3,
+ "MULTI_EXIT_DISC": 4,
+ "LOCAL_PREF": 5,
+ "ATOMIC_AGGREGATE": 6,
+ "AGGREGATOR": 7,
+ "COMMUNITIES": 8,
+ "ORIGINATOR_ID": 9,
+ "CLUSTER_LIST": 10,
+ "MP_REACH_NLRI": 14,
+ "MP_UNREACH_NLRI": 15,
+ "EXTENDED_COMMUNITIES": 16,
+ "AS4_PATH": 17,
+ "AS4_AGGREGATOR": 18,
+}
+
+func (x BGP_ATTR_TYPE) String() string {
+ return proto.EnumName(BGP_ATTR_TYPE_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 Error struct {
@@ -136,61 +277,166 @@ 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"`
+ Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"`
+ Af *AddressFamily `protobuf:"bytes,2,opt,name=af" json:"af,omitempty"`
+ RouterId string `protobuf:"bytes,3,opt,name=router_id" json:"router_id,omitempty"`
}
func (m *Arguments) Reset() { *m = Arguments{} }
func (m *Arguments) String() string { return proto.CompactTextString(m) }
func (*Arguments) ProtoMessage() {}
+func (m *Arguments) GetAf() *AddressFamily {
+ if m != nil {
+ return m.Af
+ }
+ return nil
+}
+
+type ModPathArguments struct {
+ Resource Resource `protobuf:"varint,1,opt,name=resource,enum=api.Resource" json:"resource,omitempty"`
+ Path *Path `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"`
+}
+
+func (m *ModPathArguments) Reset() { *m = ModPathArguments{} }
+func (m *ModPathArguments) String() string { return proto.CompactTextString(m) }
+func (*ModPathArguments) ProtoMessage() {}
+
+func (m *ModPathArguments) GetPath() *Path {
+ if m != nil {
+ return m.Path
+ }
+ 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"`
+}
+
+func (m *AddressFamily) Reset() { *m = AddressFamily{} }
+func (m *AddressFamily) String() string { return proto.CompactTextString(m) }
+func (*AddressFamily) ProtoMessage() {}
+
+type 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 *Aggregator) Reset() { *m = Aggregator{} }
+func (m *Aggregator) String() string { return proto.CompactTextString(m) }
+func (*Aggregator) ProtoMessage() {}
+
+type EVPNNlri struct {
+ Type EVPN_TYPE `protobuf:"varint,1,opt,name=type,enum=api.EVPN_TYPE" json:"type,omitempty"`
+ // EvpnAutoDiscoveryRoute = 2;
+ MacIpAdv *EvpnMacIpAdvertisement `protobuf:"bytes,3,opt,name=mac_ip_adv" json:"mac_ip_adv,omitempty"`
+}
+
+func (m *EVPNNlri) Reset() { *m = EVPNNlri{} }
+func (m *EVPNNlri) String() string { return proto.CompactTextString(m) }
+func (*EVPNNlri) ProtoMessage() {}
+
+func (m *EVPNNlri) GetMacIpAdv() *EvpnMacIpAdvertisement {
+ if m != nil {
+ return m.MacIpAdv
+ }
+ return nil
+}
+
+type EvpnMacIpAdvertisement struct {
+ MacAddr string `protobuf:"bytes,1,opt,name=mac_addr" json:"mac_addr,omitempty"`
+ MacAddrLen uint32 `protobuf:"varint,2,opt,name=mac_addr_len" json:"mac_addr_len,omitempty"`
+ IpAddr string `protobuf:"bytes,3,opt,name=ip_addr" json:"ip_addr,omitempty"`
+ IpAddrLen uint32 `protobuf:"varint,4,opt,name=ip_addr_len" json:"ip_addr_len,omitempty"`
+ Rd string `protobuf:"bytes,5,opt,name=rd" json:"rd,omitempty"`
+ Esi string `protobuf:"bytes,6,opt,name=esi" json:"esi,omitempty"`
+ Etag uint32 `protobuf:"varint,7,opt,name=etag" json:"etag,omitempty"`
+ Labels []uint32 `protobuf:"varint,8,rep,name=labels" json:"labels,omitempty"`
+}
+
+func (m *EvpnMacIpAdvertisement) Reset() { *m = EvpnMacIpAdvertisement{} }
+func (m *EvpnMacIpAdvertisement) String() string { return proto.CompactTextString(m) }
+func (*EvpnMacIpAdvertisement) ProtoMessage() {}
+
+type Nlri struct {
+ Af *AddressFamily `protobuf:"bytes,1,opt,name=af" json:"af,omitempty"`
+ Prefix string `protobuf:"bytes,2,opt,name=prefix" json:"prefix,omitempty"`
+ EvpnNlri *EVPNNlri `protobuf:"bytes,3,opt,name=evpn_nlri" json:"evpn_nlri,omitempty"`
+ Nexthop string `protobuf:"bytes,4,opt,name=nexthop" json:"nexthop,omitempty"`
+}
+
+func (m *Nlri) Reset() { *m = Nlri{} }
+func (m *Nlri) String() string { return proto.CompactTextString(m) }
+func (*Nlri) ProtoMessage() {}
+
+func (m *Nlri) GetAf() *AddressFamily {
+ if m != nil {
+ return m.Af
+ }
+ return nil
+}
+
+func (m *Nlri) GetEvpnNlri() *EVPNNlri {
+ if m != nil {
+ return m.EvpnNlri
+ }
+ return nil
+}
+
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"`
+ Type BGP_ATTR_TYPE `protobuf:"varint,1,opt,name=type,enum=api.BGP_ATTR_TYPE" json:"type,omitempty"`
+ Value []string `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"`
+ Origin Origin `protobuf:"varint,3,opt,name=origin,enum=api.Origin" json:"origin,omitempty"`
+ AsPath []uint32 `protobuf:"varint,4,rep,name=as_path" json:"as_path,omitempty"`
+ Nexthop string `protobuf:"bytes,5,opt,name=nexthop" json:"nexthop,omitempty"`
+ Metric uint32 `protobuf:"varint,6,opt,name=metric" json:"metric,omitempty"`
+ Pref uint32 `protobuf:"varint,7,opt,name=pref" json:"pref,omitempty"`
+ Aggregator *Aggregator `protobuf:"bytes,8,opt,name=aggregator" json:"aggregator,omitempty"`
+ Communites []uint32 `protobuf:"varint,9,rep,name=communites" json:"communites,omitempty"`
+ Originator string `protobuf:"bytes,10,opt,name=originator" json:"originator,omitempty"`
+ Cluster []string `protobuf:"bytes,11,rep,name=cluster" json:"cluster,omitempty"`
+ Nlri *Nlri `protobuf:"bytes,12,opt,name=nlri" json:"nlri,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 {
+func (m *PathAttr) GetAggregator() *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) GetNlri() *Nlri {
+ if m != nil {
+ return m.Nlri
+ }
+ return nil
}
-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"`
+ Nlri *Nlri `protobuf:"bytes,1,opt,name=nlri" json:"nlri,omitempty"`
+ Attrs []*PathAttr `protobuf:"bytes,2,rep,name=attrs" json:"attrs,omitempty"`
+ Nexthop string `protobuf:"bytes,3,opt,name=nexthop" json:"nexthop,omitempty"`
+ Age int64 `protobuf:"varint,4,opt,name=age" json:"age,omitempty"`
+ Best bool `protobuf:"varint,5,opt,name=best" json:"best,omitempty"`
+ IsWithdraw bool `protobuf:"varint,6,opt,name=is_withdraw" json:"is_withdraw,omitempty"`
}
func (m *Path) Reset() { *m = Path{} }
func (m *Path) String() string { return proto.CompactTextString(m) }
func (*Path) ProtoMessage() {}
+func (m *Path) GetNlri() *Nlri {
+ if m != nil {
+ return m.Nlri
+ }
+ return nil
+}
+
func (m *Path) GetAttrs() []*PathAttr {
if m != nil {
return m.Attrs
@@ -201,7 +447,7 @@ func (m *Path) GetAttrs() []*PathAttr {
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"`
+ BestPathIdx uint32 `protobuf:"varint,3,opt,name=best_path_idx" json:"best_path_idx,omitempty"`
}
func (m *Destination) Reset() { *m = Destination{} }
@@ -286,9 +532,12 @@ func (m *Peer) GetInfo() *PeerInfo {
func init() {
proto.RegisterEnum("api.Resource", Resource_name, Resource_value)
- proto.RegisterEnum("api.AddressFamily", AddressFamily_name, AddressFamily_value)
+ proto.RegisterEnum("api.AFI", AFI_name, AFI_value)
+ proto.RegisterEnum("api.SAFI", SAFI_name, SAFI_value)
+ proto.RegisterEnum("api.Origin", Origin_name, Origin_value)
+ proto.RegisterEnum("api.EVPN_TYPE", EVPN_TYPE_name, EVPN_TYPE_value)
+ proto.RegisterEnum("api.BGP_ATTR_TYPE", BGP_ATTR_TYPE_name, BGP_ATTR_TYPE_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
@@ -305,8 +554,7 @@ type GrpcClient interface {
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)
+ ModPath(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPathClient, error)
}
type grpcClient struct {
@@ -485,67 +733,30 @@ func (c *grpcClient) Disable(ctx context.Context, in *Arguments, opts ...grpc.Ca
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...)
+func (c *grpcClient) ModPath(ctx context.Context, opts ...grpc.CallOption) (Grpc_ModPathClient, error) {
+ stream, err := grpc.NewClientStream(ctx, &_Grpc_serviceDesc.Streams[3], c.cc, "/api.Grpc/ModPath", opts...)
if err != nil {
return nil, err
}
- x := &grpcDeletePathClient{stream}
+ x := &grpcModPathClient{stream}
return x, nil
}
-type Grpc_DeletePathClient interface {
- Send(*Arguments) error
- CloseAndRecv() (*Error, error)
+type Grpc_ModPathClient interface {
+ Send(*ModPathArguments) error
+ Recv() (*Error, error)
grpc.ClientStream
}
-type grpcDeletePathClient struct {
+type grpcModPathClient struct {
grpc.ClientStream
}
-func (x *grpcDeletePathClient) Send(m *Arguments) error {
+func (x *grpcModPathClient) Send(m *ModPathArguments) error {
return x.ClientStream.SendMsg(m)
}
-func (x *grpcDeletePathClient) CloseAndRecv() (*Error, error) {
- if err := x.ClientStream.CloseSend(); err != nil {
- return nil, err
- }
+func (x *grpcModPathClient) Recv() (*Error, error) {
m := new(Error)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
@@ -567,8 +778,7 @@ type GrpcServer interface {
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
+ ModPath(Grpc_ModPathServer) error
}
func RegisterGrpcServer(s *grpc.Server, srv GrpcServer) {
@@ -734,52 +944,26 @@ func _Grpc_Disable_Handler(srv interface{}, ctx context.Context, buf []byte) (in
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 _Grpc_ModPath_Handler(srv interface{}, stream grpc.ServerStream) error {
+ return srv.(GrpcServer).ModPath(&grpcModPathServer{stream})
}
-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)
+type Grpc_ModPathServer interface {
+ Send(*Error) error
+ Recv() (*ModPathArguments, error)
grpc.ServerStream
}
-type grpcDeletePathServer struct {
+type grpcModPathServer struct {
grpc.ServerStream
}
-func (x *grpcDeletePathServer) SendAndClose(m *Error) error {
+func (x *grpcModPathServer) Send(m *Error) error {
return x.ServerStream.SendMsg(m)
}
-func (x *grpcDeletePathServer) Recv() (*Arguments, error) {
- m := new(Arguments)
+func (x *grpcModPathServer) Recv() (*ModPathArguments, error) {
+ m := new(ModPathArguments)
if err := x.ServerStream.RecvMsg(m); err != nil {
return nil, err
}
@@ -840,13 +1024,9 @@ var _Grpc_serviceDesc = grpc.ServiceDesc{
ServerStreams: true,
},
{
- StreamName: "AddPath",
- Handler: _Grpc_AddPath_Handler,
- ClientStreams: true,
- },
- {
- StreamName: "DeletePath",
- Handler: _Grpc_DeletePath_Handler,
+ StreamName: "ModPath",
+ Handler: _Grpc_ModPath_Handler,
+ ServerStreams: true,
ClientStreams: true,
},
},
diff --git a/api/gobgp.proto b/api/gobgp.proto
index 41832653..7c796463 100644
--- a/api/gobgp.proto
+++ b/api/gobgp.proto
@@ -31,8 +31,7 @@ service Grpc {
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) {}
+ rpc ModPath(stream ModPathArguments) returns (stream Error) {}
}
message Error {
@@ -48,7 +47,11 @@ message Arguments {
Resource resource = 1;
AddressFamily af = 2;
string router_id = 3;
- string prefix = 4;
+}
+
+message ModPathArguments {
+ Resource resource = 1;
+ Path path = 2;
}
enum Resource {
@@ -58,41 +61,116 @@ enum Resource {
ADJ_OUT = 3;
}
-enum AddressFamily {
- IPV4 = 0;
- IPV6 = 1;
- EVPN = 2;
+enum AFI {
+ UNKNOWN_AFI = 0;
+ IP = 1;
+ IP6 = 2;
+ L2VPN = 25;
}
-message PathAttr {
+enum SAFI {
+ UNKNOWN_SAFI = 0;
+ UNICAST = 1;
+ MULTICAST = 2;
+ MPLS_LABEL = 4;
+ VPLS = 65;
+ EVPN = 70;
+ MPLS_VPN = 128;
+ MPLS_VPN_MULTICAST = 129;
+ ROUTE_TARGET_CONSTRTAINS = 132;
+}
- 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 AddressFamily {
+ AFI Afi = 1;
+ SAFI Safi = 2;
+}
+
+enum Origin {
+ IGP = 0;
+ EGP = 1;
+ INCOMPLETE = 2;
+}
+
+message Aggregator {
+ uint32 as = 1;
+ string address = 2;
+}
+
+enum EVPN_TYPE {
+ UNKNOWN_EVPN_TYPE = 0;
+ ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY = 1;
+ ROUTE_TYPE_MAC_IP_ADVERTISEMENT = 2;
+ INCLUSIVE_MULTICAST_ETHERNET_TAG = 3;
+ ETHERNET_SEGMENT_ROUTE = 4;
+}
+
+message EVPNNlri {
+ EVPN_TYPE type = 1;
+// EvpnAutoDiscoveryRoute = 2;
+ EvpnMacIpAdvertisement mac_ip_adv = 3;
+// EvpnInclusiveMulticastEthernetTag = 4;
+// EvpnEthernetSegmentRoute = 5;
+}
+
+message EvpnMacIpAdvertisement {
+ string mac_addr = 1;
+ uint32 mac_addr_len = 2;
+ string ip_addr = 3;
+ uint32 ip_addr_len = 4;
+ string rd = 5;
+ string esi = 6;
+ uint32 etag = 7;
+ repeated uint32 labels = 8;
+}
+
+message Nlri {
+ AddressFamily af = 1;
+ string prefix = 2;
+ EVPNNlri evpn_nlri = 3;
+ string nexthop = 4;
+}
+
+enum BGP_ATTR_TYPE {
+ UNKNOWN_ATTR = 0;
+ ORIGIN = 1;
+ AS_PATH = 2;
+ NEXT_HOP = 3;
+ MULTI_EXIT_DISC = 4;
+ LOCAL_PREF = 5;
+ ATOMIC_AGGREGATE = 6;
+ AGGREGATOR = 7;
+ COMMUNITIES = 8;
+ ORIGINATOR_ID = 9;
+ CLUSTER_LIST = 10;
+ MP_REACH_NLRI = 14;
+ MP_UNREACH_NLRI = 15;
+ EXTENDED_COMMUNITIES = 16;
+ AS4_PATH = 17;
+ AS4_AGGREGATOR = 18;
+}
+
+message PathAttr {
+ BGP_ATTR_TYPE type = 1;
+ repeated string value = 2;
+ Origin origin = 3;
+ repeated uint32 as_path = 4;
+ string nexthop = 5;
+ uint32 metric = 6;
+ uint32 pref = 7;
+ Aggregator aggregator = 8;
+ repeated uint32 communites = 9;
+ string originator = 10;
+ repeated string cluster = 11;
+ Nlri nlri = 12;
}
message Path {
- string network = 1;
+ Nlri nlri = 1;
string nexthop = 2;
int64 age = 3;
repeated PathAttr attrs = 4;
bool best = 5;
+ bool is_withdraw = 6;
}
message Destination {
diff --git a/api/util.go b/api/util.go
new file mode 100644
index 00000000..aa27e3d3
--- /dev/null
+++ b/api/util.go
@@ -0,0 +1,24 @@
+// 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.
+
+package api
+
+var AF_IPV4_UC *AddressFamily = &AddressFamily{AFI_IP, SAFI_UNICAST}
+var AF_IPV6_UC *AddressFamily = &AddressFamily{AFI_IP6, SAFI_UNICAST}
+var AF_EVPN *AddressFamily = &AddressFamily{AFI_L2VPN, SAFI_EVPN}
+
+func (lhs *AddressFamily) Equal(rhs *AddressFamily) bool {
+ return lhs.Afi == rhs.Afi && lhs.Safi == rhs.Safi
+}
diff --git a/gobgp/main.go b/gobgp/main.go
index 3f6f4e81..a433d181 100644
--- a/gobgp/main.go
+++ b/gobgp/main.go
@@ -181,7 +181,7 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool) {
s := bytes.NewBuffer(make([]byte, 0, 64))
s.WriteString("[")
for _, a := range attrs {
- if a.Type == "BGP_ATTR_TYPE_AS_PATH" {
+ if a.Type == api.BGP_ATTR_TYPE_AS_PATH {
var ss []string
for _, as := range a.AsPath {
ss = append(ss, fmt.Sprintf("%d", as))
@@ -196,17 +196,17 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool) {
s := []string{}
for _, a := range attrs {
switch a.Type {
- case "BGP_ATTR_TYPE_ORIGIN":
+ case api.BGP_ATTR_TYPE_ORIGIN:
s = append(s, fmt.Sprintf("{Origin: %s}", a.Origin))
- case "BGP_ATTR_TYPE_MULTI_EXIT_DISC":
+ case api.BGP_ATTR_TYPE_MULTI_EXIT_DISC:
s = append(s, fmt.Sprintf("{Med: %d}", a.Metric))
- case "BGP_ATTR_TYPE_LOCAL_PREF":
+ case api.BGP_ATTR_TYPE_LOCAL_PREF:
s = append(s, fmt.Sprintf("{LocalPref: %v}", a.Pref))
- case "BGP_ATTR_TYPE_ATOMIC_AGGREGATE":
+ case api.BGP_ATTR_TYPE_ATOMIC_AGGREGATE:
s = append(s, "AtomicAggregate")
- case "BGP_ATTR_TYPE_AGGREGATOR":
+ case api.BGP_ATTR_TYPE_AGGREGATOR:
s = append(s, fmt.Sprintf("{Aggregate: {AS: %d, Address: %s}", a.GetAggregator().As, a.GetAggregator().Address))
- case "BGP_ATTR_TYPE_COMMUNITIES":
+ case api.BGP_ATTR_TYPE_COMMUNITIES:
l := []string{}
known := map[uint32]string{
0xffff0000: "planned-shut",
@@ -231,11 +231,11 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool) {
}
}
s = append(s, fmt.Sprintf("{Cummunity: %v}", l))
- case "BGP_ATTR_TYPE_ORIGINATOR_ID":
+ case api.BGP_ATTR_TYPE_ORIGINATOR_ID:
s = append(s, fmt.Sprintf("{Originator: %v|", a.Originator))
- case "BGP_ATTR_TYPE_CLUSTER_LIST":
+ case api.BGP_ATTR_TYPE_CLUSTER_LIST:
s = append(s, fmt.Sprintf("{Cluster: %v|", a.Cluster))
- case "BGP_ATTR_TYPE_AS4_PATH", "BGP_ATTR_TYPE_MP_UNREACH_NLRI", "BGP_ATTR_TYPE_MP_REACH_NLRI", "BGP_ATTR_TYPE_NEXT_HOP", "BGP_ATTR_TYPE_AS_PATH":
+ case api.BGP_ATTR_TYPE_AS4_PATH, api.BGP_ATTR_TYPE_MP_REACH_NLRI, api.BGP_ATTR_TYPE_MP_UNREACH_NLRI, api.BGP_ATTR_TYPE_NEXT_HOP, api.BGP_ATTR_TYPE_AS_PATH:
default:
s = append(s, fmt.Sprintf("{%v: %v}", a.Type, a.Value))
}
@@ -251,29 +251,29 @@ func showRoute(pathList []*api.Path, showAge bool, showBest bool) {
}
}
if showAge {
- fmt.Printf(format, best, p.Network, p.Nexthop, aspath(p.Attrs), formatTimedelta(p.Age), formatAttrs(p.Attrs))
+ fmt.Printf(format, best, p.Nlri.Prefix, p.Nexthop, aspath(p.Attrs), formatTimedelta(p.Age), formatAttrs(p.Attrs))
} else {
- fmt.Printf(format, best, p.Network, p.Nexthop, aspath(p.Attrs), formatAttrs(p.Attrs))
+ fmt.Printf(format, best, p.Nlri.Prefix, p.Nexthop, aspath(p.Attrs), formatAttrs(p.Attrs))
}
}
}
func (x *ShowNeighborRibCommand) Execute(args []string) error {
- var rt api.AddressFamily
+ var rt *api.AddressFamily
if len(args) == 0 {
if x.remoteIP.To4() != nil {
- rt = api.AddressFamily_IPV4
+ rt = api.AF_IPV4_UC
} else {
- rt = api.AddressFamily_IPV6
+ rt = api.AF_IPV6_UC
}
} else {
switch args[0] {
case "ipv4":
- rt = api.AddressFamily_IPV4
+ rt = api.AF_IPV4_UC
case "ipv6":
- rt = api.AddressFamily_IPV6
+ rt = api.AF_IPV6_UC
case "evpn":
- rt = api.AddressFamily_EVPN
+ rt = api.AF_EVPN
}
}
@@ -441,6 +441,10 @@ func (x *ShowNeighborsCommand) Execute(args []string) error {
fmt.Printf(format, p.Conf.RemoteIp, fmt.Sprint(p.Conf.RemoteAs), timedelta[i], format_fsm(p.Info.AdminState, p.Info.BgpState), fmt.Sprint(p.Info.Advertized), fmt.Sprint(p.Info.Received), fmt.Sprint(p.Info.Accepted))
}
+ for i, p := range m {
+ fmt.Printf(format, p.Conf.RemoteIp, fmt.Sprint(p.Conf.RemoteAs), timedelta[i], format_fsm(p.Info.AdminState, p.Info.BgpState), fmt.Sprint(p.Info.Advertized), fmt.Sprint(p.Info.Received), fmt.Sprint(p.Info.Accepted))
+ }
+
return nil
}
@@ -448,17 +452,17 @@ type ShowGlobalCommand struct {
}
func (x *ShowGlobalCommand) Execute(args []string) error {
- var rt api.AddressFamily
+ var rt *api.AddressFamily
if len(args) == 0 {
- rt = api.AddressFamily_IPV4
+ rt = api.AF_IPV4_UC
} else {
switch args[0] {
case "ipv4":
- rt = api.AddressFamily_IPV4
+ rt = api.AF_IPV4_UC
case "ipv6":
- rt = api.AddressFamily_IPV6
+ rt = api.AF_IPV6_UC
case "evpn":
- rt = api.AddressFamily_EVPN
+ rt = api.AF_EVPN
}
}
@@ -524,19 +528,19 @@ func (x *ResetCommand) Execute(args []string) error {
return fmt.Errorf("usage: %s neighbor <router_id> [ipv4|ipv6]", x.resource)
}
- var rt api.AddressFamily
+ var rt *api.AddressFamily
switch x.resource {
case "softreset", "softresetin", "softresetout":
if len(args) == 2 {
- rt = api.AddressFamily_IPV4
+ rt = api.AF_IPV4_UC
} else {
switch args[2] {
case "ipv4":
- rt = api.AddressFamily_IPV4
+ rt = api.AF_IPV4_UC
case "ipv6":
- rt = api.AddressFamily_IPV6
+ rt = api.AF_IPV6_UC
case "evpn":
- rt = api.AddressFamily_EVPN
+ rt = api.AF_EVPN
default:
return fmt.Errorf("unsupported rf: %s", args[2])
}
@@ -548,8 +552,6 @@ func (x *ResetCommand) Execute(args []string) error {
Af: rt,
}
- fmt.Println(arg)
-
switch x.resource {
case "reset":
client.Reset(context.Background(), arg)
@@ -582,53 +584,66 @@ type PathCommand struct {
}
func (x *PathCommand) Execute(args []string) error {
- if len(args) != 3 {
+ if len(args) < 3 {
return fmt.Errorf("usage: %s global <af> <prefix>", x.modtype)
}
- var rt api.AddressFamily
+
+ if args[0] != "global" {
+ return fmt.Errorf("unsupported resource (currently only 'global' is supported): %s", args[0])
+ }
+
+ var rt *api.AddressFamily
switch args[1] {
- case "ipv4":
- rt = api.AddressFamily_IPV4
- case "ipv6":
- rt = api.AddressFamily_IPV6
- case "evpn":
- rt = api.AddressFamily_EVPN
+ case "ipv4", "v4", "4":
+ rt = api.AF_IPV4_UC
+ case "ipv6", "v6", "6":
+ rt = api.AF_IPV6_UC
+ default:
+ return fmt.Errorf("unsupported address family: %s", args[1])
}
- arg := &api.Arguments{
- Resource: api.Resource_GLOBAL,
- Af: rt,
- Prefix: args[2],
+ path := &api.Path{}
+
+ switch rt {
+ case api.AF_IPV4_UC, api.AF_IPV6_UC:
+ path.Nlri = &api.Nlri{
+ Af: rt,
+ Prefix: args[2],
+ }
}
switch x.modtype {
case "add":
- stream, err := client.AddPath(context.Background())
- if err != nil {
- return err
- }
- err = stream.Send(arg)
- if err != nil {
- return err
- }
- _, err = stream.CloseAndRecv()
- if err != nil {
- return err
- }
+ path.IsWithdraw = false
case "delete":
- stream, err := client.DeletePath(context.Background())
- if err != nil {
- return err
- }
- err = stream.Send(arg)
- if err != nil {
- return err
- }
- _, err = stream.CloseAndRecv()
- if err != nil {
- return err
- }
+ path.IsWithdraw = true
+ }
+
+ arg := &api.ModPathArguments{
+ Resource: api.Resource_GLOBAL,
+ Path: path,
+ }
+
+ stream, err := client.ModPath(context.Background())
+ if err != nil {
+ return err
+ }
+
+ err = stream.Send(arg)
+ if err != nil {
+ return err
}
+
+ stream.CloseSend()
+
+ res, e := stream.Recv()
+ if e != nil {
+ return e
+ }
+ if res.Code != api.Error_SUCCESS {
+ return fmt.Errorf("error: code: %d, msg: %s", res.Code, res.Msg)
+ }
+
return nil
}
diff --git a/gobgpd/main.go b/gobgpd/main.go
index e8922226..d2aee38a 100644
--- a/gobgpd/main.go
+++ b/gobgpd/main.go
@@ -19,7 +19,6 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/Sirupsen/logrus/hooks/syslog"
"github.com/jessevdk/go-flags"
- "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet"
"github.com/osrg/gobgp/server"
@@ -144,7 +143,7 @@ func main() {
go bgpServer.Serve()
// start grpc Server
- grpcServer := api.NewGrpcServer(api.GRPC_PORT, bgpServer.GrpcReqCh)
+ grpcServer := server.NewGrpcServer(server.GRPC_PORT, bgpServer.GrpcReqCh)
go grpcServer.Serve()
var bgpConfig *config.Bgp = nil
diff --git a/packet/bgp.go b/packet/bgp.go
index 84169bcc..8e468ec4 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -21,9 +21,11 @@ import (
"encoding/json"
"errors"
"fmt"
+ "github.com/osrg/gobgp/api"
"math"
"net"
"reflect"
+ "strings"
)
const (
@@ -452,6 +454,7 @@ type AddrPrefixInterface interface {
SAFI() uint8
Len() int
String() string
+ ToApiStruct() *api.Nlri
}
type IPAddrPrefixDefault struct {
@@ -530,6 +533,13 @@ func (r *IPAddrPrefix) SAFI() uint8 {
return SAFI_UNICAST
}
+func (r *IPAddrPrefix) ToApiStruct() *api.Nlri {
+ return &api.Nlri{
+ Af: &api.AddressFamily{api.AFI(r.AFI()), api.SAFI(r.SAFI())},
+ Prefix: r.String(),
+ }
+}
+
type IPv6AddrPrefix struct {
IPAddrPrefix
}
@@ -815,6 +825,13 @@ func (l *LabelledVPNIPAddrPrefix) SAFI() uint8 {
return SAFI_MPLS_VPN
}
+func (l *LabelledVPNIPAddrPrefix) ToApiStruct() *api.Nlri {
+ return &api.Nlri{
+ Af: &api.AddressFamily{api.AFI(l.AFI()), api.SAFI(l.SAFI())},
+ Prefix: l.String(),
+ }
+}
+
func NewLabelledVPNIPAddrPrefix(length uint8, prefix string, label Label, rd RouteDistinguisherInterface) *LabelledVPNIPAddrPrefix {
rdlen := 0
if rd != nil {
@@ -865,6 +882,13 @@ func (r *LabelledIPAddrPrefix) SAFI() uint8 {
return SAFI_MPLS_LABEL
}
+func (r *LabelledIPAddrPrefix) ToApiStruct() *api.Nlri {
+ return &api.Nlri{
+ Af: &api.AddressFamily{api.AFI(r.AFI()), api.SAFI(r.SAFI())},
+ Prefix: r.String(),
+ }
+}
+
func (r *IPAddrPrefix) decodeNextHop(data []byte) net.IP {
if r.addrlen == 0 {
r.addrlen = 4
@@ -971,6 +995,13 @@ func (n *RouteTargetMembershipNLRI) String() string {
return fmt.Sprintf("%d:%s/%d", n.AS, n.RouteTarget.String(), n.Len()*8)
}
+func (n *RouteTargetMembershipNLRI) ToApiStruct() *api.Nlri {
+ return &api.Nlri{
+ Af: &api.AddressFamily{api.AFI(n.AFI()), api.SAFI(n.SAFI())},
+ Prefix: n.String(),
+ }
+}
+
type ESIType uint8
const (
@@ -1327,10 +1358,13 @@ func (n *EVPNNLRI) String() string {
case EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT:
m := n.RouteTypeData.(*EVPNMacIPAdvertisementRoute)
+ var ss []string
switch m.RD.(type) {
case *RouteDistinguisherIPAddressAS:
- return fmt.Sprintf("%s", m.IPAddress.String())
+ ss = append(ss, fmt.Sprintf("%s", m.IPAddress.String()))
}
+ ss = append(ss, m.MacAddress.String())
+ return strings.Join(ss, ".")
case EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG:
m := n.RouteTypeData.(*EVPNMulticastEthernetTagRoute)
@@ -1346,6 +1380,13 @@ func (n *EVPNNLRI) String() string {
return fmt.Sprintf("%d:%d", n.RouteType, n.Length)
}
+func (n *EVPNNLRI) ToApiStruct() *api.Nlri {
+ return &api.Nlri{
+ Af: &api.AddressFamily{api.AFI(n.AFI()), api.SAFI(n.SAFI())},
+ Prefix: n.String(),
+ }
+}
+
func NewEVPNNLRI(routetype uint8, length uint8, routetypedata EVPNRouteTypeInterface) *EVPNNLRI {
return &EVPNNLRI{
routetype,
@@ -1559,6 +1600,7 @@ type PathAttributeInterface interface {
Len() int
getFlags() uint8
getType() BGPAttrType
+ ToApiStruct() *api.PathAttr
}
type PathAttribute struct {
@@ -1645,14 +1687,15 @@ type PathAttributeOrigin struct {
PathAttribute
}
+func (p *PathAttributeOrigin) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_ORIGIN,
+ Origin: api.Origin(uint8(p.Value[0])),
+ }
+}
+
func (p *PathAttributeOrigin) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- Value uint8
- }{
- Type: p.Type.String(),
- Value: uint8(p.Value[0]),
- })
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeOrigin(value uint8) *PathAttributeOrigin {
@@ -1879,7 +1922,7 @@ func (p *PathAttributeAsPath) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeAsPath) MarshalJSON() ([]byte, error) {
+func (p *PathAttributeAsPath) ToApiStruct() *api.PathAttr {
aslist := make([]uint32, 0)
for _, a := range p.Value {
path, y := a.(*As4PathParam)
@@ -1892,13 +1935,14 @@ func (p *PathAttributeAsPath) MarshalJSON() ([]byte, error) {
}
}
}
- return json.Marshal(struct {
- Type string
- AsPath []uint32 `json:"as_path,omitempty"`
- }{
- Type: p.Type.String(),
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_AS_PATH,
AsPath: aslist,
- })
+ }
+}
+
+func (p *PathAttributeAsPath) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeAsPath(value []AsPathParamInterface) *PathAttributeAsPath {
@@ -1936,14 +1980,15 @@ func (p *PathAttributeNextHop) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeNextHop) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- Nexthop string
- }{
- Type: p.Type.String(),
+func (p *PathAttributeNextHop) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_NEXT_HOP,
Nexthop: p.Value.String(),
- })
+ }
+}
+
+func (p *PathAttributeNextHop) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeNextHop(value string) *PathAttributeNextHop {
@@ -1983,14 +2028,15 @@ func (p *PathAttributeMultiExitDisc) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeMultiExitDisc) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- Metric uint32
- }{
- Type: p.Type.String(),
+func (p *PathAttributeMultiExitDisc) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_MULTI_EXIT_DISC,
Metric: p.Value,
- })
+ }
+}
+
+func (p *PathAttributeMultiExitDisc) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeMultiExitDisc(value uint32) *PathAttributeMultiExitDisc {
@@ -2030,14 +2076,15 @@ func (p *PathAttributeLocalPref) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeLocalPref) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- Pref uint32
- }{
- Type: p.Type.String(),
+func (p *PathAttributeLocalPref) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_LOCAL_PREF,
Pref: p.Value,
- })
+ }
+}
+
+func (p *PathAttributeLocalPref) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeLocalPref(value uint32) *PathAttributeLocalPref {
@@ -2055,12 +2102,14 @@ type PathAttributeAtomicAggregate struct {
PathAttribute
}
+func (p *PathAttributeAtomicAggregate) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_ATOMIC_AGGREGATE,
+ }
+}
+
func (p *PathAttributeAtomicAggregate) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- }{
- Type: p.Type.String(),
- })
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeAtomicAggregate() *PathAttributeAtomicAggregate {
@@ -2123,16 +2172,18 @@ func (p *PathAttributeAggregator) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeAggregator) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_AGGREGATOR,
+ Aggregator: &api.Aggregator{
+ As: p.Value.AS,
+ Address: p.Value.Address.String(),
+ },
+ }
+}
+
func (p *PathAttributeAggregator) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- AS uint32
- Address net.IP
- }{
- Type: p.Type.String(),
- AS: p.Value.AS,
- Address: p.Value.Address,
- })
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeAggregator(as interface{}, address string) *PathAttributeAggregator {
@@ -2183,14 +2234,15 @@ func (p *PathAttributeCommunities) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeCommunities) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_COMMUNITIES,
+ Communites: p.Value,
+ }
+}
+
func (p *PathAttributeCommunities) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- Value []uint32
- }{
- Type: p.Type.String(),
- Value: p.Value,
- })
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeCommunities(value []uint32) *PathAttributeCommunities {
@@ -2231,14 +2283,15 @@ func (p *PathAttributeOriginatorId) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeOriginatorId) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_ORIGINATOR_ID,
+ Originator: p.Value.String(),
+ }
+}
+
func (p *PathAttributeOriginatorId) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Type string
- Address string
- }{
- Type: p.Type.String(),
- Address: p.Value.String(),
- })
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeOriginatorId(value string) *PathAttributeOriginatorId {
@@ -2285,19 +2338,19 @@ func (p *PathAttributeClusterList) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeClusterList) MarshalJSON() ([]byte, error) {
+func (p *PathAttributeClusterList) ToApiStruct() *api.PathAttr {
l := make([]string, 0)
for _, addr := range p.Value {
l = append(l, addr.String())
}
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_CLUSTER_LIST,
+ Cluster: l,
+ }
+}
- return json.Marshal(struct {
- Type string
- Address []string
- }{
- Type: p.Type.String(),
- Address: l,
- })
+func (p *PathAttributeClusterList) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeClusterList(value []string) *PathAttributeClusterList {
@@ -2426,26 +2479,29 @@ func (p *PathAttributeMpReachNLRI) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeMpReachNLRI) MarshalJSON() ([]byte, error) {
- // TODO: fix address printing
- return json.Marshal(struct {
- Type string
- Nexthop string
- Address []string
- }{
- Type: p.Type.String(),
+func (p *PathAttributeMpReachNLRI) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_MP_REACH_NLRI,
Nexthop: p.Nexthop.String(),
- })
+ }
+}
+
+func (p *PathAttributeMpReachNLRI) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeMpReachNLRI(nexthop string, nlri []AddrPrefixInterface) *PathAttributeMpReachNLRI {
t := BGP_ATTR_TYPE_MP_REACH_NLRI
+ ip := net.ParseIP(nexthop)
+ if ip.To4() != nil {
+ ip = ip.To4()
+ }
p := &PathAttributeMpReachNLRI{
PathAttribute: PathAttribute{
Flags: pathAttrFlags[t],
Type: t,
},
- Nexthop: net.ParseIP(nexthop),
+ Nexthop: ip,
Value: nlri,
}
if len(nlri) > 0 {
@@ -2516,6 +2572,16 @@ func (p *PathAttributeMpUnreachNLRI) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeMpUnreachNLRI) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_MP_UNREACH_NLRI,
+ }
+}
+
+func (p *PathAttributeMpUnreachNLRI) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
+}
+
func NewPathAttributeMpUnreachNLRI(nlri []AddrPrefixInterface) *PathAttributeMpUnreachNLRI {
t := BGP_ATTR_TYPE_MP_UNREACH_NLRI
p := &PathAttributeMpUnreachNLRI{
@@ -2705,6 +2771,24 @@ func (p *PathAttributeExtendedCommunities) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeExtendedCommunities) ToApiStruct() *api.PathAttr {
+ value := func(arg []ExtendedCommunityInterface) []string {
+ ret := make([]string, 0, len(arg))
+ for _, v := range p.Value {
+ ret = append(ret, v.String())
+ }
+ return ret
+ }(p.Value)
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_EXTENDED_COMMUNITIES,
+ Value: value,
+ }
+}
+
+func (p *PathAttributeExtendedCommunities) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
+}
+
func NewPathAttributeExtendedCommunities(value []ExtendedCommunityInterface) *PathAttributeExtendedCommunities {
t := BGP_ATTR_TYPE_EXTENDED_COMMUNITIES
return &PathAttributeExtendedCommunities{
@@ -2762,18 +2846,19 @@ func (p *PathAttributeAs4Path) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
-func (p *PathAttributeAs4Path) MarshalJSON() ([]byte, error) {
+func (p *PathAttributeAs4Path) ToApiStruct() *api.PathAttr {
aslist := make([]uint32, 0)
for _, a := range p.Value {
aslist = append(aslist, a.AS...)
}
- return json.Marshal(struct {
- Type string
- AsPath []uint32
- }{
- Type: p.Type.String(),
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_AS4_PATH,
AsPath: aslist,
- })
+ }
+}
+
+func (p *PathAttributeAs4Path) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
}
func NewPathAttributeAs4Path(value []*As4PathParam) *PathAttributeAs4Path {
@@ -2815,6 +2900,20 @@ func (p *PathAttributeAs4Aggregator) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeAs4Aggregator) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_AS4_AGGREGATOR,
+ Aggregator: &api.Aggregator{
+ As: p.Value.AS,
+ Address: p.Value.Address.String(),
+ },
+ }
+}
+
+func (p *PathAttributeAs4Aggregator) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
+}
+
func NewPathAttributeAs4Aggregator(as uint32, address string) *PathAttributeAs4Aggregator {
t := BGP_ATTR_TYPE_AS4_AGGREGATOR
return &PathAttributeAs4Aggregator{
@@ -2833,6 +2932,17 @@ type PathAttributeUnknown struct {
PathAttribute
}
+func (p *PathAttributeUnknown) ToApiStruct() *api.PathAttr {
+ return &api.PathAttr{
+ Type: api.BGP_ATTR_TYPE_UNKNOWN_ATTR,
+ Value: []string{string(p.Value)},
+ }
+}
+
+func (p *PathAttributeUnknown) MarshalJSON() ([]byte, error) {
+ return json.Marshal(p.ToApiStruct())
+}
+
func getPathAttribute(data []byte) (PathAttributeInterface, error) {
if len(data) < 1 {
eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
diff --git a/api/grpc.go b/server/grpc_server.go
index 69e8d159..76e79943 100644
--- a/api/grpc.go
+++ b/server/grpc_server.go
@@ -13,11 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package api
+package server
import (
"fmt"
log "github.com/Sirupsen/logrus"
+ "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/packet"
"golang.org/x/net/context"
"google.golang.org/grpc"
@@ -46,6 +47,18 @@ const (
const GRPC_PORT = 8080
+func convertAf2Rf(af *api.AddressFamily) (bgp.RouteFamily, error) {
+ if af.Equal(api.AF_IPV4_UC) {
+ return bgp.RF_IPv4_UC, nil
+ } else if af.Equal(api.AF_IPV6_UC) {
+ return bgp.RF_IPv6_UC, nil
+ } else if af.Equal(api.AF_EVPN) {
+ return bgp.RF_EVPN, nil
+ }
+
+ return bgp.RouteFamily(0), fmt.Errorf("unsupported address family: %v", af)
+}
+
type Server struct {
grpcServer *grpc.Server
bgpServerCh chan *GrpcRequest
@@ -60,7 +73,7 @@ func (s *Server) Serve() error {
return nil
}
-func (s *Server) GetNeighbor(ctx context.Context, arg *Arguments) (*Peer, error) {
+func (s *Server) GetNeighbor(ctx context.Context, arg *api.Arguments) (*api.Peer, error) {
var rf bgp.RouteFamily
req := NewGrpcRequest(REQ_NEIGHBOR, arg.RouterId, rf, nil)
s.bgpServerCh <- req
@@ -71,10 +84,10 @@ func (s *Server) GetNeighbor(ctx context.Context, arg *Arguments) (*Peer, error)
return nil, err
}
- return res.Data.(*Peer), nil
+ return res.Data.(*api.Peer), nil
}
-func (s *Server) GetNeighbors(_ *Arguments, stream Grpc_GetNeighborsServer) error {
+func (s *Server) GetNeighbors(_ *api.Arguments, stream api.Grpc_GetNeighborsServer) error {
var rf bgp.RouteFamily
req := NewGrpcRequest(REQ_NEIGHBORS, "", rf, nil)
s.bgpServerCh <- req
@@ -84,7 +97,7 @@ func (s *Server) GetNeighbors(_ *Arguments, stream Grpc_GetNeighborsServer) erro
log.Debug(err.Error())
return err
}
- if err := stream.Send(res.Data.(*Peer)); err != nil {
+ if err := stream.Send(res.Data.(*api.Peer)); err != nil {
return err
}
}
@@ -92,27 +105,20 @@ func (s *Server) GetNeighbors(_ *Arguments, stream Grpc_GetNeighborsServer) erro
return nil
}
-func (s *Server) GetAdjRib(arg *Arguments, stream Grpc_GetAdjRibServer) error {
+func (s *Server) GetAdjRib(arg *api.Arguments, stream api.Grpc_GetAdjRibServer) error {
var reqType int
switch arg.Resource {
- case Resource_ADJ_IN:
+ case api.Resource_ADJ_IN:
reqType = REQ_ADJ_RIB_IN
- case Resource_ADJ_OUT:
+ case api.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)
+ rf, err := convertAf2Rf(arg.Af)
+ if err != nil {
+ return err
}
req := NewGrpcRequest(reqType, arg.RouterId, rf, nil)
@@ -123,7 +129,7 @@ func (s *Server) GetAdjRib(arg *Arguments, stream Grpc_GetAdjRibServer) error {
log.Debug(err.Error())
return err
}
- if err := stream.Send(res.Data.(*Path)); err != nil {
+ if err := stream.Send(res.Data.(*api.Path)); err != nil {
return err
}
}
@@ -131,27 +137,20 @@ func (s *Server) GetAdjRib(arg *Arguments, stream Grpc_GetAdjRibServer) error {
return nil
}
-func (s *Server) GetRib(arg *Arguments, stream Grpc_GetRibServer) error {
+func (s *Server) GetRib(arg *api.Arguments, stream api.Grpc_GetRibServer) error {
var reqType int
switch arg.Resource {
- case Resource_LOCAL:
+ case api.Resource_LOCAL:
reqType = REQ_LOCAL_RIB
- case Resource_GLOBAL:
+ case api.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)
+ rf, err := convertAf2Rf(arg.Af)
+ if err != nil {
+ return err
}
req := NewGrpcRequest(reqType, arg.RouterId, rf, nil)
@@ -162,27 +161,20 @@ func (s *Server) GetRib(arg *Arguments, stream Grpc_GetRibServer) error {
log.Debug(err.Error())
return err
}
- if err := stream.Send(res.Data.(*Destination)); err != nil {
+ if err := stream.Send(res.Data.(*api.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)
+func (s *Server) neighbor(reqType int, arg *api.Arguments) (*api.Error, error) {
+ rf, err := convertAf2Rf(arg.Af)
+ if err != nil {
+ return nil, err
}
- none := &Error{}
+ none := &api.Error{}
req := NewGrpcRequest(reqType, arg.RouterId, rf, nil)
s.bgpServerCh <- req
@@ -194,46 +186,37 @@ func (s *Server) neighbor(reqType int, arg *Arguments) (*Error, error) {
return none, nil
}
-func (s *Server) Reset(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) Reset(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_RESET, arg)
}
-func (s *Server) SoftReset(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) SoftReset(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_SOFT_RESET, arg)
}
-func (s *Server) SoftResetIn(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) SoftResetIn(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_SOFT_RESET_IN, arg)
}
-func (s *Server) SoftResetOut(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) SoftResetOut(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_SOFT_RESET_OUT, arg)
}
-func (s *Server) Shutdown(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) Shutdown(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_SHUTDOWN, arg)
}
-func (s *Server) Enable(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) Enable(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_ENABLE, arg)
}
-func (s *Server) Disable(ctx context.Context, arg *Arguments) (*Error, error) {
+func (s *Server) Disable(ctx context.Context, arg *api.Arguments) (*api.Error, error) {
return s.neighbor(REQ_NEIGHBOR_DISABLE, arg)
}
-func (s *Server) modPath(reqType int, stream grpc.ServerStream) error {
+func (s *Server) ModPath(stream api.Grpc_ModPathServer) 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)
- }
+ arg, err := stream.Recv()
if err == io.EOF {
return nil
@@ -241,25 +224,20 @@ func (s *Server) modPath(reqType int, stream grpc.ServerStream) error {
return err
}
- if arg.Resource != Resource_GLOBAL {
+ if arg.Resource != api.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)
+
+ reqType := REQ_GLOBAL_ADD
+ if arg.Path.IsWithdraw {
+ reqType = REQ_GLOBAL_DELETE
}
- req := NewGrpcRequest(reqType, arg.RouterId, rf, prefix)
+ rf, err := convertAf2Rf(arg.Path.Nlri.Af)
+ if err != nil {
+ return nil
+ }
+ req := NewGrpcRequest(reqType, "", rf, arg.Path)
s.bgpServerCh <- req
res := <-req.ResponseCh
@@ -267,15 +245,15 @@ func (s *Server) modPath(reqType int, stream grpc.ServerStream) error {
log.Debug(err.Error())
return err
}
- }
-}
-func (s *Server) AddPath(stream Grpc_AddPathServer) error {
- return s.modPath(REQ_GLOBAL_ADD, stream)
-}
+ err = stream.Send(&api.Error{
+ Code: api.Error_SUCCESS,
+ })
-func (s *Server) DeletePath(stream Grpc_DeletePathServer) error {
- return s.modPath(REQ_GLOBAL_DELETE, stream)
+ if err != nil {
+ return err
+ }
+ }
}
type GrpcRequest struct {
@@ -284,10 +262,10 @@ type GrpcRequest struct {
RouteFamily bgp.RouteFamily
ResponseCh chan *GrpcResponse
Err error
- Data map[string]interface{}
+ Data interface{}
}
-func NewGrpcRequest(reqType int, remoteAddr string, rf bgp.RouteFamily, d map[string]interface{}) *GrpcRequest {
+func NewGrpcRequest(reqType int, remoteAddr string, rf bgp.RouteFamily, d interface{}) *GrpcRequest {
r := &GrpcRequest{
RequestType: reqType,
RouteFamily: rf,
@@ -313,6 +291,6 @@ func NewGrpcServer(port int, bgpServerCh chan *GrpcRequest) *Server {
grpcServer: grpcServer,
bgpServerCh: bgpServerCh,
}
- RegisterGrpcServer(grpcServer, server)
+ api.RegisterGrpcServer(grpcServer, server)
return server
}
diff --git a/server/peer.go b/server/peer.go
index 194998fb..2570019f 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -288,14 +288,20 @@ func (peer *Peer) sendMessages(msgs []*bgp.BGPMessage) {
}
}
-func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
- result := &api.GrpcResponse{}
+func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) {
+ result := &GrpcResponse{}
switch grpcReq.RequestType {
- case api.REQ_GLOBAL_ADD, api.REQ_GLOBAL_DELETE:
+ case REQ_GLOBAL_ADD, REQ_GLOBAL_DELETE:
rf := grpcReq.RouteFamily
- prefix := grpcReq.Data["prefix"].(string)
+ path, ok := grpcReq.Data.(*api.Path)
+ if !ok {
+ result.ResponseErr = fmt.Errorf("type assertion failed")
+ grpcReq.ResponseCh <- result
+ close(grpcReq.ResponseCh)
+ return
+ }
var isWithdraw bool
- if grpcReq.RequestType == api.REQ_GLOBAL_DELETE {
+ if grpcReq.RequestType == REQ_GLOBAL_DELETE {
isWithdraw = true
}
@@ -306,9 +312,9 @@ func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam}))
if rf == bgp.RF_IPv4_UC {
- ip, net, _ := net.ParseCIDR(prefix)
+ ip, net, _ := net.ParseCIDR(path.Nlri.Prefix)
if ip.To4() == nil {
- result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", prefix)
+ result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", path.Nlri.Prefix)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
return
@@ -321,9 +327,9 @@ func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
pattr = append(pattr, bgp.NewPathAttributeNextHop("0.0.0.0"))
} else if rf == bgp.RF_IPv6_UC {
- ip, net, _ := net.ParseCIDR(prefix)
+ ip, net, _ := net.ParseCIDR(path.Nlri.Prefix)
if ip.To16() == nil {
- result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", prefix)
+ result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", path.Nlri.Prefix)
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
return
@@ -348,53 +354,40 @@ func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
}
peer.peerMsgCh <- pm
- case api.REQ_LOCAL_RIB, api.REQ_GLOBAL_RIB:
+ case REQ_LOCAL_RIB, REQ_GLOBAL_RIB:
if peer.fsm.adminState == ADMIN_STATE_DOWN {
close(grpcReq.ResponseCh)
return
}
if t, ok := peer.rib.Tables[grpcReq.RouteFamily]; ok {
- type table struct {
- Destinations []*api.Destination
- }
- var tt table
- j, _ := json.Marshal(t)
- err := json.Unmarshal(j, &tt)
- if err != nil {
- result := &api.GrpcResponse{}
- result.ResponseErr = err
- grpcReq.ResponseCh <- result
- close(grpcReq.ResponseCh)
- return
- }
- for _, dst := range tt.Destinations {
- result := &api.GrpcResponse{}
- result.Data = dst
+ for _, dst := range t.GetDestinations() {
+ result := &GrpcResponse{}
+ result.Data = dst.ToApiStruct()
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
return
}
- case api.REQ_NEIGHBOR_SHUTDOWN:
+ case REQ_NEIGHBOR_SHUTDOWN:
peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, nil)
- case api.REQ_NEIGHBOR_RESET:
+ case REQ_NEIGHBOR_RESET:
peer.fsm.idleHoldTime = peer.peerConfig.Timers.IdleHoldTimeAfterReset
peer.outgoing <- bgp.NewBGPNotificationMessage(bgp.BGP_ERROR_CEASE, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_RESET, nil)
- case api.REQ_NEIGHBOR_SOFT_RESET, api.REQ_NEIGHBOR_SOFT_RESET_IN:
+ case REQ_NEIGHBOR_SOFT_RESET, REQ_NEIGHBOR_SOFT_RESET_IN:
// soft-reconfiguration inbound
peer.sendPathsToSiblings(peer.adjRib.GetInPathList(grpcReq.RouteFamily))
- if grpcReq.RequestType == api.REQ_NEIGHBOR_SOFT_RESET_IN {
+ if grpcReq.RequestType == REQ_NEIGHBOR_SOFT_RESET_IN {
break
}
fallthrough
- case api.REQ_NEIGHBOR_SOFT_RESET_OUT:
+ case REQ_NEIGHBOR_SOFT_RESET_OUT:
pathList := peer.adjRib.GetOutPathList(grpcReq.RouteFamily)
peer.sendMessages(table.CreateUpdateMsgFromPaths(pathList))
- case api.REQ_ADJ_RIB_IN, api.REQ_ADJ_RIB_OUT:
+ case REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT:
rf := grpcReq.RouteFamily
var paths []table.Path
- if grpcReq.RequestType == api.REQ_ADJ_RIB_IN {
+ if grpcReq.RequestType == REQ_ADJ_RIB_IN {
paths = peer.adjRib.GetInPathList(rf)
log.Debugf("RouteFamily=%v adj-rib-in found : %d", rf.String(), len(paths))
} else {
@@ -403,7 +396,7 @@ func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
}
for _, p := range paths {
- result := &api.GrpcResponse{}
+ result := &GrpcResponse{}
path := &api.Path{}
j, _ := json.Marshal(p)
err := json.Unmarshal(j, path)
@@ -416,9 +409,9 @@ func (peer *Peer) handleGrpc(grpcReq *api.GrpcRequest) {
}
close(grpcReq.ResponseCh)
return
- case api.REQ_NEIGHBOR_ENABLE, api.REQ_NEIGHBOR_DISABLE:
+ case REQ_NEIGHBOR_ENABLE, REQ_NEIGHBOR_DISABLE:
var err api.Error
- if grpcReq.RequestType == api.REQ_NEIGHBOR_ENABLE {
+ if grpcReq.RequestType == REQ_NEIGHBOR_ENABLE {
select {
case peer.fsm.adminStateCh <- ADMIN_STATE_UP:
log.WithFields(log.Fields{
@@ -656,7 +649,7 @@ func (peer *Peer) handleServerMsg(m *serverMsg) {
log.Warning("can not find peer: ", d.Address.String())
}
case SRV_MSG_API:
- peer.handleGrpc(m.msgData.(*api.GrpcRequest))
+ peer.handleGrpc(m.msgData.(*GrpcRequest))
case SRV_MSG_POLICY_UPDATED:
log.Debug("policy updated")
d := m.msgData.(map[string]*policy.Policy)
@@ -827,14 +820,10 @@ func (peer *Peer) PassConn(conn *net.TCPConn) {
}
func (peer *Peer) MarshalJSON() ([]byte, error) {
- p, err := peer.ToGrpc()
- if err != nil {
- return nil, err
- }
- return json.Marshal(p)
+ return json.Marshal(peer.ToApiStruct())
}
-func (peer *Peer) ToGrpc() (*api.Peer, error) {
+func (peer *Peer) ToApiStruct() *api.Peer {
f := peer.fsm
c := f.peerConfig
@@ -904,5 +893,5 @@ func (peer *Peer) ToGrpc() (*api.Peer, error) {
return &api.Peer{
Conf: conf,
Info: info,
- }, nil
+ }
}
diff --git a/server/peer_test.go b/server/peer_test.go
index cae3b0c7..ab3bfa54 100644
--- a/server/peer_test.go
+++ b/server/peer_test.go
@@ -121,7 +121,7 @@ func TestPeerAdminShutdownWhileEstablished(t *testing.T) {
peer.connCh <- m
waitUntil(assert, bgp.BGP_FSM_ESTABLISHED, peer, 1000)
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -163,7 +163,7 @@ func TestPeerAdminShutdownWhileIdle(t *testing.T) {
waitUntil(assert, bgp.BGP_FSM_IDLE, peer, 1000)
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -197,7 +197,7 @@ func TestPeerAdminShutdownWhileActive(t *testing.T) {
waitUntil(assert, bgp.BGP_FSM_ACTIVE, peer, 1000)
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -233,7 +233,7 @@ func TestPeerAdminShutdownWhileOpensent(t *testing.T) {
peer.connCh <- m
waitUntil(assert, bgp.BGP_FSM_OPENSENT, peer, 1000)
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -277,7 +277,7 @@ func TestPeerAdminShutdownWhileOpenconfirm(t *testing.T) {
peer.connCh <- m
waitUntil(assert, bgp.BGP_FSM_OPENCONFIRM, peer, 1000)
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -327,7 +327,7 @@ func TestPeerAdminEnable(t *testing.T) {
waitUntil(assert, bgp.BGP_FSM_ESTABLISHED, peer, 1000)
// shutdown peer at first
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -342,7 +342,7 @@ func TestPeerAdminEnable(t *testing.T) {
assert.Equal(ADMIN_STATE_DOWN, peer.fsm.adminState)
// enable peer
- grpcReq = api.NewGrpcRequest(api.REQ_NEIGHBOR_ENABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq = NewGrpcRequest(REQ_NEIGHBOR_ENABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg = &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -388,7 +388,7 @@ func TestPeerAdminShutdownReject(t *testing.T) {
peer.connCh <- m
waitUntil(assert, bgp.BGP_FSM_OPENSENT, peer, 1000)
- grpcReq := api.NewGrpcRequest(api.REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq := NewGrpcRequest(REQ_NEIGHBOR_DISABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
@@ -401,7 +401,7 @@ func TestPeerAdminShutdownReject(t *testing.T) {
err := result.Data.(api.Error)
assert.Equal(err.Code, api.Error_FAIL)
- grpcReq = api.NewGrpcRequest(api.REQ_NEIGHBOR_ENABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
+ grpcReq = NewGrpcRequest(REQ_NEIGHBOR_ENABLE, "0.0.0.0", bgp.RF_IPv4_UC, nil)
msg = &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
diff --git a/server/server.go b/server/server.go
index 8212a1a0..c83c48df 100644
--- a/server/server.go
+++ b/server/server.go
@@ -18,7 +18,6 @@ package server
import (
"fmt"
log "github.com/Sirupsen/logrus"
- "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/policy"
"net"
@@ -60,7 +59,7 @@ type BgpServer struct {
globalTypeCh chan config.Global
addedPeerCh chan config.Neighbor
deletedPeerCh chan config.Neighbor
- GrpcReqCh chan *api.GrpcRequest
+ GrpcReqCh chan *GrpcRequest
listenPort int
peerMap map[string]peerMapInfo
globalRib *Peer
@@ -73,7 +72,7 @@ func NewBgpServer(port int) *BgpServer {
b.globalTypeCh = make(chan config.Global)
b.addedPeerCh = make(chan config.Neighbor)
b.deletedPeerCh = make(chan config.Neighbor)
- b.GrpcReqCh = make(chan *api.GrpcRequest, 1)
+ b.GrpcReqCh = make(chan *GrpcRequest, 1)
b.policyUpdateCh = make(chan config.RoutingPolicy)
b.listenPort = port
return &b
@@ -293,53 +292,49 @@ func (p peers) Less(i, j int) bool {
return strings.Less(0, 1)
}
-func (server *BgpServer) handleGrpc(grpcReq *api.GrpcRequest) {
+func (server *BgpServer) handleGrpc(grpcReq *GrpcRequest) {
switch grpcReq.RequestType {
- case api.REQ_NEIGHBORS:
+ case REQ_NEIGHBORS:
peerList := peers{}
for _, info := range server.peerMap {
peerList = append(peerList, info.peer)
}
sort.Sort(peerList)
for _, peer := range peerList {
- data, err := peer.ToGrpc()
- result := &api.GrpcResponse{
- ResponseErr: err,
- Data: data,
+ result := &GrpcResponse{
+ Data: peer.ToApiStruct(),
}
grpcReq.ResponseCh <- result
}
close(grpcReq.ResponseCh)
- case api.REQ_NEIGHBOR:
+ case REQ_NEIGHBOR:
remoteAddr := grpcReq.RemoteAddr
- var result *api.GrpcResponse
+ var result *GrpcResponse
info, found := server.peerMap[remoteAddr]
if found {
- data, err := info.peer.ToGrpc()
- result = &api.GrpcResponse{
- ResponseErr: err,
- Data: data,
+ result = &GrpcResponse{
+ Data: info.peer.ToApiStruct(),
}
} else {
- result = &api.GrpcResponse{
+ result = &GrpcResponse{
ResponseErr: fmt.Errorf("Neighbor that has %v does not exist.", remoteAddr),
}
}
grpcReq.ResponseCh <- result
close(grpcReq.ResponseCh)
- case api.REQ_GLOBAL_RIB, api.REQ_GLOBAL_ADD, api.REQ_GLOBAL_DELETE:
+ case REQ_GLOBAL_RIB, REQ_GLOBAL_ADD, REQ_GLOBAL_DELETE:
msg := &serverMsg{
msgType: SRV_MSG_API,
msgData: grpcReq,
}
server.globalRib.serverMsgCh <- msg
- case api.REQ_LOCAL_RIB, api.REQ_NEIGHBOR_SHUTDOWN, api.REQ_NEIGHBOR_RESET,
- api.REQ_NEIGHBOR_SOFT_RESET, api.REQ_NEIGHBOR_SOFT_RESET_IN, api.REQ_NEIGHBOR_SOFT_RESET_OUT,
- api.REQ_ADJ_RIB_IN, api.REQ_ADJ_RIB_OUT,
- api.REQ_NEIGHBOR_ENABLE, api.REQ_NEIGHBOR_DISABLE:
+ case REQ_LOCAL_RIB, REQ_NEIGHBOR_SHUTDOWN, REQ_NEIGHBOR_RESET,
+ REQ_NEIGHBOR_SOFT_RESET, REQ_NEIGHBOR_SOFT_RESET_IN, REQ_NEIGHBOR_SOFT_RESET_OUT,
+ REQ_ADJ_RIB_IN, REQ_ADJ_RIB_OUT,
+ REQ_NEIGHBOR_ENABLE, REQ_NEIGHBOR_DISABLE:
remoteAddr := grpcReq.RemoteAddr
- result := &api.GrpcResponse{}
+ result := &GrpcResponse{}
info, found := server.peerMap[remoteAddr]
if found {
msg := &serverMsg{
diff --git a/table/destination.go b/table/destination.go
index aae02822..cfd411ce 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -20,6 +20,7 @@ import (
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
+ "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/packet"
"net"
"reflect"
@@ -66,6 +67,7 @@ type Destination interface {
addNewPath(newPath Path)
constructWithdrawPath() Path
removeOldPathsFromSource(source *PeerInfo) []Path
+ ToApiStruct() *api.Destination
MarshalJSON() ([]byte, error)
}
@@ -94,7 +96,11 @@ func NewDestinationDefault(nlri bgp.AddrPrefixInterface) *DestinationDefault {
}
func (dd *DestinationDefault) MarshalJSON() ([]byte, error) {
- prefix := dd.getNlri().(*bgp.NLRInfo).Prefix
+ return json.Marshal(dd.ToApiStruct())
+}
+
+func (dd *DestinationDefault) ToApiStruct() *api.Destination {
+ prefix := dd.getNlri().String()
idx := func() int {
for i, p := range dd.knownPathList {
@@ -104,19 +110,24 @@ func (dd *DestinationDefault) MarshalJSON() ([]byte, error) {
}
log.WithFields(log.Fields{
"Topic": "Table",
- "Key": prefix.String(),
+ "Key": prefix,
}).Panic("no best path")
return 0
}()
- return json.Marshal(struct {
- Prefix string
- Paths []Path
- BestPathIdx int `json:"best_path_idx"`
- }{
- Prefix: prefix.String(),
- Paths: dd.knownPathList,
- BestPathIdx: idx,
- })
+
+ paths := func(arg []Path) []*api.Path {
+ ret := make([]*api.Path, 0, len(arg))
+ for _, p := range arg {
+ ret = append(ret, p.ToApiStruct())
+ }
+ return ret
+ }(dd.knownPathList)
+
+ return &api.Destination{
+ Prefix: prefix,
+ Paths: paths,
+ BestPathIdx: uint32(idx),
+ }
}
func (dd *DestinationDefault) getRouteFamily() bgp.RouteFamily {
diff --git a/table/path.go b/table/path.go
index fddde7d3..5abd1f10 100644
--- a/table/path.go
+++ b/table/path.go
@@ -19,6 +19,7 @@ import (
"encoding/json"
"fmt"
log "github.com/Sirupsen/logrus"
+ "github.com/osrg/gobgp/api"
"github.com/osrg/gobgp/config"
"github.com/osrg/gobgp/packet"
"net"
@@ -45,6 +46,7 @@ type Path interface {
Clone(IsWithdraw bool) Path
getTimestamp() time.Time
setTimestamp(t time.Time)
+ ToApiStruct() *api.Path
MarshalJSON() ([]byte, error)
}
@@ -170,18 +172,25 @@ func (pd *PathDefault) setTimestamp(t time.Time) {
pd.timestamp = t
}
+func (pd *PathDefault) ToApiStruct() *api.Path {
+ pathAttrs := func(arg []bgp.PathAttributeInterface) []*api.PathAttr {
+ ret := make([]*api.PathAttr, 0, len(arg))
+ for _, a := range arg {
+ ret = append(ret, a.ToApiStruct())
+ }
+ return ret
+ }(pd.getPathAttrs())
+ return &api.Path{
+ Nlri: pd.GetNlri().ToApiStruct(),
+ Nexthop: pd.GetNexthop().String(),
+ Attrs: pathAttrs,
+ Age: int64(time.Now().Sub(pd.timestamp).Seconds()),
+ IsWithdraw: pd.IsWithdraw(),
+ }
+}
+
func (pd *PathDefault) MarshalJSON() ([]byte, error) {
- return json.Marshal(struct {
- Network string
- Nexthop string
- Attrs []bgp.PathAttributeInterface
- Age int64
- }{
- Network: pd.getPrefix(),
- Nexthop: pd.GetNexthop().String(),
- Attrs: pd.getPathAttrs(),
- Age: int64(time.Now().Sub(pd.timestamp).Seconds()),
- })
+ return json.Marshal(pd.ToApiStruct())
}
// create new PathAttributes
diff --git a/table/table.go b/table/table.go
index 28799a24..d9c14144 100644
--- a/table/table.go
+++ b/table/table.go
@@ -30,7 +30,7 @@ import (
type Table interface {
createDest(nlri bgp.AddrPrefixInterface) Destination
- getDestinations() map[string]Destination
+ GetDestinations() map[string]Destination
setDestinations(destinations map[string]Destination)
getDestination(key string) Destination
setDestination(key string, dest Destination)
@@ -153,7 +153,7 @@ func (td *TableDefault) DeleteDestByPeer(peerInfo *PeerInfo) []Destination {
func deleteDestByNlri(table Table, nlri bgp.AddrPrefixInterface) Destination {
table.validateNlri(nlri)
- destinations := table.getDestinations()
+ destinations := table.GetDestinations()
dest := destinations[table.tableKey(nlri)]
if dest != nil {
delete(destinations, table.tableKey(nlri))
@@ -162,7 +162,7 @@ func deleteDestByNlri(table Table, nlri bgp.AddrPrefixInterface) Destination {
}
func deleteDest(table Table, dest Destination) {
- destinations := table.getDestinations()
+ destinations := table.GetDestinations()
delete(destinations, table.tableKey(dest.getNlri()))
}
@@ -230,7 +230,7 @@ func getOrCreateDest(table Table, nlri bgp.AddrPrefixInterface) Destination {
return dest
}
-func (td *TableDefault) getDestinations() map[string]Destination {
+func (td *TableDefault) GetDestinations() map[string]Destination {
return td.destinations
}
func (td *TableDefault) setDestinations(destinations map[string]Destination) {
diff --git a/table/table_manager.go b/table/table_manager.go
index abb00cf9..679b684c 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -269,7 +269,7 @@ func (manager *TableManager) GetPathList(rf bgp.RouteFamily) []Path {
return []Path{}
}
var paths []Path
- for _, dest := range manager.Tables[rf].getDestinations() {
+ for _, dest := range manager.Tables[rf].GetDestinations() {
paths = append(paths, dest.getBestPath())
}
return paths
diff --git a/table/table_manager_test.go b/table/table_manager_test.go
index 8e800c8c..91887cfb 100644
--- a/table/table_manager_test.go
+++ b/table/table_manager_test.go
@@ -2053,7 +2053,7 @@ func TestProcessBGPUpdate_multiple_nlri_ipv4(t *testing.T) {
// check table
table := tm.Tables[bgp.RF_IPv4_UC]
- assert.Equal(t, 13, len(table.getDestinations()))
+ assert.Equal(t, 13, len(table.GetDestinations()))
}
@@ -2200,7 +2200,7 @@ func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) {
// check table
table := tm.Tables[bgp.RF_IPv6_UC]
- assert.Equal(t, 13, len(table.getDestinations()))
+ assert.Equal(t, 13, len(table.GetDestinations()))
}
diff --git a/table/table_test.go b/table/table_test.go
index 81e377f6..407fbe0a 100644
--- a/table/table_test.go
+++ b/table/table_test.go
@@ -88,7 +88,7 @@ func TestTableSetDestinations(t *testing.T) {
destinations[tableKey] = dest
}
ipv4t.setDestinations(destinations)
- ds := ipv4t.getDestinations()
+ ds := ipv4t.GetDestinations()
assert.Equal(t, ds, destinations)
}
func TestTableGetDestinations(t *testing.T) {
@@ -103,7 +103,7 @@ func TestTableGetDestinations(t *testing.T) {
destinations[tableKey] = dest
}
ipv4t.setDestinations(destinations)
- ds := ipv4t.getDestinations()
+ ds := ipv4t.GetDestinations()
assert.Equal(t, ds, destinations)
}
diff --git a/test/scenario_test/bgp_router_test.py b/test/scenario_test/bgp_router_test.py
index 268f468d..f965d224 100644
--- a/test/scenario_test/bgp_router_test.py
+++ b/test/scenario_test/bgp_router_test.py
@@ -69,7 +69,6 @@ class GoBGPTest(GoBGPTestBase):
self.assert_global_rib()
-
# Test of advertising route to each quagga form gobgp
def test_03_advertising_route(self):
print "test_advertising_route"
@@ -157,7 +156,7 @@ class GoBGPTest(GoBGPTestBase):
still_exists = False
for dst in rib:
for path in dst['paths']:
- if path['network'] == removed_prefix:
+ if path['nlri']['prefix'] == removed_prefix:
still_exists = True
if not still_exists:
@@ -236,7 +235,7 @@ class GoBGPTest(GoBGPTestBase):
print "please wait " + str(self.initial_wait_time) + " second"
time.sleep(self.initial_wait_time)
- target_network = "192.168.20.0"
+ target_network = "192.168.20.0/24"
ans_nexthop = "10.0.0.3"
print "check whether target network %s 's nexthop is %s" % (target_network, ans_nexthop)
diff --git a/test/scenario_test/gobgp_test.py b/test/scenario_test/gobgp_test.py
index 2e998178..d3bcdc21 100644
--- a/test/scenario_test/gobgp_test.py
+++ b/test/scenario_test/gobgp_test.py
@@ -100,7 +100,7 @@ class GoBGPTestBase(unittest.TestCase):
for g_path in g_paths:
print "best_path_Idx: " + str(best_path_idx) + ", idx: " + str(idx)
print g_dest
- print "pre: ", g_dest['prefix'], "net: ", g_path['network'], "next: ", g_path['nexthop']
+ print "pre: ", g_dest['prefix'], "net: ", g_path['nlri']['prefix'], "next: ", g_path['nexthop']
if str(best_path_idx) == str(idx):
rep_nexthop = g_path['nexthop']
idx += 1
@@ -146,13 +146,12 @@ class GoBGPTestBase(unittest.TestCase):
continue
for network in networks:
elems = network.text.split(" ")
- prefix = elems[1].split("/")[0]
network = elems[1]
nexthop = peer_ip
path = Path(network, nexthop)
- dest = Destination(prefix)
+ dest = Destination(network)
dest.paths.append(path)
- quagga_config.destinations[prefix] = dest
+ quagga_config.destinations[network] = dest
# print "prefix: " + prefix
# print "network: " + network
# print "nexthop: " + nexthop
@@ -240,7 +239,7 @@ class GoBGPTestBase(unittest.TestCase):
retry_count = 0
while True:
rib = self.ask_gobgp(type, neighbor_address)
- paths = [p for p in rib if p['network'] == target_prefix]
+ paths = [p for p in rib if p['nlri']['prefix'] == target_prefix]
if len(paths) > 0:
assert len(paths) == 1
@@ -264,12 +263,15 @@ class GoBGPTestBase(unittest.TestCase):
interval = self.wait_per_retry
print "check route %s on quagga : %s" % (target_prefix, neighbor_address)
retry_count = 0
+
+ # quagga cli doesn't show prefix's netmask
+ quagga_prefix = target_prefix.split('/')[0]
while True:
tn = qaccess.login(neighbor_address)
q_rib = qaccess.show_rib(tn)
qaccess.logout(tn)
for q_path in q_rib:
- if target_prefix == q_path['Network']:
+ if quagga_prefix == q_path['Network']:
return q_path
retry_count += 1
@@ -342,7 +344,7 @@ class GoBGPTestBase(unittest.TestCase):
exist = False
for dst in rib:
for path in dst['paths']:
- if path['network'] == p.network:
+ if path['nlri']['prefix'] == p.network:
exist = True
if exist:
is_nexthop_same = path['nexthop'] == p.nexthop
diff --git a/test/scenario_test/route_server_policy_test.py b/test/scenario_test/route_server_policy_test.py
index 9ae29a2b..7c2e0456 100644
--- a/test/scenario_test/route_server_policy_test.py
+++ b/test/scenario_test/route_server_policy_test.py
@@ -25,6 +25,13 @@ from noseplugin import parser_option
from gobgp_test import GoBGPTestBase
from constant import *
+peer1 = "10.0.0.1"
+peer2 = "10.0.0.2"
+peer3 = "10.0.0.3"
+
+prefix1 = "192.168.2.0/24"
+prefix2 = "192.168.20.0/24"
+prefix3 = "192.168.200.0/24"
class GoBGPTest(GoBGPTestBase):
@@ -60,29 +67,25 @@ class GoBGPTest(GoBGPTestBase):
addresses = self.get_neighbor_address(self.gobgp_config)
self.retry_routine_for_state(addresses, "BGP_FSM_ESTABLISHED")
- peer1 = "10.0.0.1"
- peer2 = "10.0.0.2"
- peer3 = "10.0.0.3"
-
- path = self.get_paths_in_localrib(peer1, "192.168.2.0", retry=3)
+ path = self.get_paths_in_localrib(peer1, prefix1, retry=3)
self.assertIsNotNone(path)
# check show ip bgp on peer1(quagga1)
- qpath = self.get_routing_table(peer1,"192.168.2.0", retry=3)
+ qpath = self.get_routing_table(peer1,prefix1, retry=3)
print qpath
self.assertIsNotNone(qpath)
# check adj-rib-out in peer2
- path = self.get_adj_rib_in(peer2, "192.168.2.0/24", retry=3)
+ path = self.get_adj_rib_in(peer2, prefix1, retry=3)
# print path
self.assertIsNotNone(path)
- path = self.get_paths_in_localrib(peer3, "192.168.2.0",retry=0)
+ path = self.get_paths_in_localrib(peer3, prefix1,retry=0)
# print path
self.assertIsNone(path)
# check show ip bgp on peer1(quagga3)
- qpath = self.get_routing_table(peer3,"192.168.2.0", retry=3)
+ qpath = self.get_routing_table(peer3,prefix1, retry=3)
# print qpath
self.assertIsNone(qpath)
@@ -104,34 +107,30 @@ class GoBGPTest(GoBGPTestBase):
addresses = self.get_neighbor_address(self.gobgp_config)
self.retry_routine_for_state(addresses, "BGP_FSM_ESTABLISHED")
- peer1 = "10.0.0.1"
- peer2 = "10.0.0.2"
- peer3 = "10.0.0.3"
-
- paths = self.get_paths_in_localrib(peer1, "192.168.2.0", retry=3)
+ paths = self.get_paths_in_localrib(peer1, prefix1, retry=3)
# print paths
self.assertIsNotNone(paths)
# check show ip bgp on peer1(quagga1)
- qpath = self.get_routing_table(peer1, "192.168.2.0", retry=3)
+ qpath = self.get_routing_table(peer1, prefix1, retry=3)
# print qpath
self.assertIsNotNone(qpath)
# check adj-rib-out in peer2
- path = self.get_adj_rib_in(peer2, "192.168.2.0/24", retry=1)
+ path = self.get_adj_rib_in(peer2, prefix1, retry=1)
# print path
self.assertIsNotNone(path)
- path = self.get_paths_in_localrib(peer3, "192.168.2.0")
+ path = self.get_paths_in_localrib(peer3, prefix1)
# print path
self.assertIsNotNone(path)
- path = self.get_adj_rib_out(peer3, "192.168.2.0", retry=1)
+ path = self.get_adj_rib_out(peer3, prefix1, retry=1)
# print path
self.assertIsNone(path)
# check show ip bgp on peer1(quagga3)
- qpath = self.get_routing_table(peer3,"192.168.2.0", retry=3)
+ qpath = self.get_routing_table(peer3,prefix1, retry=3)
# print qpath
self.assertIsNone(qpath)
@@ -167,16 +166,12 @@ class GoBGPTest(GoBGPTestBase):
# coming from peer2(10.0.0.2) to peer3(10.0.0.3)'s import-policy.
self.initialize(policy_pattern="p3")
- peer1 = "10.0.0.1"
- peer2 = "10.0.0.2"
- peer3 = "10.0.0.3"
-
# add other network
tn = qaccess.login(peer2)
print "add network 192.168.20.0/24"
- qaccess.add_network(tn, 65002, "192.168.20.0/24")
+ qaccess.add_network(tn, 65002, prefix2)
print "add network 192.168.200.0/24"
- qaccess.add_network(tn, 65002, "192.168.200.0/24")
+ qaccess.add_network(tn, 65002, prefix3)
qaccess.logout(tn)
addresses = self.get_neighbor_address(self.gobgp_config)
@@ -197,28 +192,28 @@ class GoBGPTest(GoBGPTestBase):
return path is not None
- self.assertTrue(path_exists_in_localrib(peer1,"192.168.2.0"))
- self.assertTrue(path_exists_in_localrib(peer1,"192.168.20.0"))
- self.assertTrue(path_exists_in_localrib(peer1,"192.168.200.0"))
+ self.assertTrue(path_exists_in_localrib(peer1,prefix1))
+ self.assertTrue(path_exists_in_localrib(peer1,prefix2))
+ self.assertTrue(path_exists_in_localrib(peer1,prefix3))
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.2.0"))
- self.assertFalse(path_exists_in_localrib(peer3,"192.168.20.0",r=3))
- self.assertFalse(path_exists_in_localrib(peer3,"192.168.200.0",r=0))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix1))
+ self.assertFalse(path_exists_in_localrib(peer3,prefix2,r=3))
+ self.assertFalse(path_exists_in_localrib(peer3,prefix3,r=0))
# check show ip bgp on peer1(quagga1)
- self.assertTrue(path_exists_in_routing_table(peer1, "192.168.2.0"))
- self.assertTrue(path_exists_in_routing_table(peer1, "192.168.20.0"))
- self.assertTrue(path_exists_in_routing_table(peer1, "192.168.200.0"))
+ self.assertTrue(path_exists_in_routing_table(peer1, prefix1))
+ self.assertTrue(path_exists_in_routing_table(peer1, prefix2))
+ self.assertTrue(path_exists_in_routing_table(peer1, prefix3))
# check show ip bgp on peer3(quagga3)
- self.assertTrue(path_exists_in_routing_table(peer3, "192.168.2.0"))
- self.assertFalse(path_exists_in_routing_table(peer3, "192.168.20.0",r=3))
- self.assertFalse(path_exists_in_routing_table(peer3, "192.168.200.0",r=0))
+ self.assertTrue(path_exists_in_routing_table(peer3, prefix1))
+ self.assertFalse(path_exists_in_routing_table(peer3, prefix2,r=3))
+ self.assertFalse(path_exists_in_routing_table(peer3, prefix3,r=0))
# check adj-rib-out in peer2
- self.assertTrue(path_exists_in_adj_rib_in(peer2, "192.168.2.0/24"))
- self.assertTrue(path_exists_in_adj_rib_in(peer2, "192.168.20.0/24"))
- self.assertTrue(path_exists_in_adj_rib_in(peer2, "192.168.200.0/24"))
+ self.assertTrue(path_exists_in_adj_rib_in(peer2, prefix1))
+ self.assertTrue(path_exists_in_adj_rib_in(peer2, prefix2))
+ self.assertTrue(path_exists_in_adj_rib_in(peer2, prefix3))
# update policy
print "update_policy_config"
@@ -230,14 +225,14 @@ class GoBGPTest(GoBGPTestBase):
self.soft_reset(peer2, IPv4)
# check local-rib
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.2.0"))
- self.assertFalse(path_exists_in_localrib(peer3,"192.168.20.0",r=3))
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.200.0"))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix1))
+ self.assertFalse(path_exists_in_localrib(peer3,prefix2,r=3))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix3))
# check show ip bgp on peer3(quagga3)
- self.assertTrue(path_exists_in_routing_table(peer3, "192.168.2.0"))
- self.assertFalse(path_exists_in_routing_table(peer3, "192.168.20.0",r=0))
- self.assertTrue(path_exists_in_routing_table(peer3, "192.168.200.0"))
+ self.assertTrue(path_exists_in_routing_table(peer3, prefix1))
+ self.assertFalse(path_exists_in_routing_table(peer3, prefix2,r=0))
+ self.assertTrue(path_exists_in_routing_table(peer3, prefix3))
"""
@@ -272,16 +267,12 @@ class GoBGPTest(GoBGPTestBase):
# coming from peer2(10.0.0.2) to peer3(10.0.0.3)'s export-policy.
self.initialize(policy_pattern="p4")
- peer1 = "10.0.0.1"
- peer2 = "10.0.0.2"
- peer3 = "10.0.0.3"
-
# add other network
tn = qaccess.login(peer2)
print "add network 192.168.20.0/24"
- qaccess.add_network(tn, 65002, "192.168.20.0/24")
+ qaccess.add_network(tn, 65002, prefix2)
print "add network 192.168.200.0/24"
- qaccess.add_network(tn, 65002, "192.168.200.0/24")
+ qaccess.add_network(tn, 65002, prefix3)
qaccess.logout(tn)
addresses = self.get_neighbor_address(self.gobgp_config)
@@ -306,35 +297,35 @@ class GoBGPTest(GoBGPTestBase):
return path is not None
- self.assertTrue(path_exists_in_localrib(peer1,"192.168.2.0"))
- self.assertTrue(path_exists_in_localrib(peer1,"192.168.20.0"))
- self.assertTrue(path_exists_in_localrib(peer1,"192.168.200.0"))
+ self.assertTrue(path_exists_in_localrib(peer1,prefix1))
+ self.assertTrue(path_exists_in_localrib(peer1,prefix2))
+ self.assertTrue(path_exists_in_localrib(peer1,prefix3))
# check peer3 local-rib
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.2.0"))
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.20.0"))
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.200.0"))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix1))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix2))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix3))
# check peer3 rib-out
- self.assertTrue(path_exists_in_adj_rib_out(peer3,"192.168.2.0/24"))
- self.assertFalse(path_exists_in_adj_rib_out(peer3,"192.168.20.0/24",r=3))
- self.assertFalse(path_exists_in_adj_rib_out(peer3,"192.168.200.0/24",r=3))
+ self.assertTrue(path_exists_in_adj_rib_out(peer3,prefix1))
+ self.assertFalse(path_exists_in_adj_rib_out(peer3,prefix2,r=3))
+ self.assertFalse(path_exists_in_adj_rib_out(peer3,prefix3,r=3))
# check show ip bgp on peer1(quagga1)
- self.assertTrue(path_exists_in_routing_table(peer1, "192.168.2.0"))
- self.assertTrue(path_exists_in_routing_table(peer1, "192.168.20.0"))
- self.assertTrue(path_exists_in_routing_table(peer1, "192.168.200.0"))
+ self.assertTrue(path_exists_in_routing_table(peer1, prefix1))
+ self.assertTrue(path_exists_in_routing_table(peer1, prefix2))
+ self.assertTrue(path_exists_in_routing_table(peer1, prefix3))
# check show ip bgp on peer3(quagga3)
- self.assertTrue(path_exists_in_routing_table(peer3, "192.168.2.0"))
- self.assertFalse(path_exists_in_routing_table(peer3, "192.168.20.0",r=3))
- self.assertFalse(path_exists_in_routing_table(peer3, "192.168.200.0",r=0))
+ self.assertTrue(path_exists_in_routing_table(peer3, prefix1))
+ self.assertFalse(path_exists_in_routing_table(peer3, prefix2,r=3))
+ self.assertFalse(path_exists_in_routing_table(peer3, prefix3,r=0))
# check adj-rib-out in peer2
peer2 = "10.0.0.2"
- self.assertTrue(path_exists_in_adj_rib_in(peer2, "192.168.2.0/24"))
- self.assertTrue(path_exists_in_adj_rib_in(peer2, "192.168.20.0/24"))
- self.assertTrue(path_exists_in_adj_rib_in(peer2, "192.168.200.0/24"))
+ self.assertTrue(path_exists_in_adj_rib_in(peer2, prefix1))
+ self.assertTrue(path_exists_in_adj_rib_in(peer2, prefix2))
+ self.assertTrue(path_exists_in_adj_rib_in(peer2, prefix3))
# update policy
print "update_policy_config"
@@ -346,19 +337,19 @@ class GoBGPTest(GoBGPTestBase):
self.soft_reset(peer2, IPv4)
# check local-rib
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.2.0"))
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.20.0"))
- self.assertTrue(path_exists_in_localrib(peer3,"192.168.200.0"))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix1))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix2))
+ self.assertTrue(path_exists_in_localrib(peer3,prefix3))
# check local-adj-out-rib
- self.assertTrue(path_exists_in_adj_rib_out(peer3, "192.168.2.0/24"))
- self.assertFalse(path_exists_in_adj_rib_out(peer3, "192.168.20.0/24",r=3))
- self.assertTrue(path_exists_in_adj_rib_out(peer3, "192.168.200.0/24"))
+ self.assertTrue(path_exists_in_adj_rib_out(peer3, prefix1))
+ self.assertFalse(path_exists_in_adj_rib_out(peer3, prefix2,r=3))
+ self.assertTrue(path_exists_in_adj_rib_out(peer3, prefix3))
# check show ip bgp on peer3(quagga3)
- self.assertTrue(path_exists_in_routing_table(peer3, "192.168.2.0"))
- self.assertFalse(path_exists_in_routing_table(peer3, "192.168.20.0",r=3))
- self.assertTrue(path_exists_in_routing_table(peer3, "192.168.200.0"))
+ self.assertTrue(path_exists_in_routing_table(peer3, prefix1))
+ self.assertFalse(path_exists_in_routing_table(peer3, prefix2,r=3))
+ self.assertTrue(path_exists_in_routing_table(peer3, prefix3))
if __name__ == '__main__':
diff --git a/test/scenario_test/route_server_test.py b/test/scenario_test/route_server_test.py
index 603ffecd..61c94eb0 100644
--- a/test/scenario_test/route_server_test.py
+++ b/test/scenario_test/route_server_test.py
@@ -188,7 +188,7 @@ class GoBGPTest(GoBGPTestBase):
time.sleep(self.initial_wait_time)
check_address = "10.0.0.1"
- target_network = "192.168.20.0"
+ target_network = "192.168.20.0/24"
ans_nexthop = "10.0.0.3"
print "check of [ " + check_address + " ]"