X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fcsumonly.c;h=0177284d9cb416bc4d9b7cbec13636dd4c539560;hb=c8557ed434213fe11ecd867819823ea6865311d2;hp=25091de88114b54342ad64fceee0bbe4be1f7250;hpb=5fde1a75926bad69b430ce9d7e4da4e2447e1cb6;p=dpdk.git diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index 25091de881..0177284d9c 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,13 @@ #include #include #include +#ifdef RTE_LIB_GRO #include +#endif +#ifdef RTE_LIB_GSO #include +#endif +#include #include "testpmd.h" @@ -62,12 +66,15 @@ #define _htons(x) (x) #endif -uint16_t vxlan_gpe_udp_port = 4790; +uint16_t vxlan_gpe_udp_port = RTE_VXLAN_GPE_DEFAULT_PORT; +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; @@ -86,7 +93,7 @@ struct testpmd_offload_info { struct simple_gre_hdr { uint16_t flags; uint16_t proto; -} __attribute__((__packed__)); +} __rte_packed; static uint16_t get_udptcp_checksum(void *l3_hdr, void *l4_hdr, uint16_t ethertype) @@ -103,7 +110,7 @@ parse_ipv4(struct rte_ipv4_hdr *ipv4_hdr, struct testpmd_offload_info *info) { struct rte_tcp_hdr *tcp_hdr; - info->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4; + info->l3_len = rte_ipv4_hdr_len(ipv4_hdr); info->l4_proto = ipv4_hdr->next_proto_id; /* only fill l4_len for TCP, it's useful for TSO */ @@ -139,22 +146,23 @@ parse_ipv6(struct rte_ipv6_hdr *ipv6_hdr, struct testpmd_offload_info *info) /* * Parse an ethernet header to fill the ethertype, l2_len, l3_len and - * ipproto. This function is able to recognize IPv4/IPv6 with one optional vlan - * header. The l4_len argument is only set in case of TCP (useful for TSO). + * ipproto. This function is able to recognize IPv4/IPv6 with optional VLAN + * headers. The l4_len argument is only set in case of TCP (useful for TSO). */ static void parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info) { struct rte_ipv4_hdr *ipv4_hdr; struct rte_ipv6_hdr *ipv6_hdr; + struct rte_vlan_hdr *vlan_hdr; info->l2_len = sizeof(struct rte_ether_hdr); info->ethertype = eth_hdr->ether_type; - if (info->ethertype == _htons(RTE_ETHER_TYPE_VLAN)) { - struct rte_vlan_hdr *vlan_hdr = ( - struct rte_vlan_hdr *)(eth_hdr + 1); - + while (info->ethertype == _htons(RTE_ETHER_TYPE_VLAN) || + info->ethertype == _htons(RTE_ETHER_TYPE_QINQ)) { + vlan_hdr = (struct rte_vlan_hdr *) + ((char *)eth_hdr + info->l2_len); info->l2_len += sizeof(struct rte_vlan_hdr); info->ethertype = vlan_hdr->eth_proto; } @@ -178,6 +186,17 @@ parse_ethernet(struct rte_ether_hdr *eth_hdr, struct testpmd_offload_info *info) } } +/* Fill in outer layers length */ +static void +update_tunnel_outer(struct testpmd_offload_info *info) +{ + info->is_tunnel = 1; + info->outer_ethertype = info->ethertype; + info->outer_l2_len = info->l2_len; + info->outer_l3_len = info->l3_len; + info->outer_l4_proto = info->l4_proto; +} + /* * Parse a GTP protocol header. * No optional fields and next extension header type. @@ -198,11 +217,7 @@ parse_gtp(struct rte_udp_hdr *udp_hdr, udp_hdr->dst_port != _htons(RTE_GTPU_UDP_PORT)) return; - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); info->l2_len = 0; gtp_hdr = (struct rte_gtp_hdr *)((char *)udp_hdr + @@ -247,18 +262,15 @@ parse_vxlan(struct rte_udp_hdr *udp_hdr, { struct rte_ether_hdr *eth_hdr; - /* check udp destination port, 4789 is the default vxlan port - * (rfc7348) or that the rx offload flag is set (i40e only - * currently) */ - if (udp_hdr->dst_port != _htons(4789) && + /* check udp destination port, RTE_VXLAN_DEFAULT_PORT (4789) is the + * 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) return; - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); eth_hdr = (struct rte_ether_hdr *)((char *)udp_hdr + sizeof(struct rte_udp_hdr) + @@ -288,11 +300,7 @@ parse_vxlan_gpe(struct rte_udp_hdr *udp_hdr, if (!vxlan_gpe_hdr->proto || vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_IPV4) { - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); ipv4_hdr = (struct rte_ipv4_hdr *)((char *)vxlan_gpe_hdr + vxlan_gpe_len); @@ -302,11 +310,7 @@ parse_vxlan_gpe(struct rte_udp_hdr *udp_hdr, info->l2_len = 0; } else if (vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_IPV6) { - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); ipv6_hdr = (struct rte_ipv6_hdr *)((char *)vxlan_gpe_hdr + vxlan_gpe_len); @@ -316,11 +320,7 @@ parse_vxlan_gpe(struct rte_udp_hdr *udp_hdr, info->l2_len = 0; } else if (vxlan_gpe_hdr->proto == RTE_VXLAN_GPE_TYPE_ETH) { - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); eth_hdr = (struct rte_ether_hdr *)((char *)vxlan_gpe_hdr + vxlan_gpe_len); @@ -332,6 +332,53 @@ parse_vxlan_gpe(struct rte_udp_hdr *udp_hdr, info->l2_len += RTE_ETHER_VXLAN_GPE_HLEN; } +/* Parse a geneve header */ +static void +parse_geneve(struct rte_udp_hdr *udp_hdr, + struct testpmd_offload_info *info) +{ + struct rte_ether_hdr *eth_hdr; + struct rte_ipv4_hdr *ipv4_hdr; + struct rte_ipv6_hdr *ipv6_hdr; + struct rte_geneve_hdr *geneve_hdr; + uint16_t geneve_len; + + /* Check udp destination port. */ + if (udp_hdr->dst_port != _htons(geneve_udp_port)) + return; + + geneve_hdr = (struct rte_geneve_hdr *)((char *)udp_hdr + + sizeof(struct rte_udp_hdr)); + geneve_len = sizeof(struct rte_geneve_hdr) + geneve_hdr->opt_len * 4; + if (!geneve_hdr->proto || geneve_hdr->proto == + _htons(RTE_ETHER_TYPE_IPV4)) { + update_tunnel_outer(info); + ipv4_hdr = (struct rte_ipv4_hdr *)((char *)geneve_hdr + + geneve_len); + parse_ipv4(ipv4_hdr, info); + info->ethertype = _htons(RTE_ETHER_TYPE_IPV4); + info->l2_len = 0; + } else if (geneve_hdr->proto == _htons(RTE_ETHER_TYPE_IPV6)) { + update_tunnel_outer(info); + ipv6_hdr = (struct rte_ipv6_hdr *)((char *)geneve_hdr + + geneve_len); + info->ethertype = _htons(RTE_ETHER_TYPE_IPV6); + parse_ipv6(ipv6_hdr, info); + info->l2_len = 0; + + } else if (geneve_hdr->proto == _htons(RTE_GENEVE_TYPE_ETH)) { + update_tunnel_outer(info); + eth_hdr = (struct rte_ether_hdr *)((char *)geneve_hdr + + geneve_len); + parse_ethernet(eth_hdr, info); + } else + return; + + info->l2_len += + (sizeof(struct rte_udp_hdr) + sizeof(struct rte_geneve_hdr) + + ((struct rte_geneve_hdr *)geneve_hdr)->opt_len * 4); +} + /* Parse a gre header */ static void parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info) @@ -351,11 +398,7 @@ parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info) gre_len += GRE_EXT_LEN; if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_IPV4)) { - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); ipv4_hdr = (struct rte_ipv4_hdr *)((char *)gre_hdr + gre_len); @@ -364,11 +407,7 @@ parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info) info->l2_len = 0; } else if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_IPV6)) { - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); ipv6_hdr = (struct rte_ipv6_hdr *)((char *)gre_hdr + gre_len); @@ -377,11 +416,7 @@ parse_gre(struct simple_gre_hdr *gre_hdr, struct testpmd_offload_info *info) info->l2_len = 0; } else if (gre_hdr->proto == _htons(RTE_ETHER_TYPE_TEB)) { - info->is_tunnel = 1; - info->outer_ethertype = info->ethertype; - info->outer_l2_len = info->l2_len; - info->outer_l3_len = info->l3_len; - info->outer_l4_proto = info->l4_proto; + update_tunnel_outer(info); eth_hdr = (struct rte_ether_hdr *)((char *)gre_hdr + gre_len); @@ -450,20 +485,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 */ @@ -471,41 +507,45 @@ 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 { + udp_hdr->dgram_cksum = 0; udp_hdr->dgram_cksum = get_udptcp_checksum(l3_hdr, udp_hdr, 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 { + tcp_hdr->cksum = 0; tcp_hdr->cksum = get_udptcp_checksum(l3_hdr, tcp_hdr, 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 */ } @@ -526,14 +566,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; @@ -542,10 +582,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); @@ -553,7 +593,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; } @@ -666,7 +706,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; @@ -756,7 +796,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. */ @@ -764,16 +804,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; @@ -784,41 +828,38 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) uint32_t rx_bad_ip_csum; uint32_t rx_bad_l4_csum; 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; -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - uint64_t start_tsc; - uint64_t end_tsc; - uint64_t core_cycles; -#endif + uint64_t start_tsc = 0; -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - start_tsc = rte_rdtsc(); -#endif + get_start_cycles(&start_tsc); /* receive a burst of packet */ nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst, nb_pkt_per_burst); + inc_rx_burst_stats(fs, nb_rx); if (unlikely(nb_rx == 0)) return; -#ifdef RTE_TEST_PMD_RECORD_BURST_STATS - fs->rx_burst_stats.pkt_burst_spread[nb_rx]++; -#endif + fs->rx_packets += nb_rx; rx_bad_ip_csum = 0; 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)) @@ -829,25 +870,27 @@ 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 & RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD) + rx_bad_outer_ip_csum += 1; /* step 1: dissect packet, parsing optional vlan, ip4/ip6, vxlan * and inner headers */ 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; @@ -860,20 +903,28 @@ 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); - if (info.is_tunnel) + if (info.is_tunnel) { + tx_ol_flags |= + RTE_MBUF_F_TX_TUNNEL_VXLAN; + goto tunnel_update; + } + parse_geneve(udp_hdr, &info); + if (info.is_tunnel) { tx_ol_flags |= - PKT_TX_TUNNEL_VXLAN; + RTE_MBUF_F_TX_TUNNEL_GENEVE; + goto tunnel_update; + } } else if (info.l4_proto == IPPROTO_GRE) { struct simple_gre_hdr *gre_hdr; @@ -881,14 +932,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; } } @@ -914,7 +965,7 @@ 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)); } /* step 3: fill the mbuf meta data (flags and header lengths) */ @@ -923,10 +974,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; @@ -979,7 +1029,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 " @@ -987,30 +1037,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); @@ -1018,6 +1068,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, @@ -1039,19 +1090,31 @@ tunnel_update: } } } +#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); - if (ret >= 0) + if (ret >= 1) { + /* pkts_burst[i] can be freed safely here. */ + rte_pktmbuf_free(pkts_burst[i]); nb_segments += ret; - else { + } else if (ret == 0) { + /* 0 means it can be transmitted directly + * without gso. + */ + gso_segments[nb_segments] = pkts_burst[i]; + nb_segments += 1; + } else { TESTPMD_LOG(DEBUG, "Unable to segment packet"); rte_pktmbuf_free(pkts_burst[i]); } @@ -1059,13 +1122,16 @@ tunnel_update: tx_pkts_burst = gso_segments; nb_rx = nb_segments; - } + } 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); @@ -1085,10 +1151,9 @@ tunnel_update: fs->rx_bad_ip_csum += rx_bad_ip_csum; fs->rx_bad_l4_csum += rx_bad_l4_csum; fs->rx_bad_outer_l4_csum += rx_bad_outer_l4_csum; + fs->rx_bad_outer_ip_csum += rx_bad_outer_ip_csum; -#ifdef RTE_TEST_PMD_RECORD_BURST_STATS - fs->tx_burst_stats.pkt_burst_spread[nb_tx]++; -#endif + inc_tx_burst_stats(fs, nb_tx); if (unlikely(nb_tx < nb_rx)) { fs->fwd_dropped += (nb_rx - nb_tx); do { @@ -1096,11 +1161,7 @@ tunnel_update: } while (++nb_tx < nb_rx); } -#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES - end_tsc = rte_rdtsc(); - core_cycles = (end_tsc - start_tsc); - fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles); -#endif + get_end_cycles(fs, start_tsc); } struct fwd_engine csum_fwd_engine = {