update gobgp pkg

This commit is contained in:
Ian Azpiazu
2022-05-16 13:40:57 -04:00
parent 878ee3a63e
commit 80d743ffa5
652 changed files with 136451 additions and 98241 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -176,6 +176,26 @@ message EVPNIPMSIRoute {
google.protobuf.Any rt = 3;
}
// SRPolicyNLRI represents the NLRI for:
// - AFI=1, SAFI=73
// - AFI=2, SAFI=73
message SRPolicyNLRI {
// length field carries the length of NLRI portion expressed in bits
uint32 length = 1;
// distinguisher field carries 4-octet value uniquely identifying the policy
// in the context of <color, endpoint> tuple.
uint32 distinguisher = 2;
// color field carries 4-octet value identifying (with the endpoint) the
// policy. The color is used to match the color of the destination
// prefixes to steer traffic into the SR Policy
uint32 color = 3;
// endpoint field identifies the endpoint of a policy. The Endpoint may
// represent a single node or a set of nodes (e.g., an anycast
// address). The Endpoint is an IPv4 (4-octet) address or an IPv6
// (16-octet) address according to the AFI of the NLRI.
bytes endpoint = 4;
}
// LabeledVPNIPAddressPrefix represents the NLRI for:
// - AFI=1, SAFI=128
// - AFI=2, SAFI=128
@@ -302,13 +322,19 @@ message LsPrefixV6NLRI {
// Based om RFC 7752, Table 1.
enum LsNLRIType {
LS_NLRI_UNKNOWN = 0;
LS_NLRI_NODE = 1;
LS_NLRI_LINK = 2;
LS_NLRI_UNKNOWN = 0; LS_NLRI_NODE = 1; LS_NLRI_LINK = 2;
LS_NLRI_PREFIX_V4 = 3;
LS_NLRI_PREFIX_V6 = 4;
}
enum LsProtocolID {
LS_PROTOCOL_UNKNOWN = 0; LS_PROTOCOL_ISIS_L1 = 1; LS_PROTOCOL_ISIS_L2 = 2;
LS_PROTOCOL_OSPF_V2 = 3;
LS_PROTOCOL_DIRECT = 4;
LS_PROTOCOL_STATIC = 5;
LS_PROTOCOL_OSPF_V3 = 6;
}
// LsAddrPrefix represents the NLRI for:
// - AFI=16388, SAFI=71
message LsAddrPrefix {
@@ -319,6 +345,9 @@ message LsAddrPrefix {
// - LsPrefixV4NLRI
// - LsPrefixV6NLRI
google.protobuf.Any nlri = 2;
uint32 length = 3;
LsProtocolID protocol_id = 4;
uint64 identifier = 5;
}
message MpReachNLRIAttribute {
@@ -340,6 +369,7 @@ message MpReachNLRIAttribute {
// - VPNFlowSpecNLRI
// - OpaqueNLRI
// - LsAddrPrefix
// - SR Policy NLRI
repeated google.protobuf.Any nlris = 3;
}
@@ -370,6 +400,11 @@ message FourOctetAsSpecificExtended {
uint32 local_admin = 4;
}
message LinkBandiwdthExtended {
uint32 as = 1;
float bandwidth = 2;
}
message ValidationExtended { uint32 state = 1; }
message ColorExtended { uint32 color = 1; }
@@ -471,6 +506,127 @@ message TunnelEncapSubTLVProtocol { uint32 protocol = 1; }
message TunnelEncapSubTLVColor { uint32 color = 1; }
message TunnelEncapSubTLVSRPreference {
uint32 flags = 1;
uint32 preference = 2;
}
message TunnelEncapSubTLVSRCandidatePathName { string candidate_path_name = 1; }
message TunnelEncapSubTLVSRPriority { uint32 priority = 1; }
message TunnelEncapSubTLVSRBindingSID {
// bsid must be one of:
// - SRBindingSID
// - SRv6BindingSID
google.protobuf.Any bsid = 1;
}
message SRBindingSID {
bool s_flag = 1;
bool i_flag = 2;
bytes sid = 3;
}
enum SRv6Behavior {
RESERVED = 0; END = 1; END_WITH_PSP = 2; END_WITH_USP = 3;
END_WITH_PSP_USP = 4;
ENDX = 5;
ENDX_WITH_PSP = 6;
ENDX_WITH_USP = 7;
ENDX_WITH_PSP_USP = 8;
ENDT = 9;
ENDT_WITH_PSP = 10;
ENDT_WITH_USP = 11;
ENDT_WITH_PSP_USP = 12;
END_B6_ENCAPS = 14;
END_BM = 15;
END_DX6 = 16;
END_DX4 = 17;
END_DT6 = 18;
END_DT4 = 19;
END_DT46 = 20;
END_DX2 = 21;
END_DX2V = 22;
END_DT2U = 23;
END_DT2M = 24;
END_B6_ENCAPS_Red = 27;
END_WITH_USD = 28;
END_WITH_PSP_USD = 29;
END_WITH_USP_USD = 30;
END_WITH_PSP_USP_USD = 31;
ENDX_WITH_USD = 32;
ENDX_WITH_PSP_USD = 33;
ENDX_WITH_USP_USD = 34;
ENDX_WITH_PSP_USP_USD = 35;
ENDT_WITH_USD = 36;
ENDT_WITH_PSP_USD = 37;
ENDT_WITH_USP_USD = 38;
ENDT_WITH_PSP_USP_USD = 39;
}
message SRv6EndPointBehavior {
SRv6Behavior behavior = 1;
uint32 block_len = 2;
uint32 node_len = 3;
uint32 func_len = 4;
uint32 arg_len = 5;
}
message SRv6BindingSID {
bool s_flag = 1;
bool i_flag = 2;
bool b_flag = 3;
bytes sid = 4;
SRv6EndPointBehavior endpoint_behavior_structure = 5;
}
enum ENLPType { Reserved = 0; Type1 = 1; Type2 = 2; Type3 = 3; Type4 = 4; }
message TunnelEncapSubTLVSRENLP {
uint32 flags = 1;
ENLPType enlp = 2;
}
message SRWeight {
uint32 flags = 1;
uint32 weight = 2;
}
message SegmentFlags {
bool v_flag = 1;
bool a_flag = 2;
bool s_flag = 3;
bool b_flag = 4;
}
message SegmentTypeA {
SegmentFlags flags = 1;
uint32 label = 2;
}
message SegmentTypeB {
SegmentFlags flags = 1;
bytes sid = 2;
SRv6EndPointBehavior endpoint_behavior_structure = 3;
}
message TunnelEncapSubTLVSRSegmentList {
SRWeight weight = 1;
// segments must be one of:
// - SegmentTypeA
// - SegmentTypeB
repeated google.protobuf.Any segments = 2;
}
message TunnelEncapSubTLVEgressEndpoint {
string address = 1;
}
message TunnelEncapSubTLVUDPDestPort {
uint32 port = 1;
}
message TunnelEncapSubTLVUnknown {
uint32 type = 1;
bytes value = 2;
@@ -482,6 +638,7 @@ message TunnelEncapTLV {
// - TunnelEncapSubTLVEncapsulation
// - TunnelEncapSubTLVProtocol
// - TunnelEncapSubTLVColor
// - TunnelEncapSubTLVSRPolicy
// - TunnelEncapSubTLVUnknown
repeated google.protobuf.Any tlvs = 2;
}
@@ -651,4 +808,4 @@ message PrefixSID {
// - SRv6L3ServiceTLV Type 5
// - SRv6L2ServiceTLV Type 6 (not yet implemented)
repeated google.protobuf.Any tlvs = 1;
}
}

View File

@@ -3,15 +3,23 @@
package gobgpapi
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type AddPathMode int32
const (
@@ -27,6 +35,7 @@ var AddPathMode_name = map[int32]string{
2: "MODE_SEND",
3: "MODE_BOTH",
}
var AddPathMode_value = map[string]int32{
"MODE_NONE": 0,
"MODE_RECEIVE": 1,
@@ -37,16 +46,42 @@ var AddPathMode_value = map[string]int32{
func (x AddPathMode) String() string {
return proto.EnumName(AddPathMode_name, int32(x))
}
func (AddPathMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
type MultiProtocolCapability struct {
Family *Family `protobuf:"bytes,1,opt,name=family" json:"family,omitempty"`
func (AddPathMode) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{0}
}
func (m *MultiProtocolCapability) Reset() { *m = MultiProtocolCapability{} }
func (m *MultiProtocolCapability) String() string { return proto.CompactTextString(m) }
func (*MultiProtocolCapability) ProtoMessage() {}
func (*MultiProtocolCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} }
type MultiProtocolCapability struct {
Family *Family `protobuf:"bytes,1,opt,name=family,proto3" json:"family,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *MultiProtocolCapability) Reset() { *m = MultiProtocolCapability{} }
func (m *MultiProtocolCapability) String() string { return proto.CompactTextString(m) }
func (*MultiProtocolCapability) ProtoMessage() {}
func (*MultiProtocolCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{0}
}
func (m *MultiProtocolCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_MultiProtocolCapability.Unmarshal(m, b)
}
func (m *MultiProtocolCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_MultiProtocolCapability.Marshal(b, m, deterministic)
}
func (m *MultiProtocolCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_MultiProtocolCapability.Merge(m, src)
}
func (m *MultiProtocolCapability) XXX_Size() int {
return xxx_messageInfo_MultiProtocolCapability.Size(m)
}
func (m *MultiProtocolCapability) XXX_DiscardUnknown() {
xxx_messageInfo_MultiProtocolCapability.DiscardUnknown(m)
}
var xxx_messageInfo_MultiProtocolCapability proto.InternalMessageInfo
func (m *MultiProtocolCapability) GetFamily() *Family {
if m != nil {
@@ -56,33 +91,102 @@ func (m *MultiProtocolCapability) GetFamily() *Family {
}
type RouteRefreshCapability struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RouteRefreshCapability) Reset() { *m = RouteRefreshCapability{} }
func (m *RouteRefreshCapability) String() string { return proto.CompactTextString(m) }
func (*RouteRefreshCapability) ProtoMessage() {}
func (*RouteRefreshCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} }
func (m *RouteRefreshCapability) Reset() { *m = RouteRefreshCapability{} }
func (m *RouteRefreshCapability) String() string { return proto.CompactTextString(m) }
func (*RouteRefreshCapability) ProtoMessage() {}
func (*RouteRefreshCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{1}
}
func (m *RouteRefreshCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RouteRefreshCapability.Unmarshal(m, b)
}
func (m *RouteRefreshCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RouteRefreshCapability.Marshal(b, m, deterministic)
}
func (m *RouteRefreshCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_RouteRefreshCapability.Merge(m, src)
}
func (m *RouteRefreshCapability) XXX_Size() int {
return xxx_messageInfo_RouteRefreshCapability.Size(m)
}
func (m *RouteRefreshCapability) XXX_DiscardUnknown() {
xxx_messageInfo_RouteRefreshCapability.DiscardUnknown(m)
}
var xxx_messageInfo_RouteRefreshCapability proto.InternalMessageInfo
type CarryingLabelInfoCapability struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CarryingLabelInfoCapability) Reset() { *m = CarryingLabelInfoCapability{} }
func (m *CarryingLabelInfoCapability) String() string { return proto.CompactTextString(m) }
func (*CarryingLabelInfoCapability) ProtoMessage() {}
func (*CarryingLabelInfoCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} }
func (m *CarryingLabelInfoCapability) Reset() { *m = CarryingLabelInfoCapability{} }
func (m *CarryingLabelInfoCapability) String() string { return proto.CompactTextString(m) }
func (*CarryingLabelInfoCapability) ProtoMessage() {}
func (*CarryingLabelInfoCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{2}
}
func (m *CarryingLabelInfoCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CarryingLabelInfoCapability.Unmarshal(m, b)
}
func (m *CarryingLabelInfoCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CarryingLabelInfoCapability.Marshal(b, m, deterministic)
}
func (m *CarryingLabelInfoCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_CarryingLabelInfoCapability.Merge(m, src)
}
func (m *CarryingLabelInfoCapability) XXX_Size() int {
return xxx_messageInfo_CarryingLabelInfoCapability.Size(m)
}
func (m *CarryingLabelInfoCapability) XXX_DiscardUnknown() {
xxx_messageInfo_CarryingLabelInfoCapability.DiscardUnknown(m)
}
var xxx_messageInfo_CarryingLabelInfoCapability proto.InternalMessageInfo
type ExtendedNexthopCapabilityTuple struct {
NlriFamily *Family `protobuf:"bytes,1,opt,name=nlri_family,json=nlriFamily" json:"nlri_family,omitempty"`
NlriFamily *Family `protobuf:"bytes,1,opt,name=nlri_family,json=nlriFamily,proto3" json:"nlri_family,omitempty"`
// Nexthop AFI must be either
// gobgp.IPv4 or
// gobgp.IPv6.
NexthopFamily *Family `protobuf:"bytes,2,opt,name=nexthop_family,json=nexthopFamily" json:"nexthop_family,omitempty"`
NexthopFamily *Family `protobuf:"bytes,2,opt,name=nexthop_family,json=nexthopFamily,proto3" json:"nexthop_family,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ExtendedNexthopCapabilityTuple) Reset() { *m = ExtendedNexthopCapabilityTuple{} }
func (m *ExtendedNexthopCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*ExtendedNexthopCapabilityTuple) ProtoMessage() {}
func (*ExtendedNexthopCapabilityTuple) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} }
func (m *ExtendedNexthopCapabilityTuple) Reset() { *m = ExtendedNexthopCapabilityTuple{} }
func (m *ExtendedNexthopCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*ExtendedNexthopCapabilityTuple) ProtoMessage() {}
func (*ExtendedNexthopCapabilityTuple) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{3}
}
func (m *ExtendedNexthopCapabilityTuple) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ExtendedNexthopCapabilityTuple.Unmarshal(m, b)
}
func (m *ExtendedNexthopCapabilityTuple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ExtendedNexthopCapabilityTuple.Marshal(b, m, deterministic)
}
func (m *ExtendedNexthopCapabilityTuple) XXX_Merge(src proto.Message) {
xxx_messageInfo_ExtendedNexthopCapabilityTuple.Merge(m, src)
}
func (m *ExtendedNexthopCapabilityTuple) XXX_Size() int {
return xxx_messageInfo_ExtendedNexthopCapabilityTuple.Size(m)
}
func (m *ExtendedNexthopCapabilityTuple) XXX_DiscardUnknown() {
xxx_messageInfo_ExtendedNexthopCapabilityTuple.DiscardUnknown(m)
}
var xxx_messageInfo_ExtendedNexthopCapabilityTuple proto.InternalMessageInfo
func (m *ExtendedNexthopCapabilityTuple) GetNlriFamily() *Family {
if m != nil {
@@ -99,13 +203,36 @@ func (m *ExtendedNexthopCapabilityTuple) GetNexthopFamily() *Family {
}
type ExtendedNexthopCapability struct {
Tuples []*ExtendedNexthopCapabilityTuple `protobuf:"bytes,1,rep,name=tuples" json:"tuples,omitempty"`
Tuples []*ExtendedNexthopCapabilityTuple `protobuf:"bytes,1,rep,name=tuples,proto3" json:"tuples,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ExtendedNexthopCapability) Reset() { *m = ExtendedNexthopCapability{} }
func (m *ExtendedNexthopCapability) String() string { return proto.CompactTextString(m) }
func (*ExtendedNexthopCapability) ProtoMessage() {}
func (*ExtendedNexthopCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} }
func (m *ExtendedNexthopCapability) Reset() { *m = ExtendedNexthopCapability{} }
func (m *ExtendedNexthopCapability) String() string { return proto.CompactTextString(m) }
func (*ExtendedNexthopCapability) ProtoMessage() {}
func (*ExtendedNexthopCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{4}
}
func (m *ExtendedNexthopCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ExtendedNexthopCapability.Unmarshal(m, b)
}
func (m *ExtendedNexthopCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ExtendedNexthopCapability.Marshal(b, m, deterministic)
}
func (m *ExtendedNexthopCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_ExtendedNexthopCapability.Merge(m, src)
}
func (m *ExtendedNexthopCapability) XXX_Size() int {
return xxx_messageInfo_ExtendedNexthopCapability.Size(m)
}
func (m *ExtendedNexthopCapability) XXX_DiscardUnknown() {
xxx_messageInfo_ExtendedNexthopCapability.DiscardUnknown(m)
}
var xxx_messageInfo_ExtendedNexthopCapability proto.InternalMessageInfo
func (m *ExtendedNexthopCapability) GetTuples() []*ExtendedNexthopCapabilityTuple {
if m != nil {
@@ -115,14 +242,37 @@ func (m *ExtendedNexthopCapability) GetTuples() []*ExtendedNexthopCapabilityTupl
}
type GracefulRestartCapabilityTuple struct {
Family *Family `protobuf:"bytes,1,opt,name=family" json:"family,omitempty"`
Flags uint32 `protobuf:"varint,2,opt,name=flags" json:"flags,omitempty"`
Family *Family `protobuf:"bytes,1,opt,name=family,proto3" json:"family,omitempty"`
Flags uint32 `protobuf:"varint,2,opt,name=flags,proto3" json:"flags,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GracefulRestartCapabilityTuple) Reset() { *m = GracefulRestartCapabilityTuple{} }
func (m *GracefulRestartCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*GracefulRestartCapabilityTuple) ProtoMessage() {}
func (*GracefulRestartCapabilityTuple) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} }
func (m *GracefulRestartCapabilityTuple) Reset() { *m = GracefulRestartCapabilityTuple{} }
func (m *GracefulRestartCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*GracefulRestartCapabilityTuple) ProtoMessage() {}
func (*GracefulRestartCapabilityTuple) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{5}
}
func (m *GracefulRestartCapabilityTuple) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GracefulRestartCapabilityTuple.Unmarshal(m, b)
}
func (m *GracefulRestartCapabilityTuple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GracefulRestartCapabilityTuple.Marshal(b, m, deterministic)
}
func (m *GracefulRestartCapabilityTuple) XXX_Merge(src proto.Message) {
xxx_messageInfo_GracefulRestartCapabilityTuple.Merge(m, src)
}
func (m *GracefulRestartCapabilityTuple) XXX_Size() int {
return xxx_messageInfo_GracefulRestartCapabilityTuple.Size(m)
}
func (m *GracefulRestartCapabilityTuple) XXX_DiscardUnknown() {
xxx_messageInfo_GracefulRestartCapabilityTuple.DiscardUnknown(m)
}
var xxx_messageInfo_GracefulRestartCapabilityTuple proto.InternalMessageInfo
func (m *GracefulRestartCapabilityTuple) GetFamily() *Family {
if m != nil {
@@ -139,15 +289,38 @@ func (m *GracefulRestartCapabilityTuple) GetFlags() uint32 {
}
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"`
Flags uint32 `protobuf:"varint,1,opt,name=flags,proto3" json:"flags,omitempty"`
Time uint32 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"`
Tuples []*GracefulRestartCapabilityTuple `protobuf:"bytes,3,rep,name=tuples,proto3" json:"tuples,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GracefulRestartCapability) Reset() { *m = GracefulRestartCapability{} }
func (m *GracefulRestartCapability) String() string { return proto.CompactTextString(m) }
func (*GracefulRestartCapability) ProtoMessage() {}
func (*GracefulRestartCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} }
func (m *GracefulRestartCapability) Reset() { *m = GracefulRestartCapability{} }
func (m *GracefulRestartCapability) String() string { return proto.CompactTextString(m) }
func (*GracefulRestartCapability) ProtoMessage() {}
func (*GracefulRestartCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{6}
}
func (m *GracefulRestartCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GracefulRestartCapability.Unmarshal(m, b)
}
func (m *GracefulRestartCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GracefulRestartCapability.Marshal(b, m, deterministic)
}
func (m *GracefulRestartCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_GracefulRestartCapability.Merge(m, src)
}
func (m *GracefulRestartCapability) XXX_Size() int {
return xxx_messageInfo_GracefulRestartCapability.Size(m)
}
func (m *GracefulRestartCapability) XXX_DiscardUnknown() {
xxx_messageInfo_GracefulRestartCapability.DiscardUnknown(m)
}
var xxx_messageInfo_GracefulRestartCapability proto.InternalMessageInfo
func (m *GracefulRestartCapability) GetFlags() uint32 {
if m != nil {
@@ -171,13 +344,36 @@ func (m *GracefulRestartCapability) GetTuples() []*GracefulRestartCapabilityTupl
}
type FourOctetASNumberCapability struct {
As uint32 `protobuf:"varint,1,opt,name=as" json:"as,omitempty"`
As uint32 `protobuf:"varint,1,opt,name=as,proto3" json:"as,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FourOctetASNumberCapability) Reset() { *m = FourOctetASNumberCapability{} }
func (m *FourOctetASNumberCapability) String() string { return proto.CompactTextString(m) }
func (*FourOctetASNumberCapability) ProtoMessage() {}
func (*FourOctetASNumberCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{7} }
func (m *FourOctetASNumberCapability) Reset() { *m = FourOctetASNumberCapability{} }
func (m *FourOctetASNumberCapability) String() string { return proto.CompactTextString(m) }
func (*FourOctetASNumberCapability) ProtoMessage() {}
func (*FourOctetASNumberCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{7}
}
func (m *FourOctetASNumberCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FourOctetASNumberCapability.Unmarshal(m, b)
}
func (m *FourOctetASNumberCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FourOctetASNumberCapability.Marshal(b, m, deterministic)
}
func (m *FourOctetASNumberCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_FourOctetASNumberCapability.Merge(m, src)
}
func (m *FourOctetASNumberCapability) XXX_Size() int {
return xxx_messageInfo_FourOctetASNumberCapability.Size(m)
}
func (m *FourOctetASNumberCapability) XXX_DiscardUnknown() {
xxx_messageInfo_FourOctetASNumberCapability.DiscardUnknown(m)
}
var xxx_messageInfo_FourOctetASNumberCapability proto.InternalMessageInfo
func (m *FourOctetASNumberCapability) GetAs() uint32 {
if m != nil {
@@ -187,14 +383,37 @@ func (m *FourOctetASNumberCapability) GetAs() uint32 {
}
type AddPathCapabilityTuple struct {
Family *Family `protobuf:"bytes,1,opt,name=family" json:"family,omitempty"`
Mode AddPathMode `protobuf:"varint,2,opt,name=mode,enum=gobgpapi.AddPathMode" json:"mode,omitempty"`
Family *Family `protobuf:"bytes,1,opt,name=family,proto3" json:"family,omitempty"`
Mode AddPathMode `protobuf:"varint,2,opt,name=mode,proto3,enum=gobgpapi.AddPathMode" json:"mode,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AddPathCapabilityTuple) Reset() { *m = AddPathCapabilityTuple{} }
func (m *AddPathCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*AddPathCapabilityTuple) ProtoMessage() {}
func (*AddPathCapabilityTuple) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{8} }
func (m *AddPathCapabilityTuple) Reset() { *m = AddPathCapabilityTuple{} }
func (m *AddPathCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*AddPathCapabilityTuple) ProtoMessage() {}
func (*AddPathCapabilityTuple) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{8}
}
func (m *AddPathCapabilityTuple) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddPathCapabilityTuple.Unmarshal(m, b)
}
func (m *AddPathCapabilityTuple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AddPathCapabilityTuple.Marshal(b, m, deterministic)
}
func (m *AddPathCapabilityTuple) XXX_Merge(src proto.Message) {
xxx_messageInfo_AddPathCapabilityTuple.Merge(m, src)
}
func (m *AddPathCapabilityTuple) XXX_Size() int {
return xxx_messageInfo_AddPathCapabilityTuple.Size(m)
}
func (m *AddPathCapabilityTuple) XXX_DiscardUnknown() {
xxx_messageInfo_AddPathCapabilityTuple.DiscardUnknown(m)
}
var xxx_messageInfo_AddPathCapabilityTuple proto.InternalMessageInfo
func (m *AddPathCapabilityTuple) GetFamily() *Family {
if m != nil {
@@ -211,13 +430,36 @@ func (m *AddPathCapabilityTuple) GetMode() AddPathMode {
}
type AddPathCapability struct {
Tuples []*AddPathCapabilityTuple `protobuf:"bytes,1,rep,name=tuples" json:"tuples,omitempty"`
Tuples []*AddPathCapabilityTuple `protobuf:"bytes,1,rep,name=tuples,proto3" json:"tuples,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AddPathCapability) Reset() { *m = AddPathCapability{} }
func (m *AddPathCapability) String() string { return proto.CompactTextString(m) }
func (*AddPathCapability) ProtoMessage() {}
func (*AddPathCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{9} }
func (m *AddPathCapability) Reset() { *m = AddPathCapability{} }
func (m *AddPathCapability) String() string { return proto.CompactTextString(m) }
func (*AddPathCapability) ProtoMessage() {}
func (*AddPathCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{9}
}
func (m *AddPathCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AddPathCapability.Unmarshal(m, b)
}
func (m *AddPathCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AddPathCapability.Marshal(b, m, deterministic)
}
func (m *AddPathCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_AddPathCapability.Merge(m, src)
}
func (m *AddPathCapability) XXX_Size() int {
return xxx_messageInfo_AddPathCapability.Size(m)
}
func (m *AddPathCapability) XXX_DiscardUnknown() {
xxx_messageInfo_AddPathCapability.DiscardUnknown(m)
}
var xxx_messageInfo_AddPathCapability proto.InternalMessageInfo
func (m *AddPathCapability) GetTuples() []*AddPathCapabilityTuple {
if m != nil {
@@ -227,19 +469,43 @@ func (m *AddPathCapability) GetTuples() []*AddPathCapabilityTuple {
}
type EnhancedRouteRefreshCapability struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *EnhancedRouteRefreshCapability) Reset() { *m = EnhancedRouteRefreshCapability{} }
func (m *EnhancedRouteRefreshCapability) String() string { return proto.CompactTextString(m) }
func (*EnhancedRouteRefreshCapability) ProtoMessage() {}
func (*EnhancedRouteRefreshCapability) Descriptor() ([]byte, []int) {
return fileDescriptor1, []int{10}
return fileDescriptor_f2310f95efbbe3ac, []int{10}
}
func (m *EnhancedRouteRefreshCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_EnhancedRouteRefreshCapability.Unmarshal(m, b)
}
func (m *EnhancedRouteRefreshCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_EnhancedRouteRefreshCapability.Marshal(b, m, deterministic)
}
func (m *EnhancedRouteRefreshCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_EnhancedRouteRefreshCapability.Merge(m, src)
}
func (m *EnhancedRouteRefreshCapability) XXX_Size() int {
return xxx_messageInfo_EnhancedRouteRefreshCapability.Size(m)
}
func (m *EnhancedRouteRefreshCapability) XXX_DiscardUnknown() {
xxx_messageInfo_EnhancedRouteRefreshCapability.DiscardUnknown(m)
}
var xxx_messageInfo_EnhancedRouteRefreshCapability proto.InternalMessageInfo
type LongLivedGracefulRestartCapabilityTuple struct {
Family *Family `protobuf:"bytes,1,opt,name=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"`
Family *Family `protobuf:"bytes,1,opt,name=family,proto3" json:"family,omitempty"`
Flags uint32 `protobuf:"varint,2,opt,name=flags,proto3" json:"flags,omitempty"`
Time uint32 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LongLivedGracefulRestartCapabilityTuple) Reset() {
@@ -248,9 +514,27 @@ func (m *LongLivedGracefulRestartCapabilityTuple) Reset() {
func (m *LongLivedGracefulRestartCapabilityTuple) String() string { return proto.CompactTextString(m) }
func (*LongLivedGracefulRestartCapabilityTuple) ProtoMessage() {}
func (*LongLivedGracefulRestartCapabilityTuple) Descriptor() ([]byte, []int) {
return fileDescriptor1, []int{11}
return fileDescriptor_f2310f95efbbe3ac, []int{11}
}
func (m *LongLivedGracefulRestartCapabilityTuple) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LongLivedGracefulRestartCapabilityTuple.Unmarshal(m, b)
}
func (m *LongLivedGracefulRestartCapabilityTuple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LongLivedGracefulRestartCapabilityTuple.Marshal(b, m, deterministic)
}
func (m *LongLivedGracefulRestartCapabilityTuple) XXX_Merge(src proto.Message) {
xxx_messageInfo_LongLivedGracefulRestartCapabilityTuple.Merge(m, src)
}
func (m *LongLivedGracefulRestartCapabilityTuple) XXX_Size() int {
return xxx_messageInfo_LongLivedGracefulRestartCapabilityTuple.Size(m)
}
func (m *LongLivedGracefulRestartCapabilityTuple) XXX_DiscardUnknown() {
xxx_messageInfo_LongLivedGracefulRestartCapabilityTuple.DiscardUnknown(m)
}
var xxx_messageInfo_LongLivedGracefulRestartCapabilityTuple proto.InternalMessageInfo
func (m *LongLivedGracefulRestartCapabilityTuple) GetFamily() *Family {
if m != nil {
return m.Family
@@ -273,16 +557,37 @@ func (m *LongLivedGracefulRestartCapabilityTuple) GetTime() uint32 {
}
type LongLivedGracefulRestartCapability struct {
Tuples []*LongLivedGracefulRestartCapabilityTuple `protobuf:"bytes,1,rep,name=tuples" json:"tuples,omitempty"`
Tuples []*LongLivedGracefulRestartCapabilityTuple `protobuf:"bytes,1,rep,name=tuples,proto3" json:"tuples,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *LongLivedGracefulRestartCapability) Reset() { *m = LongLivedGracefulRestartCapability{} }
func (m *LongLivedGracefulRestartCapability) String() string { return proto.CompactTextString(m) }
func (*LongLivedGracefulRestartCapability) ProtoMessage() {}
func (*LongLivedGracefulRestartCapability) Descriptor() ([]byte, []int) {
return fileDescriptor1, []int{12}
return fileDescriptor_f2310f95efbbe3ac, []int{12}
}
func (m *LongLivedGracefulRestartCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LongLivedGracefulRestartCapability.Unmarshal(m, b)
}
func (m *LongLivedGracefulRestartCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_LongLivedGracefulRestartCapability.Marshal(b, m, deterministic)
}
func (m *LongLivedGracefulRestartCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_LongLivedGracefulRestartCapability.Merge(m, src)
}
func (m *LongLivedGracefulRestartCapability) XXX_Size() int {
return xxx_messageInfo_LongLivedGracefulRestartCapability.Size(m)
}
func (m *LongLivedGracefulRestartCapability) XXX_DiscardUnknown() {
xxx_messageInfo_LongLivedGracefulRestartCapability.DiscardUnknown(m)
}
var xxx_messageInfo_LongLivedGracefulRestartCapability proto.InternalMessageInfo
func (m *LongLivedGracefulRestartCapability) GetTuples() []*LongLivedGracefulRestartCapabilityTuple {
if m != nil {
return m.Tuples
@@ -291,22 +596,131 @@ func (m *LongLivedGracefulRestartCapability) GetTuples() []*LongLivedGracefulRes
}
type RouteRefreshCiscoCapability struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RouteRefreshCiscoCapability) Reset() { *m = RouteRefreshCiscoCapability{} }
func (m *RouteRefreshCiscoCapability) String() string { return proto.CompactTextString(m) }
func (*RouteRefreshCiscoCapability) ProtoMessage() {}
func (*RouteRefreshCiscoCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{13} }
func (m *RouteRefreshCiscoCapability) Reset() { *m = RouteRefreshCiscoCapability{} }
func (m *RouteRefreshCiscoCapability) String() string { return proto.CompactTextString(m) }
func (*RouteRefreshCiscoCapability) ProtoMessage() {}
func (*RouteRefreshCiscoCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{13}
}
func (m *RouteRefreshCiscoCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RouteRefreshCiscoCapability.Unmarshal(m, b)
}
func (m *RouteRefreshCiscoCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RouteRefreshCiscoCapability.Marshal(b, m, deterministic)
}
func (m *RouteRefreshCiscoCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_RouteRefreshCiscoCapability.Merge(m, src)
}
func (m *RouteRefreshCiscoCapability) XXX_Size() int {
return xxx_messageInfo_RouteRefreshCiscoCapability.Size(m)
}
func (m *RouteRefreshCiscoCapability) XXX_DiscardUnknown() {
xxx_messageInfo_RouteRefreshCiscoCapability.DiscardUnknown(m)
}
var xxx_messageInfo_RouteRefreshCiscoCapability proto.InternalMessageInfo
type FQDNCapability struct {
HostNameLen uint32 `protobuf:"varint,1,opt,name=host_name_len,json=hostNameLen,proto3" json:"host_name_len,omitempty"`
HostName string `protobuf:"bytes,2,opt,name=host_name,json=hostName,proto3" json:"host_name,omitempty"`
DomainNameLen uint32 `protobuf:"varint,3,opt,name=domain_name_len,json=domainNameLen,proto3" json:"domain_name_len,omitempty"`
DomainName string `protobuf:"bytes,4,opt,name=domain_name,json=domainName,proto3" json:"domain_name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FQDNCapability) Reset() { *m = FQDNCapability{} }
func (m *FQDNCapability) String() string { return proto.CompactTextString(m) }
func (*FQDNCapability) ProtoMessage() {}
func (*FQDNCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{14}
}
func (m *FQDNCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FQDNCapability.Unmarshal(m, b)
}
func (m *FQDNCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FQDNCapability.Marshal(b, m, deterministic)
}
func (m *FQDNCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_FQDNCapability.Merge(m, src)
}
func (m *FQDNCapability) XXX_Size() int {
return xxx_messageInfo_FQDNCapability.Size(m)
}
func (m *FQDNCapability) XXX_DiscardUnknown() {
xxx_messageInfo_FQDNCapability.DiscardUnknown(m)
}
var xxx_messageInfo_FQDNCapability proto.InternalMessageInfo
func (m *FQDNCapability) GetHostNameLen() uint32 {
if m != nil {
return m.HostNameLen
}
return 0
}
func (m *FQDNCapability) GetHostName() string {
if m != nil {
return m.HostName
}
return ""
}
func (m *FQDNCapability) GetDomainNameLen() uint32 {
if m != nil {
return m.DomainNameLen
}
return 0
}
func (m *FQDNCapability) GetDomainName() string {
if m != nil {
return m.DomainName
}
return ""
}
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"`
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *UnknownCapability) Reset() { *m = UnknownCapability{} }
func (m *UnknownCapability) String() string { return proto.CompactTextString(m) }
func (*UnknownCapability) ProtoMessage() {}
func (*UnknownCapability) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{14} }
func (m *UnknownCapability) Reset() { *m = UnknownCapability{} }
func (m *UnknownCapability) String() string { return proto.CompactTextString(m) }
func (*UnknownCapability) ProtoMessage() {}
func (*UnknownCapability) Descriptor() ([]byte, []int) {
return fileDescriptor_f2310f95efbbe3ac, []int{15}
}
func (m *UnknownCapability) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_UnknownCapability.Unmarshal(m, b)
}
func (m *UnknownCapability) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_UnknownCapability.Marshal(b, m, deterministic)
}
func (m *UnknownCapability) XXX_Merge(src proto.Message) {
xxx_messageInfo_UnknownCapability.Merge(m, src)
}
func (m *UnknownCapability) XXX_Size() int {
return xxx_messageInfo_UnknownCapability.Size(m)
}
func (m *UnknownCapability) XXX_DiscardUnknown() {
xxx_messageInfo_UnknownCapability.DiscardUnknown(m)
}
var xxx_messageInfo_UnknownCapability proto.InternalMessageInfo
func (m *UnknownCapability) GetCode() uint32 {
if m != nil {
@@ -323,6 +737,7 @@ func (m *UnknownCapability) GetValue() []byte {
}
func init() {
proto.RegisterEnum("gobgpapi.AddPathMode", AddPathMode_name, AddPathMode_value)
proto.RegisterType((*MultiProtocolCapability)(nil), "gobgpapi.MultiProtocolCapability")
proto.RegisterType((*RouteRefreshCapability)(nil), "gobgpapi.RouteRefreshCapability")
proto.RegisterType((*CarryingLabelInfoCapability)(nil), "gobgpapi.CarryingLabelInfoCapability")
@@ -337,45 +752,49 @@ func init() {
proto.RegisterType((*LongLivedGracefulRestartCapabilityTuple)(nil), "gobgpapi.LongLivedGracefulRestartCapabilityTuple")
proto.RegisterType((*LongLivedGracefulRestartCapability)(nil), "gobgpapi.LongLivedGracefulRestartCapability")
proto.RegisterType((*RouteRefreshCiscoCapability)(nil), "gobgpapi.RouteRefreshCiscoCapability")
proto.RegisterType((*FQDNCapability)(nil), "gobgpapi.FQDNCapability")
proto.RegisterType((*UnknownCapability)(nil), "gobgpapi.UnknownCapability")
proto.RegisterEnum("gobgpapi.AddPathMode", AddPathMode_name, AddPathMode_value)
}
func init() { proto.RegisterFile("capability.proto", fileDescriptor1) }
func init() { proto.RegisterFile("capability.proto", fileDescriptor_f2310f95efbbe3ac) }
var fileDescriptor1 = []byte{
// 520 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0xc5, 0x49, 0x88, 0x60, 0xd2, 0x44, 0xee, 0x0a, 0x4a, 0x4a, 0xd4, 0x28, 0xda, 0x0b, 0x01,
0x89, 0x48, 0x0d, 0x07, 0xb8, 0x20, 0x51, 0x52, 0x17, 0x22, 0xe5, 0xa3, 0x72, 0x0b, 0x37, 0x54,
0x36, 0xf6, 0xc6, 0x59, 0xb1, 0xde, 0xb5, 0xec, 0x75, 0x69, 0x0e, 0x9c, 0xb9, 0xf0, 0xa3, 0x91,
0x3f, 0x62, 0x9b, 0x54, 0x6e, 0x2b, 0xa4, 0xde, 0x66, 0xbc, 0x33, 0x6f, 0xde, 0x9b, 0xb7, 0x6b,
0xd0, 0x2d, 0xe2, 0x91, 0x05, 0xe3, 0x4c, 0xad, 0x07, 0x9e, 0x2f, 0x95, 0x44, 0x8f, 0x1c, 0xb9,
0x70, 0x3c, 0xe2, 0xb1, 0xe7, 0x8d, 0x38, 0x4a, 0x3e, 0xe3, 0x11, 0x3c, 0x9b, 0x86, 0x5c, 0xb1,
0xd3, 0x28, 0xb3, 0x24, 0x1f, 0x65, 0x7d, 0xa8, 0x0f, 0xf5, 0x25, 0x71, 0x19, 0x5f, 0xb7, 0xb5,
0x9e, 0xd6, 0x6f, 0x0c, 0xf5, 0xc1, 0x06, 0x62, 0x70, 0x12, 0x7f, 0x37, 0xd3, 0x73, 0xdc, 0x86,
0x3d, 0x53, 0x86, 0x8a, 0x9a, 0x74, 0xe9, 0xd3, 0x60, 0x95, 0x63, 0xe0, 0x03, 0xe8, 0x8c, 0x88,
0xef, 0xaf, 0x99, 0x70, 0x26, 0x64, 0x41, 0xf9, 0x58, 0x2c, 0x65, 0xe1, 0xf8, 0x8f, 0x06, 0x5d,
0xe3, 0x4a, 0x51, 0x61, 0x53, 0x7b, 0x46, 0xaf, 0xd4, 0x4a, 0x7a, 0xf9, 0xe9, 0x79, 0xe8, 0x71,
0x8a, 0x0e, 0xa1, 0x21, 0xb8, 0xcf, 0x2e, 0x6e, 0xa1, 0x02, 0x51, 0x51, 0x12, 0xa3, 0xb7, 0xd0,
0x12, 0x09, 0xd8, 0xa6, 0xab, 0x52, 0xd2, 0xd5, 0x4c, 0xeb, 0x92, 0x14, 0x7f, 0x83, 0xfd, 0x52,
0x36, 0xe8, 0x03, 0xd4, 0x55, 0xc4, 0x28, 0x68, 0x6b, 0xbd, 0x6a, 0xbf, 0x31, 0xec, 0xe7, 0x68,
0x37, 0x4b, 0x30, 0xd3, 0x3e, 0xfc, 0x1d, 0xba, 0x9f, 0x7c, 0x62, 0xd1, 0x65, 0xc8, 0x4d, 0x1a,
0x28, 0xe2, 0xab, 0x6d, 0xb1, 0x77, 0x5e, 0x39, 0x7a, 0x02, 0x0f, 0x97, 0x9c, 0x38, 0x41, 0x2c,
0xad, 0x69, 0x26, 0x09, 0xfe, 0xad, 0xc1, 0x7e, 0xe9, 0x88, 0xbc, 0x47, 0x2b, 0xf4, 0x20, 0x04,
0x35, 0xc5, 0x5c, 0x9a, 0x02, 0xc5, 0x71, 0x41, 0x6b, 0x75, 0x5b, 0xeb, 0xcd, 0x0a, 0x32, 0xad,
0xaf, 0xa1, 0x73, 0x22, 0x43, 0x7f, 0x6e, 0x29, 0xaa, 0x8e, 0xce, 0x66, 0xa1, 0xbb, 0xa0, 0x7e,
0x81, 0x4a, 0x0b, 0x2a, 0x64, 0xc3, 0xa3, 0x42, 0x02, 0xec, 0xc2, 0xde, 0x91, 0x6d, 0x9f, 0x12,
0xb5, 0xfa, 0xff, 0x95, 0xbc, 0x84, 0x9a, 0x2b, 0xed, 0x44, 0x48, 0x6b, 0xf8, 0x34, 0xaf, 0x4b,
0x91, 0xa7, 0xd2, 0xa6, 0x66, 0x5c, 0x82, 0xa7, 0xb0, 0x7b, 0x6d, 0x1c, 0x7a, 0xb7, 0x65, 0x70,
0xef, 0x1a, 0x42, 0x99, 0xd8, 0x1e, 0x74, 0x0d, 0xb1, 0x22, 0xc2, 0xa2, 0x76, 0xc9, 0x3b, 0xf8,
0x05, 0x2f, 0x26, 0x52, 0x38, 0x13, 0x76, 0x49, 0xed, 0xfb, 0xbd, 0x03, 0x99, 0x9f, 0xd5, 0xdc,
0x4f, 0x2c, 0x01, 0xdf, 0x3e, 0x1e, 0x8d, 0xb7, 0x16, 0x70, 0x98, 0x4f, 0xbe, 0x23, 0xf9, 0x6c,
0x23, 0x07, 0xd0, 0xf9, 0x67, 0x13, 0x2c, 0xb0, 0x8a, 0xef, 0xfe, 0x3d, 0xec, 0x7e, 0x11, 0x3f,
0x84, 0xfc, 0x29, 0x0a, 0xe3, 0x11, 0xd4, 0xac, 0xc8, 0xbf, 0xe4, 0x56, 0xc4, 0x71, 0x24, 0xf1,
0x92, 0xf0, 0x30, 0x31, 0x75, 0xc7, 0x4c, 0x92, 0x57, 0x13, 0x68, 0x14, 0x3c, 0x45, 0x4d, 0x78,
0x3c, 0x9d, 0x1f, 0x1b, 0x17, 0xb3, 0xf9, 0xcc, 0xd0, 0x1f, 0x20, 0x1d, 0x76, 0xe2, 0xd4, 0x34,
0x46, 0xc6, 0xf8, 0xab, 0xa1, 0x6b, 0x59, 0xc1, 0x99, 0x31, 0x3b, 0xd6, 0x2b, 0x59, 0xfa, 0x71,
0x7e, 0xfe, 0x59, 0xaf, 0x2e, 0xea, 0xf1, 0x9f, 0xf0, 0xcd, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff,
0x3b, 0xec, 0xd3, 0x4d, 0x34, 0x05, 0x00, 0x00,
var fileDescriptor_f2310f95efbbe3ac = []byte{
// 590 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0xc5, 0x49, 0xa8, 0xda, 0x71, 0x13, 0xdc, 0x15, 0x94, 0x94, 0xa8, 0x25, 0xda, 0x03, 0x04,
0x24, 0x22, 0x35, 0x1c, 0xe0, 0x82, 0x44, 0x49, 0x1c, 0x88, 0x94, 0x38, 0xc5, 0x2d, 0xdc, 0x50,
0xd8, 0xd8, 0x9b, 0xc4, 0xc2, 0xde, 0xb5, 0xec, 0x75, 0x69, 0x0e, 0x9c, 0xb9, 0xf0, 0x05, 0x7c,
0x2d, 0xb2, 0xd7, 0xb1, 0x4d, 0xaa, 0xb4, 0x15, 0x12, 0xb7, 0x9d, 0x9d, 0x37, 0x6f, 0xde, 0x9b,
0x1d, 0x1b, 0x34, 0x8b, 0xf8, 0x64, 0xea, 0xb8, 0x8e, 0x58, 0xb6, 0xfd, 0x80, 0x0b, 0x8e, 0xb6,
0xe7, 0x7c, 0x3a, 0xf7, 0x89, 0xef, 0x3c, 0x52, 0x93, 0x93, 0xbc, 0xc6, 0x5d, 0x78, 0x38, 0x8a,
0x5c, 0xe1, 0x9c, 0xc6, 0x91, 0xc5, 0xdd, 0x6e, 0x56, 0x87, 0x5a, 0xb0, 0x35, 0x23, 0x9e, 0xe3,
0x2e, 0xeb, 0x4a, 0x53, 0x69, 0xa9, 0x1d, 0xad, 0xbd, 0xa2, 0x68, 0xf7, 0x93, 0x7b, 0x33, 0xcd,
0xe3, 0x3a, 0xec, 0x9b, 0x3c, 0x12, 0xd4, 0xa4, 0xb3, 0x80, 0x86, 0x8b, 0x9c, 0x03, 0x1f, 0x42,
0xa3, 0x4b, 0x82, 0x60, 0xe9, 0xb0, 0xf9, 0x90, 0x4c, 0xa9, 0x3b, 0x60, 0x33, 0x5e, 0x48, 0xff,
0x52, 0xe0, 0x48, 0xbf, 0x14, 0x94, 0xd9, 0xd4, 0x36, 0xe8, 0xa5, 0x58, 0x70, 0x3f, 0xcf, 0x9e,
0x47, 0xbe, 0x4b, 0xd1, 0x31, 0xa8, 0xcc, 0x0d, 0x9c, 0xc9, 0x0d, 0x52, 0x20, 0x06, 0xc9, 0x33,
0x7a, 0x05, 0x35, 0x26, 0xc9, 0x56, 0x55, 0xa5, 0x0d, 0x55, 0xd5, 0x14, 0x27, 0x43, 0xfc, 0x05,
0x0e, 0x36, 0xaa, 0x41, 0x6f, 0x61, 0x4b, 0xc4, 0x8a, 0xc2, 0xba, 0xd2, 0x2c, 0xb7, 0xd4, 0x4e,
0x2b, 0x67, 0xbb, 0xde, 0x82, 0x99, 0xd6, 0xe1, 0xaf, 0x70, 0xf4, 0x3e, 0x20, 0x16, 0x9d, 0x45,
0xae, 0x49, 0x43, 0x41, 0x02, 0xb1, 0x6e, 0xf6, 0xd6, 0x23, 0x47, 0xf7, 0xe1, 0xee, 0xcc, 0x25,
0xf3, 0x30, 0xb1, 0x56, 0x35, 0x65, 0x80, 0x7f, 0x2a, 0x70, 0xb0, 0xb1, 0x45, 0x5e, 0xa3, 0x14,
0x6a, 0x10, 0x82, 0x8a, 0x70, 0x3c, 0x9a, 0x12, 0x25, 0xe7, 0x82, 0xd7, 0xf2, 0xba, 0xd7, 0xeb,
0x1d, 0x64, 0x5e, 0x5f, 0x40, 0xa3, 0xcf, 0xa3, 0x60, 0x6c, 0x09, 0x2a, 0x4e, 0xce, 0x8c, 0xc8,
0x9b, 0xd2, 0xa0, 0x20, 0xa5, 0x06, 0x25, 0xb2, 0xd2, 0x51, 0x22, 0x21, 0xf6, 0x60, 0xff, 0xc4,
0xb6, 0x4f, 0x89, 0x58, 0xfc, 0xfb, 0x48, 0x9e, 0x41, 0xc5, 0xe3, 0xb6, 0x34, 0x52, 0xeb, 0x3c,
0xc8, 0x71, 0x29, 0xf3, 0x88, 0xdb, 0xd4, 0x4c, 0x20, 0x78, 0x04, 0x7b, 0x57, 0xda, 0xa1, 0xd7,
0x6b, 0x0f, 0xdc, 0xbc, 0xc2, 0xb0, 0xc9, 0x6c, 0x13, 0x8e, 0x74, 0xb6, 0x20, 0xcc, 0xa2, 0xf6,
0x86, 0xef, 0xe0, 0x07, 0x3c, 0x1d, 0x72, 0x36, 0x1f, 0x3a, 0x17, 0xd4, 0xfe, 0xbf, 0x3b, 0x90,
0xbd, 0x67, 0x39, 0x7f, 0x4f, 0xcc, 0x01, 0xdf, 0xdc, 0x1e, 0x0d, 0xd6, 0x06, 0x70, 0x9c, 0x77,
0xbe, 0xa5, 0xf8, 0x6c, 0x22, 0x87, 0xd0, 0xf8, 0x6b, 0x12, 0x4e, 0x68, 0x15, 0xbf, 0xfb, 0xdf,
0x0a, 0xd4, 0xfa, 0x1f, 0x7b, 0x46, 0xa1, 0x39, 0x86, 0xea, 0x82, 0x87, 0x62, 0xc2, 0x88, 0x47,
0x27, 0x2e, 0x65, 0xe9, 0x72, 0xa8, 0xf1, 0xa5, 0x41, 0x3c, 0x3a, 0xa4, 0x0c, 0x35, 0x60, 0x27,
0xc3, 0x24, 0xa6, 0x77, 0xcc, 0xed, 0x55, 0x1e, 0x3d, 0x81, 0x7b, 0x36, 0xf7, 0x88, 0xc3, 0x72,
0x0a, 0x39, 0x82, 0xaa, 0xbc, 0x5e, 0x91, 0x3c, 0x06, 0xb5, 0x80, 0xab, 0x57, 0x12, 0x1a, 0xc8,
0x31, 0xf8, 0x0d, 0xec, 0x7d, 0x62, 0xdf, 0x18, 0xff, 0xce, 0x0a, 0xf2, 0x10, 0x54, 0xac, 0x78,
0xb9, 0xa4, 0xaa, 0xe4, 0x1c, 0xcf, 0xff, 0x82, 0xb8, 0x91, 0x94, 0xb2, 0x6b, 0xca, 0xe0, 0xf9,
0x10, 0xd4, 0xc2, 0xc2, 0xa1, 0x2a, 0xec, 0x8c, 0xc6, 0x3d, 0x7d, 0x62, 0x8c, 0x0d, 0x5d, 0xbb,
0x83, 0x34, 0xd8, 0x4d, 0x42, 0x53, 0xef, 0xea, 0x83, 0xcf, 0xba, 0xa6, 0x64, 0x80, 0x33, 0xdd,
0xe8, 0x69, 0xa5, 0x2c, 0x7c, 0x37, 0x3e, 0xff, 0xa0, 0x95, 0xa7, 0x5b, 0xc9, 0x6f, 0xfa, 0xe5,
0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x77, 0x70, 0x63, 0xd1, 0x05, 0x00, 0x00,
}

View File

@@ -94,7 +94,14 @@ message LongLivedGracefulRestartCapability {
message RouteRefreshCiscoCapability {
}
message FQDNCapability {
uint32 host_name_len = 1;
string host_name = 2;
uint32 domain_name_len = 3;
string domain_name = 4;
}
message UnknownCapability {
uint32 code = 1;
bytes value = 2;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -30,90 +30,92 @@ package gobgpapi;
// Interface exported by the server.
service GobgpApi {
rpc StartBgp(StartBgpRequest) returns (google.protobuf.Empty);
rpc StopBgp(StopBgpRequest) returns (google.protobuf.Empty);
rpc GetBgp(GetBgpRequest) returns (GetBgpResponse);
rpc StartBgp(StartBgpRequest) returns(google.protobuf.Empty);
rpc StopBgp(StopBgpRequest) returns(google.protobuf.Empty);
rpc GetBgp(GetBgpRequest) returns(GetBgpResponse);
rpc AddPeer(AddPeerRequest) returns (google.protobuf.Empty);
rpc DeletePeer(DeletePeerRequest) returns (google.protobuf.Empty);
rpc ListPeer(ListPeerRequest) returns (stream ListPeerResponse);
rpc UpdatePeer(UpdatePeerRequest) returns (UpdatePeerResponse);
rpc ResetPeer(ResetPeerRequest) returns (google.protobuf.Empty);
rpc ShutdownPeer(ShutdownPeerRequest) returns (google.protobuf.Empty);
rpc EnablePeer(EnablePeerRequest) returns (google.protobuf.Empty);
rpc DisablePeer(DisablePeerRequest) returns (google.protobuf.Empty);
rpc MonitorPeer(MonitorPeerRequest) returns (stream MonitorPeerResponse);
rpc AddPeer(AddPeerRequest) returns(google.protobuf.Empty);
rpc DeletePeer(DeletePeerRequest) returns(google.protobuf.Empty);
rpc ListPeer(ListPeerRequest) returns(stream ListPeerResponse);
rpc UpdatePeer(UpdatePeerRequest) returns(UpdatePeerResponse);
rpc ResetPeer(ResetPeerRequest) returns(google.protobuf.Empty);
rpc ShutdownPeer(ShutdownPeerRequest) returns(google.protobuf.Empty);
rpc EnablePeer(EnablePeerRequest) returns(google.protobuf.Empty);
rpc DisablePeer(DisablePeerRequest) returns(google.protobuf.Empty);
rpc MonitorPeer(MonitorPeerRequest) returns(stream MonitorPeerResponse);
rpc AddPeerGroup(AddPeerGroupRequest) returns (google.protobuf.Empty);
rpc DeletePeerGroup(DeletePeerGroupRequest) returns (google.protobuf.Empty);
rpc UpdatePeerGroup(UpdatePeerGroupRequest) returns (UpdatePeerGroupResponse);
rpc AddPeerGroup(AddPeerGroupRequest) returns(google.protobuf.Empty);
rpc DeletePeerGroup(DeletePeerGroupRequest) returns(google.protobuf.Empty);
rpc ListPeerGroup(ListPeerGroupRequest) returns(stream ListPeerGroupResponse);
rpc UpdatePeerGroup(UpdatePeerGroupRequest) returns(UpdatePeerGroupResponse);
rpc AddDynamicNeighbor(AddDynamicNeighborRequest) returns (google.protobuf.Empty);
rpc AddDynamicNeighbor(AddDynamicNeighborRequest) returns(google.protobuf.Empty);
rpc ListDynamicNeighbor(ListDynamicNeighborRequest) returns(stream ListDynamicNeighborResponse);
rpc DeleteDynamicNeighbor(DeleteDynamicNeighborRequest) returns(google.protobuf.Empty);
rpc AddPath(AddPathRequest) returns (AddPathResponse);
rpc DeletePath(DeletePathRequest) returns (google.protobuf.Empty);
rpc ListPath(ListPathRequest) returns (stream ListPathResponse);
rpc AddPathStream(stream AddPathStreamRequest) returns (google.protobuf.Empty);
rpc AddPath(AddPathRequest) returns(AddPathResponse);
rpc DeletePath(DeletePathRequest) returns(google.protobuf.Empty);
rpc ListPath(ListPathRequest) returns(stream ListPathResponse);
rpc AddPathStream(stream AddPathStreamRequest) returns(google.protobuf.Empty);
rpc GetTable(GetTableRequest) returns (GetTableResponse);
rpc MonitorTable(MonitorTableRequest) returns (stream MonitorTableResponse);
rpc GetTable(GetTableRequest) returns(GetTableResponse);
rpc MonitorTable(MonitorTableRequest) returns(stream MonitorTableResponse);
rpc AddVrf(AddVrfRequest) returns (google.protobuf.Empty);
rpc DeleteVrf(DeleteVrfRequest) returns (google.protobuf.Empty);
rpc ListVrf(ListVrfRequest) returns (stream ListVrfResponse);
rpc AddVrf(AddVrfRequest) returns(google.protobuf.Empty);
rpc DeleteVrf(DeleteVrfRequest) returns(google.protobuf.Empty);
rpc ListVrf(ListVrfRequest) returns(stream ListVrfResponse);
rpc AddPolicy(AddPolicyRequest) returns (google.protobuf.Empty);
rpc DeletePolicy(DeletePolicyRequest) returns (google.protobuf.Empty);
rpc ListPolicy(ListPolicyRequest) returns (stream ListPolicyResponse);
rpc SetPolicies(SetPoliciesRequest) returns (google.protobuf.Empty);
rpc AddPolicy(AddPolicyRequest) returns(google.protobuf.Empty);
rpc DeletePolicy(DeletePolicyRequest) returns(google.protobuf.Empty);
rpc ListPolicy(ListPolicyRequest) returns(stream ListPolicyResponse);
rpc SetPolicies(SetPoliciesRequest) returns(google.protobuf.Empty);
rpc AddDefinedSet(AddDefinedSetRequest) returns (google.protobuf.Empty);
rpc DeleteDefinedSet(DeleteDefinedSetRequest) returns (google.protobuf.Empty);
rpc ListDefinedSet(ListDefinedSetRequest) returns (stream ListDefinedSetResponse);
rpc AddDefinedSet(AddDefinedSetRequest) returns(google.protobuf.Empty);
rpc DeleteDefinedSet(DeleteDefinedSetRequest) returns(google.protobuf.Empty);
rpc ListDefinedSet(ListDefinedSetRequest)
returns(stream ListDefinedSetResponse);
rpc AddStatement(AddStatementRequest) returns (google.protobuf.Empty);
rpc DeleteStatement(DeleteStatementRequest) returns (google.protobuf.Empty);
rpc ListStatement(ListStatementRequest) returns (stream ListStatementResponse);
rpc AddStatement(AddStatementRequest) returns(google.protobuf.Empty);
rpc DeleteStatement(DeleteStatementRequest) returns(google.protobuf.Empty);
rpc ListStatement(ListStatementRequest) returns(stream ListStatementResponse);
rpc AddPolicyAssignment(AddPolicyAssignmentRequest) returns (google.protobuf.Empty);
rpc DeletePolicyAssignment(DeletePolicyAssignmentRequest) returns (google.protobuf.Empty);
rpc ListPolicyAssignment(ListPolicyAssignmentRequest) returns (stream ListPolicyAssignmentResponse);
rpc SetPolicyAssignment(SetPolicyAssignmentRequest) returns (google.protobuf.Empty);
rpc AddPolicyAssignment(AddPolicyAssignmentRequest)
returns(google.protobuf.Empty);
rpc DeletePolicyAssignment(DeletePolicyAssignmentRequest)
returns(google.protobuf.Empty);
rpc ListPolicyAssignment(ListPolicyAssignmentRequest)
returns(stream ListPolicyAssignmentResponse);
rpc SetPolicyAssignment(SetPolicyAssignmentRequest)
returns(google.protobuf.Empty);
rpc AddRpki(AddRpkiRequest) returns (google.protobuf.Empty);
rpc DeleteRpki(DeleteRpkiRequest) returns (google.protobuf.Empty);
rpc ListRpki(ListRpkiRequest) returns (stream ListRpkiResponse);
rpc EnableRpki(EnableRpkiRequest) returns (google.protobuf.Empty);
rpc DisableRpki(DisableRpkiRequest) returns (google.protobuf.Empty);
rpc ResetRpki(ResetRpkiRequest) returns (google.protobuf.Empty);
rpc ListRpkiTable(ListRpkiTableRequest) returns (stream ListRpkiTableResponse);
rpc AddRpki(AddRpkiRequest) returns(google.protobuf.Empty);
rpc DeleteRpki(DeleteRpkiRequest) returns(google.protobuf.Empty);
rpc ListRpki(ListRpkiRequest) returns(stream ListRpkiResponse);
rpc EnableRpki(EnableRpkiRequest) returns(google.protobuf.Empty);
rpc DisableRpki(DisableRpkiRequest) returns(google.protobuf.Empty);
rpc ResetRpki(ResetRpkiRequest) returns(google.protobuf.Empty);
rpc ListRpkiTable(ListRpkiTableRequest) returns(stream ListRpkiTableResponse);
rpc EnableZebra(EnableZebraRequest) returns (google.protobuf.Empty);
rpc EnableZebra(EnableZebraRequest) returns(google.protobuf.Empty);
rpc EnableMrt(EnableMrtRequest) returns (google.protobuf.Empty);
rpc DisableMrt(DisableMrtRequest) returns (google.protobuf.Empty);
rpc EnableMrt(EnableMrtRequest) returns(google.protobuf.Empty);
rpc DisableMrt(DisableMrtRequest) returns(google.protobuf.Empty);
rpc AddBmp(AddBmpRequest) returns (google.protobuf.Empty);
rpc DeleteBmp(DeleteBmpRequest) returns (google.protobuf.Empty);
rpc AddBmp(AddBmpRequest) returns(google.protobuf.Empty);
rpc DeleteBmp(DeleteBmpRequest) returns(google.protobuf.Empty);
rpc SetLogLevel(SetLogLevelRequest) returns(google.protobuf.Empty);
}
message StartBgpRequest {
Global global = 1;
}
message StartBgpRequest { Global global = 1; }
message StopBgpRequest {
}
message StopBgpRequest {}
message GetBgpRequest {
}
message GetBgpRequest {}
message GetBgpResponse {
Global global = 1;
}
message GetBgpResponse { Global global = 1; }
message AddPeerRequest {
Peer peer = 1;
}
message AddPeerRequest { Peer peer = 1; }
message DeletePeerRequest {
string address = 1;
@@ -121,13 +123,11 @@ message DeletePeerRequest {
}
message ListPeerRequest {
string address = 1;
string address = 1;
bool enableAdvertised = 2;
}
message ListPeerResponse {
Peer peer = 1;
}
message ListPeerResponse { Peer peer = 1; }
message UpdatePeerRequest {
Peer peer = 1;
@@ -147,11 +147,7 @@ message ResetPeerRequest {
string address = 1;
string communication = 2;
bool soft = 3;
enum SoftResetDirection {
IN = 0;
OUT = 1;
BOTH = 2;
}
enum SoftResetDirection { IN = 0; OUT = 1; BOTH = 2; }
SoftResetDirection direction = 4;
}
@@ -160,9 +156,7 @@ message ShutdownPeerRequest {
string communication = 2;
}
message EnablePeerRequest {
string address = 1;
}
message EnablePeerRequest { string address = 1; }
message DisablePeerRequest {
string address = 1;
@@ -171,33 +165,37 @@ message DisablePeerRequest {
message MonitorPeerRequest {
string address = 1;
bool current = 2;
bool current = 2; // Prefer initial_state.
bool initial_state = 3;
}
message MonitorPeerResponse {
Peer peer = 1;
}
message MonitorPeerResponse { Peer peer = 1; }
message AddPeerGroupRequest {
PeerGroup peer_group = 1;
}
message AddPeerGroupRequest { PeerGroup peer_group = 1; }
message DeletePeerGroupRequest {
string name = 1;
}
message DeletePeerGroupRequest { string name = 1; }
message UpdatePeerGroupRequest {
PeerGroup peer_group = 1;
bool do_soft_reset_in = 2;
}
message UpdatePeerGroupResponse {
bool needs_soft_reset_in = 1;
message UpdatePeerGroupResponse { bool needs_soft_reset_in = 1; }
message ListPeerGroupRequest { string peer_group_name = 1; }
message ListPeerGroupResponse { PeerGroup peer_group = 1; }
message AddDynamicNeighborRequest { DynamicNeighbor dynamic_neighbor = 1; }
message DeleteDynamicNeighborRequest {
string prefix = 1;
string peer_group = 2;
}
message AddDynamicNeighborRequest {
DynamicNeighbor dynamic_neighbor = 1;
}
message ListDynamicNeighborRequest { string peer_group = 1; }
message ListDynamicNeighborResponse { DynamicNeighbor dynamic_neighbor = 1; }
message AddPathRequest {
TableType table_type = 1;
@@ -205,9 +203,7 @@ message AddPathRequest {
Path path = 3;
}
message AddPathResponse {
bytes uuid = 1;
}
message AddPathResponse { bytes uuid = 1; }
message DeletePathRequest {
TableType table_type = 1;
@@ -222,17 +218,14 @@ message ListPathRequest {
string name = 2;
Family family = 3;
repeated TableLookupPrefix prefixes = 4;
enum SortType {
NONE = 0;
PREFIX = 1;
}
enum SortType { NONE = 0; PREFIX = 1; }
SortType sort_type = 5;
bool enable_filtered = 6;
bool enable_nlri_binary = 7;
bool enable_attribute_binary = 8;
}
message ListPathResponse {
Destination destination = 1;
}
message ListPathResponse { Destination destination = 1; }
message AddPathStreamRequest {
TableType table_type = 1;
@@ -260,25 +253,15 @@ message MonitorTableRequest {
bool post_policy = 5;
}
message MonitorTableResponse {
Path path = 1;
}
message MonitorTableResponse { Path path = 1; }
message AddVrfRequest {
Vrf vrf = 1;
}
message AddVrfRequest { Vrf vrf = 1; }
message DeleteVrfRequest {
string name = 1;
}
message DeleteVrfRequest { string name = 1; }
message ListVrfRequest {
string name = 1;
}
message ListVrfRequest { string name = 1; }
message ListVrfResponse {
Vrf vrf = 1;
}
message ListVrfResponse { Vrf vrf = 1; }
message AddPolicyRequest {
Policy policy = 1;
@@ -295,13 +278,9 @@ message DeletePolicyRequest {
bool all = 3;
}
message ListPolicyRequest {
string name = 1;
}
message ListPolicyRequest { string name = 1; }
message ListPolicyResponse {
Policy policy = 1;
}
message ListPolicyResponse { Policy policy = 1; }
message SetPoliciesRequest {
repeated DefinedSet defined_sets = 1;
@@ -309,9 +288,7 @@ message SetPoliciesRequest {
repeated PolicyAssignment assignments = 3;
}
message AddDefinedSetRequest {
DefinedSet defined_set = 1;
}
message AddDefinedSetRequest { DefinedSet defined_set = 1; }
message DeleteDefinedSetRequest {
DefinedSet defined_set = 1;
@@ -323,30 +300,20 @@ message ListDefinedSetRequest {
string name = 2;
}
message ListDefinedSetResponse {
DefinedSet defined_set = 1;
}
message ListDefinedSetResponse { DefinedSet defined_set = 1; }
message AddStatementRequest {
Statement statement = 1;
}
message AddStatementRequest { Statement statement = 1; }
message DeleteStatementRequest {
Statement statement = 1;
bool all = 2;
}
message ListStatementRequest {
string name = 1;
}
message ListStatementRequest { string name = 1; }
message ListStatementResponse {
Statement statement = 1;
}
message ListStatementResponse { Statement statement = 1; }
message AddPolicyAssignmentRequest {
PolicyAssignment assignment = 1;
}
message AddPolicyAssignmentRequest { PolicyAssignment assignment = 1; }
message DeletePolicyAssignmentRequest {
PolicyAssignment assignment = 1;
@@ -358,13 +325,9 @@ message ListPolicyAssignmentRequest {
PolicyDirection direction = 2;
}
message ListPolicyAssignmentResponse {
PolicyAssignment assignment = 1;
}
message ListPolicyAssignmentResponse { PolicyAssignment assignment = 1; }
message SetPolicyAssignmentRequest {
PolicyAssignment assignment = 1;
}
message SetPolicyAssignmentRequest { PolicyAssignment assignment = 1; }
message AddRpkiRequest {
string address = 1;
@@ -377,13 +340,9 @@ message DeleteRpkiRequest {
uint32 port = 2;
}
message ListRpkiRequest {
Family family = 1;
}
message ListRpkiRequest { Family family = 1; }
message ListRpkiResponse {
Rpki server = 1;
}
message ListRpkiResponse { Rpki server = 1; }
message EnableRpkiRequest {
string address = 1;
@@ -401,13 +360,9 @@ message ResetRpkiRequest {
bool soft = 3;
}
message ListRpkiTableRequest {
Family family = 1;
}
message ListRpkiTableRequest { Family family = 1; }
message ListRpkiTableResponse {
Roa roa = 1;
}
message ListRpkiTableResponse { Roa roa = 1; }
message EnableZebraRequest {
string url = 1;
@@ -426,19 +381,12 @@ message EnableMrtRequest {
uint64 rotation_interval = 4;
}
message DisableMrtRequest {
}
message DisableMrtRequest {}
message AddBmpRequest {
string address = 1;
uint32 port = 2;
enum MonitoringPolicy {
PRE = 0;
POST = 1;
BOTH = 2;
LOCAL = 3;
ALL = 4;
}
enum MonitoringPolicy { PRE = 0; POST = 1; BOTH = 2; LOCAL = 3; ALL = 4; }
MonitoringPolicy policy = 3;
int32 StatisticsTimeout = 4;
string SysName = 5;
@@ -452,23 +400,17 @@ message DeleteBmpRequest {
message Family {
enum Afi {
AFI_UNKNOWN = 0;
AFI_IP = 1;
AFI_IP6 = 2;
AFI_L2VPN = 25;
AFI_LS = 16388;
AFI_UNKNOWN = 0; AFI_IP = 1; AFI_IP6 = 2; AFI_L2VPN = 25; AFI_LS = 16388;
AFI_OPAQUE = 16397;
}
enum Safi {
SAFI_UNKNOWN = 0;
SAFI_UNICAST = 1;
SAFI_MULTICAST = 2;
SAFI_MPLS_LABEL = 4;
SAFI_UNKNOWN = 0; SAFI_UNICAST = 1; SAFI_MULTICAST = 2; SAFI_MPLS_LABEL = 4;
SAFI_ENCAPSULATION = 7;
SAFI_VPLS = 65;
SAFI_EVPN = 70;
SAFI_LS = 71;
SAFI_SR_POLICY = 73;
SAFI_MPLS_VPN = 128;
SAFI_MPLS_VPN_MULTICAST = 129;
SAFI_ROUTE_TARGET_CONSTRAINTS = 132;
@@ -481,27 +423,14 @@ message Family {
Safi safi = 2;
}
enum TableType {
GLOBAL = 0;
LOCAL = 1;
ADJ_IN = 2;
ADJ_OUT = 3;
VRF = 4;
}
enum TableType { GLOBAL = 0; LOCAL = 1; ADJ_IN = 2; ADJ_OUT = 3; VRF = 4; }
message Validation {
enum State {
STATE_NONE = 0;
STATE_NOT_FOUND = 1;
STATE_VALID = 2;
STATE_INVALID = 3;
STATE_NONE = 0; STATE_NOT_FOUND = 1; STATE_VALID = 2; STATE_INVALID = 3;
}
enum Reason {
REASOT_NONE = 0;
REASON_AS = 1;
REASON_LENGTH = 2;
}
enum Reason { REASOT_NONE = 0; REASON_AS = 1; REASON_LENGTH = 2; }
State state = 1;
Reason reason = 2;
@@ -527,6 +456,7 @@ message Path {
// - VPNFlowSpecNLRI
// - OpaqueNLRI
// - LsAddrPrefix
// - SRPolicyNLRI
google.protobuf.Any nlri = 1;
// Each attribute must be one of *Attribute defined in
// "api/attribute.proto".
@@ -558,9 +488,7 @@ message Destination {
// API representation of table.LookupOption
enum TableLookupOption {
LOOKUP_EXACT = 0;
LOOKUP_LONGER = 1;
LOOKUP_SHORTER = 2;
LOOKUP_EXACT = 0; LOOKUP_LONGER = 1; LOOKUP_SHORTER = 2;
}
// API representation of table.LookupPrefix
@@ -580,6 +508,7 @@ message Peer {
RouteServer route_server = 8;
GracefulRestart graceful_restart = 9;
repeated AfiSafi afi_safis = 10;
TtlSecurity ttl_security = 11;
}
message PeerGroup {
@@ -593,6 +522,7 @@ message PeerGroup {
RouteServer route_server = 8;
GracefulRestart graceful_restart = 9;
repeated AfiSafi afi_safis = 10;
TtlSecurity ttl_security = 11;
}
message DynamicNeighbor {
@@ -620,11 +550,7 @@ message PeerConf {
uint32 peer_as = 5;
string peer_group = 6;
uint32 peer_type = 7;
enum RemovePrivateAs {
NONE = 0;
ALL = 1;
REPLACE = 2;
}
enum RemovePrivateAs { NONE = 0; ALL = 1; REPLACE = 2; }
RemovePrivateAs remove_private_as = 8;
bool route_flap_damping = 9;
uint32 send_community = 10;
@@ -642,11 +568,7 @@ message PeerGroupConf {
uint32 peer_as = 4;
string peer_group_name = 5;
uint32 peer_type = 6;
enum RemovePrivateAs {
NONE = 0;
ALL = 1;
REPLACE = 2;
}
enum RemovePrivateAs { NONE = 0; ALL = 1; REPLACE = 2; }
RemovePrivateAs remove_private_as = 7;
bool route_flap_damping = 8;
uint32 send_community = 9;
@@ -659,11 +581,7 @@ message PeerGroupState {
uint32 peer_as = 4;
string peer_group_name = 5;
uint32 peer_type = 6;
enum RemovePrivateAs {
NONE = 0;
ALL = 1;
REPLACE = 2;
}
enum RemovePrivateAs { NONE = 0; ALL = 1; REPLACE = 2; }
RemovePrivateAs remove_private_as = 7;
bool route_flap_damping = 8;
uint32 send_community = 9;
@@ -671,6 +589,11 @@ message PeerGroupState {
uint32 total_prefixes = 11;
}
message TtlSecurity {
bool enabled = 1;
uint32 ttl_min = 2;
}
message EbgpMultihop {
bool enabled = 1;
uint32 multihop_ttl = 2;
@@ -695,19 +618,13 @@ message PeerState {
bool route_flap_damping = 11;
uint32 send_community = 12;
enum SessionState {
UNKNOWN = 0;
IDLE = 1;
CONNECT = 2;
ACTIVE = 3;
OPENSENT = 4;
UNKNOWN = 0; IDLE = 1; CONNECT = 2; ACTIVE = 3; OPENSENT = 4;
OPENCONFIRM = 5;
ESTABLISHED = 6;
}
SessionState session_state = 13;
enum AdminState {
UP = 0;
DOWN = 1;
PFX_CT = 2; // prefix counter over limit
UP = 0; DOWN = 1; PFX_CT = 2; // prefix counter over limit
}
AdminState admin_state = 15;
uint32 out_q = 16;
@@ -742,11 +659,11 @@ message Queues {
}
message Timers {
TimersConfig config =1;
TimersConfig config = 1;
TimersState state = 2;
}
message TimersConfig{
message TimersConfig {
uint64 connect_retry = 1;
uint64 hold_time = 2;
uint64 keepalive_interval = 3;
@@ -754,7 +671,7 @@ message TimersConfig{
uint64 idle_hold_time_after_reset = 5;
}
message TimersState{
message TimersState {
uint64 connect_retry = 1;
uint64 hold_time = 2;
uint64 keepalive_interval = 3;
@@ -794,9 +711,7 @@ message GracefulRestart {
string mode = 11;
}
message MpGracefulRestartConfig {
bool enabled = 1;
}
message MpGracefulRestartConfig { bool enabled = 1; }
message MpGracefulRestartState {
bool enabled = 1;
@@ -848,13 +763,9 @@ message RouteSelectionOptions {
RouteSelectionOptionsState state = 2;
}
message UseMultiplePathsConfig {
bool enabled = 1;
}
message UseMultiplePathsConfig { bool enabled = 1; }
message UseMultiplePathsState {
bool enabled = 1;
}
message UseMultiplePathsState { bool enabled = 1; }
message EbgpConfig {
bool allow_multiple_as = 1;
@@ -871,13 +782,9 @@ message Ebgp {
EbgpState state = 2;
}
message IbgpConfig {
uint32 maximum_paths = 1;
}
message IbgpConfig { uint32 maximum_paths = 1; }
message IbgpState {
uint32 maximum_paths = 1;
}
message IbgpState { uint32 maximum_paths = 1; }
message Ibgp {
IbgpConfig config = 1;
@@ -891,13 +798,9 @@ message UseMultiplePaths {
Ibgp ibgp = 4;
}
message RouteTargetMembershipConfig {
uint32 deferral_time = 1;
}
message RouteTargetMembershipConfig { uint32 deferral_time = 1; }
message RouteTargetMembershipState {
uint32 deferral_time = 1;
}
message RouteTargetMembershipState { uint32 deferral_time = 1; }
message RouteTargetMembership {
RouteTargetMembershipConfig config = 1;
@@ -963,17 +866,13 @@ message AddPaths {
}
message Prefix {
string ip_prefix = 1;
string ip_prefix = 1;
uint32 mask_length_min = 2;
uint32 mask_length_max = 3;
}
enum DefinedType {
PREFIX = 0;
NEIGHBOR = 1;
TAG = 2;
AS_PATH = 3;
COMMUNITY = 4;
PREFIX = 0; NEIGHBOR = 1; TAG = 2; AS_PATH = 3; COMMUNITY = 4;
EXT_COMMUNITY = 5;
LARGE_COMMUNITY = 6;
NEXT_HOP = 7;
@@ -986,22 +885,14 @@ message DefinedSet {
repeated Prefix prefixes = 4;
}
enum MatchType {
ANY = 0;
ALL = 1;
INVERT = 2;
}
enum MatchType { ANY = 0; ALL = 1; INVERT = 2; }
message MatchSet {
MatchType match_type = 1;
string name = 2;
}
enum AsPathLengthType {
EQ = 0;
GE = 1;
LE = 2;
}
enum AsPathLengthType { EQ = 0; GE = 1; LE = 2; }
message AsPathLength {
AsPathLengthType length_type = 1;
@@ -1017,9 +908,7 @@ message Conditions {
MatchSet ext_community_set = 6;
int32 rpki_result = 7;
enum RouteType {
ROUTE_TYPE_NONE = 0;
ROUTE_TYPE_INTERNAL = 1;
ROUTE_TYPE_EXTERNAL = 2;
ROUTE_TYPE_NONE = 0; ROUTE_TYPE_INTERNAL = 1; ROUTE_TYPE_EXTERNAL = 2;
ROUTE_TYPE_LOCAL = 3;
}
RouteType route_type = 8;
@@ -1028,16 +917,10 @@ message Conditions {
repeated Family afi_safi_in = 11;
}
enum RouteAction {
NONE = 0;
ACCEPT = 1;
REJECT = 2;
}
enum RouteAction { NONE = 0; ACCEPT = 1; REJECT = 2; }
enum CommunityActionType {
COMMUNITY_ADD = 0;
COMMUNITY_REMOVE = 1;
COMMUNITY_REPLACE = 2;
COMMUNITY_ADD = 0; COMMUNITY_REMOVE = 1; COMMUNITY_REPLACE = 2;
}
message CommunityAction {
@@ -1045,10 +928,7 @@ message CommunityAction {
repeated string communities = 2;
}
enum MedActionType {
MED_MOD = 0;
MED_REPLACE = 1;
}
enum MedActionType { MED_MOD = 0; MED_REPLACE = 1; }
message MedAction {
MedActionType action_type = 1;
@@ -1064,11 +944,10 @@ message AsPrependAction {
message NexthopAction {
string address = 1;
bool self = 2;
bool unchanged = 3;
}
message LocalPrefAction {
uint32 value = 1;
}
message LocalPrefAction { uint32 value = 1; }
message Actions {
RouteAction route_action = 1;
@@ -1092,11 +971,7 @@ message Policy {
repeated Statement statements = 2;
}
enum PolicyDirection {
UNKNOWN = 0;
IMPORT = 1;
EXPORT = 2;
}
enum PolicyDirection { UNKNOWN = 0; IMPORT = 1; EXPORT = 2; }
message PolicyAssignment {
string name = 1;
@@ -1155,6 +1030,7 @@ message Global {
Confederation confederation = 9;
GracefulRestart graceful_restart = 10;
ApplyPolicy apply_policy = 11;
string bind_to_device = 12;
}
message Confederation {
@@ -1171,7 +1047,7 @@ message RPKIConf {
message RPKIState {
google.protobuf.Timestamp uptime = 1;
google.protobuf.Timestamp downtime = 2;
bool up = 3;
bool up = 3;
uint32 record_ipv4 = 4;
uint32 record_ipv6 = 5;
uint32 prefix_ipv4 = 6;
@@ -1192,3 +1068,10 @@ message Rpki {
RPKIConf conf = 1;
RPKIState state = 2;
}
message SetLogLevelRequest {
enum Level {
PANIC = 0; FATAL = 1; ERROR = 2; WARN = 3; INFO = 4; DEBUG = 5; TRACE = 6;
}
Level level = 1;
}

View File

@@ -634,28 +634,54 @@ func MarshalNLRI(value bgp.AddrPrefixInterface) *any.Any {
switch n := v.NLRI.(type) {
case *bgp.LsNodeNLRI:
nlri = &api.LsAddrPrefix{
Type: api.LsNLRIType_LS_NLRI_NODE,
Nlri: MarshalLsNodeNLRI(n),
Type: api.LsNLRIType_LS_NLRI_NODE,
Nlri: MarshalLsNodeNLRI(n),
Length: uint32(n.Length),
ProtocolId: api.LsProtocolID(n.ProtocolID),
Identifier: n.Identifier,
}
case *bgp.LsLinkNLRI:
nlri = &api.LsAddrPrefix{
Type: api.LsNLRIType_LS_NLRI_LINK,
Nlri: MarshalLsLinkNLRI(n),
Type: api.LsNLRIType_LS_NLRI_LINK,
Nlri: MarshalLsLinkNLRI(n),
Length: uint32(n.Length),
ProtocolId: api.LsProtocolID(n.ProtocolID),
Identifier: n.Identifier,
}
case *bgp.LsPrefixV4NLRI:
nlri = &api.LsAddrPrefix{
Type: api.LsNLRIType_LS_NLRI_PREFIX_V4,
Nlri: MarshalLsPrefixV4NLRI(n),
Type: api.LsNLRIType_LS_NLRI_PREFIX_V4,
Nlri: MarshalLsPrefixV4NLRI(n),
Length: uint32(n.Length),
ProtocolId: api.LsProtocolID(n.ProtocolID),
Identifier: n.Identifier,
}
case *bgp.LsPrefixV6NLRI:
nlri = &api.LsAddrPrefix{
Type: api.LsNLRIType_LS_NLRI_PREFIX_V6,
Nlri: MarshalLsPrefixV6NLRI(n),
Type: api.LsNLRIType_LS_NLRI_PREFIX_V6,
Nlri: MarshalLsPrefixV6NLRI(n),
Length: uint32(n.Length),
ProtocolId: api.LsProtocolID(n.ProtocolID),
Identifier: n.Identifier,
}
}
case *bgp.SRPolicyIPv4:
nlri = &api.SRPolicyNLRI{
Length: uint32(v.Length),
Distinguisher: v.Distinguisher,
Color: v.Color,
Endpoint: v.Endpoint,
}
case *bgp.SRPolicyIPv6:
nlri = &api.SRPolicyNLRI{
Length: uint32(v.Length),
Distinguisher: v.Distinguisher,
Color: v.Color,
Endpoint: v.Endpoint,
}
}
an, _ := ptypes.MarshalAny(nlri)
@@ -756,6 +782,13 @@ func UnmarshalNLRI(rf bgp.RouteFamily, an *any.Any) (bgp.AddrPrefixInterface, er
}
nlri = bgp.NewEVPNIPPrefixRoute(rd, *esi, v.EthernetTag, uint8(v.IpPrefixLen), v.IpPrefix, v.GwAddress, v.Label)
}
case *api.SRPolicyNLRI:
switch rf {
case bgp.RF_SR_POLICY_IPv4:
nlri = bgp.NewSRPolicyIPv4(v.Length, v.Distinguisher, v.Color, v.Endpoint)
case bgp.RF_SR_POLICY_IPv6:
nlri = bgp.NewSRPolicyIPv6(v.Length, v.Distinguisher, v.Color, v.Endpoint)
}
case *api.LabeledVPNIPAddressPrefix:
rd, err := UnmarshalRD(v.Rd)
if err != nil {
@@ -828,7 +861,7 @@ func NewMpReachNLRIAttributeFromNative(a *bgp.PathAttributeMpReachNLRI) *api.MpR
nexthops = nil
} else {
nexthops = []string{a.Nexthop.String()}
if a.LinkLocalNexthop != nil {
if a.LinkLocalNexthop != nil && a.LinkLocalNexthop.IsLinkLocalUnicast() {
nexthops = append(nexthops, a.LinkLocalNexthop.String())
}
}
@@ -951,6 +984,11 @@ func NewExtendedCommunitiesAttributeFromNative(a *bgp.PathAttributeExtendedCommu
community = &api.ValidationExtended{
State: uint32(v.State),
}
case *bgp.LinkBandwidthExtended:
community = &api.LinkBandiwdthExtended{
As: uint32(v.AS),
Bandwidth: v.Bandwidth,
}
case *bgp.ColorExtended:
community = &api.ColorExtended{
Color: v.Color,
@@ -1050,6 +1088,8 @@ func unmarshalExComm(a *api.ExtendedCommunitiesAttribute) (*bgp.PathAttributeExt
community = bgp.NewFourOctetAsSpecificExtended(bgp.ExtendedCommunityAttrSubType(v.SubType), v.As, uint16(v.LocalAdmin), v.IsTransitive)
case *api.ValidationExtended:
community = bgp.NewValidationExtended(bgp.ValidationState(v.State))
case *api.LinkBandiwdthExtended:
community = bgp.NewLinkBandwidthExtended(uint16(v.As), v.Bandwidth)
case *api.ColorExtended:
community = bgp.NewColorExtended(v.Color)
case *api.EncapExtended:
@@ -1143,11 +1183,49 @@ func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *api.Tun
subTlv = &api.TunnelEncapSubTLVColor{
Color: sv.Color,
}
case *bgp.TunnelEncapSubTLVEgressEndpoint:
subTlv = &api.TunnelEncapSubTLVEgressEndpoint{
Address: sv.Address.String(),
}
case *bgp.TunnelEncapSubTLVUDPDestPort:
subTlv = &api.TunnelEncapSubTLVUDPDestPort{
Port: uint32(sv.UDPDestPort),
}
case *bgp.TunnelEncapSubTLVUnknown:
subTlv = &api.TunnelEncapSubTLVUnknown{
Type: uint32(sv.Type),
Value: sv.Value,
}
case *bgp.TunnelEncapSubTLVSRBSID:
subTlv = MarshalSRBSID(sv)
// TODO (sbezverk) Add processing of SRv6 Binding SID when it gets assigned ID
case *bgp.TunnelEncapSubTLVSRCandidatePathName:
subTlv = &api.TunnelEncapSubTLVSRCandidatePathName{
CandidatePathName: sv.CandidatePathName,
}
// TODO (sbezverk) Add processing of SR Policy name when it gets assigned ID
case *bgp.TunnelEncapSubTLVSRENLP:
subTlv = &api.TunnelEncapSubTLVSRENLP{
Flags: uint32(sv.Flags),
Enlp: api.ENLPType(sv.ENLP),
}
case *bgp.TunnelEncapSubTLVSRPreference:
subTlv = &api.TunnelEncapSubTLVSRPreference{
Flags: uint32(sv.Flags),
Preference: sv.Preference,
}
case *bgp.TunnelEncapSubTLVSRPriority:
subTlv = &api.TunnelEncapSubTLVSRPriority{
Priority: uint32(sv.Priority),
}
case *bgp.TunnelEncapSubTLVSRSegmentList:
subTlv = &api.TunnelEncapSubTLVSRSegmentList{
Weight: &api.SRWeight{
Flags: uint32(sv.Weight.Flags),
Weight: uint32(sv.Weight.Weight),
},
Segments: MarshalSRSegments(sv.Segments),
}
}
an, _ := ptypes.MarshalAny(subTlv)
subTlvs = append(subTlvs, an)
@@ -1433,6 +1511,9 @@ func MarshalPathAttributes(attrList []bgp.PathAttributeInterface) []*any.Any {
case *bgp.PathAttributeLs:
n, _ := ptypes.MarshalAny(NewLsAttributeFromNative(a))
anyList = append(anyList, n)
case *bgp.PathAttributePrefixSID:
n, _ := ptypes.MarshalAny(NewPrefixSIDAttributeFromNative(a))
anyList = append(anyList, n)
case *bgp.PathAttributeUnknown:
n, _ := ptypes.MarshalAny(NewUnknownAttributeFromNative(a))
anyList = append(anyList, n)
@@ -1506,6 +1587,9 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
}
return bgp.NewPathAttributeClusterList(a.Ids), nil
case *api.MpReachNLRIAttribute:
if a.Family == nil {
return nil, fmt.Errorf("empty family")
}
rf := ToRouteFamily(a.Family)
nlris, err := UnmarshalNLRIs(rf, a.Nlris)
if err != nil {
@@ -1589,10 +1673,62 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol))
case *api.TunnelEncapSubTLVColor:
subTlv = bgp.NewTunnelEncapSubTLVColor(sv.Color)
case *api.TunnelEncapSubTLVEgressEndpoint:
subTlv = bgp.NewTunnelEncapSubTLVEgressEndpoint(sv.Address)
case *api.TunnelEncapSubTLVUDPDestPort:
subTlv = bgp.NewTunnelEncapSubTLVUDPDestPort(uint16(sv.Port))
case *api.TunnelEncapSubTLVSRPreference:
subTlv = bgp.NewTunnelEncapSubTLVSRPreference(sv.Flags, sv.Preference)
case *api.TunnelEncapSubTLVSRPriority:
subTlv = bgp.NewTunnelEncapSubTLVSRPriority(uint8(sv.Priority))
case *api.TunnelEncapSubTLVSRCandidatePathName:
subTlv = bgp.NewTunnelEncapSubTLVSRCandidatePathName(sv.CandidatePathName)
case *api.TunnelEncapSubTLVSRENLP:
subTlv = bgp.NewTunnelEncapSubTLVSRENLP(sv.Flags, bgp.SRENLPValue(sv.Enlp))
case *api.TunnelEncapSubTLVSRBindingSID:
var err error
subTlv, err = UnmarshalSRBSID(sv.Bsid)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err)
}
case *api.TunnelEncapSubTLVSRSegmentList:
var err error
weight := uint32(0)
flags := uint8(0)
if sv.Weight != nil {
weight = sv.Weight.Weight
flags = uint8(sv.Weight.Flags)
}
s := &bgp.TunnelEncapSubTLVSRSegmentList{
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
Type: bgp.ENCAP_SUBTLV_TYPE_SRSEGMENT_LIST,
Length: uint16(6), // Weight (6 bytes) + length of segment (added later, after all segments are discovered)
},
Weight: &bgp.SegmentListWeight{
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
Type: bgp.SegmentListSubTLVWeight,
Length: uint16(6),
},
Flags: flags,
Weight: weight,
},
Segments: make([]bgp.TunnelEncapSubTLVInterface, 0),
}
if len(sv.Segments) != 0 {
s.Segments, err = UnmarshalSRSegments(sv.Segments)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal tunnel encapsulation attribute sub tlv: %s", err)
}
}
// Get total length of Segment List Sub TLV
for _, seg := range s.Segments {
s.TunnelEncapSubTLV.Length += uint16(seg.Len() + 2) // Adding 1 byte of type and 1 byte of length for each Segment object
}
subTlv = s
case *api.TunnelEncapSubTLVUnknown:
subTlv = bgp.NewTunnelEncapSubTLVUnknown(bgp.EncapSubTLVType(sv.Type), sv.Value)
default:
return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v", subValue.Message)
return nil, fmt.Errorf("invalid tunnel encapsulation attribute sub tlv: %v type: %T", subValue.Message, sv)
}
subTlvs = append(subTlvs, subTlv)
}
@@ -1654,3 +1790,190 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) {
}
return nil, errors.New("unknown path attribute")
}
// MarshalSRBSID marshals SR Policy Binding SID Sub TLV structure
func MarshalSRBSID(bsid *bgp.TunnelEncapSubTLVSRBSID) *any.Any {
var r proto.Message
s := &api.SRBindingSID{
Sid: make([]byte, len(bsid.BSID.Value)),
}
copy(s.Sid, bsid.BSID.Value)
s.SFlag = bsid.Flags&0x80 == 0x80
s.IFlag = bsid.Flags&0x40 == 0x40
r = s
a, _ := ptypes.MarshalAny(r)
return a
}
// UnmarshalSRBSID unmarshals SR Policy Binding SID Sub TLV and returns native TunnelEncapSubTLVInterface interface
func UnmarshalSRBSID(bsid *any.Any) (bgp.TunnelEncapSubTLVInterface, error) {
var value ptypes.DynamicAny
if err := ptypes.UnmarshalAny(bsid, &value); err != nil {
return nil, fmt.Errorf("failed to unmarshal tunnel encap sub tlv: %s", err)
}
switch v := value.Message.(type) {
case *api.SRBindingSID:
b, err := bgp.NewBSID(v.Sid)
if err != nil {
return nil, err
}
flags := uint8(0x0)
if v.SFlag {
flags += 0x80
}
if v.IFlag {
flags += 0x40
}
return &bgp.TunnelEncapSubTLVSRBSID{
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID,
Length: uint16(2 + b.Len()),
},
BSID: b,
Flags: flags,
}, nil
case *api.SRv6BindingSID:
b, err := bgp.NewBSID(v.Sid)
if err != nil {
return nil, err
}
result := &bgp.TunnelEncapSubTLVSRv6BSID{
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
Type: bgp.ENCAP_SUBTLV_TYPE_SRBINDING_SID,
Length: uint16(2 + b.Len()),
},
Flags: 0,
BSID: b,
}
if v.EndpointBehaviorStructure != nil {
result.EPBAS = &bgp.SRv6EndpointBehaviorStructure{
Behavior: bgp.SRBehavior(v.EndpointBehaviorStructure.Behavior),
BlockLen: uint8(v.EndpointBehaviorStructure.BlockLen),
NodeLen: uint8(v.EndpointBehaviorStructure.NodeLen),
FuncLen: uint8(v.EndpointBehaviorStructure.FuncLen),
ArgLen: uint8(v.EndpointBehaviorStructure.ArgLen),
}
}
return result, nil
default:
return nil, fmt.Errorf("unknown binding sid type %+v", v)
}
}
// MarshalSRSegments marshals a slice of SR Policy Segment List
func MarshalSRSegments(segs []bgp.TunnelEncapSubTLVInterface) []*any.Any {
anyList := make([]*any.Any, 0, len(segs))
for _, seg := range segs {
var r proto.Message
switch s := seg.(type) {
case *bgp.SegmentTypeA:
r = &api.SegmentTypeA{
Label: s.Label,
Flags: &api.SegmentFlags{
VFlag: s.Flags&0x80 == 0x80,
AFlag: s.Flags&0x40 == 0x40,
SFlag: s.Flags&0x20 == 0x20,
BFlag: s.Flags&0x10 == 0x10,
},
}
case *bgp.SegmentTypeB:
flags := &api.SegmentFlags{
VFlag: s.Flags&0x80 == 0x80,
AFlag: s.Flags&0x40 == 0x40,
SFlag: s.Flags&0x20 == 0x20,
BFlag: s.Flags&0x10 == 0x10,
}
segment := &api.SegmentTypeB{
Flags: flags,
Sid: s.SID,
}
if s.SRv6EBS != nil {
segment.EndpointBehaviorStructure = &api.SRv6EndPointBehavior{
Behavior: api.SRv6Behavior(s.SRv6EBS.Behavior),
BlockLen: uint32(s.SRv6EBS.BlockLen),
NodeLen: uint32(s.SRv6EBS.NodeLen),
FuncLen: uint32(s.SRv6EBS.FuncLen),
ArgLen: uint32(s.SRv6EBS.ArgLen),
}
}
r = segment
default:
// Unrecognize Segment type, skip it
continue
}
a, _ := ptypes.MarshalAny(r)
anyList = append(anyList, a)
}
return anyList
}
// UnmarshalSRSegments unmarshals SR Policy Segments slice of structs
func UnmarshalSRSegments(s []*any.Any) ([]bgp.TunnelEncapSubTLVInterface, error) {
if len(s) == 0 {
return nil, nil
}
segments := make([]bgp.TunnelEncapSubTLVInterface, len(s))
for i := 0; i < len(s); i++ {
var value ptypes.DynamicAny
if err := ptypes.UnmarshalAny(s[i], &value); err != nil {
return nil, fmt.Errorf("failed to unmarshal SR Policy Segment: %s", err)
}
switch v := value.Message.(type) {
case *api.SegmentTypeA:
seg := &bgp.SegmentTypeA{
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
Type: bgp.EncapSubTLVType(bgp.TypeA),
Length: 6,
},
Label: v.Label,
}
if v.Flags.VFlag {
seg.Flags += 0x80
}
if v.Flags.AFlag {
seg.Flags += 0x40
}
if v.Flags.SFlag {
seg.Flags += 0x20
}
if v.Flags.BFlag {
seg.Flags += 0x10
}
segments[i] = seg
case *api.SegmentTypeB:
seg := &bgp.SegmentTypeB{
TunnelEncapSubTLV: bgp.TunnelEncapSubTLV{
Type: bgp.EncapSubTLVType(bgp.TypeB),
Length: 18,
},
SID: v.GetSid(),
}
if v.Flags.VFlag {
seg.Flags += 0x80
}
if v.Flags.AFlag {
seg.Flags += 0x40
}
if v.Flags.SFlag {
seg.Flags += 0x20
}
if v.Flags.BFlag {
seg.Flags += 0x10
}
if v.EndpointBehaviorStructure != nil {
ebs := v.GetEndpointBehaviorStructure()
seg.SRv6EBS = &bgp.SRv6EndpointBehaviorStructure{
Behavior: bgp.SRBehavior(ebs.Behavior),
BlockLen: uint8(ebs.BlockLen),
NodeLen: uint8(ebs.NodeLen),
FuncLen: uint8(ebs.FuncLen),
ArgLen: uint8(ebs.ArgLen),
}
}
segments[i] = seg
}
}
return segments, nil
}

View File

@@ -110,6 +110,15 @@ func NewRouteRefreshCiscoCapability(a *bgp.CapRouteRefreshCisco) *api.RouteRefre
return &api.RouteRefreshCiscoCapability{}
}
func NewFQDNCapability(a *bgp.CapFQDN) *api.FQDNCapability {
return &api.FQDNCapability{
HostNameLen: uint32(a.HostNameLen),
HostName: a.HostName,
DomainNameLen: uint32(a.DomainNameLen),
DomainName: a.DomainName,
}
}
func NewUnknownCapability(a *bgp.CapUnknown) *api.UnknownCapability {
return &api.UnknownCapability{
Code: uint32(a.CapCode),
@@ -140,6 +149,8 @@ func MarshalCapability(value bgp.ParameterCapabilityInterface) (*any.Any, error)
m = NewLongLivedGracefulRestartCapability(n)
case *bgp.CapRouteRefreshCisco:
m = NewRouteRefreshCiscoCapability(n)
case *bgp.CapFQDN:
m = NewFQDNCapability(n)
case *bgp.CapUnknown:
m = NewUnknownCapability(n)
default:
@@ -227,6 +238,8 @@ func unmarshalCapability(a *any.Any) (bgp.ParameterCapabilityInterface, error) {
return bgp.NewCapLongLivedGracefulRestart(tuples), nil
case *api.RouteRefreshCiscoCapability:
return bgp.NewCapRouteRefreshCisco(), nil
case *api.FQDNCapability:
return bgp.NewCapFQDN(a.HostName, a.DomainName), nil
case *api.UnknownCapability:
return bgp.NewCapUnknown(bgp.BGPCapabilityCode(a.Code), a.Value), nil
}

View File

@@ -260,6 +260,8 @@ const (
AFI_SAFI_TYPE_IPV6_FLOWSPEC AfiSafiType = "ipv6-flowspec"
AFI_SAFI_TYPE_L3VPN_IPV6_FLOWSPEC AfiSafiType = "l3vpn-ipv6-flowspec"
AFI_SAFI_TYPE_L2VPN_FLOWSPEC AfiSafiType = "l2vpn-flowspec"
AFI_SAFI_TYPE_IPV4_SRPOLICY AfiSafiType = "ipv4-srpolicy"
AFI_SAFI_TYPE_IPV6_SRPOLICY AfiSafiType = "ipv6-srpolicy"
AFI_SAFI_TYPE_OPAQUE AfiSafiType = "opaque"
AFI_SAFI_TYPE_LS AfiSafiType = "ls"
)
@@ -285,8 +287,10 @@ var AfiSafiTypeToIntMap = map[AfiSafiType]int{
AFI_SAFI_TYPE_IPV6_FLOWSPEC: 17,
AFI_SAFI_TYPE_L3VPN_IPV6_FLOWSPEC: 18,
AFI_SAFI_TYPE_L2VPN_FLOWSPEC: 19,
AFI_SAFI_TYPE_OPAQUE: 20,
AFI_SAFI_TYPE_LS: 21,
AFI_SAFI_TYPE_IPV4_SRPOLICY: 20,
AFI_SAFI_TYPE_IPV6_SRPOLICY: 21,
AFI_SAFI_TYPE_OPAQUE: 22,
AFI_SAFI_TYPE_LS: 23,
}
var IntToAfiSafiTypeMap = map[int]AfiSafiType{
@@ -310,8 +314,10 @@ var IntToAfiSafiTypeMap = map[int]AfiSafiType{
17: AFI_SAFI_TYPE_IPV6_FLOWSPEC,
18: AFI_SAFI_TYPE_L3VPN_IPV6_FLOWSPEC,
19: AFI_SAFI_TYPE_L2VPN_FLOWSPEC,
20: AFI_SAFI_TYPE_OPAQUE,
21: AFI_SAFI_TYPE_LS,
20: AFI_SAFI_TYPE_IPV4_SRPOLICY,
21: AFI_SAFI_TYPE_IPV6_SRPOLICY,
22: AFI_SAFI_TYPE_OPAQUE,
23: AFI_SAFI_TYPE_LS,
}
func (v AfiSafiType) Validate() error {
@@ -1135,7 +1141,7 @@ type ZebraState struct {
MplsLabelRangeSize uint32 `mapstructure:"mpls-label-range-size" json:"mpls-label-range-size,omitempty"`
// original -> gobgp:software-name
// Configure zebra software name.
// quagga, frr3, frr4, frr5, frr6, frr7 can be used.
// frr4, cumulus, frr6, frr7, frr7.2, and frr7.3 can be used.
SoftwareName string `mapstructure:"software-name" json:"software-name,omitempty"`
}
@@ -1165,7 +1171,7 @@ type ZebraConfig struct {
MplsLabelRangeSize uint32 `mapstructure:"mpls-label-range-size" json:"mpls-label-range-size,omitempty"`
// original -> gobgp:software-name
// Configure zebra software name.
// quagga, frr3, frr4, frr5, frr6, frr7 can be used.
// frr4, cumulus, frr6, frr7, frr7.2, and frr7.3 can be used.
SoftwareName string `mapstructure:"software-name" json:"software-name,omitempty"`
}

View File

@@ -130,7 +130,7 @@ func (n *Neighbor) IsConfederation(g *Global) bool {
}
func (n *Neighbor) IsEBGPPeer(g *Global) bool {
return n.Config.PeerAs != g.Config.As
return n.Config.PeerAs != n.Config.LocalAs
}
func (n *Neighbor) CreateRfMap() map[bgp.RouteFamily]bgp.BGPAddPathMode {
@@ -299,14 +299,22 @@ func newAfiSafiConfigFromConfigStruct(c *AfiSafi) *api.AfiSafiConfig {
}
func newApplyPolicyFromConfigStruct(c *ApplyPolicy) *api.ApplyPolicy {
f := func(t DefaultPolicyType) api.RouteAction {
if t == DEFAULT_POLICY_TYPE_ACCEPT_ROUTE {
return api.RouteAction_ACCEPT
} else if t == DEFAULT_POLICY_TYPE_REJECT_ROUTE {
return api.RouteAction_REJECT
}
return api.RouteAction_NONE
}
applyPolicy := &api.ApplyPolicy{
ImportPolicy: &api.PolicyAssignment{
Direction: api.PolicyDirection_IMPORT,
DefaultAction: api.RouteAction(c.Config.DefaultImportPolicy.ToInt()),
DefaultAction: f(c.Config.DefaultImportPolicy),
},
ExportPolicy: &api.PolicyAssignment{
Direction: api.PolicyDirection_EXPORT,
DefaultAction: api.RouteAction(c.Config.DefaultExportPolicy.ToInt()),
DefaultAction: f(c.Config.DefaultExportPolicy),
},
}
@@ -376,6 +384,13 @@ func newMpGracefulRestartFromConfigStruct(c *MpGracefulRestart) *api.MpGracefulR
Config: &api.MpGracefulRestartConfig{
Enabled: c.Config.Enabled,
},
State: &api.MpGracefulRestartState{
Enabled: c.State.Enabled,
Received: c.State.Received,
Advertised: c.State.Advertised,
EndOfRibReceived: c.State.EndOfRibReceived,
EndOfRibSent: c.State.EndOfRibSent,
},
}
}
@@ -504,6 +519,10 @@ func NewPeerFromConfigStruct(pconf *Neighbor) *api.Peer {
Enabled: pconf.EbgpMultihop.Config.Enabled,
MultihopTtl: uint32(pconf.EbgpMultihop.Config.MultihopTtl),
},
TtlSecurity: &api.TtlSecurity{
Enabled: pconf.TtlSecurity.Config.Enabled,
TtlMin: uint32(pconf.TtlSecurity.Config.TtlMin),
},
Timers: &api.Timers{
Config: &api.TimersConfig{
ConnectRetry: uint64(timer.Config.ConnectRetry),
@@ -549,6 +568,8 @@ func NewPeerGroupFromConfigStruct(pconf *PeerGroup) *api.PeerGroup {
afiSafis := make([]*api.AfiSafi, 0, len(pconf.AfiSafis))
for _, f := range pconf.AfiSafis {
if afiSafi := newAfiSafiFromConfigStruct(&f); afiSafi != nil {
afiSafi.AddPaths.Config.Receive = pconf.AddPaths.Config.Receive
afiSafi.AddPaths.Config.SendMax = uint32(pconf.AddPaths.Config.SendMax)
afiSafis = append(afiSafis, afiSafi)
}
}
@@ -576,6 +597,10 @@ func NewPeerGroupFromConfigStruct(pconf *PeerGroup) *api.PeerGroup {
Enabled: pconf.EbgpMultihop.Config.Enabled,
MultihopTtl: uint32(pconf.EbgpMultihop.Config.MultihopTtl),
},
TtlSecurity: &api.TtlSecurity{
Enabled: pconf.TtlSecurity.Config.Enabled,
TtlMin: uint32(pconf.TtlSecurity.Config.TtlMin),
},
Timers: &api.Timers{
Config: &api.TimersConfig{
ConnectRetry: uint64(timer.Config.ConnectRetry),

View File

@@ -50,6 +50,7 @@ const (
BPR_ROUTER_ID
BPR_OLDER
BPR_NON_LLGR_STALE
BPR_NEIGH_ADDR
)
var BestPathReasonStringMap = map[BestPathReason]string{
@@ -68,6 +69,7 @@ var BestPathReasonStringMap = map[BestPathReason]string{
BPR_ROUTER_ID: "Router ID",
BPR_OLDER: "Older",
BPR_NON_LLGR_STALE: "no LLGR Stale",
BPR_NEIGH_ADDR: "Neighbor Address",
}
func (r *BestPathReason) String() string {
@@ -346,9 +348,6 @@ func (dest *Destination) implicitWithdraw(newPath *Path) {
func (dest *Destination) computeKnownBestPath() (*Path, BestPathReason, error) {
if SelectionOptions.DisableBestPathSelection {
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("computeKnownBestPath skipped")
return nil, BPR_DISABLED, nil
}
@@ -358,10 +357,6 @@ func (dest *Destination) computeKnownBestPath() (*Path, BestPathReason, error) {
return nil, BPR_UNKNOWN, nil
}
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("computeKnownBestPath knownPathList: %d", len(dest.knownPathList))
// We pick the first path as current best path. This helps in breaking
// tie between two new paths learned in one cycle for which best-path
// calculation steps lead to tie.
@@ -433,10 +428,9 @@ func (dst *Destination) sort() BestPathReason {
better = compareByReachableNexthop(path1, path2)
reason = BPR_REACHABLE_NEXT_HOP
}
if better == nil {
better = compareByHighestWeight(path1, path2)
reason = BPR_HIGHEST_WEIGHT
}
// compareByHighestWeight was a no-op and was removed.
if better == nil {
better = compareByLocalPref(path1, path2)
reason = BPR_LOCAL_PREF
@@ -461,25 +455,21 @@ func (dst *Destination) sort() BestPathReason {
better = compareByASNumber(path1, path2)
reason = BPR_ASN
}
if better == nil {
better = compareByIGPCost(path1, path2)
reason = BPR_IGP_COST
}
// compareByIGPCost was a no-op and was removed.
if better == nil {
better = compareByAge(path1, path2)
reason = BPR_OLDER
}
if better == nil {
var e error
better, e = compareByRouterID(path1, path2)
if e != nil {
log.WithFields(log.Fields{
"Topic": "Table",
"Error": e,
}).Error("Could not get best path by comparing router ID")
}
better, _ = compareByRouterID(path1, path2)
reason = BPR_ROUTER_ID
}
if better == nil {
better = compareByNeighborAddress(path1, path2)
reason = BPR_NEIGH_ADDR
}
if better == nil {
reason = BPR_UNKNOWN
better = path1
@@ -616,9 +606,6 @@ func compareByReachableNexthop(path1, path2 *Path) *Path {
//
// If no path matches this criteria, return nil.
// For BGP Nexthop Tracking, evaluates next-hop is validated by IGP.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("enter compareByReachableNexthop -- path1: %s, path2: %s", path1, path2)
if path1.IsNexthopInvalid && !path2.IsNexthopInvalid {
return path2
@@ -629,19 +616,6 @@ func compareByReachableNexthop(path1, path2 *Path) *Path {
return nil
}
func compareByHighestWeight(path1, path2 *Path) *Path {
// Selects a path with highest weight.
//
// Weight is BGPS specific parameter. It is local to the router on which it
// is configured.
// Return:
// nil if best path among given paths cannot be decided, else best path.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("enter compareByHighestWeight -- path1: %s, path2: %s", path1, path2)
return nil
}
func compareByLocalPref(path1, path2 *Path) *Path {
// Selects a path with highest local-preference.
//
@@ -651,9 +625,6 @@ func compareByLocalPref(path1, path2 *Path) *Path {
// we return None.
//
// # Default local-pref values is 100
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByLocalPref")
localPref1, _ := path1.GetLocalPref()
localPref2, _ := path2.GetLocalPref()
// Highest local-preference value is preferred.
@@ -674,9 +645,6 @@ func compareByLocalOrigin(path1, path2 *Path) *Path {
// Returns None if given paths have same source.
//
// If both paths are from same sources we cannot compare them here.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByLocalOrigin")
if path1.GetSource().Equal(path2.GetSource()) {
return nil
}
@@ -699,34 +667,12 @@ func compareByASPath(path1, path2 *Path) *Path {
// Shortest as-path length is preferred. If both path have same lengths,
// we return None.
if SelectionOptions.IgnoreAsPathLength {
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("compareByASPath -- skip")
return nil
}
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByASPath")
attribute1 := path1.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
attribute2 := path2.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
// With addpath support, we could compare paths from API don't
// AS_PATH. No need to warn here.
if !path1.IsLocal() && !path2.IsLocal() && (attribute1 == nil || attribute2 == nil) {
log.WithFields(log.Fields{
"Topic": "Table",
"Key": "compareByASPath",
"ASPath1": attribute1,
"ASPath2": attribute2,
}).Warn("can't compare ASPath because it's not present")
}
l1 := path1.GetAsPathLen()
l2 := path2.GetAsPathLen()
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("compareByASPath -- l1: %d, l2: %d", l1, l2)
if l1 > l2 {
return path2
} else if l1 < l2 {
@@ -741,27 +687,16 @@ func compareByOrigin(path1, path2 *Path) *Path {
//
// IGP is preferred over EGP; EGP is preferred over Incomplete.
// If both paths have same origin, we return None.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByOrigin")
attribute1 := path1.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
attribute2 := path2.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
if attribute1 == nil || attribute2 == nil {
log.WithFields(log.Fields{
"Topic": "Table",
"Key": "compareByOrigin",
"Origin1": attribute1,
"Origin2": attribute2,
}).Error("can't compare origin because it's not present")
return nil
}
origin1 := attribute1.(*bgp.PathAttributeOrigin).Value
origin2 := attribute2.(*bgp.PathAttributeOrigin).Value
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("compareByOrigin -- origin1: %d, origin2: %d", origin1, origin2)
// If both paths have same origins
if origin1 == origin2 {
@@ -807,9 +742,6 @@ func compareByMED(path1, path2 *Path) *Path {
}()
if SelectionOptions.AlwaysCompareMed || isInternal || isSameAS {
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByMED")
getMed := func(path *Path) uint32 {
attribute := path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
if attribute == nil {
@@ -821,9 +753,6 @@ func compareByMED(path1, path2 *Path) *Path {
med1 := getMed(path1)
med2 := getMed(path2)
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("compareByMED -- med1: %d, med2: %d", med1, med2)
if med1 == med2 {
return nil
} else if med1 < med2 {
@@ -831,9 +760,6 @@ func compareByMED(path1, path2 *Path) *Path {
}
return path2
} else {
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("skip compareByMED %v %v %v", SelectionOptions.AlwaysCompareMed, isInternal, isSameAS)
return nil
}
}
@@ -844,13 +770,7 @@ func compareByASNumber(path1, path2 *Path) *Path {
//
//eBGP path is preferred over iBGP. If both paths are from same kind of
//peers, return None.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByASNumber")
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("compareByASNumber -- p1Asn: %d, p2Asn: %d", path1.GetSource().AS, path2.GetSource().AS)
// Path from confederation member should be treated as internal (IBGP learned) path.
isIBGP1 := path1.GetSource().Confederation || path1.IsIBGP()
isIBGP2 := path2.GetSource().Confederation || path2.IsIBGP()
@@ -866,17 +786,6 @@ func compareByASNumber(path1, path2 *Path) *Path {
return nil
}
func compareByIGPCost(path1, path2 *Path) *Path {
// Select the route with the lowest IGP cost to the next hop.
//
// Return None if igp cost is same.
// Currently BGPS has no concept of IGP and IGP cost.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debugf("enter compareByIGPCost -- path1: %v, path2: %v", path1, path2)
return nil
}
func compareByRouterID(path1, path2 *Path) (*Path, error) {
// Select the route received from the peer with the lowest BGP router ID.
//
@@ -884,9 +793,6 @@ func compareByRouterID(path1, path2 *Path) (*Path, error) {
// not pick best-path based on this criteria.
// RFC: http://tools.ietf.org/html/rfc5004
// We pick best path between two iBGP paths as usual.
log.WithFields(log.Fields{
"Topic": "Table",
}).Debug("enter compareByRouterID")
// If both paths are from NC we have same router Id, hence cannot compare.
if path1.IsLocal() && path2.IsLocal() {
@@ -918,6 +824,28 @@ func compareByRouterID(path1, path2 *Path) (*Path, error) {
}
}
func compareByNeighborAddress(path1, path2 *Path) *Path {
// Select the route received from the peer with the lowest peer address as
// per RFC 4271 9.1.2.2. g
p1 := path1.GetSource().Address
if p1 == nil {
return path1
}
p2 := path2.GetSource().Address
if p2 == nil {
return path2
}
cmp := bytes.Compare(p1, p2)
if cmp < 0 {
return path1
} else if cmp > 0 {
return path2
}
return nil
}
func compareByAge(path1, path2 *Path) *Path {
if !path1.IsIBGP() && !path2.IsIBGP() && !SelectionOptions.ExternalCompareRouterId {
age1 := path1.GetTimestamp().UnixNano()

View File

@@ -442,13 +442,29 @@ func (p *packerV4) pack(options ...*bgp.MarshallingOption) []*bgp.BGPMessage {
paths := c.paths
attrs := paths[0].GetPathAttrs()
// we can apply a fix here when gobgp receives from MP peer
// and propagtes to non-MP peer
// we should make sure that next-hop exists in pathattrs
// while we build the update message
// we do not want to modify the `path` though
if paths[0].getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) == nil {
attrs = append(attrs, bgp.NewPathAttributeNextHop(paths[0].GetNexthop().String()))
}
// if we have ever reach here
// there is no point keeping MP_REACH_NLRI in the announcement
attrs_without_mp := make([]bgp.PathAttributeInterface, 0, len(attrs))
for _, attr := range attrs {
if attr.GetType() != bgp.BGP_ATTR_TYPE_MP_REACH_NLRI {
attrs_without_mp = append(attrs_without_mp, attr)
}
}
attrsLen := 0
for _, a := range attrs {
for _, a := range attrs_without_mp {
attrsLen += a.Len()
}
loop(attrsLen, paths, func(nlris []*bgp.IPAddrPrefix) {
msgs = append(msgs, bgp.NewBGPUpdateMessage(nil, attrs, nlris))
msgs = append(msgs, bgp.NewBGPUpdateMessage(nil, attrs_without_mp, nlris))
})
}
}

View File

@@ -1233,12 +1233,12 @@ func nlriToIPNet(nlri bgp.AddrPrefixInterface) *net.IPNet {
case *bgp.LabeledIPAddrPrefix:
return &net.IPNet{
IP: net.IP(T.Prefix.To4()),
Mask: net.CIDRMask(int(T.Length), 32),
Mask: net.CIDRMask(int(T.Length)-T.Labels.Len()*8, 32),
}
case *bgp.LabeledIPv6AddrPrefix:
return &net.IPNet{
IP: net.IP(T.Prefix.To4()),
Mask: net.CIDRMask(int(T.Length), 128),
IP: net.IP(T.Prefix.To16()),
Mask: net.CIDRMask(int(T.Length)-T.Labels.Len()*8, 128),
}
}
return nil

View File

@@ -1116,7 +1116,7 @@ func ParseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) {
return r || s == bgp.VALIDATION_STATE_INVALID.String()
}
if len(elems) < 2 && (len(elems) < 1 && !isValidationState(elems[0])) {
return nil, fmt.Errorf("invalid ext-community (rt|soo):<value> | valid | not-found | invalid")
return nil, fmt.Errorf("invalid ext-community (rt|soo|encap|lb):<value> | valid | not-found | invalid")
}
if isValidationState(elems[0]) {
subtype = bgp.EC_SUBTYPE_ORIGIN_VALIDATION
@@ -1127,15 +1127,19 @@ func ParseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) {
subtype = bgp.EC_SUBTYPE_ROUTE_TARGET
case "soo":
subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN
case "encap":
subtype = bgp.EC_SUBTYPE_ENCAPSULATION
case "lb":
subtype = bgp.EC_SUBTYPE_LINK_BANDWIDTH
default:
return nil, fmt.Errorf("invalid ext-community (rt|soo):<value> | valid | not-found | invalid")
return nil, fmt.Errorf("invalid ext-community (rt|soo|encap|lb):<value> | valid | not-found | invalid")
}
value = elems[1]
}
return bgp.ParseExtendedCommunity(subtype, value)
}
var _regexpCommunity2 = regexp.MustCompile(`(\d+.)*\d+:\d+`)
var _regexpCommunity2 = regexp.MustCompile(`^(\d+.)*\d+:\d+$`)
func ParseCommunityRegexp(arg string) (*regexp.Regexp, error) {
i, err := strconv.ParseUint(arg, 10, 32)
@@ -1160,15 +1164,19 @@ func ParseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *reg
var subtype bgp.ExtendedCommunityAttrSubType
elems := strings.SplitN(arg, ":", 2)
if len(elems) < 2 {
return subtype, nil, fmt.Errorf("invalid ext-community format([rt|soo]:<value>)")
return subtype, nil, fmt.Errorf("invalid ext-community format([rt|soo|encap|lb]:<value>)")
}
switch strings.ToLower(elems[0]) {
case "rt":
subtype = bgp.EC_SUBTYPE_ROUTE_TARGET
case "soo":
subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN
case "encap":
subtype = bgp.EC_SUBTYPE_ENCAPSULATION
case "lb":
subtype = bgp.EC_SUBTYPE_LINK_BANDWIDTH
default:
return subtype, nil, fmt.Errorf("unknown ext-community subtype. rt, soo is supported")
return subtype, nil, fmt.Errorf("unknown ext-community subtype. rt, soo, encap, lb is supported")
}
exp, err := ParseCommunityRegexp(elems[1])
return subtype, exp, err
@@ -1212,8 +1220,12 @@ func (s *ExtCommunitySet) List() []string {
return fmt.Sprintf("rt:%s", arg)
case bgp.EC_SUBTYPE_ROUTE_ORIGIN:
return fmt.Sprintf("soo:%s", arg)
case bgp.EC_SUBTYPE_ENCAPSULATION:
return fmt.Sprintf("encap:%s", arg)
case bgp.EC_SUBTYPE_ORIGIN_VALIDATION:
return arg
case bgp.EC_SUBTYPE_LINK_BANDWIDTH:
return fmt.Sprintf("lb:%s", arg)
default:
return fmt.Sprintf("%d:%s", s.subtypeList[idx], arg)
}
@@ -1439,11 +1451,17 @@ func (c *PrefixCondition) Option() MatchOption {
// subsequent comparison is skipped if that matches the conditions.
// If PrefixList's length is zero, return true.
func (c *PrefixCondition) Evaluate(path *Path, _ *PolicyOptions) bool {
if path.GetRouteFamily() != c.set.family {
pathAfi, _ := bgp.RouteFamilyToAfiSafi(path.GetRouteFamily())
cAfi, _ := bgp.RouteFamilyToAfiSafi(c.set.family)
if cAfi != pathAfi {
return false
}
r := nlriToIPNet(path.GetNlri())
if r == nil {
return false
}
ones, _ := r.Mask.Size()
masklen := uint8(ones)
result := false
@@ -2218,6 +2236,10 @@ func (a *ExtCommunityAction) ToConfig() *config.SetExtCommunity {
return fmt.Sprintf("rt:%s", arg)
case bgp.EC_SUBTYPE_ROUTE_ORIGIN:
return fmt.Sprintf("soo:%s", arg)
case bgp.EC_SUBTYPE_ENCAPSULATION:
return fmt.Sprintf("encap:%s", arg)
case bgp.EC_SUBTYPE_LINK_BANDWIDTH:
return fmt.Sprintf("lb:%s", arg)
case bgp.EC_SUBTYPE_ORIGIN_VALIDATION:
return arg
default:
@@ -2563,8 +2585,9 @@ func NewAsPathPrependAction(action config.SetAsPathPrepend) (*AsPathPrependActio
}
type NexthopAction struct {
value net.IP
self bool
value net.IP
self bool
unchanged bool
}
func (a *NexthopAction) Type() ActionType {
@@ -2578,6 +2601,12 @@ func (a *NexthopAction) Apply(path *Path, options *PolicyOptions) *Path {
}
return path
}
if a.unchanged {
if options != nil && options.OldNextHop != nil {
path.SetNexthop(options.OldNextHop)
}
return path
}
path.SetNexthop(a.value)
return path
}
@@ -2586,6 +2615,9 @@ func (a *NexthopAction) ToConfig() config.BgpNextHopType {
if a.self {
return config.BgpNextHopType("self")
}
if a.unchanged {
return config.BgpNextHopType("unchanged")
}
return config.BgpNextHopType(a.value.String())
}
@@ -2605,6 +2637,10 @@ func NewNexthopAction(c config.BgpNextHopType) (*NexthopAction, error) {
return &NexthopAction{
self: true,
}, nil
case "unchanged":
return &NexthopAction{
unchanged: true,
}, nil
}
addr := net.ParseIP(string(c))
if addr == nil {
@@ -4046,6 +4082,11 @@ func toStatementApi(s *config.Statement) *api.Statement {
Self: true,
}
}
if string(s.Actions.BgpActions.SetNextHop) == "unchanged" {
return &api.NexthopAction{
Unchanged: true,
}
}
return &api.NexthopAction{
Address: string(s.Actions.BgpActions.SetNextHop),
}

View File

@@ -209,6 +209,7 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error)
switch t.routeFamily {
case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC, bgp.RF_IPv4_MPLS, bgp.RF_IPv6_MPLS:
_, prefix, err := net.ParseCIDR(key)
ones, bits := prefix.Mask.Size()
if err != nil {
return nil, err
}
@@ -216,7 +217,25 @@ func (t *Table) GetLongerPrefixDestinations(key string) ([]*Destination, error)
for _, dst := range t.GetDestinations() {
r.Add(nlriToIPNet(dst.nlri), dst)
}
r.WalkPrefix(prefix, func(_ *net.IPNet, v interface{}) bool {
p := &net.IPNet{
IP: prefix.IP,
Mask: net.CIDRMask((ones>>3)<<3, bits),
}
mask := 0
div := 0
if ones%8 != 0 {
mask = 8 - ones&0x7
div = ones >> 3
}
r.WalkPrefix(p, func(n *net.IPNet, v interface{}) bool {
if mask != 0 && n.IP[div]>>mask != p.IP[div]>>mask {
return true
}
l, _ := n.Mask.Size()
if ones > l {
return true
}
results = append(results, v.(*Destination))
return true
})

View File

@@ -60,6 +60,8 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time)
l = append(l, a.Value...)
dels = append(dels, l...)
default:
// update msg may not contain next_hop (type:3) in attr
// due to it uses MpReachNLRI and it also has empty update.NLRI
attrs = append(attrs, attr)
}
}
@@ -92,6 +94,11 @@ func ProcessMessage(m *bgp.BGPMessage, peerInfo *PeerInfo, timestamp time.Time)
reachAttrs[len(reachAttrs)-1] = reach
for _, nlri := range reach.Value {
// when build path from reach
// reachAttrs might not contain next_hop if `attrs` does not have one
// this happens when a MP peer send update to gobgp
// However nlri is always populated because how we build the path
// path.info{nlri: nlri}
p := NewPath(peerInfo, nlri, false, reachAttrs, timestamp, false)
p.SetHash(hash)
pathList = append(pathList, p)
@@ -179,8 +186,8 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) {
return msgs, nil
}
func (tm *TableManager) update(newPath *Path) *Update {
t := tm.Tables[newPath.GetRouteFamily()]
func (manager *TableManager) update(newPath *Path) *Update {
t := manager.Tables[newPath.GetRouteFamily()]
t.validatePath(newPath)
dst := t.getOrCreateDest(newPath.GetNlri(), 64)
u := dst.Calculate(newPath)

View File

@@ -57,71 +57,87 @@ func _() {
_ = x[_mplsLabelsAdd-46]
_ = x[_mplsLabelsDelete-47]
_ = x[_mplsLabelsReplace-48]
_ = x[_ipmrRouteStats-49]
_ = x[labelManagerConnect-50]
_ = x[labelManagerConnectAsync-51]
_ = x[getLabelChunk-52]
_ = x[releaseLabelChunk-53]
_ = x[_fecRegister-54]
_ = x[_fecUnregister-55]
_ = x[_fecUpdate-56]
_ = x[_advertiseDefaultGW-57]
_ = x[_advertiseSviMACIP-58]
_ = x[_advertiseSubnet-59]
_ = x[_advertiseAllVNI-60]
_ = x[_localESAdd-61]
_ = x[_localESDel-62]
_ = x[_vniAdd-63]
_ = x[_vniDel-64]
_ = x[_l3VNIAdd-65]
_ = x[_l3VNIDel-66]
_ = x[_remoteVTEPAdd-67]
_ = x[_remoteVTEPDel-68]
_ = x[_macIPAdd-69]
_ = x[_macIPDel-70]
_ = x[_ipPrefixRouteAdd-71]
_ = x[_ipPrefixRouteDel-72]
_ = x[_remoteMACIPAdd-73]
_ = x[_remoteMACIPDel-74]
_ = x[_duplicateAddrDetection-75]
_ = x[_pwAdd-76]
_ = x[_pwDelete-77]
_ = x[_pwSet-78]
_ = x[_pwUnset-79]
_ = x[_pwStatusUpdate-80]
_ = x[_ruleAdd-81]
_ = x[_ruleDelete-82]
_ = x[_ruleNotifyOwner-83]
_ = x[_tableManagerConnect-84]
_ = x[_getTableChunk-85]
_ = x[_releaseTableChunk-86]
_ = x[_ipSetCreate-87]
_ = x[_ipSetDestroy-88]
_ = x[_ipSetEntryAdd-89]
_ = x[_ipSetEntryDelete-90]
_ = x[_ipSetNotifyOwner-91]
_ = x[_ipSetEntryNotifyOwner-92]
_ = x[_ipTableAdd-93]
_ = x[_ipTableDelete-94]
_ = x[_ipTableNotifyOwner-95]
_ = x[_vxlanFloodControl-96]
_ = x[_vxlanSgAdd-97]
_ = x[_vxlanSgDel-98]
_ = x[_vxlanSgReplay-99]
_ = x[_mlagProcessUp-100]
_ = x[_mlagProcessDown-101]
_ = x[_mlagClientRegister-102]
_ = x[_mlagClientUnregister-103]
_ = x[_mlagClientForwardMsg-104]
_ = x[zebraError-105]
_ = x[_clientCapabilities-106]
_ = x[BackwardIPv6RouteAdd-107]
_ = x[BackwardIPv6RouteDelete-108]
_ = x[_srPolicySet-49]
_ = x[_srPolicyDelete-50]
_ = x[_srPolicyNotifyStatus-51]
_ = x[_ipmrRouteStats-52]
_ = x[labelManagerConnect-53]
_ = x[labelManagerConnectAsync-54]
_ = x[getLabelChunk-55]
_ = x[releaseLabelChunk-56]
_ = x[_fecRegister-57]
_ = x[_fecUnregister-58]
_ = x[_fecUpdate-59]
_ = x[_advertiseDefaultGW-60]
_ = x[_advertiseSviMACIP-61]
_ = x[_advertiseSubnet-62]
_ = x[_advertiseAllVNI-63]
_ = x[_localESAdd-64]
_ = x[_localESDel-65]
_ = x[_remoteESVTEPAdd-66]
_ = x[_remoteESVTEPDel-67]
_ = x[_localESEVIAdd-68]
_ = x[_localESEVIDel-69]
_ = x[_vniAdd-70]
_ = x[_vniDel-71]
_ = x[_l3VNIAdd-72]
_ = x[_l3VNIDel-73]
_ = x[_remoteVTEPAdd-74]
_ = x[_remoteVTEPDel-75]
_ = x[_macIPAdd-76]
_ = x[_macIPDel-77]
_ = x[_ipPrefixRouteAdd-78]
_ = x[_ipPrefixRouteDel-79]
_ = x[_remoteMACIPAdd-80]
_ = x[_remoteMACIPDel-81]
_ = x[_duplicateAddrDetection-82]
_ = x[_pwAdd-83]
_ = x[_pwDelete-84]
_ = x[_pwSet-85]
_ = x[_pwUnset-86]
_ = x[_pwStatusUpdate-87]
_ = x[_ruleAdd-88]
_ = x[_ruleDelete-89]
_ = x[_ruleNotifyOwner-90]
_ = x[_tableManagerConnect-91]
_ = x[_getTableChunk-92]
_ = x[_releaseTableChunk-93]
_ = x[_ipSetCreate-94]
_ = x[_ipSetDestroy-95]
_ = x[_ipSetEntryAdd-96]
_ = x[_ipSetEntryDelete-97]
_ = x[_ipSetNotifyOwner-98]
_ = x[_ipSetEntryNotifyOwner-99]
_ = x[_ipTableAdd-100]
_ = x[_ipTableDelete-101]
_ = x[_ipTableNotifyOwner-102]
_ = x[_vxlanFloodControl-103]
_ = x[_vxlanSgAdd-104]
_ = x[_vxlanSgDel-105]
_ = x[_vxlanSgReplay-106]
_ = x[_mlagProcessUp-107]
_ = x[_mlagProcessDown-108]
_ = x[_mlagClientRegister-109]
_ = x[_mlagClientUnregister-110]
_ = x[_mlagClientForwardMsg-111]
_ = x[zebraError-112]
_ = x[_clientCapabilities-113]
_ = x[_opaqueMessage-114]
_ = x[_opaqueRegister-115]
_ = x[_opaqueUnregister-116]
_ = x[_neighDiscover-117]
_ = x[BackwardIPv6RouteAdd-118]
_ = x[BackwardIPv6RouteDelete-119]
_ = x[zapi6Frr7dot3MinDifferentAPIType-49]
_ = x[zapi6Frr7dot2MinDifferentAPIType-48]
_ = x[zapi5ClMinDifferentAPIType-19]
_ = x[zapi5MinDifferentAPIType-7]
_ = x[zapi4MinDifferentAPIType-6]
_ = x[zapi3MinDifferentAPIType-0]
_ = x[zapi6Frr7dot3LabelManagerConnect-50]
_ = x[zapi6Frr7dot3LabelManagerConnectAsync-51]
_ = x[zapi6Frr7dot3GetLabelChunk-52]
_ = x[zapi6Frr7dot3ReleaseLabelChunk-53]
_ = x[zapi6Frr7dot2LabelManagerConnect-49]
_ = x[zapi6Frr7dot2LabelManagerConnectAsync-50]
_ = x[zapi6Frr7dot2GetLabelChunk-51]
@@ -212,9 +228,9 @@ func _() {
_ = x[zapi3NexthopUpdate-29]
}
const _APIType_name = "interfaceAddinterfaceDeleteinterfaceAddressAddinterfaceAddressDeleteinterfaceUpinterfaceDown_interfaceSetMaster_interfaceSetProtoDownRouteAddRouteDelete_routeNotifyOwnerredistributeAdd_redistributeDelete_redistributeDefaultAdd_redistributeDefaultDeleterouterIDAdd_routerIDDeleterouterIDUpdatehello_capabilitiesnexthopRegisternexthopUnregisternexthopUpdate_interfaceNBRAddressAdd_interfaceNBRAddressDelete_interfaceBFDDestUpdate_importRouteRegister_importRouteUnregister_importCheckUpdate_bfdDestRegister_bfdDestDeregister_bfdDestUpdate_bfdDestReplayredistributeRouteAddredistributeRouteDel_vrfUnregister_vrfAdd_vrfDeletevrfLabel_interfaceVRFUpdate_bfdClientRegister_bfdClientDeregister_interfaceEnableRADV_interfaceDisableRADVipv4NexthopLookupMRIB_interfaceLinkParams_mplsLabelsAdd_mplsLabelsDelete_mplsLabelsReplace_ipmrRouteStatslabelManagerConnectlabelManagerConnectAsyncgetLabelChunkreleaseLabelChunk_fecRegister_fecUnregister_fecUpdate_advertiseDefaultGW_advertiseSviMACIP_advertiseSubnet_advertiseAllVNI_localESAdd_localESDel_vniAdd_vniDel_l3VNIAdd_l3VNIDel_remoteVTEPAdd_remoteVTEPDel_macIPAdd_macIPDel_ipPrefixRouteAdd_ipPrefixRouteDel_remoteMACIPAdd_remoteMACIPDel_duplicateAddrDetection_pwAdd_pwDelete_pwSet_pwUnset_pwStatusUpdate_ruleAdd_ruleDelete_ruleNotifyOwner_tableManagerConnect_getTableChunk_releaseTableChunk_ipSetCreate_ipSetDestroy_ipSetEntryAdd_ipSetEntryDelete_ipSetNotifyOwner_ipSetEntryNotifyOwner_ipTableAdd_ipTableDelete_ipTableNotifyOwner_vxlanFloodControl_vxlanSgAdd_vxlanSgDel_vxlanSgReplay_mlagProcessUp_mlagProcessDown_mlagClientRegister_mlagClientUnregister_mlagClientForwardMsgzebraError_clientCapabilitiesBackwardIPv6RouteAddBackwardIPv6RouteDelete"
const _APIType_name = "interfaceAddinterfaceDeleteinterfaceAddressAddinterfaceAddressDeleteinterfaceUpinterfaceDown_interfaceSetMaster_interfaceSetProtoDownRouteAddRouteDelete_routeNotifyOwnerredistributeAdd_redistributeDelete_redistributeDefaultAdd_redistributeDefaultDeleterouterIDAdd_routerIDDeleterouterIDUpdatehello_capabilitiesnexthopRegisternexthopUnregisternexthopUpdate_interfaceNBRAddressAdd_interfaceNBRAddressDelete_interfaceBFDDestUpdate_importRouteRegister_importRouteUnregister_importCheckUpdate_bfdDestRegister_bfdDestDeregister_bfdDestUpdate_bfdDestReplayredistributeRouteAddredistributeRouteDel_vrfUnregister_vrfAdd_vrfDeletevrfLabel_interfaceVRFUpdate_bfdClientRegister_bfdClientDeregister_interfaceEnableRADV_interfaceDisableRADVipv4NexthopLookupMRIB_interfaceLinkParams_mplsLabelsAdd_mplsLabelsDelete_mplsLabelsReplace_srPolicySet_srPolicyDelete_srPolicyNotifyStatus_ipmrRouteStatslabelManagerConnectlabelManagerConnectAsyncgetLabelChunkreleaseLabelChunk_fecRegister_fecUnregister_fecUpdate_advertiseDefaultGW_advertiseSviMACIP_advertiseSubnet_advertiseAllVNI_localESAdd_localESDel_remoteESVTEPAdd_remoteESVTEPDel_localESEVIAdd_localESEVIDel_vniAdd_vniDel_l3VNIAdd_l3VNIDel_remoteVTEPAdd_remoteVTEPDel_macIPAdd_macIPDel_ipPrefixRouteAdd_ipPrefixRouteDel_remoteMACIPAdd_remoteMACIPDel_duplicateAddrDetection_pwAdd_pwDelete_pwSet_pwUnset_pwStatusUpdate_ruleAdd_ruleDelete_ruleNotifyOwner_tableManagerConnect_getTableChunk_releaseTableChunk_ipSetCreate_ipSetDestroy_ipSetEntryAdd_ipSetEntryDelete_ipSetNotifyOwner_ipSetEntryNotifyOwner_ipTableAdd_ipTableDelete_ipTableNotifyOwner_vxlanFloodControl_vxlanSgAdd_vxlanSgDel_vxlanSgReplay_mlagProcessUp_mlagProcessDown_mlagClientRegister_mlagClientUnregister_mlagClientForwardMsgzebraError_clientCapabilities_opaqueMessage_opaqueRegister_opaqueUnregister_neighDiscoverBackwardIPv6RouteAddBackwardIPv6RouteDelete"
var _APIType_index = [...]uint16{0, 12, 27, 46, 68, 79, 92, 111, 133, 141, 152, 169, 184, 203, 226, 252, 263, 278, 292, 297, 310, 325, 342, 355, 378, 404, 427, 447, 469, 487, 503, 521, 535, 549, 569, 589, 603, 610, 620, 628, 647, 665, 685, 705, 726, 747, 767, 781, 798, 816, 831, 850, 874, 887, 904, 916, 930, 940, 959, 977, 993, 1009, 1020, 1031, 1038, 1045, 1054, 1063, 1077, 1091, 1100, 1109, 1126, 1143, 1158, 1173, 1196, 1202, 1211, 1217, 1225, 1240, 1248, 1259, 1275, 1295, 1309, 1327, 1339, 1352, 1366, 1383, 1400, 1422, 1433, 1447, 1466, 1484, 1495, 1506, 1520, 1534, 1550, 1569, 1590, 1611, 1621, 1640, 1660, 1683}
var _APIType_index = [...]uint16{0, 12, 27, 46, 68, 79, 92, 111, 133, 141, 152, 169, 184, 203, 226, 252, 263, 278, 292, 297, 310, 325, 342, 355, 378, 404, 427, 447, 469, 487, 503, 521, 535, 549, 569, 589, 603, 610, 620, 628, 647, 665, 685, 705, 726, 747, 767, 781, 798, 816, 828, 843, 864, 879, 898, 922, 935, 952, 964, 978, 988, 1007, 1025, 1041, 1057, 1068, 1079, 1095, 1111, 1125, 1139, 1146, 1153, 1162, 1171, 1185, 1199, 1208, 1217, 1234, 1251, 1266, 1281, 1304, 1310, 1319, 1325, 1333, 1348, 1356, 1367, 1383, 1403, 1417, 1435, 1447, 1460, 1474, 1491, 1508, 1530, 1541, 1555, 1574, 1592, 1603, 1614, 1628, 1642, 1658, 1677, 1698, 1719, 1729, 1748, 1762, 1777, 1794, 1808, 1828, 1851}
func (i APIType) String() string {
if i >= APIType(len(_APIType_index)-1) {

View File

@@ -37,13 +37,15 @@ func _() {
_ = x[routeOpenfabric-26]
_ = x[routeVRRP-27]
_ = x[routeNHG-28]
_ = x[routeAll-29]
_ = x[routeMax-30]
_ = x[routeSRTE-29]
_ = x[routeAll-30]
_ = x[routeMax-31]
_ = x[zapi5Frr4RouteAll-24]
_ = x[zapi5Frr5RouteAll-25]
_ = x[zapi6Frr6RouteAll-26]
_ = x[zapi6Frr7RouteAll-27]
_ = x[zapi6Frr7dot2RouteAll-28]
_ = x[zapi6Frr7dot3RouteAll-29]
_ = x[zapi4RouteNHRP-11]
_ = x[zapi4RouteHSLS-12]
_ = x[zapi4RouteOLSR-13]
@@ -61,9 +63,9 @@ func _() {
_ = x[zapi3RouteNHRP-14]
}
const _RouteType_name = "routeSystemrouteKernelrouteConnectRouteStaticrouteRIProuteRIPNGrouteOSPFrouteOSPF6routeISISRouteBGProutePIMrouteEIGRProuteNHRProuteHSLSrouteOLSRrouteTABLErouteLDProuteVNCrouteVNCDirectrouteVNCDirectRHrouteBGPDirectrouteBGPDirectEXTrouteBABELrouteSHARProutePBRrouteBFDrouteOpenfabricrouteVRRProuteNHGrouteAllrouteMax"
const _RouteType_name = "routeSystemrouteKernelrouteConnectRouteStaticrouteRIProuteRIPNGrouteOSPFrouteOSPF6routeISISRouteBGProutePIMrouteEIGRProuteNHRProuteHSLSrouteOLSRrouteTABLErouteLDProuteVNCrouteVNCDirectrouteVNCDirectRHrouteBGPDirectrouteBGPDirectEXTrouteBABELrouteSHARProutePBRrouteBFDrouteOpenfabricrouteVRRProuteNHGrouteSRTErouteAllrouteMax"
var _RouteType_index = [...]uint16{0, 11, 22, 34, 45, 53, 63, 72, 82, 91, 99, 107, 117, 126, 135, 144, 154, 162, 170, 184, 200, 214, 231, 241, 251, 259, 267, 282, 291, 299, 307, 315}
var _RouteType_index = [...]uint16{0, 11, 22, 34, 45, 53, 63, 72, 82, 91, 99, 107, 117, 126, 135, 144, 154, 162, 170, 184, 200, 214, 231, 241, 251, 259, 267, 282, 291, 299, 308, 316, 324}
func (i RouteType) String() string {
if i >= RouteType(len(_RouteType_index)-1) {

View File

@@ -115,8 +115,8 @@ const (
const softwareNameMinimumVersion uint8 = 5
var allowableSoftwareNameArrays = [][]string{
{"frr4", "cumulus"}, //version:5
{"frr7.2", "frr7", "frr6"}, //version:6
{"frr4", "cumulus"}, //version:5
{"frr7.3", "frr7.2", "frr7", "frr6"}, //version:6
}
// IsAllowableSoftwareName returns bool from version number and softwareName
@@ -317,71 +317,83 @@ const (
_interfaceLinkParams
_mplsLabelsAdd
_mplsLabelsDelete
_mplsLabelsReplace // add in frr7.3
_mplsLabelsReplace // add in frr7.3
_srPolicySet // add in frr7.5
_srPolicyDelete // 50 // add in frr7.5
_srPolicyNotifyStatus // add in frr7.5
_ipmrRouteStats
labelManagerConnect // 50
labelManagerConnect // 53
labelManagerConnectAsync // add in frr5
getLabelChunk
releaseLabelChunk
_fecRegister
_fecUnregister
_fecUpdate
_advertiseDefaultGW
_advertiseSviMACIP // add in frr7.1
_advertiseDefaultGW // 60
_advertiseSviMACIP // add in frr7.1
_advertiseSubnet
_advertiseAllVNI // 60
_advertiseAllVNI // 63
_localESAdd
_localESDel
_vniAdd
_localESDel // 65
_remoteESVTEPAdd // add in frr7.5
_remoteESVTEPDel // add in frr7.5
_localESEVIAdd // add in frr7.5
_localESEVIDel // add in frr7.5
_vniAdd // 70
_vniDel
_l3VNIAdd
_l3VNIDel
_remoteVTEPAdd
_remoteVTEPDel
_macIPAdd
_macIPDel // 70
_macIPDel // 77
_ipPrefixRouteAdd
_ipPrefixRouteDel
_remoteMACIPAdd
_remoteMACIPAdd // 80
_remoteMACIPDel
_duplicateAddrDetection
_pwAdd
_pwDelete
_pwSet
_pwUnset
_pwStatusUpdate // 80
_pwStatusUpdate // 87
_ruleAdd
_ruleDelete
_ruleNotifyOwner
_ruleNotifyOwner // 90
_tableManagerConnect
_getTableChunk
_releaseTableChunk
_ipSetCreate
_ipSetDestroy
_ipSetEntryAdd
_ipSetEntryDelete // 90
_ipSetEntryDelete // 97
_ipSetNotifyOwner
_ipSetEntryNotifyOwner
_ipTableAdd
_ipTableAdd // 100
_ipTableDelete
_ipTableNotifyOwner
_vxlanFloodControl
_vxlanSgAdd
_vxlanSgDel
_vxlanSgReplay
_mlagProcessUp // 100 // add in frr7.3
_mlagProcessUp // 107 // add in frr7.3
_mlagProcessDown // add in frr7.3
_mlagClientRegister // add in frr7.3
_mlagClientUnregister // add in frr7.3
_mlagClientUnregister // 110 // add in frr7.3
_mlagClientForwardMsg // add in frr7.3
zebraError // add in frr7.3
_clientCapabilities // add in frr7.4
_opaqueMessage // add in frr7.5
_opaqueRegister // add in frr7.5
_opaqueUnregister // add in frr7.5
_neighDiscover // 117 // add in frr7.5
// BackwardIPv6RouteAdd is referred in zclient_test
BackwardIPv6RouteAdd // quagga, frr3, frr4, frr5
// BackwardIPv6RouteDelete is referred in zclient_test
BackwardIPv6RouteDelete // quagga, frr3, frr4, frr5
)
const (
zapi6Frr7dot3MinDifferentAPIType APIType = 49 //frr7.3(zapi6)
zapi6Frr7dot2MinDifferentAPIType APIType = 48 //frr7.2(zapi6)
zapi5ClMinDifferentAPIType APIType = 19 //cumuluslinux3.7.7, zebra4.0+cl3u13(zapi5)
zapi5MinDifferentAPIType APIType = 7 //frr4&5(zapi5), frr6&7.0&7.1(zapi6)
@@ -399,15 +411,31 @@ func minDifferentAPIType(version uint8, softwareName string) APIType {
} else if version == 5 ||
(version == 6 && (softwareName == "frr6" || softwareName == "frr7")) {
return zapi5MinDifferentAPIType
} else if version == 6 && softwareName == "frr7.2" {
return zapi6Frr7dot2MinDifferentAPIType
}
return zapi6Frr7dot2MinDifferentAPIType
return zapi6Frr7dot3MinDifferentAPIType
}
const (
zapi6Frr7dot2LabelManagerConnect APIType = 49 // difference from frr7.3
zapi6Frr7dot2LabelManagerConnectAsync APIType = 50 // difference from frr7.3
zapi6Frr7dot2GetLabelChunk APIType = 51 // difference from frr7.3
zapi6Frr7dot2ReleaseLabelChunk APIType = 52 // difference from frr7.3
zapi6Frr7dot3LabelManagerConnect APIType = 50 // difference from frr7.5
zapi6Frr7dot3LabelManagerConnectAsync APIType = 51 // difference from frr7.5
zapi6Frr7dot3GetLabelChunk APIType = 52 // difference from frr7.5
zapi6Frr7dot3ReleaseLabelChunk APIType = 53 // difference from frr7.5
)
var apiTypeZapi6Frr7dot3Map = map[APIType]APIType{
labelManagerConnect: zapi6Frr7dot3LabelManagerConnect,
labelManagerConnectAsync: zapi6Frr7dot3LabelManagerConnectAsync,
getLabelChunk: zapi6Frr7dot3GetLabelChunk,
releaseLabelChunk: zapi6Frr7dot3ReleaseLabelChunk,
}
const (
zapi6Frr7dot2LabelManagerConnect APIType = 49 // difference from frr7.5
zapi6Frr7dot2LabelManagerConnectAsync APIType = 50 // difference from frr7.5
zapi6Frr7dot2GetLabelChunk APIType = 51 // difference from frr7.5
zapi6Frr7dot2ReleaseLabelChunk APIType = 52 // difference from frr7.5
)
var apiTypeZapi6Frr7dot2Map = map[APIType]APIType{
@@ -656,7 +684,9 @@ func (t APIType) doesNeedConversion(version uint8, softwareName string) bool {
return true
}
func apiTypeMap(version uint8, softwareName string) map[APIType]APIType {
if version == 6 && softwareName == "frr7" {
if version == 6 && softwareName == "frr7.2" {
return apiTypeZapi6Frr7dot2Map
} else if version == 6 && softwareName == "frr7" {
return apiTypeZapi6Frr7Map
} else if version == 6 && softwareName == "frr6" {
return apiTypeZapi6Frr6Map
@@ -672,7 +702,7 @@ func apiTypeMap(version uint8, softwareName string) map[APIType]APIType {
} else if version < 4 {
return apiTypeZapi3Map
}
return apiTypeZapi6Frr7dot2Map
return apiTypeZapi6Frr7dot3Map
}
// ToEach is referred in zclient_test
@@ -762,6 +792,7 @@ const (
routeOpenfabric // FRRRouting version 7 (Zapi6) adds.
routeVRRP // FRRRouting version 7.2 (Zapi6) adds.
routeNHG // FRRRouting version 7.3 (Zapi6) adds.
routeSRTE // FRRRouting version 7.5 (Zapi6) adds.
routeAll
routeMax // max value for error
)
@@ -771,6 +802,7 @@ const (
zapi6Frr6RouteAll RouteType = 26
zapi6Frr7RouteAll RouteType = 27
zapi6Frr7dot2RouteAll RouteType = 28
zapi6Frr7dot3RouteAll RouteType = 29
)
func getRouteAll(version uint8, softwareName string) RouteType {
@@ -786,6 +818,8 @@ func getRouteAll(version uint8, softwareName string) RouteType {
return zapi6Frr7RouteAll
} else if softwareName == "frr7.2" {
return zapi6Frr7dot2RouteAll
} else if softwareName == "frr7.3" {
return zapi6Frr7dot3RouteAll
}
}
return routeAll
@@ -881,6 +915,7 @@ var routeTypeValueMap = map[string]RouteType{
"openfabric": routeOpenfabric, // add in frr7.0(zapi6)
"vrrp": routeVRRP, // add in frr7.2(zapi6)
"nhg": routeNHG, // add in frr7.3(zapi6)
"srte": routeSRTE, // add in frr7.5(zapi6)
"wildcard": routeAll,
}
@@ -918,7 +953,7 @@ func ipFromFamily(family uint8, buf []byte) net.IP {
}
// MessageFlag is the type of API Message Flags.
type MessageFlag uint8
type MessageFlag uint32 // MESSAGE_FLAG is 32bit after frr7.5, 8bit before frr7.4
const ( // For FRRouting version 4, 5 and 6 (ZAPI version 5 and 6).
// MessageNexthop is referred in zclient
@@ -932,9 +967,10 @@ const ( // For FRRouting version 4, 5 and 6 (ZAPI version 5 and 6).
MessageMTU MessageFlag = 0x10
messageSRCPFX MessageFlag = 0x20
// MessageLabel is referred in zclient
MessageLabel MessageFlag = 0x40 // deleted in frr7.3
messageBackupNexthops MessageFlag = 0x40 // added in frr7.4
messageTableID MessageFlag = 0x80 // introduced in frr5
MessageLabel MessageFlag = 0x40 // deleted in frr7.3
messageBackupNexthops MessageFlag = 0x40 // added in frr7.4
messageTableID MessageFlag = 0x80 // introduced in frr5
messageSRTE MessageFlag = 0x100 // introduced in frr7.5
)
const ( // For FRRouting.
@@ -993,7 +1029,7 @@ func (f MessageFlag) string(version uint8, softwareName string) string {
if version > 3 && f&messageSRCPFX.ToEach(version) > 0 {
ss = append(ss, "SRCPFX")
}
if version == 6 && softwareName == "" && f&messageBackupNexthops > 0 { // added in frr7.4
if version == 6 && softwareName == "" && f&messageBackupNexthops > 0 { // added in frr7.4, frr7.5
ss = append(ss, "BACKUP_NEXTHOPS")
} else if version > 4 && f&MessageLabel > 0 {
ss = append(ss, "LABEL")
@@ -1001,6 +1037,9 @@ func (f MessageFlag) string(version uint8, softwareName string) string {
if version > 5 && f&messageTableID > 0 {
ss = append(ss, "TABLEID")
}
if version == 6 && softwareName == "" && f&messageSRTE > 0 { // added in frr7.5
ss = append(ss, "SRTE")
}
return strings.Join(ss, "|")
}
@@ -1338,7 +1377,7 @@ func NewClient(network, address string, typ RouteType, version uint8, software s
// Start receive loop only when the first message successfully received.
go func() {
defer closeChannel(incoming)
defer close(incoming)
for {
if m, err := receiveSingleMsg(); err != nil {
return
@@ -1407,7 +1446,16 @@ func (c *Client) SendHello() error {
// SendRouterIDAdd sends ROUTER_ID_ADD message to zebra daemon.
func (c *Client) SendRouterIDAdd() error {
return c.sendCommand(routerIDAdd, DefaultVrf, nil)
bodies := make([]*routerIDUpdateBody, 0)
for _, afi := range []afi{afiIP, afiIP6} {
bodies = append(bodies, &routerIDUpdateBody{
afi: afi,
})
}
for _, body := range bodies {
c.sendCommand(routerIDAdd, DefaultVrf, body)
}
return nil
}
// SendInterfaceAdd sends INTERFACE_ADD message to zebra daemon.
@@ -1417,7 +1465,6 @@ func (c *Client) SendInterfaceAdd() error {
// SendRedistribute sends REDISTRIBUTE message to zebra daemon.
func (c *Client) SendRedistribute(t RouteType, vrfID uint32) error {
if c.redistDefault != t {
bodies := make([]*redistributeBody, 0)
if c.Version <= 3 {
@@ -1435,7 +1482,7 @@ func (c *Client) SendRedistribute(t RouteType, vrfID uint32) error {
}
for _, body := range bodies {
return c.sendCommand(redistributeAdd, vrfID, body)
c.sendCommand(redistributeAdd, vrfID, body)
}
}
return nil
@@ -1634,16 +1681,22 @@ func (b *unknownBody) string(version uint8, softwareName string) string {
type helloBody struct {
redistDefault RouteType
instance uint16
sessionID uint32 // frr7.4, frr7.5
receiveNotify uint8
synchronous uint8 // frr7.4, frr7.5
}
// Ref: zread_hello in zebra/zserv.c of Quagga1.2&FRR3 (ZAPI3&4)
// Ref: zread_hello in zebra/zapi_msg.c of FRR5 (ZAPI5)
func (b *helloBody) decodeFromBytes(data []byte, version uint8, softwareName string) error {
b.redistDefault = RouteType(data[0])
if version >= 4 {
if version > 3 { //frr
b.instance = binary.BigEndian.Uint16(data[1:3])
if version >= 5 {
if version == 6 && softwareName == "" { // frr7.5
b.sessionID = binary.BigEndian.Uint32(data[3:7])
b.receiveNotify = data[7]
b.synchronous = data[8]
} else if version > 4 {
b.receiveNotify = data[3]
}
}
@@ -1656,14 +1709,20 @@ func (b *helloBody) serialize(version uint8, softwareName string) ([]byte, error
return []byte{uint8(b.redistDefault)}, nil
}
var buf []byte
if version == 4 {
buf = make([]byte, 3)
if version == 6 && softwareName == "" { // frr7.5
buf = make([]byte, 9)
} else if version > 4 {
buf = make([]byte, 4)
} else if version == 4 {
buf = make([]byte, 3)
}
buf[0] = uint8(b.redistDefault)
binary.BigEndian.PutUint16(buf[1:3], b.instance)
if version > 4 {
if version == 6 && softwareName == "" { // frr7.5
binary.BigEndian.PutUint32(buf[3:7], b.sessionID)
buf[7] = b.receiveNotify
buf[8] = b.synchronous
} else if version > 4 {
buf[3] = b.receiveNotify
}
return buf, nil
@@ -1870,6 +1929,7 @@ func (b *interfaceAddressUpdateBody) string(version uint8, softwareName string)
type routerIDUpdateBody struct {
length uint8
prefix net.IP
afi afi
}
// Ref: zebra_router_id_update_read in lib/zclient.c of Quagga1.2&FRR3&FRR5 (ZAPI3&4&5)
@@ -1885,7 +1945,12 @@ func (b *routerIDUpdateBody) decodeFromBytes(data []byte, version uint8, softwar
return nil
}
// Ref: zclient_send_router_id_update in lib/zclient.c of FRR7.5
func (b *routerIDUpdateBody) serialize(version uint8, softwareName string) ([]byte, error) {
if version == 6 && softwareName == "" {
//stream_putw(s, afi);
return []byte{0x00, uint8(b.afi)}, nil
}
return []byte{}, nil
}
@@ -1894,9 +1959,11 @@ func (b *routerIDUpdateBody) string(version uint8, softwareName string) string {
}
const (
zapiNexthopFlagOnlink uint8 = 0x01 // frr7.1, 7.2, 7.3, 7.4
zapiNexthopFlagLabel uint8 = 0x02 // frr7.3, 7.4
zapiNexthopFlagWeight uint8 = 0x04 // frr7.3, 7.4
zapiNexthopFlagOnlink uint8 = 0x01 // frr7.1, 7.2, 7.3, 7.4, 7.5
zapiNexthopFlagLabel uint8 = 0x02 // frr7.3, 7.4, 7.5
zapiNexthopFlagWeight uint8 = 0x04 // frr7.3, 7.4, 7.5
zapiNexthopFlagHasBackup uint8 = 0x08 // frr7.4, 7.5
)
// Flag for nexthop processing. It is gobgp's internal flag.
@@ -1921,7 +1988,7 @@ func nexthopProcessFlagForIPRouteBody(version uint8, softwareName string, isDeco
processFlag := (nexthopHasVrfID | nexthopHasType) // frr4, 5, 6, 7
if version == 6 {
switch softwareName {
case "":
case "", "frr7.3":
processFlag |= (nexthopHasFlag | nexthopProcessIPToIPIFindex)
case "frr7.2", "frr7.0":
processFlag |= nexthopHasOnlink
@@ -1942,6 +2009,9 @@ type Nexthop struct {
MplsLabels []uint32
weight uint32
rmac [6]byte
srteColor uint32
backupNum uint8
backupIndex []uint8
}
func (n Nexthop) string() string {
@@ -1994,6 +2064,9 @@ func (n Nexthop) encode(version uint8, softwareName string, processFlag nexthopP
if n.weight > 0 {
n.flags |= zapiNexthopFlagWeight
}
if n.backupNum > 0 {
n.flags |= zapiNexthopFlagHasBackup
}
}
if processFlag&nexthopHasFlag > 0 || processFlag&nexthopHasOnlink > 0 {
// frr7.1, 7.2 has onlink, 7.3 has flag
@@ -2051,6 +2124,20 @@ func (n Nexthop) encode(version uint8, softwareName string, processFlag nexthopP
//frr: stream_put(s, &(api_nh->rmac), sizeof(struct ethaddr));
buf = append(buf, n.rmac[:]...)
}
// added in frr7.5 (Color for Segment Routing TE.)
if message&messageSRTE > 0 && (version == 6 && softwareName == "") {
tmpbuf := make([]byte, 4)
binary.BigEndian.PutUint32(tmpbuf, uint32(n.srteColor))
buf = append(buf, tmpbuf...) //frr: stream_putl(s, api_nh->srte_color);
}
if n.flags&zapiNexthopFlagHasBackup > 0 {
tmpbuf := make([]byte, 1+1*n.backupNum)
tmpbuf[0] = n.backupNum //frr: stream_putc(s, api_nh->backup_num);
for i := uint8(0); i < n.backupNum; i++ {
tmpbuf[i+1] = n.backupIndex[i]
}
buf = append(buf, tmpbuf...)
}
return buf
}
@@ -2109,7 +2196,10 @@ func (n *Nexthop) decode(data []byte, version uint8, softwareName string, family
n.blackholeType = data[offset] //frr: STREAM_GETC(s, api_nh->bh_type);
offset++
}
if n.flags&zapiNexthopFlagLabel > 0 || message&MessageLabel > 0 {
if n.flags&zapiNexthopFlagLabel > 0 || (message&MessageLabel > 0 &&
(version == 5 || version == 6 &&
(softwareName == "frr6" || softwareName == "frr7" ||
softwareName == "frr7.2"))) {
n.LabelNum = uint8(data[offset]) //frr: STREAM_GETC(s, api_nh->label_num);
offset++
if n.LabelNum > maxMplsLabel {
@@ -2136,6 +2226,25 @@ func (n *Nexthop) decode(data []byte, version uint8, softwareName string, family
copy(n.rmac[0:], data[offset:offset+6])
offset += 6
}
// added in frr7.5 (Color for Segment Routing TE.)
if message&messageSRTE > 0 && (version == 6 && softwareName == "") {
//STREAM_GETL(s, api_nh->srte_color);
n.srteColor = binary.BigEndian.Uint32(data[offset:])
offset += 4
}
// added in frr7.4 (Index of backup nexthop)
if n.flags&zapiNexthopFlagHasBackup > 0 {
n.backupNum = data[offset] //frr: STREAM_GETC(s, api_nh->backup_num);
offset++
if n.backupNum > 0 {
n.backupIndex = make([]uint8, n.backupNum)
for i := uint8(0); i < n.backupNum; i++ {
//frr STREAM_GETC(s, api_nh->backup_idx[i]);
n.backupIndex[i] = data[offset]
offset++
}
}
}
return offset, nil
}
@@ -2186,6 +2295,7 @@ type IPRouteBody struct {
Mtu uint32
tag uint32
tableID uint32
srteColor uint32
API APIType // API is referred in zclient_test
}
@@ -2261,13 +2371,25 @@ func (b *IPRouteBody) IsWithdraw(version uint8, softwareName string) bool {
func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, error) {
var buf []byte
numNexthop := len(b.Nexthops)
if version <= 3 {
buf = make([]byte, 5)
} else if version == 4 {
buf = make([]byte, 10)
} else { // version >= 5
buf = make([]byte, 9) //type(1)+instance(2)+flags(4)+message(1)+safi(1)
bufInitSize := 12
switch version {
case 2, 3:
bufInitSize = 5
case 4:
bufInitSize = 10
case 5:
bufInitSize = 9 //type(1)+instance(2)+flags(4)+message(1)+safi(1)
case 6:
switch softwareName {
case "frr6", "frr7", "frr7.2", "frr7.3":
bufInitSize = 9 //type(1)+instance(2)+flags(4)+message(1)+safi(1)
default:
bufInitSize = 12 //type(1)+instance(2)+flags(4)+message(4)+safi(1)
}
}
buf = make([]byte, bufInitSize)
buf[0] = uint8(b.Type.toEach(version, softwareName)) //frr: stream_putc(s, api->type);
if version < 4 {
buf[1] = uint8(b.Flags)
@@ -2278,27 +2400,33 @@ func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, err
binary.BigEndian.PutUint16(buf[1:3], uint16(b.instance))
//frr: stream_putl(s, api->flags);
binary.BigEndian.PutUint32(buf[3:7], uint32(b.Flags))
//frr: stream_putc(s, api->message);
buf[7] = uint8(b.Message)
if version == 4 {
binary.BigEndian.PutUint16(buf[8:10], uint16(b.Safi))
} else { // version >= 5
//frr: stream_putc(s, api->safi);
buf[8] = uint8(b.Safi)
// only zapi version 5 (frr4.0.x) have evpn routes
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
// size of struct ethaddr is 6 octets defined by ETH_ALEN
buf = append(buf, b.Nexthops[numNexthop-1].rmac[:6]...)
if version == 6 && softwareName == "" {
//frr7.5: stream_putl(s, api->message);
binary.BigEndian.PutUint32(buf[7:11], uint32(b.Message))
buf[11] = uint8(b.Safi)
} else {
//before frr7.4: stream_putc(s, api->message);
buf[7] = uint8(b.Message)
if version > 4 {
//frr: stream_putc(s, api->safi);
buf[8] = uint8(b.Safi)
} else { // version 2,3 and 4 (quagga, frr3)
binary.BigEndian.PutUint16(buf[8:10], uint16(b.Safi))
}
if b.Prefix.Family == syscall.AF_UNSPEC {
b.Prefix.Family = familyFromPrefix(b.Prefix.Prefix)
}
//frr: stream_putc(s, api->prefix.family);
buf = append(buf, b.Prefix.Family)
}
}
// only zapi version 5 (frr4.0.x) have evpn routes
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
// size of struct ethaddr is 6 octets defined by ETH_ALEN
buf = append(buf, b.Nexthops[numNexthop-1].rmac[:6]...)
}
if version > 4 { // version 5, 6 (after frr4)
if b.Prefix.Family == syscall.AF_UNSPEC {
b.Prefix.Family = familyFromPrefix(b.Prefix.Prefix)
}
//frr: stream_putc(s, api->prefix.family);
buf = append(buf, b.Prefix.Family)
}
byteLen := (int(b.Prefix.PrefixLen) + 7) / 8
buf = append(buf, b.Prefix.PrefixLen) //frr: stream_putc(s, api->prefix.prefixlen);
//frr: stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
@@ -2329,7 +2457,8 @@ func (b *IPRouteBody) serialize(version uint8, softwareName string) ([]byte, err
buf = append(buf, nexthop.encode(version, softwareName, processFlag, b.Message, b.Flags)...)
}
}
if b.Message&messageBackupNexthops > 0 { // added in frr7.4
// MESSAGE_BACKUP_NEXTHOPS is added in frr7.4
if version == 6 && softwareName == "" && b.Message&messageBackupNexthops > 0 {
tmpbuf := make([]byte, 2)
binary.BigEndian.PutUint16(tmpbuf, uint16(len(b.backupNexthops)))
buf = append(buf, tmpbuf...) //frr: stream_putw(s, api->nexthop_num);
@@ -2428,17 +2557,23 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
b.Flags = Flag(binary.BigEndian.Uint32(data[3:7]))
data = data[7:]
}
b.Message = MessageFlag(data[0]) //frr: STREAM_GETC(s, api->message);
if version == 6 && softwareName == "" {
//frr7.5: STREAM_GETL(s, api->message);
b.Message = MessageFlag(binary.BigEndian.Uint32(data[0:4]))
data = data[4:]
} else {
b.Message = MessageFlag(data[0]) //frr: STREAM_GETC(s, api->message);
data = data[1:]
}
b.Safi = Safi(SafiUnicast)
b.Prefix.Family = b.API.addressFamily(version) // return AF_UNSPEC if version > 4
var evpnNexthop Nexthop
if version > 4 {
b.Safi = Safi(data[1]) //frr: STREAM_GETC(s, api->safi);
b.Safi = Safi(data[0]) //frr: STREAM_GETC(s, api->safi);
if b.Safi > safiMax { //frr5 and later work, ToDo: fix for older version
return fmt.Errorf("unknown safi type: %d in version: %d (%s)", b.Type, version, softwareName)
}
data = data[2:]
data = data[1:]
// zapi version 5 only
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
@@ -2448,6 +2583,7 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
}
b.Prefix.Family = data[0] //frr: STREAM_GETC(s, api->prefix.family);
data = data[1:]
}
addrByteLen, err := addressByteLength(b.Prefix.Family)
@@ -2457,11 +2593,11 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
addrBitLen := uint8(addrByteLen * 8)
b.Prefix.PrefixLen = data[1] //frr: STREAM_GETC(s, api->prefix.prefixlen);
b.Prefix.PrefixLen = data[0] //frr: STREAM_GETC(s, api->prefix.prefixlen);
if b.Prefix.PrefixLen > addrBitLen {
return fmt.Errorf("prefix length %d is greater than %d", b.Prefix.PrefixLen, addrBitLen)
}
data = data[2:]
data = data[1:]
pos := 0
rest := len(data)
@@ -2474,6 +2610,7 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
copy(buf, data[pos:pos+byteLen])
b.Prefix.Prefix = ipFromFamily(b.Prefix.Family, buf)
pos += byteLen
if version > 3 && b.Message&messageSRCPFX.ToEach(version) > 0 {
if pos+1 > rest {
return fmt.Errorf("MessageSRCPFX message length invalid pos:%d rest:%d", pos, rest)
@@ -2496,21 +2633,28 @@ func (b *IPRouteBody) decodeFromBytes(data []byte, version uint8, softwareName s
}
b.Nexthops = []Nexthop{}
offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, false)
if err != nil {
return err
if b.Message&MessageNexthop.ToEach(version) > 0 {
offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, false)
if err != nil {
return err
}
pos += offset
}
pos += offset
b.backupNexthops = []Nexthop{} // backupNexthops is added in frr7.4
offset, err = b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, true)
if err != nil {
return err
if b.Message&messageBackupNexthops.ToEach(version) > 0 {
offset, err := b.decodeMessageNexthopFromBytes(data[pos:], version, softwareName, true)
if err != nil {
return err
}
pos += offset
}
pos += offset
// version 5 only, In version 6, EvpnRoute is processed in MessageNexthop
if version == 5 && b.Flags&flagEvpnRoute.ToEach(version, softwareName) > 0 {
b.Nexthops = append(b.Nexthops, evpnNexthop)
}
if version < 5 && b.Message&messageIFIndex > 0 { // version 4, 3, 2
if pos+1 > rest {
return fmt.Errorf("MessageIFIndex message length invalid pos:%d rest:%d", pos, rest)
@@ -2792,17 +2936,27 @@ func (b *NexthopRegisterBody) string(version uint8, softwareName string) string
// NexthopUpdateBody uses same data structure as IPRoute (zapi_route) after frr4 (Zapi5)
type NexthopUpdateBody IPRouteBody
// Ref: send_client in zebra/zebra_rnh.c of Quagga1.2&FRR3&FRR5(ZAPI3&4$5)
// Ref: send_client in zebra/zebra_rnh.c of Quagga1.2&FRR3&FRR5(ZAPI3&4$5) and befre FRR7.4
// Ref: zebra_send_rnh_update zebra/zebra_rnh.c of FRR7.5
func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byte, error) {
var buf []byte
offset := 0
if version == 6 && softwareName == "" { // after frr7.5
buf = make([]byte, 7)
binary.BigEndian.PutUint32(buf, uint32(b.Message))
offset += 4
} else { // before frr7.4
buf = make([]byte, 3)
}
// Address Family (2 bytes)
buf := make([]byte, 3)
binary.BigEndian.PutUint16(buf, uint16(b.Prefix.Family))
binary.BigEndian.PutUint16(buf[offset:], uint16(b.Prefix.Family))
addrByteLen, err := addressByteLength(b.Prefix.Family)
if err != nil {
return nil, err
}
buf[2] = byte(addrByteLen * 8)
buf[offset+2] = byte(addrByteLen * 8)
// Prefix Length (1 byte) + Prefix (variable)
switch b.Prefix.Family {
case syscall.AF_INET:
@@ -2812,6 +2966,11 @@ func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byt
default:
return nil, fmt.Errorf("invalid address family: %d", b.Prefix.Family)
}
if b.Message&messageSRTE > 0 { // frr 7.5
tmpbuf := make([]byte, 4)
binary.BigEndian.PutUint32(tmpbuf, b.srteColor)
buf = append(buf, tmpbuf...)
}
if version >= 5 {
// Type (1 byte) (if version>=5)
// instance (2 bytes) (if version>=5)
@@ -2837,6 +2996,11 @@ func (b *NexthopUpdateBody) serialize(version uint8, softwareName string) ([]byt
// Ref: bgp_parse_nexthop_update in bgpd/bgp_nht.c of Quagga1.2&FRR3 (ZAPI3&4)
// Ref: zapi_nexthop_update_decode in lib/zclient.c of FRR5.x (ZAPI5)
func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, softwareName string) error {
if version == 6 && softwareName == "" { // frr7.5
//frr7.5: STREAM_GETL(s, nhr->message);
b.Message = MessageFlag(binary.BigEndian.Uint32(data[0:4]))
data = data[4:]
}
// Address Family (2 bytes)
prefixFamily := binary.BigEndian.Uint16(data[0:2])
b.Prefix.Family = uint8(prefixFamily)
@@ -2851,6 +3015,11 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
b.Prefix.Prefix = ipFromFamily(b.Prefix.Family, data[offset:offset+addrByteLen])
offset += addrByteLen
if b.Message&messageSRTE > 0 { // frr 7.5
b.srteColor = binary.BigEndian.Uint32(data[offset : offset+4])
offset += 4
}
if version > 4 {
b.Type = RouteType(data[offset])
b.instance = binary.BigEndian.Uint16(data[offset+1 : offset+3])
@@ -2876,7 +3045,7 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
processFlag := nexthopProcessFlag(nexthopHasType)
if version == 6 {
switch softwareName {
case "":
case "", "frr7.3":
processFlag |= (nexthopHasVrfID | nexthopHasFlag | nexthopProcessIPToIPIFindex)
case "frr7.0", "frr7.2":
processFlag |= (nexthopHasVrfID | nexthopProcessIPToIPIFindex)
@@ -2885,20 +3054,20 @@ func (b *NexthopUpdateBody) decodeFromBytes(data []byte, version uint8, software
}
} else if version == 5 {
switch softwareName {
case "frr5", "":
case "":
processFlag |= nexthopProcessIPToIPIFindex
}
} else if version < 4 { // quagga
processFlag |= nexthopProcessIFnameToIFindex
}
message := MessageFlag(0)
// after frr7.3, MessageLabel is deleted
if (version == 6 && !(softwareName == "frr7.3" || softwareName == "")) ||
(version == 5 && (softwareName == "frr5" || softwareName == "")) {
message |= MessageLabel
(version == 5 && softwareName == "") {
b.Message |= MessageLabel
}
nexthopsByteLen, err := decodeNexthops(&b.Nexthops, data[offset:], version, softwareName, b.Prefix.Family, numNexthop, processFlag, message, Flag(0), nexthopType(0))
nexthopsByteLen, err := decodeNexthops(&b.Nexthops, data[offset:], version, softwareName, b.Prefix.Family, numNexthop, processFlag, b.Message, Flag(0), nexthopType(0))
if err != nil {
return err
}

File diff suppressed because it is too large Load Diff

View File

@@ -52,7 +52,7 @@ func (s *TLV) DecodeFromBytes(data []byte) ([]byte, error) {
p++
s.Length = binary.BigEndian.Uint16(data[p : p+2])
if len(data) < s.Len() {
if s.Len() < prefixSIDtlvHdrLen || len(data) < s.Len() {
return nil, malformedAttrListErr("decoding failed: Prefix SID TLV malformed")
}

View File

@@ -0,0 +1,967 @@
package bgp
import (
"encoding/binary"
"encoding/json"
"fmt"
"net"
"strconv"
api "github.com/osrg/gobgp/api"
)
type SRPolicyNLRI struct {
PrefixDefault
rf RouteFamily
Length uint8
Distinguisher uint32
Color uint32
Endpoint []byte
}
const (
// SRPolicyIPv4NLRILen defines IPv4 SR Policy NLRI portion length in bits
SRPolicyIPv4NLRILen = 96
// SRPolicyIPv6NLRILen defines IPv6 SR Policy NLRI portion length in bits
SRPolicyIPv6NLRILen = 192
)
func (s *SRPolicyNLRI) Flat() map[string]string {
return map[string]string{}
}
func (s *SRPolicyNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...*MarshallingOption) error {
if IsAddPathEnabled(true, rf, options) {
var err error
data, err = s.decodePathIdentifier(data)
if err != nil {
return err
}
}
switch data[0] {
case SRPolicyIPv4NLRILen:
s.rf = RF_SR_POLICY_IPv4
case SRPolicyIPv6NLRILen:
s.rf = RF_SR_POLICY_IPv6
default:
msg := fmt.Sprintf("Invalid length %d for SR Policy NLRI", len(data))
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
p := 0
s.Length = data[p] / 8
p++
s.Distinguisher = binary.BigEndian.Uint32(data[p : p+4])
p += 4
s.Color = binary.BigEndian.Uint32(data[p : p+4])
p += 4
s.Endpoint = data[p:]
return nil
}
func (s *SRPolicyNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) {
buf := make([]byte, 1+s.Length)
p := 0
buf[0] = s.Length * 8
p++
binary.BigEndian.PutUint32(buf[p:p+4], s.Distinguisher)
p += 4
binary.BigEndian.PutUint32(buf[p:p+4], s.Color)
p += 4
copy(buf[p:], s.Endpoint)
if IsAddPathEnabled(false, s.rf, options) {
id, err := s.serializeIdentifier()
if err != nil {
return nil, err
}
return append(id, buf...), nil
}
return buf, nil
}
func (s *SRPolicyNLRI) AFI() uint16 {
afi, _ := RouteFamilyToAfiSafi(s.rf)
return afi
}
func (s *SRPolicyNLRI) SAFI() uint8 {
_, safi := RouteFamilyToAfiSafi(s.rf)
return safi
}
func (s *SRPolicyNLRI) Len(options ...*MarshallingOption) int {
buf, _ := s.Serialize(options...)
return len(buf)
}
func (s *SRPolicyNLRI) String() string {
afi, _ := RouteFamilyToAfiSafi(s.rf)
var endp string
switch afi {
case AFI_IP:
endp = net.IP(s.Endpoint).To4().String()
case AFI_IP6:
endp = net.IP(s.Endpoint).To16().String()
default:
endp = "[" + string(s.Endpoint) + "]"
}
return fmt.Sprintf("{ Length: %d (bytes), Distinguisher: %d, Color %d, Endpoint: %s }", s.Length, s.Distinguisher, s.Color, endp)
}
func (s *SRPolicyNLRI) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Length uint8 `json:"length"`
Distinguisher uint32 `json:"distinguisher"`
Color uint32 `json:"color"`
Endpoint string `json:"endpoint"`
}{
Length: s.Length,
Distinguisher: s.Distinguisher,
Color: s.Color,
Endpoint: string(s.Endpoint),
})
}
type SRPolicyIPv4 struct {
SRPolicyNLRI
}
func (s *SRPolicyIPv4) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
return s.decodeFromBytes(s.rf, data)
}
func NewSRPolicyIPv4(l uint32, d uint32, c uint32, ep []byte) *SRPolicyIPv4 {
return &SRPolicyIPv4{
SRPolicyNLRI: SRPolicyNLRI{
rf: RF_SR_POLICY_IPv4,
Length: uint8(l / 8),
Distinguisher: d,
Color: c,
Endpoint: ep,
},
}
}
type SRPolicyIPv6 struct {
SRPolicyNLRI
}
func (s *SRPolicyIPv6) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
return s.decodeFromBytes(s.rf, data)
}
func NewSRPolicyIPv6(l uint32, d uint32, c uint32, ep []byte) *SRPolicyIPv6 {
return &SRPolicyIPv6{
SRPolicyNLRI: SRPolicyNLRI{
rf: RF_SR_POLICY_IPv6,
Length: uint8(l / 8),
Distinguisher: d,
Color: c,
Endpoint: ep,
},
}
}
type TunnelEncapSubTLVSRPreference struct {
TunnelEncapSubTLV
Flags uint8
Preference uint32
}
func (t *TunnelEncapSubTLVSRPreference) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return err
}
// Second byte carries the length of SR Preference SubTLV
if t.Length != 6 {
msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRPreference length: %d", t.Length)
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
t.Flags = value[0]
t.Preference = binary.BigEndian.Uint32(value[2:6])
return nil
}
func (t *TunnelEncapSubTLVSRPreference) Serialize() ([]byte, error) {
buf := make([]byte, 6)
buf[0] = t.Flags
binary.BigEndian.PutUint32(buf[2:6], t.Preference)
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRPreference) String() string {
return fmt.Sprintf("{Flags: 0x%02x, Preference: %d}", t.Flags, t.Preference)
}
func (t *TunnelEncapSubTLVSRPreference) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Flags uint8 `json:"flags"`
Preference uint32 `json:"preference"`
}{
Type: t.Type,
Flags: t.Flags,
Preference: t.Preference,
})
}
func NewTunnelEncapSubTLVSRPreference(flags uint32, preference uint32) *TunnelEncapSubTLVSRPreference {
return &TunnelEncapSubTLVSRPreference{
TunnelEncapSubTLV: TunnelEncapSubTLV{
Type: ENCAP_SUBTLV_TYPE_SRPREFERENCE,
Length: 6,
},
Flags: uint8(flags),
Preference: preference,
}
}
type TunnelEncapSubTLVSRPriority struct {
TunnelEncapSubTLV
Priority uint8
}
func (t *TunnelEncapSubTLVSRPriority) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return err
}
// Second byte carries the length of SR Preference SubTLV
if t.Length != 2 {
msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRPriority length: %d", t.Length)
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
t.Priority = value[0]
return nil
}
func (t *TunnelEncapSubTLVSRPriority) Serialize() ([]byte, error) {
buf := make([]byte, 1+1)
buf[0] = t.Priority
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRPriority) String() string {
return fmt.Sprintf("{Priority: %d}", t.Priority)
}
func (t *TunnelEncapSubTLVSRPriority) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Priority uint8 `json:"priority"`
}{
Type: t.Type,
Priority: t.Priority,
})
}
func NewTunnelEncapSubTLVSRPriority(priority uint8) *TunnelEncapSubTLVSRPriority {
return &TunnelEncapSubTLVSRPriority{
TunnelEncapSubTLV: TunnelEncapSubTLV{
Type: ENCAP_SUBTLV_TYPE_SRPRIORITY,
Length: 2,
},
Priority: priority,
}
}
type TunnelEncapSubTLVSRCandidatePathName struct {
TunnelEncapSubTLV
CandidatePathName string
}
func (t *TunnelEncapSubTLVSRCandidatePathName) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return err
}
// Skip Reserved byte
t.CandidatePathName = string(value[1:t.TunnelEncapSubTLV.Len()])
return nil
}
func (t *TunnelEncapSubTLVSRCandidatePathName) Serialize() ([]byte, error) {
buf := make([]byte, 1+len(t.CandidatePathName))
copy(buf[1:], t.CandidatePathName)
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRCandidatePathName) String() string {
return fmt.Sprintf("{Candidate Path Name: %s}", t.CandidatePathName)
}
func (t *TunnelEncapSubTLVSRCandidatePathName) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
CandidatePathName string `json:"candidate_path_name"`
}{
Type: t.Type,
CandidatePathName: t.CandidatePathName,
})
}
func NewTunnelEncapSubTLVSRCandidatePathName(cpn string) *TunnelEncapSubTLVSRCandidatePathName {
return &TunnelEncapSubTLVSRCandidatePathName{
TunnelEncapSubTLV: TunnelEncapSubTLV{
Type: ENCAP_SUBTLV_TYPE_SRCANDIDATE_PATH_NAME,
Length: uint16(len(cpn) + 1), // length of Candidate Path name string + 1 Reserved byte
},
CandidatePathName: cpn,
}
}
type SRENLPValue uint8
const (
// ENLPType1 Indicates to push an IPv4 Explicit NULL label on an unlabeled IPv4
// packet, but do not push an IPv6 Explicit NULL label on an
// unlabeled IPv6 packet.
ENLPType1 SRENLPValue = 1
// ENLPType2 Indicates to push an IPv6 Explicit NULL label on an unlabeled IPv6
// packet, but do not push an IPv4 Explicit NULL label on an
// unlabeled IPv4 packet.
ENLPType2 SRENLPValue = 2
// ENLPType3 Indicates to push an IPv4 Explicit NULL label on an unlabeled IPv4
// packet, and push an IPv6 Explicit NULL label on an unlabeled
// IPv6 packet.
ENLPType3 SRENLPValue = 3
// ENLPType4 Indicates to not push an Explicit NULL label.
ENLPType4 SRENLPValue = 4
)
type TunnelEncapSubTLVSRENLP struct {
TunnelEncapSubTLV
Flags uint8
ENLP SRENLPValue
}
func (t *TunnelEncapSubTLVSRENLP) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return err
}
// Second byte carries the length of SR Preference SubTLV
if t.Length != 3 {
msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRENLP length: %d", t.Length)
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
t.Flags = value[0]
switch SRENLPValue(value[2]) {
case ENLPType1:
case ENLPType2:
case ENLPType3:
case ENLPType4:
default:
msg := fmt.Sprintf("Invalid ENLP Type: %d", value[2])
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
t.ENLP = SRENLPValue(value[2])
return nil
}
func (t *TunnelEncapSubTLVSRENLP) Serialize() ([]byte, error) {
buf := make([]byte, t.Length)
buf[0] = t.Flags
buf[2] = byte(t.ENLP)
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRENLP) String() string {
return fmt.Sprintf("{Flags: 0x%02x, ENLP Type: %d}", t.Flags, t.ENLP)
}
func (t *TunnelEncapSubTLVSRENLP) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Flags uint8 `json:"flags"`
ENLP uint8 `json:"enlp"`
}{
Type: t.Type,
Flags: t.Flags,
ENLP: uint8(t.ENLP),
})
}
func NewTunnelEncapSubTLVSRENLP(flags uint32, enlp SRENLPValue) *TunnelEncapSubTLVSRENLP {
return &TunnelEncapSubTLVSRENLP{
TunnelEncapSubTLV: TunnelEncapSubTLV{
Type: ENCAP_SUBTLV_TYPE_SRENLP,
Length: 3,
},
Flags: uint8(flags),
ENLP: enlp,
}
}
type BSID struct {
Value []byte
}
func (b *BSID) String() string {
switch len(b.Value) {
case 0:
return "n/a"
case 4:
bsid := binary.BigEndian.Uint32(b.Value)
bsid >>= 12
return strconv.Itoa(int(bsid))
case 16:
return net.IP(b.Value).To16().String()
default:
return "invalid"
}
}
func (b *BSID) Serialize() []byte {
return b.Value
}
func (b *BSID) Len() int {
return len(b.Value)
}
func NewBSID(v []byte) (*BSID, error) {
var bsid *BSID
switch len(v) {
case 0:
case 4:
t := binary.BigEndian.Uint32(v)
t <<= 12
bsid = &BSID{
Value: make([]byte, len(v)),
}
binary.BigEndian.PutUint32(bsid.Value, t)
case 16:
bsid = &BSID{
Value: make([]byte, len(v)),
}
copy(bsid.Value, v)
default:
return nil, fmt.Errorf("invalid length %d", len(v))
}
return bsid, nil
}
type TunnelEncapSubTLVSRBSID struct {
TunnelEncapSubTLV
Flags uint8
BSID *BSID
}
func (t *TunnelEncapSubTLVSRBSID) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
// Check Sub TLV length, only 3 possible length are allowed
switch t.Length {
case 2: // No BSID, do not initializing BSID struct
case 6:
fallthrough
case 18:
t.BSID = &BSID{
Value: make([]byte, t.Length-2),
}
copy(t.BSID.Value, value[2:t.Length])
default:
msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRBSID length: %d", t.Length)
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
t.Flags = value[0]
return nil
}
func (t *TunnelEncapSubTLVSRBSID) Serialize() ([]byte, error) {
l := 2
if t.BSID != nil {
l += t.BSID.Len()
}
buf := make([]byte, l) // 1st byte Flags, 2nd byte Reserved, 3rd+ BSID
buf[0] = t.Flags
if t.BSID != nil {
bsid := t.BSID.Serialize()
copy(buf[2:], bsid)
}
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRBSID) String() string {
return fmt.Sprintf("{S-Flag: %t, I-Flag: %t, BSID: %s}", t.Flags&0x80 == 0x80, t.Flags&0x40 == 0x40, t.BSID.String())
}
func (t *TunnelEncapSubTLVSRBSID) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Flags uint8 `json:"flags"`
BSID string `json:"binding_sid,omitempty"`
}{
Type: t.Type,
Flags: t.Flags,
BSID: t.BSID.String(),
})
}
type TunnelEncapSubTLVSRv6BSID struct {
TunnelEncapSubTLV
Flags uint8
BSID *BSID
EPBAS *SRv6EndpointBehaviorStructure
}
func (t *TunnelEncapSubTLVSRv6BSID) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
t.Flags = value[0]
t.BSID, err = NewBSID(value[2:t.Length])
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
return nil
}
func (t *TunnelEncapSubTLVSRv6BSID) Serialize() ([]byte, error) {
buf := make([]byte, t.Length)
buf[0] = t.Flags
copy(buf[2:t.BSID.Len()], t.BSID.Serialize())
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRv6BSID) String() string {
return fmt.Sprintf("{S-Flag: %t, I-Flag: %t, B-Flag: %t, BSID: %s}", t.Flags&0x80 == 0x80, t.Flags&0x40 == 0x40, t.Flags&0x20 == 0x20, t.BSID.String())
}
func (t *TunnelEncapSubTLVSRv6BSID) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Flags uint8 `json:"flags"`
BSID string `json:"binding_sid,omitempty"`
}{
Type: t.Type,
Flags: t.Flags,
BSID: t.BSID.String(),
})
}
// SegmentType defines a type of Segment in Segment List
type SegmentType int
const (
// TypeA Segment Sub-TLV encodes a single SR-MPLS SID
TypeA SegmentType = 1
// TypeB Segment Sub-TLV encodes a single SRv6 SID.
TypeB SegmentType = 13
// TypeC Segment Sub-TLV encodes an IPv4 node address, SR Algorithm
// and an optional SR-MPLS SID
TypeC SegmentType = 3
// TypeD Segment Sub-TLV encodes an IPv6 node address, SR Algorithm
// and an optional SR-MPLS SID.
TypeD SegmentType = 4
// TypeE Segment Sub-TLV encodes an IPv4 node address, a local
// interface Identifier (Local Interface ID) and an optional SR-MPLS
// SID.
TypeE SegmentType = 5
// TypeF Segment Sub-TLV encodes an adjacency local address, an
// adjacency remote address and an optional SR-MPLS SID.
TypeF SegmentType = 6
// TypeG Segment Sub-TLV encodes an IPv6 Link Local adjacency with
// IPv6 local node address, a local interface identifier (Local
// Interface ID), IPv6 remote node address , a remote interface
// identifier (Remote Interface ID) and an optional SR-MPLS SID.
TypeG SegmentType = 7
// TypeH Segment Sub-TLV encodes an adjacency local address, an
// adjacency remote address and an optional SR-MPLS SID.
TypeH SegmentType = 8
// TypeI Segment Sub-TLV encodes an IPv6 node address, SR Algorithm
// and an optional SRv6 SID.
TypeI SegmentType = 14
// TypeJ Segment Sub-TLV encodes an IPv6 Link Local adjacency with
// local node address, a local interface identifier (Local Interface
// ID), remote IPv6 node address, a remote interface identifier (Remote
// Interface ID) and an optional SRv6 SID.
TypeJ SegmentType = 15
// TypeK Segment Sub-TLV encodes an adjacency local address, an
// adjacency remote address and an optional SRv6 SID.
TypeK SegmentType = 16
)
// Weight sub-TLV specifies the weight associated to a given segment list.
type SegmentListWeight struct {
TunnelEncapSubTLV
Flags uint8
Weight uint32
}
func (s *SegmentListWeight) DecodeFromBytes(data []byte) error {
value, err := s.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
s.Flags = value[0]
s.Weight = binary.BigEndian.Uint32(value[2:6])
return nil
}
func (s *SegmentListWeight) Serialize() ([]byte, error) {
buf := make([]byte, 6)
buf[0] = s.Flags
binary.BigEndian.PutUint32(buf[2:6], s.Weight)
return s.TunnelEncapSubTLV.Serialize(buf)
}
func (s *SegmentListWeight) String() string {
return fmt.Sprintf("{Flags: 0x%02x, Weight: %d}", s.Flags, s.Weight)
}
func (s *SegmentListWeight) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Flags uint8 `json:"flags"`
Weight uint32 `json:"weight,omitempty"`
}{
Type: s.Type,
Flags: s.Flags,
Weight: s.Weight,
})
}
type SegmentTypeA struct {
TunnelEncapSubTLV
Flags uint8
Label uint32
}
func (s *SegmentTypeA) DecodeFromBytes(data []byte) error {
value, err := s.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
s.Flags = value[0]
s.Label = binary.BigEndian.Uint32(value[2:6])
return nil
}
func (s *SegmentTypeA) Serialize() ([]byte, error) {
buf := make([]byte, 6)
buf[0] = s.Flags
binary.BigEndian.PutUint32(buf[2:6], s.Label)
return s.TunnelEncapSubTLV.Serialize(buf)
}
func (s *SegmentTypeA) String() string {
return fmt.Sprintf("{V-flag: %t, A-flag:, %t S-flag: %t, B-flag: %t, Label: %d TC: %d S: %t TTL: %d}",
s.Flags&0x80 == 0x80, s.Flags&0x40 == 0x40, s.Flags&0x20 == 0x20, s.Flags&0x10 == 0x10,
s.Label>>12, s.Label&0x00000e00>>9, s.Label&0x00000100 == 0x00000100, s.Label&0x000000ff)
}
func (s *SegmentTypeA) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
VFlag bool `json:"v_flag"`
AFlag bool `json:"a_flag"`
SFlag bool `json:"s_flag"`
BFlag bool `json:"b_flag"`
Label uint32 `json:"label"`
TC uint8 `json:"tc"`
S bool `json:"s"`
TTL uint8 `json:"ttl"`
}{
Type: s.Type,
VFlag: s.Flags&0x80 == 0x80,
AFlag: s.Flags&0x40 == 0x40,
SFlag: s.Flags&0x20 == 0x20,
BFlag: s.Flags&0x10 == 0x10,
Label: s.Label >> 12,
TC: uint8(s.Label & 0x00000e00 >> 9),
S: s.Label&0x00000100 == 0x00000100,
TTL: uint8(s.Label & 0x000000ff),
})
}
type SRBehavior int32
const (
RESERVED SRBehavior = SRBehavior(api.SRv6Behavior_RESERVED)
END SRBehavior = SRBehavior(api.SRv6Behavior_END)
END_WITH_PSP SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_PSP)
END_WITH_USP SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_USP)
END_WITH_PSP_USP SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_PSP_USP)
ENDX SRBehavior = SRBehavior(api.SRv6Behavior_ENDX)
ENDX_WITH_PSP SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_PSP)
ENDX_WITH_USP SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_USP)
ENDX_WITH_PSP_USP SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_PSP_USP)
ENDT SRBehavior = SRBehavior(api.SRv6Behavior_ENDT)
ENDT_WITH_PSP SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_PSP)
ENDT_WITH_USP SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_USP)
ENDT_WITH_PSP_USP SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_PSP_USP)
END_B6_ENCAPS SRBehavior = SRBehavior(api.SRv6Behavior_END_B6_ENCAPS)
END_BM SRBehavior = SRBehavior(api.SRv6Behavior_END_BM)
END_DX6 SRBehavior = SRBehavior(api.SRv6Behavior_END_DX6)
END_DX4 SRBehavior = SRBehavior(api.SRv6Behavior_END_DX4)
END_DT6 SRBehavior = SRBehavior(api.SRv6Behavior_END_DT6)
END_DT4 SRBehavior = SRBehavior(api.SRv6Behavior_END_DT4)
END_DT46 SRBehavior = SRBehavior(api.SRv6Behavior_END_DT46)
END_DX2 SRBehavior = SRBehavior(api.SRv6Behavior_END_DX2)
END_DX2V SRBehavior = SRBehavior(api.SRv6Behavior_END_DX2V)
END_DT2U SRBehavior = SRBehavior(api.SRv6Behavior_RESERVED)
END_DT2M SRBehavior = SRBehavior(api.SRv6Behavior_END_DT2M)
END_B6_ENCAPS_Red SRBehavior = SRBehavior(api.SRv6Behavior_END_B6_ENCAPS_Red)
END_WITH_USD SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_USD)
END_WITH_PSP_USD SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_PSP_USD)
END_WITH_USP_USD SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_USP_USD)
END_WITH_PSP_USP_USD SRBehavior = SRBehavior(api.SRv6Behavior_END_WITH_PSP_USP_USD)
ENDX_WITH_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_USD)
ENDX_WITH_PSP_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_PSP_USD)
ENDX_WITH_USP_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_USP_USD)
ENDX_WITH_PSP_USP_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDX_WITH_PSP_USP_USD)
ENDT_WITH_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_USD)
ENDT_WITH_PSP_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_PSP_USD)
ENDT_WITH_USP_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_USP_USD)
ENDT_WITH_PSP_USP_USD SRBehavior = SRBehavior(api.SRv6Behavior_ENDT_WITH_PSP_USP_USD)
)
type SRv6EndpointBehaviorStructure struct {
Behavior SRBehavior
BlockLen uint8
NodeLen uint8
FuncLen uint8
ArgLen uint8
}
func (s *SRv6EndpointBehaviorStructure) DecodeFromBytes(data []byte) error {
if len(data) < 8 {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Malformed BGP message")
}
behavior := binary.BigEndian.Uint16(data[0:2])
s.Behavior = SRBehavior(behavior)
s.BlockLen = data[4]
s.NodeLen = data[5]
s.FuncLen = data[6]
s.ArgLen = data[7]
return nil
}
func (s *SRv6EndpointBehaviorStructure) Serialize() ([]byte, error) {
buf := make([]byte, 8)
binary.BigEndian.PutUint16(buf[0:2], uint16(s.Behavior))
buf[4] = s.BlockLen
buf[5] = s.NodeLen
buf[6] = s.FuncLen
buf[7] = s.ArgLen
return buf, nil
}
func (s *SRv6EndpointBehaviorStructure) String() string {
return fmt.Sprintf("{Behavior: %s, BlockLen: %d, NodeLen: %d, FuncLen: %d, ArgLen: %d}",
api.SRv6Behavior(s.Behavior).String(), s.BlockLen, s.NodeLen, s.FuncLen, s.ArgLen)
}
func (s *SRv6EndpointBehaviorStructure) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Behavior SRBehavior `json:"behavior"`
BlockLen uint8 `json:"block_Len"`
NodeLen uint8 `json:"node_len"`
FuncLen uint8 `json:"func_len"`
ArgLen uint8 `json:"arg_len"`
}{
Behavior: s.Behavior,
BlockLen: s.BlockLen,
NodeLen: s.NodeLen,
FuncLen: s.FuncLen,
ArgLen: s.ArgLen,
})
}
type SegmentTypeB struct {
TunnelEncapSubTLV
Flags uint8
SID []byte
SRv6EBS *SRv6EndpointBehaviorStructure
}
func (s *SegmentTypeB) DecodeFromBytes(data []byte) error {
value, err := s.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
if len(value) < 18 {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Malformed BGP message")
}
s.Flags = value[0]
s.SID = value[2:18]
if len(value) == 26 {
s.SRv6EBS = &SRv6EndpointBehaviorStructure{}
err = s.SRv6EBS.DecodeFromBytes(value[18:])
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
}
return nil
}
func (s *SegmentTypeB) Serialize() ([]byte, error) {
buf := make([]byte, 18)
buf[0] = s.Flags
copy(buf[2:], s.SID)
if s.SRv6EBS != nil {
if ebs, _ := s.SRv6EBS.Serialize(); ebs != nil {
buf = append(buf, ebs...)
}
}
return s.TunnelEncapSubTLV.Serialize(buf)
}
func (s *SegmentTypeB) String() string {
if s.SRv6EBS == nil {
return fmt.Sprintf("{V-flag: %t, A-flag:, %t S-flag: %t, B-flag: %t, Sid: %s}",
s.Flags&0x80 == 0x80, s.Flags&0x40 == 0x40, s.Flags&0x20 == 0x20, s.Flags&0x10 == 0x10, net.IP(s.SID).To16().String())
} else {
return fmt.Sprintf("{V-flag: %t, A-flag:, %t S-flag: %t, B-flag: %t, Sid: %s, Ebs: %s}",
s.Flags&0x80 == 0x80, s.Flags&0x40 == 0x40, s.Flags&0x20 == 0x20, s.Flags&0x10 == 0x10, net.IP(s.SID).To16().String(),
s.SRv6EBS.String())
}
}
func (s *SegmentTypeB) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
VFlag bool `json:"v_flag"`
AFlag bool `json:"a_flag"`
SFlag bool `json:"s_flag"`
BFlag bool `json:"b_flag"`
Sid string `json:"sid"`
SRv6EBS *SRv6EndpointBehaviorStructure `json:"endpointBehaviorStructure"`
}{
Type: s.Type,
VFlag: s.Flags&0x80 == 0x80,
AFlag: s.Flags&0x40 == 0x40,
SFlag: s.Flags&0x20 == 0x20,
BFlag: s.Flags&0x10 == 0x10,
Sid: net.IP(s.SID).To16().String(),
SRv6EBS: s.SRv6EBS,
})
}
const (
// SegmentListSubTLVWeight defines code for Segment List's Weight sub-TLV
SegmentListSubTLVWeight = 9
)
type TunnelEncapSubTLVSRSegmentList struct {
TunnelEncapSubTLV
Weight *SegmentListWeight
Segments []TunnelEncapSubTLVInterface
}
func (t *TunnelEncapSubTLVSRSegmentList) DecodeFromBytes(data []byte) error {
value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data)
if err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
if len(value) < 1 {
return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Malformed BGP message")
}
// Skip reserved byte to access inner SubTLV type
value = value[1:]
var segments []TunnelEncapSubTLVInterface
p := 0
for p < t.TunnelEncapSubTLV.Len()-4 {
var segment TunnelEncapSubTLVInterface
switch SegmentType(value[0]) {
case SegmentListSubTLVWeight:
t.Weight = &SegmentListWeight{}
if err := t.Weight.DecodeFromBytes(value); err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
p += t.Weight.TunnelEncapSubTLV.Len()
value = value[t.Weight.TunnelEncapSubTLV.Len():]
continue
case TypeA:
segment = &SegmentTypeA{}
if err := segment.DecodeFromBytes(value); err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
case TypeB:
segment = &SegmentTypeB{}
if err := segment.DecodeFromBytes(value); err != nil {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error())
}
case TypeC:
fallthrough
case TypeD:
fallthrough
case TypeE:
fallthrough
case TypeF:
fallthrough
case TypeG:
fallthrough
case TypeH:
fallthrough
case TypeI:
fallthrough
case TypeJ:
fallthrough
case TypeK:
msg := fmt.Sprintf("Invalid SR Policy Segment SubTLV %d is not yet supported", value[0])
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
default:
msg := fmt.Sprintf("Invalid SR Policy Segment List SubTLV %d", value[0])
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg)
}
segments = append(segments, segment)
p += segment.Len()
value = value[segment.Len():]
}
if len(segments) == 0 {
t.Segments = nil
} else {
t.Segments = segments
}
return nil
}
func (t *TunnelEncapSubTLVSRSegmentList) Serialize() ([]byte, error) {
buf := make([]byte, 0)
// Add reserved byte
buf = append(buf, 0x0)
if t.Weight != nil {
wbuf, err := t.Weight.Serialize()
if err != nil {
return nil, err
}
buf = append(buf, wbuf...)
}
for _, s := range t.Segments {
sbuf, err := s.Serialize()
if err != nil {
return nil, err
}
buf = append(buf, sbuf...)
}
return t.TunnelEncapSubTLV.Serialize(buf[:])
}
func (t *TunnelEncapSubTLVSRSegmentList) String() string {
msg := "{"
if t.Weight != nil {
msg += "Weight: " + t.Weight.String() + ","
}
msg += "Segment List: [ "
for _, s := range t.Segments {
msg += s.String() + ","
}
msg += " ] }"
return msg
}
func (t *TunnelEncapSubTLVSRSegmentList) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Type EncapSubTLVType `json:"type"`
Weight *SegmentListWeight
Segments []TunnelEncapSubTLVInterface
}{
Type: t.Type,
Weight: t.Weight,
Segments: t.Segments,
})
}

View File

@@ -313,7 +313,7 @@ func ValidateBGPMessage(m *BGPMessage) error {
return nil
}
func ValidateOpenMsg(m *BGPOpen, expectedAS uint32) (uint32, error) {
func ValidateOpenMsg(m *BGPOpen, expectedAS uint32, myAS uint32, myId net.IP) (uint32, error) {
if m.Version != 4 {
return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_VERSION_NUMBER, nil, fmt.Sprintf("unsupported version %d", m.Version))
}
@@ -331,6 +331,20 @@ func ValidateOpenMsg(m *BGPOpen, expectedAS uint32) (uint32, error) {
}
}
}
// rfc6286 (Autonomous-System-Wide Unique BGP Identifier for BGP-4)
// If the BGP Identifier field of the OPEN message is zero, or if it
// is the same as the BGP Identifier of the local BGP speaker and the
// message is from an internal peer, then the Error Subcode is set to
// "Bad BGP Identifier".
routerId := m.ID
if routerId.IsUnspecified() {
return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_BAD_BGP_IDENTIFIER, nil, fmt.Sprintf("bad BGP identifier %s (0.0.0.0)", routerId.String()))
}
if as == myAS && routerId.Equal(myId) {
return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_BAD_BGP_IDENTIFIER, nil, fmt.Sprintf("bad BGP identifier %s", routerId.String()))
}
if expectedAS != 0 && as != expectedAS {
return 0, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_BAD_PEER_AS, nil, fmt.Sprintf("as number mismatch expected %d, received %d", expectedAS, as))
}

View File

@@ -164,12 +164,11 @@ func NewBMPRouteMonitoring(p BMPPeerHeader, update *bgp.BGPMessage) *BMPMessage
}
func (body *BMPRouteMonitoring) ParseBody(msg *BMPMessage, data []byte) error {
update, err := bgp.ParseBGPMessage(data)
if err != nil {
return err
}
body.BGPUpdate = update
return nil
var err error
body.BGPUpdate, err = bgp.ParseBGPMessage(data)
return err
}
func (body *BMPRouteMonitoring) Serialize() ([]byte, error) {
@@ -225,7 +224,7 @@ func (s *BMPStatsTLV32) ParseValue(data []byte) error {
if s.Length != 4 {
return fmt.Errorf("invalid length: %d bytes (%d bytes expected)", s.Length, 4)
}
s.Value = binary.BigEndian.Uint32(data[:8])
s.Value = binary.BigEndian.Uint32(data[:4])
return nil
}
@@ -1065,8 +1064,13 @@ func ParseBMPMessage(data []byte) (msg *BMPMessage, err error) {
err = msg.Body.ParseBody(msg, data)
if err != nil {
if msg.Header.Type == BMP_MSG_ROUTE_MONITORING {
return msg, err
}
return nil, err
}
return msg, nil
}

View File

@@ -115,17 +115,17 @@ func (b *bmpClient) loop() {
}
if func() bool {
ops := []watchOption{watchPeerState(true)}
ops := []watchOption{watchPeerState(true, false)}
if b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_BOTH {
log.WithFields(
log.Fields{"Topic": "bmp"},
).Warn("both option for route-monitoring-policy is obsoleted")
}
if b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_PRE_POLICY || b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_ALL {
ops = append(ops, watchUpdate(true))
ops = append(ops, watchUpdate(true, ""))
}
if b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_POST_POLICY || b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_ALL {
ops = append(ops, watchPostUpdate(true))
ops = append(ops, watchPostUpdate(true, ""))
}
if b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_LOCAL_RIB || b.c.RouteMonitoringPolicy == config.BMP_ROUTE_MONITORING_POLICY_TYPE_ALL {
ops = append(ops, watchBestPath(true))

View File

@@ -21,6 +21,7 @@ import (
"io"
"math/rand"
"net"
"os"
"strconv"
"sync"
"syscall"
@@ -714,8 +715,11 @@ func capAddPathFromConfig(pConf *config.Neighbor) bgp.ParameterCapabilityInterfa
}
func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInterface {
fqdn, _ := os.Hostname()
caps := make([]bgp.ParameterCapabilityInterface, 0, 4)
caps = append(caps, bgp.NewCapRouteRefresh())
caps = append(caps, bgp.NewCapFQDN(fqdn, ""))
for _, af := range pConf.AfiSafis {
caps = append(caps, bgp.NewCapMultiProtocol(af.State.Family))
}
@@ -869,7 +873,8 @@ func (h *fsmHandler) afiSafiDisable(rf bgp.RouteFamily) string {
}
func (h *fsmHandler) handlingError(m *bgp.BGPMessage, e error, useRevisedError bool) bgp.ErrorHandling {
handling := bgp.ERROR_HANDLING_NONE
// ineffectual assignment to handling (ineffassign)
var handling bgp.ErrorHandling
if m.Header.Type == bgp.BGP_MSG_UPDATE && useRevisedError {
factor := e.(*bgp.MessageError)
handling = factor.ErrorHandling
@@ -1015,6 +1020,13 @@ func (h *fsmHandler) recvMessageWithError() (*fsmMsg, error) {
case bgp.BGP_MSG_ROUTE_REFRESH:
fmsg.MsgType = fsmMsgRouteRefresh
case bgp.BGP_MSG_UPDATE:
// if the length of h.holdTimerResetCh
// isn't zero, the timer will be reset
// soon anyway.
select {
case h.holdTimerResetCh <- true:
default:
}
body := m.Body.(*bgp.BGPUpdate)
isEBGP := h.fsm.pConf.IsEBGPPeer(h.fsm.gConf)
isConfed := h.fsm.pConf.IsConfederationMember(h.fsm.gConf)
@@ -1266,7 +1278,7 @@ func (h *fsmHandler) opensent(ctx context.Context) (bgp.FSMState, *fsmStateReaso
fsm.lock.RLock()
fsmPeerAS := fsm.pConf.Config.PeerAs
fsm.lock.RUnlock()
peerAs, err := bgp.ValidateOpenMsg(body, fsmPeerAS)
peerAs, err := bgp.ValidateOpenMsg(body, fsmPeerAS, fsm.peerInfo.LocalAS, net.ParseIP(fsm.gConf.Config.RouterId))
if err != nil {
m, _ := fsm.sendNotificationFromErrorMsg(err.(*bgp.MessageError))
return bgp.BGP_FSM_IDLE, newfsmStateReason(fsmInvalidMsg, m, nil)
@@ -1569,6 +1581,14 @@ func (h *fsmHandler) openconfirm(ctx context.Context) (bgp.FSMState, *fsmStateRe
}
func (h *fsmHandler) sendMessageloop(ctx context.Context, wg *sync.WaitGroup) error {
sendToStateReasonCh := func(typ fsmStateReasonType, notif *bgp.BGPMessage) {
// probably doesn't happen but be cautious
select {
case h.stateReasonCh <- *newfsmStateReason(typ, notif, nil):
default:
}
}
defer wg.Done()
conn := h.conn
fsm := h.fsm
@@ -1603,7 +1623,7 @@ func (h *fsmHandler) sendMessageloop(ctx context.Context, wg *sync.WaitGroup) er
err = conn.SetWriteDeadline(time.Now().Add(time.Second * time.Duration(fsm.pConf.Timers.State.NegotiatedHoldTime)))
fsm.lock.RUnlock()
if err != nil {
h.stateReasonCh <- *newfsmStateReason(fsmWriteFailed, nil, nil)
sendToStateReasonCh(fsmWriteFailed, nil)
conn.Close()
return fmt.Errorf("failed to set write deadline")
}
@@ -1617,7 +1637,7 @@ func (h *fsmHandler) sendMessageloop(ctx context.Context, wg *sync.WaitGroup) er
"Data": err,
}).Warn("failed to send")
fsm.lock.RUnlock()
h.stateReasonCh <- *newfsmStateReason(fsmWriteFailed, nil, nil)
sendToStateReasonCh(fsmWriteFailed, nil)
conn.Close()
return fmt.Errorf("closed")
}
@@ -1651,7 +1671,7 @@ func (h *fsmHandler) sendMessageloop(ctx context.Context, wg *sync.WaitGroup) er
}).Warn("sent notification")
fsm.lock.RUnlock()
}
h.stateReasonCh <- *newfsmStateReason(fsmNotificationSent, m, nil)
sendToStateReasonCh(fsmNotificationSent, m)
conn.Close()
return fmt.Errorf("closed")
case bgp.BGP_MSG_UPDATE:

View File

@@ -64,8 +64,9 @@ func (s *server) serve() error {
l := []net.Listener{}
var err error
for _, host := range strings.Split(s.hosts, ",") {
network, address := parseHost(host)
var lis net.Listener
lis, err = net.Listen("tcp", host)
lis, err = net.Listen(network, address)
if err != nil {
log.WithFields(log.Fields{
"Topic": "grpc",
@@ -101,6 +102,38 @@ func (s *server) serve() error {
return nil
}
func (s *server) ListDynamicNeighbor(r *api.ListDynamicNeighborRequest, stream api.GobgpApi_ListDynamicNeighborServer) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
fn := func(dn *api.DynamicNeighbor) {
if err := stream.Send(&api.ListDynamicNeighborResponse{DynamicNeighbor: dn}); err != nil {
cancel()
return
}
}
return s.bgpServer.ListDynamicNeighbor(ctx, r, fn)
}
func (s *server) ListPeerGroup(r *api.ListPeerGroupRequest, stream api.GobgpApi_ListPeerGroupServer) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
fn := func(pg *api.PeerGroup) {
if err := stream.Send(&api.ListPeerGroupResponse{PeerGroup: pg}); err != nil {
cancel()
return
}
}
return s.bgpServer.ListPeerGroup(ctx, r, fn)
}
func parseHost(host string) (string, string) {
const unixScheme = "unix://"
if strings.HasPrefix(host, unixScheme) {
return "unix", host[len(unixScheme):]
}
return "tcp", host
}
func (s *server) ListPeer(r *api.ListPeerRequest, stream api.GobgpApi_ListPeerServer) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -153,11 +186,26 @@ func toPathAPI(binNlri []byte, binPattrs [][]byte, anyNlri *any.Any, anyPattrs [
return p
}
func toPathApi(path *table.Path, v *table.Validation) *api.Path {
func toPathApi(path *table.Path, v *table.Validation, nlri_binary, attribute_binary bool) *api.Path {
nlri := path.GetNlri()
anyNlri := apiutil.MarshalNLRI(nlri)
anyPattrs := apiutil.MarshalPathAttributes(path.GetPathAttrs())
return toPathAPI(nil, nil, anyNlri, anyPattrs, path, v)
var binNlri []byte
if nlri_binary {
binNlri, _ = nlri.Serialize()
}
var binPattrs [][]byte
if attribute_binary {
pa := path.GetPathAttrs()
binPattrs = make([][]byte, 0, len(pa))
for _, a := range pa {
b, e := a.Serialize()
if e == nil {
binPattrs = append(binPattrs, b)
}
}
}
return toPathAPI(binNlri, binPattrs, anyNlri, anyPattrs, path, v)
}
func getValidation(v map[*table.Path]*table.Validation, p *table.Path) *table.Validation {
@@ -281,6 +329,11 @@ func api2Path(resource api.TableType, path *api.Path, isWithdraw bool) (*table.P
return nil, err
}
// TODO (sbezverk) At this poinnt nlri and path attributes are converted to native mode
// need to check if update with SR Policy nlri comes with mandatory route distinguisher
// extended community or NO_ADVERTISE community, with Tunnel Encapsulation Attribute 23
// and tunnel type 15. If it is not the case ignore update and log an error.
pattrs := make([]bgp.PathAttributeInterface, 0)
seen := make(map[bgp.BGPAttrType]struct{})
for _, attr := range attrList {
@@ -295,6 +348,9 @@ func api2Path(resource api.TableType, path *api.Path, isWithdraw bool) (*table.P
case *bgp.PathAttributeNextHop:
nexthop = a.Value.String()
case *bgp.PathAttributeMpReachNLRI:
if len(a.Value) == 0 {
return nil, fmt.Errorf("invalid mp reach attribute")
}
nlri = a.Value[0]
nexthop = a.Nexthop.String()
default:
@@ -486,20 +542,29 @@ func readApplyPolicyFromAPIStruct(c *config.ApplyPolicy, a *api.ApplyPolicy) {
if c == nil || a == nil {
return
}
f := func(a api.RouteAction) config.DefaultPolicyType {
if a == api.RouteAction_ACCEPT {
return config.DEFAULT_POLICY_TYPE_ACCEPT_ROUTE
} else if a == api.RouteAction_REJECT {
return config.DEFAULT_POLICY_TYPE_REJECT_ROUTE
}
return ""
}
if a.ImportPolicy != nil {
c.Config.DefaultImportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ImportPolicy.DefaultAction)]
c.Config.DefaultImportPolicy = f(a.ImportPolicy.DefaultAction)
for _, p := range a.ImportPolicy.Policies {
c.Config.ImportPolicyList = append(c.Config.ImportPolicyList, p.Name)
}
}
if a.ExportPolicy != nil {
c.Config.DefaultExportPolicy = config.IntToDefaultPolicyTypeMap[int(a.ExportPolicy.DefaultAction)]
c.Config.DefaultExportPolicy = f(a.ExportPolicy.DefaultAction)
for _, p := range a.ExportPolicy.Policies {
c.Config.ExportPolicyList = append(c.Config.ExportPolicyList, p.Name)
}
}
if a.InPolicy != nil {
c.Config.DefaultInPolicy = config.IntToDefaultPolicyTypeMap[int(a.InPolicy.DefaultAction)]
c.Config.DefaultInPolicy = f(a.InPolicy.DefaultAction)
for _, p := range a.InPolicy.Policies {
c.Config.InPolicyList = append(c.Config.InPolicyList, p.Name)
}
@@ -668,6 +733,10 @@ func newNeighborFromAPIStruct(a *api.Peer) (*config.Neighbor, error) {
pconf.EbgpMultihop.Config.Enabled = a.EbgpMultihop.Enabled
pconf.EbgpMultihop.Config.MultihopTtl = uint8(a.EbgpMultihop.MultihopTtl)
}
if a.TtlSecurity != nil {
pconf.TtlSecurity.Config.Enabled = a.TtlSecurity.Enabled
pconf.TtlSecurity.Config.TtlMin = uint8(a.TtlSecurity.TtlMin)
}
if a.State != nil {
pconf.State.SessionState = config.SessionState(strings.ToUpper(string(a.State.SessionState)))
pconf.State.AdminState = config.IntToAdminStateMap[int(a.State.AdminState)]
@@ -771,6 +840,10 @@ func newPeerGroupFromAPIStruct(a *api.PeerGroup) (*config.PeerGroup, error) {
pconf.EbgpMultihop.Config.Enabled = a.EbgpMultihop.Enabled
pconf.EbgpMultihop.Config.MultihopTtl = uint8(a.EbgpMultihop.MultihopTtl)
}
if a.TtlSecurity != nil {
pconf.TtlSecurity.Config.Enabled = a.TtlSecurity.Enabled
pconf.TtlSecurity.Config.TtlMin = uint8(a.TtlSecurity.TtlMin)
}
if a.Info != nil {
pconf.State.TotalPaths = a.Info.TotalPaths
pconf.State.TotalPrefixes = a.Info.TotalPrefixes
@@ -808,6 +881,10 @@ func (s *server) AddDynamicNeighbor(ctx context.Context, r *api.AddDynamicNeighb
return &empty.Empty{}, s.bgpServer.AddDynamicNeighbor(ctx, r)
}
func (s *server) DeleteDynamicNeighbor(ctx context.Context, r *api.DeleteDynamicNeighborRequest) (*empty.Empty, error) {
return &empty.Empty{}, s.bgpServer.DeleteDynamicNeighbor(ctx, r)
}
func newPrefixFromApiStruct(a *api.Prefix) (*table.Prefix, error) {
_, prefix, err := net.ParseCIDR(a.IpPrefix)
if err != nil {
@@ -1135,6 +1212,11 @@ func toStatementApi(s *config.Statement) *api.Statement {
Self: true,
}
}
if string(s.Actions.BgpActions.SetNextHop) == "unchanged" {
return &api.NexthopAction{
Unchanged: true,
}
}
return &api.NexthopAction{
Address: string(s.Actions.BgpActions.SetNextHop),
}
@@ -1410,6 +1492,9 @@ func newNexthopActionFromApiStruct(a *api.NexthopAction) (*table.NexthopAction,
if a.Self {
return "self"
}
if a.Unchanged {
return "unchanged"
}
return a.Address
}(),
))
@@ -1757,3 +1842,7 @@ func (s *server) StopBgp(ctx context.Context, r *api.StopBgpRequest) (*empty.Emp
func (s *server) GetTable(ctx context.Context, r *api.GetTableRequest) (*api.GetTableResponse, error) {
return s.bgpServer.GetTable(ctx, r)
}
func (s *server) SetLogLevel(ctx context.Context, r *api.SetLogLevelRequest) (*empty.Empty, error) {
return &empty.Empty{}, s.bgpServer.SetLogLevel(ctx, r)
}

View File

@@ -51,7 +51,7 @@ func (m *mrtWriter) loop() error {
ops := []watchOption{}
switch m.c.DumpType {
case config.MRT_TYPE_UPDATES:
ops = append(ops, watchUpdate(false))
ops = append(ops, watchUpdate(false, ""))
case config.MRT_TYPE_TABLE:
if len(m.c.TableName) > 0 {
ops = append(ops, watchTableName(m.c.TableName))

View File

@@ -57,6 +57,10 @@ func (pg *peerGroup) AddDynamicNeighbor(c *config.DynamicNeighbor) {
pg.dynamicNeighbors[c.Config.Prefix] = c
}
func (pg *peerGroup) DeleteDynamicNeighbor(prefix string) {
delete(pg.dynamicNeighbors, prefix)
}
func newDynamicPeer(g *config.Global, neighborAddress string, pg *config.PeerGroup, loc *table.TableManager, policy *table.RoutingPolicy) *peer {
conf := config.Neighbor{
Config: config.NeighborConfig{
@@ -131,6 +135,15 @@ func (peer *peer) ID() string {
return peer.fsm.pConf.State.NeighborAddress
}
func (peer *peer) RouterID() string {
peer.fsm.lock.RLock()
defer peer.fsm.lock.RUnlock()
if peer.fsm.peerInfo.ID != nil {
return peer.fsm.peerInfo.ID.String()
}
return ""
}
func (peer *peer) TableID() string {
return peer.tableId
}
@@ -348,7 +361,22 @@ func (peer *peer) stopPeerRestarting() {
}
func (peer *peer) filterPathFromSourcePeer(path, old *table.Path) *table.Path {
if peer.ID() != path.GetSource().Address.String() {
// Consider 3 peers - A, B, C and prefix P originated by C. Parallel eBGP
// sessions exist between A & B, and both have a single session with C.
//
// When A receives the withdraw from C, we enter this func for each peer of
// A, with the following:
// peer: [C, B #1, B #2]
// path: new best for P facing B
// old: old best for P facing C
//
// Our comparison between peer identifier and path source ID must be router
// ID-based (not neighbor address), otherwise we will return early. If we
// return early for one of the two sessions facing B
// (whichever is not the new best path), we fail to send a withdraw towards
// B, and the route is "stuck".
// TODO: considerations for RFC6286
if peer.RouterID() != path.GetSource().ID.String() {
return path
}

View File

@@ -23,6 +23,7 @@ import (
"reflect"
"strconv"
"sync"
"syscall"
"time"
"github.com/eapache/channels"
@@ -52,35 +53,56 @@ func (l *tcpListener) Close() error {
}
// avoid mapped IPv6 address
func newTCPListener(address string, port uint32, ch chan *net.TCPConn) (*tcpListener, error) {
func newTCPListener(address string, port uint32, bindToDev string, ch chan *net.TCPConn) (*tcpListener, error) {
proto := "tcp4"
family := syscall.AF_INET
if ip := net.ParseIP(address); ip == nil {
return nil, fmt.Errorf("can't listen on %s", address)
} else if ip.To4() == nil {
proto = "tcp6"
family = syscall.AF_INET6
}
addr, err := net.ResolveTCPAddr(proto, net.JoinHostPort(address, strconv.Itoa(int(port))))
if err != nil {
return nil, err
addr := net.JoinHostPort(address, strconv.Itoa(int(port)))
var lc net.ListenConfig
lc.Control = func(network, address string, c syscall.RawConn) error {
if bindToDev != "" {
err := setBindToDevSockopt(c, bindToDev)
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": addr,
"BindToDev": bindToDev,
}).Warnf("failed to bind Listener to device (%s): %s", bindToDev, err)
return err
}
}
// Note: Set TTL=255 for incoming connection listener in order to accept
// connection in case for the neighbor has TTL Security settings.
err := setsockoptIpTtl(c, family, 255)
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": addr,
}).Warnf("cannot set TTL(=%d) for TCPListener: %s", 255, err)
}
return nil
}
l, err := net.ListenTCP(proto, addr)
l, err := lc.Listen(context.Background(), proto, addr)
if err != nil {
return nil, err
}
// Note: Set TTL=255 for incoming connection listener in order to accept
// connection in case for the neighbor has TTL Security settings.
if err := setListenTCPTTLSockopt(l, 255); err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",
"Key": addr,
}).Warnf("cannot set TTL(=%d) for TCPListener: %s", 255, err)
listener, ok := l.(*net.TCPListener)
if !ok {
err = fmt.Errorf("unexpected connection listener (not for TCP)")
return nil, err
}
closeCh := make(chan struct{})
go func() error {
for {
conn, err := l.AcceptTCP()
conn, err := listener.AcceptTCP()
if err != nil {
close(closeCh)
log.WithFields(log.Fields{
@@ -93,7 +115,7 @@ func newTCPListener(address string, port uint32, ch chan *net.TCPConn) (*tcpList
}
}()
return &tcpListener{
l: l,
l: listener,
ch: closeCh,
}, nil
}
@@ -118,6 +140,7 @@ func GrpcOption(opt []grpc.ServerOption) ServerOption {
}
type BgpServer struct {
apiServer *server
bgpConfig config.Bgp
acceptCh chan *net.TCPConn
incomings []*channels.InfiniteChannel
@@ -158,9 +181,9 @@ func NewBgpServer(opt ...ServerOption) *BgpServer {
s.mrtManager = newMrtManager(s)
if len(opts.grpcAddress) != 0 {
grpc.EnableTracing = false
api := newAPIserver(s, grpc.NewServer(opts.grpcOption...), opts.grpcAddress)
s.apiServer = newAPIserver(s, grpc.NewServer(opts.grpcOption...), opts.grpcAddress)
go func() {
if err := api.serve(); err != nil {
if err := s.apiServer.serve(); err != nil {
log.Fatalf("failed to listen grpc port: %s", err)
}
}()
@@ -169,6 +192,14 @@ func NewBgpServer(opt ...ServerOption) *BgpServer {
return s
}
func (s *BgpServer) Stop() {
s.StopBgp(context.Background(), &api.StopBgpRequest{})
if s.apiServer != nil {
s.apiServer.grpcServer.Stop()
}
}
func (s *BgpServer) addIncoming(ch *channels.InfiniteChannel) {
s.incomings = append(s.incomings, ch)
}
@@ -555,7 +586,7 @@ func filterpath(peer *peer, path, old *table.Path) *table.Path {
return nil
}
if !peer.isRouteServerClient() && isASLoop(peer, path) {
if !peer.isRouteServerClient() && isASLoop(peer, path) && !path.IsLocal() {
return nil
}
return path
@@ -853,8 +884,12 @@ func (s *BgpServer) notifyPostPolicyUpdateWatcher(peer *peer, pathList []*table.
}
func newWatchEventPeerState(peer *peer, m *fsmMsg) *watchEventPeerState {
_, rport := peer.fsm.RemoteHostPort()
laddr, lport := peer.fsm.LocalHostPort()
var laddr string
var rport, lport uint16
if peer.fsm.conn != nil {
_, rport = peer.fsm.RemoteHostPort()
laddr, lport = peer.fsm.LocalHostPort()
}
sentOpen := buildopen(peer.fsm.gConf, peer.fsm.pConf)
peer.fsm.lock.RLock()
recvOpen := peer.fsm.recvOpen
@@ -1296,6 +1331,7 @@ func (s *BgpServer) deleteDynamicNeighbor(peer *peer, oldState bgp.FSMState, e *
peer.fsm.lock.RUnlock()
cleanInfiniteChannel(peer.fsm.outgoingCh)
cleanInfiniteChannel(peer.fsm.incomingCh)
s.delIncoming(peer.fsm.incomingCh)
s.broadcastPeerState(peer, oldState, e)
}
@@ -1696,6 +1732,9 @@ func (s *BgpServer) handleFSMMessage(peer *peer, e *fsmMsg) {
}
func (s *BgpServer) EnableZebra(ctx context.Context, r *api.EnableZebraRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if s.zclient != nil {
return fmt.Errorf("already connected to Zebra")
@@ -1718,6 +1757,9 @@ func (s *BgpServer) EnableZebra(ctx context.Context, r *api.EnableZebraRequest)
}
func (s *BgpServer) AddBmp(ctx context.Context, r *api.AddBmpRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
_, ok := api.AddBmpRequest_MonitoringPolicy_name[int32(r.Policy)]
if !ok {
@@ -1735,6 +1777,9 @@ func (s *BgpServer) AddBmp(ctx context.Context, r *api.AddBmpRequest) error {
}
func (s *BgpServer) DeleteBmp(ctx context.Context, r *api.DeleteBmpRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.bmpManager.deleteServer(&config.BmpServerConfig{
Address: r.Address,
@@ -1744,6 +1789,9 @@ func (s *BgpServer) DeleteBmp(ctx context.Context, r *api.DeleteBmpRequest) erro
}
func (s *BgpServer) StopBgp(ctx context.Context, r *api.StopBgpRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
s.mgmtOperation(func() error {
names := make([]string, 0, len(s.neighborMap))
for k := range s.neighborMap {
@@ -1769,11 +1817,15 @@ func (s *BgpServer) StopBgp(ctx context.Context, r *api.StopBgpRequest) error {
if s.shutdownWG != nil {
s.shutdownWG.Wait()
s.shutdownWG = nil
}
return nil
}
func (s *BgpServer) SetPolicies(ctx context.Context, r *api.SetPoliciesRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
rp, err := newRoutingPolicyFromApiStruct(r)
if err != nil {
return err
@@ -1989,6 +2041,9 @@ func (s *BgpServer) addPathStream(vrfId string, pathList []*table.Path) error {
}
func (s *BgpServer) AddPath(ctx context.Context, r *api.AddPathRequest) (*api.AddPathResponse, error) {
if r == nil || r.Path == nil {
return nil, fmt.Errorf("nil request")
}
var uuidBytes []byte
err := s.mgmtOperation(func() error {
path, err := api2Path(r.TableType, r.Path, false)
@@ -2009,6 +2064,9 @@ func (s *BgpServer) AddPath(ctx context.Context, r *api.AddPathRequest) (*api.Ad
}
func (s *BgpServer) DeletePath(ctx context.Context, r *api.DeletePathRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
deletePathList := make([]*table.Path, 0)
@@ -2082,10 +2140,10 @@ func (s *BgpServer) updatePath(vrfId string, pathList []*table.Path) error {
}
func (s *BgpServer) StartBgp(ctx context.Context, r *api.StartBgpRequest) error {
if r == nil || r.Global == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Global == nil {
return fmt.Errorf("invalid request")
}
g := r.Global
if net.ParseIP(g.RouterId) == nil {
return fmt.Errorf("invalid router-id format: %s", g.RouterId)
@@ -2099,7 +2157,7 @@ func (s *BgpServer) StartBgp(ctx context.Context, r *api.StartBgpRequest) error
if c.Config.Port > 0 {
acceptCh := make(chan *net.TCPConn, 4096)
for _, addr := range c.Config.LocalAddressList {
l, err := newTCPListener(addr, uint32(c.Config.Port), acceptCh)
l, err := newTCPListener(addr, uint32(c.Config.Port), g.BindToDevice, acceptCh)
if err != nil {
return err
}
@@ -2135,7 +2193,10 @@ func (s *BgpServer) listVrf() (l []*table.Vrf) {
return l
}
func (s *BgpServer) ListVrf(ctx context.Context, _ *api.ListVrfRequest, fn func(*api.Vrf)) error {
func (s *BgpServer) ListVrf(ctx context.Context, r *api.ListVrfRequest, fn func(*api.Vrf)) error {
if r == nil {
return fmt.Errorf("nil request")
}
toApi := func(v *table.Vrf) *api.Vrf {
return &api.Vrf{
Name: v.Name,
@@ -2148,7 +2209,10 @@ func (s *BgpServer) ListVrf(ctx context.Context, _ *api.ListVrfRequest, fn func(
var l []*api.Vrf
s.mgmtOperation(func() error {
l = make([]*api.Vrf, 0, len(s.globalRib.Vrfs))
for _, vrf := range s.globalRib.Vrfs {
for name, vrf := range s.globalRib.Vrfs {
if r.Name != "" && r.Name != name {
continue
}
l = append(l, toApi(vrf.Clone()))
}
return nil
@@ -2165,11 +2229,10 @@ func (s *BgpServer) ListVrf(ctx context.Context, _ *api.ListVrfRequest, fn func(
}
func (s *BgpServer) AddVrf(ctx context.Context, r *api.AddVrfRequest) error {
if r == nil || r.Vrf == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Vrf == nil {
return fmt.Errorf("invalid request")
}
name := r.Vrf.Name
id := r.Vrf.Id
@@ -2206,10 +2269,10 @@ func (s *BgpServer) AddVrf(ctx context.Context, r *api.AddVrfRequest) error {
}
func (s *BgpServer) DeleteVrf(ctx context.Context, r *api.DeleteVrfRequest) error {
if r == nil || r.Name == "" {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Name == "" {
return fmt.Errorf("invalid request")
}
name := r.Name
for _, n := range s.neighborMap {
n.fsm.lock.RLock()
@@ -2473,6 +2536,9 @@ func (s *BgpServer) getAdjRib(addr string, family bgp.RouteFamily, in bool, enab
}
func (s *BgpServer) ListPath(ctx context.Context, r *api.ListPathRequest, fn func(*api.Destination)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var tbl *table.Table
var v map[*table.Path]*table.Validation
var filtered map[string]*table.Path
@@ -2520,7 +2586,7 @@ func (s *BgpServer) ListPath(ctx context.Context, r *api.ListPathRequest, fn fun
}
knownPathList := dst.GetAllKnownPathList()
for i, path := range knownPathList {
p := toPathApi(path, getValidation(v, path))
p := toPathApi(path, getValidation(v, path), r.EnableNlriBinary, r.EnableAttributeBinary)
if !table.SelectionOptions.DisableBestPathSelection {
if i == 0 {
switch r.TableType {
@@ -2638,8 +2704,8 @@ func (s *BgpServer) getVrfRibInfo(name string, family bgp.RouteFamily) (info *ta
}
func (s *BgpServer) GetTable(ctx context.Context, r *api.GetTableRequest) (*api.GetTableResponse, error) {
if r == nil {
return nil, fmt.Errorf("invalid request")
if r == nil || r.Family == nil {
return nil, fmt.Errorf("nil request")
}
family := bgp.RouteFamily(0)
if r.Family != nil {
@@ -2674,6 +2740,9 @@ func (s *BgpServer) GetTable(ctx context.Context, r *api.GetTableRequest) (*api.
}
func (s *BgpServer) GetBgp(ctx context.Context, r *api.GetBgpRequest) (*api.GetBgpResponse, error) {
if r == nil {
return nil, fmt.Errorf("nil request")
}
var rsp *api.GetBgpResponse
s.mgmtOperation(func() error {
g := s.bgpConfig.Global
@@ -2691,7 +2760,72 @@ func (s *BgpServer) GetBgp(ctx context.Context, r *api.GetBgpRequest) (*api.GetB
return rsp, nil
}
func (s *BgpServer) ListDynamicNeighbor(ctx context.Context, r *api.ListDynamicNeighborRequest, fn func(neighbor *api.DynamicNeighbor)) error {
if r == nil {
return fmt.Errorf("nil request")
}
toApi := func(dn *config.DynamicNeighbor) *api.DynamicNeighbor {
return &api.DynamicNeighbor{
Prefix: dn.Config.Prefix,
PeerGroup: dn.Config.PeerGroup,
}
}
var l []*api.DynamicNeighbor
s.mgmtOperation(func() error {
peerGroupName := r.PeerGroup
for k, group := range s.peerGroupMap {
if peerGroupName != "" && peerGroupName != k {
continue
}
for _, dn := range group.dynamicNeighbors {
l = append(l, toApi(dn))
}
}
return nil
}, false)
for _, dn := range l {
select {
case <-ctx.Done():
return nil
default:
fn(dn)
}
}
return nil
}
func (s *BgpServer) ListPeerGroup(ctx context.Context, r *api.ListPeerGroupRequest, fn func(*api.PeerGroup)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var l []*api.PeerGroup
s.mgmtOperation(func() error {
peerGroupName := r.PeerGroupName
l = make([]*api.PeerGroup, 0, len(s.peerGroupMap))
for k, group := range s.peerGroupMap {
if peerGroupName != "" && peerGroupName != k {
continue
}
pg := config.NewPeerGroupFromConfigStruct(group.Conf)
l = append(l, pg)
}
return nil
}, false)
for _, pg := range l {
select {
case <-ctx.Done():
return nil
default:
fn(pg)
}
}
return nil
}
func (s *BgpServer) ListPeer(ctx context.Context, r *api.ListPeerRequest, fn func(*api.Peer)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var l []*api.Peer
s.mgmtOperation(func() error {
address := r.Address
@@ -2839,6 +2973,9 @@ func (s *BgpServer) addNeighbor(c *config.Neighbor) error {
}
func (s *BgpServer) AddPeerGroup(ctx context.Context, r *api.AddPeerGroupRequest) error {
if r == nil || r.PeerGroup == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
c, err := newPeerGroupFromAPIStruct(r.PeerGroup)
if err != nil {
@@ -2849,6 +2986,9 @@ func (s *BgpServer) AddPeerGroup(ctx context.Context, r *api.AddPeerGroupRequest
}
func (s *BgpServer) AddPeer(ctx context.Context, r *api.AddPeerRequest) error {
if r == nil || r.Peer == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
c, err := newNeighborFromAPIStruct(r.Peer)
if err != nil {
@@ -2859,6 +2999,9 @@ func (s *BgpServer) AddPeer(ctx context.Context, r *api.AddPeerRequest) error {
}
func (s *BgpServer) AddDynamicNeighbor(ctx context.Context, r *api.AddDynamicNeighborRequest) error {
if r == nil || r.DynamicNeighbor == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
c := &config.DynamicNeighbor{Config: config.DynamicNeighborConfig{
Prefix: r.DynamicNeighbor.Prefix,
@@ -2929,6 +3072,9 @@ func (s *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) erro
}
func (s *BgpServer) DeletePeerGroup(ctx context.Context, r *api.DeletePeerGroupRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
name := r.Name
for _, n := range s.neighborMap {
@@ -2944,6 +3090,9 @@ func (s *BgpServer) DeletePeerGroup(ctx context.Context, r *api.DeletePeerGroupR
}
func (s *BgpServer) DeletePeer(ctx context.Context, r *api.DeletePeerRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
c := &config.Neighbor{Config: config.NeighborConfig{
NeighborAddress: r.Address,
@@ -2953,6 +3102,16 @@ func (s *BgpServer) DeletePeer(ctx context.Context, r *api.DeletePeerRequest) er
}, true)
}
func (s *BgpServer) DeleteDynamicNeighbor(ctx context.Context, r *api.DeleteDynamicNeighborRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
s.peerGroupMap[r.PeerGroup].DeleteDynamicNeighbor(r.Prefix)
return nil
}, true)
}
func (s *BgpServer) updatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool, err error) {
name := pg.Config.PeerGroupName
@@ -2974,6 +3133,9 @@ func (s *BgpServer) updatePeerGroup(pg *config.PeerGroup) (needsSoftResetIn bool
}
func (s *BgpServer) UpdatePeerGroup(ctx context.Context, r *api.UpdatePeerGroupRequest) (rsp *api.UpdatePeerGroupResponse, err error) {
if r == nil || r.PeerGroup == nil {
return nil, fmt.Errorf("nil request")
}
doSoftreset := false
err = s.mgmtOperation(func() error {
pg, err := newPeerGroupFromAPIStruct(r.PeerGroup)
@@ -3081,6 +3243,9 @@ func (s *BgpServer) updateNeighbor(c *config.Neighbor) (needsSoftResetIn bool, e
}
func (s *BgpServer) UpdatePeer(ctx context.Context, r *api.UpdatePeerRequest) (rsp *api.UpdatePeerResponse, err error) {
if r == nil || r.Peer == nil {
return nil, fmt.Errorf("nil request")
}
doSoftReset := false
err = s.mgmtOperation(func() error {
c, err := newNeighborFromAPIStruct(r.Peer)
@@ -3124,12 +3289,18 @@ func (s *BgpServer) sendNotification(op, addr string, subcode uint8, data []byte
}
func (s *BgpServer) ShutdownPeer(ctx context.Context, r *api.ShutdownPeerRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.sendNotification("Neighbor shutdown", r.Address, bgp.BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN, newAdministrativeCommunication(r.Communication))
}, true)
}
func (s *BgpServer) ResetPeer(ctx context.Context, r *api.ResetPeerRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
addr := r.Address
comm := r.Communication
@@ -3197,18 +3368,27 @@ func (s *BgpServer) setAdminState(addr, communication string, enable bool) error
}
func (s *BgpServer) EnablePeer(ctx context.Context, r *api.EnablePeerRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.setAdminState(r.Address, "", true)
}, true)
}
func (s *BgpServer) DisablePeer(ctx context.Context, r *api.DisablePeerRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.setAdminState(r.Address, r.Communication, false)
}, true)
}
func (s *BgpServer) ListDefinedSet(ctx context.Context, r *api.ListDefinedSetRequest, fn func(*api.DefinedSet)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var cd *config.DefinedSets
var err error
err = s.mgmtOperation(func() error {
@@ -3303,10 +3483,10 @@ func (s *BgpServer) ListDefinedSet(ctx context.Context, r *api.ListDefinedSetReq
}
func (s *BgpServer) AddDefinedSet(ctx context.Context, r *api.AddDefinedSetRequest) error {
if r == nil || r.DefinedSet == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.DefinedSet == nil {
return fmt.Errorf("invalid request")
}
set, err := newDefinedSetFromApiStruct(r.DefinedSet)
if err != nil {
return err
@@ -3316,10 +3496,10 @@ func (s *BgpServer) AddDefinedSet(ctx context.Context, r *api.AddDefinedSetReque
}
func (s *BgpServer) DeleteDefinedSet(ctx context.Context, r *api.DeleteDefinedSetRequest) error {
if r == nil || r.DefinedSet == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.DefinedSet == nil {
return fmt.Errorf("invalid request")
}
set, err := newDefinedSetFromApiStruct(r.DefinedSet)
if err != nil {
return err
@@ -3329,6 +3509,9 @@ func (s *BgpServer) DeleteDefinedSet(ctx context.Context, r *api.DeleteDefinedSe
}
func (s *BgpServer) ListStatement(ctx context.Context, r *api.ListStatementRequest, fn func(*api.Statement)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var l []*api.Statement
s.mgmtOperation(func() error {
s := s.policy.GetStatement(r.Name)
@@ -3350,10 +3533,10 @@ func (s *BgpServer) ListStatement(ctx context.Context, r *api.ListStatementReque
}
func (s *BgpServer) AddStatement(ctx context.Context, r *api.AddStatementRequest) error {
if r == nil || r.Statement == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Statement == nil {
return fmt.Errorf("invalid request")
}
st, err := newStatementFromApiStruct(r.Statement)
if err != nil {
return err
@@ -3363,10 +3546,10 @@ func (s *BgpServer) AddStatement(ctx context.Context, r *api.AddStatementRequest
}
func (s *BgpServer) DeleteStatement(ctx context.Context, r *api.DeleteStatementRequest) error {
if r == nil || r.Statement == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Statement == nil {
return fmt.Errorf("invalid request")
}
st, err := newStatementFromApiStruct(r.Statement)
if err == nil {
err = s.policy.DeleteStatement(st, r.All)
@@ -3376,6 +3559,9 @@ func (s *BgpServer) DeleteStatement(ctx context.Context, r *api.DeleteStatementR
}
func (s *BgpServer) ListPolicy(ctx context.Context, r *api.ListPolicyRequest, fn func(*api.Policy)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var l []*api.Policy
s.mgmtOperation(func() error {
pl := s.policy.GetPolicy(r.Name)
@@ -3397,10 +3583,10 @@ func (s *BgpServer) ListPolicy(ctx context.Context, r *api.ListPolicyRequest, fn
}
func (s *BgpServer) AddPolicy(ctx context.Context, r *api.AddPolicyRequest) error {
if r == nil || r.Policy == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Policy == nil {
return fmt.Errorf("invalid request")
}
p, err := newPolicyFromApiStruct(r.Policy)
if err == nil {
err = s.policy.AddPolicy(p, r.ReferExistingStatements)
@@ -3410,10 +3596,10 @@ func (s *BgpServer) AddPolicy(ctx context.Context, r *api.AddPolicyRequest) erro
}
func (s *BgpServer) DeletePolicy(ctx context.Context, r *api.DeletePolicyRequest) error {
if r == nil || r.Policy == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Policy == nil {
return fmt.Errorf("invalid request")
}
p, err := newPolicyFromApiStruct(r.Policy)
if err != nil {
return err
@@ -3456,12 +3642,11 @@ func (s *BgpServer) toPolicyInfo(name string, dir api.PolicyDirection) (string,
}
func (s *BgpServer) ListPolicyAssignment(ctx context.Context, r *api.ListPolicyAssignmentRequest, fn func(*api.PolicyAssignment)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var a []*api.PolicyAssignment
err := s.mgmtOperation(func() error {
if r == nil {
return fmt.Errorf("invalid request")
}
names := make([]string, 0, len(s.neighborMap)+1)
if r.Name == "" {
names = append(names, table.GLOBAL_RIB_NAME)
@@ -3491,9 +3676,6 @@ func (s *BgpServer) ListPolicyAssignment(ctx context.Context, r *api.ListPolicyA
if err != nil {
return err
}
if len(policies) == 0 {
continue
}
t := &table.PolicyAssignment{
Name: name,
Type: dir,
@@ -3519,10 +3701,10 @@ func (s *BgpServer) ListPolicyAssignment(ctx context.Context, r *api.ListPolicyA
}
func (s *BgpServer) AddPolicyAssignment(ctx context.Context, r *api.AddPolicyAssignmentRequest) error {
if r == nil || r.Assignment == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Assignment == nil {
return fmt.Errorf("invalid request")
}
id, dir, err := s.toPolicyInfo(r.Assignment.Name, r.Assignment.Direction)
if err != nil {
return err
@@ -3532,10 +3714,10 @@ func (s *BgpServer) AddPolicyAssignment(ctx context.Context, r *api.AddPolicyAss
}
func (s *BgpServer) DeletePolicyAssignment(ctx context.Context, r *api.DeletePolicyAssignmentRequest) error {
if r == nil || r.Assignment == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Assignment == nil {
return fmt.Errorf("invalid request")
}
id, dir, err := s.toPolicyInfo(r.Assignment.Name, r.Assignment.Direction)
if err != nil {
return err
@@ -3545,10 +3727,10 @@ func (s *BgpServer) DeletePolicyAssignment(ctx context.Context, r *api.DeletePol
}
func (s *BgpServer) SetPolicyAssignment(ctx context.Context, r *api.SetPolicyAssignmentRequest) error {
if r == nil || r.Assignment == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r == nil || r.Assignment == nil {
return fmt.Errorf("invalid request")
}
id, dir, err := s.toPolicyInfo(r.Assignment.Name, r.Assignment.Direction)
if err != nil {
return err
@@ -3558,6 +3740,9 @@ func (s *BgpServer) SetPolicyAssignment(ctx context.Context, r *api.SetPolicyAss
}
func (s *BgpServer) EnableMrt(ctx context.Context, r *api.EnableMrtRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.mrtManager.enable(&config.MrtConfig{
DumpInterval: r.DumpInterval,
@@ -3569,12 +3754,18 @@ func (s *BgpServer) EnableMrt(ctx context.Context, r *api.EnableMrtRequest) erro
}
func (s *BgpServer) DisableMrt(ctx context.Context, r *api.DisableMrtRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.mrtManager.disable(&config.MrtConfig{})
}, false)
}
func (s *BgpServer) ListRpki(ctx context.Context, r *api.ListRpkiRequest, fn func(*api.Rpki)) error {
if r == nil || r.Family == nil {
return fmt.Errorf("nil request")
}
var l []*api.Rpki
err := s.mgmtOperation(func() error {
for _, r := range s.roaManager.GetServers() {
@@ -3623,6 +3814,9 @@ func (s *BgpServer) ListRpki(ctx context.Context, r *api.ListRpkiRequest, fn fun
}
func (s *BgpServer) ListRpkiTable(ctx context.Context, r *api.ListRpkiTableRequest, fn func(*api.Roa)) error {
if r == nil {
return fmt.Errorf("nil request")
}
var l []*api.Roa
err := s.mgmtOperation(func() error {
family := bgp.RouteFamily(0)
@@ -3649,30 +3843,45 @@ func (s *BgpServer) ListRpkiTable(ctx context.Context, r *api.ListRpkiTableReque
}
func (s *BgpServer) AddRpki(ctx context.Context, r *api.AddRpkiRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.roaManager.AddServer(net.JoinHostPort(r.Address, strconv.Itoa(int(r.Port))), r.Lifetime)
}, false)
}
func (s *BgpServer) DeleteRpki(ctx context.Context, r *api.DeleteRpkiRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.roaManager.DeleteServer(r.Address)
}, false)
}
func (s *BgpServer) EnableRpki(ctx context.Context, r *api.EnableRpkiRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.roaManager.Enable(r.Address)
}, false)
}
func (s *BgpServer) DisableRpki(ctx context.Context, r *api.DisableRpkiRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
return s.roaManager.Disable(r.Address)
}, false)
}
func (s *BgpServer) ResetRpki(ctx context.Context, r *api.ResetRpkiRequest) error {
if r == nil {
return fmt.Errorf("nil request")
}
return s.mgmtOperation(func() error {
if r.Soft {
return s.roaManager.SoftReset(r.Address)
@@ -3691,9 +3900,9 @@ func (s *BgpServer) MonitorTable(ctx context.Context, r *api.MonitorTableRequest
return s.watch(watchBestPath(r.Current)), nil
case api.TableType_ADJ_IN:
if r.PostPolicy {
return s.watch(watchPostUpdate(r.Current)), nil
return s.watch(watchPostUpdate(r.Current, r.Name)), nil
}
return s.watch(watchUpdate(r.Current)), nil
return s.watch(watchUpdate(r.Current, r.Name)), nil
default:
return nil, fmt.Errorf("unsupported resource type: %v", r.TableType)
}
@@ -3733,11 +3942,14 @@ func (s *BgpServer) MonitorTable(ctx context.Context, r *api.MonitorTableRequest
if path == nil || (r.Family != nil && family != path.GetRouteFamily()) {
continue
}
if len(r.Name) > 0 && r.Name != path.GetSource().Address.String() {
continue
}
select {
case <-ctx.Done():
return
default:
fn(toPathApi(path, nil))
fn(toPathApi(path, nil, false, false))
}
}
case <-ctx.Done():
@@ -3754,7 +3966,13 @@ func (s *BgpServer) MonitorPeer(ctx context.Context, r *api.MonitorPeerRequest,
}
go func() {
w := s.watch(watchPeerState(r.Current))
// So that both flags are not required, assume that if the
// initial_state flag is true, then the caller desires that the initial
// state be returned whether or not it is established and regardless of
// the value of `current`.
current := r.Current || r.InitialState
nonEstablished := r.InitialState
w := s.watch(watchPeerState(current, nonEstablished))
defer func() {
w.Stop()
}()
@@ -3795,6 +4013,22 @@ func (s *BgpServer) MonitorPeer(ctx context.Context, r *api.MonitorPeerRequest,
return nil
}
func (s *BgpServer) SetLogLevel(ctx context.Context, r *api.SetLogLevelRequest) error {
prevLevel := log.GetLevel()
newLevel := log.Level(r.Level)
if prevLevel == newLevel {
log.WithFields(log.Fields{
"Topic": "Config",
}).Infof("Logging level unchanged -- level already set to %v", newLevel)
} else {
log.SetLevel(newLevel)
log.WithFields(log.Fields{
"Topic": "Config",
}).Infof("Logging level changed -- prev: %v, new: %v", prevLevel, newLevel)
}
return nil
}
type watchEventType string
const (
@@ -3879,8 +4113,10 @@ type watchOptions struct {
initUpdate bool
initPostUpdate bool
initPeerState bool
nonEstablished bool
tableName string
recvMessage bool
peerAddress string
}
type watchOption func(*watchOptions)
@@ -3894,29 +4130,34 @@ func watchBestPath(current bool) watchOption {
}
}
func watchUpdate(current bool) watchOption {
func watchUpdate(current bool, peerAddress string) watchOption {
return func(o *watchOptions) {
o.preUpdate = true
if current {
o.initUpdate = true
}
o.peerAddress = peerAddress
}
}
func watchPostUpdate(current bool) watchOption {
func watchPostUpdate(current bool, peerAddress string) watchOption {
return func(o *watchOptions) {
o.postUpdate = true
if current {
o.initPostUpdate = true
}
o.peerAddress = peerAddress
}
}
func watchPeerState(current bool) watchOption {
func watchPeerState(current, includeNonEstablished bool) watchOption {
return func(o *watchOptions) {
o.peerState = true
if current {
o.initPeerState = true
if includeNonEstablished {
o.nonEstablished = true
}
}
}
}
@@ -4071,11 +4312,13 @@ func (s *BgpServer) watch(opts ...watchOption) (w *watcher) {
}
if w.opts.initPeerState {
for _, peer := range s.neighborMap {
peer.fsm.lock.RLock()
notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED
peer.fsm.lock.RUnlock()
if notEstablished {
continue
if !w.opts.nonEstablished {
peer.fsm.lock.RLock()
notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED
peer.fsm.lock.RUnlock()
if notEstablished {
continue
}
}
w.notify(newWatchEventPeerState(peer, nil))
}
@@ -4090,10 +4333,14 @@ func (s *BgpServer) watch(opts ...watchOption) (w *watcher) {
for _, peer := range s.neighborMap {
peer.fsm.lock.RLock()
notEstablished := peer.fsm.state != bgp.BGP_FSM_ESTABLISHED
peerAddress := peer.fsm.peerInfo.Address.String()
peer.fsm.lock.RUnlock()
if notEstablished {
continue
}
if len(w.opts.peerAddress) > 0 && w.opts.peerAddress != peerAddress {
continue
}
configNeighbor := w.s.toConfig(peer, false)
for _, rf := range peer.configuredRFlist() {
peer.fsm.lock.RLock()
@@ -4148,9 +4395,13 @@ func (s *BgpServer) watch(opts ...watchOption) (w *watcher) {
for peerInfo, paths := range pathsByPeer {
// create copy which can be access to without mutex
var configNeighbor *config.Neighbor
if peer, ok := s.neighborMap[peerInfo.Address.String()]; ok {
peerAddress := peerInfo.Address.String()
if peer, ok := s.neighborMap[peerAddress]; ok {
configNeighbor = w.s.toConfig(peer, false)
}
if w.opts.peerAddress != "" && w.opts.peerAddress != peerAddress {
continue
}
w.notify(&watchEventUpdate{
PeerAS: peerInfo.AS,

View File

@@ -17,6 +17,7 @@
package server
import (
"fmt"
"net"
"syscall"
@@ -27,10 +28,6 @@ func setTCPMD5SigSockopt(l *net.TCPListener, address string, key string) error {
return setTcpMD5SigSockopt(l, address, key)
}
func setListenTCPTTLSockopt(l *net.TCPListener, ttl int) error {
return setListenTcpTTLSockopt(l, ttl)
}
func setTCPTTLSockopt(conn *net.TCPConn, ttl int) error {
return setTcpTTLSockopt(conn, ttl)
}
@@ -39,6 +36,10 @@ func setTCPMinTTLSockopt(conn *net.TCPConn, ttl int) error {
return setTcpMinTTLSockopt(conn, ttl)
}
func setBindToDevSockopt(sc syscall.RawConn, device string) error {
return fmt.Errorf("binding connection to a device is not supported")
}
func dialerControl(network, address string, c syscall.RawConn, ttl, ttlMin uint8, password string, bindInterface string) error {
if password != "" {
log.WithFields(log.Fields{

View File

@@ -35,15 +35,6 @@ func setTcpMD5SigSockopt(l *net.TCPListener, address string, key string) error {
return setsockOptInt(sc, syscall.IPPROTO_TCP, tcpMD5SIG, 1)
}
func setListenTcpTTLSockopt(l *net.TCPListener, ttl int) error {
family := extractFamilyFromTCPListener(l)
sc, err := l.SyscallConn()
if err != nil {
return err
}
return setsockoptIpTtl(sc, family, ttl)
}
func setTcpTTLSockopt(conn *net.TCPConn, ttl int) error {
family := extractFamilyFromTCPConn(conn)
sc, err := conn.SyscallConn()

View File

@@ -27,15 +27,6 @@ func setTcpMD5SigSockopt(l *net.TCPListener, address string, key string) error {
return fmt.Errorf("setting md5 is not supported")
}
func setListenTcpTTLSockopt(l *net.TCPListener, ttl int) error {
family := extractFamilyFromTCPListener(l)
sc, err := l.SyscallConn()
if err != nil {
return err
}
return setsockoptIpTtl(sc, family, ttl)
}
func setTcpTTLSockopt(conn *net.TCPConn, ttl int) error {
family := syscall.AF_INET
if strings.Contains(conn.RemoteAddr().String(), "[") {

View File

@@ -70,13 +70,8 @@ func setTCPMD5SigSockopt(l *net.TCPListener, address string, key string) error {
return setsockOptString(sc, syscall.IPPROTO_TCP, tcpMD5SIG, string(b[:]))
}
func setListenTCPTTLSockopt(l *net.TCPListener, ttl int) error {
family := extractFamilyFromTCPListener(l)
sc, err := l.SyscallConn()
if err != nil {
return err
}
return setsockoptIpTtl(sc, family, ttl)
func setBindToDevSockopt(sc syscall.RawConn, device string) error {
return setsockOptString(sc, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, device)
}
func setTCPTTLSockopt(conn *net.TCPConn, ttl int) error {
@@ -162,14 +157,9 @@ func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8
}
}
if bindInterface != "" {
if err := c.Control(func(fd uintptr) {
sockerr = os.NewSyscallError("setsockopt", syscall.SetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, bindInterface))
}); err != nil {
if err := setBindToDevSockopt(c, bindInterface); err != nil {
return err
}
if sockerr != nil {
return sockerr
}
}
return nil
}

View File

@@ -370,15 +370,6 @@ func setTCPMD5SigSockopt(l *net.TCPListener, address string, key string) error {
return setsockoptTcpMD5Sig(sc, address, key)
}
func setListenTCPTTLSockopt(l *net.TCPListener, ttl int) error {
family := extractFamilyFromTCPListener(l)
sc, err := l.SyscallConn()
if err != nil {
return err
}
return setsockoptIpTtl(sc, family, ttl)
}
func setTCPTTLSockopt(conn *net.TCPConn, ttl int) error {
family := extractFamilyFromTCPConn(conn)
sc, err := conn.SyscallConn()
@@ -403,6 +394,10 @@ func setTCPMinTTLSockopt(conn *net.TCPConn, ttl int) error {
return setsockOptInt(sc, level, name, ttl)
}
func setBindToDevSockopt(sc syscall.RawConn, device string) error {
return fmt.Errorf("binding connection to a device is not supported")
}
func dialerControl(network, address string, c syscall.RawConn, ttl, minTtl uint8, password string, bindInterface string) error {
if password != "" {
log.WithFields(log.Fields{

View File

@@ -59,20 +59,12 @@ func decodeAdministrativeCommunication(data []byte) (string, []byte) {
if communicationLen > bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX {
communicationLen = bgp.BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX
}
if communicationLen > len(data)+1 {
communicationLen = len(data) + 1
if communicationLen > len(data)-1 {
communicationLen = len(data) - 1
}
return string(data[1 : communicationLen+1]), data[communicationLen+1:]
}
func extractFamilyFromTCPListener(l *net.TCPListener) int {
family := syscall.AF_INET
if strings.Contains(l.Addr().String(), "[") {
family = syscall.AF_INET6
}
return family
}
func extractFamilyFromTCPConn(conn *net.TCPConn) int {
family := syscall.AF_INET
if strings.Contains(conn.RemoteAddr().String(), "[") {

View File

@@ -364,7 +364,7 @@ func (z *zebraClient) updatePathByNexthopCache(paths []*table.Path) {
func (z *zebraClient) loop() {
w := z.server.watch([]watchOption{
watchBestPath(true),
watchPostUpdate(true),
watchPostUpdate(true, ""),
}...)
defer w.Stop()