On Fri, Jan 14, 2022 at 3:33 PM Flavio Leitner <f...@sysclose.org> wrote:
>
>
> Hi Mike,
>
> Thanks for working on this issue.
>
> On Fri, Jan 14, 2022 at 10:45:35AM -0500, Mike Pattrick wrote:
> > Formerly when userspace TSO was enabled but with a non-DKDK interface
> > without support IP checksum offloading, FTP NAT connections would fail
> > if the packet length changed. This can happen if the packets length
> > changes during L7 NAT translation, predominantly with FTP.
> >
> > Now we correct the IP header checksum if hwol is disabled or if DPDK
> > will not handle the IP checksum. This fixes the conntrack - IPv4 FTP
> > Passive with DNAT" test when run with check-system-tso.
> >
> > Reported-by: Flavio Leitner <f...@sysclose.org>
>
> Actually, this was initially reported by Ilya.
>
> > Signed-off-by: Mike Pattrick <m...@redhat.com>
> > ---
> >  lib/conntrack.c | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/conntrack.c b/lib/conntrack.c
> > index 33a1a9295..1b8a26ac2 100644
> > --- a/lib/conntrack.c
> > +++ b/lib/conntrack.c
> > @@ -3402,7 +3402,8 @@ handle_ftp_ctl(struct conntrack *ct, const struct 
> > conn_lookup_ctx *ctx,
> >                  }
> >                  if (seq_skew) {
> >                      ip_len = ntohs(l3_hdr->ip_tot_len) + seq_skew;
> > -                    if (!dp_packet_hwol_is_ipv4(pkt)) {
> > +                    if (!dp_packet_hwol_is_ipv4(pkt) ||
> > +                        !dp_packet_ip_checksum_valid(pkt)) {
> >                          l3_hdr->ip_csum = recalc_csum16(l3_hdr->ip_csum,
> >                                                          l3_hdr->ip_tot_len,
> >                                                          htons(ip_len));
>
> The problem is that the current code doesn't include IPv4 csum
> handling as required by the Linux software ports.
>
> The patch above resolves the unit test issue because non-DPDK
> interfaces will not flag the packet with good IP csum, and then
> the csum is updated accordingly. However, a packet coming from
> a physical DPDK port can have that flag set by the PMD, then if
> it goes through that part the IP csum is not updated, which
> will cause a problem if that packet is sent out over a Linux
> software port later.

This is a good point, I was trying to get to a happy medium without
repurposing the patchset that you had previously submitted. That way
this patch could be available immediately, and your more thorough TSO
patchset could be applied after.

I had also prepared a larger patch as part of this work, but scrapped
it because it was duplicating a lot of the work you had previously
done. But if you prefer the more substantial solution, we can scrap
this patch and I can submit the larger one.

Cheers,
M

> A better solution would to have the IP csum updated if the
> packet requires and the port doesn't support that as proposed
> in the RFC[1].
>
> [1] https://mail.openvswitch.org/pipermail/ovs-dev/2021-December/389993.html
>     [See: dp_packet_ol_send_prepare()]
>
> Perhaps we can achieve something in the middle with something
> like below (not tested).
>
> What do you think?
>
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index 33a1a9295..9e0364719 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -3403,6 +3403,8 @@ handle_ftp_ctl(struct conntrack *ct, const struct 
> conn_lookup_ctx *ctx,
>                  if (seq_skew) {
>                      ip_len = ntohs(l3_hdr->ip_tot_len) + seq_skew;
>                      if (!dp_packet_hwol_is_ipv4(pkt)) {
> +                        dp_packet_ip_checksum_reset_valid(pkt);
> +                    } else {
>                          l3_hdr->ip_csum = recalc_csum16(l3_hdr->ip_csum,
>                                                          l3_hdr->ip_tot_len,
>                                                          htons(ip_len));
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index ee0805ae6..8a880a0ce 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -25,6 +25,7 @@
>  #include <rte_mbuf.h>
>  #endif
>
> +#include "csum.h"
>  #include "netdev-afxdp.h"
>  #include "netdev-dpdk.h"
>  #include "openvswitch/list.h"
> @@ -1064,6 +1065,20 @@ dp_packet_ip_checksum_valid(const struct dp_packet *p)
>              DP_PACKET_OL_RX_IP_CKSUM_GOOD;
>  }
>
> +/* Sets IP valid checksum flag in packet 'p'. */
> +static inline void
> +dp_packet_ip_checksum_set_valid(const struct dp_packet *p)
> +{
> +    *dp_packet_ol_flags_ptr(p) |= DP_PACKET_OL_RX_IP_CKSUM_GOOD;
> +}
> +
> +/* Resets IP valid checksum flag in packet 'p'. */
> +static inline void
> +dp_packet_ip_checksum_reset_valid(const struct dp_packet *p)
> +{
> +    *dp_packet_ol_flags_ptr(p) &= ~DP_PACKET_OL_RX_IP_CKSUM_GOOD;
> +}
> +
>  static inline bool
>  dp_packet_ip_checksum_bad(const struct dp_packet *p)
>  {
> @@ -1071,6 +1086,17 @@ dp_packet_ip_checksum_bad(const struct dp_packet *p)
>              DP_PACKET_OL_RX_IP_CKSUM_BAD;
>  }
>
> +/* Calculate and set the IPv4 header checksum in packet 'p'. */
> +static inline void
> +dp_packet_ip_set_header_csum(struct dp_packet *p)
> +{
> +    struct ip_header *ip = dp_packet_l3(p);
> +
> +    ovs_assert(ip);
> +    ip->ip_csum = 0;
> +    ip->ip_csum = csum(ip, sizeof *ip);
> +}
> +
>  static inline bool
>  dp_packet_l4_checksum_valid(const struct dp_packet *p)
>  {
> diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
> index 620a451de..a2a87ab92 100644
> --- a/lib/netdev-linux.c
> +++ b/lib/netdev-linux.c
> @@ -932,7 +932,6 @@ netdev_linux_common_construct(struct netdev *netdev_)
>          netdev_->ol_flags |= NETDEV_TX_OFFLOAD_TCP_CKSUM;
>          netdev_->ol_flags |= NETDEV_TX_OFFLOAD_UDP_CKSUM;
>          netdev_->ol_flags |= NETDEV_TX_OFFLOAD_SCTP_CKSUM;
> -        netdev_->ol_flags |= NETDEV_TX_OFFLOAD_IPV4_CKSUM;
>      }
>
>      return 0;
> diff --git a/lib/netdev.c b/lib/netdev.c
> index 8305f6c42..5bbde02af 100644
> --- a/lib/netdev.c
> +++ b/lib/netdev.c
> @@ -794,6 +794,15 @@ netdev_send_prepare_packet(const uint64_t netdev_flags,
>  {
>      uint64_t l4_mask;
>
> +    if (dp_packet_hwol_is_ipv4(packet)
> +        && !dp_packet_ip_checksum_valid(packet)
> +        && !(netdev_flags & NETDEV_TX_OFFLOAD_IPV4_CKSUM)) {
> +        /* The packet requested IPv4 offload and the netdev
> +         * doesn't support that. */
> +        dp_packet_ip_set_header_csum(packet);
> +        dp_packet_ip_checksum_set_valid(packet);
> +    }
> +
>      if (dp_packet_hwol_is_tso(packet)
>          && !(netdev_flags & NETDEV_TX_OFFLOAD_TCP_TSO)) {
>              /* Fall back to GSO in software. */
>
>
>
> --
> fbl
>

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to