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

Reply via email to