X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fcsumonly.c;h=7df201e04730e7043f111795e45185108d17ca5f;hb=94b3c1a72507b49df61889f0f237dae85bb49be5;hp=37ed415cee8872be3096770e57a7d6f04bd220fc;hpb=d139cf231ba3eb740929a7c7a9118dfb627434a5;p=dpdk.git diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index 37ed415cee..7df201e047 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -41,8 +40,12 @@ #include #include #include +#ifdef RTE_LIB_GRO #include +#endif +#ifdef RTE_LIB_GSO #include +#endif #include #include "testpmd.h" @@ -69,7 +72,9 @@ uint16_t geneve_udp_port = RTE_GENEVE_DEFAULT_PORT; /* structure that caches offload info for the current packet */ struct testpmd_offload_info { uint16_t ethertype; +#ifdef RTE_LIB_GSO uint8_t gso_enable; +#endif uint16_t l2_len; uint16_t l3_len; uint16_t l4_len; @@ -91,12 +96,13 @@ struct simple_gre_hdr { } __rte_packed; static uint16_t -get_udptcp_checksum(void *l3_hdr, void *l4_hdr, uint16_t ethertype) +get_udptcp_checksum(struct rte_mbuf *m, void *l3_hdr, uint16_t l4_off, + uint16_t ethertype) { if (ethertype == _htons(RTE_ETHER_TYPE_IPV4)) - return rte_ipv4_udptcp_cksum(l3_hdr, l4_hdr); + return rte_ipv4_udptcp_cksum_mbuf(m, l3_hdr, l4_off); else /* assume ethertype == RTE_ETHER_TYPE_IPV6 */ - return rte_ipv6_udptcp_cksum(l3_hdr, l4_hdr); + return rte_ipv6_udptcp_cksum_mbuf(m, l3_hdr, l4_off); } /* Parse an IPv4 header to fill l3_len, l4_len, and l4_proto */ @@ -217,15 +223,14 @@ parse_gtp(struct rte_udp_hdr *udp_hdr, gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr + sizeof(struct rte_udp_hdr)); - + if (gtp_hdr->e || gtp_hdr->s || gtp_hdr->pn) + gtp_len += sizeof(struct rte_gtp_hdr_ext_word); /* * Check message type. If message type is 0xff, it is * a GTP data packet. If not, it is a GTP control packet */ if (gtp_hdr->msg_type == 0xff) { - ip_ver = *(uint8_t *)((char *)udp_hdr + - sizeof(struct rte_udp_hdr) + - sizeof(struct rte_gtp_hdr)); + ip_ver = *(uint8_t *)((char *)gtp_hdr + gtp_len); ip_ver = (ip_ver) & 0xf0; if (ip_ver == RTE_GTP_TYPE_IPV4) { @@ -252,8 +257,7 @@ parse_gtp(struct rte_udp_hdr *udp_hdr, /* Parse a vxlan header */ static void parse_vxlan(struct rte_udp_hdr *udp_hdr, - struct testpmd_offload_info *info, - uint32_t pkt_type) + struct testpmd_offload_info *info) { struct rte_ether_hdr *eth_hdr; @@ -261,8 +265,7 @@ parse_vxlan(struct rte_udp_hdr *udp_hdr, * default vxlan port (rfc7348) or that the rx offload flag is set * (i40e only currently) */ - if (udp_hdr->dst_port != _htons(RTE_VXLAN_DEFAULT_PORT) && - RTE_ETH_IS_TUNNEL_PKT(pkt_type) == 0) + if (udp_hdr->dst_port != _htons(RTE_VXLAN_DEFAULT_PORT)) return; update_tunnel_outer(info); @@ -455,7 +458,7 @@ parse_encap_ip(void *encap_ip, struct testpmd_offload_info *info) * depending on the testpmd command line configuration */ static uint64_t process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, - uint64_t tx_offloads) + uint64_t tx_offloads, struct rte_mbuf *m) { struct rte_ipv4_hdr *ipv4_hdr = l3_hdr; struct rte_udp_hdr *udp_hdr; @@ -463,6 +466,7 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, struct rte_sctp_hdr *sctp_hdr; uint64_t ol_flags = 0; uint32_t max_pkt_len, tso_segsz = 0; + uint16_t l4_off; /* ensure packet is large enough to require tso */ if (!info->is_tunnel) { @@ -480,20 +484,21 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV4)) { ipv4_hdr = l3_hdr; - ipv4_hdr->hdr_checksum = 0; - ol_flags |= PKT_TX_IPV4; + ol_flags |= RTE_MBUF_F_TX_IPV4; if (info->l4_proto == IPPROTO_TCP && tso_segsz) { - ol_flags |= PKT_TX_IP_CKSUM; + ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; } else { - if (tx_offloads & DEV_TX_OFFLOAD_IPV4_CKSUM) - ol_flags |= PKT_TX_IP_CKSUM; - else + if (tx_offloads & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) { + ol_flags |= RTE_MBUF_F_TX_IP_CKSUM; + } else { + ipv4_hdr->hdr_checksum = 0; ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr); + } } } else if (info->ethertype == _htons(RTE_ETHER_TYPE_IPV6)) - ol_flags |= PKT_TX_IPV6; + ol_flags |= RTE_MBUF_F_TX_IPV6; else return 0; /* packet type not supported, nothing to do */ @@ -501,41 +506,56 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, udp_hdr = (struct rte_udp_hdr *)((char *)l3_hdr + info->l3_len); /* do not recalculate udp cksum if it was 0 */ if (udp_hdr->dgram_cksum != 0) { - udp_hdr->dgram_cksum = 0; - if (tx_offloads & DEV_TX_OFFLOAD_UDP_CKSUM) - ol_flags |= PKT_TX_UDP_CKSUM; - else { + if (tx_offloads & RTE_ETH_TX_OFFLOAD_UDP_CKSUM) { + ol_flags |= RTE_MBUF_F_TX_UDP_CKSUM; + } else { + if (info->is_tunnel) + l4_off = info->outer_l2_len + + info->outer_l3_len + + info->l2_len + info->l3_len; + else + l4_off = info->l2_len + info->l3_len; + udp_hdr->dgram_cksum = 0; udp_hdr->dgram_cksum = - get_udptcp_checksum(l3_hdr, udp_hdr, + get_udptcp_checksum(m, l3_hdr, l4_off, info->ethertype); } } +#ifdef RTE_LIB_GSO if (info->gso_enable) - ol_flags |= PKT_TX_UDP_SEG; + ol_flags |= RTE_MBUF_F_TX_UDP_SEG; +#endif } else if (info->l4_proto == IPPROTO_TCP) { tcp_hdr = (struct rte_tcp_hdr *)((char *)l3_hdr + info->l3_len); - tcp_hdr->cksum = 0; if (tso_segsz) - ol_flags |= PKT_TX_TCP_SEG; - else if (tx_offloads & DEV_TX_OFFLOAD_TCP_CKSUM) - ol_flags |= PKT_TX_TCP_CKSUM; - else { + ol_flags |= RTE_MBUF_F_TX_TCP_SEG; + else if (tx_offloads & RTE_ETH_TX_OFFLOAD_TCP_CKSUM) { + ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM; + } else { + if (info->is_tunnel) + l4_off = info->outer_l2_len + info->outer_l3_len + + info->l2_len + info->l3_len; + else + l4_off = info->l2_len + info->l3_len; + tcp_hdr->cksum = 0; tcp_hdr->cksum = - get_udptcp_checksum(l3_hdr, tcp_hdr, + get_udptcp_checksum(m, l3_hdr, l4_off, info->ethertype); } +#ifdef RTE_LIB_GSO if (info->gso_enable) - ol_flags |= PKT_TX_TCP_SEG; + ol_flags |= RTE_MBUF_F_TX_TCP_SEG; +#endif } else if (info->l4_proto == IPPROTO_SCTP) { sctp_hdr = (struct rte_sctp_hdr *) ((char *)l3_hdr + info->l3_len); - sctp_hdr->cksum = 0; /* sctp payload must be a multiple of 4 to be * offloaded */ - if ((tx_offloads & DEV_TX_OFFLOAD_SCTP_CKSUM) && + if ((tx_offloads & RTE_ETH_TX_OFFLOAD_SCTP_CKSUM) && ((ipv4_hdr->total_length & 0x3) == 0)) { - ol_flags |= PKT_TX_SCTP_CKSUM; + ol_flags |= RTE_MBUF_F_TX_SCTP_CKSUM; } else { + sctp_hdr->cksum = 0; /* XXX implement CRC32c, example available in * RFC3309 */ } @@ -547,7 +567,7 @@ process_inner_cksums(void *l3_hdr, const struct testpmd_offload_info *info, /* Calculate the checksum of outer header */ static uint64_t process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info, - uint64_t tx_offloads, int tso_enabled) + uint64_t tx_offloads, int tso_enabled, struct rte_mbuf *m) { struct rte_ipv4_hdr *ipv4_hdr = outer_l3_hdr; struct rte_ipv6_hdr *ipv6_hdr = outer_l3_hdr; @@ -556,14 +576,14 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info, if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4)) { ipv4_hdr->hdr_checksum = 0; - ol_flags |= PKT_TX_OUTER_IPV4; + ol_flags |= RTE_MBUF_F_TX_OUTER_IPV4; - if (tx_offloads & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) - ol_flags |= PKT_TX_OUTER_IP_CKSUM; + if (tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) + ol_flags |= RTE_MBUF_F_TX_OUTER_IP_CKSUM; else ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr); } else - ol_flags |= PKT_TX_OUTER_IPV6; + ol_flags |= RTE_MBUF_F_TX_OUTER_IPV6; if (info->outer_l4_proto != IPPROTO_UDP) return ol_flags; @@ -572,10 +592,10 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info, ((char *)outer_l3_hdr + info->outer_l3_len); if (tso_enabled) - ol_flags |= PKT_TX_TCP_SEG; + ol_flags |= RTE_MBUF_F_TX_TCP_SEG; /* Skip SW outer UDP checksum generation if HW supports it */ - if (tx_offloads & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) { + if (tx_offloads & RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM) { if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4)) udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags); @@ -583,7 +603,7 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info, udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags); - ol_flags |= PKT_TX_OUTER_UDP_CKSUM; + ol_flags |= RTE_MBUF_F_TX_OUTER_UDP_CKSUM; return ol_flags; } @@ -601,12 +621,9 @@ process_outer_cksums(void *outer_l3_hdr, struct testpmd_offload_info *info, /* do not recalculate udp cksum if it was 0 */ if (udp_hdr->dgram_cksum != 0) { udp_hdr->dgram_cksum = 0; - if (info->outer_ethertype == _htons(RTE_ETHER_TYPE_IPV4)) - udp_hdr->dgram_cksum = - rte_ipv4_udptcp_cksum(ipv4_hdr, udp_hdr); - else - udp_hdr->dgram_cksum = - rte_ipv6_udptcp_cksum(ipv6_hdr, udp_hdr); + udp_hdr->dgram_cksum = get_udptcp_checksum(m, outer_l3_hdr, + info->outer_l2_len + info->outer_l3_len, + info->outer_ethertype); } return ol_flags; @@ -696,7 +713,7 @@ pkt_copy_split(const struct rte_mbuf *pkt) mp = current_fwd_lcore()->mbp; if (tx_pkt_split == TX_PKT_SPLIT_RND) - nb_seg = random() % tx_pkt_nb_segs + 1; + nb_seg = rte_rand() % tx_pkt_nb_segs + 1; else nb_seg = tx_pkt_nb_segs; @@ -761,6 +778,28 @@ pkt_copy_split(const struct rte_mbuf *pkt) return md[0]; } +#if defined(RTE_LIB_GRO) || defined(RTE_LIB_GSO) +/* + * Re-calculate IP checksum for merged/fragmented packets. + */ +static void +pkts_ip_csum_recalc(struct rte_mbuf **pkts_burst, const uint16_t nb_pkts, uint64_t tx_offloads) +{ + int i; + struct rte_ipv4_hdr *ipv4_hdr; + for (i = 0; i < nb_pkts; i++) { + if ((pkts_burst[i]->ol_flags & RTE_MBUF_F_TX_IPV4) && + (tx_offloads & RTE_ETH_TX_OFFLOAD_IPV4_CKSUM) == 0) { + ipv4_hdr = rte_pktmbuf_mtod_offset(pkts_burst[i], + struct rte_ipv4_hdr *, + pkts_burst[i]->l2_len); + ipv4_hdr->hdr_checksum = 0; + ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr); + } + } +} +#endif + /* * Receive a burst of packets, and for each packet: * - parse packet, and try to recognize a supported packet type (1) @@ -786,7 +825,7 @@ pkt_copy_split(const struct rte_mbuf *pkt) * * The testpmd command line for this forward engine sets the flags * TESTPMD_TX_OFFLOAD_* in ports[tx_port].tx_ol_flags. They control - * wether a checksum must be calculated in software or in hardware. The + * whether a checksum must be calculated in software or in hardware. The * IP, UDP, TCP and SCTP flags always concern the inner layer. The * OUTER_IP is only useful for tunnel packets. */ @@ -794,16 +833,20 @@ static void pkt_burst_checksum_forward(struct fwd_stream *fs) { struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; +#ifdef RTE_LIB_GSO struct rte_mbuf *gso_segments[GSO_MAX_PKT_BURST]; struct rte_gso_ctx *gso_ctx; +#endif struct rte_mbuf **tx_pkts_burst; struct rte_port *txp; struct rte_mbuf *m, *p; struct rte_ether_hdr *eth_hdr; void *l3_hdr = NULL, *outer_l3_hdr = NULL; /* can be IPv4 or IPv6 */ +#ifdef RTE_LIB_GRO void **gro_ctx; uint16_t gro_pkts_num; uint8_t gro_enable; +#endif uint16_t nb_rx; uint16_t nb_tx; uint16_t nb_prep; @@ -816,8 +859,6 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) uint32_t rx_bad_outer_l4_csum; uint32_t rx_bad_outer_ip_csum; struct testpmd_offload_info info; - uint16_t nb_segments = 0; - int ret; uint64_t start_tsc = 0; @@ -835,15 +876,19 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) rx_bad_l4_csum = 0; rx_bad_outer_l4_csum = 0; rx_bad_outer_ip_csum = 0; +#ifdef RTE_LIB_GRO gro_enable = gro_ports[fs->rx_port].enable; +#endif txp = &ports[fs->tx_port]; tx_offloads = txp->dev_conf.txmode.offloads; memset(&info, 0, sizeof(info)); info.tso_segsz = txp->tso_segsz; info.tunnel_tso_segsz = txp->tunnel_tso_segsz; +#ifdef RTE_LIB_GSO if (gso_ports[fs->tx_port].enable) info.gso_enable = 1; +#endif for (i = 0; i < nb_rx; i++) { if (likely(i < nb_rx - 1)) @@ -854,17 +899,17 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) info.is_tunnel = 0; info.pkt_len = rte_pktmbuf_pkt_len(m); tx_ol_flags = m->ol_flags & - (IND_ATTACHED_MBUF | EXT_ATTACHED_MBUF); + (RTE_MBUF_F_INDIRECT | RTE_MBUF_F_EXTERNAL); rx_ol_flags = m->ol_flags; /* Update the L3/L4 checksum error packet statistics */ - if ((rx_ol_flags & PKT_RX_IP_CKSUM_MASK) == PKT_RX_IP_CKSUM_BAD) + if ((rx_ol_flags & RTE_MBUF_F_RX_IP_CKSUM_MASK) == RTE_MBUF_F_RX_IP_CKSUM_BAD) rx_bad_ip_csum += 1; - if ((rx_ol_flags & PKT_RX_L4_CKSUM_MASK) == PKT_RX_L4_CKSUM_BAD) + if ((rx_ol_flags & RTE_MBUF_F_RX_L4_CKSUM_MASK) == RTE_MBUF_F_RX_L4_CKSUM_BAD) rx_bad_l4_csum += 1; - if (rx_ol_flags & PKT_RX_OUTER_L4_CKSUM_BAD) + if (rx_ol_flags & RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD) rx_bad_outer_l4_csum += 1; - if (rx_ol_flags & PKT_RX_EIP_CKSUM_BAD) + if (rx_ol_flags & RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD) rx_bad_outer_ip_csum += 1; /* step 1: dissect packet, parsing optional vlan, ip4/ip6, vxlan @@ -872,9 +917,9 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); rte_ether_addr_copy(&peer_eth_addrs[fs->peer_addr], - ð_hdr->d_addr); + ð_hdr->dst_addr); rte_ether_addr_copy(&ports[fs->tx_port].eth_addr, - ð_hdr->s_addr); + ð_hdr->src_addr); parse_ethernet(eth_hdr, &info); l3_hdr = (char *)eth_hdr + info.l2_len; @@ -887,28 +932,33 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) ((char *)l3_hdr + info.l3_len); parse_gtp(udp_hdr, &info); if (info.is_tunnel) { - tx_ol_flags |= PKT_TX_TUNNEL_GTP; + tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_GTP; goto tunnel_update; } parse_vxlan_gpe(udp_hdr, &info); if (info.is_tunnel) { tx_ol_flags |= - PKT_TX_TUNNEL_VXLAN_GPE; + RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE; goto tunnel_update; } - parse_vxlan(udp_hdr, &info, - m->packet_type); + parse_vxlan(udp_hdr, &info); if (info.is_tunnel) { tx_ol_flags |= - PKT_TX_TUNNEL_VXLAN; + RTE_MBUF_F_TX_TUNNEL_VXLAN; goto tunnel_update; } parse_geneve(udp_hdr, &info); if (info.is_tunnel) { tx_ol_flags |= - PKT_TX_TUNNEL_GENEVE; + RTE_MBUF_F_TX_TUNNEL_GENEVE; goto tunnel_update; } + /* Always keep last. */ + if (unlikely(RTE_ETH_IS_TUNNEL_PKT( + m->packet_type) != 0)) { + TESTPMD_LOG(DEBUG, "Unknown tunnel packet. UDP dst port: %hu", + udp_hdr->dst_port); + } } else if (info.l4_proto == IPPROTO_GRE) { struct simple_gre_hdr *gre_hdr; @@ -916,14 +966,14 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) ((char *)l3_hdr + info.l3_len); parse_gre(gre_hdr, &info); if (info.is_tunnel) - tx_ol_flags |= PKT_TX_TUNNEL_GRE; + tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_GRE; } else if (info.l4_proto == IPPROTO_IPIP) { void *encap_ip_hdr; encap_ip_hdr = (char *)l3_hdr + info.l3_len; parse_encap_ip(encap_ip_hdr, &info); if (info.is_tunnel) - tx_ol_flags |= PKT_TX_TUNNEL_IPIP; + tx_ol_flags |= RTE_MBUF_F_TX_TUNNEL_IPIP; } } @@ -941,7 +991,7 @@ tunnel_update: /* process checksums of inner headers first */ tx_ol_flags |= process_inner_cksums(l3_hdr, &info, - tx_offloads); + tx_offloads, m); /* Then process outer headers if any. Note that the software * checksum will be wrong if one of the inner checksums is @@ -949,7 +999,8 @@ tunnel_update: if (info.is_tunnel == 1) { tx_ol_flags |= process_outer_cksums(outer_l3_hdr, &info, tx_offloads, - !!(tx_ol_flags & PKT_TX_TCP_SEG)); + !!(tx_ol_flags & RTE_MBUF_F_TX_TCP_SEG), + m); } /* step 3: fill the mbuf meta data (flags and header lengths) */ @@ -958,10 +1009,9 @@ tunnel_update: if (info.is_tunnel == 1) { if (info.tunnel_tso_segsz || (tx_offloads & - DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) || + RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) || (tx_offloads & - DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) || - (tx_ol_flags & PKT_TX_OUTER_IPV6)) { + RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM)) { m->outer_l2_len = info.outer_l2_len; m->outer_l3_len = info.outer_l3_len; m->l2_len = info.l2_len; @@ -1014,7 +1064,7 @@ tunnel_update: "l4_proto=%d l4_len=%d flags=%s\n", info.l2_len, rte_be_to_cpu_16(info.ethertype), info.l3_len, info.l4_proto, info.l4_len, buf); - if (rx_ol_flags & PKT_RX_LRO) + if (rx_ol_flags & RTE_MBUF_F_RX_LRO) printf("rx: m->lro_segsz=%u\n", m->tso_segsz); if (info.is_tunnel == 1) printf("rx: outer_l2_len=%d outer_ethertype=%x " @@ -1022,30 +1072,30 @@ tunnel_update: rte_be_to_cpu_16(info.outer_ethertype), info.outer_l3_len); /* dump tx packet info */ - if ((tx_offloads & (DEV_TX_OFFLOAD_IPV4_CKSUM | - DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM | - DEV_TX_OFFLOAD_SCTP_CKSUM)) || + if ((tx_offloads & (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM | + RTE_ETH_TX_OFFLOAD_UDP_CKSUM | + RTE_ETH_TX_OFFLOAD_TCP_CKSUM | + RTE_ETH_TX_OFFLOAD_SCTP_CKSUM)) || info.tso_segsz != 0) printf("tx: m->l2_len=%d m->l3_len=%d " "m->l4_len=%d\n", m->l2_len, m->l3_len, m->l4_len); if (info.is_tunnel == 1) { if ((tx_offloads & - DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM) || + RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM) || (tx_offloads & - DEV_TX_OFFLOAD_OUTER_UDP_CKSUM) || - (tx_ol_flags & PKT_TX_OUTER_IPV6)) + RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM) || + (tx_ol_flags & RTE_MBUF_F_TX_OUTER_IPV6)) printf("tx: m->outer_l2_len=%d " "m->outer_l3_len=%d\n", m->outer_l2_len, m->outer_l3_len); if (info.tunnel_tso_segsz != 0 && - (m->ol_flags & PKT_TX_TCP_SEG)) + (m->ol_flags & RTE_MBUF_F_TX_TCP_SEG)) printf("tx: m->tso_segsz=%d\n", m->tso_segsz); } else if (info.tso_segsz != 0 && - (m->ol_flags & PKT_TX_TCP_SEG)) + (m->ol_flags & RTE_MBUF_F_TX_TCP_SEG)) printf("tx: m->tso_segsz=%d\n", m->tso_segsz); rte_get_tx_ol_flag_list(m->ol_flags, buf, sizeof(buf)); printf("tx: flags=%s", buf); @@ -1053,6 +1103,7 @@ tunnel_update: } } +#ifdef RTE_LIB_GRO if (unlikely(gro_enable)) { if (gro_flush_cycles == GRO_DEFAULT_FLUSH_CYCLES) { nb_rx = rte_gro_reassemble_burst(pkts_burst, nb_rx, @@ -1073,14 +1124,20 @@ tunnel_update: fs->gro_times = 0; } } + + pkts_ip_csum_recalc(pkts_burst, nb_rx, tx_offloads); } +#endif + +#ifdef RTE_LIB_GSO + if (gso_ports[fs->tx_port].enable != 0) { + uint16_t nb_segments = 0; - if (gso_ports[fs->tx_port].enable == 0) - tx_pkts_burst = pkts_burst; - else { gso_ctx = &(current_fwd_lcore()->gso_ctx); gso_ctx->gso_size = gso_max_segment_size; for (i = 0; i < nb_rx; i++) { + int ret; + ret = rte_gso_segment(pkts_burst[i], gso_ctx, &gso_segments[nb_segments], GSO_MAX_PKT_BURST - nb_segments); @@ -1102,13 +1159,18 @@ tunnel_update: tx_pkts_burst = gso_segments; nb_rx = nb_segments; - } + + pkts_ip_csum_recalc(tx_pkts_burst, nb_rx, tx_offloads); + } else +#endif + tx_pkts_burst = pkts_burst; nb_prep = rte_eth_tx_prepare(fs->tx_port, fs->tx_queue, tx_pkts_burst, nb_rx); if (nb_prep != nb_rx) - printf("Preparing packet burst to transmit failed: %s\n", - rte_strerror(rte_errno)); + fprintf(stderr, + "Preparing packet burst to transmit failed: %s\n", + rte_strerror(rte_errno)); nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, tx_pkts_burst, nb_prep); @@ -1141,9 +1203,22 @@ tunnel_update: get_end_cycles(fs, start_tsc); } +static void +stream_init_checksum_forward(struct fwd_stream *fs) +{ + bool rx_stopped, tx_stopped; + + rx_stopped = ports[fs->rx_port].rxq[fs->rx_queue].state == + RTE_ETH_QUEUE_STATE_STOPPED; + tx_stopped = ports[fs->tx_port].txq[fs->tx_queue].state == + RTE_ETH_QUEUE_STATE_STOPPED; + fs->disabled = rx_stopped || tx_stopped; +} + struct fwd_engine csum_fwd_engine = { .fwd_mode_name = "csum", .port_fwd_begin = NULL, .port_fwd_end = NULL, + .stream_init = stream_init_checksum_forward, .packet_fwd = pkt_burst_checksum_forward, };