From 15ae65b5c8de7cabb7e50637506b67bcf1150a94 Mon Sep 17 00:00:00 2001 From: JihoJung Date: Fri, 10 Jan 2025 11:21:20 +0900 Subject: [PATCH 1/3] Fix NewIpEcnField --- openflow15/match.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openflow15/match.go b/openflow15/match.go index af846a4..bb06fa9 100644 --- a/openflow15/match.go +++ b/openflow15/match.go @@ -1382,16 +1382,17 @@ func (m *IpEcnField) UnmarshalBinary(data []byte) (err error) { return } -// Return a MatchField for vlan id matching -func NewIpEcnField(vlanPcp uint8) *MatchField { +// Return a MatchField for ecn matching +func NewIpEcnField(ecn uint8) *MatchField { f := new(MatchField) f.Class = OXM_CLASS_OPENFLOW_BASIC f.Field = OXM_FIELD_IP_ECN f.HasMask = false - vlanPcpField := new(IpEcnField) - f.Value = vlanPcpField - f.Length = uint8(vlanPcpField.Len()) + ecnField := new(IpEcnField) + ecnField.IpEcn = ecn + f.Value = ecnField + f.Length = uint8(ecnField.Len()) return f } From ba63710e07cbab8a33bbc65bc8de55b45b1749a7 Mon Sep 17 00:00:00 2001 From: JihoJung Date: Fri, 10 Jan 2025 11:21:57 +0900 Subject: [PATCH 2/3] Use go 1.22 --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 3299a1b..2b632a8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module antrea.io/libOpenflow -go 1.23.0 +go 1.22 require ( github.com/sirupsen/logrus v1.9.3 From 2aa6ba4c48146bd99fe879067739dfaca4369581 Mon Sep 17 00:00:00 2001 From: JihoJung Date: Fri, 10 Jan 2025 11:40:23 +0900 Subject: [PATCH 3/3] Add NXActionStack for push/pop --- openflow15/action_ext.go | 293 +++++++++++++++++++++++++++++++++++++++ openflow15/nx_action.go | 2 + 2 files changed, 295 insertions(+) create mode 100644 openflow15/action_ext.go diff --git a/openflow15/action_ext.go b/openflow15/action_ext.go new file mode 100644 index 0000000..847249a --- /dev/null +++ b/openflow15/action_ext.go @@ -0,0 +1,293 @@ +package openflow15 + +import ( + "encoding/binary" + "errors" + "fmt" +) + +/* +// Action structure for NXAST_ENCAP +// see more details: openvswitch-2.17.8/include/openvswitch/ofp-ed-props.h + +struct nx_action_encap { + ovs_be16 type; // OFPAT_VENDOR. + ovs_be16 len; // Total size including any property TLVs. + ovs_be32 vendor; // NX_VENDOR_ID. + ovs_be16 subtype; // NXAST_ENCAP. + ovs_be16 hdr_size; // Header size in bytes, 0 = 'not specified'. + ovs_be32 new_pkt_type; // Header type to add and PACKET_TYPE of result. + struct ofp_ed_prop_header props[]; // Encap TLV properties. +}; +OFP_ASSERT(sizeof(struct nx_action_encap) == 16); + +// +// External representation of encap/decap properties. +// These must be padded to a multiple of 8 bytes. +// +struct ofp_ed_prop_header { + ovs_be16 prop_class; + uint8_t type; + uint8_t len; +}; + +struct ofp_ed_prop_nsh_md_type { + struct ofp_ed_prop_header header; + uint8_t md_type; // NSH MD type . + uint8_t pad[3]; // Padding to 8 bytes. +}; + +struct ofp_ed_prop_nsh_tlv { + struct ofp_ed_prop_header header; + ovs_be16 tlv_class; // Metadata class. + uint8_t tlv_type; // Metadata type including C bit. + uint8_t tlv_len; // Metadata value length (0-127). + + // tlv_len octets of metadata value, padded to a multiple of 8 bytes. + uint8_t data[0]; +}; +*/ + +const ( + ENCAP_PKT_TYPE_ETHERNET = 0 + ENCAP_PKT_TYPE_MPLS = 1<<16 | 0x8847 + ENCAP_PKT_TYPE_MPLS_MC = 1<<16 | 0x8848 + ENCAP_PKT_TYPE_NSH = 1<<16 | 0x894f +) + +type NXActionEncap struct { + *NXActionHeader + HeaderSize uint16 + PacketType uint32 +} + +func (a *NXActionEncap) Len() (n uint16) { + return a.Length +} + +func (a *NXActionEncap) MarshalBinary() (data []byte, err error) { + data = make([]byte, int(a.Len())) + var b []byte + n := 0 + + b, err = a.NXActionHeader.MarshalBinary() + copy(data[n:], b) + n += len(b) + + binary.BigEndian.PutUint16(data[n:], a.HeaderSize) + n += 2 + + binary.BigEndian.PutUint32(data[n:], a.PacketType) + n += 4 + + return +} + +func (a *NXActionEncap) UnmarshalBinary(data []byte) error { + return fmt.Errorf("NXActionEncap.UnmarshalBinary is not implemted") +} + +func NewNXActionEncap(pktType uint32) *NXActionEncap { + a := &NXActionEncap{ + NXActionHeader: NewNxActionHeader(NXAST_RAW_ENCAP), + PacketType: pktType, + } + + a.Length = 16 + return a +} + +func NewNXActionDecap(pktType uint32) *NXActionEncap { + a := &NXActionEncap{ + NXActionHeader: NewNxActionHeader(NXAST_RAW_DECAP), + PacketType: pktType, + } + + a.Length = 16 + return a +} + +/* +struct nx_action_stack { + ovs_be16 type; // OFPAT_VENDOR. + ovs_be16 len; // Length is 16. + ovs_be32 vendor; // NX_VENDOR_ID. + ovs_be16 subtype; // NXAST_STACK_PUSH or NXAST_STACK_POP. + ovs_be16 offset; // Bit offset into the field. + // Followed by: + //- OXM/NXM header for field to push or pop (4 or 8 bytes). + // - ovs_be16 'n_bits', the number of bits to extract from the field. + // - Enough 0-bytes to pad out the action to 24 bytes. + + //uint8_t pad[12]; // See above. +}; +*/ + +type NXActionStack struct { + *NXActionHeader + OfsNbits uint16 // Bit offset into the field. + SrcField *MatchField // OXM/NXM header for field to push or pop (4 or 8 bytes) + Nbits uint16 // the number of bits to extract from the field. + zero [6]uint8 // 6 uint8 with all Value as 0, reserved, to 24 bytes +} + +func (a *NXActionStack) Len() (n uint16) { + return a.Length +} + +func (a *NXActionStack) MarshalBinary() (data []byte, err error) { + data = make([]byte, int(a.Len())) + var b []byte + n := 0 + + b, err = a.NXActionHeader.MarshalBinary() + copy(data[n:], b) + n += len(b) + binary.BigEndian.PutUint16(data[n:], a.OfsNbits) + n += 2 + fieldHeaderData := a.SrcField.MarshalHeader() + binary.BigEndian.PutUint32(data[n:], fieldHeaderData) + n += 4 + binary.BigEndian.PutUint16(data[n:], a.Nbits) + n += 2 + copy(data[n:], a.zero[0:]) + n += 6 + + return +} + +func (a *NXActionStack) UnmarshalBinary(data []byte) error { + n := 0 + a.NXActionHeader = new(NXActionHeader) + if err := a.NXActionHeader.UnmarshalBinary(data[n:]); err != nil { + return err + } + n += int(a.NXActionHeader.Len()) + if len(data) < int(a.Len()) { + return errors.New("the []byte is too short to unmarshal a full NXActionStack message") + } + a.OfsNbits = binary.BigEndian.Uint16(data[n:]) + n += 2 + a.SrcField = new(MatchField) + if err := a.SrcField.UnmarshalHeader(data[n : n+4]); err != nil { + err = fmt.Errorf("Failed to unmarshal NXActionStack's SrcField, err=%s, data=%v", err, data[n:n+4]) + return err + } + + n += 4 + a.Nbits = binary.BigEndian.Uint16(data[n:]) + + return nil +} + +func newNXActionStack(act uint16) *NXActionStack { + a := &NXActionStack{ + NXActionHeader: NewNxActionHeader(act), + zero: [6]uint8{}, + } + a.Length = 24 + return a +} + +func NewNXActionStackPush(srcField *MatchField, nBits uint16) *NXActionStack { + a := &NXActionStack{ + NXActionHeader: NewNxActionHeader(NXAST_STACK_PUSH), + zero: [6]uint8{}, + } + a.Length = 24 + a.SrcField = srcField + a.Nbits = nBits + + return a +} + +func NewNXActionStackPop(srcField *MatchField, nBits uint16) *NXActionStack { + a := &NXActionStack{ + NXActionHeader: NewNxActionHeader(NXAST_STACK_POP), + zero: [6]uint8{}, + } + a.Length = 24 + a.SrcField = srcField + a.Nbits = nBits + + return a +} + +type MplsTtlField struct { + Ttl uint8 +} + +func (m *MplsTtlField) Len() uint16 { + return 1 +} + +func (m *MplsTtlField) MarshalBinary() (data []byte, err error) { + data = make([]byte, 1) + data[0] = m.Ttl + return +} + +func (m *MplsTtlField) UnmarshalBinary(data []byte) error { + if len(data) < int(m.Len()) { + return fmt.Errorf("the []byte is too short to unmarshal a full Mpls TtlField message") + } + m.Ttl = data[0] + return nil +} + +// NewMplsTtlField will return a MatchField for mpls ttl +func NewMplsTtlField(ttl uint8) *MatchField { + f := new(MatchField) + f.Class = OXM_CLASS_NXM_1 + f.Field = NXM_NX_MPLS_TTL + f.HasMask = false + + ttlField := new(MplsTtlField) + ttlField.Ttl = ttl + f.Value = ttlField + f.Length = uint8(ttlField.Len()) + + return f +} + +/* +type NXActionCtClear struct { + *NXActionHeader +} + +func (a *NXActionCtClear) Len() (n uint16) { + return a.Length +} + +func (a *NXActionCtClear) MarshalBinary() (data []byte, err error) { + data = make([]byte, int(a.Len())) + var b []byte + n := 0 + + b, err = a.NXActionHeader.MarshalBinary() + copy(data[n:], b) + n += len(b) + + return +} + +func (a *NXActionCtClear) UnmarshalBinary(data []byte) error { + n := 0 + a.NXActionHeader = new(NXActionHeader) + if err := a.NXActionHeader.UnmarshalBinary(data[n:]); err != nil { + return err + } + + return nil +} + +func NewNXActionCtClear() *NXActionCtClear { + a := &NXActionCtClear{ + NXActionHeader: NewNxActionHeader(NXAST_CT_CLEAR), + } + + //a.Length = a.NXActionHeader.Len() + + return a +} +*/ diff --git a/openflow15/nx_action.go b/openflow15/nx_action.go index 55978d8..a492770 100644 --- a/openflow15/nx_action.go +++ b/openflow15/nx_action.go @@ -157,7 +157,9 @@ func DecodeNxAction(data []byte) (Action, error) { case NXAST_SET_MPLS_TTL: case NXAST_DEC_MPLS_TTL: case NXAST_STACK_PUSH: + a = new(NXActionStack) case NXAST_STACK_POP: + a = new(NXActionStack) case NXAST_SAMPLE: case NXAST_SET_MPLS_LABEL: case NXAST_SET_MPLS_TC: