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 <tho...@monjalon.net>
Signed-off-by: Michael Pfeiffer <michael.pfeif...@tu-ilmenau.de>
---
 app/test-pmd/5tswap.c              |  2 +-
 app/test-pmd/csumonly.c            |  2 +-
 drivers/net/hinic/hinic_pmd_tx.c   | 11 ++---------
 drivers/net/tap/rte_eth_tap.c      |  3 +--
 drivers/net/vmxnet3/vmxnet3_rxtx.c |  3 +--
 examples/l3fwd/l3fwd_em.c          |  3 +--
 lib/librte_net/rte_ip.h            | 24 +++++++++++++++++++-----
 lib/librte_net/rte_net.c           | 11 ++---------
 lib/librte_vhost/virtio_net.c      |  2 +-
 9 files changed, 29 insertions(+), 32 deletions(-)

diff --git a/app/test-pmd/5tswap.c b/app/test-pmd/5tswap.c
index 3cf1692ea..e8cef9623 100644
--- a/app/test-pmd/5tswap.c
+++ b/app/test-pmd/5tswap.c
@@ -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);
diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 7ece398bd..49943121a 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -103,7 +103,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 */
diff --git a/drivers/net/hinic/hinic_pmd_tx.c b/drivers/net/hinic/hinic_pmd_tx.c
index d9f251a32..2dd4fe184 100644
--- a/drivers/net/hinic/hinic_pmd_tx.c
+++ b/drivers/net/hinic/hinic_pmd_tx.c
@@ -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);
diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index b127ce62d..e592a469b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -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
diff --git a/drivers/net/vmxnet3/vmxnet3_rxtx.c 
b/drivers/net/vmxnet3/vmxnet3_rxtx.c
index 73e270f30..e10f9ee87 100644
--- a/drivers/net/vmxnet3/vmxnet3_rxtx.c
+++ b/drivers/net/vmxnet3/vmxnet3_rxtx.c
@@ -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) -
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index c529dcd3e..9996bfba3 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -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)
diff --git a/lib/librte_net/rte_ip.h b/lib/librte_net/rte_ip.h
index bb55ebb6f..a5f241f33 100644
--- a/lib/librte_net/rte_ip.h
+++ b/lib/librte_net/rte_ip.h
@@ -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().
@@ -269,7 +284,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;
 }
 
@@ -303,7 +318,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;
@@ -313,8 +327,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));
 }
@@ -339,7 +353,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;
diff --git a/lib/librte_net/rte_net.c b/lib/librte_net/rte_net.c
index 6f45b1339..bfe500397 100644
--- a/lib/librte_net/rte_net.c
+++ b/lib/librte_net/rte_net.c
@@ -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 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                        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 @@ uint32_t rte_net_get_ptype(const struct rte_mbuf *m,
                        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)
diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c
index 0a0bea1a5..867e87bde 100644
--- a/lib/librte_vhost/virtio_net.c
+++ b/lib/librte_vhost/virtio_net.c
@@ -1846,7 +1846,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;
-- 
2.28.0

Reply via email to