net: add function to calculate IPv4 header length
authorMichael Pfeiffer <michael.pfeiffer@tu-ilmenau.de>
Mon, 12 Oct 2020 14:55:46 +0000 (16:55 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 16 Oct 2020 17:48:17 +0000 (19:48 +0200)
Add a function to calculate the length of an IPv4 header as suggested
on the mailing list [1]. Call where appropriate.

[1] https://mails.dpdk.org/archives/dev/2020-October/184471.html

Suggested-by: Thomas Monjalon <thomas@monjalon.net>
Signed-off-by: Michael Pfeiffer <michael.pfeiffer@tu-ilmenau.de>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
app/test-pmd/5tswap.c
app/test-pmd/csumonly.c
drivers/net/hinic/hinic_pmd_tx.c
drivers/net/tap/rte_eth_tap.c
drivers/net/vmxnet3/vmxnet3_rxtx.c
examples/l3fwd/l3fwd_em.c
lib/librte_net/rte_ip.h
lib/librte_net/rte_net.c
lib/librte_vhost/virtio_net.c

index 3cf1692..e8cef96 100644 (file)
@@ -142,7 +142,7 @@ pkt_burst_5tuple_swap(struct fwd_stream *fs)
                if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {
                        swap_ipv4(h.ipv4);
                        next_proto = h.ipv4->next_proto_id;
-                       mb->l3_len = (h.ipv4->version_ihl & 0x0f) * 4;
+                       mb->l3_len = rte_ipv4_hdr_len(h.ipv4);
                        h.byte += mb->l3_len;
                } else if (proto == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {
                        swap_ipv6(h.ipv6);
index 8f2f840..3d7d244 100644 (file)
@@ -105,7 +105,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 */
index d9f251a..2dd4fe1 100644 (file)
@@ -23,7 +23,6 @@
 /* packet header and tx offload info */
 #define ETHER_LEN_NO_VLAN              14
 #define ETHER_LEN_WITH_VLAN            18
-#define HEADER_LEN_OFFSET              2
 #define VXLANLEN                       8
 #define MAX_PLD_OFFSET                 221
 #define MAX_SINGLE_SGE_SIZE            65536
@@ -714,7 +713,6 @@ hinic_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
                uint8_t  proto;    /* L4 protocol type. */
                uint16_t len;      /* L4 length. */
        } psd_hdr;
-       uint8_t ihl;
 
        psd_hdr.src_addr = ipv4_hdr->src_addr;
        psd_hdr.dst_addr = ipv4_hdr->dst_addr;
@@ -723,13 +721,9 @@ hinic_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
        if (ol_flags & PKT_TX_TCP_SEG) {
                psd_hdr.len = 0;
        } else {
-               /* ipv4_hdr->version_ihl is uint8_t big endian, ihl locates
-                * lower 4 bits and unit is 4 bytes
-                */
-               ihl = (ipv4_hdr->version_ihl & 0xF) << 2;
                psd_hdr.len =
                rte_cpu_to_be_16(rte_be_to_cpu_16(ipv4_hdr->total_length) -
-                                ihl);
+                                rte_ipv4_hdr_len(ipv4_hdr));
        }
        return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr));
 }
@@ -803,8 +797,7 @@ static inline void hinic_analyze_tx_info(struct rte_mbuf *mbuf,
 
        if (pkt_type == RTE_ETHER_TYPE_IPV4) {
                ip4h = (struct rte_ipv4_hdr *)(hdr + off_info->outer_l2_len);
-               off_info->outer_l3_len = (ip4h->version_ihl & 0xf) <<
-                                       HEADER_LEN_OFFSET;
+               off_info->outer_l3_len = rte_ipv4_hdr_len(ip4h);
        } else if (pkt_type == RTE_ETHER_TYPE_IPV6) {
                /* not support ipv6 extension header */
                off_info->outer_l3_len = sizeof(struct rte_ipv6_hdr);
index b127ce6..e592a46 100644 (file)
@@ -316,8 +316,7 @@ tap_verify_csum(struct rte_mbuf *mbuf)
        if (l3 == RTE_PTYPE_L3_IPV4 || l3 == RTE_PTYPE_L3_IPV4_EXT) {
                struct rte_ipv4_hdr *iph = l3_hdr;
 
-               /* ihl contains the number of 4-byte words in the header */
-               l3_len = 4 * (iph->version_ihl & 0xf);
+               l3_len = rte_ipv4_hdr_len(iph);
                if (unlikely(l2_len + l3_len > rte_pktmbuf_data_len(mbuf)))
                        return;
                /* check that the total length reported by header is not
index 73e270f..e10f9ee 100644 (file)
@@ -687,8 +687,7 @@ vmxnet3_guess_mss(struct vmxnet3_hw *hw, const Vmxnet3_RxCompDesc *rcd,
                                        - sizeof(struct rte_tcp_hdr);
 
                ipv4_hdr = (struct rte_ipv4_hdr *)(ptr + hlen);
-               hlen += (ipv4_hdr->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
-                               RTE_IPV4_IHL_MULTIPLIER;
+               hlen += rte_ipv4_hdr_len(ipv4_hdr);
        } else if (rcd->v6) {
                if (unlikely(slen < hlen + sizeof(struct rte_ipv6_hdr)))
                        return hw->mtu - sizeof(struct rte_ipv6_hdr) -
index c529dcd..9996bfb 100644 (file)
@@ -579,8 +579,7 @@ em_parse_ptype(struct rte_mbuf *m)
        l3 = (uint8_t *)eth_hdr + sizeof(struct rte_ether_hdr);
        if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
                ipv4_hdr = (struct rte_ipv4_hdr *)l3;
-               hdr_len = (ipv4_hdr->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
-                         RTE_IPV4_IHL_MULTIPLIER;
+               hdr_len = rte_ipv4_hdr_len(ipv4_hdr);
                if (hdr_len == sizeof(struct rte_ipv4_hdr)) {
                        packet_type |= RTE_PTYPE_L3_IPV4;
                        if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
index 8382d0f..5463276 100644 (file)
@@ -103,6 +103,21 @@ struct rte_ipv4_hdr {
 #define RTE_IPV4_MIN_IHL    (0x5)
 #define RTE_IPV4_VHL_DEF    ((IPVERSION << 4) | RTE_IPV4_MIN_IHL)
 
+/**
+ * Get the length of an IPv4 header.
+ *
+ * @param ipv4_hdr
+ *   Pointer to the IPv4 header.
+ * @return
+ *   The length of the IPv4 header (with options if present) in bytes.
+ */
+static inline uint8_t
+rte_ipv4_hdr_len(const struct rte_ipv4_hdr *ipv4_hdr)
+{
+       return (uint8_t)((ipv4_hdr->version_ihl & RTE_IPV4_HDR_IHL_MASK) *
+               RTE_IPV4_IHL_MULTIPLIER);
+}
+
 /**
  * @internal Calculate a sum of all words in the buffer.
  * Helper routine for the rte_raw_cksum().
@@ -272,7 +287,7 @@ static inline uint16_t
 rte_ipv4_cksum(const struct rte_ipv4_hdr *ipv4_hdr)
 {
        uint16_t cksum;
-       cksum = rte_raw_cksum(ipv4_hdr, (ipv4_hdr->version_ihl & 0xf) * 4);
+       cksum = rte_raw_cksum(ipv4_hdr, rte_ipv4_hdr_len(ipv4_hdr));
        return (uint16_t)~cksum;
 }
 
@@ -306,7 +321,6 @@ rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
        } psd_hdr;
 
        uint32_t l3_len;
-       uint8_t ip_hdr_len;
 
        psd_hdr.src_addr = ipv4_hdr->src_addr;
        psd_hdr.dst_addr = ipv4_hdr->dst_addr;
@@ -316,8 +330,8 @@ rte_ipv4_phdr_cksum(const struct rte_ipv4_hdr *ipv4_hdr, uint64_t ol_flags)
                psd_hdr.len = 0;
        } else {
                l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
-               ip_hdr_len = (ipv4_hdr->version_ihl & 0xf) * 4;
-               psd_hdr.len = rte_cpu_to_be_16((uint16_t)(l3_len - ip_hdr_len));
+               psd_hdr.len = rte_cpu_to_be_16((uint16_t)(l3_len -
+                       rte_ipv4_hdr_len(ipv4_hdr)));
        }
        return rte_raw_cksum(&psd_hdr, sizeof(psd_hdr));
 }
@@ -342,7 +356,7 @@ rte_ipv4_udptcp_cksum(const struct rte_ipv4_hdr *ipv4_hdr, const void *l4_hdr)
        uint32_t l3_len, l4_len;
        uint8_t ip_hdr_len;
 
-       ip_hdr_len = (ipv4_hdr->version_ihl & 0xf) * 4;
+       ip_hdr_len = rte_ipv4_hdr_len(ipv4_hdr);
        l3_len = rte_be_to_cpu_16(ipv4_hdr->total_length);
        if (l3_len < ip_hdr_len)
                return 0;
index 6f45b13..bfe5003 100644 (file)
@@ -171,13 +171,6 @@ ptype_tunnel(uint16_t *proto, const struct rte_mbuf *m,
        }
 }
 
-/* get the ipv4 header length */
-static uint8_t
-ip4_hlen(const struct rte_ipv4_hdr *hdr)
-{
-       return (hdr->version_ihl & 0xf) * 4;
-}
-
 /* parse ipv6 extended headers, update offset and return next proto */
 int
 rte_net_skip_ip6_ext(uint16_t proto, const struct rte_mbuf *m, uint32_t *off,
@@ -308,7 +301,7 @@ l3:
                        return pkt_type;
 
                pkt_type |= ptype_l3_ip(ip4h->version_ihl);
-               hdr_lens->l3_len = ip4_hlen(ip4h);
+               hdr_lens->l3_len = rte_ipv4_hdr_len(ip4h);
                off += hdr_lens->l3_len;
 
                if ((layers & RTE_PTYPE_L4_MASK) == 0)
@@ -440,7 +433,7 @@ l3:
                        return pkt_type;
 
                pkt_type |= ptype_inner_l3_ip(ip4h->version_ihl);
-               hdr_lens->inner_l3_len = ip4_hlen(ip4h);
+               hdr_lens->inner_l3_len = rte_ipv4_hdr_len(ip4h);
                off += hdr_lens->inner_l3_len;
 
                if ((layers & RTE_PTYPE_INNER_L4_MASK) == 0)
index 1b23327..513428e 100644 (file)
@@ -1847,7 +1847,7 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr)
        case RTE_ETHER_TYPE_IPV4:
                ipv4_hdr = l3_hdr;
                *l4_proto = ipv4_hdr->next_proto_id;
-               m->l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;
+               m->l3_len = rte_ipv4_hdr_len(ipv4_hdr);
                *l4_hdr = (char *)l3_hdr + m->l3_len;
                m->ol_flags |= PKT_TX_IPV4;
                break;