diff options
-rw-r--r-- | Vagrantfile | 9 | ||||
-rw-r--r-- | Vagrantfile-FreeBSD | 2 | ||||
-rw-r--r-- | lib/conntrack.c | 74 | ||||
-rw-r--r-- | tests/atlocal.in | 3 | ||||
-rw-r--r-- | tests/system-traffic.at | 14 |
5 files changed, 59 insertions, 43 deletions
diff --git a/Vagrantfile b/Vagrantfile index 0192f66ea..fbd772a1b 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -12,7 +12,8 @@ dnf -y install autoconf automake openssl-devel libtool \ python-twisted python-zope-interface \ desktop-file-utils groff graphviz rpmdevtools nc curl \ wget python-six pyftpdlib checkpolicy selinux-policy-devel \ - libcap-ng-devel kernel-devel-`uname -r` ethtool python-tftpy + libcap-ng-devel kernel-devel-`uname -r` ethtool python-tftpy \ + lftp echo "search extra update built-in" >/etc/depmod.d/search_path.conf SCRIPT @@ -28,7 +29,8 @@ aptitude -y install -R \ wget python-six ethtool \ libcap-ng-dev libssl-dev python-dev openssl \ python-pyftpdlib python-flake8 python-tftpy \ - linux-headers-`uname -r` + linux-headers-`uname -r` \ + lftp SCRIPT $bootstrap_centos = <<SCRIPT @@ -37,7 +39,8 @@ yum -y install autoconf automake openssl-devel libtool \ python-twisted-core python-zope-interface \ desktop-file-utils groff graphviz rpmdevtools nc curl \ wget python-six pyftpdlib checkpolicy selinux-policy-devel \ - libcap-ng-devel kernel-devel-`uname -r` ethtool net-tools + libcap-ng-devel kernel-devel-`uname -r` ethtool net-tools \ + lftp SCRIPT $configure_ovs = <<SCRIPT diff --git a/Vagrantfile-FreeBSD b/Vagrantfile-FreeBSD index 8f00abe8d..52599eefa 100644 --- a/Vagrantfile-FreeBSD +++ b/Vagrantfile-FreeBSD @@ -12,7 +12,7 @@ Vagrant.require_version ">=1.7.0" $bootstrap_freebsd = <<SCRIPT sed -e 's/\#DEFAULT_ALWAYS_YES = false/DEFAULT_ALWAYS_YES = true/g' -e 's/\#ASSUME_ALWAYS_YES = false/ASSUME_ALWAYS_YES = true/g' /usr/local/etc/pkg.conf > /tmp/pkg.conf mv -f /tmp/pkg.conf /usr/local/etc/pkg.conf -pkg install automake libtool wget python py27-six gmake +pkg install automake libtool wget python py27-six gmake lftp SCRIPT $configure_ovs = <<SCRIPT diff --git a/lib/conntrack.c b/lib/conntrack.c index 6f6021a97..ae549bda3 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -3170,9 +3170,8 @@ repl_ftp_v6_addr(struct dp_packet *pkt, struct ct_addr v6_addr_rep, static void handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, - struct dp_packet *pkt, - const struct conn *conn_for_expectation, - long long now, enum ftp_ctl_pkt ftp_ctl, bool nat) + struct dp_packet *pkt, const struct conn *ec, long long now, + enum ftp_ctl_pkt ftp_ctl, bool nat) { struct ip_header *l3_hdr = dp_packet_l3(pkt); ovs_be32 v4_addr_rep = 0; @@ -3180,31 +3179,24 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, size_t addr_offset_from_ftp_data_start = 0; size_t addr_size = 0; char *ftp_data_start; - bool do_seq_skew_adj = true; enum ct_alg_mode mode = CT_FTP_MODE_ACTIVE; if (detect_ftp_ctl_type(ctx, pkt) != ftp_ctl) { return; } - if (!nat || !conn_for_expectation->seq_skew) { - do_seq_skew_adj = false; - } - struct ovs_16aligned_ip6_hdr *nh6 = dp_packet_l3(pkt); int64_t seq_skew = 0; - if (ftp_ctl == CT_FTP_CTL_OTHER) { - seq_skew = conn_for_expectation->seq_skew; - } else if (ftp_ctl == CT_FTP_CTL_INTEREST) { + if (ftp_ctl == CT_FTP_CTL_INTEREST) { enum ftp_ctl_pkt rc; if (ctx->key.dl_type == htons(ETH_TYPE_IPV6)) { - rc = process_ftp_ctl_v6(ct, pkt, conn_for_expectation, + rc = process_ftp_ctl_v6(ct, pkt, ec, &v6_addr_rep, &ftp_data_start, &addr_offset_from_ftp_data_start, &addr_size, &mode); } else { - rc = process_ftp_ctl_v4(ct, pkt, conn_for_expectation, + rc = process_ftp_ctl_v4(ct, pkt, ec, &v4_addr_rep, &ftp_data_start, &addr_offset_from_ftp_data_start); } @@ -3217,62 +3209,63 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, uint16_t ip_len; if (ctx->key.dl_type == htons(ETH_TYPE_IPV6)) { - seq_skew = repl_ftp_v6_addr(pkt, v6_addr_rep, ftp_data_start, - addr_offset_from_ftp_data_start, - addr_size, mode); + if (nat) { + seq_skew = repl_ftp_v6_addr(pkt, v6_addr_rep, + ftp_data_start, + addr_offset_from_ftp_data_start, + addr_size, mode); + } + if (seq_skew) { - ip_len = ntohs(nh6->ip6_ctlun.ip6_un1.ip6_un1_plen); - ip_len += seq_skew; + ip_len = ntohs(nh6->ip6_ctlun.ip6_un1.ip6_un1_plen) + + seq_skew; nh6->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(ip_len); - conn_seq_skew_set(ct, &conn_for_expectation->key, now, - seq_skew, ctx->reply); } } else { - seq_skew = repl_ftp_v4_addr(pkt, v4_addr_rep, ftp_data_start, - addr_offset_from_ftp_data_start); - ip_len = ntohs(l3_hdr->ip_tot_len); + if (nat) { + seq_skew = repl_ftp_v4_addr(pkt, v4_addr_rep, + ftp_data_start, + addr_offset_from_ftp_data_start); + } if (seq_skew) { - ip_len += seq_skew; + ip_len = ntohs(l3_hdr->ip_tot_len) + seq_skew; l3_hdr->ip_csum = recalc_csum16(l3_hdr->ip_csum, l3_hdr->ip_tot_len, htons(ip_len)); l3_hdr->ip_tot_len = htons(ip_len); - conn_seq_skew_set(ct, &conn_for_expectation->key, now, - seq_skew, ctx->reply); } } } else { OVS_NOT_REACHED(); } - } else { - OVS_NOT_REACHED(); } struct tcp_header *th = dp_packet_l4(pkt); - if (do_seq_skew_adj && seq_skew != 0) { - if (ctx->reply != conn_for_expectation->seq_skew_dir) { + 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 ((seq_skew > 0) && (tcp_ack < seq_skew)) { + if ((ec->seq_skew > 0) && (tcp_ack < ec->seq_skew)) { /* Should not be possible; will be marked invalid. */ tcp_ack = 0; - } else if ((seq_skew < 0) && (UINT32_MAX - tcp_ack < -seq_skew)) { - tcp_ack = (-seq_skew) - (UINT32_MAX - tcp_ack); + } 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 -= seq_skew; + 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 ((seq_skew > 0) && (UINT32_MAX - tcp_seq < seq_skew)) { - tcp_seq = seq_skew - (UINT32_MAX - tcp_seq); - } else if ((seq_skew < 0) && (tcp_seq < -seq_skew)) { + 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 += seq_skew; + tcp_seq += ec->seq_skew; } ovs_be32 new_tcp_seq = htonl(tcp_seq); put_16aligned_be32(&th->tcp_seq, new_tcp_seq); @@ -3290,6 +3283,11 @@ handle_ftp_ctl(struct conntrack *ct, const struct conn_lookup_ctx *ctx, uint8_t pad = dp_packet_l2_pad_size(pkt); th->tcp_csum = csum_finish( csum_continue(tcp_csum, th, tail - (char *) th - pad)); + + if (seq_skew) { + conn_seq_skew_set(ct, &ec->key, now, seq_skew + ec->seq_skew, + ctx->reply); + } } static void diff --git a/tests/atlocal.in b/tests/atlocal.in index 388f79ed8..5eff0a0aa 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -193,6 +193,9 @@ fi # Set HAVE_TCPDUMP find_command tcpdump +# Set HAVE_LFTP +find_command lftp + CURL_OPT="-g -v --max-time 1 --retry 2 --retry-delay 1 --connect-timeout 1" # Determine whether "diff" supports "normal" diffs. (busybox diff does not.) diff --git a/tests/system-traffic.at b/tests/system-traffic.at index b2ab80010..14ce7d24e 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -4226,6 +4226,7 @@ dnl NAT, using the provided flow table. m4_define([CHECK_FTP_NAT], [AT_SETUP([conntrack - FTP NAT $1]) AT_SKIP_IF([test $HAVE_FTP = no]) + AT_SKIP_IF([test $HAVE_LFTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() @@ -4246,7 +4247,18 @@ m4_define([CHECK_FTP_NAT], OVS_START_L7([at_ns1], [ftp]) dnl FTP requests from p0->p1 should work fine. - NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 -4 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v --server-response --no-remove-listing -o wget0.log -d]) + AT_DATA([ftp.cmd], [dnl +set net:max-retries 1 +set net:timeout 1 +set ftp:passive-mode off +cache off +connect ftp://anonymous:@10.1.1.2 +ls +ls +ls +ls +]) + NS_CHECK_EXEC([at_ns0], [lftp -f ftp.cmd > lftp.log]) dnl Discards CLOSE_WAIT and CLOSING AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [$4]) |