diff options
-rw-r--r-- | platform/linux-generic/include/odp_packet_dpdk.h | 8 | ||||
-rw-r--r-- | platform/linux-generic/pktio/dpdk.c | 120 | ||||
-rw-r--r-- | platform/linux-generic/pktio/dpdk_parse.c | 94 |
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 */ |