diff options
author | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2018-06-20 23:15:11 +0900 |
---|---|---|
committer | IWASE Yusuke <iwase.yusuke0@gmail.com> | 2018-06-21 10:40:25 +0900 |
commit | 493d024701e3034824f9f62010c2beeabe1f2253 (patch) | |
tree | f40c40d994c6754ee4ea050d8d23e0ba97c511c1 /api | |
parent | 92814f7b85c01ffc7eca750cfec3b7bbc200a2d3 (diff) |
api: Define protobuf for BGP Capabilities
Example of protoc command:
$ export PROTOBUF=${HOME}/protobuf/src
$ export GOBGP=${GOPATH}/src/github.com/osrg/gobgp
$ protoc \
-I ${PROTOBUF} \
-I ${GOBGP}/api \
--go_out=plugins=grpc:${GOBGP}/api \
${GOBGP}/api/gobgp.proto \
${GOBGP}/api/attribute.proto \
${GOBGP}/api/capability.proto
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Diffstat (limited to 'api')
-rw-r--r-- | api/capability.go | 288 | ||||
-rw-r--r-- | api/capability.pb.go | 379 | ||||
-rw-r--r-- | api/capability.proto | 100 | ||||
-rw-r--r-- | api/capability_test.go | 216 | ||||
-rw-r--r-- | api/gobgp.pb.go | 18 |
5 files changed, 1000 insertions, 1 deletions
diff --git a/api/capability.go b/api/capability.go new file mode 100644 index 00000000..80e16c6f --- /dev/null +++ b/api/capability.go @@ -0,0 +1,288 @@ +// Copyright (C) 2018 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 gobgpapi + +import ( + "fmt" + + proto "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + "github.com/golang/protobuf/ptypes/any" + + "github.com/osrg/gobgp/packet/bgp" +) + +func NewMultiProtocolCapability(a *bgp.CapMultiProtocol) *MultiProtocolCapability { + return &MultiProtocolCapability{ + Family: Family(a.CapValue), + } +} + +func (a *MultiProtocolCapability) ToNative() (*bgp.CapMultiProtocol, error) { + return bgp.NewCapMultiProtocol(bgp.RouteFamily(a.Family)), nil +} + +func NewRouteRefreshCapability(a *bgp.CapRouteRefresh) *RouteRefreshCapability { + return &RouteRefreshCapability{} +} + +func (a *RouteRefreshCapability) ToNative() (*bgp.CapRouteRefresh, error) { + return bgp.NewCapRouteRefresh(), nil +} + +func NewCarryingLabelInfoCapability(a *bgp.CapCarryingLabelInfo) *CarryingLabelInfoCapability { + return &CarryingLabelInfoCapability{} +} + +func (a *CarryingLabelInfoCapability) ToNative() (*bgp.CapCarryingLabelInfo, error) { + return bgp.NewCapCarryingLabelInfo(), nil +} + +func NewExtendedNexthopCapability(a *bgp.CapExtendedNexthop) *ExtendedNexthopCapability { + tuples := make([]*ExtendedNexthopCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &ExtendedNexthopCapabilityTuple{ + NlriFamily: Family(bgp.AfiSafiToRouteFamily(t.NLRIAFI, uint8(t.NLRISAFI))), + NexthopFamily: Family(bgp.AfiSafiToRouteFamily(t.NexthopAFI, bgp.SAFI_UNICAST)), + }) + } + return &ExtendedNexthopCapability{ + Tuples: tuples, + } +} + +func (a *ExtendedNexthopCapability) ToNative() (*bgp.CapExtendedNexthop, error) { + tuples := make([]*bgp.CapExtendedNexthopTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + var nhAfi uint16 + switch t.NexthopFamily { + case Family_IPv4: + nhAfi = bgp.AFI_IP + case Family_IPv6: + nhAfi = bgp.AFI_IP6 + default: + return nil, fmt.Errorf("invalid address family for nexthop afi in extended nexthop capability: %s", t.NexthopFamily) + } + tuples = append(tuples, bgp.NewCapExtendedNexthopTuple(bgp.RouteFamily(t.NlriFamily), nhAfi)) + } + return bgp.NewCapExtendedNexthop(tuples), nil +} + +func NewGracefulRestartCapability(a *bgp.CapGracefulRestart) *GracefulRestartCapability { + tuples := make([]*GracefulRestartCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &GracefulRestartCapabilityTuple{ + Family: Family(bgp.AfiSafiToRouteFamily(t.AFI, uint8(t.SAFI))), + Flags: uint32(t.Flags), + }) + } + return &GracefulRestartCapability{ + Flags: uint32(a.Flags), + Time: uint32(a.Time), + Tuples: tuples, + } +} + +func (a *GracefulRestartCapability) ToNative() (*bgp.CapGracefulRestart, error) { + tuples := make([]*bgp.CapGracefulRestartTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + var forward bool + if t.Flags&0x80 > 0 { + forward = true + } + tuples = append(tuples, bgp.NewCapGracefulRestartTuple(bgp.RouteFamily(t.Family), forward)) + } + var restarting bool + if a.Flags&0x08 > 0 { + restarting = true + } + var notification bool + if a.Flags&0x04 > 0 { + notification = true + } + return bgp.NewCapGracefulRestart(restarting, notification, uint16(a.Time), tuples), nil +} + +func NewFourOctetASNumberCapability(a *bgp.CapFourOctetASNumber) *FourOctetASNumberCapability { + return &FourOctetASNumberCapability{ + As: a.CapValue, + } +} + +func (a *FourOctetASNumberCapability) ToNative() (*bgp.CapFourOctetASNumber, error) { + return bgp.NewCapFourOctetASNumber(a.As), nil +} + +func NewAddPathCapability(a *bgp.CapAddPath) *AddPathCapability { + tuples := make([]*AddPathCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &AddPathCapabilityTuple{ + Family: Family(t.RouteFamily), + Mode: AddPathMode(t.Mode), + }) + } + return &AddPathCapability{ + Tuples: tuples, + } +} + +func (a *AddPathCapability) ToNative() (*bgp.CapAddPath, error) { + tuples := make([]*bgp.CapAddPathTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, bgp.NewCapAddPathTuple(bgp.RouteFamily(t.Family), bgp.BGPAddPathMode(t.Mode))) + } + return bgp.NewCapAddPath(tuples), nil +} + +func NewEnhancedRouteRefreshCapability(a *bgp.CapEnhancedRouteRefresh) *EnhancedRouteRefreshCapability { + return &EnhancedRouteRefreshCapability{} +} + +func (a *EnhancedRouteRefreshCapability) ToNative() (*bgp.CapEnhancedRouteRefresh, error) { + return bgp.NewCapEnhancedRouteRefresh(), nil +} + +func NewLongLivedGracefulRestartCapability(a *bgp.CapLongLivedGracefulRestart) *LongLivedGracefulRestartCapability { + tuples := make([]*LongLivedGracefulRestartCapabilityTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + tuples = append(tuples, &LongLivedGracefulRestartCapabilityTuple{ + Family: Family(bgp.AfiSafiToRouteFamily(t.AFI, uint8(t.SAFI))), + Flags: uint32(t.Flags), + Time: t.RestartTime, + }) + } + return &LongLivedGracefulRestartCapability{ + Tuples: tuples, + } +} + +func (a *LongLivedGracefulRestartCapability) ToNative() (*bgp.CapLongLivedGracefulRestart, error) { + tuples := make([]*bgp.CapLongLivedGracefulRestartTuple, 0, len(a.Tuples)) + for _, t := range a.Tuples { + var forward bool + if t.Flags&0x80 > 0 { + forward = true + } + tuples = append(tuples, bgp.NewCapLongLivedGracefulRestartTuple(bgp.RouteFamily(t.Family), forward, t.Time)) + } + return bgp.NewCapLongLivedGracefulRestart(tuples), nil +} + +func NewRouteRefreshCiscoCapability(a *bgp.CapRouteRefreshCisco) *RouteRefreshCiscoCapability { + return &RouteRefreshCiscoCapability{} +} + +func (a *RouteRefreshCiscoCapability) ToNative() (*bgp.CapRouteRefreshCisco, error) { + return bgp.NewCapRouteRefreshCisco(), nil +} + +func NewUnknownCapability(a *bgp.CapUnknown) *UnknownCapability { + return &UnknownCapability{ + Code: uint32(a.CapCode), + Value: a.CapValue, + } +} + +func (a *UnknownCapability) ToNative() (*bgp.CapUnknown, error) { + return bgp.NewCapUnknown(bgp.BGPCapabilityCode(a.Code), a.Value), nil +} + +func MarshalCapability(value bgp.ParameterCapabilityInterface) (*any.Any, error) { + var m proto.Message + switch n := value.(type) { + case *bgp.CapMultiProtocol: + m = NewMultiProtocolCapability(n) + case *bgp.CapRouteRefresh: + m = NewRouteRefreshCapability(n) + case *bgp.CapCarryingLabelInfo: + m = NewCarryingLabelInfoCapability(n) + case *bgp.CapExtendedNexthop: + m = NewExtendedNexthopCapability(n) + case *bgp.CapGracefulRestart: + m = NewGracefulRestartCapability(n) + case *bgp.CapFourOctetASNumber: + m = NewFourOctetASNumberCapability(n) + case *bgp.CapAddPath: + m = NewAddPathCapability(n) + case *bgp.CapEnhancedRouteRefresh: + m = NewEnhancedRouteRefreshCapability(n) + case *bgp.CapLongLivedGracefulRestart: + m = NewLongLivedGracefulRestartCapability(n) + case *bgp.CapRouteRefreshCisco: + m = NewRouteRefreshCiscoCapability(n) + case *bgp.CapUnknown: + m = NewUnknownCapability(n) + default: + return nil, fmt.Errorf("invalid capability type to marshal: %+v", value) + } + return ptypes.MarshalAny(m) +} + +func MarshalCapabilities(values []bgp.ParameterCapabilityInterface) ([]*any.Any, error) { + caps := make([]*any.Any, 0, len(values)) + for _, value := range values { + a, err := MarshalCapability(value) + if err != nil { + return nil, err + } + caps = append(caps, a) + } + return caps, nil +} + +func UnmarshalCapability(a *any.Any) (bgp.ParameterCapabilityInterface, error) { + var value ptypes.DynamicAny + if err := ptypes.UnmarshalAny(a, &value); err != nil { + return nil, fmt.Errorf("failed to unmarshal capability: %s", err) + } + switch v := value.Message.(type) { + case *MultiProtocolCapability: + return v.ToNative() + case *RouteRefreshCapability: + return v.ToNative() + case *CarryingLabelInfoCapability: + return v.ToNative() + case *ExtendedNexthopCapability: + return v.ToNative() + case *GracefulRestartCapability: + return v.ToNative() + case *FourOctetASNumberCapability: + return v.ToNative() + case *AddPathCapability: + return v.ToNative() + case *EnhancedRouteRefreshCapability: + return v.ToNative() + case *LongLivedGracefulRestartCapability: + return v.ToNative() + case *RouteRefreshCiscoCapability: + return v.ToNative() + case *UnknownCapability: + return v.ToNative() + } + return nil, fmt.Errorf("invalid capability type to unmarshal: %s", a.TypeUrl) +} + +func UnmarshalCapabilities(values []*any.Any) ([]bgp.ParameterCapabilityInterface, error) { + caps := make([]bgp.ParameterCapabilityInterface, 0, len(values)) + for _, value := range values { + c, err := UnmarshalCapability(value) + if err != nil { + return nil, err + } + caps = append(caps, c) + } + return caps, nil +} diff --git a/api/capability.pb.go b/api/capability.pb.go new file mode 100644 index 00000000..9e468509 --- /dev/null +++ b/api/capability.pb.go @@ -0,0 +1,379 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: capability.proto + +package gobgpapi + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type AddPathMode int32 + +const ( + AddPathMode_MODE_NONE AddPathMode = 0 + AddPathMode_MODE_RECEIVE AddPathMode = 1 + AddPathMode_MODE_SEND AddPathMode = 2 + AddPathMode_MODE_BOTH AddPathMode = 3 +) + +var AddPathMode_name = map[int32]string{ + 0: "MODE_NONE", + 1: "MODE_RECEIVE", + 2: "MODE_SEND", + 3: "MODE_BOTH", +} +var AddPathMode_value = map[string]int32{ + "MODE_NONE": 0, + "MODE_RECEIVE": 1, + "MODE_SEND": 2, + "MODE_BOTH": 3, +} + +func (x AddPathMode) String() string { + return proto.EnumName(AddPathMode_name, int32(x)) +} +func (AddPathMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } + +type MultiProtocolCapability struct { + Family Family `protobuf:"varint,1,opt,name=family,enum=gobgpapi.Family" json:"family,omitempty"` +} + +func (m *MultiProtocolCapability) Reset() { *m = MultiProtocolCapability{} } +func (m *MultiProtocolCapability) String() string { return proto.CompactTextString(m) } +func (*MultiProtocolCapability) ProtoMessage() {} +func (*MultiProtocolCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } + +func (m *MultiProtocolCapability) GetFamily() Family { + if m != nil { + return m.Family + } + return Family_RESERVED +} + +type RouteRefreshCapability struct { +} + +func (m *RouteRefreshCapability) Reset() { *m = RouteRefreshCapability{} } +func (m *RouteRefreshCapability) String() string { return proto.CompactTextString(m) } +func (*RouteRefreshCapability) ProtoMessage() {} +func (*RouteRefreshCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} } + +type CarryingLabelInfoCapability struct { +} + +func (m *CarryingLabelInfoCapability) Reset() { *m = CarryingLabelInfoCapability{} } +func (m *CarryingLabelInfoCapability) String() string { return proto.CompactTextString(m) } +func (*CarryingLabelInfoCapability) ProtoMessage() {} +func (*CarryingLabelInfoCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{2} } + +type ExtendedNexthopCapabilityTuple struct { + NlriFamily Family `protobuf:"varint,1,opt,name=nlri_family,json=nlriFamily,enum=gobgpapi.Family" json:"nlri_family,omitempty"` + // Nexthop AFI must be either + // gobgp.IPv4 or + // gobgp.IPv6. + NexthopFamily Family `protobuf:"varint,2,opt,name=nexthop_family,json=nexthopFamily,enum=gobgpapi.Family" json:"nexthop_family,omitempty"` +} + +func (m *ExtendedNexthopCapabilityTuple) Reset() { *m = ExtendedNexthopCapabilityTuple{} } +func (m *ExtendedNexthopCapabilityTuple) String() string { return proto.CompactTextString(m) } +func (*ExtendedNexthopCapabilityTuple) ProtoMessage() {} +func (*ExtendedNexthopCapabilityTuple) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{3} } + +func (m *ExtendedNexthopCapabilityTuple) GetNlriFamily() Family { + if m != nil { + return m.NlriFamily + } + return Family_RESERVED +} + +func (m *ExtendedNexthopCapabilityTuple) GetNexthopFamily() Family { + if m != nil { + return m.NexthopFamily + } + return Family_RESERVED +} + +type ExtendedNexthopCapability struct { + Tuples []*ExtendedNexthopCapabilityTuple `protobuf:"bytes,1,rep,name=tuples" json:"tuples,omitempty"` +} + +func (m *ExtendedNexthopCapability) Reset() { *m = ExtendedNexthopCapability{} } +func (m *ExtendedNexthopCapability) String() string { return proto.CompactTextString(m) } +func (*ExtendedNexthopCapability) ProtoMessage() {} +func (*ExtendedNexthopCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{4} } + +func (m *ExtendedNexthopCapability) GetTuples() []*ExtendedNexthopCapabilityTuple { + if m != nil { + return m.Tuples + } + return nil +} + +type GracefulRestartCapabilityTuple struct { + Family Family `protobuf:"varint,1,opt,name=family,enum=gobgpapi.Family" json:"family,omitempty"` + Flags uint32 `protobuf:"varint,2,opt,name=flags" json:"flags,omitempty"` +} + +func (m *GracefulRestartCapabilityTuple) Reset() { *m = GracefulRestartCapabilityTuple{} } +func (m *GracefulRestartCapabilityTuple) String() string { return proto.CompactTextString(m) } +func (*GracefulRestartCapabilityTuple) ProtoMessage() {} +func (*GracefulRestartCapabilityTuple) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{5} } + +func (m *GracefulRestartCapabilityTuple) GetFamily() Family { + if m != nil { + return m.Family + } + return Family_RESERVED +} + +func (m *GracefulRestartCapabilityTuple) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +type GracefulRestartCapability struct { + Flags uint32 `protobuf:"varint,1,opt,name=flags" json:"flags,omitempty"` + Time uint32 `protobuf:"varint,2,opt,name=time" json:"time,omitempty"` + Tuples []*GracefulRestartCapabilityTuple `protobuf:"bytes,3,rep,name=tuples" json:"tuples,omitempty"` +} + +func (m *GracefulRestartCapability) Reset() { *m = GracefulRestartCapability{} } +func (m *GracefulRestartCapability) String() string { return proto.CompactTextString(m) } +func (*GracefulRestartCapability) ProtoMessage() {} +func (*GracefulRestartCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{6} } + +func (m *GracefulRestartCapability) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +func (m *GracefulRestartCapability) GetTime() uint32 { + if m != nil { + return m.Time + } + return 0 +} + +func (m *GracefulRestartCapability) GetTuples() []*GracefulRestartCapabilityTuple { + if m != nil { + return m.Tuples + } + return nil +} + +type FourOctetASNumberCapability struct { + As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"` +} + +func (m *FourOctetASNumberCapability) Reset() { *m = FourOctetASNumberCapability{} } +func (m *FourOctetASNumberCapability) String() string { return proto.CompactTextString(m) } +func (*FourOctetASNumberCapability) ProtoMessage() {} +func (*FourOctetASNumberCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{7} } + +func (m *FourOctetASNumberCapability) GetAs() uint32 { + if m != nil { + return m.As + } + return 0 +} + +type AddPathCapabilityTuple struct { + Family Family `protobuf:"varint,1,opt,name=family,enum=gobgpapi.Family" json:"family,omitempty"` + Mode AddPathMode `protobuf:"varint,2,opt,name=mode,enum=gobgpapi.AddPathMode" json:"mode,omitempty"` +} + +func (m *AddPathCapabilityTuple) Reset() { *m = AddPathCapabilityTuple{} } +func (m *AddPathCapabilityTuple) String() string { return proto.CompactTextString(m) } +func (*AddPathCapabilityTuple) ProtoMessage() {} +func (*AddPathCapabilityTuple) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{8} } + +func (m *AddPathCapabilityTuple) GetFamily() Family { + if m != nil { + return m.Family + } + return Family_RESERVED +} + +func (m *AddPathCapabilityTuple) GetMode() AddPathMode { + if m != nil { + return m.Mode + } + return AddPathMode_MODE_NONE +} + +type AddPathCapability struct { + Tuples []*AddPathCapabilityTuple `protobuf:"bytes,1,rep,name=tuples" json:"tuples,omitempty"` +} + +func (m *AddPathCapability) Reset() { *m = AddPathCapability{} } +func (m *AddPathCapability) String() string { return proto.CompactTextString(m) } +func (*AddPathCapability) ProtoMessage() {} +func (*AddPathCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{9} } + +func (m *AddPathCapability) GetTuples() []*AddPathCapabilityTuple { + if m != nil { + return m.Tuples + } + return nil +} + +type EnhancedRouteRefreshCapability struct { +} + +func (m *EnhancedRouteRefreshCapability) Reset() { *m = EnhancedRouteRefreshCapability{} } +func (m *EnhancedRouteRefreshCapability) String() string { return proto.CompactTextString(m) } +func (*EnhancedRouteRefreshCapability) ProtoMessage() {} +func (*EnhancedRouteRefreshCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{10} } + +type LongLivedGracefulRestartCapabilityTuple struct { + Family Family `protobuf:"varint,1,opt,name=family,enum=gobgpapi.Family" json:"family,omitempty"` + Flags uint32 `protobuf:"varint,2,opt,name=flags" json:"flags,omitempty"` + Time uint32 `protobuf:"varint,3,opt,name=time" json:"time,omitempty"` +} + +func (m *LongLivedGracefulRestartCapabilityTuple) Reset() { + *m = LongLivedGracefulRestartCapabilityTuple{} +} +func (m *LongLivedGracefulRestartCapabilityTuple) String() string { return proto.CompactTextString(m) } +func (*LongLivedGracefulRestartCapabilityTuple) ProtoMessage() {} +func (*LongLivedGracefulRestartCapabilityTuple) Descriptor() ([]byte, []int) { + return fileDescriptor2, []int{11} +} + +func (m *LongLivedGracefulRestartCapabilityTuple) GetFamily() Family { + if m != nil { + return m.Family + } + return Family_RESERVED +} + +func (m *LongLivedGracefulRestartCapabilityTuple) GetFlags() uint32 { + if m != nil { + return m.Flags + } + return 0 +} + +func (m *LongLivedGracefulRestartCapabilityTuple) GetTime() uint32 { + if m != nil { + return m.Time + } + return 0 +} + +type LongLivedGracefulRestartCapability struct { + Tuples []*LongLivedGracefulRestartCapabilityTuple `protobuf:"bytes,1,rep,name=tuples" json:"tuples,omitempty"` +} + +func (m *LongLivedGracefulRestartCapability) Reset() { *m = LongLivedGracefulRestartCapability{} } +func (m *LongLivedGracefulRestartCapability) String() string { return proto.CompactTextString(m) } +func (*LongLivedGracefulRestartCapability) ProtoMessage() {} +func (*LongLivedGracefulRestartCapability) Descriptor() ([]byte, []int) { + return fileDescriptor2, []int{12} +} + +func (m *LongLivedGracefulRestartCapability) GetTuples() []*LongLivedGracefulRestartCapabilityTuple { + if m != nil { + return m.Tuples + } + return nil +} + +type RouteRefreshCiscoCapability struct { +} + +func (m *RouteRefreshCiscoCapability) Reset() { *m = RouteRefreshCiscoCapability{} } +func (m *RouteRefreshCiscoCapability) String() string { return proto.CompactTextString(m) } +func (*RouteRefreshCiscoCapability) ProtoMessage() {} +func (*RouteRefreshCiscoCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{13} } + +type UnknownCapability struct { + Code uint32 `protobuf:"varint,1,opt,name=code" json:"code,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *UnknownCapability) Reset() { *m = UnknownCapability{} } +func (m *UnknownCapability) String() string { return proto.CompactTextString(m) } +func (*UnknownCapability) ProtoMessage() {} +func (*UnknownCapability) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{14} } + +func (m *UnknownCapability) GetCode() uint32 { + if m != nil { + return m.Code + } + return 0 +} + +func (m *UnknownCapability) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func init() { + proto.RegisterType((*MultiProtocolCapability)(nil), "gobgpapi.MultiProtocolCapability") + proto.RegisterType((*RouteRefreshCapability)(nil), "gobgpapi.RouteRefreshCapability") + proto.RegisterType((*CarryingLabelInfoCapability)(nil), "gobgpapi.CarryingLabelInfoCapability") + proto.RegisterType((*ExtendedNexthopCapabilityTuple)(nil), "gobgpapi.ExtendedNexthopCapabilityTuple") + proto.RegisterType((*ExtendedNexthopCapability)(nil), "gobgpapi.ExtendedNexthopCapability") + proto.RegisterType((*GracefulRestartCapabilityTuple)(nil), "gobgpapi.GracefulRestartCapabilityTuple") + proto.RegisterType((*GracefulRestartCapability)(nil), "gobgpapi.GracefulRestartCapability") + proto.RegisterType((*FourOctetASNumberCapability)(nil), "gobgpapi.FourOctetASNumberCapability") + proto.RegisterType((*AddPathCapabilityTuple)(nil), "gobgpapi.AddPathCapabilityTuple") + proto.RegisterType((*AddPathCapability)(nil), "gobgpapi.AddPathCapability") + proto.RegisterType((*EnhancedRouteRefreshCapability)(nil), "gobgpapi.EnhancedRouteRefreshCapability") + proto.RegisterType((*LongLivedGracefulRestartCapabilityTuple)(nil), "gobgpapi.LongLivedGracefulRestartCapabilityTuple") + proto.RegisterType((*LongLivedGracefulRestartCapability)(nil), "gobgpapi.LongLivedGracefulRestartCapability") + proto.RegisterType((*RouteRefreshCiscoCapability)(nil), "gobgpapi.RouteRefreshCiscoCapability") + proto.RegisterType((*UnknownCapability)(nil), "gobgpapi.UnknownCapability") + proto.RegisterEnum("gobgpapi.AddPathMode", AddPathMode_name, AddPathMode_value) +} + +func init() { proto.RegisterFile("capability.proto", fileDescriptor2) } + +var fileDescriptor2 = []byte{ + // 520 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6f, 0xd3, 0x4e, + 0x10, 0xfd, 0x39, 0xc9, 0x2f, 0x82, 0x49, 0x13, 0xb9, 0x2b, 0x28, 0x29, 0x51, 0xa3, 0x68, 0x2f, + 0x04, 0x24, 0x22, 0xb5, 0x1c, 0xe0, 0x82, 0x44, 0x49, 0x5d, 0x88, 0x94, 0x8f, 0xca, 0x2d, 0xdc, + 0x50, 0xd9, 0xd8, 0x6b, 0x67, 0xc5, 0x7a, 0xd7, 0xb2, 0xd7, 0xa5, 0x39, 0x70, 0xe6, 0xc2, 0x1f, + 0x8d, 0xfc, 0x11, 0xdb, 0xa4, 0x72, 0x5b, 0x21, 0x71, 0x9b, 0xf1, 0xce, 0xbc, 0x79, 0x6f, 0xde, + 0xae, 0x41, 0xb7, 0x88, 0x4f, 0x96, 0x8c, 0x33, 0xb5, 0x1e, 0xf9, 0x81, 0x54, 0x12, 0x3d, 0x70, + 0xe5, 0xd2, 0xf5, 0x89, 0xcf, 0x9e, 0xb6, 0x92, 0x28, 0xfd, 0x8c, 0xc7, 0xf0, 0x64, 0x16, 0x71, + 0xc5, 0xce, 0xe2, 0xcc, 0x92, 0x7c, 0x9c, 0xf7, 0xa1, 0x21, 0x34, 0x1d, 0xe2, 0x31, 0xbe, 0xee, + 0x6a, 0x03, 0x6d, 0xd8, 0x39, 0xd2, 0x47, 0x1b, 0x88, 0xd1, 0x69, 0xf2, 0xdd, 0xcc, 0xce, 0x71, + 0x17, 0xf6, 0x4c, 0x19, 0x29, 0x6a, 0x52, 0x27, 0xa0, 0xe1, 0xaa, 0xc0, 0xc0, 0x07, 0xd0, 0x1b, + 0x93, 0x20, 0x58, 0x33, 0xe1, 0x4e, 0xc9, 0x92, 0xf2, 0x89, 0x70, 0x64, 0xe9, 0xf8, 0x97, 0x06, + 0x7d, 0xe3, 0x5a, 0x51, 0x61, 0x53, 0x7b, 0x4e, 0xaf, 0xd5, 0x4a, 0xfa, 0xc5, 0xe9, 0x45, 0xe4, + 0x73, 0x8a, 0x0e, 0xa1, 0x25, 0x78, 0xc0, 0x2e, 0xef, 0xa0, 0x02, 0x71, 0x51, 0x1a, 0xa3, 0xd7, + 0xd0, 0x11, 0x29, 0xd8, 0xa6, 0xab, 0x56, 0xd1, 0xd5, 0xce, 0xea, 0xd2, 0x14, 0x7f, 0x81, 0xfd, + 0x4a, 0x36, 0xe8, 0x1d, 0x34, 0x55, 0xcc, 0x28, 0xec, 0x6a, 0x83, 0xfa, 0xb0, 0x75, 0x34, 0x2c, + 0xd0, 0x6e, 0x97, 0x60, 0x66, 0x7d, 0xf8, 0x2b, 0xf4, 0x3f, 0x04, 0xc4, 0xa2, 0x4e, 0xc4, 0x4d, + 0x1a, 0x2a, 0x12, 0xa8, 0x6d, 0xb1, 0xf7, 0x5e, 0x39, 0x7a, 0x04, 0xff, 0x3b, 0x9c, 0xb8, 0x61, + 0x22, 0xad, 0x6d, 0xa6, 0x09, 0xfe, 0xa9, 0xc1, 0x7e, 0xe5, 0x88, 0xa2, 0x47, 0x2b, 0xf5, 0x20, + 0x04, 0x0d, 0xc5, 0x3c, 0x9a, 0x01, 0x25, 0x71, 0x49, 0x6b, 0x7d, 0x5b, 0xeb, 0xed, 0x0a, 0x72, + 0xad, 0x2f, 0xa1, 0x77, 0x2a, 0xa3, 0x60, 0x61, 0x29, 0xaa, 0x8e, 0xcf, 0xe7, 0x91, 0xb7, 0xa4, + 0x41, 0x89, 0x4a, 0x07, 0x6a, 0x64, 0xc3, 0xa3, 0x46, 0x42, 0xec, 0xc1, 0xde, 0xb1, 0x6d, 0x9f, + 0x11, 0xb5, 0xfa, 0xfb, 0x95, 0x3c, 0x87, 0x86, 0x27, 0x6d, 0x9a, 0x99, 0xfd, 0xb8, 0xa8, 0xcb, + 0x90, 0x67, 0xd2, 0xa6, 0x66, 0x52, 0x82, 0x67, 0xb0, 0x7b, 0x63, 0x1c, 0x7a, 0xb3, 0x65, 0xf0, + 0xe0, 0x06, 0x42, 0x95, 0xd8, 0x01, 0xf4, 0x0d, 0xb1, 0x22, 0xc2, 0xa2, 0x76, 0xc5, 0x3b, 0xf8, + 0x01, 0xcf, 0xa6, 0x52, 0xb8, 0x53, 0x76, 0x45, 0xed, 0x7f, 0x7b, 0x07, 0x72, 0x3f, 0xeb, 0x85, + 0x9f, 0x58, 0x02, 0xbe, 0x7b, 0x3c, 0x9a, 0x6c, 0x2d, 0xe0, 0xb0, 0x98, 0x7c, 0x4f, 0xf2, 0xf9, + 0x46, 0x0e, 0xa0, 0xf7, 0xc7, 0x26, 0x58, 0x68, 0x95, 0xdf, 0xfd, 0x5b, 0xd8, 0xfd, 0x24, 0xbe, + 0x09, 0xf9, 0x5d, 0x94, 0xc6, 0x23, 0x68, 0x58, 0xb1, 0x7f, 0xe9, 0xad, 0x48, 0xe2, 0x58, 0xe2, + 0x15, 0xe1, 0x51, 0x6a, 0xea, 0x8e, 0x99, 0x26, 0x2f, 0xa6, 0xd0, 0x2a, 0x79, 0x8a, 0xda, 0xf0, + 0x70, 0xb6, 0x38, 0x31, 0x2e, 0xe7, 0x8b, 0xb9, 0xa1, 0xff, 0x87, 0x74, 0xd8, 0x49, 0x52, 0xd3, + 0x18, 0x1b, 0x93, 0xcf, 0x86, 0xae, 0xe5, 0x05, 0xe7, 0xc6, 0xfc, 0x44, 0xaf, 0xe5, 0xe9, 0xfb, + 0xc5, 0xc5, 0x47, 0xbd, 0xbe, 0x6c, 0x26, 0x7f, 0xc2, 0x57, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, + 0xd6, 0xbd, 0xd3, 0xc3, 0x34, 0x05, 0x00, 0x00, +} diff --git a/api/capability.proto b/api/capability.proto new file mode 100644 index 00000000..78504b5d --- /dev/null +++ b/api/capability.proto @@ -0,0 +1,100 @@ +// Copyright (C) 2018 Nippon Telegraph and Telephone Corporation. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation files +// (the "Software"), to deal in the Software without restriction, +// including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, +// and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +syntax = "proto3"; + +import "gobgp.proto"; + +package gobgpapi; + +enum AddPathMode { + MODE_NONE = 0; + MODE_RECEIVE = 1; + MODE_SEND = 2; + MODE_BOTH = 3; +} + +message MultiProtocolCapability { + gobgpapi.Family family = 1; +} + +message RouteRefreshCapability { +} + +message CarryingLabelInfoCapability { +} + +message ExtendedNexthopCapabilityTuple { + gobgpapi.Family nlri_family = 1; + // Nexthop AFI must be either + // gobgp.IPv4 or + // gobgp.IPv6. + gobgpapi.Family nexthop_family = 2; +} + +message ExtendedNexthopCapability { + repeated ExtendedNexthopCapabilityTuple tuples = 1; +} + +message GracefulRestartCapabilityTuple { + gobgpapi.Family family = 1; + uint32 flags = 2; +} + +message GracefulRestartCapability { + uint32 flags = 1; + uint32 time = 2; + repeated GracefulRestartCapabilityTuple tuples = 3; +} + +message FourOctetASNumberCapability { + uint32 as = 1; +} + +message AddPathCapabilityTuple { + gobgpapi.Family family = 1; + AddPathMode mode = 2; +} + +message AddPathCapability { + repeated AddPathCapabilityTuple tuples = 1; +} + +message EnhancedRouteRefreshCapability { +} + +message LongLivedGracefulRestartCapabilityTuple { + gobgpapi.Family family = 1; + uint32 flags = 2; + uint32 time = 3; +} + +message LongLivedGracefulRestartCapability { + repeated LongLivedGracefulRestartCapabilityTuple tuples = 1; +} + +message RouteRefreshCiscoCapability { +} + +message UnknownCapability { + uint32 code = 1; + bytes value = 2; +}
\ No newline at end of file diff --git a/api/capability_test.go b/api/capability_test.go new file mode 100644 index 00000000..e092c836 --- /dev/null +++ b/api/capability_test.go @@ -0,0 +1,216 @@ +// Copyright (C) 2018 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 gobgpapi + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/osrg/gobgp/packet/bgp" +) + +func Test_MultiProtocolCapability(t *testing.T) { + assert := assert.New(t) + + input := &MultiProtocolCapability{ + Family: Family_IPv4, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(bgp.RF_IPv4_UC, n.CapValue) + + output := NewMultiProtocolCapability(n) + assert.Equal(input, output) +} + +func Test_RouteRefreshCapability(t *testing.T) { + assert := assert.New(t) + + input := &RouteRefreshCapability{} + + n, err := input.ToNative() + assert.Nil(err) + + output := NewRouteRefreshCapability(n) + assert.Equal(input, output) +} + +func Test_CarryingLabelInfoCapability(t *testing.T) { + assert := assert.New(t) + + input := &CarryingLabelInfoCapability{} + + n, err := input.ToNative() + assert.Nil(err) + + output := NewCarryingLabelInfoCapability(n) + assert.Equal(input, output) +} + +func Test_ExtendedNexthopCapability(t *testing.T) { + assert := assert.New(t) + + input := &ExtendedNexthopCapability{ + Tuples: []*ExtendedNexthopCapabilityTuple{ + { + NlriFamily: Family_IPv4, + NexthopFamily: Family_IPv6, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(1, len(n.Tuples)) + assert.Equal(uint16(bgp.AFI_IP), n.Tuples[0].NLRIAFI) + assert.Equal(uint16(bgp.SAFI_UNICAST), n.Tuples[0].NLRISAFI) + assert.Equal(uint16(bgp.AFI_IP6), n.Tuples[0].NexthopAFI) + + output := NewExtendedNexthopCapability(n) + assert.Equal(input, output) +} + +func Test_GracefulRestartCapability(t *testing.T) { + assert := assert.New(t) + + input := &GracefulRestartCapability{ + Flags: 0x08 | 0x04, // restarting|notification + Time: 90, + Tuples: []*GracefulRestartCapabilityTuple{ + { + Family: Family_IPv4, + Flags: 0x80, // forward + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(1, len(n.Tuples)) + assert.Equal(uint8(0x08|0x04), n.Flags) + assert.Equal(uint16(90), n.Time) + assert.Equal(uint16(bgp.AFI_IP), n.Tuples[0].AFI) + assert.Equal(uint8(bgp.SAFI_UNICAST), n.Tuples[0].SAFI) + assert.Equal(uint8(0x80), n.Tuples[0].Flags) + + output := NewGracefulRestartCapability(n) + assert.Equal(input, output) +} + +func Test_FourOctetASNumberCapability(t *testing.T) { + assert := assert.New(t) + + input := &FourOctetASNumberCapability{ + As: 100, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(uint32(100), n.CapValue) + + output := NewFourOctetASNumberCapability(n) + assert.Equal(input, output) +} + +func Test_AddPathCapability(t *testing.T) { + assert := assert.New(t) + + input := &AddPathCapability{ + Tuples: []*AddPathCapabilityTuple{ + { + Family: Family_IPv4, + Mode: AddPathMode_MODE_BOTH, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(1, len(n.Tuples)) + assert.Equal(bgp.RF_IPv4_UC, n.Tuples[0].RouteFamily) + assert.Equal(bgp.BGP_ADD_PATH_BOTH, n.Tuples[0].Mode) + + output := NewAddPathCapability(n) + assert.Equal(input, output) +} + +func Test_EnhancedRouteRefreshCapability(t *testing.T) { + assert := assert.New(t) + + input := &EnhancedRouteRefreshCapability{} + + n, err := input.ToNative() + assert.Nil(err) + + output := NewEnhancedRouteRefreshCapability(n) + assert.Equal(input, output) +} + +func Test_LongLivedGracefulRestartCapability(t *testing.T) { + assert := assert.New(t) + + input := &LongLivedGracefulRestartCapability{ + Tuples: []*LongLivedGracefulRestartCapabilityTuple{ + { + Family: Family_IPv4, + Flags: 0x80, // forward + Time: 90, + }, + }, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(1, len(n.Tuples)) + assert.Equal(uint16(bgp.AFI_IP), n.Tuples[0].AFI) + assert.Equal(uint8(bgp.SAFI_UNICAST), n.Tuples[0].SAFI) + assert.Equal(uint8(0x80), n.Tuples[0].Flags) + assert.Equal(uint32(90), n.Tuples[0].RestartTime) + + output := NewLongLivedGracefulRestartCapability(n) + assert.Equal(input, output) +} + +func Test_RouteRefreshCiscoCapability(t *testing.T) { + assert := assert.New(t) + + input := &RouteRefreshCiscoCapability{} + + n, err := input.ToNative() + assert.Nil(err) + + output := NewRouteRefreshCiscoCapability(n) + assert.Equal(input, output) +} + +func Test_UnknownCapability(t *testing.T) { + assert := assert.New(t) + + input := &UnknownCapability{ + Code: 0xff, + Value: []byte{0x11, 0x22, 0x33, 0x44}, + } + + n, err := input.ToNative() + assert.Nil(err) + assert.Equal(bgp.BGPCapabilityCode(0xff), n.CapCode) + assert.Equal([]byte{0x11, 0x22, 0x33, 0x44}, n.CapValue) + + output := NewUnknownCapability(n) + assert.Equal(input, output) +} diff --git a/api/gobgp.pb.go b/api/gobgp.pb.go index 4bc57beb..b35dc3a1 100644 --- a/api/gobgp.pb.go +++ b/api/gobgp.pb.go @@ -7,6 +7,7 @@ Package gobgpapi is a generated protocol buffer package. It is generated from these files: gobgp.proto attribute.proto + capability.proto It has these top-level messages: GetNeighborRequest @@ -274,6 +275,21 @@ It has these top-level messages: LargeCommunity LargeCommunitiesAttribute UnknownAttribute + MultiProtocolCapability + RouteRefreshCapability + CarryingLabelInfoCapability + ExtendedNexthopCapabilityTuple + ExtendedNexthopCapability + GracefulRestartCapabilityTuple + GracefulRestartCapability + FourOctetASNumberCapability + AddPathCapabilityTuple + AddPathCapability + EnhancedRouteRefreshCapability + LongLivedGracefulRestartCapabilityTuple + LongLivedGracefulRestartCapability + RouteRefreshCiscoCapability + UnknownCapability */ package gobgpapi @@ -5870,7 +5886,7 @@ func (m *GetRoaResponse) GetRoas() []*Roa { type Vrf struct { Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // Route Distinguisher must be on of + // Route Distinguisher must be one of // RouteDistinguisherTwoOctetAS, // RouteDistinguisherIPAddressAS, // or RouteDistinguisherFourOctetAS. |