[dpdk-dev] [PATCH v8 1/6] ethdev: add Tx preparation

Ananyev, Konstantin konstantin.ananyev at intel.com
Mon Oct 24 14:14:49 CEST 2016


Hi Tomasz,

> 
>  /**
> + * Validate general requirements for tx offload in mbuf.
> + *
> + * This function checks correctness and completeness of Tx offload settings.
> + *
> + * @param m
> + *   The packet mbuf to be validated.
> + * @return
> + *   0 if packet is valid
> + */
> +static inline int
> +rte_validate_tx_offload(const struct rte_mbuf *m)
> +{
> +	uint64_t ol_flags = m->ol_flags;
> +
> +	/* Does packet set any of available offloads? */
> +	if (!(ol_flags & PKT_TX_OFFLOAD_MASK))
> +		return 0;
> +
> +	/* IP checksum can be counted only for IPv4 packet */
> +	if ((ol_flags & PKT_TX_IP_CKSUM) && (ol_flags & PKT_TX_IPV6))
> +		return -EINVAL;
> +
> +	/* IP type not set when required */
> +	if (ol_flags & (PKT_TX_L4_MASK | PKT_TX_TCP_SEG))
> +		if (!(ol_flags & (PKT_TX_IPV4 | PKT_TX_IPV6)))
> +			return -EINVAL;
> +
> +	/* Check requirements for TSO packet */
> +	if (ol_flags & PKT_TX_TCP_SEG)
> +		if ((m->tso_segsz == 0) ||
> +				((ol_flags & PKT_TX_IPV4) &&
> +				!(ol_flags & PKT_TX_IP_CKSUM)))
> +			return -EINVAL;
> +
> +	/* PKT_TX_OUTER_IP_CKSUM set for non outer IPv4 packet. */
> +	if ((ol_flags & PKT_TX_OUTER_IP_CKSUM) &&
> +			!(ol_flags & PKT_TX_OUTER_IPV4))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +/**
>   * Dump an mbuf structure to a file.
>   *
>   * Dump all fields for the given packet mbuf and all its associated
> diff --git a/lib/librte_net/rte_net.h b/lib/librte_net/rte_net.h
> index d4156ae..79669d7 100644
> --- a/lib/librte_net/rte_net.h
> +++ b/lib/librte_net/rte_net.h
> @@ -38,6 +38,11 @@
>  extern "C" {
>  #endif
> 
> +#include <rte_ip.h>
> +#include <rte_udp.h>
> +#include <rte_tcp.h>
> +#include <rte_sctp.h>
> +
>  /**
>   * Structure containing header lengths associated to a packet, filled
>   * by rte_net_get_ptype().
> @@ -86,6 +91,91 @@ struct rte_net_hdr_lens {
>  uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
>  	struct rte_net_hdr_lens *hdr_lens, uint32_t layers);
> 
> +/**
> + * Fix pseudo header checksum
> + *
> + * This function fixes pseudo header checksum for TSO and non-TSO tcp/udp in
> + * provided mbufs packet data.
> + *
> + * - for non-TSO tcp/udp packets full pseudo-header checksum is counted and set
> + *   in packet data,
> + * - for TSO the IP payload length is not included in pseudo header.
> + *
> + * This function expects that used headers are in the first data segment of
> + * mbuf, and are not fragmented.
> + *
> + * @param m
> + *   The packet mbuf to be validated.
> + * @return
> + *   0 if checksum is initialized properly
> + */
> +static inline int
> +rte_phdr_cksum_fix(struct rte_mbuf *m)
> +{
> +	struct ipv4_hdr *ipv4_hdr;
> +	struct ipv6_hdr *ipv6_hdr;
> +	struct tcp_hdr *tcp_hdr;
> +	struct udp_hdr *udp_hdr;
> +	uint64_t ol_flags = m->ol_flags;
> +	uint64_t inner_l3_offset = m->l2_len;
> +
> +	if (ol_flags & PKT_TX_OUTER_IP_CKSUM)
> +		inner_l3_offset += m->outer_l2_len + m->outer_l3_len;
> +
> +	/* headers are fragmented */
> +	if (unlikely(rte_pktmbuf_data_len(m) >= inner_l3_offset + m->l3_len +
> +			m->l4_len))

Might be better to move that check into rte_validate_tx_offload(),
so it would be called only when TX_DEBUG is on.
Another thing, shouldn't it be:
if (rte_pktmbuf_data_len(m) < inner_l3_offset + m->l3_len + m->l4_len)
?
Konstantin


> +		return -ENOTSUP;
> +
> +	if ((ol_flags & PKT_TX_UDP_CKSUM) == PKT_TX_UDP_CKSUM) {
> +		if (ol_flags & PKT_TX_IPV4) {
> +			ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
> +					inner_l3_offset);
> +
> +			if (ol_flags & PKT_TX_IP_CKSUM)
> +				ipv4_hdr->hdr_checksum = 0;
> +
> +			udp_hdr = (struct udp_hdr *)((char *)ipv4_hdr +
> +					m->l3_len);
> +			udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
> +					ol_flags);
> +		} else {
> +			ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
> +					inner_l3_offset);
> +			/* non-TSO udp */
> +			udp_hdr = rte_pktmbuf_mtod_offset(m, struct udp_hdr *,
> +					inner_l3_offset + m->l3_len);
> +			udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
> +					ol_flags);
> +		}
> +	} else if ((ol_flags & PKT_TX_TCP_CKSUM) ||
> +			(ol_flags & PKT_TX_TCP_SEG)) {
> +		if (ol_flags & PKT_TX_IPV4) {
> +			ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
> +					inner_l3_offset);
> +
> +			if (ol_flags & PKT_TX_IP_CKSUM)
> +				ipv4_hdr->hdr_checksum = 0;
> +
> +			/* non-TSO tcp or TSO */
> +			tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr +
> +					m->l3_len);
> +			tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
> +					ol_flags);
> +		} else {
> +			ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *,
> +					inner_l3_offset);
> +			/* non-TSO tcp or TSO */
> +			tcp_hdr = rte_pktmbuf_mtod_offset(m, struct tcp_hdr *,
> +					inner_l3_offset + m->l3_len);
> +			tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
> +					ol_flags);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  #ifdef __cplusplus
>  }
>  #endif
> --
> 1.7.9.5



More information about the dev mailing list