summaryrefslogtreecommitdiff
path: root/lib/conntrack.c
diff options
context:
space:
mode:
authorDarrell Ball <dlu998@gmail.com>2019-01-15 18:58:17 -0800
committerBen Pfaff <blp@ovn.org>2019-01-18 16:16:17 -0800
commitd13d711503595c0265ebf58f68250bbc9225ee9b (patch)
treec54bed04b9e6f0a44e2b404dab4a8227c7d801be /lib/conntrack.c
parentefa29a891031431fb1e69026f3e4d6c17f6f92c2 (diff)
downloadopenvswitch-d13d711503595c0265ebf58f68250bbc9225ee9b.tar.gz
conntrack: Fix FTP seq_skew boundary adjustments.
At the same time, splice out a function and also rely on the compiler for overflow/underflow handling. Found by inspection. Fixes: bd5e81a0e596 ("Userspace Datapath: Add ALG infra and FTP.") Signed-off-by: Darrell Ball <dlu998@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib/conntrack.c')
-rw-r--r--lib/conntrack.c38
1 files changed, 10 insertions, 28 deletions
diff --git a/lib/conntrack.c b/lib/conntrack.c
index c6864b9eb..f732b9ee4 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -3176,6 +3176,13 @@ repl_ftp_v6_addr(struct dp_packet *pkt, struct ct_addr v6_addr_rep,
return overall_delta;
}
+/* Increment/decrement a TCP sequence number. */
+static void
+adj_seqnum(ovs_16aligned_be32 *val, int32_t inc)
+{
+ put_16aligned_be32(val, htonl(ntohl(get_16aligned_be32(val)) + inc));
+}
+
static void
handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
struct dp_packet *pkt, const struct conn *ec, long long now,
@@ -3250,34 +3257,9 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx,
struct tcp_header *th = dp_packet_l4(pkt);
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);
- } 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);
- }
+ ctx->reply != ec->seq_skew_dir ?
+ adj_seqnum(&th->tcp_ack, -ec->seq_skew) :
+ adj_seqnum(&th->tcp_seq, ec->seq_skew);
}
th->tcp_csum = 0;