From 4c8ab0d4b5090b5b9ca115bdeb3dd8e1a627f5e2 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sat, 1 Sep 2018 21:51:21 +0000 Subject: support UDP destination port sub-TLV As specified in draft-ietf-idr-tunnel-encaps. Signed-off-by: Mikael Magnusson --- api/attribute.proto | 4 +++ internal/pkg/apiutil/attribute.go | 6 +++++ internal/pkg/apiutil/attribute_test.go | 5 ++++ pkg/packet/bgp/bgp.go | 49 ++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/api/attribute.proto b/api/attribute.proto index 9ed2e6e8..409a12d1 100644 --- a/api/attribute.proto +++ b/api/attribute.proto @@ -613,6 +613,10 @@ message TunnelEncapSubTLVSRSegmentList { repeated google.protobuf.Any segments = 2; } +message TunnelEncapSubTLVUDPDestPort { + uint32 port = 1; +} + message TunnelEncapSubTLVUnknown { uint32 type = 1; bytes value = 2; diff --git a/internal/pkg/apiutil/attribute.go b/internal/pkg/apiutil/attribute.go index f440772b..0e4eecae 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.TunnelEncapSubTLVUDPDestPort: + subTlv = &api.TunnelEncapSubTLVUDPDestPort{ + Port: uint32(sv.UDPDestPort), + } case *bgp.TunnelEncapSubTLVUnknown: subTlv = &api.TunnelEncapSubTLVUnknown{ Type: uint32(sv.Type), @@ -1658,6 +1662,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.TunnelEncapSubTLVUDPDestPort: + subTlv = bgp.NewTunnelEncapSubTLVUDPDestPort(uint16(sv.Port)) case *api.TunnelEncapSubTLVSRPreference: subTlv = bgp.NewTunnelEncapSubTLVSRPreference(sv.Flags, sv.Preference) case *api.TunnelEncapSubTLVSRPriority: diff --git a/internal/pkg/apiutil/attribute_test.go b/internal/pkg/apiutil/attribute_test.go index a3eff1a7..6c694030 100644 --- a/internal/pkg/apiutil/attribute_test.go +++ b/internal/pkg/apiutil/attribute_test.go @@ -1428,6 +1428,11 @@ func Test_TunnelEncapAttribute(t *testing.T) { }) assert.Nil(err) subTlvs = append(subTlvs, a) + a, err = ptypes.MarshalAny(&api.TunnelEncapSubTLVUDPDestPort{ + Port: 400, + }) + assert.Nil(err) + subTlvs = append(subTlvs, a) a, err = ptypes.MarshalAny(&api.TunnelEncapSubTLVUnknown{ Type: 0xff, // Max of uint8 Value: []byte{0x55, 0x66, 0x77, 0x88}, diff --git a/pkg/packet/bgp/bgp.go b/pkg/packet/bgp/bgp.go index 9add140f..263d684a 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_UDP_DEST_PORT EncapSubTLVType = 8 ENCAP_SUBTLV_TYPE_SRPREFERENCE EncapSubTLVType = 12 ENCAP_SUBTLV_TYPE_SRBINDING_SID EncapSubTLVType = 13 ENCAP_SUBTLV_TYPE_SRENLP EncapSubTLVType = 14 @@ -11596,6 +11597,52 @@ func NewTunnelEncapSubTLVColor(color uint32) *TunnelEncapSubTLVColor { } } +type TunnelEncapSubTLVUDPDestPort struct { + TunnelEncapSubTLV + UDPDestPort uint16 +} + +func (t *TunnelEncapSubTLVUDPDestPort) DecodeFromBytes(data []byte) error { + value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) + if err != nil { + return err + } + if t.Length < 2 { + return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLVUDPDestPort bytes available") + } + t.UDPDestPort = binary.BigEndian.Uint16(value[0:2]) + return nil +} + +func (t *TunnelEncapSubTLVUDPDestPort) Serialize() ([]byte, error) { + buf := make([]byte, 2) + binary.BigEndian.PutUint16(buf, t.UDPDestPort) + return t.TunnelEncapSubTLV.Serialize(buf) +} + +func (t *TunnelEncapSubTLVUDPDestPort) String() string { + return fmt.Sprintf("{UDPDestPort: %d}", t.UDPDestPort) +} + +func (t *TunnelEncapSubTLVUDPDestPort) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type EncapSubTLVType `json:"type"` + UDPDestPort uint16 `json:"port"` + }{ + Type: t.Type, + UDPDestPort: t.UDPDestPort, + }) +} + +func NewTunnelEncapSubTLVUDPDestPort(port uint16) *TunnelEncapSubTLVUDPDestPort { + return &TunnelEncapSubTLVUDPDestPort{ + TunnelEncapSubTLV: TunnelEncapSubTLV{ + Type: ENCAP_SUBTLV_TYPE_UDP_DEST_PORT, + }, + UDPDestPort: port, + } +} + type TunnelEncapTLV struct { Type TunnelType Length uint16 @@ -11628,6 +11675,8 @@ func (t *TunnelEncapTLV) DecodeFromBytes(data []byte) error { subTlv = &TunnelEncapSubTLVProtocol{} case ENCAP_SUBTLV_TYPE_COLOR: subTlv = &TunnelEncapSubTLVColor{} + case ENCAP_SUBTLV_TYPE_UDP_DEST_PORT: + subTlv = &TunnelEncapSubTLVUDPDestPort{} case ENCAP_SUBTLV_TYPE_SRPREFERENCE: subTlv = &TunnelEncapSubTLVSRPreference{} case ENCAP_SUBTLV_TYPE_SRBINDING_SID: -- cgit v1.2.3