Hello,

On Wed, Jan 9, 2019 at 4:44 AM Darrell Ball <dlu...@gmail.com> wrote:

> Fixes: bd5e81a0e596 ("Userspace Datapath: Add ALG infra and FTP.")
> Signed-off-by: Darrell Ball <dlu...@gmail.com>
> ---
>
> Backport to 2.8.
>
>  lib/conntrack.c | 10 ++++------
>  1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index 6f6021a..e992b77 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -3255,10 +3255,9 @@ handle_ftp_ctl(struct conntrack *ct, const struct
> conn_lookup_ctx *ctx,
>              uint32_t tcp_ack = ntohl(get_16aligned_be32(&th->tcp_ack));
>
>              if ((seq_skew > 0) && (tcp_ack < seq_skew)) {
> -                /* Should not be possible; will be marked invalid. */
> -                tcp_ack = 0;
> +                tcp_ack = UINT32_MAX - (seq_skew - tcp_ack - 1);
>              } else if ((seq_skew < 0) && (UINT32_MAX - tcp_ack <
> -seq_skew)) {
> -                tcp_ack = (-seq_skew) - (UINT32_MAX - tcp_ack);
> +                tcp_ack = (-seq_skew) - (UINT32_MAX - tcp_ack) - 1;
>              } else {
>                  tcp_ack -= seq_skew;
>              }
> @@ -3267,10 +3266,9 @@ handle_ftp_ctl(struct conntrack *ct, const struct
> conn_lookup_ctx *ctx,
>          } else {
>              uint32_t tcp_seq = ntohl(get_16aligned_be32(&th->tcp_seq));
>              if ((seq_skew > 0) && (UINT32_MAX - tcp_seq < seq_skew)) {
> -                tcp_seq = seq_skew - (UINT32_MAX - tcp_seq);
> +                tcp_seq = seq_skew - (UINT32_MAX - tcp_seq) - 1;
>              } else if ((seq_skew < 0) && (tcp_seq < -seq_skew)) {
> -                /* Should not be possible; will be marked invalid. */
> -                tcp_seq = 0;
> +                tcp_seq = UINT32_MAX - ((-seq_skew) - tcp_seq - 1);
>              } else {
>                  tcp_seq += seq_skew;
>              }
> --
> 1.9.1
>
>
Ah, now that I think about it, I had seen some packets with ack == 0 but
did not reproduce (it was in my todolist).
Good catch.

Just wondering, can't we rely integer promotion then truncation on 32bits ?
My test program tends to show it works.

Something like:

diff --git a/lib/conntrack.c b/lib/conntrack.c
index eb36353..04ddf5e 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -3329,32 +3329,13 @@ handle_ftp_ctl(struct conntrack *ct, const struct
conn_lookup_ctx *ctx,

     if (nat && ec->seq_skew != 0) {
         if (ctx->reply != ec->seq_skew_dir) {
-
             uint32_t tcp_ack = ntohl(get_16aligned_be32(&th->tcp_ack));

-            if ((ec->seq_skew > 0) && (tcp_ack < ec->seq_skew)) {
-                /* Should not be possible; will be marked invalid. */
-                tcp_ack = 0;
-            } else if ((ec->seq_skew < 0) &&
-                       (UINT32_MAX - tcp_ack < -ec->seq_skew)) {
-                tcp_ack = (-ec->seq_skew) - (UINT32_MAX - tcp_ack);
-            } else {
-                tcp_ack -= ec->seq_skew;
-            }
-            ovs_be32 new_tcp_ack = htonl(tcp_ack);
-            put_16aligned_be32(&th->tcp_ack, new_tcp_ack);
+            put_16aligned_be32(&th->tcp_ack, htonl(tcp_ack -
ec->seq_skew));
         } else {
             uint32_t tcp_seq = ntohl(get_16aligned_be32(&th->tcp_seq));
-            if ((ec->seq_skew > 0) && (UINT32_MAX - tcp_seq <
ec->seq_skew)) {
-                tcp_seq = ec->seq_skew - (UINT32_MAX - tcp_seq);
-            } else if ((ec->seq_skew < 0) && (tcp_seq < -ec->seq_skew)) {
-                /* Should not be possible; will be marked invalid. */
-                tcp_seq = 0;
-            } else {
-                tcp_seq += ec->seq_skew;
-            }
-            ovs_be32 new_tcp_seq = htonl(tcp_seq);
-            put_16aligned_be32(&th->tcp_seq, new_tcp_seq);
+
+            put_16aligned_be32(&th->tcp_seq, htonl(tcp_seq +
ec->seq_skew));
         }
     }


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

Reply via email to