aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/linux-generic/include/odp_packet_dpdk.h8
-rw-r--r--platform/linux-generic/pktio/dpdk.c120
-rw-r--r--platform/linux-generic/pktio/dpdk_parse.c94
3 files changed, 113 insertions, 109 deletions
diff --git a/platform/linux-generic/include/odp_packet_dpdk.h b/platform/linux-generic/include/odp_packet_dpdk.h
index 31d4557e7..020c2b976 100644
--- a/platform/linux-generic/include/odp_packet_dpdk.h
+++ b/platform/linux-generic/include/odp_packet_dpdk.h
@@ -78,16 +78,18 @@ int dpdk_packet_parse_common(packet_parser_t *pkt_hdr,
uint32_t pkt_len,
uint32_t seg_len,
struct rte_mbuf *mbuf,
- int layer);
+ int layer,
+ odp_pktin_config_opt_t pktin_cfg);
static inline int dpdk_packet_parse_layer(odp_packet_hdr_t *pkt_hdr,
struct rte_mbuf *mbuf,
- odp_pktio_parser_layer_t layer)
+ odp_pktio_parser_layer_t layer,
+ odp_pktin_config_opt_t pktin_cfg)
{
uint32_t seg_len = pkt_hdr->buf_hdr.seg[0].len;
void *base = pkt_hdr->buf_hdr.seg[0].data;
return dpdk_packet_parse_common(&pkt_hdr->p, base, pkt_hdr->frame_len,
- seg_len, mbuf, layer);
+ seg_len, mbuf, layer, pktin_cfg);
}
#endif
diff --git a/platform/linux-generic/pktio/dpdk.c b/platform/linux-generic/pktio/dpdk.c
index 6d045ebd4..206a6a458 100644
--- a/platform/linux-generic/pktio/dpdk.c
+++ b/platform/linux-generic/pktio/dpdk.c
@@ -418,73 +418,6 @@ static struct rte_mempool_ops ops_stack = {
MEMPOOL_REGISTER_OPS(ops_stack);
-#define IP4_CSUM_RESULT(m) (m->ol_flags & PKT_RX_IP_CKSUM_MASK)
-#define L4_CSUM_RESULT(m) (m->ol_flags & PKT_RX_L4_CKSUM_MASK)
-#define UDP4_CSUM(_p) (((_odp_udphdr_t *)_odp_packet_l4_ptr(_p, NULL))->chksum)
-
-#define PKTIN_CSUM_BITS 0x1C
-
-static inline int pkt_set_ol_rx(odp_pktin_config_opt_t *pktin_cfg,
- odp_packet_hdr_t *pkt_hdr,
- struct rte_mbuf *mbuf)
-{
- uint64_t packet_csum_result;
-
- if (pktin_cfg->bit.ipv4_chksum &&
- pkt_hdr->p.input_flags.ipv4) {
- packet_csum_result = IP4_CSUM_RESULT(mbuf);
-
- if (packet_csum_result == PKT_RX_IP_CKSUM_GOOD) {
- pkt_hdr->p.input_flags.l3_chksum_done = 1;
- } else if (packet_csum_result != PKT_RX_IP_CKSUM_UNKNOWN) {
- if (pktin_cfg->bit.drop_ipv4_err)
- return -1;
-
- pkt_hdr->p.input_flags.l3_chksum_done = 1;
- pkt_hdr->p.flags.ip_err = 1;
- pkt_hdr->p.flags.l3_chksum_err = 1;
- }
- }
-
- if (pktin_cfg->bit.udp_chksum &&
- pkt_hdr->p.input_flags.udp) {
- packet_csum_result = L4_CSUM_RESULT(mbuf);
-
- if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) {
- pkt_hdr->p.input_flags.l4_chksum_done = 1;
- } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) {
- if (pkt_hdr->p.input_flags.ipv4 &&
- pkt_hdr->p.input_flags.udp &&
- !UDP4_CSUM(packet_handle(pkt_hdr))) {
- pkt_hdr->p.input_flags.l4_chksum_done = 1;
- return 0;
- }
- if (pktin_cfg->bit.drop_udp_err)
- return -1;
-
- pkt_hdr->p.input_flags.l4_chksum_done = 1;
- pkt_hdr->p.flags.udp_err = 1;
- pkt_hdr->p.flags.l4_chksum_err = 1;
- }
- } else if (pktin_cfg->bit.tcp_chksum &&
- pkt_hdr->p.input_flags.tcp) {
- packet_csum_result = L4_CSUM_RESULT(mbuf);
-
- if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) {
- pkt_hdr->p.input_flags.l4_chksum_done = 1;
- } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) {
- if (pktin_cfg->bit.drop_tcp_err)
- return -1;
-
- pkt_hdr->p.input_flags.l4_chksum_done = 1;
- pkt_hdr->p.flags.tcp_err = 1;
- pkt_hdr->p.flags.l4_chksum_err = 1;
- }
- }
-
- return 0;
-}
-
static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
odp_packet_t pkt_table[],
struct rte_mbuf *mbuf_table[],
@@ -499,7 +432,7 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
int nb_pkts = 0;
int alloc_len, num;
odp_pool_t pool = pktio_entry->s.pkt_dpdk.pool;
- odp_pktin_config_opt_t *pktin_cfg = &pktio_entry->s.config.pktin;
+ odp_pktin_config_opt_t pktin_cfg = pktio_entry->s.config.pktin;
odp_proto_layer_t parse_layer = pktio_entry->s.config.parser.layer;
odp_pktio_t input = pktio_entry->s.handle;
@@ -531,9 +464,14 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry)) {
packet_parse_reset(&parsed_hdr);
packet_set_len(&parsed_hdr, pkt_len);
- dpdk_packet_parse_common(&parsed_hdr.p, data,
- pkt_len, pkt_len, mbuf,
- ODP_PROTO_LAYER_ALL);
+ if (dpdk_packet_parse_common(&parsed_hdr.p, data,
+ pkt_len, pkt_len, mbuf,
+ ODP_PROTO_LAYER_ALL,
+ pktin_cfg)) {
+ odp_packet_free(pkt_table[i]);
+ rte_pktmbuf_free(mbuf);
+ continue;
+ }
if (cls_classify_packet(pktio_entry,
(const uint8_t *)data,
pkt_len, pkt_len, &pool,
@@ -553,21 +491,18 @@ static inline int mbuf_to_pkt(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry))
copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
else if (parse_layer != ODP_PROTO_LAYER_NONE)
- dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer);
+ if (dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer,
+ pktin_cfg)) {
+ odp_packet_free(pkt);
+ rte_pktmbuf_free(mbuf);
+ continue;
+ }
if (mbuf->ol_flags & PKT_RX_RSS_HASH)
packet_set_flow_hash(pkt_hdr, mbuf->hash.rss);
packet_set_ts(pkt_hdr, ts);
- if (pktin_cfg->all_bits & PKTIN_CSUM_BITS) {
- if (pkt_set_ol_rx(pktin_cfg, pkt_hdr, mbuf)) {
- odp_packet_free(pkt);
- rte_pktmbuf_free(mbuf);
- continue;
- }
- }
-
pkt_table[nb_pkts++] = pkt;
rte_pktmbuf_free(mbuf);
@@ -756,7 +691,7 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry,
int i;
int nb_pkts = 0;
odp_pool_t pool = pktio_entry->s.pkt_dpdk.pool;
- odp_pktin_config_opt_t *pktin_cfg = &pktio_entry->s.config.pktin;
+ odp_pktin_config_opt_t pktin_cfg = pktio_entry->s.config.pktin;
odp_proto_layer_t parse_layer = pktio_entry->s.config.parser.layer;
odp_pktio_t input = pktio_entry->s.handle;
@@ -781,9 +716,13 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry)) {
packet_parse_reset(&parsed_hdr);
packet_set_len(&parsed_hdr, pkt_len);
- dpdk_packet_parse_common(&parsed_hdr.p, data,
- pkt_len, pkt_len, mbuf,
- ODP_PROTO_LAYER_ALL);
+ if (dpdk_packet_parse_common(&parsed_hdr.p, data,
+ pkt_len, pkt_len, mbuf,
+ ODP_PROTO_LAYER_ALL,
+ pktin_cfg)) {
+ rte_pktmbuf_free(mbuf);
+ continue;
+ }
if (cls_classify_packet(pktio_entry,
(const uint8_t *)data,
pkt_len, pkt_len, &pool,
@@ -804,20 +743,17 @@ static inline int mbuf_to_pkt_zero(pktio_entry_t *pktio_entry,
if (pktio_cls_enabled(pktio_entry))
copy_packet_cls_metadata(&parsed_hdr, pkt_hdr);
else if (parse_layer != ODP_PROTO_LAYER_NONE)
- dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer);
+ if (dpdk_packet_parse_layer(pkt_hdr, mbuf, parse_layer,
+ pktin_cfg)) {
+ rte_pktmbuf_free(mbuf);
+ continue;
+ }
if (mbuf->ol_flags & PKT_RX_RSS_HASH)
packet_set_flow_hash(pkt_hdr, mbuf->hash.rss);
packet_set_ts(pkt_hdr, ts);
- if (pktin_cfg->all_bits & PKTIN_CSUM_BITS) {
- if (pkt_set_ol_rx(pktin_cfg, pkt_hdr, mbuf)) {
- rte_pktmbuf_free(mbuf);
- continue;
- }
- }
-
pkt_table[nb_pkts++] = pkt;
}
diff --git a/platform/linux-generic/pktio/dpdk_parse.c b/platform/linux-generic/pktio/dpdk_parse.c
index 1a388b105..155c68326 100644
--- a/platform/linux-generic/pktio/dpdk_parse.c
+++ b/platform/linux-generic/pktio/dpdk_parse.c
@@ -20,6 +20,9 @@
#include <rte_config.h>
#include <rte_mbuf.h>
+#define IP4_CSUM_RESULT(ol_flags) (ol_flags & PKT_RX_IP_CKSUM_MASK)
+#define L4_CSUM_RESULT(ol_flags) (ol_flags & PKT_RX_L4_CKSUM_MASK)
+
/** Parser helper function for Ethernet packets */
static inline uint16_t dpdk_parse_eth(packet_parser_t *prs,
const uint8_t **parseptr,
@@ -126,7 +129,9 @@ error:
static inline uint8_t dpdk_parse_ipv4(packet_parser_t *prs,
const uint8_t **parseptr,
uint32_t *offset, uint32_t frame_len,
- uint32_t mbuf_packet_type)
+ uint32_t mbuf_packet_type,
+ uint64_t mbuf_ol,
+ uint32_t do_csum)
{
const _odp_ipv4hdr_t *ipv4 = (const _odp_ipv4hdr_t *)*parseptr;
uint32_t dstaddr = _odp_be_to_cpu_32(ipv4->dst_addr);
@@ -147,6 +152,18 @@ static inline uint8_t dpdk_parse_ipv4(packet_parser_t *prs,
*offset += ihl * 4;
*parseptr += ihl * 4;
+ if (do_csum) {
+ uint64_t packet_csum_result = IP4_CSUM_RESULT(mbuf_ol);
+
+ if (packet_csum_result == PKT_RX_IP_CKSUM_GOOD) {
+ prs->input_flags.l3_chksum_done = 1;
+ } else if (packet_csum_result != PKT_RX_IP_CKSUM_UNKNOWN) {
+ prs->input_flags.l3_chksum_done = 1;
+ prs->flags.ip_err = 1;
+ prs->flags.l3_chksum_err = 1;
+ }
+ }
+
if (odp_unlikely(ihl > _ODP_IPV4HDR_IHL_MIN))
prs->input_flags.ipopt = 1;
@@ -252,7 +269,9 @@ static inline uint8_t dpdk_parse_ipv6(packet_parser_t *prs,
* Parser helper function for TCP
*/
static inline void dpdk_parse_tcp(packet_parser_t *prs,
- const uint8_t **parseptr)
+ const uint8_t **parseptr,
+ uint64_t mbuf_ol,
+ uint32_t do_csum)
{
const _odp_tcphdr_t *tcp = (const _odp_tcphdr_t *)*parseptr;
uint32_t len = tcp->hl * 4;
@@ -260,6 +279,18 @@ static inline void dpdk_parse_tcp(packet_parser_t *prs,
if (odp_unlikely(tcp->hl < sizeof(_odp_tcphdr_t) / sizeof(uint32_t)))
prs->flags.tcp_err = 1;
+ if (do_csum) {
+ uint64_t packet_csum_result = L4_CSUM_RESULT(mbuf_ol);
+
+ if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) {
+ prs->input_flags.l4_chksum_done = 1;
+ } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) {
+ prs->input_flags.l4_chksum_done = 1;
+ prs->flags.tcp_err = 1;
+ prs->flags.l4_chksum_err = 1;
+ }
+ }
+
*parseptr += len;
}
@@ -267,7 +298,9 @@ static inline void dpdk_parse_tcp(packet_parser_t *prs,
* Parser helper function for UDP
*/
static inline void dpdk_parse_udp(packet_parser_t *prs,
- const uint8_t **parseptr)
+ const uint8_t **parseptr,
+ uint64_t mbuf_ol,
+ uint32_t do_csum)
{
const _odp_udphdr_t *udp = (const _odp_udphdr_t *)*parseptr;
uint32_t udplen = _odp_be_to_cpu_16(udp->length);
@@ -276,6 +309,22 @@ static inline void dpdk_parse_udp(packet_parser_t *prs,
if (odp_unlikely(udplen < sizeof(_odp_udphdr_t)))
prs->flags.udp_err = 1;
+ if (do_csum) {
+ uint64_t packet_csum_result = L4_CSUM_RESULT(mbuf_ol);
+
+ if (packet_csum_result == PKT_RX_L4_CKSUM_GOOD) {
+ prs->input_flags.l4_chksum_done = 1;
+ } else if (packet_csum_result != PKT_RX_L4_CKSUM_UNKNOWN) {
+ if (prs->input_flags.ipv4 && !udp->chksum) {
+ prs->input_flags.l4_chksum_done = 1;
+ } else {
+ prs->input_flags.l4_chksum_done = 1;
+ prs->flags.udp_err = 1;
+ prs->flags.l4_chksum_err = 1;
+ }
+ }
+ }
+
if (odp_unlikely(ipsec_port == udp->dst_port && udplen > 4)) {
uint32_t val;
@@ -295,14 +344,16 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
uint32_t offset,
uint32_t frame_len, uint32_t seg_len,
int layer, uint16_t ethtype,
- uint32_t mbuf_packet_type)
+ uint32_t mbuf_packet_type,
+ uint64_t mbuf_ol,
+ odp_pktin_config_opt_t pktin_cfg)
{
uint8_t ip_proto;
prs->l3_offset = offset;
if (odp_unlikely(layer <= ODP_PROTO_LAYER_L2))
- return prs->flags.all.error != 0;
+ return 0;
/* Set l3 flag only for known ethtypes */
prs->input_flags.l3 = 1;
@@ -312,8 +363,11 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
case _ODP_ETHTYPE_IPV4:
prs->input_flags.ipv4 = 1;
ip_proto = dpdk_parse_ipv4(prs, &parseptr, &offset, frame_len,
- mbuf_packet_type);
+ mbuf_packet_type, mbuf_ol,
+ pktin_cfg.bit.ipv4_chksum);
prs->l4_offset = offset;
+ if (prs->flags.ip_err && pktin_cfg.bit.drop_ipv4_err)
+ return -1; /* drop */
break;
case _ODP_ETHTYPE_IPV6:
@@ -321,6 +375,8 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
ip_proto = dpdk_parse_ipv6(prs, &parseptr, &offset, frame_len,
seg_len, mbuf_packet_type);
prs->l4_offset = offset;
+ if (prs->flags.ip_err && pktin_cfg.bit.drop_ipv6_err)
+ return -1; /* drop */
break;
case _ODP_ETHTYPE_ARP:
@@ -334,7 +390,7 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
}
if (layer == ODP_PROTO_LAYER_L3)
- return prs->flags.all.error != 0;
+ return 0;
/* Set l4 flag only for known ip_proto */
prs->input_flags.l4 = 1;
@@ -354,16 +410,22 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
case _ODP_IPPROTO_TCP:
if (odp_unlikely(offset + _ODP_TCPHDR_LEN > seg_len))
- return -1;
+ return -1; /* drop */
prs->input_flags.tcp = 1;
- dpdk_parse_tcp(prs, &parseptr);
+ dpdk_parse_tcp(prs, &parseptr, mbuf_ol,
+ pktin_cfg.bit.tcp_chksum);
+ if (prs->flags.tcp_err && pktin_cfg.bit.drop_tcp_err)
+ return -1; /* drop */
break;
case _ODP_IPPROTO_UDP:
if (odp_unlikely(offset + _ODP_UDPHDR_LEN > seg_len))
- return -1;
+ return -1; /* drop */
prs->input_flags.udp = 1;
- dpdk_parse_udp(prs, &parseptr);
+ dpdk_parse_udp(prs, &parseptr, mbuf_ol,
+ pktin_cfg.bit.udp_chksum);
+ if (prs->flags.udp_err && pktin_cfg.bit.drop_udp_err)
+ return -1; /* drop */
break;
case _ODP_IPPROTO_AH:
@@ -389,7 +451,7 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
break;
}
- return prs->flags.all.error != 0;
+ return 0;
}
/**
@@ -397,12 +459,14 @@ int dpdk_packet_parse_common_l3_l4(packet_parser_t *prs,
*/
int dpdk_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
uint32_t frame_len, uint32_t seg_len,
- struct rte_mbuf *mbuf, int layer)
+ struct rte_mbuf *mbuf, int layer,
+ odp_pktin_config_opt_t pktin_cfg)
{
uint32_t offset;
uint16_t ethtype;
const uint8_t *parseptr;
uint32_t mbuf_packet_type;
+ uint64_t mbuf_ol;
parseptr = ptr;
offset = 0;
@@ -411,6 +475,7 @@ int dpdk_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
return 0;
mbuf_packet_type = mbuf->packet_type;
+ mbuf_ol = mbuf->ol_flags;
/* Assume valid L2 header, no CRC/FCS check in SW */
prs->l2_offset = offset;
@@ -420,7 +485,8 @@ int dpdk_packet_parse_common(packet_parser_t *prs, const uint8_t *ptr,
return dpdk_packet_parse_common_l3_l4(prs, parseptr, offset, frame_len,
seg_len, layer, ethtype,
- mbuf_packet_type);
+ mbuf_packet_type, mbuf_ol,
+ pktin_cfg);
}
#endif /* ODP_PKTIO_DPDK */