From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 8951CA0032;
	Fri, 14 Jan 2022 10:30:25 +0100 (CET)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id ECE8442773;
	Fri, 14 Jan 2022 10:30:24 +0100 (CET)
Received: from mail-ed1-f42.google.com (mail-ed1-f42.google.com
 [209.85.208.42]) by mails.dpdk.org (Postfix) with ESMTP id 9B1B840DDD
 for <dev@dpdk.org>; Fri, 14 Jan 2022 10:30:24 +0100 (CET)
Received: by mail-ed1-f42.google.com with SMTP id q25so32848746edb.2
 for <dev@dpdk.org>; Fri, 14 Jan 2022 01:30:24 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=emumba-com.20210112.gappssmtp.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=nfqetnaGo505HQtRUTMAYnsTBtUPNF96XbKH3T9ME7M=;
 b=7pj+o9jTUVqLZvGLxZR4v2EAnneSTwr4+sPTLrICVE96KfTexDdCmrTkHoI+wtd1Qb
 yaMudoeGAPAsZ3+f0BXjrNd58IWdjxNnj4IDToun71QBuNGFJ4esK4SP6NrEWVQ3JT0R
 xIeVfbzbQrtborb9uaEb4T0SHyb6pWMOtjjnxFGF/2Q01wTd36YzjM0h1JN+AhCCcWI4
 /MP7EVn/VHlFQoP4Pq2Rko26QR1CBaem2wYGcFARdmYYf17dyLkWYagUo7C7ubbdrCRc
 GITzGlASrqq+aIIkMRpHyeMioSz2uSF2aeVXTNa2/LGRiTV4AYQVQx34jDVxLDtUHdDR
 Il1g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=nfqetnaGo505HQtRUTMAYnsTBtUPNF96XbKH3T9ME7M=;
 b=yAyZ3VIAZWkjcDrLCyL13d53HHcewF0McEdUAt48BAiercnsEpPtb1QSjVBswgZVgV
 O894R2lKK0GOeWU61TccQ0aL3M9QahxE7I3uOZ19R6ZCcNPY7gym6OMVRS8S3GMCsWAL
 MNyhzYB0/zEChrRb7QCGDRkNblh4sBeJL0VEj+jF9VaLJ3BzKeEjAdKI7EYlNAtfAsKE
 r1+A1vldp0+KhDvpQzqVCHYlIxGUIG1JNVJBqfhShopteiPp8v46q7CROdEp5TG/XqEA
 f9fKxO3XlrUPAZsefjwmZ/euQMUjF+2P1+CPNQ8G25IBcX6WxCA1STOAY1nHqZ9uJh7v
 DlpA==
X-Gm-Message-State: AOAM531OU2ugQq5vE3dQBPM0Yov0gGJKcN+P7cxXkYgGmhFVbdmOlYSF
 8sXIVHVxifeVMOPqQY1AxL0jOoNVvACj6Ab9e4yjC9MmOL3E5Qs=
X-Google-Smtp-Source: ABdhPJzoPPUAJhvjkyc0By55x0hVccjgJgkrJa+HhZHrOhF9sy6eYIwsraz9cNOZRI6+BAFE4el45KcSgPMyO3JdZhU=
X-Received: by 2002:a05:6402:292f:: with SMTP id
 ee47mr941119edb.262.1642152624271; 
 Fri, 14 Jan 2022 01:30:24 -0800 (PST)
MIME-Version: 1.0
References: <20211008155111.125786-1-usama.nadeem@emumba.com>
 <20211014184322.5148-1-usama.nadeem@emumba.com>
 <DM6PR11MB449171FEA4B0CC67C36B94D39A8D9@DM6PR11MB4491.namprd11.prod.outlook.com>
In-Reply-To: <DM6PR11MB449171FEA4B0CC67C36B94D39A8D9@DM6PR11MB4491.namprd11.prod.outlook.com>
From: Usama Nadeem <usama.nadeem@emumba.com>
Date: Fri, 14 Jan 2022 14:30:11 +0500
Message-ID: <CABDMEvkuQeJ9bPw2uTg2H5_ZjX3MdG5TCBKGq40r1TGPm0COYQ@mail.gmail.com>
Subject: Re: [dpdk-dev] [PATCH v4] examples/l3fwd: ipv4 and udp/tcp cksum
 verification through software
To: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
Cc: "thomas@monjalon.net" <thomas@monjalon.net>, "dev@dpdk.org" <dev@dpdk.org>
Content-Type: multipart/alternative; boundary="000000000000d6472505d5877325"
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

--000000000000d6472505d5877325
Content-Type: text/plain; charset="UTF-8"

Hello, and thank you for the recommendations. I did investigate the
alternative options offered. I have a question about it. After verifying
mbuf's cksum, we may set the RTE MBUF F RX * CKSUM_* flags. I was just
wondering if it should be done at the application level or in the driver
code.
If we add this feature to driver code, do we have to include it in all
drivers that don't support sw-based cksums, and will it vary per driver?
Is it possible to accomplish it in a generic way? As an example, how about
at the application level. If we set the RTE MBUF F RX * CKSUM_* flags on
the application level, it will be independent of the individual drivers.
Thanks

On Thu, Nov 4, 2021 at 6:19 PM Ananyev, Konstantin <
konstantin.ananyev@intel.com> wrote:

> > checks if ipv4 and udptcp cksum offload capability available
> > If not available, cksum is verified through software
> > If cksum is corrupt, packet is dropped, rest of the packets
> > are forwarded back.
>
> From what I see right now l3fwd:
>    a) enables HW RX cksum offload
>    b) simply ignores HW provided cksum status
> Which came as a real surprise to me.
> Feel free to correct me if I missed something obvious here.
>
> So, I think first we need to add missing check first,
> even though it might cause some perf drop.
> Then make changes to actually check provided by HW status and
> when HW doesn't provide such offload do check in SW.
>
> Another alternative would be to remove request for HW offloads
> and document l3fwd that it doesn't check checksums at all,
> but I don't think it is a good way.
>
> > Bugzilla ID:545
> > Signed-off-by: Usama Nadeem <usama.nadeem@emumba.com>
> > ---
> >  examples/l3fwd/l3fwd.h     |  6 ++++
> >  examples/l3fwd/l3fwd_lpm.c | 72 ++++++++++++++++++++++++++++++++++++--
> >  examples/l3fwd/main.c      | 33 +++++++++++++++--
> >  3 files changed, 105 insertions(+), 6 deletions(-)
> >
> > diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
> > index a808d60247..c2c21a91fb 100644
> > --- a/examples/l3fwd/l3fwd.h
> > +++ b/examples/l3fwd/l3fwd.h
> > @@ -55,6 +55,8 @@
> >  #define L3FWD_HASH_ENTRIES           (1024*1024*1)
> >  #endif
> >  #define HASH_ENTRY_NUMBER_DEFAULT    4
> > +extern bool l3_sft_cksum;
> > +extern bool l4_sft_cksum;
>
> About the approach itself.
> We have similar issue for HW PTYPE recognition - some HW doesn't support
> it.
> So we check HW capabilities and if required we setup SW RX callbacks to do
> determine PTYPE in SW. Note that for EM/LPM we have different callbacks.
> I think for cksum checks we can do the same:
> check HW capabilities, if they are missing add a new callback that would
> calculate/check cksum and set  RTE_MBUF_F_RX_*_CKSUM_* flags.
> That way it will HW/SW cksum will be transparent for the rest of l3fwd
> code.
>
> About cksums required: for LPM/FIB mode just IPv4 cksum seems enough.
> For EM we probably need L4 cksum too, though not sure is it really needed.
> Wonder what other people think here?
>
>  >  struct mbuf_table {
> >       uint16_t len;
> > @@ -210,6 +212,10 @@ em_main_loop(__rte_unused void *dummy);
> >  int
> >  lpm_main_loop(__rte_unused void *dummy);
> >
> > +int
> > +check_software_cksum(struct rte_mbuf **pkts_burst,
> > +struct rte_mbuf **pkts_burst_to_send, int nb_rx);
> > +
> >  int
> >  fib_main_loop(__rte_unused void *dummy);
> >
> > diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
> > index 232b606b54..ecaf323943 100644
> > --- a/examples/l3fwd/l3fwd_lpm.c
> > +++ b/examples/l3fwd/l3fwd_lpm.c
> > @@ -26,6 +26,7 @@
> >  #include <rte_udp.h>
> >  #include <rte_lpm.h>
> >  #include <rte_lpm6.h>
> > +#include <rte_net.h>
> >
> >  #include "l3fwd.h"
> >  #include "l3fwd_event.h"
> > @@ -139,16 +140,65 @@ lpm_get_dst_port_with_ipv4(const struct lcore_conf
> *qconf, struct rte_mbuf *pkt,
> >  #include "l3fwd_lpm.h"
> >  #endif
> >
> > +
> > +int check_software_cksum(struct rte_mbuf **pkts_burst,
> > +struct rte_mbuf **pkts_burst_to_send, int nb_rx)
> > +{
> > +     int j;
> > +     int i = 0;
> > +     struct rte_net_hdr_lens hdr_lens;
> > +     struct rte_ipv4_hdr *ipv4_hdr;
> > +     void *l3_hdr;
> > +     void *l4_hdr;
> > +     rte_be16_t prev_cksum;
> > +     int dropped_pkts_udp_tcp = 0;
> > +     int dropped_pkts_ipv4 = 0;
> > +     bool dropped;
> > +     for (j = 0; j < nb_rx; j++) {
> > +             dropped = false;
> > +             rte_net_get_ptype(pkts_burst[j], &hdr_lens,
> RTE_PTYPE_ALL_MASK);
> > +             l3_hdr = rte_pktmbuf_mtod_offset(pkts_burst[j],
> > +             void *, hdr_lens.l2_len);
> > +             l4_hdr = rte_pktmbuf_mtod_offset(pkts_burst[j],
> > +             void *, hdr_lens.l2_len + hdr_lens.l3_len);
> > +             ipv4_hdr = l3_hdr;
> > +             prev_cksum = ipv4_hdr->hdr_checksum;
> > +             ipv4_hdr->hdr_checksum = 0;
> > +             ipv4_hdr->hdr_checksum = rte_ipv4_cksum(ipv4_hdr);
> > +
> > +             if (l3_sft_cksum && prev_cksum != ipv4_hdr->hdr_checksum) {
> > +                     rte_pktmbuf_free(pkts_burst[j]);
> > +                     dropped_pkts_ipv4++;
> > +                     dropped = true;
> > +             } else if (l4_sft_cksum &&
> > +                             rte_ipv4_udptcp_cksum_verify
> > +                             (l3_hdr, l4_hdr) != 0) {
> > +
> > +                     rte_pktmbuf_free(pkts_burst[j]);
> > +                     dropped_pkts_udp_tcp++;
> > +                     dropped = true;
> > +             }
> > +             if (dropped == false) {
> > +                     pkts_burst_to_send[i] = pkts_burst[j];
> > +                     i++;
> > +             }
> > +
> > +     }
> > +     return dropped_pkts_udp_tcp+dropped_pkts_ipv4;
> > +}
> > +
> >  /* main processing loop */
> >  int
> >  lpm_main_loop(__rte_unused void *dummy)
> >  {
> >       struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
> > +     struct rte_mbuf *pkts_burst_to_send[MAX_PKT_BURST];
> >       unsigned lcore_id;
> >       uint64_t prev_tsc, diff_tsc, cur_tsc;
> >       int i, nb_rx;
> >       uint16_t portid;
> >       uint8_t queueid;
> > +     int dropped;
> >       struct lcore_conf *qconf;
> >       const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) /
> >               US_PER_S * BURST_TX_DRAIN_US;
> > @@ -209,19 +259,35 @@ lpm_main_loop(__rte_unused void *dummy)
> >                       if (nb_rx == 0)
> >                               continue;
> >
> > +                     if (l3_sft_cksum || l4_sft_cksum) {
> > +                             dropped = check_software_cksum(pkts_burst,
> > +                             pkts_burst_to_send,     nb_rx);
> > +
> > +                             nb_rx = nb_rx-dropped;
> > +                     }
> > +
> > +
> >  #if defined RTE_ARCH_X86 || defined __ARM_NEON \
> >                        || defined RTE_ARCH_PPC_64
> > +             if (l3_sft_cksum == false && l4_sft_cksum == false)
> >                       l3fwd_lpm_send_packets(nb_rx, pkts_burst,
> >                                               portid, qconf);
> > +             else
> > +                     l3fwd_lpm_send_packets(nb_rx, pkts_burst_to_send,
> > +                                             portid, qconf);
> > +
> >  #else
> > -                     l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst,
> > +                     if (l3_sft_cksum == false && l4_sft_cksum == false)
> > +                             l3fwd_lpm_no_opt_send_packets(nb_rx,
> pkts_burst,
> >                                                       portid, qconf);
> > +                     else
> > +                             l3fwd_lpm_no_opt_send_packets(nb_rx,
> > +                             pkts_burst_to_send, portid, qconf);
> > +
> >  #endif /* X86 */
> >               }
> > -
> >               cur_tsc = rte_rdtsc();
> >       }
> > -
> >       return 0;
> >  }
> >
> > diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> > index 00ac267af1..a54aca070d 100644
> > --- a/examples/l3fwd/main.c
> > +++ b/examples/l3fwd/main.c
> > @@ -61,6 +61,9 @@ static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
> >  /**< Ports set in promiscuous mode off by default. */
> >  static int promiscuous_on;
> >
> > +bool l3_sft_cksum;
> > +bool l4_sft_cksum;
> > +
> >  /* Select Longest-Prefix, Exact match or Forwarding Information Base. */
> >  enum L3FWD_LOOKUP_MODE {
> >       L3FWD_LOOKUP_DEFAULT,
> > @@ -123,7 +126,6 @@ static struct rte_eth_conf port_conf = {
> >               .mq_mode = ETH_MQ_RX_RSS,
> >               .max_rx_pkt_len = RTE_ETHER_MAX_LEN,
> >               .split_hdr_size = 0,
> > -             .offloads = DEV_RX_OFFLOAD_CHECKSUM,
> >       },
> >       .rx_adv_conf = {
> >               .rss_conf = {
> > @@ -981,6 +983,7 @@ prepare_ptype_parser(uint16_t portid, uint16_t
> queueid)
> >       return 0;
> >  }
> >
> > +
> >  static void
> >  l3fwd_poll_resource_setup(void)
> >  {
> > @@ -993,7 +996,8 @@ l3fwd_poll_resource_setup(void)
> >       unsigned int nb_ports;
> >       unsigned int lcore_id;
> >       int ret;
> > -
> > +     l3_sft_cksum = false;
> > +     l4_sft_cksum = false;
> >       if (check_lcore_params() < 0)
> >               rte_exit(EXIT_FAILURE, "check_lcore_params failed\n");
> >
> > @@ -1034,11 +1038,34 @@ l3fwd_poll_resource_setup(void)
> >                       rte_exit(EXIT_FAILURE,
> >                               "Error during getting device (port %u)
> info: %s\n",
> >                               portid, strerror(-ret));
> > -
> >               if (dev_info.tx_offload_capa &
> DEV_TX_OFFLOAD_MBUF_FAST_FREE)
> >                       local_port_conf.txmode.offloads |=
> >                               DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> >
> > +             if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM)
> > +                     local_port_conf.rxmode.offloads |=
> > +                     DEV_RX_OFFLOAD_IPV4_CKSUM;
> > +             else {
> > +                     l3_sft_cksum = true;
> > +                     printf("WARNING: IPV4 checksum offload not
> available.\n");
> > +                     }
> > +
> > +             if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM)
> > +                     local_port_conf.rxmode.offloads |=
> > +                             DEV_RX_OFFLOAD_UDP_CKSUM;
> > +             else {
> > +                     l4_sft_cksum = true;
> > +                     printf("WARNING: UDP checksum offload not
> available.\n");
> > +             }
> > +
> > +             if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
> > +                     local_port_conf.rxmode.offloads |=
> > +                             DEV_RX_OFFLOAD_TCP_CKSUM;
> > +             else {
> > +                     l4_sft_cksum = true;
> > +                     printf("WARNING: TCP checksum offload not
> available.\n");
> > +             }
> > +
> >               local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> >                       dev_info.flow_type_rss_offloads;
> >
> > --
> > 2.25.1
>
>

-- 
-Usama

--000000000000d6472505d5877325
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hello, and thank you for the recommendations. I did invest=
igate the alternative options offered. I have a question about it. After ve=
rifying mbuf&#39;s cksum, we may set the RTE MBUF F RX * CKSUM_* flags. I w=
as just wondering if it should be done at the application level or in the d=
river code.<br>If we add this feature to driver code, do we have to include=
 it in all drivers that don&#39;t support sw-based cksums, and will it vary=
 per driver?<br>Is it possible to accomplish it in a generic way? As an exa=
mple, how about at the application level. If we set the RTE MBUF F RX * CKS=
UM_* flags on the application level, it will be independent of the individu=
al drivers.<br>Thanks<br></div><br><div class=3D"gmail_quote"><div dir=3D"l=
tr" class=3D"gmail_attr">On Thu, Nov 4, 2021 at 6:19 PM Ananyev, Konstantin=
 &lt;<a href=3D"mailto:konstantin.ananyev@intel.com">konstantin.ananyev@int=
el.com</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex">&gt; checks if ipv4 and udptcp cksum offload capability available<br>
&gt; If not available, cksum is verified through software<br>
&gt; If cksum is corrupt, packet is dropped, rest of the packets<br>
&gt; are forwarded back.<br>
<br>
>From what I see right now l3fwd:<br>
=C2=A0 =C2=A0a) enables HW RX cksum offload <br>
=C2=A0 =C2=A0b) simply ignores HW provided cksum status <br>
Which came as a real surprise to me. <br>
Feel free to correct me if I missed something obvious here.<br>
<br>
So, I think first we need to add missing check first,<br>
even though it might cause some perf drop. <br>
Then make changes to actually check provided by HW status and<br>
when HW doesn&#39;t provide such offload do check in SW.<br>
<br>
Another alternative would be to remove request for HW offloads<br>
and document l3fwd that it doesn&#39;t check checksums at all,<br>
but I don&#39;t think it is a good way.<br>
<br>
&gt; Bugzilla ID:545<br>
&gt; Signed-off-by: Usama Nadeem &lt;<a href=3D"mailto:usama.nadeem@emumba.=
com" target=3D"_blank">usama.nadeem@emumba.com</a>&gt;<br>
&gt; ---<br>
&gt;=C2=A0 examples/l3fwd/l3fwd.h=C2=A0 =C2=A0 =C2=A0|=C2=A0 6 ++++<br>
&gt;=C2=A0 examples/l3fwd/l3fwd_lpm.c | 72 ++++++++++++++++++++++++++++++++=
++++--<br>
&gt;=C2=A0 examples/l3fwd/main.c=C2=A0 =C2=A0 =C2=A0 | 33 +++++++++++++++--=
<br>
&gt;=C2=A0 3 files changed, 105 insertions(+), 6 deletions(-)<br>
&gt; <br>
&gt; diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h<br>
&gt; index a808d60247..c2c21a91fb 100644<br>
&gt; --- a/examples/l3fwd/l3fwd.h<br>
&gt; +++ b/examples/l3fwd/l3fwd.h<br>
&gt; @@ -55,6 +55,8 @@<br>
&gt;=C2=A0 #define L3FWD_HASH_ENTRIES=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0(1024*1024*1)<br>
&gt;=C2=A0 #endif<br>
&gt;=C2=A0 #define HASH_ENTRY_NUMBER_DEFAULT=C2=A0 =C2=A0 4<br>
&gt; +extern bool l3_sft_cksum;<br>
&gt; +extern bool l4_sft_cksum;<br>
<br>
About the approach itself.<br>
We have similar issue for HW PTYPE recognition - some HW doesn&#39;t suppor=
t it.<br>
So we check HW capabilities and if required we setup SW RX callbacks to do<=
br>
determine PTYPE in SW. Note that for EM/LPM we have different callbacks.<br=
>
I think for cksum checks we can do the same:<br>
check HW capabilities, if they are missing add a new callback that would<br=
>
calculate/check cksum and set=C2=A0 RTE_MBUF_F_RX_*_CKSUM_* flags.<br>
That way it will HW/SW cksum will be transparent for the rest of l3fwd code=
.=C2=A0 <br>
<br>
About cksums required: for LPM/FIB mode just IPv4 cksum seems enough.<br>
For EM we probably need L4 cksum too, though not sure is it really needed.<=
br>
Wonder what other people think here? <br>
<br>
=C2=A0&gt;=C2=A0 struct mbuf_table {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0uint16_t len;<br>
&gt; @@ -210,6 +212,10 @@ em_main_loop(__rte_unused void *dummy);<br>
&gt;=C2=A0 int<br>
&gt;=C2=A0 lpm_main_loop(__rte_unused void *dummy);<br>
&gt; <br>
&gt; +int<br>
&gt; +check_software_cksum(struct rte_mbuf **pkts_burst,<br>
&gt; +struct rte_mbuf **pkts_burst_to_send, int nb_rx);<br>
&gt; +<br>
&gt;=C2=A0 int<br>
&gt;=C2=A0 fib_main_loop(__rte_unused void *dummy);<br>
&gt; <br>
&gt; diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c<b=
r>
&gt; index 232b606b54..ecaf323943 100644<br>
&gt; --- a/examples/l3fwd/l3fwd_lpm.c<br>
&gt; +++ b/examples/l3fwd/l3fwd_lpm.c<br>
&gt; @@ -26,6 +26,7 @@<br>
&gt;=C2=A0 #include &lt;rte_udp.h&gt;<br>
&gt;=C2=A0 #include &lt;rte_lpm.h&gt;<br>
&gt;=C2=A0 #include &lt;rte_lpm6.h&gt;<br>
&gt; +#include &lt;rte_net.h&gt;<br>
&gt; <br>
&gt;=C2=A0 #include &quot;l3fwd.h&quot;<br>
&gt;=C2=A0 #include &quot;l3fwd_event.h&quot;<br>
&gt; @@ -139,16 +140,65 @@ lpm_get_dst_port_with_ipv4(const struct lcore_co=
nf *qconf, struct rte_mbuf *pkt,<br>
&gt;=C2=A0 #include &quot;l3fwd_lpm.h&quot;<br>
&gt;=C2=A0 #endif<br>
&gt; <br>
&gt; +<br>
&gt; +int check_software_cksum(struct rte_mbuf **pkts_burst,<br>
&gt; +struct rte_mbuf **pkts_burst_to_send, int nb_rx)<br>
&gt; +{<br>
&gt; +=C2=A0 =C2=A0 =C2=A0int j;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0int i =3D 0;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0struct rte_net_hdr_lens hdr_lens;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0struct rte_ipv4_hdr *ipv4_hdr;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0void *l3_hdr;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0void *l4_hdr;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0rte_be16_t prev_cksum;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0int dropped_pkts_udp_tcp =3D 0;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0int dropped_pkts_ipv4 =3D 0;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0bool dropped;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0for (j =3D 0; j &lt; nb_rx; j++) {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dropped =3D false;<br=
>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_net_get_ptype(pkt=
s_burst[j], &amp;hdr_lens, RTE_PTYPE_ALL_MASK);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l3_hdr =3D rte_pktmbu=
f_mtod_offset(pkts_burst[j],<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0void *, hdr_lens.l2_l=
en);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l4_hdr =3D rte_pktmbu=
f_mtod_offset(pkts_burst[j],<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0void *, hdr_lens.l2_l=
en + hdr_lens.l3_len);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipv4_hdr =3D l3_hdr;<=
br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0prev_cksum =3D ipv4_h=
dr-&gt;hdr_checksum;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipv4_hdr-&gt;hdr_chec=
ksum =3D 0;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ipv4_hdr-&gt;hdr_chec=
ksum =3D rte_ipv4_cksum(ipv4_hdr);<br>
&gt; +<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l3_sft_cksum &amp=
;&amp; prev_cksum !=3D ipv4_hdr-&gt;hdr_checksum) {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0rte_pktmbuf_free(pkts_burst[j]);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0dropped_pkts_ipv4++;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0dropped =3D true;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} else if (l4_sft_cks=
um &amp;&amp;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_ipv4_udptcp_cksum_verify<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(l3_hdr, l4_hdr) !=3D 0) {<br>
&gt; +<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0rte_pktmbuf_free(pkts_burst[j]);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0dropped_pkts_udp_tcp++;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0dropped =3D true;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (dropped =3D=3D fa=
lse) {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0pkts_burst_to_send[i] =3D pkts_burst[j];<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0i++;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
&gt; +<br>
&gt; +=C2=A0 =C2=A0 =C2=A0}<br>
&gt; +=C2=A0 =C2=A0 =C2=A0return dropped_pkts_udp_tcp+dropped_pkts_ipv4;<br=
>
&gt; +}<br>
&gt; +<br>
&gt;=C2=A0 /* main processing loop */<br>
&gt;=C2=A0 int<br>
&gt;=C2=A0 lpm_main_loop(__rte_unused void *dummy)<br>
&gt;=C2=A0 {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0struct rte_mbuf *pkts_burst[MAX_PKT_BURST];<=
br>
&gt; +=C2=A0 =C2=A0 =C2=A0struct rte_mbuf *pkts_burst_to_send[MAX_PKT_BURST=
];<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned lcore_id;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0uint64_t prev_tsc, diff_tsc, cur_tsc;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0int i, nb_rx;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0uint16_t portid;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0uint8_t queueid;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0int dropped;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0struct lcore_conf *qconf;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0const uint64_t drain_tsc =3D (rte_get_tsc_hz=
() + US_PER_S - 1) /<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0US_PER_S * BURST=
_TX_DRAIN_US;<br>
&gt; @@ -209,19 +259,35 @@ lpm_main_loop(__rte_unused void *dummy)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0if (nb_rx =3D=3D 0)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0continue;<br>
&gt; <br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0if (l3_sft_cksum || l4_sft_cksum) {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dropped =3D check_software_cksum(pkts_bu=
rst,<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pkts_burst_to_send,=C2=A0 =C2=A0 =C2=A0n=
b_rx);<br>
&gt; +<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0nb_rx =3D nb_rx-dropped;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0}<br>
&gt; +<br>
&gt; +<br>
&gt;=C2=A0 #if defined RTE_ARCH_X86 || defined __ARM_NEON \<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 || defined RTE_ARCH_PPC_64<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l3_sft_cksum =3D=
=3D false &amp;&amp; l4_sft_cksum =3D=3D false)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0l3fwd_lpm_send_packets(nb_rx, pkts_burst,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0portid, qconf);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0l3fwd_lpm_send_packets(nb_rx, pkts_burst_to_send,<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0portid, qconf);<br>
&gt; +<br>
&gt;=C2=A0 #else<br>
&gt; -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst,<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0if (l3_sft_cksum =3D=3D false &amp;&amp; l4_sft_cksum =3D=3D false)<=
br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l3fwd_lpm_no_opt_send_packets(nb_rx, pkt=
s_burst,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0portid, qconf);<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0else<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l3fwd_lpm_no_opt_send_packets(nb_rx,<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pkts_burst_to_send, portid, qconf);<br>
&gt; +<br>
&gt;=C2=A0 #endif /* X86 */<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
&gt; -<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cur_tsc =3D rte_=
rdtsc();<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
&gt; -<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;<br>
&gt;=C2=A0 }<br>
&gt; <br>
&gt; diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c<br>
&gt; index 00ac267af1..a54aca070d 100644<br>
&gt; --- a/examples/l3fwd/main.c<br>
&gt; +++ b/examples/l3fwd/main.c<br>
&gt; @@ -61,6 +61,9 @@ static uint16_t nb_txd =3D RTE_TEST_TX_DESC_DEFAULT;=
<br>
&gt;=C2=A0 /**&lt; Ports set in promiscuous mode off by default. */<br>
&gt;=C2=A0 static int promiscuous_on;<br>
&gt; <br>
&gt; +bool l3_sft_cksum;<br>
&gt; +bool l4_sft_cksum;<br>
&gt; +<br>
&gt;=C2=A0 /* Select Longest-Prefix, Exact match or Forwarding Information =
Base. */<br>
&gt;=C2=A0 enum L3FWD_LOOKUP_MODE {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0L3FWD_LOOKUP_DEFAULT,<br>
&gt; @@ -123,7 +126,6 @@ static struct rte_eth_conf port_conf =3D {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.mq_mode =3D ETH=
_MQ_RX_RSS,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.max_rx_pkt_len =
=3D RTE_ETHER_MAX_LEN,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.split_hdr_size =
=3D 0,<br>
&gt; -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.offloads =3D DEV_RX_=
OFFLOAD_CHECKSUM,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0},<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0.rx_adv_conf =3D {<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0.rss_conf =3D {<=
br>
&gt; @@ -981,6 +983,7 @@ prepare_ptype_parser(uint16_t portid, uint16_t que=
ueid)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;<br>
&gt;=C2=A0 }<br>
&gt; <br>
&gt; +<br>
&gt;=C2=A0 static void<br>
&gt;=C2=A0 l3fwd_poll_resource_setup(void)<br>
&gt;=C2=A0 {<br>
&gt; @@ -993,7 +996,8 @@ l3fwd_poll_resource_setup(void)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int nb_ports;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int lcore_id;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0int ret;<br>
&gt; -<br>
&gt; +=C2=A0 =C2=A0 =C2=A0l3_sft_cksum =3D false;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0l4_sft_cksum =3D false;<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0if (check_lcore_params() &lt; 0)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rte_exit(EXIT_FA=
ILURE, &quot;check_lcore_params failed\n&quot;);<br>
&gt; <br>
&gt; @@ -1034,11 +1038,34 @@ l3fwd_poll_resource_setup(void)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0rte_exit(EXIT_FAILURE,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&quot;Error during getting device =
(port %u) info: %s\n&quot;,<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0portid, strerror(-ret));<br>
&gt; -<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (dev_info.tx_=
offload_capa &amp; DEV_TX_OFFLOAD_MBUF_FAST_FREE)<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0local_port_conf.txmode.offloads |=3D<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DEV_TX_OFFLOAD_MBUF_FAST_FREE;<br>
&gt; <br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (dev_info.rx_offlo=
ad_capa &amp; DEV_RX_OFFLOAD_IPV4_CKSUM)<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0local_port_conf.rxmode.offloads |=3D<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0DEV_RX_OFFLOAD_IPV4_CKSUM;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0l3_sft_cksum =3D true;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0printf(&quot;WARNING: IPV4 checksum offload not available.\n&quot;);=
<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0}<br>
&gt; +<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (dev_info.rx_offlo=
ad_capa &amp; DEV_RX_OFFLOAD_UDP_CKSUM)<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0local_port_conf.rxmode.offloads |=3D<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DEV_RX_OFFLOAD_UDP_CKSUM;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0l4_sft_cksum =3D true;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0printf(&quot;WARNING: UDP checksum offload not available.\n&quot;);<=
br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
&gt; +<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (dev_info.rx_offlo=
ad_capa &amp; DEV_RX_OFFLOAD_TCP_CKSUM)<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0local_port_conf.rxmode.offloads |=3D<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DEV_RX_OFFLOAD_TCP_CKSUM;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else {<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0l4_sft_cksum =3D true;<br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0printf(&quot;WARNING: TCP checksum offload not available.\n&quot;);<=
br>
&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
&gt; +<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0local_port_conf.=
rx_adv_conf.rss_conf.rss_hf &amp;=3D<br>
&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0dev_info.flow_type_rss_offloads;<br>
&gt; <br>
&gt; --<br>
&gt; 2.25.1<br>
<br>
</blockquote></div><br clear=3D"all"><div><br></div>-- <br><div dir=3D"ltr"=
 class=3D"gmail_signature"><div dir=3D"ltr">-Usama<br></div></div>

--000000000000d6472505d5877325--