diff options
author | Zoltan Kiss <zoltan.kiss@linaro.org> | 2016-01-20 16:55:07 +0000 |
---|---|---|
committer | Zoltan Kiss <zoltan.kiss@linaro.org> | 2016-01-25 14:34:25 +0000 |
commit | c986883f6184aa3f22ae28e0b7419ce751fd7bfc (patch) | |
tree | 97982bd5fbb10e16c67f01388baa36274668838a /platform/linux-dpdk | |
parent | 70d52b245128205c5df28209c4fa7b5fb2d7ad18 (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.h | 35 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet.c | 81 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet_flags.c | 6 |
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; } |