aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-dpdk
diff options
context:
space:
mode:
authorZoltan Kiss <zoltan.kiss@linaro.org>2016-01-20 16:55:07 +0000
committerZoltan Kiss <zoltan.kiss@linaro.org>2016-01-25 14:34:25 +0000
commitc986883f6184aa3f22ae28e0b7419ce751fd7bfc (patch)
tree97982bd5fbb10e16c67f01388baa36274668838a /platform/linux-dpdk
parent70d52b245128205c5df28209c4fa7b5fb2d7ad18 (diff)
Port "e6216bc6 linux-generic: pktio: fill in L2 parse results by default"
But don't parse L2 header by default, only on demand. Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org>
Diffstat (limited to 'platform/linux-dpdk')
-rw-r--r--platform/linux-dpdk/include/odp_packet_internal.h35
-rw-r--r--platform/linux-dpdk/odp_packet.c81
-rw-r--r--platform/linux-dpdk/odp_packet_flags.c6
3 files changed, 88 insertions, 34 deletions
diff --git a/platform/linux-dpdk/include/odp_packet_internal.h b/platform/linux-dpdk/include/odp_packet_internal.h
index 648c6ea75..48a736c63 100644
--- a/platform/linux-dpdk/include/odp_packet_internal.h
+++ b/platform/linux-dpdk/include/odp_packet_internal.h
@@ -39,7 +39,8 @@ typedef union {
uint32_t all;
struct {
- uint32_t unparsed:1; /**< Set to inticate parse needed */
+ uint32_t parsed_l2:1; /**< L2 parsed */
+ uint32_t parsed_all:1;/**< Parsing complete */
uint32_t l2:1; /**< known L2 protocol present */
uint32_t l3:1; /**< known L3 protocol present */
@@ -153,12 +154,11 @@ static inline odp_packet_hdr_t *odp_packet_hdr(odp_packet_t pkt)
*/
void odp_packet_parse(odp_packet_t pkt, size_t len, size_t l2_offset);
-#define ODP_PACKET_UNPARSED ~0
-
static inline void _odp_packet_reset_parse(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- pkt_hdr->input_flags.all = ODP_PACKET_UNPARSED;
+ pkt_hdr->input_flags.parsed_l2 = 0;
+ pkt_hdr->input_flags.parsed_all = 0;
}
static inline void copy_packet_parser_metadata(odp_packet_hdr_t *src_hdr,
@@ -186,8 +186,35 @@ int _odp_packet_copy_to_packet(odp_packet_t srcpkt, uint32_t srcoffset,
odp_packet_t dstpkt, uint32_t dstoffset,
uint32_t len);
+static inline int packet_parse_l2_not_done(odp_packet_hdr_t *pkt_hdr)
+{
+ return !pkt_hdr->input_flags.parsed_l2;
+}
+
+static inline int packet_parse_not_complete(odp_packet_hdr_t *pkt_hdr)
+{
+ return !pkt_hdr->input_flags.parsed_all;
+}
+
int _odp_packet_parse(odp_packet_hdr_t *pkt_hdr);
+/* Fill in parser metadata for L2 */
+void packet_parse_l2(odp_packet_hdr_t *pkt_hdr);
+
+/* Perform full packet parse */
+static inline int packet_parse_full(odp_packet_hdr_t *pkt_hdr)
+{
+ return _odp_packet_parse(pkt_hdr);
+}
+
+static inline uint32_t packet_hdr_len(odp_packet_hdr_t* pkt_hdr)
+{
+ return rte_pktmbuf_pkt_len(&pkt_hdr->buf_hdr.mb);
+}
+
+/* Reset parser metadata for a new parse */
+void packet_parse_reset(odp_packet_hdr_t *pkt_hdr);
+
void _odp_packet_copy_md_to_packet(odp_packet_t srcpkt, odp_packet_t dstpkt);
/* Convert a packet handle to a buffer handle */
diff --git a/platform/linux-dpdk/odp_packet.c b/platform/linux-dpdk/odp_packet.c
index 5b7490bb1..44bbbff5b 100644
--- a/platform/linux-dpdk/odp_packet.c
+++ b/platform/linux-dpdk/odp_packet.c
@@ -71,6 +71,22 @@ odp_buffer_t _odp_packet_to_buffer(odp_packet_t pkt)
return (odp_buffer_t)pkt;
}
+void packet_parse_reset(odp_packet_hdr_t *pkt_hdr)
+{
+ /* Reset parser metadata before new parse */
+ pkt_hdr->error_flags.all = 0;
+ pkt_hdr->input_flags.all = 0;
+ pkt_hdr->output_flags.all = 0;
+ pkt_hdr->l2_offset = 0;
+ pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
+ pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
+ pkt_hdr->payload_offset = ODP_PACKET_OFFSET_INVALID;
+ pkt_hdr->vlan_s_tag = 0;
+ pkt_hdr->vlan_c_tag = 0;
+ pkt_hdr->l3_protocol = 0;
+ pkt_hdr->l4_protocol = 0;
+}
+
static odp_packet_t packet_alloc(pool_entry_t* pool, uint32_t len)
{
odp_packet_t pkt;
@@ -298,13 +314,16 @@ static inline void *packet_offset_to_ptr(odp_packet_t pkt, uint32_t *len,
void *odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
{
const size_t offset = odp_packet_l2_offset(pkt);
+ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+ if (packet_parse_not_complete(pkt_hdr))
+ _odp_packet_parse(pkt_hdr);
return packet_offset_to_ptr(pkt, len, offset);
}
uint32_t odp_packet_l2_offset(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
return pkt_hdr->l2_offset;
}
@@ -314,7 +333,7 @@ int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1)))
return -1;
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
pkt_hdr->l2_offset = offset;
return 0;
@@ -323,6 +342,9 @@ int odp_packet_l2_offset_set(odp_packet_t pkt, uint32_t offset)
void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
{
const size_t offset = odp_packet_l3_offset(pkt);
+ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+ if (packet_parse_not_complete(pkt_hdr))
+ _odp_packet_parse(pkt_hdr);
return packet_offset_to_ptr(pkt, len, offset);
}
@@ -330,7 +352,7 @@ void *odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
uint32_t odp_packet_l3_offset(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
return pkt_hdr->l3_offset;
}
@@ -340,7 +362,7 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1)))
return -1;
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
pkt_hdr->l3_offset = offset;
return 0;
@@ -349,6 +371,9 @@ int odp_packet_l3_offset_set(odp_packet_t pkt, uint32_t offset)
void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
{
const size_t offset = odp_packet_l4_offset(pkt);
+ odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
+ if (packet_parse_not_complete(pkt_hdr))
+ _odp_packet_parse(pkt_hdr);
return packet_offset_to_ptr(pkt, len, offset);
}
@@ -356,7 +381,7 @@ void *odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
uint32_t odp_packet_l4_offset(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
return pkt_hdr->l4_offset;
}
@@ -366,7 +391,7 @@ int odp_packet_l4_offset_set(odp_packet_t pkt, uint32_t offset)
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
if (odp_unlikely(offset >= (odp_packet_len(pkt) - 1)))
return -1;
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
pkt_hdr->l4_offset = offset;
return 0;
@@ -636,6 +661,25 @@ static inline void parse_udp(odp_packet_hdr_t *pkt_hdr,
*parseptr += sizeof(odph_udphdr_t);
}
+/**
+ * Initialize L2 related parser flags and metadata
+ */
+void packet_parse_l2(odp_packet_hdr_t *pkt_hdr)
+{
+ /* Packet alloc or reset have already init other offsets and flags */
+
+ /* We only support Ethernet for now */
+ pkt_hdr->input_flags.eth = 1;
+
+ /* Detect jumbo frames */
+ if (odp_packet_len((odp_packet_t)pkt_hdr) > ODPH_ETH_LEN_MAX)
+ pkt_hdr->input_flags.jumbo = 1;
+
+ /* Assume valid L2 header, no CRC/FCS check in SW */
+ pkt_hdr->input_flags.l2 = 1;
+
+ pkt_hdr->input_flags.parsed_l2 = 1;
+}
/**
* Simple packet parser: eth, VLAN, IP, TCP/UDP/ICMP
@@ -658,28 +702,10 @@ int _odp_packet_parse(odp_packet_hdr_t *pkt_hdr)
uint32_t len = pkt_hdr->buf_hdr.mb.pkt_len;
odp_packet_t pkt = (odp_packet_t)pkt_hdr;
- /* Reset parser metadata for new parse */
- pkt_hdr->error_flags.all = 0;
- pkt_hdr->input_flags.all = 0;
- pkt_hdr->output_flags.all = 0;
- pkt_hdr->l2_offset = 0;
- pkt_hdr->l3_offset = ODP_PACKET_OFFSET_INVALID;
- pkt_hdr->l4_offset = ODP_PACKET_OFFSET_INVALID;
- pkt_hdr->payload_offset = ODP_PACKET_OFFSET_INVALID;
- pkt_hdr->vlan_s_tag = 0;
- pkt_hdr->vlan_c_tag = 0;
- pkt_hdr->l3_protocol = 0;
- pkt_hdr->l4_protocol = 0;
-
- /* We only support Ethernet for now */
- pkt_hdr->input_flags.eth = 1;
-
- /* Detect jumbo frames */
- if (len > ODPH_ETH_LEN_MAX)
- pkt_hdr->input_flags.jumbo = 1;
+ packet_parse_reset(pkt_hdr);
- /* Assume valid L2 header, no CRC/FCS check in SW */
- pkt_hdr->input_flags.l2 = 1;
+ if (packet_parse_l2_not_done(pkt_hdr))
+ packet_parse_l2(pkt_hdr);
eth = (odph_ethhdr_t *)odp_packet_data(pkt);
offset = sizeof(odph_ethhdr_t);
@@ -793,6 +819,7 @@ int _odp_packet_parse(odp_packet_hdr_t *pkt_hdr)
pkt_hdr->payload_offset = offset;
parse_exit:
+ pkt_hdr->input_flags.parsed_all = 1;
return pkt_hdr->error_flags.all != 0;
}
diff --git a/platform/linux-dpdk/odp_packet_flags.c b/platform/linux-dpdk/odp_packet_flags.c
index 4f680a13d..83a4006e5 100644
--- a/platform/linux-dpdk/odp_packet_flags.c
+++ b/platform/linux-dpdk/odp_packet_flags.c
@@ -9,14 +9,14 @@
#define retflag(p, x) do { \
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
- if (pkt_hdr->input_flags.unparsed) \
+ if (packet_parse_not_complete(pkt_hdr)) \
_odp_packet_parse(pkt_hdr); \
return pkt_hdr->x; \
} while (0)
#define setflag(p, x, v) do { \
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(p); \
- if (pkt_hdr->input_flags.unparsed) \
+ if (packet_parse_not_complete(pkt_hdr)) \
_odp_packet_parse(pkt_hdr); \
pkt_hdr->x = v & 1; \
} while (0)
@@ -24,7 +24,7 @@
int odp_packet_has_error(odp_packet_t pkt)
{
odp_packet_hdr_t *pkt_hdr = odp_packet_hdr(pkt);
- if (pkt_hdr->input_flags.unparsed)
+ if (packet_parse_not_complete(pkt_hdr))
_odp_packet_parse(pkt_hdr);
return odp_packet_hdr(pkt)->error_flags.all != 0;
}