diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2021-02-21 15:51:58 +0100 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@gmail.com> | 2021-03-14 08:46:44 +0900 |
commit | 390e3127cea7a4b3fb9fcc089cfc7ffd02f108e1 (patch) | |
tree | ad217b125dae6cd1ae2c4587fe75243bc7a4c9df | |
parent | dc708d5bed57af5b7f7968ab1845519d8458fc7f (diff) |
add support for tunnel egress endpoint sub-TLV
As specified in draft-ietf-idr-tunnel-encaps-22.
Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
-rw-r--r-- | api/attribute.pb.go | 281 | ||||
-rw-r--r-- | api/attribute.proto | 4 | ||||
-rw-r--r-- | internal/pkg/apiutil/attribute.go | 6 | ||||
-rw-r--r-- | pkg/packet/bgp/bgp.go | 107 |
4 files changed, 268 insertions, 130 deletions
diff --git a/api/attribute.pb.go b/api/attribute.pb.go index 2df06776..5500251c 100644 --- a/api/attribute.pb.go +++ b/api/attribute.pb.go @@ -93,6 +93,7 @@ It has these top-level messages: SegmentTypeA SegmentTypeB TunnelEncapSubTLVSRSegmentList + TunnelEncapSubTLVEgressEndpoint TunnelEncapSubTLVUDPDestPort TunnelEncapSubTLVUnknown TunnelEncapTLV @@ -2847,6 +2848,24 @@ func (m *TunnelEncapSubTLVSRSegmentList) GetSegments() []*google_protobuf.Any { return nil } +type TunnelEncapSubTLVEgressEndpoint struct { + Address string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"` +} + +func (m *TunnelEncapSubTLVEgressEndpoint) Reset() { *m = TunnelEncapSubTLVEgressEndpoint{} } +func (m *TunnelEncapSubTLVEgressEndpoint) String() string { return proto.CompactTextString(m) } +func (*TunnelEncapSubTLVEgressEndpoint) ProtoMessage() {} +func (*TunnelEncapSubTLVEgressEndpoint) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{83} +} + +func (m *TunnelEncapSubTLVEgressEndpoint) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + type TunnelEncapSubTLVUDPDestPort struct { Port uint32 `protobuf:"varint,1,opt,name=port" json:"port,omitempty"` } @@ -2854,7 +2873,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{83} } +func (*TunnelEncapSubTLVUDPDestPort) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{84} } func (m *TunnelEncapSubTLVUDPDestPort) GetPort() uint32 { if m != nil { @@ -2871,7 +2890,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{84} } +func (*TunnelEncapSubTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{85} } func (m *TunnelEncapSubTLVUnknown) GetType() uint32 { if m != nil { @@ -2901,7 +2920,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{85} } +func (*TunnelEncapTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{86} } func (m *TunnelEncapTLV) GetType() uint32 { if m != nil { @@ -2924,7 +2943,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{86} } +func (*TunnelEncapAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{87} } func (m *TunnelEncapAttribute) GetTlvs() []*TunnelEncapTLV { if m != nil { @@ -2943,7 +2962,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{87} } +func (*IPv6AddressSpecificExtended) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{88} } func (m *IPv6AddressSpecificExtended) GetIsTransitive() bool { if m != nil { @@ -2982,7 +3001,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{88} + return fileDescriptor0, []int{89} } func (m *RedirectIPv6AddressSpecificExtended) GetAddress() string { @@ -3010,7 +3029,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{89} + return fileDescriptor0, []int{90} } func (m *IP6ExtendedCommunitiesAttribute) GetCommunities() []*google_protobuf.Any { @@ -3027,7 +3046,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{90} } +func (*AigpTLVIGPMetric) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{91} } func (m *AigpTLVIGPMetric) GetMetric() uint64 { if m != nil { @@ -3044,7 +3063,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{91} } +func (*AigpTLVUnknown) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{92} } func (m *AigpTLVUnknown) GetType() uint32 { if m != nil { @@ -3070,7 +3089,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{92} } +func (*AigpAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{93} } func (m *AigpAttribute) GetTlvs() []*google_protobuf.Any { if m != nil { @@ -3088,7 +3107,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{93} } +func (*LargeCommunity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{94} } func (m *LargeCommunity) GetGlobalAdmin() uint32 { if m != nil { @@ -3118,7 +3137,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{94} } +func (*LargeCommunitiesAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{95} } func (m *LargeCommunitiesAttribute) GetCommunities() []*LargeCommunity { if m != nil { @@ -3139,7 +3158,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{95} } +func (*LsNodeFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{96} } func (m *LsNodeFlags) GetOverload() bool { if m != nil { @@ -3193,7 +3212,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{96} } +func (*LsIGPFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{97} } func (m *LsIGPFlags) GetDown() bool { if m != nil { @@ -3231,7 +3250,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{97} } +func (*LsSrRange) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{98} } func (m *LsSrRange) GetBegin() uint32 { if m != nil { @@ -3256,7 +3275,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{98} } +func (*LsSrCapabilities) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{99} } func (m *LsSrCapabilities) GetIpv4Supported() bool { if m != nil { @@ -3286,7 +3305,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{99} } +func (*LsSrLocalBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{100} } func (m *LsSrLocalBlock) GetRanges() []*LsSrRange { if m != nil { @@ -3310,7 +3329,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{100} } +func (*LsAttributeNode) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{101} } func (m *LsAttributeNode) GetName() string { if m != nil { @@ -3395,7 +3414,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{101} } +func (*LsAttributeLink) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{102} } func (m *LsAttributeLink) GetName() string { if m != nil { @@ -3504,7 +3523,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{102} } +func (*LsAttributePrefix) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{103} } func (m *LsAttributePrefix) GetIgpFlags() *LsIGPFlags { if m != nil { @@ -3536,7 +3555,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{103} } +func (*LsAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{104} } func (m *LsAttribute) GetNode() *LsAttributeNode { if m != nil { @@ -3568,7 +3587,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{104} } +func (*UnknownAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{105} } func (m *UnknownAttribute) GetFlags() uint32 { if m != nil { @@ -3604,7 +3623,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{105} } +func (*SRv6StructureSubSubTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{106} } func (m *SRv6StructureSubSubTLV) GetLocalBlockLength() uint32 { if m != nil { @@ -3656,7 +3675,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{106} } +func (*SRv6SIDFlags) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{107} } func (m *SRv6SIDFlags) GetFlag_1() bool { if m != nil { @@ -3672,7 +3691,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{107} } +func (*SRv6TLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{108} } func (m *SRv6TLV) GetTlv() []*google_protobuf.Any { if m != nil { @@ -3694,7 +3713,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{108} } +func (*SRv6InformationSubTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{109} } func (m *SRv6InformationSubTLV) GetSid() []byte { if m != nil { @@ -3734,7 +3753,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{109} } +func (*SRv6L3ServiceTLV) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{110} } func (m *SRv6L3ServiceTLV) GetSubTlvs() map[uint32]*SRv6TLV { if m != nil { @@ -3756,7 +3775,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{110} } +func (*PrefixSID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{111} } func (m *PrefixSID) GetTlvs() []*google_protobuf.Any { if m != nil { @@ -3849,6 +3868,7 @@ func init() { proto.RegisterType((*SegmentTypeA)(nil), "gobgpapi.SegmentTypeA") proto.RegisterType((*SegmentTypeB)(nil), "gobgpapi.SegmentTypeB") proto.RegisterType((*TunnelEncapSubTLVSRSegmentList)(nil), "gobgpapi.TunnelEncapSubTLVSRSegmentList") + proto.RegisterType((*TunnelEncapSubTLVEgressEndpoint)(nil), "gobgpapi.TunnelEncapSubTLVEgressEndpoint") proto.RegisterType((*TunnelEncapSubTLVUDPDestPort)(nil), "gobgpapi.TunnelEncapSubTLVUDPDestPort") proto.RegisterType((*TunnelEncapSubTLVUnknown)(nil), "gobgpapi.TunnelEncapSubTLVUnknown") proto.RegisterType((*TunnelEncapTLV)(nil), "gobgpapi.TunnelEncapTLV") @@ -3886,7 +3906,7 @@ func init() { func init() { proto.RegisterFile("attribute.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 4229 bytes of a gzipped FileDescriptorProto + // 4244 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0x4d, 0x73, 0xdb, 0x48, 0x76, 0xcb, 0x0f, 0x49, 0xd4, 0xe3, 0x87, 0x20, 0xe8, 0x63, 0x24, 0xd9, 0x1e, 0x7b, 0xe1, 0x2f, 0x45, 0xf6, 0x68, 0xd6, 0xb2, 0x86, 0x3b, 0x9e, 0xa9, 0x4d, 0x8a, 0x16, 0x69, 0x0f, 0x33, 0x14, @@ -4051,105 +4071,106 @@ var fileDescriptor0 = []byte{ 0x45, 0x6f, 0xa8, 0x8f, 0xd3, 0x92, 0x96, 0x33, 0x66, 0x97, 0x12, 0x49, 0xee, 0x60, 0x76, 0x3a, 0x94, 0xe5, 0xf9, 0xfc, 0x47, 0xe1, 0xf9, 0xdb, 0x19, 0x5e, 0xb6, 0xaf, 0x8b, 0xf9, 0x1d, 0x4c, 0x22, 0x75, 0x27, 0xd6, 0x26, 0x5f, 0x46, 0x4d, 0x1b, 0x05, 0x3f, 0x07, 0xa9, 0x61, 0xf5, 0x17, - 0xa9, 0x78, 0x74, 0x5d, 0x57, 0x2d, 0x09, 0x48, 0x7b, 0x70, 0xf3, 0xd2, 0xfa, 0xc7, 0xcd, 0x5e, - 0x13, 0x91, 0xa8, 0xe7, 0x87, 0xac, 0xc9, 0x18, 0xa7, 0x79, 0x55, 0x9d, 0x7d, 0x6b, 0x4d, 0xd8, - 0xb8, 0x3c, 0x87, 0xc7, 0xeb, 0xf7, 0x88, 0xd3, 0x5d, 0xa8, 0xa5, 0xb8, 0x0c, 0x3a, 0x27, 0x33, - 0xe7, 0xd2, 0xfa, 0xd9, 0x9d, 0x5c, 0xbf, 0x1b, 0x46, 0xa1, 0x35, 0x61, 0x35, 0xc5, 0x2f, 0x89, - 0x8b, 0x8f, 0x05, 0x07, 0x1e, 0x9f, 0x37, 0x12, 0xed, 0x65, 0x57, 0x17, 0x5c, 0x44, 0x79, 0x55, - 0xff, 0x08, 0xcb, 0xab, 0x6c, 0xf2, 0x57, 0xff, 0x09, 0x92, 0xbf, 0xbf, 0x80, 0xdb, 0xed, 0x5e, - 0xfd, 0x27, 0xc9, 0x9e, 0x76, 0x40, 0x69, 0x60, 0x87, 0x2a, 0xba, 0xfd, 0xb2, 0x77, 0x88, 0xa2, - 0x10, 0x5b, 0xd4, 0x4f, 0x8c, 0xd8, 0x17, 0x13, 0xb4, 0xa8, 0x0b, 0x48, 0xfb, 0x0a, 0x6a, 0x82, - 0xf6, 0xfd, 0xad, 0xea, 0x19, 0x54, 0xe9, 0xdc, 0x74, 0x57, 0x20, 0x7d, 0xfc, 0xd7, 0x19, 0xd0, - 0x18, 0x6a, 0x1d, 0x5a, 0xe0, 0xc8, 0x7d, 0xb3, 0xba, 0xc4, 0x71, 0xfd, 0x61, 0xac, 0x31, 0xd1, - 0x80, 0xe5, 0x38, 0xa6, 0xb2, 0x44, 0xa7, 0xb6, 0x19, 0x99, 0x4f, 0x32, 0x3a, 0x6d, 0x52, 0x4c, - 0x96, 0x60, 0x4f, 0xf6, 0x8f, 0x63, 0x82, 0x3d, 0xed, 0x15, 0x6c, 0x66, 0x96, 0xcd, 0xa8, 0xfb, - 0xab, 0x59, 0xea, 0x4e, 0xd9, 0x70, 0x56, 0xe0, 0xac, 0xca, 0xff, 0x98, 0x83, 0x32, 0x6f, 0x7b, - 0x71, 0x77, 0xbb, 0x05, 0x25, 0x7f, 0x82, 0x42, 0xd7, 0x37, 0x6d, 0x59, 0xc7, 0x48, 0x98, 0x3d, - 0xc3, 0x47, 0x91, 0x69, 0x9d, 0x89, 0x67, 0xf8, 0x92, 0x1e, 0xc3, 0xec, 0xc5, 0xe9, 0x4d, 0x84, - 0x42, 0x5a, 0xff, 0x70, 0xd7, 0x1b, 0xc3, 0xac, 0x99, 0x3e, 0x0c, 0x85, 0xeb, 0xa5, 0x9f, 0xf4, - 0x50, 0x79, 0xab, 0x9b, 0xc5, 0xb0, 0x92, 0x2e, 0x20, 0x9a, 0x5e, 0x8a, 0x2e, 0x6f, 0x49, 0xcf, - 0x4f, 0xea, 0xda, 0xdf, 0xb1, 0x3e, 0x69, 0xfb, 0x65, 0xef, 0x85, 0xcc, 0x53, 0x6d, 0xff, 0xb5, - 0x27, 0x04, 0x63, 0xdf, 0xea, 0x2d, 0x00, 0xcf, 0x37, 0xc6, 0x1e, 0x7b, 0xfa, 0x15, 0x62, 0x2d, - 0x7a, 0xfe, 0x31, 0x47, 0xd0, 0xab, 0x28, 0xcd, 0x39, 0xb9, 0x50, 0x25, 0xbd, 0x22, 0x0c, 0x9a, - 0xdb, 0xfc, 0x7d, 0xa8, 0x05, 0xa1, 0x1f, 0x98, 0x0e, 0xcd, 0xc8, 0x3c, 0x42, 0x4c, 0x21, 0x6b, - 0x35, 0xc6, 0x76, 0x09, 0x31, 0xb5, 0xa7, 0xb0, 0xd8, 0x21, 0xfd, 0x50, 0x37, 0x3d, 0x87, 0x59, - 0xd6, 0x10, 0x25, 0xff, 0x17, 0x71, 0x80, 0x6e, 0x15, 0x79, 0xb2, 0xbf, 0x4e, 0x3f, 0xb5, 0xdf, - 0xb3, 0xe7, 0x85, 0x7e, 0x78, 0x60, 0x06, 0xbc, 0xdd, 0x8c, 0x11, 0x5b, 0x10, 0x07, 0x93, 0x7d, - 0x83, 0x8c, 0x03, 0xea, 0x2c, 0x91, 0xd4, 0x75, 0x95, 0x62, 0xfb, 0x12, 0x29, 0xc8, 0xea, 0x29, - 0xb2, 0x7c, 0x4c, 0x56, 0x4f, 0xc8, 0x1e, 0xc1, 0x7c, 0x48, 0x65, 0x92, 0xad, 0xaa, 0x95, 0x74, - 0x37, 0x4f, 0xc8, 0xab, 0x0b, 0x12, 0xed, 0x57, 0x50, 0xa3, 0x48, 0xf6, 0x36, 0xf0, 0x9c, 0x66, - 0x48, 0xa9, 0xe9, 0xb9, 0xb7, 0x4f, 0xff, 0xdb, 0x02, 0x2c, 0x75, 0x12, 0xdb, 0x63, 0xad, 0x51, - 0x15, 0x8a, 0xa9, 0x0c, 0x96, 0x7d, 0xab, 0x8f, 0x64, 0xd8, 0xe3, 0x9d, 0xca, 0xb5, 0xe9, 0x26, - 0x6b, 0x26, 0xea, 0x3d, 0x80, 0x25, 0x7e, 0x48, 0xc9, 0xfb, 0x07, 0xf7, 0x7b, 0xfc, 0xec, 0xe4, - 0x0b, 0x88, 0xfa, 0x08, 0xd4, 0x29, 0x3a, 0x63, 0x52, 0x17, 0x4f, 0x0e, 0x4b, 0x19, 0xd2, 0x93, - 0x3a, 0x6f, 0x26, 0x60, 0xc2, 0x1e, 0x65, 0x98, 0x99, 0x55, 0xf4, 0x12, 0x45, 0x34, 0x42, 0x64, - 0xb2, 0xf7, 0x3b, 0xd6, 0x55, 0x61, 0xc6, 0x56, 0xd1, 0x05, 0xa4, 0x1e, 0xc0, 0x12, 0x09, 0x0d, - 0x2b, 0x75, 0x56, 0xec, 0xf5, 0x78, 0xaa, 0x4b, 0x9c, 0x3d, 0x4d, 0xbd, 0x46, 0xb2, 0xa7, 0x7b, - 0x17, 0xaa, 0x24, 0x34, 0x4c, 0xd7, 0xa1, 0x49, 0xf8, 0xd9, 0x88, 0x6c, 0x94, 0xd8, 0x1a, 0x15, - 0x12, 0x36, 0x62, 0x9c, 0xfa, 0xa7, 0x50, 0x23, 0xa1, 0x78, 0xb6, 0x61, 0x99, 0xea, 0xc6, 0x22, - 0x5b, 0x68, 0x23, 0xbb, 0x50, 0x72, 0x4e, 0x74, 0x7e, 0x02, 0x69, 0x7f, 0x2c, 0x66, 0x0e, 0xa2, - 0x83, 0xbd, 0xf3, 0x99, 0x07, 0x31, 0x43, 0xb7, 0xf9, 0x77, 0xd7, 0x6d, 0x61, 0xb6, 0x6e, 0xb7, - 0x41, 0x11, 0xaf, 0x0e, 0x09, 0x57, 0x7e, 0x0c, 0x35, 0x8e, 0x8f, 0xd9, 0x7e, 0x06, 0x2b, 0xd3, - 0x94, 0x46, 0xfc, 0xee, 0xa3, 0x64, 0x89, 0x4f, 0xea, 0xd4, 0x11, 0x32, 0x2f, 0x6a, 0x38, 0xa1, - 0x3f, 0x0e, 0xd8, 0xe1, 0x54, 0x75, 0x60, 0xa8, 0x97, 0x14, 0xa3, 0xee, 0xc0, 0xb2, 0xcd, 0x1b, - 0x65, 0x46, 0x84, 0x0c, 0x11, 0x19, 0xf8, 0x03, 0xff, 0x92, 0x18, 0x18, 0x20, 0x11, 0x3a, 0x6e, - 0x01, 0x60, 0x27, 0x90, 0x44, 0x25, 0xfe, 0xb6, 0x8b, 0x9d, 0x20, 0x89, 0x2c, 0xc2, 0x06, 0x16, - 0x33, 0x36, 0x70, 0x13, 0x16, 0x87, 0xa6, 0x67, 0xbf, 0xc6, 0x76, 0x74, 0xb6, 0x01, 0xac, 0xf9, - 0x93, 0x20, 0xd4, 0x27, 0xb0, 0x1a, 0x22, 0x82, 0xc2, 0x89, 0x39, 0x74, 0x91, 0x91, 0x10, 0x96, - 0x19, 0xe1, 0x4a, 0x32, 0xf6, 0x3c, 0x3d, 0x65, 0xec, 0xf1, 0x01, 0x64, 0xa7, 0xa6, 0x54, 0xee, - 0x14, 0xe8, 0x94, 0x64, 0x2c, 0x99, 0xb2, 0x0d, 0x0a, 0x35, 0x21, 0xfb, 0xd7, 0xa6, 0x85, 0x3c, - 0xeb, 0xc2, 0xa0, 0x85, 0x41, 0x95, 0x6d, 0xa0, 0x46, 0xc2, 0x86, 0x44, 0xf7, 0x31, 0x6f, 0x54, - 0x86, 0xae, 0x43, 0x36, 0x6a, 0xec, 0xbd, 0x9e, 0x03, 0xda, 0xdf, 0xe4, 0x60, 0x39, 0x65, 0x1d, - 0xe2, 0x9d, 0xe1, 0x09, 0xd0, 0xed, 0x1b, 0xe9, 0x7c, 0x34, 0xf3, 0xd8, 0x20, 0x1d, 0xad, 0x5e, - 0xc2, 0x4e, 0xf0, 0x42, 0xa6, 0xe9, 0x42, 0x49, 0xf9, 0x8c, 0x92, 0x34, 0x66, 0xe3, 0xe2, 0x45, - 0x84, 0xc4, 0x6f, 0x9e, 0x65, 0x22, 0xde, 0x34, 0xfa, 0xd8, 0xd6, 0xfe, 0x89, 0xc5, 0x96, 0x24, - 0x4e, 0x7d, 0x06, 0xc5, 0xd4, 0xbb, 0xcb, 0x66, 0x7a, 0xe5, 0x8c, 0x43, 0xd1, 0x19, 0x19, 0x25, - 0x77, 0xb1, 0x77, 0x2e, 0x3c, 0xc8, 0x6c, 0x72, 0x6a, 0xf6, 0x3a, 0x23, 0x53, 0x9f, 0x66, 0x9e, - 0xea, 0xcb, 0x7b, 0x37, 0x66, 0x4e, 0x10, 0x3f, 0xc0, 0xc8, 0x3f, 0x0f, 0x74, 0x50, 0x44, 0xfa, - 0xf0, 0x03, 0x7b, 0x24, 0x33, 0x9a, 0xac, 0xff, 0x96, 0x87, 0x75, 0x5a, 0x89, 0xc5, 0x65, 0x56, - 0x7f, 0x3c, 0xe4, 0xf9, 0xaf, 0xfa, 0x58, 0x5e, 0xb2, 0xb8, 0x58, 0x4d, 0xfe, 0xfb, 0x50, 0xdc, - 0xf8, 0x72, 0x77, 0xf8, 0x53, 0xcd, 0x0e, 0x2c, 0x27, 0xaf, 0x55, 0x92, 0x98, 0xaf, 0xbf, 0x14, - 0x3f, 0x4c, 0x09, 0xda, 0x87, 0xb0, 0x44, 0x0b, 0xd7, 0x08, 0xfb, 0x9e, 0x91, 0x79, 0xf7, 0xa9, - 0x49, 0x74, 0x42, 0x68, 0x86, 0xce, 0x98, 0x26, 0xf6, 0x92, 0x90, 0x67, 0x91, 0x35, 0x89, 0x16, - 0x84, 0x4f, 0x60, 0x95, 0x65, 0xb0, 0x81, 0x4f, 0x13, 0xd6, 0x84, 0x2d, 0x2f, 0x86, 0x57, 0x32, - 0x63, 0x57, 0x4d, 0x11, 0xff, 0x48, 0xcc, 0xcf, 0x98, 0x72, 0xc4, 0x7f, 0x98, 0xb8, 0x0f, 0x15, - 0xa6, 0xab, 0x76, 0x33, 0x2e, 0xf7, 0xa8, 0xbe, 0x8d, 0x27, 0xb2, 0xdc, 0xa3, 0xd0, 0x13, 0xed, - 0x09, 0x2c, 0x50, 0x32, 0xaa, 0xc3, 0x07, 0x50, 0x88, 0xdc, 0xc9, 0xb5, 0xa9, 0x1a, 0x25, 0xd0, - 0xfe, 0x35, 0xcf, 0x1b, 0x0c, 0x6d, 0xef, 0xd4, 0x0f, 0x47, 0xac, 0x19, 0x25, 0x4e, 0x41, 0x14, - 0xda, 0xb9, 0xa4, 0xd0, 0x7e, 0x9c, 0x8d, 0x56, 0x53, 0xfd, 0x06, 0x29, 0x9c, 0x34, 0x85, 0x47, - 0xb0, 0x7c, 0xa9, 0x2c, 0x17, 0xda, 0x56, 0xa6, 0x6b, 0x6d, 0xf5, 0x3b, 0xa8, 0xd0, 0x34, 0x9f, - 0xa5, 0xfa, 0x34, 0xc5, 0x2c, 0x32, 0xb9, 0x3f, 0xcf, 0xae, 0x70, 0x49, 0xc6, 0x5d, 0x61, 0x33, - 0xee, 0x84, 0xb4, 0xbc, 0x28, 0xbc, 0xd0, 0x81, 0xc4, 0x88, 0xad, 0x1e, 0x2c, 0x4d, 0x0d, 0xcf, - 0xe8, 0xb2, 0x3d, 0x4c, 0x67, 0xbe, 0xe5, 0xbd, 0xe5, 0xec, 0x82, 0xb4, 0x96, 0xe1, 0xe3, 0x5f, - 0xe5, 0xbf, 0xcc, 0x69, 0xff, 0x9c, 0x03, 0x85, 0xa2, 0x3b, 0x4f, 0xfb, 0x28, 0x9c, 0x60, 0x0b, - 0x51, 0x35, 0x3d, 0x17, 0x05, 0x4a, 0x92, 0x18, 0x3f, 0xcc, 0x32, 0x49, 0x53, 0xef, 0x66, 0xa4, - 0x65, 0x95, 0x0c, 0x15, 0xf5, 0x10, 0x2a, 0x3f, 0xa6, 0x9c, 0x5f, 0xc0, 0xa2, 0x70, 0x2f, 0xbc, - 0x77, 0xf5, 0x6e, 0x49, 0xfb, 0x0e, 0x61, 0xef, 0xf6, 0xe2, 0x25, 0x55, 0x5d, 0x81, 0xa5, 0x4e, - 0xdf, 0xa0, 0xa0, 0x71, 0xdc, 0xfd, 0xb6, 0x7b, 0xf4, 0xaa, 0xab, 0xfc, 0x4c, 0x55, 0xa0, 0x22, - 0x91, 0xdd, 0xa3, 0x66, 0x4b, 0xc9, 0xa5, 0x31, 0x9d, 0x76, 0xf7, 0x5b, 0x25, 0xaf, 0xae, 0xc1, - 0xb2, 0xc4, 0xf4, 0xf4, 0xd6, 0x8b, 0xf6, 0xf7, 0xc6, 0xc9, 0xbe, 0x52, 0x98, 0x85, 0xae, 0x2b, - 0xc5, 0x9d, 0xff, 0x62, 0xaf, 0xbc, 0xc9, 0x63, 0xaa, 0xfa, 0x09, 0xac, 0x74, 0xfa, 0x46, 0x4f, - 0x3f, 0x1a, 0x1c, 0x1d, 0x1c, 0x75, 0x52, 0x6b, 0x4f, 0x0d, 0xb4, 0xfb, 0xed, 0xbe, 0xd1, 0x79, - 0xa2, 0xe4, 0x66, 0x0f, 0xec, 0x29, 0xf9, 0xe9, 0x81, 0xa3, 0x7e, 0xef, 0x85, 0x71, 0xb2, 0xa7, - 0x14, 0xd4, 0x75, 0x50, 0xd3, 0x03, 0xcd, 0xb6, 0xde, 0x3a, 0x18, 0x28, 0xc5, 0x69, 0x7c, 0x7f, - 0xd0, 0x18, 0xb4, 0x0f, 0x94, 0xb9, 0xd9, 0x8c, 0x9e, 0x2a, 0xf3, 0x3b, 0xff, 0x3e, 0xc7, 0x2f, - 0x66, 0x6c, 0xc7, 0x15, 0x28, 0xe9, 0xad, 0x7e, 0x4b, 0x3f, 0x69, 0x35, 0x95, 0x9f, 0xa9, 0x0b, - 0x50, 0x68, 0x75, 0x9b, 0x5c, 0x4b, 0xad, 0x6e, 0xd3, 0x78, 0xd5, 0x1e, 0x7c, 0x63, 0xf4, 0xfa, - 0x3d, 0x25, 0x9f, 0xc1, 0x1c, 0xf7, 0x7b, 0x4a, 0x41, 0x5d, 0x05, 0x25, 0x4d, 0xc3, 0xb0, 0x45, - 0xb5, 0x04, 0xc5, 0x56, 0xb7, 0xf9, 0xbd, 0x32, 0xa7, 0x2e, 0x43, 0x95, 0x7e, 0x25, 0x4c, 0xe6, - 0xb3, 0x28, 0x4a, 0xbf, 0x40, 0xd5, 0x9c, 0xa1, 0x62, 0xe8, 0x92, 0x60, 0x33, 0x50, 0x16, 0xc5, - 0x9c, 0x41, 0xc2, 0x06, 0xb2, 0x28, 0x4a, 0x5f, 0x16, 0x6c, 0x06, 0x59, 0x36, 0x15, 0x41, 0x69, - 0x3c, 0xaf, 0x1b, 0xad, 0xee, 0x41, 0xa3, 0xd7, 0x57, 0x6a, 0x2a, 0xc0, 0x3c, 0x43, 0x1d, 0x2a, - 0x4b, 0x6a, 0x19, 0x16, 0xe8, 0x77, 0xf3, 0xfb, 0xba, 0xa2, 0x24, 0xc0, 0xbe, 0xb2, 0x1c, 0x03, - 0x83, 0xba, 0xa2, 0x26, 0xc0, 0xbe, 0xb2, 0x42, 0x35, 0x26, 0x80, 0xba, 0xb2, 0x9a, 0x4c, 0xda, - 0x53, 0xd6, 0xe2, 0xa1, 0xef, 0xf7, 0x4e, 0x94, 0xf5, 0x84, 0x70, 0xef, 0x58, 0xf9, 0x24, 0x05, - 0x1d, 0x2a, 0x1b, 0x42, 0xdc, 0x44, 0x2e, 0x43, 0x47, 0xb6, 0x72, 0x63, 0x4a, 0xc9, 0x4d, 0xe5, - 0xe6, 0x0c, 0x25, 0x37, 0x95, 0x5b, 0x19, 0xec, 0xb1, 0xc0, 0x7e, 0xaa, 0x6e, 0xc0, 0xea, 0xf4, - 0x81, 0xb0, 0x91, 0xdb, 0xd3, 0x7a, 0x6f, 0x2a, 0x77, 0x66, 0xe9, 0xbd, 0xa9, 0xfc, 0x3c, 0x8b, - 0x96, 0x0c, 0x34, 0x75, 0x13, 0xd6, 0x2e, 0x9d, 0x12, 0x1b, 0xba, 0x3b, 0x7d, 0x18, 0x4d, 0xe5, - 0xde, 0xac, 0xc3, 0x68, 0x2a, 0xf7, 0xb3, 0x68, 0xc9, 0xe0, 0x81, 0xe0, 0x3d, 0xb8, 0xcc, 0xfb, - 0xe1, 0x4e, 0x93, 0x2a, 0x8d, 0x77, 0x20, 0x99, 0xa5, 0x8a, 0x84, 0x4a, 0xf9, 0x99, 0xba, 0x08, - 0x73, 0x14, 0x4b, 0xaf, 0x93, 0xf8, 0xa4, 0x17, 0x48, 0x7c, 0x3e, 0x55, 0x0a, 0xf2, 0x73, 0x5f, - 0x29, 0x0e, 0xe7, 0x99, 0xef, 0x78, 0xfa, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x42, 0xb7, 0x81, - 0x22, 0x93, 0x32, 0x00, 0x00, + 0xa9, 0x78, 0x74, 0x5d, 0x57, 0x2d, 0x09, 0x48, 0x5f, 0xc3, 0xed, 0xcb, 0x5e, 0xde, 0xa1, 0x71, + 0xa6, 0x25, 0x4c, 0xeb, 0x9a, 0x67, 0xc9, 0x3d, 0xb8, 0x79, 0x69, 0xf2, 0x71, 0xb3, 0xd7, 0x44, + 0x24, 0xea, 0xf9, 0x21, 0xeb, 0x50, 0xc6, 0x39, 0x62, 0x55, 0x67, 0xdf, 0x5a, 0x13, 0x36, 0x2e, + 0xcf, 0xe1, 0xc1, 0xfe, 0x3d, 0x82, 0x7c, 0x17, 0x6a, 0x29, 0x2e, 0x83, 0xce, 0xc9, 0xcc, 0xb9, + 0xb4, 0xf8, 0x76, 0x27, 0xd7, 0xab, 0x82, 0x51, 0x68, 0x4d, 0x58, 0x4d, 0xf1, 0x4b, 0x82, 0xea, + 0x63, 0xc1, 0x81, 0x07, 0xf7, 0x8d, 0x44, 0xf5, 0xd9, 0xd5, 0x05, 0x17, 0x51, 0x9b, 0xd5, 0x3f, + 0xc2, 0xda, 0x2c, 0x9b, 0x39, 0xd6, 0x7f, 0x82, 0xcc, 0xf1, 0x2f, 0xe0, 0x76, 0xbb, 0x57, 0xff, + 0x49, 0x52, 0xaf, 0x1d, 0x50, 0x1a, 0xd8, 0xa1, 0x8a, 0x6e, 0xbf, 0xec, 0x1d, 0xa2, 0x28, 0xc4, + 0x16, 0x75, 0x32, 0x23, 0xf6, 0xc5, 0x04, 0x2d, 0xea, 0x02, 0xd2, 0xbe, 0x82, 0x9a, 0xa0, 0x7d, + 0x7f, 0xab, 0x7a, 0x06, 0x55, 0x3a, 0x37, 0xdd, 0x52, 0x48, 0x1f, 0xff, 0x75, 0x06, 0x34, 0x86, + 0x5a, 0x87, 0x56, 0x47, 0x72, 0xdf, 0xac, 0xa8, 0x71, 0x5c, 0x7f, 0x18, 0x6b, 0x4c, 0x74, 0x6f, + 0x39, 0x8e, 0xa9, 0x2c, 0xd1, 0xa9, 0x6d, 0x46, 0xe6, 0x93, 0x8c, 0x4e, 0x9b, 0x14, 0x93, 0x25, + 0xd8, 0x93, 0xcd, 0xe7, 0x98, 0x60, 0x4f, 0x7b, 0x05, 0x9b, 0x99, 0x65, 0x33, 0xea, 0xfe, 0x6a, + 0x96, 0xba, 0x53, 0x36, 0x9c, 0x15, 0x38, 0xab, 0xf2, 0x3f, 0xe6, 0xa0, 0xcc, 0x7b, 0x66, 0xdc, + 0x57, 0x6f, 0x41, 0xc9, 0x9f, 0xa0, 0xd0, 0xf5, 0x4d, 0x5b, 0x16, 0x41, 0x12, 0x66, 0x6f, 0xf8, + 0x51, 0x64, 0x5a, 0x67, 0xe2, 0x0d, 0xbf, 0xa4, 0xc7, 0x30, 0x7b, 0xae, 0x7a, 0x13, 0xa1, 0x90, + 0x16, 0x4f, 0xdc, 0x6f, 0xc7, 0x30, 0xeb, 0xc4, 0x0f, 0x43, 0xe1, 0xb7, 0xe9, 0x27, 0x3d, 0x54, + 0xde, 0x27, 0x67, 0x01, 0xb0, 0xa4, 0x0b, 0x88, 0xe6, 0xa6, 0xa2, 0x45, 0x5c, 0xd2, 0xf3, 0x93, + 0xba, 0xf6, 0x77, 0xac, 0xc9, 0xda, 0x7e, 0xd9, 0x7b, 0x21, 0x93, 0x5c, 0xdb, 0x7f, 0xed, 0x09, + 0xc1, 0xd8, 0xb7, 0x7a, 0x0b, 0xc0, 0xf3, 0x8d, 0xb1, 0xc7, 0xde, 0x8d, 0x85, 0x58, 0x8b, 0x9e, + 0x7f, 0xcc, 0x11, 0xf4, 0x2a, 0x4a, 0x73, 0x4e, 0x2e, 0x54, 0x49, 0xaf, 0x08, 0x83, 0xe6, 0x36, + 0x7f, 0x1f, 0x6a, 0x41, 0xe8, 0x07, 0xa6, 0x43, 0xd3, 0x39, 0x8f, 0x10, 0x53, 0xc8, 0x5a, 0x8d, + 0xb1, 0x5d, 0x42, 0x4c, 0xed, 0x29, 0x2c, 0x76, 0x48, 0x3f, 0xd4, 0x4d, 0xcf, 0x61, 0x96, 0x35, + 0x44, 0xc9, 0xcf, 0x49, 0x1c, 0xa0, 0x5b, 0x45, 0x9e, 0x6c, 0xce, 0xd3, 0x4f, 0xed, 0xf7, 0xec, + 0x6d, 0xa2, 0x1f, 0x1e, 0x98, 0x01, 0xef, 0x55, 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, 0x47, 0x30, 0x1f, 0x52, 0x99, 0x64, 0x9f, 0x6b, 0x25, 0xdd, 0x0a, + 0x14, 0xf2, 0xea, 0x82, 0x44, 0xfb, 0x15, 0xd4, 0x28, 0x92, 0x3d, 0x2c, 0x3c, 0xa7, 0xe9, 0x55, + 0x6a, 0x7a, 0xee, 0xed, 0xd3, 0xff, 0xb6, 0x00, 0x4b, 0x9d, 0xc4, 0xf6, 0x58, 0x5f, 0x55, 0x85, + 0x62, 0x2a, 0xfd, 0x65, 0xdf, 0xea, 0x23, 0x19, 0x33, 0x79, 0x9b, 0x73, 0x6d, 0xba, 0x43, 0x9b, + 0x09, 0x99, 0x0f, 0x60, 0x89, 0x1f, 0x52, 0xf2, 0x78, 0xc2, 0xfd, 0x1e, 0x3f, 0x3b, 0xf9, 0x7c, + 0xa2, 0x3e, 0x02, 0x75, 0x8a, 0xce, 0x98, 0xd4, 0xc5, 0x7b, 0xc5, 0x52, 0x86, 0xf4, 0xa4, 0xce, + 0x3b, 0x11, 0x98, 0xb0, 0x17, 0x1d, 0x66, 0x66, 0x15, 0xbd, 0x44, 0x11, 0x8d, 0x10, 0x99, 0xec, + 0xf1, 0x8f, 0xb5, 0x64, 0x98, 0xb1, 0x55, 0x74, 0x01, 0xa9, 0x07, 0xb0, 0x44, 0x42, 0xc3, 0x4a, + 0x9d, 0x15, 0x7b, 0x7a, 0x9e, 0x6a, 0x31, 0x67, 0x4f, 0x53, 0xaf, 0x91, 0xec, 0xe9, 0xde, 0x85, + 0x2a, 0x09, 0x0d, 0xd3, 0x75, 0x68, 0x06, 0x7f, 0x36, 0x22, 0x1b, 0x25, 0xb6, 0x46, 0x85, 0x84, + 0x8d, 0x18, 0xa7, 0xfe, 0x29, 0xd4, 0x48, 0x28, 0xde, 0x7c, 0x58, 0x9a, 0xbb, 0xb1, 0xc8, 0x16, + 0xda, 0xc8, 0x2e, 0x94, 0x9c, 0x13, 0x9d, 0x9f, 0x40, 0xda, 0x1f, 0x8b, 0x99, 0x83, 0xe8, 0x60, + 0xef, 0x7c, 0xe6, 0x41, 0xcc, 0xd0, 0x6d, 0xfe, 0xdd, 0x75, 0x5b, 0x98, 0xad, 0xdb, 0x6d, 0x50, + 0xc4, 0x93, 0x45, 0xc2, 0x95, 0x1f, 0x43, 0x8d, 0xe3, 0x63, 0xb6, 0x9f, 0xc1, 0xca, 0x34, 0xa5, + 0x11, 0x3f, 0x1a, 0x29, 0x59, 0xe2, 0x93, 0x3a, 0x75, 0x84, 0xcc, 0x8b, 0x1a, 0x4e, 0xe8, 0x8f, + 0x03, 0x76, 0x38, 0x55, 0x1d, 0x18, 0xea, 0x25, 0xc5, 0xa8, 0x3b, 0xb0, 0x6c, 0xf3, 0x2e, 0x9b, + 0x11, 0x21, 0x43, 0x44, 0x06, 0xfe, 0x77, 0xc0, 0x92, 0x18, 0x18, 0x20, 0x11, 0x3a, 0x6e, 0x01, + 0x60, 0x27, 0x90, 0x44, 0x25, 0xfe, 0x30, 0x8c, 0x9d, 0x20, 0x89, 0x2c, 0xc2, 0x06, 0x16, 0x33, + 0x36, 0x70, 0x13, 0x16, 0x87, 0xa6, 0x67, 0xbf, 0xc6, 0x76, 0x74, 0xb6, 0x01, 0xac, 0x73, 0x94, + 0x20, 0xd4, 0x27, 0xb0, 0x1a, 0x22, 0x82, 0xc2, 0x89, 0x39, 0x74, 0x91, 0x91, 0x10, 0x96, 0x19, + 0xe1, 0x4a, 0x32, 0xf6, 0x3c, 0x3d, 0x65, 0xec, 0xf1, 0x01, 0x64, 0xa7, 0xa6, 0x54, 0xee, 0x14, + 0xe8, 0x94, 0x64, 0x2c, 0x99, 0xb2, 0x0d, 0x0a, 0x35, 0x21, 0xfb, 0xd7, 0xa6, 0x85, 0x3c, 0xeb, + 0xc2, 0xa0, 0x55, 0x45, 0x95, 0x6d, 0xa0, 0x46, 0xc2, 0x86, 0x44, 0xf7, 0x31, 0xef, 0x72, 0x86, + 0xae, 0x43, 0x36, 0x6a, 0xec, 0xb1, 0x9f, 0x03, 0xda, 0xdf, 0xe4, 0x60, 0x39, 0x65, 0x1d, 0xe2, + 0x91, 0xe2, 0x09, 0xd0, 0xed, 0x1b, 0xe9, 0x64, 0x36, 0xf3, 0x52, 0x21, 0x1d, 0xad, 0x5e, 0xc2, + 0x4e, 0xf0, 0x42, 0xe6, 0xf8, 0x42, 0x49, 0xf9, 0x8c, 0x92, 0x34, 0x66, 0xe3, 0xe2, 0x39, 0x85, + 0xc4, 0x0f, 0xa6, 0x65, 0x22, 0x1e, 0x44, 0xfa, 0xd8, 0xd6, 0xfe, 0x89, 0xc5, 0x96, 0x24, 0x4e, + 0x7d, 0x06, 0xc5, 0xd4, 0xa3, 0xcd, 0x66, 0x7a, 0xe5, 0x8c, 0x43, 0xd1, 0x19, 0x19, 0x25, 0x77, + 0xb1, 0x77, 0x2e, 0x3c, 0xc8, 0x6c, 0x72, 0x6a, 0xf6, 0x3a, 0x23, 0x53, 0x9f, 0x66, 0xde, 0xf9, + 0xcb, 0x7b, 0x37, 0x66, 0x4e, 0x10, 0x7f, 0xcf, 0xc8, 0xdf, 0x16, 0x74, 0x50, 0x44, 0xfa, 0xf0, + 0x03, 0x1b, 0x2c, 0x33, 0x3a, 0xb4, 0xff, 0x96, 0x87, 0x75, 0x5a, 0xc6, 0xc5, 0x35, 0x5a, 0x7f, + 0x3c, 0xe4, 0xf9, 0xaf, 0xfa, 0x58, 0x5e, 0xb2, 0xb8, 0xd2, 0x4d, 0x7e, 0x1a, 0x51, 0xdc, 0xf8, + 0x72, 0x77, 0xf8, 0x3b, 0xcf, 0x0e, 0x2c, 0x27, 0x4f, 0x5d, 0x92, 0x98, 0xaf, 0xbf, 0x14, 0xbf, + 0x6a, 0x09, 0xda, 0x87, 0xb0, 0x44, 0xab, 0xde, 0x08, 0xfb, 0x9e, 0x91, 0x79, 0x34, 0xaa, 0x49, + 0x74, 0x42, 0x68, 0x86, 0xce, 0x98, 0x56, 0x05, 0x92, 0x90, 0x67, 0x91, 0x35, 0x89, 0x16, 0x84, + 0x4f, 0x60, 0x95, 0x65, 0xb0, 0x81, 0x4f, 0x13, 0xd6, 0x84, 0x2d, 0xaf, 0xa4, 0x57, 0x32, 0x63, + 0x57, 0x4d, 0x11, 0x3f, 0x58, 0xcc, 0xcf, 0x98, 0x72, 0xc4, 0xff, 0xb6, 0xb8, 0x0f, 0x15, 0xa6, + 0xab, 0x76, 0x33, 0xae, 0x15, 0xa9, 0xbe, 0x8d, 0x27, 0xb2, 0x56, 0xa4, 0xd0, 0x13, 0xed, 0x09, + 0x2c, 0x50, 0x32, 0xaa, 0xc3, 0x07, 0x50, 0x88, 0xdc, 0xc9, 0xb5, 0xa9, 0x1a, 0x25, 0xd0, 0xfe, + 0x35, 0xcf, 0xbb, 0x13, 0x6d, 0xef, 0xd4, 0x0f, 0x47, 0xac, 0x93, 0x25, 0x4e, 0x41, 0x54, 0xe9, + 0xb9, 0xa4, 0x4a, 0x7f, 0x9c, 0x8d, 0x56, 0x53, 0xcd, 0x0a, 0x29, 0x9c, 0x34, 0x85, 0x47, 0xb0, + 0x7c, 0xa9, 0xa6, 0x17, 0xda, 0x56, 0xa6, 0x0b, 0x75, 0xf5, 0x3b, 0xa8, 0xd0, 0x34, 0x9f, 0xa5, + 0xfa, 0x34, 0xc5, 0x2c, 0x32, 0xb9, 0x3f, 0xcf, 0xae, 0x70, 0x49, 0xc6, 0x5d, 0x61, 0x33, 0xee, + 0x84, 0xb4, 0xbc, 0x28, 0xbc, 0xd0, 0x81, 0xc4, 0x88, 0xad, 0x1e, 0x2c, 0x4d, 0x0d, 0xcf, 0x68, + 0xd1, 0x3d, 0x4c, 0x67, 0xbe, 0xe5, 0xbd, 0xe5, 0xec, 0x82, 0xb4, 0x96, 0xe1, 0xe3, 0x5f, 0xe5, + 0xbf, 0xcc, 0x69, 0xff, 0x9c, 0x03, 0x85, 0xa2, 0x3b, 0x4f, 0xfb, 0x28, 0x9c, 0x60, 0x0b, 0x51, + 0x35, 0x3d, 0x17, 0x05, 0x4a, 0x92, 0x18, 0x3f, 0xcc, 0x32, 0x49, 0x53, 0xef, 0x66, 0xa4, 0x65, + 0x95, 0x0c, 0x15, 0xf5, 0x10, 0x2a, 0x3f, 0xa6, 0x9c, 0x5f, 0xc0, 0xa2, 0x70, 0x2f, 0xbc, 0xf1, + 0xf5, 0x6e, 0x49, 0xfb, 0x0e, 0x61, 0x8f, 0xfe, 0xe2, 0x19, 0x56, 0x5d, 0x81, 0xa5, 0x4e, 0xdf, + 0xa0, 0xa0, 0x71, 0xdc, 0xfd, 0xb6, 0x7b, 0xf4, 0xaa, 0xab, 0xfc, 0x4c, 0x55, 0xa0, 0x22, 0x91, + 0xdd, 0xa3, 0x66, 0x4b, 0xc9, 0xa5, 0x31, 0x9d, 0x76, 0xf7, 0x5b, 0x25, 0xaf, 0xae, 0xc1, 0xb2, + 0xc4, 0xf4, 0xf4, 0xd6, 0x8b, 0xf6, 0xf7, 0xc6, 0xc9, 0xbe, 0x52, 0x98, 0x85, 0xae, 0x2b, 0xc5, + 0x9d, 0xff, 0x62, 0x4f, 0xc4, 0xc9, 0x4b, 0xac, 0xfa, 0x09, 0xac, 0x74, 0xfa, 0x46, 0x4f, 0x3f, + 0x1a, 0x1c, 0x1d, 0x1c, 0x75, 0x52, 0x6b, 0x4f, 0x0d, 0xb4, 0xfb, 0xed, 0xbe, 0xd1, 0x79, 0xa2, + 0xe4, 0x66, 0x0f, 0xec, 0x29, 0xf9, 0xe9, 0x81, 0xa3, 0x7e, 0xef, 0x85, 0x71, 0xb2, 0xa7, 0x14, + 0xd4, 0x75, 0x50, 0xd3, 0x03, 0xcd, 0xb6, 0xde, 0x3a, 0x18, 0x28, 0xc5, 0x69, 0x7c, 0x7f, 0xd0, + 0x18, 0xb4, 0x0f, 0x94, 0xb9, 0xd9, 0x8c, 0x9e, 0x2a, 0xf3, 0x3b, 0xff, 0x3e, 0xc7, 0x2f, 0x66, + 0x6c, 0xc7, 0x15, 0x28, 0xe9, 0xad, 0x7e, 0x4b, 0x3f, 0x69, 0x35, 0x95, 0x9f, 0xa9, 0x0b, 0x50, + 0x68, 0x75, 0x9b, 0x5c, 0x4b, 0xad, 0x6e, 0xd3, 0x78, 0xd5, 0x1e, 0x7c, 0x63, 0xf4, 0xfa, 0x3d, + 0x25, 0x9f, 0xc1, 0x1c, 0xf7, 0x7b, 0x4a, 0x41, 0x5d, 0x05, 0x25, 0x4d, 0xc3, 0xb0, 0x45, 0xb5, + 0x04, 0xc5, 0x56, 0xb7, 0xf9, 0xbd, 0x32, 0xa7, 0x2e, 0x43, 0x95, 0x7e, 0x25, 0x4c, 0xe6, 0xb3, + 0x28, 0x4a, 0xbf, 0x40, 0xd5, 0x9c, 0xa1, 0x62, 0xe8, 0x92, 0x60, 0x33, 0x50, 0x16, 0xc5, 0x9c, + 0x41, 0xc2, 0x06, 0xb2, 0x28, 0x4a, 0x5f, 0x16, 0x6c, 0x06, 0x59, 0x36, 0x15, 0x41, 0x69, 0x3c, + 0xaf, 0x1b, 0xad, 0xee, 0x41, 0xa3, 0xd7, 0x57, 0x6a, 0x2a, 0xc0, 0x3c, 0x43, 0x1d, 0x2a, 0x4b, + 0x6a, 0x19, 0x16, 0xe8, 0x77, 0xf3, 0xfb, 0xba, 0xa2, 0x24, 0xc0, 0xbe, 0xb2, 0x1c, 0x03, 0x83, + 0xba, 0xa2, 0x26, 0xc0, 0xbe, 0xb2, 0x42, 0x35, 0x26, 0x80, 0xba, 0xb2, 0x9a, 0x4c, 0xda, 0x53, + 0xd6, 0xe2, 0xa1, 0xef, 0xf7, 0x4e, 0x94, 0xf5, 0x84, 0x70, 0xef, 0x58, 0xf9, 0x24, 0x05, 0x1d, + 0x2a, 0x1b, 0x42, 0xdc, 0x44, 0x2e, 0x43, 0x47, 0xb6, 0x72, 0x63, 0x4a, 0xc9, 0x4d, 0xe5, 0xe6, + 0x0c, 0x25, 0x37, 0x95, 0x5b, 0x19, 0xec, 0xb1, 0xc0, 0x7e, 0xaa, 0x6e, 0xc0, 0xea, 0xf4, 0x81, + 0xb0, 0x91, 0xdb, 0xd3, 0x7a, 0x6f, 0x2a, 0x77, 0x66, 0xe9, 0xbd, 0xa9, 0xfc, 0x3c, 0x8b, 0x96, + 0x0c, 0x34, 0x75, 0x13, 0xd6, 0x2e, 0x9d, 0x12, 0x1b, 0xba, 0x3b, 0x7d, 0x18, 0x4d, 0xe5, 0xde, + 0xac, 0xc3, 0x68, 0x2a, 0xf7, 0xb3, 0x68, 0xc9, 0xe0, 0x81, 0xe0, 0x3d, 0xb8, 0xcc, 0xfb, 0xe1, + 0x4e, 0x93, 0x2a, 0x8d, 0xb7, 0x2f, 0x99, 0xa5, 0x8a, 0x84, 0x4a, 0xf9, 0x99, 0xba, 0x08, 0x73, + 0x14, 0x4b, 0xaf, 0x93, 0xf8, 0xa4, 0x17, 0x48, 0x7c, 0x3e, 0x55, 0x0a, 0xf2, 0x73, 0x5f, 0x29, + 0x0e, 0xe7, 0x99, 0xef, 0x78, 0xfa, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x90, 0x3b, 0xff, 0x8b, + 0xd0, 0x32, 0x00, 0x00, } diff --git a/api/attribute.proto b/api/attribute.proto index 409a12d1..94e496c6 100644 --- a/api/attribute.proto +++ b/api/attribute.proto @@ -613,6 +613,10 @@ message TunnelEncapSubTLVSRSegmentList { repeated google.protobuf.Any segments = 2; } +message TunnelEncapSubTLVEgressEndpoint { + string address = 1; +} + message TunnelEncapSubTLVUDPDestPort { uint32 port = 1; } diff --git a/internal/pkg/apiutil/attribute.go b/internal/pkg/apiutil/attribute.go index 0e4eecae..f6003a6a 100644 --- a/internal/pkg/apiutil/attribute.go +++ b/internal/pkg/apiutil/attribute.go @@ -1176,6 +1176,10 @@ 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), @@ -1662,6 +1666,8 @@ 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: diff --git a/pkg/packet/bgp/bgp.go b/pkg/packet/bgp/bgp.go index af0656d3..32649a8e 100644 --- a/pkg/packet/bgp/bgp.go +++ b/pkg/packet/bgp/bgp.go @@ -257,6 +257,7 @@ const ( ENCAP_SUBTLV_TYPE_ENCAPSULATION EncapSubTLVType = 1 ENCAP_SUBTLV_TYPE_PROTOCOL EncapSubTLVType = 2 ENCAP_SUBTLV_TYPE_COLOR EncapSubTLVType = 4 + ENCAP_SUBTLV_TYPE_EGRESS_ENDPOINT EncapSubTLVType = 6 ENCAP_SUBTLV_TYPE_UDP_DEST_PORT EncapSubTLVType = 8 ENCAP_SUBTLV_TYPE_SRPREFERENCE EncapSubTLVType = 12 ENCAP_SUBTLV_TYPE_SRBINDING_SID EncapSubTLVType = 13 @@ -11641,6 +11642,110 @@ func NewTunnelEncapSubTLVColor(color uint32) *TunnelEncapSubTLVColor { } } +type TunnelEncapSubTLVEgressEndpoint struct { + TunnelEncapSubTLV + Address net.IP +} + +// Tunnel Egress Endpoint Sub-TLV subfield positions +const ( + EGRESS_ENDPOINT_RESERVED_POS = 0 + EGRESS_ENDPOINT_FAMILY_POS = 4 + EGRESS_ENDPOINT_ADDRESS_POS = 6 +) + +func (t *TunnelEncapSubTLVEgressEndpoint) DecodeFromBytes(data []byte) error { + value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) + if err != nil { + return err + } + if t.Length < EGRESS_ENDPOINT_ADDRESS_POS { + return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLVEgressEndpoint bytes available") + } + addressFamily := binary.BigEndian.Uint16(value[EGRESS_ENDPOINT_FAMILY_POS : EGRESS_ENDPOINT_FAMILY_POS+2]) + + var addressLen uint16 + switch addressFamily { + case 0: + addressLen = 0 + case AFI_IP: + addressLen = net.IPv4len + case AFI_IP6: + addressLen = net.IPv6len + default: + return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Unsupported address family in TunnelEncapSubTLVEgressEndpoint") + } + if t.Length != EGRESS_ENDPOINT_ADDRESS_POS+addressLen { + return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLVEgressEndpoint address bytes available") + } + t.Address = nil + if addressFamily != 0 { + t.Address = net.IP(value[EGRESS_ENDPOINT_ADDRESS_POS : EGRESS_ENDPOINT_ADDRESS_POS+addressLen]) + } + + return nil +} + +func (t *TunnelEncapSubTLVEgressEndpoint) Serialize() ([]byte, error) { + var length uint32 = EGRESS_ENDPOINT_ADDRESS_POS + var family uint16 + var ip net.IP + if t.Address == nil { + family = 0 + } else if t.Address.To4() != nil { + length += net.IPv4len + family = AFI_IP + ip = t.Address.To4() + } else { + length += net.IPv6len + family = AFI_IP6 + ip = t.Address.To16() + } + buf := make([]byte, length) + binary.BigEndian.PutUint32(buf, 0) + binary.BigEndian.PutUint16(buf[EGRESS_ENDPOINT_FAMILY_POS:], family) + if family != 0 { + copy(buf[EGRESS_ENDPOINT_ADDRESS_POS:], ip) + } + return t.TunnelEncapSubTLV.Serialize(buf) +} + +func (t *TunnelEncapSubTLVEgressEndpoint) String() string { + address := "" + if t.Address != nil { + address = t.Address.String() + } + return fmt.Sprintf("{EgressEndpoint: %s}", address) +} + +func (t *TunnelEncapSubTLVEgressEndpoint) MarshalJSON() ([]byte, error) { + address := "" + if t.Address != nil { + address = t.Address.String() + } + + return json.Marshal(struct { + Type EncapSubTLVType `json:"type"` + Address string `json:"address"` + }{ + Type: t.Type, + Address: address, + }) +} + +func NewTunnelEncapSubTLVEgressEndpoint(address string) *TunnelEncapSubTLVEgressEndpoint { + var ip net.IP = nil + if address != "" { + ip = net.ParseIP(address) + } + return &TunnelEncapSubTLVEgressEndpoint{ + TunnelEncapSubTLV: TunnelEncapSubTLV{ + Type: ENCAP_SUBTLV_TYPE_EGRESS_ENDPOINT, + }, + Address: ip, + } +} + type TunnelEncapSubTLVUDPDestPort struct { TunnelEncapSubTLV UDPDestPort uint16 @@ -11721,6 +11826,8 @@ func (t *TunnelEncapTLV) DecodeFromBytes(data []byte) error { subTlv = &TunnelEncapSubTLVColor{} case ENCAP_SUBTLV_TYPE_UDP_DEST_PORT: subTlv = &TunnelEncapSubTLVUDPDestPort{} + case ENCAP_SUBTLV_TYPE_EGRESS_ENDPOINT: + subTlv = &TunnelEncapSubTLVEgressEndpoint{} case ENCAP_SUBTLV_TYPE_SRPREFERENCE: subTlv = &TunnelEncapSubTLVSRPreference{} case ENCAP_SUBTLV_TYPE_SRBINDING_SID: |