diff options
-rw-r--r-- | api/attribute.pb.go | 447 | ||||
-rw-r--r-- | api/attribute.proto | 4 | ||||
-rw-r--r-- | cmd/gobgp/global.go | 89 | ||||
-rw-r--r-- | internal/pkg/apiutil/attribute.go | 6 | ||||
-rw-r--r-- | pkg/packet/bgp/bgp.go | 55 | ||||
-rw-r--r-- | pkg/server/bmp.go | 6 | ||||
-rw-r--r-- | pkg/server/fsm.go | 14 | ||||
-rw-r--r-- | pkg/server/peer.go | 3 | ||||
-rw-r--r-- | pkg/server/rpki.go | 8 | ||||
-rw-r--r-- | pkg/server/server.go | 234 |
10 files changed, 622 insertions, 244 deletions
diff --git a/api/attribute.pb.go b/api/attribute.pb.go index 909a3035..f30a3d61 100644 --- a/api/attribute.pb.go +++ b/api/attribute.pb.go @@ -78,6 +78,7 @@ It has these top-level messages: As4AggregatorAttribute PmsiTunnelAttribute TunnelEncapSubTLVEncapsulation + TunnelEncapSubTLVWireguard TunnelEncapSubTLVProtocol TunnelEncapSubTLVColor TunnelEncapSubTLVSRPreference @@ -2457,6 +2458,22 @@ func (m *TunnelEncapSubTLVEncapsulation) GetCookie() []byte { return nil } +type TunnelEncapSubTLVWireguard struct { + Peer []byte `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"` +} + +func (m *TunnelEncapSubTLVWireguard) Reset() { *m = TunnelEncapSubTLVWireguard{} } +func (m *TunnelEncapSubTLVWireguard) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapSubTLVWireguard) ProtoMessage() {} +func (*TunnelEncapSubTLVWireguard) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{68} } + +func (m *TunnelEncapSubTLVWireguard) GetPeer() []byte { + if m != nil { + return m.Peer + } + return nil +} + type TunnelEncapSubTLVProtocol struct { Protocol uint32 `protobuf:"varint,1,opt,name=protocol" json:"protocol,omitempty"` } @@ -2464,7 +2481,7 @@ type TunnelEncapSubTLVProtocol struct { func (m *TunnelEncapSubTLVProtocol) Reset() { *m = TunnelEncapSubTLVProtocol{} } func (m *TunnelEncapSubTLVProtocol) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVProtocol) ProtoMessage() {} -func (*TunnelEncapSubTLVProtocol) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{68} } +func (*TunnelEncapSubTLVProtocol) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{69} } func (m *TunnelEncapSubTLVProtocol) GetProtocol() uint32 { if m != nil { @@ -2480,7 +2497,7 @@ type TunnelEncapSubTLVColor struct { func (m *TunnelEncapSubTLVColor) Reset() { *m = TunnelEncapSubTLVColor{} } func (m *TunnelEncapSubTLVColor) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVColor) ProtoMessage() {} -func (*TunnelEncapSubTLVColor) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{69} } +func (*TunnelEncapSubTLVColor) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{70} } func (m *TunnelEncapSubTLVColor) GetColor() uint32 { if m != nil { @@ -2497,7 +2514,7 @@ type TunnelEncapSubTLVSRPreference struct { func (m *TunnelEncapSubTLVSRPreference) Reset() { *m = TunnelEncapSubTLVSRPreference{} } func (m *TunnelEncapSubTLVSRPreference) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVSRPreference) ProtoMessage() {} -func (*TunnelEncapSubTLVSRPreference) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{70} } +func (*TunnelEncapSubTLVSRPreference) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{71} } func (m *TunnelEncapSubTLVSRPreference) GetFlags() uint32 { if m != nil { @@ -2521,7 +2538,7 @@ func (m *TunnelEncapSubTLVSRCandidatePathName) Reset() { *m = TunnelEnca func (m *TunnelEncapSubTLVSRCandidatePathName) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVSRCandidatePathName) ProtoMessage() {} func (*TunnelEncapSubTLVSRCandidatePathName) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{71} + return fileDescriptor0, []int{72} } func (m *TunnelEncapSubTLVSRCandidatePathName) GetCandidatePathName() string { @@ -2538,7 +2555,7 @@ type TunnelEncapSubTLVSRPriority struct { func (m *TunnelEncapSubTLVSRPriority) Reset() { *m = TunnelEncapSubTLVSRPriority{} } func (m *TunnelEncapSubTLVSRPriority) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVSRPriority) ProtoMessage() {} -func (*TunnelEncapSubTLVSRPriority) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{72} } +func (*TunnelEncapSubTLVSRPriority) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{73} } func (m *TunnelEncapSubTLVSRPriority) GetPriority() uint32 { if m != nil { @@ -2557,7 +2574,7 @@ type TunnelEncapSubTLVSRBindingSID struct { func (m *TunnelEncapSubTLVSRBindingSID) Reset() { *m = TunnelEncapSubTLVSRBindingSID{} } func (m *TunnelEncapSubTLVSRBindingSID) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVSRBindingSID) ProtoMessage() {} -func (*TunnelEncapSubTLVSRBindingSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{73} } +func (*TunnelEncapSubTLVSRBindingSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{74} } func (m *TunnelEncapSubTLVSRBindingSID) GetBsid() *google_protobuf.Any { if m != nil { @@ -2575,7 +2592,7 @@ type SRBindingSID struct { func (m *SRBindingSID) Reset() { *m = SRBindingSID{} } func (m *SRBindingSID) String() string { return proto.CompactTextString(m) } func (*SRBindingSID) ProtoMessage() {} -func (*SRBindingSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{74} } +func (*SRBindingSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{75} } func (m *SRBindingSID) GetSFlag() bool { if m != nil { @@ -2609,7 +2626,7 @@ type SRv6EndPointBehavior struct { func (m *SRv6EndPointBehavior) Reset() { *m = SRv6EndPointBehavior{} } func (m *SRv6EndPointBehavior) String() string { return proto.CompactTextString(m) } func (*SRv6EndPointBehavior) ProtoMessage() {} -func (*SRv6EndPointBehavior) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{75} } +func (*SRv6EndPointBehavior) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{76} } func (m *SRv6EndPointBehavior) GetBehavior() SRv6Behavior { if m != nil { @@ -2657,7 +2674,7 @@ type SRv6BindingSID struct { func (m *SRv6BindingSID) Reset() { *m = SRv6BindingSID{} } func (m *SRv6BindingSID) String() string { return proto.CompactTextString(m) } func (*SRv6BindingSID) ProtoMessage() {} -func (*SRv6BindingSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{76} } +func (*SRv6BindingSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{77} } func (m *SRv6BindingSID) GetSFlag() bool { if m != nil { @@ -2702,7 +2719,7 @@ type TunnelEncapSubTLVSRENLP struct { func (m *TunnelEncapSubTLVSRENLP) Reset() { *m = TunnelEncapSubTLVSRENLP{} } func (m *TunnelEncapSubTLVSRENLP) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVSRENLP) ProtoMessage() {} -func (*TunnelEncapSubTLVSRENLP) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{77} } +func (*TunnelEncapSubTLVSRENLP) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{78} } func (m *TunnelEncapSubTLVSRENLP) GetFlags() uint32 { if m != nil { @@ -2726,7 +2743,7 @@ type SRWeight struct { func (m *SRWeight) Reset() { *m = SRWeight{} } func (m *SRWeight) String() string { return proto.CompactTextString(m) } func (*SRWeight) ProtoMessage() {} -func (*SRWeight) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{78} } +func (*SRWeight) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{79} } func (m *SRWeight) GetFlags() uint32 { if m != nil { @@ -2752,7 +2769,7 @@ type SegmentFlags struct { func (m *SegmentFlags) Reset() { *m = SegmentFlags{} } func (m *SegmentFlags) String() string { return proto.CompactTextString(m) } func (*SegmentFlags) ProtoMessage() {} -func (*SegmentFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{79} } +func (*SegmentFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{80} } func (m *SegmentFlags) GetVFlag() bool { if m != nil { @@ -2790,7 +2807,7 @@ type SegmentTypeA struct { func (m *SegmentTypeA) Reset() { *m = SegmentTypeA{} } func (m *SegmentTypeA) String() string { return proto.CompactTextString(m) } func (*SegmentTypeA) ProtoMessage() {} -func (*SegmentTypeA) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{80} } +func (*SegmentTypeA) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{81} } func (m *SegmentTypeA) GetFlags() *SegmentFlags { if m != nil { @@ -2815,7 +2832,7 @@ type SegmentTypeB struct { func (m *SegmentTypeB) Reset() { *m = SegmentTypeB{} } func (m *SegmentTypeB) String() string { return proto.CompactTextString(m) } func (*SegmentTypeB) ProtoMessage() {} -func (*SegmentTypeB) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{81} } +func (*SegmentTypeB) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{82} } func (m *SegmentTypeB) GetFlags() *SegmentFlags { if m != nil { @@ -2850,7 +2867,7 @@ func (m *TunnelEncapSubTLVSRSegmentList) Reset() { *m = TunnelEncapSubTL func (m *TunnelEncapSubTLVSRSegmentList) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVSRSegmentList) ProtoMessage() {} func (*TunnelEncapSubTLVSRSegmentList) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{82} + return fileDescriptor0, []int{83} } func (m *TunnelEncapSubTLVSRSegmentList) GetWeight() *SRWeight { @@ -2875,7 +2892,7 @@ func (m *TunnelEncapSubTLVEgressEndpoint) Reset() { *m = TunnelEncapSubT func (m *TunnelEncapSubTLVEgressEndpoint) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVEgressEndpoint) ProtoMessage() {} func (*TunnelEncapSubTLVEgressEndpoint) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{83} + return fileDescriptor0, []int{84} } func (m *TunnelEncapSubTLVEgressEndpoint) GetAddress() string { @@ -2892,7 +2909,7 @@ type TunnelEncapSubTLVUDPDestPort struct { func (m *TunnelEncapSubTLVUDPDestPort) Reset() { *m = TunnelEncapSubTLVUDPDestPort{} } func (m *TunnelEncapSubTLVUDPDestPort) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVUDPDestPort) ProtoMessage() {} -func (*TunnelEncapSubTLVUDPDestPort) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{84} } +func (*TunnelEncapSubTLVUDPDestPort) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} } func (m *TunnelEncapSubTLVUDPDestPort) GetPort() uint32 { if m != nil { @@ -2909,7 +2926,7 @@ type TunnelEncapSubTLVUnknown struct { func (m *TunnelEncapSubTLVUnknown) Reset() { *m = TunnelEncapSubTLVUnknown{} } func (m *TunnelEncapSubTLVUnknown) String() string { return proto.CompactTextString(m) } func (*TunnelEncapSubTLVUnknown) ProtoMessage() {} -func (*TunnelEncapSubTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} } +func (*TunnelEncapSubTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} } func (m *TunnelEncapSubTLVUnknown) GetType() uint32 { if m != nil { @@ -2939,7 +2956,7 @@ type TunnelEncapTLV struct { func (m *TunnelEncapTLV) Reset() { *m = TunnelEncapTLV{} } func (m *TunnelEncapTLV) String() string { return proto.CompactTextString(m) } func (*TunnelEncapTLV) ProtoMessage() {} -func (*TunnelEncapTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} } +func (*TunnelEncapTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} } func (m *TunnelEncapTLV) GetType() uint32 { if m != nil { @@ -2962,7 +2979,7 @@ type TunnelEncapAttribute struct { func (m *TunnelEncapAttribute) Reset() { *m = TunnelEncapAttribute{} } func (m *TunnelEncapAttribute) String() string { return proto.CompactTextString(m) } func (*TunnelEncapAttribute) ProtoMessage() {} -func (*TunnelEncapAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} } +func (*TunnelEncapAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} } func (m *TunnelEncapAttribute) GetTlvs() []*TunnelEncapTLV { if m != nil { @@ -2981,7 +2998,7 @@ type IPv6AddressSpecificExtended struct { func (m *IPv6AddressSpecificExtended) Reset() { *m = IPv6AddressSpecificExtended{} } func (m *IPv6AddressSpecificExtended) String() string { return proto.CompactTextString(m) } func (*IPv6AddressSpecificExtended) ProtoMessage() {} -func (*IPv6AddressSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} } +func (*IPv6AddressSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{89} } func (m *IPv6AddressSpecificExtended) GetIsTransitive() bool { if m != nil { @@ -3020,7 +3037,7 @@ func (m *RedirectIPv6AddressSpecificExtended) Reset() { *m = RedirectIPv func (m *RedirectIPv6AddressSpecificExtended) String() string { return proto.CompactTextString(m) } func (*RedirectIPv6AddressSpecificExtended) ProtoMessage() {} func (*RedirectIPv6AddressSpecificExtended) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{89} + return fileDescriptor0, []int{90} } func (m *RedirectIPv6AddressSpecificExtended) GetAddress() string { @@ -3048,7 +3065,7 @@ func (m *IP6ExtendedCommunitiesAttribute) Reset() { *m = IP6ExtendedComm func (m *IP6ExtendedCommunitiesAttribute) String() string { return proto.CompactTextString(m) } func (*IP6ExtendedCommunitiesAttribute) ProtoMessage() {} func (*IP6ExtendedCommunitiesAttribute) Descriptor() ([]byte, []int) { - return fileDescriptor0, []int{90} + return fileDescriptor0, []int{91} } func (m *IP6ExtendedCommunitiesAttribute) GetCommunities() []*google_protobuf.Any { @@ -3065,7 +3082,7 @@ type AigpTLVIGPMetric struct { func (m *AigpTLVIGPMetric) Reset() { *m = AigpTLVIGPMetric{} } func (m *AigpTLVIGPMetric) String() string { return proto.CompactTextString(m) } func (*AigpTLVIGPMetric) ProtoMessage() {} -func (*AigpTLVIGPMetric) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} } +func (*AigpTLVIGPMetric) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} } func (m *AigpTLVIGPMetric) GetMetric() uint64 { if m != nil { @@ -3082,7 +3099,7 @@ type AigpTLVUnknown struct { func (m *AigpTLVUnknown) Reset() { *m = AigpTLVUnknown{} } func (m *AigpTLVUnknown) String() string { return proto.CompactTextString(m) } func (*AigpTLVUnknown) ProtoMessage() {} -func (*AigpTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} } +func (*AigpTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{93} } func (m *AigpTLVUnknown) GetType() uint32 { if m != nil { @@ -3108,7 +3125,7 @@ type AigpAttribute struct { func (m *AigpAttribute) Reset() { *m = AigpAttribute{} } func (m *AigpAttribute) String() string { return proto.CompactTextString(m) } func (*AigpAttribute) ProtoMessage() {} -func (*AigpAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{93} } +func (*AigpAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{94} } func (m *AigpAttribute) GetTlvs() []*google_protobuf.Any { if m != nil { @@ -3126,7 +3143,7 @@ type LargeCommunity struct { func (m *LargeCommunity) Reset() { *m = LargeCommunity{} } func (m *LargeCommunity) String() string { return proto.CompactTextString(m) } func (*LargeCommunity) ProtoMessage() {} -func (*LargeCommunity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{94} } +func (*LargeCommunity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{95} } func (m *LargeCommunity) GetGlobalAdmin() uint32 { if m != nil { @@ -3156,7 +3173,7 @@ type LargeCommunitiesAttribute struct { func (m *LargeCommunitiesAttribute) Reset() { *m = LargeCommunitiesAttribute{} } func (m *LargeCommunitiesAttribute) String() string { return proto.CompactTextString(m) } func (*LargeCommunitiesAttribute) ProtoMessage() {} -func (*LargeCommunitiesAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{95} } +func (*LargeCommunitiesAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{96} } func (m *LargeCommunitiesAttribute) GetCommunities() []*LargeCommunity { if m != nil { @@ -3177,7 +3194,7 @@ type LsNodeFlags struct { func (m *LsNodeFlags) Reset() { *m = LsNodeFlags{} } func (m *LsNodeFlags) String() string { return proto.CompactTextString(m) } func (*LsNodeFlags) ProtoMessage() {} -func (*LsNodeFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{96} } +func (*LsNodeFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{97} } func (m *LsNodeFlags) GetOverload() bool { if m != nil { @@ -3231,7 +3248,7 @@ type LsIGPFlags struct { func (m *LsIGPFlags) Reset() { *m = LsIGPFlags{} } func (m *LsIGPFlags) String() string { return proto.CompactTextString(m) } func (*LsIGPFlags) ProtoMessage() {} -func (*LsIGPFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{97} } +func (*LsIGPFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{98} } func (m *LsIGPFlags) GetDown() bool { if m != nil { @@ -3269,7 +3286,7 @@ type LsSrRange struct { func (m *LsSrRange) Reset() { *m = LsSrRange{} } func (m *LsSrRange) String() string { return proto.CompactTextString(m) } func (*LsSrRange) ProtoMessage() {} -func (*LsSrRange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{98} } +func (*LsSrRange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{99} } func (m *LsSrRange) GetBegin() uint32 { if m != nil { @@ -3294,7 +3311,7 @@ type LsSrCapabilities struct { func (m *LsSrCapabilities) Reset() { *m = LsSrCapabilities{} } func (m *LsSrCapabilities) String() string { return proto.CompactTextString(m) } func (*LsSrCapabilities) ProtoMessage() {} -func (*LsSrCapabilities) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{99} } +func (*LsSrCapabilities) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{100} } func (m *LsSrCapabilities) GetIpv4Supported() bool { if m != nil { @@ -3324,7 +3341,7 @@ type LsSrLocalBlock struct { func (m *LsSrLocalBlock) Reset() { *m = LsSrLocalBlock{} } func (m *LsSrLocalBlock) String() string { return proto.CompactTextString(m) } func (*LsSrLocalBlock) ProtoMessage() {} -func (*LsSrLocalBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{100} } +func (*LsSrLocalBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{101} } func (m *LsSrLocalBlock) GetRanges() []*LsSrRange { if m != nil { @@ -3348,7 +3365,7 @@ type LsAttributeNode struct { func (m *LsAttributeNode) Reset() { *m = LsAttributeNode{} } func (m *LsAttributeNode) String() string { return proto.CompactTextString(m) } func (*LsAttributeNode) ProtoMessage() {} -func (*LsAttributeNode) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{101} } +func (*LsAttributeNode) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{102} } func (m *LsAttributeNode) GetName() string { if m != nil { @@ -3433,7 +3450,7 @@ type LsAttributeLink struct { func (m *LsAttributeLink) Reset() { *m = LsAttributeLink{} } func (m *LsAttributeLink) String() string { return proto.CompactTextString(m) } func (*LsAttributeLink) ProtoMessage() {} -func (*LsAttributeLink) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{102} } +func (*LsAttributeLink) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{103} } func (m *LsAttributeLink) GetName() string { if m != nil { @@ -3542,7 +3559,7 @@ type LsAttributePrefix struct { func (m *LsAttributePrefix) Reset() { *m = LsAttributePrefix{} } func (m *LsAttributePrefix) String() string { return proto.CompactTextString(m) } func (*LsAttributePrefix) ProtoMessage() {} -func (*LsAttributePrefix) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{103} } +func (*LsAttributePrefix) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{104} } func (m *LsAttributePrefix) GetIgpFlags() *LsIGPFlags { if m != nil { @@ -3574,7 +3591,7 @@ type LsAttribute struct { func (m *LsAttribute) Reset() { *m = LsAttribute{} } func (m *LsAttribute) String() string { return proto.CompactTextString(m) } func (*LsAttribute) ProtoMessage() {} -func (*LsAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{104} } +func (*LsAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{105} } func (m *LsAttribute) GetNode() *LsAttributeNode { if m != nil { @@ -3606,7 +3623,7 @@ type UnknownAttribute struct { func (m *UnknownAttribute) Reset() { *m = UnknownAttribute{} } func (m *UnknownAttribute) String() string { return proto.CompactTextString(m) } func (*UnknownAttribute) ProtoMessage() {} -func (*UnknownAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{105} } +func (*UnknownAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{106} } func (m *UnknownAttribute) GetFlags() uint32 { if m != nil { @@ -3642,7 +3659,7 @@ type SRv6StructureSubSubTLV struct { func (m *SRv6StructureSubSubTLV) Reset() { *m = SRv6StructureSubSubTLV{} } func (m *SRv6StructureSubSubTLV) String() string { return proto.CompactTextString(m) } func (*SRv6StructureSubSubTLV) ProtoMessage() {} -func (*SRv6StructureSubSubTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{106} } +func (*SRv6StructureSubSubTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{107} } func (m *SRv6StructureSubSubTLV) GetLocalBlockLength() uint32 { if m != nil { @@ -3694,7 +3711,7 @@ type SRv6SIDFlags struct { func (m *SRv6SIDFlags) Reset() { *m = SRv6SIDFlags{} } func (m *SRv6SIDFlags) String() string { return proto.CompactTextString(m) } func (*SRv6SIDFlags) ProtoMessage() {} -func (*SRv6SIDFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{107} } +func (*SRv6SIDFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{108} } func (m *SRv6SIDFlags) GetFlag_1() bool { if m != nil { @@ -3710,7 +3727,7 @@ type SRv6TLV struct { func (m *SRv6TLV) Reset() { *m = SRv6TLV{} } func (m *SRv6TLV) String() string { return proto.CompactTextString(m) } func (*SRv6TLV) ProtoMessage() {} -func (*SRv6TLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{108} } +func (*SRv6TLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{109} } func (m *SRv6TLV) GetTlv() []*google_protobuf.Any { if m != nil { @@ -3732,7 +3749,7 @@ type SRv6InformationSubTLV struct { func (m *SRv6InformationSubTLV) Reset() { *m = SRv6InformationSubTLV{} } func (m *SRv6InformationSubTLV) String() string { return proto.CompactTextString(m) } func (*SRv6InformationSubTLV) ProtoMessage() {} -func (*SRv6InformationSubTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{109} } +func (*SRv6InformationSubTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{110} } func (m *SRv6InformationSubTLV) GetSid() []byte { if m != nil { @@ -3772,7 +3789,7 @@ type SRv6L3ServiceTLV struct { func (m *SRv6L3ServiceTLV) Reset() { *m = SRv6L3ServiceTLV{} } func (m *SRv6L3ServiceTLV) String() string { return proto.CompactTextString(m) } func (*SRv6L3ServiceTLV) ProtoMessage() {} -func (*SRv6L3ServiceTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{110} } +func (*SRv6L3ServiceTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{111} } func (m *SRv6L3ServiceTLV) GetSubTlvs() map[uint32]*SRv6TLV { if m != nil { @@ -3794,7 +3811,7 @@ type PrefixSID struct { func (m *PrefixSID) Reset() { *m = PrefixSID{} } func (m *PrefixSID) String() string { return proto.CompactTextString(m) } func (*PrefixSID) ProtoMessage() {} -func (*PrefixSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{111} } +func (*PrefixSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{112} } func (m *PrefixSID) GetTlvs() []*google_protobuf.Any { if m != nil { @@ -3872,6 +3889,7 @@ func init() { proto.RegisterType((*As4AggregatorAttribute)(nil), "gobgpapi.As4AggregatorAttribute") proto.RegisterType((*PmsiTunnelAttribute)(nil), "gobgpapi.PmsiTunnelAttribute") proto.RegisterType((*TunnelEncapSubTLVEncapsulation)(nil), "gobgpapi.TunnelEncapSubTLVEncapsulation") + proto.RegisterType((*TunnelEncapSubTLVWireguard)(nil), "gobgpapi.TunnelEncapSubTLVWireguard") proto.RegisterType((*TunnelEncapSubTLVProtocol)(nil), "gobgpapi.TunnelEncapSubTLVProtocol") proto.RegisterType((*TunnelEncapSubTLVColor)(nil), "gobgpapi.TunnelEncapSubTLVColor") proto.RegisterType((*TunnelEncapSubTLVSRPreference)(nil), "gobgpapi.TunnelEncapSubTLVSRPreference") @@ -3925,23 +3943,23 @@ func init() { func init() { proto.RegisterFile("attribute.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 4262 bytes of a gzipped FileDescriptorProto + // 4284 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0x4d, 0x6f, 0x1b, 0x49, - 0x76, 0xc3, 0x0f, 0x49, 0xd4, 0xe3, 0x87, 0x5a, 0xad, 0x8f, 0x91, 0xe4, 0xcf, 0xed, 0x19, 0xdb, - 0x8a, 0xec, 0xd1, 0xac, 0x65, 0x0d, 0x77, 0x3c, 0x83, 0x4d, 0x40, 0x8b, 0xb4, 0x87, 0x19, 0x8a, + 0x76, 0xcb, 0x0f, 0x49, 0xd4, 0xe3, 0x87, 0x5a, 0xad, 0x8f, 0x91, 0xe4, 0xcf, 0xed, 0x19, 0xdb, + 0x8a, 0xec, 0xd1, 0x8c, 0x65, 0x0d, 0x77, 0x3c, 0x83, 0x4d, 0x40, 0x8b, 0xb4, 0x87, 0x19, 0x8a, 0xe2, 0x34, 0x29, 0x79, 0x72, 0xd9, 0x4e, 0xb3, 0xbb, 0xd4, 0xaa, 0x55, 0xb3, 0xbb, 0xb7, 0xab, 0x49, 0x5b, 0x97, 0x0d, 0x90, 0x43, 0x80, 0x45, 0xb0, 0x41, 0x4e, 0xc1, 0x02, 0x7b, 0xc9, 0x25, 0x01, 0x12, 0x04, 0x39, 0xee, 0x25, 0x3f, 0x20, 0xc8, 0x39, 0xbf, 0x25, 0xf7, 0xa0, 0xbe, 0xfa, 0x83, 0xa2, 0x64, 0x7b, 0x3c, 0x03, 0xf8, 0xd6, 0xef, 0xd5, 0xab, 0x57, 0xaf, 0x5e, 0xbd, 0x7a, 0x5f, 0xd5, 0xb0, 0x64, 0x46, 0x51, 0x88, 0x87, 0xe3, 0x08, 0xed, 0x06, 0xa1, 0x1f, 0xf9, 0x6a, - 0xc9, 0xf1, 0x87, 0x4e, 0x60, 0x06, 0x78, 0x6b, 0xd3, 0xf1, 0x7d, 0xc7, 0x45, 0x9f, 0x33, 0xfc, - 0x70, 0x7c, 0xfa, 0xb9, 0xe9, 0x5d, 0x70, 0xa2, 0xad, 0x32, 0x23, 0xe2, 0x80, 0xf6, 0x67, 0xb0, + 0xc9, 0xf1, 0x87, 0x4e, 0x60, 0x06, 0x78, 0x6b, 0xd3, 0xf1, 0x7d, 0xc7, 0x45, 0x9f, 0x31, 0xfc, + 0x70, 0x7c, 0xfa, 0x99, 0xe9, 0x5d, 0x70, 0xa2, 0xad, 0x32, 0x23, 0xe2, 0x80, 0xf6, 0x67, 0xb0, 0x74, 0x14, 0x62, 0x07, 0x7b, 0x0d, 0xc9, 0x4a, 0x5d, 0x87, 0x79, 0x9f, 0xa1, 0x36, 0x72, 0x77, 0x73, 0xdb, 0x55, 0x5d, 0x40, 0xda, 0x53, 0x58, 0x6c, 0x90, 0x3e, 0x72, 0x46, 0xc8, 0x8b, 0x54, 0x15, 0x8a, 0xd1, 0x45, 0x80, 0x04, 0x09, 0xfb, 0x56, 0x37, 0x60, 0xc1, 0x1b, 0x8f, 0x86, 0x28, 0x24, 0x1b, 0xf9, 0xbb, 0x85, 0xed, 0xaa, 0x2e, 0x41, 0xed, 0x19, 0x2c, 0x35, 0x48, 0xcf, 0x8c, - 0xce, 0x92, 0x55, 0x3e, 0x87, 0x12, 0xe1, 0xbc, 0xc8, 0x46, 0xee, 0x6e, 0x61, 0xbb, 0xbc, 0xb7, - 0xb2, 0x2b, 0xa5, 0xdf, 0x8d, 0xd7, 0xd1, 0x63, 0x22, 0xed, 0x33, 0x50, 0xba, 0xe8, 0x75, 0xf4, + 0xce, 0x92, 0x55, 0x3e, 0x83, 0x12, 0xe1, 0xbc, 0xc8, 0x46, 0xee, 0x6e, 0x61, 0xbb, 0xbc, 0xb7, + 0xb2, 0x2b, 0xa5, 0xdf, 0x8d, 0xd7, 0xd1, 0x63, 0x22, 0xed, 0x53, 0x50, 0xba, 0xe8, 0x75, 0xf4, 0x8d, 0x1f, 0x24, 0x4c, 0x36, 0xa1, 0xe4, 0xa1, 0xd7, 0x91, 0x71, 0xe6, 0x07, 0x4c, 0x92, 0x45, 0x7d, 0xc1, 0xe3, 0x34, 0xda, 0x0e, 0xac, 0x1f, 0x8e, 0xdd, 0x08, 0xb7, 0x5e, 0xe3, 0xa8, 0x89, 0x89, 0x95, 0x4c, 0x52, 0xa0, 0x30, 0x42, 0xb6, 0x90, 0x9c, 0x7e, 0x6a, 0x4f, 0x40, 0xed, 0xf8, @@ -3956,7 +3974,7 @@ var fileDescriptor0 = []byte{ 0x7d, 0x03, 0x4b, 0xed, 0x5e, 0x83, 0x4b, 0x46, 0xb7, 0x8e, 0x5f, 0x53, 0xdd, 0x04, 0xec, 0xcb, 0x70, 0x91, 0xb4, 0x93, 0x45, 0x8e, 0xe9, 0x20, 0x8f, 0x9a, 0x10, 0x07, 0xd8, 0x66, 0x17, 0x75, 0x01, 0x69, 0x0e, 0xac, 0x77, 0xcc, 0x21, 0x72, 0x91, 0x3d, 0xcd, 0x70, 0x1d, 0xe6, 0x5d, 0x3a, - 0x22, 0xf7, 0x24, 0xa0, 0xa9, 0x85, 0xf2, 0x57, 0x2f, 0x54, 0xc8, 0x2c, 0xf4, 0x19, 0x2c, 0xb7, + 0x22, 0xf7, 0x24, 0xa0, 0xa9, 0x85, 0xf2, 0x57, 0x2f, 0x54, 0xc8, 0x2c, 0xf4, 0x29, 0x2c, 0xb7, 0x3c, 0xcb, 0x0c, 0xc8, 0xd8, 0x35, 0x23, 0xec, 0x7b, 0xdd, 0x8e, 0xde, 0x4e, 0xab, 0x3b, 0x97, 0x55, 0x77, 0x0f, 0x6e, 0xea, 0xfe, 0x38, 0x42, 0x4d, 0x4c, 0x22, 0xec, 0x39, 0x63, 0x4c, 0xce, 0x50, 0x38, 0x78, 0xe5, 0x1f, 0x59, 0x11, 0x8a, 0x1a, 0x7d, 0x75, 0x15, 0xe6, 0x4c, 0x7b, 0x14, @@ -3965,10 +3983,10 @@ var fileDescriptor0 = []byte{ 0x99, 0xe1, 0x73, 0x7f, 0x1c, 0xfe, 0x70, 0x19, 0x5b, 0xb0, 0xd9, 0x8a, 0xce, 0x50, 0xe8, 0xa1, 0x48, 0x5c, 0xb7, 0xb6, 0x8d, 0xbc, 0x08, 0x9f, 0x62, 0x14, 0xce, 0xbc, 0xe0, 0xab, 0x30, 0x37, 0x31, 0xdd, 0x31, 0x62, 0x9c, 0x2a, 0x3a, 0x07, 0xb4, 0x3f, 0xe5, 0xe0, 0x76, 0xeb, 0xa4, 0xd7, - 0x95, 0xbc, 0x1a, 0xe3, 0xc8, 0xa7, 0x37, 0xce, 0x9f, 0xa0, 0xf0, 0x82, 0xc9, 0xac, 0x7e, 0x0a, + 0x95, 0xbc, 0x1a, 0xe3, 0xc8, 0xa7, 0x37, 0xce, 0x9f, 0xa0, 0xf0, 0x82, 0xc9, 0xac, 0x7e, 0x02, 0xf9, 0x90, 0xdb, 0x5e, 0x79, 0x6f, 0x75, 0x97, 0xbb, 0xa6, 0x5d, 0xe9, 0x9a, 0x76, 0x1b, 0xde, - 0x85, 0x9e, 0x0f, 0x6d, 0xf5, 0x0b, 0x28, 0x20, 0x82, 0x19, 0xf3, 0xf2, 0xde, 0x27, 0x89, 0x37, - 0xb8, 0x52, 0x48, 0x9d, 0xd2, 0xab, 0x3f, 0x83, 0x0a, 0x12, 0x14, 0x46, 0x64, 0x3a, 0xcc, 0x12, + 0x85, 0x9e, 0x0f, 0x6d, 0xf5, 0x0b, 0x28, 0x20, 0x82, 0x19, 0xf3, 0xf2, 0xde, 0xc7, 0x89, 0x37, + 0xb8, 0x52, 0x48, 0x9d, 0xd2, 0xab, 0x3f, 0x87, 0x0a, 0x12, 0x14, 0x46, 0x64, 0x3a, 0xcc, 0x12, 0xaa, 0x7a, 0x59, 0xe2, 0x06, 0xa6, 0x43, 0x05, 0x67, 0xf6, 0xb4, 0x51, 0xe4, 0xba, 0x61, 0x80, 0xf6, 0x7f, 0x39, 0xb8, 0x41, 0x05, 0x3f, 0x6c, 0x1c, 0xd0, 0x93, 0x99, 0xa0, 0x30, 0xc2, 0x04, 0x31, 0xb7, 0xf3, 0x41, 0x48, 0x7d, 0x07, 0xca, 0x23, 0xd3, 0x32, 0xa4, 0xcd, 0x16, 0x99, 0xa9, @@ -3982,7 +4000,7 @@ var fileDescriptor0 = []byte{ 0xb7, 0x00, 0x9c, 0x57, 0xf1, 0xae, 0xe7, 0xf9, 0xae, 0x9d, 0x57, 0x29, 0xf7, 0xc4, 0xef, 0xcb, 0x42, 0xfa, 0xbe, 0xfc, 0x0d, 0xd4, 0xb8, 0x2a, 0x0e, 0xfb, 0xed, 0x1f, 0xd9, 0x3c, 0x28, 0xa3, 0x88, 0xed, 0xf4, 0x6a, 0x46, 0x91, 0xf6, 0x5b, 0xa8, 0xf4, 0xf5, 0x9e, 0xef, 0x62, 0xeb, 0x82, - 0x39, 0x74, 0x6a, 0xe0, 0xc8, 0x73, 0xa2, 0x33, 0x99, 0xa9, 0x70, 0x48, 0xfd, 0x14, 0xaa, 0x76, + 0x39, 0x74, 0x6a, 0xe0, 0xc8, 0x73, 0xa2, 0x33, 0x99, 0xa9, 0x70, 0x48, 0xfd, 0x04, 0xaa, 0x76, 0xda, 0x4d, 0x8a, 0x15, 0xb3, 0x48, 0xba, 0x49, 0xcb, 0x77, 0xfd, 0x50, 0x28, 0x98, 0x03, 0xd4, 0x61, 0x22, 0xcf, 0x0e, 0x7c, 0xec, 0x45, 0x4c, 0xb3, 0x15, 0x3d, 0x86, 0xe9, 0xc5, 0xd9, 0x14, 0xf1, 0x8b, 0xe9, 0xe1, 0xed, 0x42, 0x18, 0x57, 0x52, 0xfe, 0x0d, 0x4a, 0xca, 0x06, 0xba, 0xc2, @@ -4005,7 +4023,7 @@ var fileDescriptor0 = []byte{ 0x6c, 0xfb, 0x9e, 0x6f, 0x23, 0x66, 0x33, 0x25, 0x3d, 0x85, 0x61, 0xee, 0xce, 0x09, 0x8c, 0x90, 0xde, 0x82, 0x90, 0xb2, 0xe0, 0x71, 0xb0, 0x8c, 0x9d, 0x80, 0xdd, 0x8c, 0xb0, 0x6d, 0x6b, 0x7f, 0xc8, 0x53, 0x41, 0x3b, 0xd8, 0x3b, 0x4f, 0x09, 0xaa, 0x41, 0xd5, 0xc5, 0xde, 0xb9, 0xc1, 0x93, - 0x7c, 0x2c, 0x2b, 0x82, 0x32, 0x45, 0xb2, 0x72, 0xa0, 0x6d, 0xab, 0x9f, 0x42, 0x8d, 0xd1, 0x84, + 0x7c, 0x2c, 0x2b, 0x82, 0x32, 0x45, 0xb2, 0x72, 0xa0, 0x6d, 0xab, 0x9f, 0x40, 0x8d, 0xd1, 0x84, 0x68, 0xe4, 0x47, 0x28, 0x91, 0xbf, 0x42, 0xb1, 0x3a, 0x43, 0xb6, 0x6d, 0x75, 0x17, 0x56, 0xb0, 0x17, 0xa1, 0xf0, 0xd4, 0xb4, 0x10, 0x73, 0xaa, 0x06, 0x0e, 0x26, 0xfb, 0xc2, 0xee, 0x97, 0xe3, 0x21, 0xea, 0x2e, 0xda, 0xc1, 0x64, 0x5f, 0x7d, 0x04, 0xaa, 0x87, 0xb0, 0x73, 0x36, 0xf4, 0xc3, @@ -4029,7 +4047,7 @@ var fileDescriptor0 = []byte{ 0x61, 0x78, 0x5d, 0x8c, 0xd3, 0x8c, 0x50, 0x76, 0x42, 0xb8, 0xc3, 0x5f, 0xd4, 0x4b, 0xa2, 0x15, 0x42, 0x68, 0x24, 0xa0, 0x1b, 0xa3, 0xe9, 0xed, 0x35, 0x91, 0x80, 0x91, 0x68, 0x1e, 0xac, 0x1f, 0x06, 0xc7, 0x5e, 0xf8, 0x3e, 0xc2, 0xbc, 0xcb, 0x7a, 0xbf, 0xcf, 0xc1, 0x56, 0x5c, 0x69, 0x13, - 0x1a, 0xe2, 0xf0, 0x29, 0xb6, 0x5a, 0xaf, 0x23, 0xe4, 0xd9, 0xc8, 0x56, 0x3f, 0x81, 0x2a, 0x26, + 0x1a, 0xe2, 0xf0, 0x29, 0xb6, 0x5a, 0xaf, 0x23, 0xe4, 0xd9, 0xc8, 0x56, 0x3f, 0x86, 0x2a, 0x26, 0x46, 0x14, 0x9a, 0x1e, 0xc1, 0x11, 0x9e, 0xf0, 0x83, 0x2e, 0xe9, 0x15, 0x4c, 0x06, 0x31, 0x4e, 0xdd, 0x84, 0x12, 0x19, 0x0f, 0x13, 0xef, 0x53, 0xd5, 0x17, 0xc8, 0x78, 0x48, 0xcf, 0x5e, 0xa4, 0x40, 0x85, 0x38, 0x05, 0xba, 0x03, 0x65, 0x6e, 0xc6, 0xbc, 0x56, 0xe6, 0x29, 0x08, 0xb7, 0xec, @@ -4037,160 +4055,161 @@ var fileDescriptor0 = []byte{ 0x2b, 0x7b, 0x3e, 0x6f, 0x16, 0xed, 0x1f, 0x72, 0x70, 0x23, 0xa9, 0xf8, 0x3f, 0x00, 0x5d, 0xed, 0x80, 0x7a, 0x62, 0xba, 0xd8, 0x66, 0x2d, 0x96, 0x58, 0x8c, 0x55, 0x98, 0x23, 0x91, 0x19, 0xc9, 0xc4, 0x89, 0x03, 0xda, 0x3d, 0xa8, 0x1e, 0xd0, 0x04, 0x3b, 0x4d, 0xc6, 0xd3, 0xef, 0x5c, 0x2a, - 0xfd, 0xd6, 0x7e, 0x0e, 0x55, 0xd6, 0xb8, 0x89, 0xc9, 0xee, 0x40, 0x39, 0x1a, 0x7b, 0x1e, 0x72, - 0x8d, 0x54, 0x32, 0x06, 0x1c, 0xc5, 0x22, 0xcb, 0x06, 0xac, 0x37, 0xd1, 0xa9, 0x39, 0x76, 0xa3, - 0x17, 0x66, 0x84, 0x5e, 0x99, 0x17, 0x72, 0xaa, 0xf6, 0x2d, 0xd4, 0x78, 0x52, 0xf3, 0x6e, 0x1a, - 0x8a, 0x73, 0x9d, 0x42, 0x3a, 0xd7, 0xd1, 0x41, 0x69, 0xf5, 0xdb, 0x2c, 0xfb, 0x8f, 0xd9, 0x6d, - 0x83, 0x82, 0x89, 0x41, 0xb0, 0xe7, 0xb8, 0xc8, 0x30, 0xad, 0x14, 0xc7, 0x1a, 0x26, 0x7d, 0x86, - 0x6e, 0x58, 0x92, 0x27, 0x2f, 0xa8, 0xf2, 0xe9, 0x82, 0x6a, 0x0f, 0x56, 0x5a, 0xfd, 0xf6, 0x28, - 0xf0, 0xc3, 0x28, 0x95, 0xc4, 0xd3, 0xbb, 0x8c, 0x88, 0x81, 0x19, 0x5e, 0x34, 0x88, 0x4a, 0x88, - 0x70, 0x3a, 0xed, 0x18, 0x56, 0x0e, 0x4d, 0xeb, 0xd0, 0xe7, 0xf1, 0x37, 0x16, 0x85, 0x56, 0x84, - 0xc4, 0x20, 0x11, 0xb6, 0xce, 0x2f, 0x84, 0x0c, 0x25, 0x4c, 0xfa, 0x0c, 0xa6, 0x05, 0x18, 0x41, - 0xbf, 0x19, 0x23, 0xcf, 0x42, 0x86, 0x37, 0x1e, 0xc9, 0x02, 0x4c, 0xe2, 0xba, 0xe3, 0x91, 0x76, - 0x0f, 0x96, 0x79, 0xb6, 0x74, 0x68, 0x26, 0x06, 0xa5, 0x40, 0x61, 0x64, 0x5a, 0x42, 0x04, 0xfa, - 0xa9, 0x3d, 0x85, 0x95, 0x41, 0x68, 0x9e, 0x9e, 0x62, 0x4b, 0x37, 0xa3, 0x44, 0xaf, 0xd3, 0x85, - 0x86, 0x0a, 0xc5, 0x90, 0x5a, 0x00, 0x5d, 0x28, 0xaf, 0xb3, 0x6f, 0xed, 0x5b, 0x58, 0x13, 0x53, - 0xa9, 0x4e, 0x52, 0xf6, 0xb2, 0x05, 0xa5, 0x08, 0x85, 0x23, 0xec, 0x99, 0xae, 0x94, 0x5c, 0xc2, - 0xd4, 0x15, 0x13, 0x73, 0x14, 0xb8, 0x9c, 0x55, 0x49, 0x17, 0x90, 0x76, 0x0c, 0x9a, 0x8e, 0x6c, - 0x1c, 0x22, 0x2b, 0xba, 0xc6, 0x79, 0x4c, 0x8b, 0x35, 0x65, 0xd0, 0xf9, 0x4b, 0x06, 0xfd, 0xd7, - 0xf0, 0x89, 0x64, 0x7b, 0x9d, 0x0f, 0xb8, 0xb2, 0x91, 0xf8, 0xe6, 0x15, 0x4e, 0x92, 0x15, 0xae, - 0xbb, 0xca, 0xef, 0x2c, 0xf9, 0xc3, 0x58, 0xbb, 0x3a, 0x1a, 0x99, 0xe1, 0x79, 0xcc, 0x49, 0x85, - 0xa2, 0x4d, 0x2c, 0x59, 0x02, 0xb1, 0x6f, 0xed, 0x6b, 0x58, 0x3a, 0xf6, 0xce, 0x3d, 0xff, 0x95, - 0x97, 0x26, 0x7b, 0xcb, 0x76, 0xdf, 0x09, 0xdc, 0x94, 0xb3, 0x66, 0xb6, 0xa8, 0xeb, 0x97, 0x5b, - 0xd4, 0x57, 0x85, 0x80, 0x4c, 0xe3, 0xfa, 0x00, 0x94, 0x06, 0xd9, 0x7f, 0xcf, 0x47, 0x82, 0x67, - 0xb0, 0xde, 0x20, 0xfb, 0xef, 0xd7, 0x7b, 0x47, 0xb0, 0xd2, 0x1b, 0x11, 0x3c, 0x60, 0x2e, 0x26, - 0x61, 0xb0, 0x0a, 0x73, 0xa7, 0xae, 0xe9, 0xc8, 0x53, 0xe1, 0x40, 0xac, 0xb7, 0x7c, 0x56, 0x6f, - 0xfc, 0xb2, 0x17, 0x52, 0x97, 0x5d, 0xf4, 0xdf, 0x79, 0x4b, 0x21, 0x8f, 0x6d, 0xed, 0x2f, 0xe1, - 0x36, 0x5f, 0x82, 0xf9, 0xbb, 0xfe, 0x78, 0x38, 0xe8, 0x9c, 0x64, 0x7a, 0xd6, 0xe9, 0x32, 0xac, - 0xca, 0xcb, 0xb0, 0x75, 0x98, 0xb7, 0x7c, 0xff, 0x1c, 0xcb, 0x23, 0x11, 0x90, 0xf6, 0x0b, 0xd8, - 0xbc, 0xc4, 0x4b, 0xe6, 0x22, 0xf4, 0x7e, 0xc9, 0x5c, 0x44, 0xf0, 0x8a, 0x61, 0x6d, 0x17, 0xd6, - 0x2f, 0x4d, 0x64, 0x6e, 0xfa, 0x0a, 0xf7, 0x7c, 0x0c, 0xb7, 0x2e, 0xd1, 0xf7, 0x75, 0x9a, 0x8b, - 0xa1, 0x90, 0xba, 0x92, 0x2b, 0xb4, 0x74, 0x9b, 0xb7, 0x0a, 0x38, 0x8d, 0xb4, 0xde, 0x04, 0xa3, - 0x9d, 0xc0, 0xa7, 0x33, 0xd8, 0x1e, 0x98, 0x9e, 0x4d, 0x83, 0x0b, 0xa2, 0x46, 0xd1, 0x35, 0x47, - 0x88, 0x96, 0x42, 0x96, 0x44, 0x1a, 0x81, 0x19, 0x9d, 0x19, 0x9e, 0x39, 0x42, 0xe2, 0x12, 0x2e, - 0x5b, 0xd3, 0xf4, 0xda, 0x53, 0xb8, 0x31, 0x53, 0x5c, 0xec, 0x87, 0xb4, 0x78, 0x61, 0x9a, 0xe1, - 0xdf, 0x89, 0x66, 0x38, 0xac, 0xb5, 0x67, 0xee, 0xf4, 0x19, 0xf6, 0x6c, 0xec, 0x39, 0xfd, 0x76, - 0x93, 0xe6, 0x93, 0x43, 0x82, 0xaf, 0x2f, 0xc3, 0x19, 0x85, 0xd6, 0x85, 0x4a, 0x66, 0xe6, 0x1a, - 0xcc, 0x13, 0x83, 0x2a, 0x46, 0xb8, 0xbb, 0x39, 0xf2, 0xdc, 0x35, 0x1d, 0x8a, 0xc6, 0x1c, 0xcd, - 0x7d, 0xdd, 0x1c, 0x66, 0x68, 0x05, 0x0a, 0x44, 0x14, 0xc6, 0x15, 0x9d, 0x7e, 0x6a, 0x7f, 0xca, - 0xc1, 0x6a, 0x5f, 0x9f, 0xd4, 0x5b, 0x9e, 0xdd, 0xf3, 0xb1, 0x17, 0x3d, 0x43, 0x67, 0xe6, 0x04, - 0xfb, 0xa1, 0xba, 0x07, 0xa5, 0xa1, 0xf8, 0x16, 0x09, 0x71, 0x2a, 0x3b, 0xa5, 0x33, 0x24, 0xa5, - 0x1e, 0xd3, 0xd1, 0xc0, 0x31, 0x74, 0x7d, 0xeb, 0x3c, 0xd5, 0xc4, 0x29, 0x31, 0x44, 0x07, 0x79, - 0xec, 0x7d, 0xcd, 0xb7, 0x51, 0xaa, 0x25, 0xb5, 0x40, 0x61, 0x31, 0x74, 0x3a, 0xf6, 0x2c, 0x36, - 0xc4, 0x33, 0x83, 0x05, 0x0a, 0xd3, 0xa1, 0x8f, 0x61, 0xc1, 0x0c, 0x9d, 0x54, 0xeb, 0x71, 0xde, - 0x0c, 0x9d, 0x0e, 0xf2, 0xb4, 0xff, 0xce, 0x41, 0x8d, 0x89, 0xf1, 0x43, 0x75, 0xb1, 0x06, 0xf3, - 0x43, 0x8e, 0x2e, 0x70, 0xf4, 0x30, 0xad, 0xa2, 0x62, 0xac, 0x22, 0xf5, 0x57, 0x70, 0x43, 0x76, - 0xed, 0x0c, 0xb9, 0x55, 0x83, 0x44, 0xe1, 0xd8, 0x8a, 0xc6, 0x21, 0x62, 0x62, 0x95, 0xf7, 0x6e, - 0x67, 0x95, 0x33, 0xad, 0x4e, 0x7d, 0x53, 0xb2, 0x90, 0x98, 0xbe, 0x64, 0xa0, 0xbd, 0x84, 0x8f, - 0x67, 0x58, 0x47, 0xab, 0xdb, 0xe9, 0x5d, 0x71, 0x03, 0xee, 0x43, 0x11, 0x79, 0x6e, 0xc0, 0xb6, - 0x53, 0xdb, 0x53, 0x53, 0xcd, 0xe0, 0x6e, 0xa7, 0xc7, 0xab, 0x14, 0x3a, 0xae, 0x7d, 0x09, 0xa5, - 0xbe, 0xfe, 0x92, 0x16, 0xe9, 0xd1, 0x15, 0x9c, 0xd6, 0x61, 0xfe, 0x15, 0x1b, 0x17, 0xa7, 0x25, - 0x20, 0xed, 0xd7, 0x50, 0x11, 0xfe, 0xf0, 0x39, 0xa3, 0x5b, 0x83, 0xf9, 0x49, 0x46, 0xb3, 0x13, - 0xa9, 0x42, 0x33, 0xa3, 0x59, 0x53, 0xa2, 0x49, 0x46, 0xb3, 0x64, 0x4a, 0xe1, 0xc5, 0x94, 0xc2, - 0x35, 0x3d, 0x5e, 0x8b, 0x8a, 0xde, 0x50, 0x1f, 0xa5, 0x25, 0x2d, 0x67, 0xac, 0x2e, 0x25, 0x92, - 0xdc, 0xc1, 0xec, 0x64, 0xe8, 0x3f, 0x73, 0x19, 0xa6, 0xcf, 0xde, 0x91, 0xa9, 0xb0, 0x81, 0xfc, - 0x5b, 0xdb, 0x40, 0xe1, 0x7d, 0x6d, 0xe0, 0xb7, 0x33, 0x1c, 0x78, 0x5f, 0x17, 0xb2, 0x75, 0x30, - 0x89, 0xd4, 0x9d, 0xf8, 0xa8, 0xf8, 0x16, 0xd4, 0xf4, 0x62, 0xfc, 0x90, 0xe5, 0xf1, 0xa9, 0x3f, - 0x4f, 0x85, 0xba, 0xeb, 0x1a, 0x76, 0x49, 0xac, 0xfb, 0x1a, 0xee, 0x5c, 0x0e, 0x20, 0x0e, 0x0d, - 0x61, 0x2d, 0x21, 0xf3, 0x35, 0x2f, 0x9e, 0x7b, 0x70, 0xf3, 0xd2, 0xe4, 0xe3, 0x66, 0xaf, 0x89, - 0x48, 0xd4, 0xf3, 0x43, 0xd6, 0xfc, 0x8c, 0xd3, 0xcf, 0xaa, 0xce, 0xbe, 0xb5, 0x26, 0x6c, 0x5c, - 0x9e, 0xc3, 0xf3, 0x88, 0x77, 0xc8, 0x1f, 0xba, 0x50, 0x4b, 0x71, 0x19, 0x74, 0x4e, 0x66, 0xce, - 0xa5, 0x75, 0xbd, 0x3b, 0xb9, 0x5e, 0x15, 0x8c, 0x42, 0x6b, 0xc2, 0x6a, 0x8a, 0x5f, 0x12, 0xaf, - 0x1f, 0x09, 0x0e, 0x3c, 0x6f, 0xd8, 0x48, 0x54, 0x9f, 0x5d, 0x5d, 0x70, 0x11, 0x65, 0x5f, 0xfd, - 0x03, 0x2c, 0xfb, 0xb2, 0x49, 0x69, 0xfd, 0x27, 0x48, 0x4a, 0xff, 0x0a, 0xee, 0xb4, 0x7b, 0xf5, - 0x9f, 0x24, 0xab, 0xdb, 0x01, 0xa5, 0x81, 0x1d, 0xaa, 0xe8, 0xf6, 0x8b, 0xde, 0x21, 0x8a, 0x42, - 0x6c, 0x51, 0x0f, 0x36, 0x62, 0x5f, 0x4c, 0xd0, 0xa2, 0x2e, 0x20, 0xed, 0x2b, 0xa8, 0x09, 0xda, - 0x77, 0xb7, 0xaa, 0xa7, 0x50, 0xa5, 0x73, 0xd3, 0xdd, 0x8a, 0xf4, 0xf1, 0x5f, 0x67, 0x40, 0x63, - 0xa8, 0x75, 0x68, 0xe1, 0x25, 0xf7, 0xcd, 0xea, 0x25, 0xc7, 0xf5, 0x87, 0xb1, 0xc6, 0x44, 0x63, - 0x98, 0xe3, 0x98, 0xca, 0x12, 0x9d, 0xda, 0x66, 0x64, 0x3e, 0xce, 0xe8, 0xb4, 0x49, 0x31, 0x59, - 0x82, 0x3d, 0xd9, 0xd7, 0x8e, 0x09, 0xf6, 0xb4, 0x97, 0xb0, 0x99, 0x59, 0x36, 0xa3, 0xee, 0xaf, - 0x66, 0xa9, 0x3b, 0x65, 0xc3, 0x59, 0x81, 0xb3, 0x2a, 0xff, 0x63, 0x0e, 0xca, 0xbc, 0x1d, 0xc7, - 0x03, 0xc1, 0x16, 0x94, 0xfc, 0x09, 0x0a, 0x5d, 0xdf, 0xb4, 0x65, 0x7d, 0x25, 0x61, 0xf6, 0x7b, - 0x40, 0x14, 0x99, 0xd6, 0x99, 0xf8, 0x3d, 0xa0, 0xa4, 0xc7, 0x30, 0x7b, 0x09, 0x7b, 0x1d, 0xa1, - 0x90, 0xd6, 0x65, 0x3c, 0x28, 0xc4, 0x30, 0x6b, 0xf2, 0x0f, 0x43, 0x11, 0x14, 0xe8, 0x27, 0x3d, - 0x54, 0xde, 0x82, 0x67, 0xc1, 0xb5, 0xa4, 0x0b, 0x88, 0xa6, 0xbd, 0xa2, 0xfb, 0x5c, 0xd2, 0xf3, - 0x93, 0xba, 0xf6, 0xf7, 0xac, 0x7f, 0xdb, 0x7e, 0xd1, 0x7b, 0x2e, 0xf3, 0x67, 0xdb, 0x7f, 0xe5, - 0x09, 0xc1, 0xd8, 0xb7, 0x7a, 0x0b, 0xc0, 0xf3, 0x8d, 0xb1, 0xc7, 0x9e, 0xa4, 0x85, 0x58, 0x8b, - 0x9e, 0x7f, 0xcc, 0x11, 0xf4, 0x2a, 0x4a, 0x73, 0x4e, 0x2e, 0x54, 0x49, 0xaf, 0x08, 0x83, 0xe6, - 0x36, 0x7f, 0x0f, 0x6a, 0x41, 0xe8, 0x07, 0xa6, 0x43, 0x33, 0x45, 0x8f, 0x10, 0x53, 0xc8, 0x5a, - 0x8d, 0xb1, 0x5d, 0x42, 0x4c, 0xed, 0x09, 0x2c, 0x76, 0x48, 0x3f, 0xd4, 0x4d, 0xcf, 0x61, 0x96, - 0x35, 0x44, 0xc9, 0x7f, 0x4f, 0x1c, 0xa0, 0x5b, 0x45, 0x9e, 0xec, 0xfb, 0xd3, 0x4f, 0xed, 0xf7, - 0xec, 0xd9, 0xa3, 0x1f, 0x1e, 0x98, 0x01, 0x6f, 0x83, 0x63, 0xc4, 0x16, 0xc4, 0xc1, 0x64, 0xdf, - 0x20, 0xe3, 0x80, 0x3a, 0x4b, 0x24, 0x75, 0x5d, 0xa5, 0xd8, 0xbe, 0x44, 0x0a, 0xb2, 0x7a, 0x8a, - 0x2c, 0x1f, 0x93, 0xd5, 0x13, 0xb2, 0x87, 0x30, 0x1f, 0x52, 0x99, 0x64, 0x0b, 0x6d, 0x25, 0xdd, - 0x65, 0x14, 0xf2, 0xea, 0x82, 0x44, 0xfb, 0x25, 0xd4, 0x28, 0x92, 0xbd, 0x59, 0x3c, 0xa3, 0xa9, - 0x5b, 0x6a, 0x7a, 0xee, 0xcd, 0xd3, 0xff, 0xae, 0x00, 0x4b, 0x9d, 0xc4, 0xf6, 0x58, 0xcb, 0x56, - 0x85, 0x62, 0x2a, 0xb3, 0x66, 0xdf, 0xea, 0x43, 0x19, 0x8f, 0x79, 0x07, 0x75, 0x6d, 0xba, 0xf9, - 0x9b, 0x09, 0xc7, 0xf7, 0x61, 0x89, 0x1f, 0x52, 0xf2, 0x2e, 0xc3, 0xfd, 0x1e, 0x3f, 0x3b, 0xf9, - 0x32, 0xa3, 0x3e, 0x04, 0x75, 0x8a, 0xce, 0x98, 0xd4, 0xc5, 0x53, 0xc8, 0x52, 0x86, 0xf4, 0xa4, - 0xce, 0x9b, 0x1c, 0x98, 0xb0, 0xc7, 0x22, 0x66, 0x66, 0x15, 0xbd, 0x44, 0x11, 0x8d, 0x10, 0x99, - 0xec, 0x5d, 0x91, 0x75, 0x7b, 0x98, 0xb1, 0x55, 0x74, 0x01, 0xa9, 0x07, 0xb0, 0x44, 0x42, 0xc3, - 0x4a, 0x9d, 0x15, 0x7b, 0xd5, 0x9e, 0xea, 0x5e, 0x67, 0x4f, 0x53, 0xaf, 0x91, 0xec, 0xe9, 0x7e, - 0x02, 0x55, 0x12, 0x1a, 0xa6, 0xeb, 0xd0, 0xe2, 0xe0, 0x6c, 0x44, 0x36, 0x4a, 0x6c, 0x8d, 0x0a, - 0x09, 0x1b, 0x31, 0x4e, 0xfd, 0x73, 0xa8, 0x91, 0x50, 0x3c, 0x27, 0xb1, 0x14, 0x7a, 0x63, 0x91, - 0x2d, 0xb4, 0x91, 0x5d, 0x28, 0x39, 0x27, 0x3a, 0x3f, 0x81, 0xb4, 0x3f, 0x16, 0x33, 0x07, 0xd1, - 0xc1, 0xde, 0xf9, 0xcc, 0x83, 0x98, 0xa1, 0xdb, 0xfc, 0xdb, 0xeb, 0xb6, 0x30, 0x5b, 0xb7, 0xdb, - 0xa0, 0x88, 0xd7, 0x90, 0x84, 0x2b, 0x3f, 0x86, 0x1a, 0xc7, 0xc7, 0x6c, 0x3f, 0x83, 0x95, 0x69, - 0x4a, 0x23, 0x7e, 0x8f, 0x52, 0xb2, 0xc4, 0x27, 0x75, 0xea, 0x08, 0x99, 0x17, 0x35, 0x9c, 0xd0, - 0x1f, 0x07, 0xec, 0x70, 0xaa, 0x3a, 0x30, 0xd4, 0x0b, 0x8a, 0x51, 0x77, 0x60, 0xd9, 0xe6, 0x0d, - 0x3c, 0x23, 0x42, 0x86, 0x88, 0x0c, 0xfc, 0xc7, 0x83, 0x25, 0x31, 0x30, 0x40, 0x22, 0x74, 0xdc, - 0x02, 0xc0, 0x4e, 0x20, 0x89, 0x4a, 0xfc, 0xcd, 0x19, 0x3b, 0x41, 0x12, 0x59, 0x84, 0x0d, 0x2c, - 0x66, 0x6c, 0xe0, 0x26, 0x2c, 0x0e, 0x4d, 0xcf, 0x7e, 0x85, 0xed, 0xe8, 0x6c, 0x03, 0x58, 0x53, - 0x2a, 0x41, 0xa8, 0x8f, 0x61, 0x35, 0x44, 0x04, 0x85, 0x13, 0x73, 0xe8, 0x22, 0x23, 0x21, 0x2c, - 0x33, 0xc2, 0x95, 0x64, 0xec, 0x59, 0x7a, 0xca, 0xd8, 0xe3, 0x03, 0xc8, 0x4e, 0x4d, 0xa9, 0xdc, - 0x2d, 0xd0, 0x29, 0xc9, 0x58, 0x32, 0x65, 0x1b, 0x14, 0x6a, 0x42, 0xf6, 0xaf, 0x4d, 0x0b, 0x79, - 0xd6, 0x85, 0x41, 0xb3, 0xd5, 0x2a, 0xdb, 0x40, 0x8d, 0x84, 0x0d, 0x89, 0xee, 0x63, 0xde, 0x40, - 0x0d, 0x5d, 0x87, 0x6c, 0xd4, 0xd8, 0x7f, 0x04, 0x1c, 0xd0, 0xfe, 0x36, 0x07, 0xcb, 0x29, 0xeb, - 0x10, 0xef, 0x1f, 0x8f, 0x81, 0x6e, 0xdf, 0x48, 0x27, 0xca, 0x99, 0x47, 0x10, 0xe9, 0x68, 0xf5, - 0x12, 0x76, 0x82, 0xe7, 0xb2, 0x80, 0x10, 0x4a, 0xca, 0x67, 0x94, 0xa4, 0x31, 0x1b, 0x17, 0x2f, - 0x35, 0x24, 0x7e, 0x8b, 0x2d, 0x13, 0xf1, 0xd6, 0xd2, 0xc7, 0xb6, 0xf6, 0xcf, 0x2c, 0xb6, 0x24, - 0x71, 0xea, 0x33, 0x28, 0xa6, 0xde, 0x83, 0x36, 0xd3, 0x2b, 0x67, 0x1c, 0x8a, 0xce, 0xc8, 0x28, - 0xb9, 0x8b, 0xbd, 0x73, 0xe1, 0x41, 0x66, 0x93, 0x53, 0xb3, 0xd7, 0x19, 0x99, 0xfa, 0x24, 0xf3, - 0x0b, 0x41, 0x79, 0xef, 0xc6, 0xcc, 0x09, 0xe2, 0xc7, 0x1c, 0xf9, 0x47, 0x84, 0x0e, 0x8a, 0x48, - 0x1f, 0x7e, 0x60, 0xef, 0x66, 0x46, 0xf3, 0xf7, 0xdf, 0xf3, 0xb0, 0x4e, 0xcb, 0x83, 0x38, 0xf9, - 0xef, 0x8f, 0x87, 0x3c, 0xff, 0x55, 0x1f, 0xc9, 0x4b, 0x16, 0x57, 0xd1, 0xc9, 0xff, 0x28, 0x8a, - 0x1b, 0x5f, 0xee, 0x0e, 0x7f, 0x42, 0xda, 0x81, 0xe5, 0xe4, 0x15, 0x4d, 0x12, 0xf3, 0xf5, 0x97, - 0xe2, 0x07, 0x33, 0x41, 0xfb, 0x00, 0x96, 0x68, 0x45, 0x1d, 0x61, 0xdf, 0x33, 0x32, 0xef, 0x51, - 0x35, 0x89, 0x4e, 0x08, 0xcd, 0xd0, 0x19, 0xd3, 0xaa, 0x40, 0x12, 0xf2, 0x2c, 0xb2, 0x26, 0xd1, - 0x82, 0xf0, 0x31, 0xac, 0xb2, 0x0c, 0x36, 0xf0, 0x69, 0xc2, 0x9a, 0xb0, 0xe5, 0x55, 0xfa, 0x4a, - 0x66, 0xec, 0xaa, 0x29, 0xe2, 0xdf, 0x8d, 0xf9, 0x19, 0x53, 0x8e, 0xf8, 0x8f, 0x1c, 0xf7, 0xa0, - 0xc2, 0x74, 0xd5, 0x6e, 0xc6, 0x85, 0x28, 0xd5, 0xb7, 0xf1, 0x58, 0x16, 0xa2, 0x14, 0x7a, 0xac, - 0x3d, 0x86, 0x05, 0x4a, 0x46, 0x75, 0x78, 0x1f, 0x0a, 0x91, 0x3b, 0xb9, 0x36, 0x55, 0xa3, 0x04, - 0xda, 0xbf, 0xe5, 0x61, 0x8d, 0xce, 0x69, 0x7b, 0xa7, 0x7e, 0x38, 0x62, 0x4d, 0x32, 0x71, 0x0a, - 0xa2, 0xfa, 0xcb, 0x25, 0xd5, 0xdf, 0xa3, 0x6c, 0xb4, 0x9a, 0x6a, 0x84, 0x48, 0xe1, 0xa4, 0x29, - 0x3c, 0x84, 0xe5, 0x4b, 0xb5, 0xa2, 0xd0, 0xb6, 0x32, 0x5d, 0x01, 0xaa, 0xdf, 0x41, 0x85, 0xa6, - 0xf9, 0x2c, 0xd5, 0xa7, 0x29, 0x66, 0x91, 0xc9, 0xfd, 0x79, 0x76, 0x85, 0x4b, 0x32, 0xee, 0x0a, - 0x9b, 0x71, 0x27, 0xa4, 0xe5, 0x45, 0xe1, 0x85, 0x0e, 0x24, 0x46, 0x6c, 0xf5, 0x60, 0x69, 0x6a, - 0x78, 0x46, 0xf7, 0xef, 0x41, 0x3a, 0xf3, 0x2d, 0xef, 0x2d, 0x67, 0x17, 0xa4, 0xb5, 0x0c, 0x1f, - 0xff, 0x2a, 0xff, 0x65, 0x4e, 0xfb, 0x97, 0x1c, 0x28, 0x14, 0xdd, 0x79, 0xd2, 0x47, 0xe1, 0x04, - 0x5b, 0x88, 0xaa, 0xe9, 0x99, 0x28, 0x50, 0x92, 0xc4, 0xf8, 0x41, 0x96, 0x49, 0x9a, 0x7a, 0x37, - 0x23, 0x2d, 0xab, 0x64, 0xa8, 0xa8, 0x87, 0x50, 0xf9, 0x31, 0xe5, 0xfc, 0x02, 0x16, 0x85, 0x7b, - 0xe1, 0x3d, 0xb5, 0xb7, 0x4b, 0xda, 0x77, 0x08, 0xfb, 0x9f, 0x40, 0xbc, 0xf0, 0xaa, 0x2b, 0xb0, - 0xd4, 0xe9, 0x1b, 0x14, 0x34, 0x8e, 0xbb, 0xdf, 0x76, 0x8f, 0x5e, 0x76, 0x95, 0x8f, 0x54, 0x05, - 0x2a, 0x12, 0xd9, 0x3d, 0x6a, 0xb6, 0x94, 0x5c, 0x1a, 0xd3, 0x69, 0x77, 0xbf, 0x55, 0xf2, 0xea, - 0x1a, 0x2c, 0x4b, 0x4c, 0x4f, 0x6f, 0x3d, 0x6f, 0x7f, 0x6f, 0x9c, 0xec, 0x2b, 0x85, 0x59, 0xe8, - 0xba, 0x52, 0xdc, 0xf9, 0x2f, 0xf6, 0xfa, 0x9c, 0x3c, 0xf2, 0xaa, 0x1f, 0xc3, 0x4a, 0xa7, 0x6f, - 0xf4, 0xf4, 0xa3, 0xc1, 0xd1, 0xc1, 0x51, 0x27, 0xb5, 0xf6, 0xd4, 0x40, 0xbb, 0xdf, 0xee, 0x1b, - 0x9d, 0xc7, 0x4a, 0x6e, 0xf6, 0xc0, 0x9e, 0x92, 0x9f, 0x1e, 0x38, 0xea, 0xf7, 0x9e, 0x1b, 0x27, - 0x7b, 0x4a, 0x41, 0x5d, 0x07, 0x35, 0x3d, 0xd0, 0x6c, 0xeb, 0xad, 0x83, 0x81, 0x52, 0x9c, 0xc6, - 0xf7, 0x07, 0x8d, 0x41, 0xfb, 0x40, 0x99, 0x9b, 0xcd, 0xe8, 0x89, 0x32, 0xbf, 0xf3, 0x1f, 0x73, - 0xfc, 0x62, 0xc6, 0x76, 0x5c, 0x81, 0x92, 0xde, 0xea, 0xb7, 0xf4, 0x93, 0x56, 0x53, 0xf9, 0x48, - 0x5d, 0x80, 0x42, 0xab, 0xdb, 0xe4, 0x5a, 0x6a, 0x75, 0x9b, 0xc6, 0xcb, 0xf6, 0xe0, 0x1b, 0xa3, - 0xd7, 0xef, 0x29, 0xf9, 0x0c, 0xe6, 0xb8, 0xdf, 0x53, 0x0a, 0xea, 0x2a, 0x28, 0x69, 0x1a, 0x86, - 0x2d, 0xaa, 0x25, 0x28, 0xb6, 0xba, 0xcd, 0xef, 0x95, 0x39, 0x75, 0x19, 0xaa, 0xf4, 0x2b, 0x61, - 0x32, 0x9f, 0x45, 0x51, 0xfa, 0x05, 0xaa, 0xe6, 0x0c, 0x15, 0x43, 0x97, 0x04, 0x9b, 0x81, 0xb2, - 0x28, 0xe6, 0x0c, 0x12, 0x36, 0x90, 0x45, 0x51, 0xfa, 0xb2, 0x60, 0x33, 0xc8, 0xb2, 0xa9, 0x08, - 0x4a, 0xe3, 0x59, 0xdd, 0x68, 0x75, 0x0f, 0x1a, 0xbd, 0xbe, 0x52, 0x53, 0x01, 0xe6, 0x19, 0xea, - 0x50, 0x59, 0x52, 0xcb, 0xb0, 0x40, 0xbf, 0x9b, 0xdf, 0xd7, 0x15, 0x25, 0x01, 0xf6, 0x95, 0xe5, - 0x18, 0x18, 0xd4, 0x15, 0x35, 0x01, 0xf6, 0x95, 0x15, 0xaa, 0x31, 0x01, 0xd4, 0x95, 0xd5, 0x64, - 0xd2, 0x9e, 0xb2, 0x16, 0x0f, 0x7d, 0xbf, 0x77, 0xa2, 0xac, 0x27, 0x84, 0x7b, 0xc7, 0xca, 0xc7, - 0x29, 0xe8, 0x50, 0xd9, 0x10, 0xe2, 0x26, 0x72, 0x19, 0x3a, 0xb2, 0x95, 0x1b, 0x53, 0x4a, 0x6e, - 0x2a, 0x37, 0x67, 0x28, 0xb9, 0xa9, 0xdc, 0xca, 0x60, 0x8f, 0x05, 0xf6, 0xb6, 0xba, 0x01, 0xab, - 0xd3, 0x07, 0xc2, 0x46, 0xee, 0x4c, 0xeb, 0xbd, 0xa9, 0xdc, 0x9d, 0xa5, 0xf7, 0xa6, 0xf2, 0xb3, - 0x2c, 0x5a, 0x32, 0xd0, 0xd4, 0x4d, 0x58, 0xbb, 0x74, 0x4a, 0x6c, 0xe8, 0x93, 0xe9, 0xc3, 0x68, - 0x2a, 0x9f, 0xce, 0x3a, 0x8c, 0xa6, 0x72, 0x2f, 0x8b, 0x96, 0x0c, 0xee, 0x0b, 0xde, 0x83, 0xcb, - 0xbc, 0x1f, 0xec, 0x34, 0xa9, 0xd2, 0x78, 0x6f, 0x94, 0x59, 0xaa, 0x48, 0xa8, 0x94, 0x8f, 0xd4, - 0x45, 0x98, 0xa3, 0x58, 0x7a, 0x9d, 0xc4, 0x27, 0xbd, 0x40, 0xe2, 0xf3, 0x89, 0x52, 0x90, 0x9f, - 0xfb, 0x4a, 0x71, 0x38, 0xcf, 0x7c, 0xc7, 0x93, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xa5, 0xe0, - 0x03, 0xfe, 0x2b, 0x33, 0x00, 0x00, + 0xfd, 0xd6, 0x3e, 0x87, 0x2a, 0x6b, 0xdc, 0xc4, 0x64, 0x77, 0xa0, 0x1c, 0x8d, 0x3d, 0x0f, 0xb9, + 0x46, 0x2a, 0x19, 0x03, 0x8e, 0x62, 0x91, 0x65, 0x03, 0xd6, 0x9b, 0xe8, 0xd4, 0x1c, 0xbb, 0xd1, + 0x0b, 0x33, 0x42, 0xaf, 0xcc, 0x0b, 0x39, 0x55, 0xfb, 0x16, 0x6a, 0x3c, 0xa9, 0x79, 0x37, 0x0d, + 0xc5, 0xb9, 0x4e, 0x21, 0x9d, 0xeb, 0xe8, 0xa0, 0xb4, 0xfa, 0x6d, 0x96, 0xfd, 0xc7, 0xec, 0xb6, + 0x41, 0xc1, 0xc4, 0x20, 0xd8, 0x73, 0x5c, 0x64, 0x98, 0x56, 0x8a, 0x63, 0x0d, 0x93, 0x3e, 0x43, + 0x37, 0x2c, 0xc9, 0x93, 0x17, 0x54, 0xf9, 0x74, 0x41, 0xb5, 0x07, 0x2b, 0xad, 0x7e, 0x7b, 0x14, + 0xf8, 0x61, 0x94, 0x4a, 0xe2, 0xe9, 0x5d, 0x46, 0xc4, 0xc0, 0x0c, 0x2f, 0x1a, 0x44, 0x25, 0x44, + 0x38, 0x9d, 0x76, 0x0c, 0x2b, 0x87, 0xa6, 0x75, 0xe8, 0xf3, 0xf8, 0x1b, 0x8b, 0x42, 0x2b, 0x42, + 0x62, 0x90, 0x08, 0x5b, 0xe7, 0x17, 0x42, 0x86, 0x12, 0x26, 0x7d, 0x06, 0xd3, 0x02, 0x8c, 0xa0, + 0xdf, 0x8c, 0x91, 0x67, 0x21, 0xc3, 0x1b, 0x8f, 0x64, 0x01, 0x26, 0x71, 0xdd, 0xf1, 0x48, 0xbb, + 0x07, 0xcb, 0x3c, 0x5b, 0x3a, 0x34, 0x13, 0x83, 0x52, 0xa0, 0x30, 0x32, 0x2d, 0x21, 0x02, 0xfd, + 0xd4, 0x9e, 0xc2, 0xca, 0x20, 0x34, 0x4f, 0x4f, 0xb1, 0xa5, 0x9b, 0x51, 0xa2, 0xd7, 0xe9, 0x42, + 0x43, 0x85, 0x62, 0x48, 0x2d, 0x80, 0x2e, 0x94, 0xd7, 0xd9, 0xb7, 0xf6, 0x2d, 0xac, 0x89, 0xa9, + 0x54, 0x27, 0x29, 0x7b, 0xd9, 0x82, 0x52, 0x84, 0xc2, 0x11, 0xf6, 0x4c, 0x57, 0x4a, 0x2e, 0x61, + 0xea, 0x8a, 0x89, 0x39, 0x0a, 0x5c, 0xce, 0xaa, 0xa4, 0x0b, 0x48, 0x3b, 0x06, 0x4d, 0x47, 0x36, + 0x0e, 0x91, 0x15, 0x5d, 0xe3, 0x3c, 0xa6, 0xc5, 0x9a, 0x32, 0xe8, 0xfc, 0x25, 0x83, 0xfe, 0x6b, + 0xf8, 0x58, 0xb2, 0xbd, 0xce, 0x07, 0x5c, 0xd9, 0x48, 0x7c, 0xf3, 0x0a, 0x27, 0xc9, 0x0a, 0xd7, + 0x5d, 0xe5, 0x77, 0x96, 0xfc, 0x61, 0xac, 0x5d, 0x1d, 0x8d, 0xcc, 0xf0, 0x3c, 0xe6, 0xa4, 0x42, + 0xd1, 0x26, 0x96, 0x2c, 0x81, 0xd8, 0xb7, 0xf6, 0x35, 0x2c, 0x1d, 0x7b, 0xe7, 0x9e, 0xff, 0xca, + 0x4b, 0x93, 0xbd, 0x65, 0xbb, 0xef, 0x04, 0x6e, 0xca, 0x59, 0x33, 0x5b, 0xd4, 0xf5, 0xcb, 0x2d, + 0xea, 0xab, 0x42, 0x40, 0xa6, 0x71, 0x7d, 0x00, 0x4a, 0x83, 0xec, 0xbf, 0xe7, 0x23, 0xc1, 0x33, + 0x58, 0x6f, 0x90, 0xfd, 0xf7, 0xeb, 0xbd, 0x23, 0x58, 0xe9, 0x8d, 0x08, 0x1e, 0x30, 0x17, 0x93, + 0x30, 0x58, 0x85, 0xb9, 0x53, 0xd7, 0x74, 0xe4, 0xa9, 0x70, 0x20, 0xd6, 0x5b, 0x3e, 0xab, 0x37, + 0x7e, 0xd9, 0x0b, 0xa9, 0xcb, 0x2e, 0xfa, 0xef, 0xbc, 0xa5, 0x90, 0xc7, 0xb6, 0xf6, 0x97, 0x70, + 0x9b, 0x2f, 0xc1, 0xfc, 0x5d, 0x7f, 0x3c, 0x1c, 0x74, 0x4e, 0x32, 0x3d, 0xeb, 0x74, 0x19, 0x56, + 0xe5, 0x65, 0xd8, 0x3a, 0xcc, 0x5b, 0xbe, 0x7f, 0x8e, 0xe5, 0x91, 0x08, 0x48, 0xfb, 0x1c, 0xb6, + 0x2e, 0xf1, 0x7a, 0x89, 0x43, 0xe4, 0x8c, 0xcd, 0x90, 0x9d, 0x6d, 0x80, 0x50, 0x28, 0xea, 0x39, + 0xf6, 0xad, 0xfd, 0x02, 0x36, 0x2f, 0xcd, 0x90, 0xd9, 0x0b, 0xbd, 0x91, 0x32, 0x7b, 0x11, 0xab, + 0xc7, 0xb0, 0xb6, 0x0b, 0xeb, 0x97, 0x26, 0x32, 0xc7, 0x7e, 0x85, 0x43, 0x3f, 0x86, 0x5b, 0x97, + 0xe8, 0xfb, 0x3a, 0xcd, 0xde, 0x50, 0x48, 0x9d, 0xcf, 0x15, 0x7a, 0xbd, 0xcd, 0x9b, 0x0b, 0x9c, + 0x46, 0xda, 0x7b, 0x82, 0xd1, 0x4e, 0xe0, 0x93, 0x19, 0x6c, 0x0f, 0x4c, 0xcf, 0xa6, 0xe1, 0x08, + 0x51, 0x33, 0xea, 0x9a, 0x23, 0x44, 0x8b, 0x27, 0x4b, 0x22, 0x8d, 0xc0, 0x8c, 0xce, 0x0c, 0xcf, + 0x1c, 0x21, 0x71, 0x6d, 0x97, 0xad, 0x69, 0x7a, 0xed, 0x29, 0xdc, 0x98, 0x29, 0x2e, 0xf6, 0x43, + 0x5a, 0xee, 0x30, 0xcd, 0xf0, 0xef, 0x44, 0x33, 0x1c, 0xd6, 0xda, 0x33, 0x77, 0xfa, 0x0c, 0x7b, + 0x36, 0xf6, 0x9c, 0x7e, 0xbb, 0x49, 0x33, 0xd0, 0x21, 0xc1, 0xd7, 0x17, 0xee, 0x8c, 0x42, 0xeb, + 0x42, 0x25, 0x33, 0x73, 0x0d, 0xe6, 0x89, 0x41, 0x15, 0x23, 0x1c, 0xe4, 0x1c, 0x79, 0xee, 0x9a, + 0x0e, 0x45, 0x63, 0x8e, 0xe6, 0xde, 0x71, 0x0e, 0x33, 0xb4, 0x02, 0x05, 0x22, 0x4a, 0xe9, 0x8a, + 0x4e, 0x3f, 0xb5, 0x3f, 0xe5, 0x60, 0xb5, 0xaf, 0x4f, 0xea, 0x2d, 0xcf, 0xee, 0xf9, 0xd8, 0x8b, + 0x9e, 0xa1, 0x33, 0x73, 0x82, 0xfd, 0x50, 0xdd, 0x83, 0xd2, 0x50, 0x7c, 0x8b, 0x14, 0x3a, 0x95, + 0xcf, 0xd2, 0x19, 0x92, 0x52, 0x8f, 0xe9, 0x68, 0xa8, 0x19, 0xba, 0xbe, 0x75, 0x9e, 0x6a, 0xfb, + 0x94, 0x18, 0xa2, 0x83, 0x3c, 0xf6, 0x22, 0xe7, 0xdb, 0x28, 0xd5, 0xc4, 0x5a, 0xa0, 0xb0, 0x18, + 0x3a, 0x1d, 0x7b, 0x16, 0x1b, 0xe2, 0xb9, 0xc4, 0x02, 0x85, 0xe9, 0xd0, 0x47, 0xb0, 0x60, 0x86, + 0x4e, 0xaa, 0x59, 0x39, 0x6f, 0x86, 0x4e, 0x07, 0x79, 0xda, 0x7f, 0xe7, 0xa0, 0xc6, 0xc4, 0xf8, + 0xa1, 0xba, 0x58, 0x83, 0xf9, 0x21, 0x47, 0x17, 0x38, 0x7a, 0x98, 0x56, 0x51, 0x31, 0x56, 0x91, + 0xfa, 0x2b, 0xb8, 0x21, 0xfb, 0x7c, 0x86, 0xdc, 0xaa, 0x41, 0xa2, 0x70, 0x6c, 0x45, 0xe3, 0x10, + 0x31, 0xb1, 0xca, 0x7b, 0xb7, 0xb3, 0xca, 0x99, 0x56, 0xa7, 0xbe, 0x29, 0x59, 0x48, 0x4c, 0x5f, + 0x32, 0xd0, 0x5e, 0xc2, 0x47, 0x33, 0xac, 0xa3, 0xd5, 0xed, 0xf4, 0xae, 0xb8, 0x01, 0xf7, 0xa1, + 0x88, 0x3c, 0x37, 0x60, 0xdb, 0xa9, 0xed, 0xa9, 0xa9, 0xf6, 0x71, 0xb7, 0xd3, 0xe3, 0x75, 0x0d, + 0x1d, 0xd7, 0xbe, 0x84, 0x52, 0x5f, 0x7f, 0x49, 0xcb, 0xfa, 0xe8, 0x0a, 0x4e, 0xeb, 0x30, 0xff, + 0x8a, 0x8d, 0x8b, 0xd3, 0x12, 0x90, 0xf6, 0x6b, 0xa8, 0x08, 0x0f, 0xfa, 0x9c, 0xd1, 0xad, 0xc1, + 0xfc, 0x24, 0xa3, 0xd9, 0x89, 0x54, 0xa1, 0x99, 0xd1, 0xac, 0x29, 0xd1, 0x24, 0xa3, 0x59, 0x32, + 0xa5, 0xf0, 0x62, 0x4a, 0xe1, 0x9a, 0x1e, 0xaf, 0x45, 0x45, 0x6f, 0xa8, 0x8f, 0xd2, 0x92, 0x96, + 0x33, 0x56, 0x97, 0x12, 0x49, 0xee, 0x60, 0x76, 0xfa, 0xf4, 0x9f, 0xb9, 0x0c, 0xd3, 0x67, 0xef, + 0xc8, 0x54, 0xd8, 0x40, 0xfe, 0xad, 0x6d, 0xa0, 0xf0, 0xbe, 0x36, 0xf0, 0xdb, 0x19, 0x2e, 0xbf, + 0xaf, 0x0b, 0xd9, 0x3a, 0x98, 0x44, 0xea, 0x4e, 0x7c, 0x54, 0x7c, 0x0b, 0x6a, 0x7a, 0x31, 0x7e, + 0xc8, 0xf2, 0xf8, 0xd4, 0xcf, 0x53, 0xc1, 0xf1, 0xba, 0x16, 0x5f, 0x12, 0x1d, 0xbf, 0x86, 0x3b, + 0x97, 0x43, 0x8e, 0x43, 0x83, 0x5e, 0x4b, 0xc8, 0x7c, 0xcd, 0x1b, 0xe9, 0x1e, 0xdc, 0xbc, 0x34, + 0xf9, 0xb8, 0xd9, 0x6b, 0x22, 0x12, 0xf5, 0xfc, 0x90, 0xb5, 0x4b, 0xe3, 0x84, 0xb5, 0xaa, 0xb3, + 0x6f, 0xad, 0x09, 0x1b, 0x97, 0xe7, 0xf0, 0xcc, 0xe3, 0x1d, 0x32, 0x8e, 0x2e, 0xd4, 0x52, 0x5c, + 0x06, 0x9d, 0x93, 0x99, 0x73, 0xb7, 0xa1, 0x18, 0xb9, 0x93, 0xeb, 0x55, 0xc1, 0x28, 0xb4, 0x26, + 0xac, 0xa6, 0xf8, 0x25, 0x11, 0xfe, 0x91, 0xe0, 0xc0, 0x33, 0x8d, 0x8d, 0x44, 0xf5, 0xd9, 0xd5, + 0x05, 0x17, 0x51, 0x28, 0xd6, 0x3f, 0xc0, 0x42, 0x31, 0x9b, 0xc6, 0xd6, 0x7f, 0x82, 0x34, 0xf6, + 0xaf, 0xe0, 0x4e, 0xbb, 0x57, 0xff, 0x49, 0xf2, 0xc0, 0x1d, 0x50, 0x1a, 0xd8, 0xa1, 0x8a, 0x6e, + 0xbf, 0xe8, 0x1d, 0xa2, 0x28, 0xc4, 0x16, 0xf5, 0x60, 0x23, 0xf6, 0xc5, 0x04, 0x2d, 0xea, 0x02, + 0xd2, 0xbe, 0x82, 0x9a, 0xa0, 0x7d, 0x77, 0xab, 0x7a, 0x0a, 0x55, 0x3a, 0x37, 0xdd, 0xdf, 0x48, + 0x1f, 0xff, 0x75, 0x06, 0x34, 0x86, 0x5a, 0x87, 0x96, 0x6a, 0x72, 0xdf, 0xac, 0xc2, 0x72, 0x5c, + 0x7f, 0x18, 0x6b, 0x4c, 0xb4, 0x92, 0x39, 0x8e, 0xa9, 0x2c, 0xd1, 0xa9, 0x6d, 0x46, 0xe6, 0xe3, + 0x8c, 0x4e, 0x9b, 0x14, 0x93, 0x25, 0xd8, 0x93, 0x9d, 0xf0, 0x98, 0x60, 0x4f, 0x7b, 0x09, 0x9b, + 0x99, 0x65, 0x33, 0xea, 0xfe, 0x6a, 0x96, 0xba, 0x53, 0x36, 0x9c, 0x15, 0x38, 0xab, 0xf2, 0x3f, + 0xe6, 0xa0, 0xcc, 0x1b, 0x78, 0x3c, 0x10, 0x6c, 0x41, 0xc9, 0x9f, 0xa0, 0xd0, 0xf5, 0x4d, 0x5b, + 0x56, 0x64, 0x12, 0x66, 0x3f, 0x14, 0x44, 0x91, 0x69, 0x9d, 0x89, 0x1f, 0x0a, 0x4a, 0x7a, 0x0c, + 0xb3, 0xb7, 0xb3, 0xd7, 0x11, 0x0a, 0x69, 0x25, 0xc7, 0x83, 0x42, 0x0c, 0xb3, 0x67, 0x81, 0x61, + 0x28, 0x82, 0x02, 0xfd, 0xa4, 0x87, 0xca, 0x9b, 0xf6, 0x2c, 0xb8, 0x96, 0x74, 0x01, 0xd1, 0x44, + 0x59, 0xf4, 0xab, 0x4b, 0x7a, 0x7e, 0x52, 0xd7, 0xfe, 0x9e, 0x75, 0x7c, 0xdb, 0x2f, 0x7a, 0xcf, + 0x65, 0xc6, 0x6d, 0xfb, 0xaf, 0x3c, 0x21, 0x18, 0xfb, 0x56, 0x6f, 0x01, 0x78, 0xbe, 0x31, 0xf6, + 0xd8, 0x23, 0xb6, 0x10, 0x6b, 0xd1, 0xf3, 0x8f, 0x39, 0x82, 0x5e, 0x45, 0x69, 0xce, 0xc9, 0x85, + 0x2a, 0xe9, 0x15, 0x61, 0xd0, 0xdc, 0xe6, 0xef, 0x41, 0x2d, 0x08, 0xfd, 0xc0, 0x74, 0x68, 0xa6, + 0xe8, 0x11, 0x62, 0x0a, 0x59, 0xab, 0x31, 0xb6, 0x4b, 0x88, 0xa9, 0x3d, 0x81, 0xc5, 0x0e, 0xe9, + 0x87, 0xba, 0xe9, 0x39, 0xcc, 0xb2, 0x86, 0x28, 0xf9, 0x53, 0x8a, 0x03, 0x74, 0xab, 0xc8, 0x93, + 0x2f, 0x05, 0xf4, 0x53, 0xfb, 0x3d, 0x7b, 0x28, 0xe9, 0x87, 0x07, 0x66, 0xc0, 0x1b, 0xe7, 0x18, + 0xb1, 0x05, 0x71, 0x30, 0xd9, 0x37, 0xc8, 0x38, 0xa0, 0xce, 0x12, 0x49, 0x5d, 0x57, 0x29, 0xb6, + 0x2f, 0x91, 0x82, 0xac, 0x9e, 0x22, 0xcb, 0xc7, 0x64, 0xf5, 0x84, 0xec, 0x21, 0xcc, 0x87, 0x54, + 0x26, 0xd9, 0x74, 0x5b, 0x49, 0xf7, 0x25, 0x85, 0xbc, 0xba, 0x20, 0xd1, 0x7e, 0x09, 0x35, 0x8a, + 0x64, 0xaf, 0x1c, 0xcf, 0x68, 0xea, 0x96, 0x9a, 0x9e, 0x7b, 0xf3, 0xf4, 0xbf, 0x2b, 0xc0, 0x52, + 0x27, 0xb1, 0x3d, 0xd6, 0xe4, 0x55, 0xa1, 0x98, 0xca, 0xac, 0xd9, 0xb7, 0xfa, 0x50, 0xc6, 0x63, + 0xde, 0x73, 0x5d, 0x9b, 0x6e, 0x17, 0x67, 0xc2, 0xf1, 0x7d, 0x58, 0xe2, 0x87, 0x94, 0xbc, 0xe4, + 0x70, 0xbf, 0xc7, 0xcf, 0x4e, 0xbe, 0xe5, 0xa8, 0x0f, 0x41, 0x9d, 0xa2, 0x33, 0x26, 0x75, 0xf1, + 0x78, 0xb2, 0x94, 0x21, 0x3d, 0xa9, 0xf3, 0xb6, 0x08, 0x26, 0xec, 0x79, 0x89, 0x99, 0x59, 0x45, + 0x2f, 0x51, 0x44, 0x23, 0x44, 0x26, 0x7b, 0x89, 0x64, 0xfd, 0x21, 0x66, 0x6c, 0x15, 0x5d, 0x40, + 0xea, 0x01, 0x2c, 0x91, 0xd0, 0xb0, 0x52, 0x67, 0xc5, 0xde, 0xc1, 0xa7, 0xfa, 0xdd, 0xd9, 0xd3, + 0xd4, 0x6b, 0x24, 0x7b, 0xba, 0x1f, 0x43, 0x95, 0x84, 0x86, 0xe9, 0x3a, 0xb4, 0x38, 0x38, 0x1b, + 0x91, 0x8d, 0x12, 0x5b, 0xa3, 0x42, 0xc2, 0x46, 0x8c, 0x53, 0xff, 0x1c, 0x6a, 0x24, 0x14, 0x0f, + 0x50, 0x2c, 0x85, 0xde, 0x58, 0x64, 0x0b, 0x6d, 0x64, 0x17, 0x4a, 0xce, 0x89, 0xce, 0x4f, 0x20, + 0xed, 0x8f, 0xc5, 0xcc, 0x41, 0x74, 0xb0, 0x77, 0x3e, 0xf3, 0x20, 0x66, 0xe8, 0x36, 0xff, 0xf6, + 0xba, 0x2d, 0xcc, 0xd6, 0xed, 0x36, 0x28, 0xe2, 0xfd, 0x24, 0xe1, 0xca, 0x8f, 0xa1, 0xc6, 0xf1, + 0x31, 0xdb, 0x4f, 0x61, 0x65, 0x9a, 0xd2, 0x88, 0x5f, 0xb0, 0x94, 0x2c, 0xf1, 0x49, 0x9d, 0x3a, + 0x42, 0xe6, 0x45, 0x0d, 0x27, 0xf4, 0xc7, 0x01, 0x3b, 0x9c, 0xaa, 0x0e, 0x0c, 0xf5, 0x82, 0x62, + 0xd4, 0x1d, 0x58, 0xb6, 0x79, 0xcb, 0xcf, 0x88, 0x90, 0x21, 0x22, 0x03, 0xff, 0x55, 0x61, 0x49, + 0x0c, 0x0c, 0x90, 0x08, 0x1d, 0xb7, 0x00, 0xb0, 0x13, 0x48, 0xa2, 0x12, 0x7f, 0xa5, 0xc6, 0x4e, + 0x90, 0x44, 0x16, 0x61, 0x03, 0x8b, 0x19, 0x1b, 0xb8, 0x09, 0x8b, 0x43, 0xd3, 0xb3, 0x5f, 0x61, + 0x3b, 0x3a, 0xdb, 0x00, 0xd6, 0xc6, 0x4a, 0x10, 0xea, 0x63, 0x58, 0x0d, 0x11, 0x41, 0xe1, 0xc4, + 0x1c, 0xba, 0xc8, 0x48, 0x08, 0xcb, 0x8c, 0x70, 0x25, 0x19, 0x7b, 0x96, 0x9e, 0x32, 0xf6, 0xf8, + 0x00, 0xb2, 0x53, 0x53, 0x2a, 0x77, 0x0b, 0x74, 0x4a, 0x32, 0x96, 0x4c, 0xd9, 0x06, 0x85, 0x9a, + 0x90, 0xfd, 0x6b, 0xd3, 0x42, 0x9e, 0x75, 0x61, 0xd0, 0x6c, 0xb5, 0xca, 0x36, 0x50, 0x23, 0x61, + 0x43, 0xa2, 0xfb, 0x98, 0xb7, 0x5c, 0x43, 0xd7, 0x21, 0x1b, 0x35, 0xf6, 0xe7, 0x01, 0x07, 0xb4, + 0xbf, 0xcd, 0xc1, 0x72, 0xca, 0x3a, 0xc4, 0x8b, 0xc9, 0x63, 0xa0, 0xdb, 0x37, 0xd2, 0x89, 0x72, + 0xe6, 0xd9, 0x44, 0x3a, 0x5a, 0xbd, 0x84, 0x9d, 0xe0, 0xb9, 0x2c, 0x20, 0x84, 0x92, 0xf2, 0x19, + 0x25, 0x69, 0xcc, 0xc6, 0xc5, 0xdb, 0x0e, 0x89, 0x5f, 0x6f, 0xcb, 0x44, 0xbc, 0xce, 0xf4, 0xb1, + 0xad, 0xfd, 0x33, 0x8b, 0x2d, 0x49, 0x9c, 0xfa, 0x14, 0x8a, 0xa9, 0x17, 0xa4, 0xcd, 0xf4, 0xca, + 0x19, 0x87, 0xa2, 0x33, 0x32, 0x4a, 0xee, 0x62, 0xef, 0x5c, 0x78, 0x90, 0xd9, 0xe4, 0xd4, 0xec, + 0x75, 0x46, 0xa6, 0x3e, 0xc9, 0xfc, 0x74, 0x50, 0xde, 0xbb, 0x31, 0x73, 0x82, 0xf8, 0x95, 0x47, + 0xfe, 0x43, 0xa1, 0x83, 0x22, 0xd2, 0x87, 0x1f, 0xd8, 0xed, 0x99, 0xd1, 0x2e, 0xfe, 0xf7, 0x3c, + 0xac, 0xd3, 0xf2, 0x20, 0x4e, 0xfe, 0xfb, 0xe3, 0x21, 0xcf, 0x7f, 0xd5, 0x47, 0xf2, 0x92, 0xc5, + 0x55, 0x74, 0xf2, 0x07, 0x8b, 0xe2, 0xc6, 0x97, 0xbb, 0xc3, 0x1f, 0x9d, 0x76, 0x60, 0x39, 0x79, + 0x77, 0x93, 0xc4, 0x7c, 0xfd, 0xa5, 0xf8, 0x89, 0x4d, 0xd0, 0x3e, 0x80, 0x25, 0x5a, 0x51, 0x47, + 0xd8, 0xf7, 0x8c, 0xcc, 0x0b, 0x56, 0x4d, 0xa2, 0x13, 0x42, 0x33, 0x74, 0xc6, 0xb4, 0x2a, 0x90, + 0x84, 0x3c, 0x8b, 0xac, 0x49, 0xb4, 0x20, 0x7c, 0x0c, 0xab, 0x2c, 0x83, 0x0d, 0x7c, 0x9a, 0xb0, + 0x26, 0x6c, 0x79, 0x95, 0xbe, 0x92, 0x19, 0xbb, 0x6a, 0x8a, 0xf8, 0xdb, 0x63, 0x7e, 0xc6, 0x94, + 0x23, 0xfe, 0xeb, 0xc7, 0x3d, 0xa8, 0x30, 0x5d, 0xb5, 0x9b, 0x71, 0x21, 0x4a, 0xf5, 0x6d, 0x3c, + 0x96, 0x85, 0x28, 0x85, 0x1e, 0x6b, 0x8f, 0x61, 0x81, 0x92, 0x51, 0x1d, 0xde, 0x87, 0x42, 0xe4, + 0x4e, 0xae, 0x4d, 0xd5, 0x28, 0x81, 0xf6, 0x6f, 0x79, 0x58, 0xa3, 0x73, 0xda, 0xde, 0xa9, 0x1f, + 0x8e, 0x58, 0x5b, 0x4d, 0x9c, 0x82, 0xa8, 0xfe, 0x72, 0x49, 0xf5, 0xf7, 0x28, 0x1b, 0xad, 0xa6, + 0x1a, 0x21, 0x52, 0x38, 0x69, 0x0a, 0x0f, 0x61, 0xf9, 0x52, 0xad, 0x28, 0xb4, 0xad, 0x4c, 0x57, + 0x80, 0xea, 0x77, 0x50, 0xa1, 0x69, 0x3e, 0x4b, 0xf5, 0x69, 0x8a, 0x59, 0x64, 0x72, 0x7f, 0x96, + 0x5d, 0xe1, 0x92, 0x8c, 0xbb, 0xc2, 0x66, 0xdc, 0x09, 0x69, 0x79, 0x51, 0x78, 0xa1, 0x03, 0x89, + 0x11, 0x5b, 0x3d, 0x58, 0x9a, 0x1a, 0x9e, 0xd1, 0x2f, 0x7c, 0x90, 0xce, 0x7c, 0xcb, 0x7b, 0xcb, + 0xd9, 0x05, 0x69, 0x2d, 0xc3, 0xc7, 0xbf, 0xca, 0x7f, 0x99, 0xd3, 0xfe, 0x25, 0x07, 0x0a, 0x45, + 0x77, 0x9e, 0xf4, 0x51, 0x38, 0xc1, 0x16, 0xa2, 0x6a, 0x7a, 0x26, 0x0a, 0x94, 0x24, 0x31, 0x7e, + 0x90, 0x65, 0x92, 0xa6, 0xde, 0xcd, 0x48, 0xcb, 0x2a, 0x19, 0x2a, 0xea, 0x21, 0x54, 0x7e, 0x4c, + 0x39, 0xbf, 0x80, 0x45, 0xe1, 0x5e, 0x78, 0x4f, 0xed, 0xed, 0x92, 0xf6, 0x1d, 0xc2, 0xfe, 0x40, + 0x10, 0x6f, 0xc2, 0xea, 0x0a, 0x2c, 0x75, 0xfa, 0x06, 0x05, 0x8d, 0xe3, 0xee, 0xb7, 0xdd, 0xa3, + 0x97, 0x5d, 0xe5, 0x67, 0xaa, 0x02, 0x15, 0x89, 0xec, 0x1e, 0x35, 0x5b, 0x4a, 0x2e, 0x8d, 0xe9, + 0xb4, 0xbb, 0xdf, 0x2a, 0x79, 0x75, 0x0d, 0x96, 0x25, 0xa6, 0xa7, 0xb7, 0x9e, 0xb7, 0xbf, 0x37, + 0x4e, 0xf6, 0x95, 0xc2, 0x2c, 0x74, 0x5d, 0x29, 0xee, 0xfc, 0x17, 0x7b, 0xaf, 0x4e, 0x9e, 0x85, + 0xd5, 0x8f, 0x60, 0xa5, 0xd3, 0x37, 0x7a, 0xfa, 0xd1, 0xe0, 0xe8, 0xe0, 0xa8, 0x93, 0x5a, 0x7b, + 0x6a, 0xa0, 0xdd, 0x6f, 0xf7, 0x8d, 0xce, 0x63, 0x25, 0x37, 0x7b, 0x60, 0x4f, 0xc9, 0x4f, 0x0f, + 0x1c, 0xf5, 0x7b, 0xcf, 0x8d, 0x93, 0x3d, 0xa5, 0xa0, 0xae, 0x83, 0x9a, 0x1e, 0x68, 0xb6, 0xf5, + 0xd6, 0xc1, 0x40, 0x29, 0x4e, 0xe3, 0xfb, 0x83, 0xc6, 0xa0, 0x7d, 0xa0, 0xcc, 0xcd, 0x66, 0xf4, + 0x44, 0x99, 0xdf, 0xf9, 0x8f, 0x39, 0x7e, 0x31, 0x63, 0x3b, 0xae, 0x40, 0x49, 0x6f, 0xf5, 0x5b, + 0xfa, 0x49, 0xab, 0xa9, 0xfc, 0x4c, 0x5d, 0x80, 0x42, 0xab, 0xdb, 0xe4, 0x5a, 0x6a, 0x75, 0x9b, + 0xc6, 0xcb, 0xf6, 0xe0, 0x1b, 0xa3, 0xd7, 0xef, 0x29, 0xf9, 0x0c, 0xe6, 0xb8, 0xdf, 0x53, 0x0a, + 0xea, 0x2a, 0x28, 0x69, 0x1a, 0x86, 0x2d, 0xaa, 0x25, 0x28, 0xb6, 0xba, 0xcd, 0xef, 0x95, 0x39, + 0x75, 0x19, 0xaa, 0xf4, 0x2b, 0x61, 0x32, 0x9f, 0x45, 0x51, 0xfa, 0x05, 0xaa, 0xe6, 0x0c, 0x15, + 0x43, 0x97, 0x04, 0x9b, 0x81, 0xb2, 0x28, 0xe6, 0x0c, 0x12, 0x36, 0x90, 0x45, 0x51, 0xfa, 0xb2, + 0x60, 0x33, 0xc8, 0xb2, 0xa9, 0x08, 0x4a, 0xe3, 0x59, 0xdd, 0x68, 0x75, 0x0f, 0x1a, 0xbd, 0xbe, + 0x52, 0x53, 0x01, 0xe6, 0x19, 0xea, 0x50, 0x59, 0x52, 0xcb, 0xb0, 0x40, 0xbf, 0x9b, 0xdf, 0xd7, + 0x15, 0x25, 0x01, 0xf6, 0x95, 0xe5, 0x18, 0x18, 0xd4, 0x15, 0x35, 0x01, 0xf6, 0x95, 0x15, 0xaa, + 0x31, 0x01, 0xd4, 0x95, 0xd5, 0x64, 0xd2, 0x9e, 0xb2, 0x16, 0x0f, 0x7d, 0xbf, 0x77, 0xa2, 0xac, + 0x27, 0x84, 0x7b, 0xc7, 0xca, 0x47, 0x29, 0xe8, 0x50, 0xd9, 0x10, 0xe2, 0x26, 0x72, 0x19, 0x3a, + 0xb2, 0x95, 0x1b, 0x53, 0x4a, 0x6e, 0x2a, 0x37, 0x67, 0x28, 0xb9, 0xa9, 0xdc, 0xca, 0x60, 0x8f, + 0x05, 0xf6, 0xb6, 0xba, 0x01, 0xab, 0xd3, 0x07, 0xc2, 0x46, 0xee, 0x4c, 0xeb, 0xbd, 0xa9, 0xdc, + 0x9d, 0xa5, 0xf7, 0xa6, 0xf2, 0xf3, 0x2c, 0x5a, 0x32, 0xd0, 0xd4, 0x4d, 0x58, 0xbb, 0x74, 0x4a, + 0x6c, 0xe8, 0xe3, 0xe9, 0xc3, 0x68, 0x2a, 0x9f, 0xcc, 0x3a, 0x8c, 0xa6, 0x72, 0x2f, 0x8b, 0x96, + 0x0c, 0xee, 0x0b, 0xde, 0x83, 0xcb, 0xbc, 0x1f, 0xec, 0x34, 0xa9, 0xd2, 0x78, 0x6f, 0x94, 0x59, + 0xaa, 0x48, 0xa8, 0x94, 0x9f, 0xa9, 0x8b, 0x30, 0x47, 0xb1, 0xf4, 0x3a, 0x89, 0x4f, 0x7a, 0x81, + 0xc4, 0xe7, 0x13, 0xa5, 0x20, 0x3f, 0xf7, 0x95, 0xe2, 0x70, 0x9e, 0xf9, 0x8e, 0x27, 0xff, 0x1f, + 0x00, 0x00, 0xff, 0xff, 0x11, 0x40, 0xa1, 0x1d, 0x5d, 0x33, 0x00, 0x00, } diff --git a/api/attribute.proto b/api/attribute.proto index 24b63248..2ba903bc 100644 --- a/api/attribute.proto +++ b/api/attribute.proto @@ -501,6 +501,10 @@ message TunnelEncapSubTLVEncapsulation { bytes cookie = 2; } +message TunnelEncapSubTLVWireguard { + bytes peer = 1; +} + message TunnelEncapSubTLVProtocol { uint32 protocol = 1; } message TunnelEncapSubTLVColor { uint32 color = 1; } diff --git a/cmd/gobgp/global.go b/cmd/gobgp/global.go index 6bc58d0c..bcd4acdd 100644 --- a/cmd/gobgp/global.go +++ b/cmd/gobgp/global.go @@ -16,6 +16,8 @@ package main import ( + "encoding/base64" + // "encoding/binary" "encoding/json" "fmt" "net" @@ -1103,6 +1105,92 @@ func extractPmsiTunnel(args []string) ([]string, bgp.PathAttributeInterface, err return args, nil, nil } +func extractTunnelEncap(args []string) ([]string, bgp.PathAttributeInterface, error) { + for idx, arg := range args { + if arg == "tunnel-encap" { + var subencap bgp.TunnelEncapSubTLVInterface + var egress bgp.TunnelEncapSubTLVInterface + var udp_port bgp.TunnelEncapSubTLVInterface + var color bgp.TunnelEncapSubTLVInterface + subTlvsLen := 1 + subidx := idx + 1 + for subidx < len(args) { + arg = args[subidx] + if arg == "wireguard" { + if len(args) < (subidx + 1) { + return nil, nil, fmt.Errorf("invalid wireguard format") + } + peer, err := base64.StdEncoding.DecodeString(args[subidx+1]) + if err != nil { + return nil, nil, err + } + subencap = bgp.NewTunnelEncapSubTLVWireguard(peer) + subTlvsLen++ + subidx += 2 + } else if arg == "egress" { + if len(args) < (subidx + 2) { + return nil, nil, fmt.Errorf("invalid egress endpoint format") + } + egress = bgp.NewTunnelEncapSubTLVEgressEndpoint(args[subidx+1]) + subTlvsLen++ + subidx += 2 + } else if arg == "udp" { + if len(args) < (subidx + 2) { + return nil, nil, fmt.Errorf("invalid udp format") + } + port, err := strconv.ParseUint(args[subidx+1], 10, 16) + if err != nil { + return nil, nil, fmt.Errorf("invalid udp format") + } + udp_port = bgp.NewTunnelEncapSubTLVUDPDestPort(uint16(port)) + subTlvsLen++ + subidx += 2 + } else if arg == "color" { + if len(args) < (subidx + 2) { + return nil, nil, fmt.Errorf("invalid color extended community format") + } + value, err := strconv.ParseUint(args[subidx+1], 10, 32) + if err != nil { + return nil, nil, fmt.Errorf("invalid color extended community format") + } + color = bgp.NewTunnelEncapSubTLVColor(uint32(value)) + subTlvsLen++ + subidx += 2 + } else { + print("FOO:" + args[subidx+1]) + break + } + } + + tlvsLen := 1 + tlvs := make([]*bgp.TunnelEncapTLV, 0, tlvsLen) + subTlvs := make([]bgp.TunnelEncapSubTLVInterface, 0, subTlvsLen) + + if subencap != nil { + subTlvs = append(subTlvs, subencap) + } + if egress != nil { + subTlvs = append(subTlvs, egress) + } + if udp_port != nil { + subTlvs = append(subTlvs, udp_port) + } + if color != nil { + subTlvs = append(subTlvs, color) + } + + tlvType := bgp.TUNNEL_TYPE_WIREGUARD // Experimental Wireguard + tlvs = append(tlvs, bgp.NewTunnelEncapTLV(bgp.TunnelType(tlvType), subTlvs)) + + //subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16()) + encap := bgp.NewPathAttributeTunnelEncap(tlvs) + + return append(args[:idx], args[subidx:]...), encap, nil + } + } + return args, nil, nil +} + func extractAigp(args []string) ([]string, bgp.PathAttributeInterface, error) { for idx, arg := range args { if arg == "aigp" { @@ -1161,6 +1249,7 @@ func parsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) { extractAggregator, // 7 AGGREGATOR extractCommunity, // 8 COMMUNITY extractPmsiTunnel, // 22 PMSI_TUNNEL + extractTunnelEncap, // 23 Tunnel Encapsulation Attribute extractAigp, // 26 AIGP extractLargeCommunity, // 32 LARGE_COMMUNITY } diff --git a/internal/pkg/apiutil/attribute.go b/internal/pkg/apiutil/attribute.go index 19060932..0262c59d 100644 --- a/internal/pkg/apiutil/attribute.go +++ b/internal/pkg/apiutil/attribute.go @@ -1168,6 +1168,10 @@ func NewTunnelEncapAttributeFromNative(a *bgp.PathAttributeTunnelEncap) *api.Tun Key: sv.Key, Cookie: sv.Cookie, } + case *bgp.TunnelEncapSubTLVWireguard: + subTlv = &api.TunnelEncapSubTLVWireguard{ + Peer: sv.Peer, + } case *bgp.TunnelEncapSubTLVProtocol: subTlv = &api.TunnelEncapSubTLVProtocol{ Protocol: uint32(sv.Protocol), @@ -1662,6 +1666,8 @@ func unmarshalAttribute(an *any.Any) (bgp.PathAttributeInterface, error) { switch sv := subValue.Message.(type) { case *api.TunnelEncapSubTLVEncapsulation: subTlv = bgp.NewTunnelEncapSubTLVEncapsulation(sv.Key, sv.Cookie) + case *api.TunnelEncapSubTLVWireguard: + subTlv = bgp.NewTunnelEncapSubTLVWireguard(sv.Peer) case *api.TunnelEncapSubTLVProtocol: subTlv = bgp.NewTunnelEncapSubTLVProtocol(uint16(sv.Protocol)) case *api.TunnelEncapSubTLVColor: diff --git a/pkg/packet/bgp/bgp.go b/pkg/packet/bgp/bgp.go index c46bc878..6a13896f 100644 --- a/pkg/packet/bgp/bgp.go +++ b/pkg/packet/bgp/bgp.go @@ -17,6 +17,7 @@ package bgp import ( "bytes" + "encoding/base64" "encoding/binary" "encoding/json" "errors" @@ -188,6 +189,7 @@ const ( TUNNEL_TYPE_MPLS_IN_UDP TunnelType = 13 TUNNEL_TYPE_SR_POLICY TunnelType = 15 TUNNEL_TYPE_GENEVE TunnelType = 19 + TUNNEL_TYPE_WIREGUARD TunnelType = 51820 ) func (p TunnelType) String() string { @@ -214,6 +216,8 @@ func (p TunnelType) String() string { return "sr-policy" case TUNNEL_TYPE_GENEVE: return "geneve" + case TUNNEL_TYPE_WIREGUARD: + return "wireguard" default: return fmt.Sprintf("TunnelType(%d)", uint8(p)) } @@ -11691,6 +11695,50 @@ func NewTunnelEncapSubTLVEncapsulation(key uint32, cookie []byte) *TunnelEncapSu } } +type TunnelEncapSubTLVWireguard struct { + TunnelEncapSubTLV + Peer []byte +} + +func (t *TunnelEncapSubTLVWireguard) DecodeFromBytes(data []byte) error { + value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) + if err != nil { + return err + } + if t.Length < 32 { // FIXME + return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLVWireguard bytes available") + } + t.Peer = value + return nil +} + +func (t *TunnelEncapSubTLVWireguard) Serialize() ([]byte, error) { + return t.TunnelEncapSubTLV.Serialize(t.Peer) +} + +func (t *TunnelEncapSubTLVWireguard) String() string { + return fmt.Sprintf("{Peer: %s}", base64.StdEncoding.EncodeToString(t.Peer)) +} + +func (t *TunnelEncapSubTLVWireguard) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type EncapSubTLVType `json:"type"` + Peer []byte `json:"peer"` + }{ + Type: t.Type, + Peer: t.Peer, + }) +} + +func NewTunnelEncapSubTLVWireguard(peer []byte) *TunnelEncapSubTLVWireguard { + return &TunnelEncapSubTLVWireguard{ + TunnelEncapSubTLV: TunnelEncapSubTLV{ + Type: ENCAP_SUBTLV_TYPE_ENCAPSULATION, + }, + Peer: peer, + } +} + type TunnelEncapSubTLVProtocol struct { TunnelEncapSubTLV Protocol uint16 @@ -11962,7 +12010,12 @@ func (t *TunnelEncapTLV) DecodeFromBytes(data []byte) error { var subTlv TunnelEncapSubTLVInterface switch subType { case ENCAP_SUBTLV_TYPE_ENCAPSULATION: - subTlv = &TunnelEncapSubTLVEncapsulation{} + switch t.Type { + case TUNNEL_TYPE_WIREGUARD: + subTlv = &TunnelEncapSubTLVWireguard{} + default: + subTlv = &TunnelEncapSubTLVEncapsulation{} + } case ENCAP_SUBTLV_TYPE_PROTOCOL: subTlv = &TunnelEncapSubTLVProtocol{} case ENCAP_SUBTLV_TYPE_COLOR: diff --git a/pkg/server/bmp.go b/pkg/server/bmp.go index 67eebd0c..828bdd56 100644 --- a/pkg/server/bmp.go +++ b/pkg/server/bmp.go @@ -81,11 +81,11 @@ func (r ribout) update(p *table.Path) bool { return true } -func (b *bmpClient) tryConnect() *net.TCPConn { +func (b *bmpClient) tryConnect() net.Conn { interval := 1 for { log.WithFields(log.Fields{"Topic": "bmp"}).Debugf("Connecting BMP server:%s", b.host) - conn, err := net.Dial("tcp", b.host) + conn, err := transport.Dial("tcp", b.host) if err != nil { select { case <-b.dead: @@ -98,7 +98,7 @@ func (b *bmpClient) tryConnect() *net.TCPConn { } } else { log.WithFields(log.Fields{"Topic": "bmp"}).Infof("BMP server is connected:%s", b.host) - return conn.(*net.TCPConn) + return conn } } } diff --git a/pkg/server/fsm.go b/pkg/server/fsm.go index 2228b7ca..d7521f4e 100644 --- a/pkg/server/fsm.go +++ b/pkg/server/fsm.go @@ -179,8 +179,8 @@ type fsm struct { outgoingCh *channels.InfiniteChannel incomingCh *channels.InfiniteChannel reason *fsmStateReason - conn net.Conn - connCh chan net.Conn + conn Conn + connCh chan Conn idleHoldTime float64 opensentHoldTime float64 adminState adminState @@ -274,7 +274,7 @@ func newFSM(gConf *config.Global, pConf *config.Neighbor) *fsm { state: bgp.BGP_FSM_IDLE, outgoingCh: channels.NewInfiniteChannel(), incomingCh: channels.NewInfiniteChannel(), - connCh: make(chan net.Conn, 1), + connCh: make(chan Conn, 1), opensentHoldTime: float64(holdtimeOpensent), adminState: adminState, adminStateCh: make(chan adminStateOperation, 1), @@ -548,13 +548,13 @@ func (h *fsmHandler) connectLoop(ctx context.Context, wg *sync.WaitGroup) { } if err == nil { - d := net.Dialer{ + d := transport.NewDialer(&net.Dialer{ LocalAddr: laddr, Timeout: time.Duration(tick-1) * time.Second, Control: func(network, address string, c syscall.RawConn) error { return dialerControl(network, address, c, ttl, ttlMin, password, bindInterface) }, - } + }) conn, err := d.DialContext(ctx, "tcp", net.JoinHostPort(addr, strconv.Itoa(port))) select { @@ -638,7 +638,7 @@ func (h *fsmHandler) active(ctx context.Context) (bgp.FSMState, *fsmStateReason) ttl = int(fsm.pConf.Transport.Config.Ttl) } if ttl != 0 { - if err := setTCPTTLSockopt(conn.(*net.TCPConn), ttl); err != nil { + if err := conn.SetTCPTTLSockopt(ttl); err != nil { log.WithFields(log.Fields{ "Topic": "Peer", "Key": fsm.pConf.Config.NeighborAddress, @@ -647,7 +647,7 @@ func (h *fsmHandler) active(ctx context.Context) (bgp.FSMState, *fsmStateReason) } } if ttlMin != 0 { - if err := setTCPMinTTLSockopt(conn.(*net.TCPConn), ttlMin); err != nil { + if err := conn.SetTCPMinTTLSockopt(ttlMin); err != nil { log.WithFields(log.Fields{ "Topic": "Peer", "Key": fsm.pConf.Config.NeighborAddress, diff --git a/pkg/server/peer.go b/pkg/server/peer.go index 243a3dcc..b8946050 100644 --- a/pkg/server/peer.go +++ b/pkg/server/peer.go @@ -17,7 +17,6 @@ package server import ( "fmt" - "net" "time" "github.com/osrg/gobgp/internal/pkg/config" @@ -559,7 +558,7 @@ func (peer *peer) StaleAll(rfList []bgp.RouteFamily) []*table.Path { return peer.adjRibIn.StaleAll(rfList) } -func (peer *peer) PassConn(conn *net.TCPConn) { +func (peer *peer) PassConn(conn Conn) { select { case peer.fsm.connCh <- conn: default: diff --git a/pkg/server/rpki.go b/pkg/server/rpki.go index 00fbfcfa..af51fa02 100644 --- a/pkg/server/rpki.go +++ b/pkg/server/rpki.go @@ -53,7 +53,7 @@ type roaEvent struct { EventType roaEventType Src string Data []byte - conn *net.TCPConn + conn net.Conn } type roaManager struct { @@ -309,7 +309,7 @@ func (m *roaManager) GetServers() []*config.RpkiServer { type roaClient struct { host string - conn *net.TCPConn + conn net.Conn state config.RpkiServerState eventCh chan *roaEvent sessionID uint16 @@ -383,14 +383,14 @@ func (c *roaClient) tryConnect() { return default: } - if conn, err := net.Dial("tcp", c.host); err != nil { + if conn, err := transport.Dial("tcp", c.host); err != nil { // better to use context with timeout time.Sleep(connectRetryInterval * time.Second) } else { c.eventCh <- &roaEvent{ EventType: roaConnected, Src: c.host, - conn: conn.(*net.TCPConn), + conn: conn, } return } diff --git a/pkg/server/server.go b/pkg/server/server.go index f1320c5c..8ac9f44a 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -39,8 +39,216 @@ import ( "github.com/osrg/gobgp/pkg/packet/bgp" ) +type ListenTCP func(network string, laddr *net.TCPAddr) (*net.TCPListener, error) + +type Dial func(network, address string) (Conn, error) + +type Dialer interface { + DialContext(ctx context.Context, network, address string) (Conn, error) +} + +type Listener interface { + Accept() (Conn, error) +} + +type ListenConfig interface { + Listen(ctx context.Context, network, address string) (Listener, error) +} + +type NewDialer func(defaults *net.Dialer) Dialer + +type NewListenConfig func(defaults *net.ListenConfig) ListenConfig + +type TransportOptions struct { + Dial + ListenTCP + NewDialer + NewListenConfig +} + +type Conn interface { + net.Conn + + SetTCPTTLSockopt(ttl int) error + SetTCPMinTTLSockopt(ttl int) error +} + +type TCPConn interface { + Conn +} + +type TCPListener interface { + Listener + AcceptTCP() (TCPConn, error) + Addr() net.Addr + Close() error + SetTCPMD5SigSockopt(address string, key string) error +} + +// Golang net.TCPConn wrapper +type netTCPConn struct { + c *net.TCPConn +} + +func (c *netTCPConn) Close() error { + return c.c.Close() +} + +func (c *netTCPConn) LocalAddr() net.Addr { + return c.c.LocalAddr() +} + +func (c *netTCPConn) Read(b []byte) (int, error) { + return c.c.Read(b) +} + +func (c *netTCPConn) RemoteAddr() net.Addr { + return c.c.RemoteAddr() +} + +func (c *netTCPConn) SetDeadline(t time.Time) error { + return c.c.SetDeadline(t) +} + +func (c *netTCPConn) SetReadDeadline(t time.Time) error { + return c.c.SetReadDeadline(t) +} + +func (c *netTCPConn) SetWriteDeadline(t time.Time) error { + return c.c.SetWriteDeadline(t) +} + +func (c *netTCPConn) SetTCPTTLSockopt(ttl int) error { + return setTCPTTLSockopt(c.c, ttl) +} + +func (c *netTCPConn) SetTCPMinTTLSockopt(ttl int) error { + return setTCPMinTTLSockopt(c.c, ttl) +} + +func (c *netTCPConn) Write(b []byte) (int, error) { + return c.c.Write(b) +} + +// Golang net.TCPListener wrapper +type netTCPListener struct { + l *net.TCPListener +} + +func (l *netTCPListener) Accept() (Conn, error) { + conn, err := l.l.AcceptTCP() + if err != nil { + return nil, err + } + tconn, err := netDotConnToConn("tcp", conn) + if err != nil { + return nil, err + } + return tconn, nil +} + +func (l *netTCPListener) AcceptTCP() (TCPConn, error) { + conn, err := l.Accept () + if err != nil { + return nil, err + } + return conn.(TCPConn), nil +} + +func (l *netTCPListener) Addr() net.Addr { + return l.l.Addr() +} + +func (l *netTCPListener) Close() error { + return l.l.Close() +} + +func (l *netTCPListener) SetTCPMD5SigSockopt(address string, key string) error { + return setTCPMD5SigSockopt(l.l, address, key) +} + +func netDotConnToConn(network string, conn net.Conn) (Conn, error) { + switch network { + case "tcp": + return &netTCPConn{ + c: conn.(*net.TCPConn), + }, nil + default: + return nil, fmt.Errorf("unsupported network type %s", network) + } +} + +func netDotListenerToListener(network string, listener net.Listener) (TCPListener, error) { + log.Printf("netDotListenerToListener") + switch network { + case "tcp","tcp4","tcp6": + return &netTCPListener{ + l: listener.(*net.TCPListener), + }, nil + default: + return nil, fmt.Errorf("unsupported network type %s", network) + } +} + +var transport TransportOptions = TransportOptions{ + Dial: func(network, address string) (Conn, error) { + conn, err := net.Dial(network, address) + if err != nil { + return nil, err + } + + return netDotConnToConn(network, conn) + }, + NewDialer: newNetDialer, + NewListenConfig: newNetListenConfig, +} + +type netDialer struct { + d *net.Dialer +} + +type netListenConfig struct { + lc *net.ListenConfig +} + +func (d *netDialer) DialContext(ctx context.Context, network, address string) (Conn, error) { + conn, err := d.d.DialContext(ctx, network, address) + if err != nil { + return nil, err + } + + return netDotConnToConn(network, conn) +} + +func (lc *netListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) { + listener, err := lc.lc.Listen(ctx, network, address) + if err != nil { + return nil, err + } + + return netDotListenerToListener(network, listener) +} + +func newNetDialer(defaults *net.Dialer) Dialer { + dialer := &netDialer{ + defaults, + } + return dialer +} + +func newNetListenConfig(defaults *net.ListenConfig) ListenConfig { + lc := &netListenConfig{ + defaults, + } + return lc +} + +func SetTransportOptions(options *TransportOptions) { + transport = *options +} + type tcpListener struct { - l *net.TCPListener + l TCPListener ch chan struct{} } @@ -53,7 +261,7 @@ func (l *tcpListener) Close() error { } // avoid mapped IPv6 address -func newTCPListener(address string, port uint32, bindToDev string, ch chan *net.TCPConn) (*tcpListener, error) { +func newTCPListener(address string, port uint32, bindToDev string, ch chan TCPConn) (*tcpListener, error) { proto := "tcp4" family := syscall.AF_INET if ip := net.ParseIP(address); ip == nil { @@ -89,13 +297,13 @@ func newTCPListener(address string, port uint32, bindToDev string, ch chan *net. return nil } - l, err := lc.Listen(context.Background(), proto, addr) + l, err := transport.NewListenConfig(&lc).Listen(context.Background(), proto, addr) if err != nil { return nil, err } - listener, ok := l.(*net.TCPListener) + listener, ok := l.(TCPListener) if !ok { - err = fmt.Errorf("unexpected connection listener (not for TCP)") + err = fmt.Errorf("unexpected connection listener (not for TCP) %T", l) return nil, err } @@ -141,7 +349,7 @@ func GrpcOption(opt []grpc.ServerOption) ServerOption { type BgpServer struct { bgpConfig config.Bgp - acceptCh chan *net.TCPConn + acceptCh chan TCPConn incomings []*channels.InfiniteChannel mgmtCh chan *mgmtOp policy *table.RoutingPolicy @@ -204,8 +412,8 @@ func (s *BgpServer) delIncoming(ch *channels.InfiniteChannel) { } } -func (s *BgpServer) listListeners(addr string) []*net.TCPListener { - list := make([]*net.TCPListener, 0, len(s.listeners)) +func (s *BgpServer) listListeners(addr string) []TCPListener { + list := make([]TCPListener, 0, len(s.listeners)) rhs := net.ParseIP(addr).To4() != nil for _, l := range s.listeners { host, _, _ := net.SplitHostPort(l.l.Addr().String()) @@ -251,7 +459,7 @@ func (s *BgpServer) mgmtOperation(f func() error, checkActive bool) (err error) return } -func (s *BgpServer) passConnToPeer(conn *net.TCPConn) { +func (s *BgpServer) passConnToPeer(conn Conn) { host, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) ipaddr, _ := net.ResolveIPAddr("ip", host) remoteAddr := ipaddr.String() @@ -421,7 +629,7 @@ func (s *BgpServer) Serve() { op := value.Interface().(*mgmtOp) s.handleMGMTOp(op) case 1: - conn := value.Interface().(*net.TCPConn) + conn := value.Interface().(Conn) s.passConnToPeer(conn) case 2: ev := value.Interface().(*roaEvent) @@ -2146,7 +2354,7 @@ func (s *BgpServer) StartBgp(ctx context.Context, r *api.StartBgpRequest) error } if c.Config.Port > 0 { - acceptCh := make(chan *net.TCPConn, 4096) + acceptCh := make(chan TCPConn, 4096) for _, addr := range c.Config.LocalAddressList { l, err := newTCPListener(addr, uint32(c.Config.Port), g.BindToDevice, acceptCh) if err != nil { @@ -2934,7 +3142,7 @@ func (s *BgpServer) addNeighbor(c *config.Neighbor) error { if s.bgpConfig.Global.Config.Port > 0 { for _, l := range s.listListeners(addr) { if c.Config.AuthPassword != "" { - if err := setTCPMD5SigSockopt(l, addr, c.Config.AuthPassword); err != nil { + if err := l.SetTCPMD5SigSockopt(addr, c.Config.AuthPassword); err != nil { log.WithFields(log.Fields{ "Topic": "Peer", "Key": addr, @@ -3042,7 +3250,7 @@ func (s *BgpServer) deleteNeighbor(c *config.Neighbor, code, subcode uint8) erro return fmt.Errorf("can't delete a peer configuration for %s", addr) } for _, l := range s.listListeners(addr) { - if err := setTCPMD5SigSockopt(l, addr, ""); err != nil { + if err := l.SetTCPMD5SigSockopt(addr, ""); err != nil { log.WithFields(log.Fields{ "Topic": "Peer", "Key": addr, |