/*
* Packet Offload Features Flags. It also carry packet type information.
* Critical resources. Both rx/tx shared these bits. Be cautious on any change
+ *
+ * - RX flags start at bit position zero, and get added to the left of previous
+ * flags.
+ * - The most-significant 8 bits are reserved for generic mbuf flags
+ * - TX flags therefore start at bit position 55 (i.e. 63-8), and new flags get
+ * added to the right of the previously defined flags
*/
-#define PKT_RX_VLAN_PKT 0x0001 /**< RX packet is a 802.1q VLAN packet. */
-#define PKT_RX_RSS_HASH 0x0002 /**< RX packet with RSS hash result. */
-#define PKT_RX_FDIR 0x0004 /**< RX packet with FDIR infos. */
-#define PKT_RX_L4_CKSUM_BAD 0x0008 /**< L4 cksum of RX pkt. is not OK. */
-#define PKT_RX_IP_CKSUM_BAD 0x0010 /**< IP cksum of RX pkt. is not OK. */
-#define PKT_RX_EIP_CKSUM_BAD 0x0000 /**< External IP header checksum error. */
-#define PKT_RX_OVERSIZE 0x0000 /**< Num of desc of an RX pkt oversize. */
-#define PKT_RX_HBUF_OVERFLOW 0x0000 /**< Header buffer overflow. */
-#define PKT_RX_RECIP_ERR 0x0000 /**< Hardware processing error. */
-#define PKT_RX_MAC_ERR 0x0000 /**< MAC error. */
-#define PKT_RX_IPV4_HDR 0x0020 /**< RX packet with IPv4 header. */
-#define PKT_RX_IPV4_HDR_EXT 0x0040 /**< RX packet with extended IPv4 header. */
-#define PKT_RX_IPV6_HDR 0x0080 /**< RX packet with IPv6 header. */
-#define PKT_RX_IPV6_HDR_EXT 0x0100 /**< RX packet with extended IPv6 header. */
-#define PKT_RX_IEEE1588_PTP 0x0200 /**< RX IEEE1588 L2 Ethernet PT Packet. */
-#define PKT_RX_IEEE1588_TMST 0x0400 /**< RX IEEE1588 L2/L4 timestamped packet.*/
-
-#define PKT_TX_VLAN_PKT 0x0800 /**< TX packet is a 802.1q VLAN packet. */
-#define PKT_TX_IP_CKSUM 0x1000 /**< IP cksum of TX pkt. computed by NIC. */
-#define PKT_TX_IPV4_CSUM 0x1000 /**< Alias of PKT_TX_IP_CKSUM. */
-#define PKT_TX_IPV4 PKT_RX_IPV4_HDR /**< IPv4 with no IP checksum offload. */
-#define PKT_TX_IPV6 PKT_RX_IPV6_HDR /**< IPv6 packet */
-/*
- * Bit 14~13 used for L4 packet type with checksum enabled.
- * 00: Reserved
- * 01: TCP checksum
- * 10: SCTP checksum
- * 11: UDP checksum
+#define PKT_RX_VLAN_PKT (1ULL << 0) /**< RX packet is a 802.1q VLAN packet. */
+#define PKT_RX_RSS_HASH (1ULL << 1) /**< RX packet with RSS hash result. */
+#define PKT_RX_FDIR (1ULL << 2) /**< RX packet with FDIR match indicate. */
+#define PKT_RX_L4_CKSUM_BAD (1ULL << 3) /**< L4 cksum of RX pkt. is not OK. */
+#define PKT_RX_IP_CKSUM_BAD (1ULL << 4) /**< IP cksum of RX pkt. is not OK. */
+#define PKT_RX_EIP_CKSUM_BAD (0ULL << 0) /**< External IP header checksum error. */
+#define PKT_RX_OVERSIZE (0ULL << 0) /**< Num of desc of an RX pkt oversize. */
+#define PKT_RX_HBUF_OVERFLOW (0ULL << 0) /**< Header buffer overflow. */
+#define PKT_RX_RECIP_ERR (0ULL << 0) /**< Hardware processing error. */
+#define PKT_RX_MAC_ERR (0ULL << 0) /**< MAC error. */
+#define PKT_RX_IPV4_HDR (1ULL << 5) /**< RX packet with IPv4 header. */
+#define PKT_RX_IPV4_HDR_EXT (1ULL << 6) /**< RX packet with extended IPv4 header. */
+#define PKT_RX_IPV6_HDR (1ULL << 7) /**< RX packet with IPv6 header. */
+#define PKT_RX_IPV6_HDR_EXT (1ULL << 8) /**< RX packet with extended IPv6 header. */
+#define PKT_RX_IEEE1588_PTP (1ULL << 9) /**< RX IEEE1588 L2 Ethernet PT Packet. */
+#define PKT_RX_IEEE1588_TMST (1ULL << 10) /**< RX IEEE1588 L2/L4 timestamped packet.*/
+#define PKT_RX_TUNNEL_IPV4_HDR (1ULL << 11) /**< RX tunnel packet with IPv4 header.*/
+#define PKT_RX_TUNNEL_IPV6_HDR (1ULL << 12) /**< RX tunnel packet with IPv6 header. */
+#define PKT_RX_FDIR_ID (1ULL << 13) /**< FD id reported if FDIR match. */
+#define PKT_RX_FDIR_FLX (1ULL << 14) /**< Flexible bytes reported if FDIR match. */
+/* add new RX flags here */
+
+/* add new TX flags here */
+#define PKT_TX_VXLAN_CKSUM (1ULL << 50) /**< TX checksum of VXLAN computed by NIC */
+#define PKT_TX_IEEE1588_TMST (1ULL << 51) /**< TX IEEE1588 packet to timestamp. */
+
+/**
+ * Bits 52+53 used for L4 packet type with checksum enabled: 00: Reserved,
+ * 01: TCP checksum, 10: SCTP checksum, 11: UDP checksum. To use hardware
+ * L4 checksum offload, the user needs to:
+ * - fill l2_len and l3_len in mbuf
+ * - set the flags PKT_TX_TCP_CKSUM, PKT_TX_SCTP_CKSUM or PKT_TX_UDP_CKSUM
+ * - set the flag PKT_TX_IPV4 or PKT_TX_IPV6
+ * - calculate the pseudo header checksum and set it in the L4 header (only
+ * for TCP or UDP). For SCTP, set the crc field to 0.
*/
-#define PKT_TX_L4_MASK 0x6000 /**< Mask bits for L4 checksum offload request. */
-#define PKT_TX_L4_NO_CKSUM 0x0000 /**< Disable L4 cksum of TX pkt. */
-#define PKT_TX_TCP_CKSUM 0x2000 /**< TCP cksum of TX pkt. computed by NIC. */
-#define PKT_TX_SCTP_CKSUM 0x4000 /**< SCTP cksum of TX pkt. computed by NIC. */
-#define PKT_TX_UDP_CKSUM 0x6000 /**< UDP cksum of TX pkt. computed by NIC. */
-/* Bit 15 */
-#define PKT_TX_IEEE1588_TMST 0x8000 /**< TX IEEE1588 packet to timestamp. */
+#define PKT_TX_L4_NO_CKSUM (0ULL << 52) /**< Disable L4 cksum of TX pkt. */
+#define PKT_TX_TCP_CKSUM (1ULL << 52) /**< TCP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_SCTP_CKSUM (2ULL << 52) /**< SCTP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_UDP_CKSUM (3ULL << 52) /**< UDP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_L4_MASK (3ULL << 52) /**< Mask for L4 cksum offload request. */
+
+#define PKT_TX_IP_CKSUM (1ULL << 54) /**< IP cksum of TX pkt. computed by NIC. */
+#define PKT_TX_IPV4_CSUM PKT_TX_IP_CKSUM /**< Alias of PKT_TX_IP_CKSUM. */
+
+/** Tell the NIC it's an IPv4 packet. Required for L4 checksum offload. */
+#define PKT_TX_IPV4 PKT_RX_IPV4_HDR
+
+/** Tell the NIC it's an IPv6 packet. Required for L4 checksum offload. */
+#define PKT_TX_IPV6 PKT_RX_IPV6_HDR
+
+#define PKT_TX_VLAN_PKT (1ULL << 55) /**< TX packet is a 802.1q VLAN packet. */
+
+/* Use final bit of flags to indicate a control mbuf */
+#define CTRL_MBUF_FLAG (1ULL << 63) /**< Mbuf contains control data */
/**
* Bit Mask to indicate what bits required for building TX context
*/
#define PKT_TX_OFFLOAD_MASK (PKT_TX_VLAN_PKT | PKT_TX_IP_CKSUM | PKT_TX_L4_MASK)
+/* define a set of marker types that can be used to refer to set points in the
+ * mbuf */
+typedef void *MARKER[0]; /**< generic marker for a point in a structure */
+typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
+ * with a single assignment */
/**
* The generic rte_mbuf, containing a packet mbuf.
*/
struct rte_mbuf {
- struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+ MARKER cacheline0;
+
void *buf_addr; /**< Virtual address of segment buffer. */
phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */
- uint16_t buf_len; /**< Length of segment buffer. */
- /* valid for any segment */
- struct rte_mbuf *next; /**< Next segment of scattered packet. */
+ /* next 8 bytes are initialised on RX descriptor rearm */
+ MARKER64 rearm_data;
+ uint16_t buf_len; /**< Length of segment buffer. */
uint16_t data_off;
- uint16_t data_len; /**< Amount of data in segment buffer. */
- uint32_t pkt_len; /**< Total pkt len: sum of all segments. */
-#ifdef RTE_MBUF_REFCNT
/**
* 16-bit Reference counter.
* It should only be accessed using the following functions:
* config option.
*/
union {
- rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */
- uint16_t refcnt; /**< Non-atomically accessed refcnt */
- };
-#else
- uint16_t refcnt_reserved; /**< Do not use this field */
+#ifdef RTE_MBUF_REFCNT
+ rte_atomic16_t refcnt_atomic; /**< Atomically accessed refcnt */
+ uint16_t refcnt; /**< Non-atomically accessed refcnt */
#endif
- uint16_t reserved; /**< Unused field. Required for padding */
- uint16_t ol_flags; /**< Offload features. */
+ uint16_t refcnt_reserved; /**< Do not use this field */
+ };
+ uint8_t nb_segs; /**< Number of segments. */
+ uint8_t port; /**< Input port. */
+
+ uint64_t ol_flags; /**< Offload features. */
+
+ /* remaining bytes are set on RX when pulling packet from descriptor */
+ MARKER rx_descriptor_fields1;
+
+ /**
+ * The packet type, which is used to indicate ordinary packet and also
+ * tunneled packet format, i.e. each number is represented a type of
+ * packet.
+ */
+ uint16_t packet_type;
- /* these fields are valid for first segment only */
- uint8_t nb_segs; /**< Number of segments. */
- uint8_t port; /**< Input port. */
+ uint16_t data_len; /**< Amount of data in segment buffer. */
+ uint32_t pkt_len; /**< Total pkt len: sum of all segments. */
+ uint16_t vlan_tci; /**< VLAN Tag Control Identifier (CPU order) */
+ uint16_t reserved;
+ union {
+ uint32_t rss; /**< RSS hash result if RSS enabled */
+ struct {
+ union {
+ struct {
+ uint16_t hash;
+ uint16_t id;
+ };
+ uint32_t lo;
+ /**< Second 4 flexible bytes */
+ };
+ uint32_t hi;
+ /**< First 4 flexible bytes or FD ID, dependent on
+ PKT_RX_FDIR_* flag in ol_flags. */
+ } fdir; /**< Filter identifier if FDIR enabled */
+ uint32_t sched; /**< Hierarchical scheduler */
+ uint32_t usr; /**< User defined tags. See @rte_distributor_process */
+ } hash; /**< hash information */
+
+ /* second cache line - fields only used in slow path or on TX */
+ MARKER cacheline1 __rte_cache_aligned;
- /* offload features, valid for first segment only */
+ union {
+ void *userdata; /**< Can be used for external metadata */
+ uint64_t udata64; /**< Allow 8-byte userdata on 32-bit */
+ };
+
+ struct rte_mempool *pool; /**< Pool from which mbuf was allocated. */
+ struct rte_mbuf *next; /**< Next segment of scattered packet. */
+
+ /* fields to support TX offloads */
union {
uint16_t l2_l3_len; /**< combined l2/l3 lengths as single var */
struct {
uint16_t l2_len:7; /**< L2 (MAC) Header Length. */
};
};
- uint16_t vlan_tci; /**< VLAN Tag Control Identifier (CPU order). */
- union {
- uint32_t rss; /**< RSS hash result if RSS enabled */
- struct {
- uint16_t hash;
- uint16_t id;
- } fdir; /**< Filter identifier if FDIR enabled */
- uint32_t sched; /**< Hierarchical scheduler */
- } hash; /**< hash information */
+ /* fields for TX offloading of tunnels */
union {
- uint8_t metadata[0];
- uint16_t metadata16[0];
- uint32_t metadata32[0];
- uint64_t metadata64[0];
- } __rte_cache_aligned;
+ uint16_t inner_l2_l3_len;
+ /**< combined inner l2/l3 lengths as single var */
+ struct {
+ uint16_t inner_l3_len:9;
+ /**< inner L3 (IP) Header Length. */
+ uint16_t inner_l2_len:7;
+ /**< inner L2 (MAC) Header Length. */
+ };
+ };
} __rte_cache_aligned;
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset) \
- (mbuf->metadata[offset])
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset) \
- (mbuf->metadata16[offset/sizeof(uint16_t)])
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset) \
- (mbuf->metadata32[offset/sizeof(uint32_t)])
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset) \
- (mbuf->metadata64[offset/sizeof(uint64_t)])
-
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
- (&mbuf->metadata[offset])
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset) \
- (&mbuf->metadata16[offset/sizeof(uint16_t)])
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset) \
- (&mbuf->metadata32[offset/sizeof(uint32_t)])
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset) \
- (&mbuf->metadata64[offset/sizeof(uint64_t)])
-
/**
* Given the buf_addr returns the pointer to corresponding mbuf.
*/
*/
#define rte_ctrlmbuf_len(m) rte_pktmbuf_data_len(m)
+/**
+ * Tests if an mbuf is a control mbuf
+ *
+ * @param m
+ * The mbuf to be tested
+ * @return
+ * - True (1) if the mbuf is a control mbuf
+ * - False(0) otherwise
+ */
+static inline int
+rte_is_ctrlmbuf(struct rte_mbuf *m)
+{
+ return (!!(m->ol_flags & CTRL_MBUF_FLAG));
+}
+
/* Operations on pkt mbuf */
/**
m->next = NULL;
m->pkt_len = 0;
m->l2_l3_len = 0;
+ m->inner_l2_l3_len = 0;
m->vlan_tci = 0;
m->nb_segs = 1;
m->port = 0xff;
m->ol_flags = 0;
+ m->packet_type = 0;
m->data_off = (RTE_PKTMBUF_HEADROOM <= m->buf_len) ?
RTE_PKTMBUF_HEADROOM : m->buf_len;
mi->port = md->port;
mi->vlan_tci = md->vlan_tci;
mi->l2_l3_len = md->l2_l3_len;
+ mi->inner_l2_l3_len = md->inner_l2_l3_len;
mi->hash = md->hash;
mi->next = NULL;
mi->pkt_len = mi->data_len;
mi->nb_segs = 1;
mi->ol_flags = md->ol_flags;
+ mi->packet_type = md->packet_type;
__rte_mbuf_sanity_check(mi, 1);
__rte_mbuf_sanity_check(md, 0);
static inline void __attribute__((always_inline))
rte_pktmbuf_free_seg(struct rte_mbuf *m)
{
- if (likely(NULL != (m = __rte_pktmbuf_prefree_seg(m))))
+ if (likely(NULL != (m = __rte_pktmbuf_prefree_seg(m)))) {
+ m->next = NULL;
__rte_mbuf_raw_free(m);
+ }
}
/**