mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
lib: Add support for tftp ct helper.
The kernel datapath provides support for TFTP helpers, so add support for this ALG to the commandline and OpenFlow encoding/decoding. Signed-off-by: Joe Stringer <joe@ovn.org> Acked-by: Daniele Di Proietto <diproiettod@vmware.com> Acked-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
parent
c26ed9c251
commit
40c7b2fc0d
@ -125,6 +125,10 @@ The datapath tests for userspace and Linux datapaths also rely upon:
|
||||
|
||||
- netcat. Several common implementations are known to work.
|
||||
|
||||
- curl. Version 7.47.0 is known to work. Earlier versions should also work.
|
||||
|
||||
- tftpy. Version 0.6.2 is known to work. Earlier versions should also work.
|
||||
|
||||
The ovs-vswitchd.conf.db(5) manpage will include an E-R diagram, in formats
|
||||
other than plain text, only if you have the following:
|
||||
|
||||
|
1
NEWS
1
NEWS
@ -26,6 +26,7 @@ Post-v2.6.0
|
||||
"selection_method" and related options in ovs-ofctl(8) for
|
||||
details.
|
||||
* The "sample" action now supports "ingress" and "egress" options.
|
||||
* The "ct" action now supports the TFTP ALG where support is available.
|
||||
- ovs-ofctl:
|
||||
* 'bundle' command now supports packet-out messages.
|
||||
* New syntax for 'ovs-ofctl packet-out' command, which uses the
|
||||
|
10
Vagrantfile
vendored
10
Vagrantfile
vendored
@ -9,9 +9,9 @@ $bootstrap_fedora = <<SCRIPT
|
||||
dnf -y update
|
||||
dnf -y install autoconf automake openssl-devel libtool \
|
||||
python-twisted-core python-zope-interface \
|
||||
desktop-file-utils groff graphviz rpmdevtools nc \
|
||||
desktop-file-utils groff graphviz rpmdevtools nc curl \
|
||||
wget python-six pyftpdlib checkpolicy selinux-policy-devel \
|
||||
libcap-ng-devel kernel-devel-`uname -r` ethtool
|
||||
libcap-ng-devel kernel-devel-`uname -r` ethtool python-tftpy
|
||||
echo "search extra update built-in" >/etc/depmod.d/search_path.conf
|
||||
SCRIPT
|
||||
|
||||
@ -23,10 +23,10 @@ aptitude -y install -R \
|
||||
debhelper dh-autoreconf uuid-runtime \
|
||||
autoconf automake libtool \
|
||||
python-all python-twisted-core python-twisted-conch \
|
||||
xdg-utils groff graphviz netcat \
|
||||
xdg-utils groff graphviz netcat curl \
|
||||
wget python-six ethtool \
|
||||
libcap-ng-dev libssl-dev python-dev openssl \
|
||||
python-pyftpdlib python-flake8 \
|
||||
python-pyftpdlib python-flake8 python-tftpy \
|
||||
linux-headers-`uname -r`
|
||||
SCRIPT
|
||||
|
||||
@ -34,7 +34,7 @@ $bootstrap_centos = <<SCRIPT
|
||||
yum -y update
|
||||
yum -y install autoconf automake openssl-devel libtool \
|
||||
python-twisted-core python-zope-interface \
|
||||
desktop-file-utils groff graphviz rpmdevtools nc \
|
||||
desktop-file-utils groff graphviz rpmdevtools nc curl \
|
||||
wget python-six pyftpdlib checkpolicy selinux-policy-devel \
|
||||
libcap-ng-devel kernel-devel-`uname -r` ethtool
|
||||
SCRIPT
|
||||
|
@ -566,6 +566,10 @@ enum nx_conntrack_flags {
|
||||
#define IPPORT_FTP 21
|
||||
#endif
|
||||
|
||||
#if !defined(IPPORT_TFTP)
|
||||
#define IPPORT_TFTP 69
|
||||
#endif
|
||||
|
||||
/* OFPACT_CT.
|
||||
*
|
||||
* Used for NXAST_CT. */
|
||||
|
@ -5454,10 +5454,19 @@ parse_CT(char *arg, struct ofpbuf *ofpacts,
|
||||
static void
|
||||
format_alg(int port, struct ds *s)
|
||||
{
|
||||
if (port == IPPORT_FTP) {
|
||||
switch(port) {
|
||||
case IPPORT_FTP:
|
||||
ds_put_format(s, "%salg=%sftp,", colors.param, colors.end);
|
||||
} else if (port) {
|
||||
break;
|
||||
case IPPORT_TFTP:
|
||||
ds_put_format(s, "%salg=%stftp,", colors.param, colors.end);
|
||||
break;
|
||||
case 0:
|
||||
/* Don't print. */
|
||||
break;
|
||||
default:
|
||||
ds_put_format(s, "%salg=%s%d,", colors.param, colors.end, port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7170,7 +7179,8 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
|
||||
|
||||
if (!dl_type_is_ip_any(flow->dl_type)
|
||||
|| (flow->ct_state & CS_INVALID && oc->flags & NX_CT_F_COMMIT)
|
||||
|| (oc->alg == IPPORT_FTP && flow->nw_proto != IPPROTO_TCP)) {
|
||||
|| (oc->alg == IPPORT_FTP && flow->nw_proto != IPPROTO_TCP)
|
||||
|| (oc->alg == IPPORT_TFTP && flow->nw_proto != IPPROTO_UDP)) {
|
||||
/* We can't downgrade to OF1.0 and expect inconsistent CT actions
|
||||
* be silently discarded. Instead, datapath flow install fails, so
|
||||
* it is better to flag inconsistent CT actions as hard errors. */
|
||||
|
@ -181,6 +181,10 @@ str_to_connhelper(const char *str, uint16_t *alg)
|
||||
*alg = IPPORT_FTP;
|
||||
return NULL;
|
||||
}
|
||||
if (!strcmp(str, "tftp")) {
|
||||
*alg = IPPORT_TFTP;
|
||||
return NULL;
|
||||
}
|
||||
return xasprintf("invalid conntrack helper \"%s\"", str);
|
||||
}
|
||||
|
||||
|
@ -4550,10 +4550,16 @@ static void
|
||||
put_ct_helper(struct ofpbuf *odp_actions, struct ofpact_conntrack *ofc)
|
||||
{
|
||||
if (ofc->alg) {
|
||||
if (ofc->alg == IPPORT_FTP) {
|
||||
switch(ofc->alg) {
|
||||
case IPPORT_FTP:
|
||||
nl_msg_put_string(odp_actions, OVS_CT_ATTR_HELPER, "ftp");
|
||||
} else {
|
||||
break;
|
||||
case IPPORT_TFTP:
|
||||
nl_msg_put_string(odp_actions, OVS_CT_ATTR_HELPER, "tftp");
|
||||
break;
|
||||
default:
|
||||
VLOG_WARN("Cannot serialize ct_helper %d\n", ofc->alg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,12 +117,24 @@ if test "$IS_WIN32" = "yes"; then
|
||||
HAVE_PYTHON3="no"
|
||||
fi
|
||||
|
||||
if test "$HAVE_PYTHON" = "yes" \
|
||||
&& test "x`$PYTHON $abs_top_srcdir/tests/test-l7.py --help | grep 'ftp'`" != x; then
|
||||
HAVE_PYFTPDLIB="yes"
|
||||
else
|
||||
HAVE_PYFTPDLIB="no"
|
||||
fi
|
||||
find_l7_lib()
|
||||
{
|
||||
set +x
|
||||
var=HAVE_`echo "$1" | tr '[a-z]' '[A-Z]'`
|
||||
if test "$HAVE_PYTHON" = "yes"; then
|
||||
result=$($PYTHON $abs_top_srcdir/tests/test-l7.py --help | grep "$1")
|
||||
if test "x${result}" != x; then
|
||||
eval ${var}="yes"
|
||||
else
|
||||
eval ${var}="no"
|
||||
fi
|
||||
else
|
||||
eval ${var}="no"
|
||||
fi
|
||||
}
|
||||
|
||||
find_l7_lib ftp
|
||||
find_l7_lib tftp
|
||||
|
||||
# Look for a commnand in the system. If it is found, defines
|
||||
# HAVE_COMMAND="yes", otherwise HAVE_COMMAND="no".
|
||||
@ -148,6 +160,8 @@ else
|
||||
NC_EOF_OPT="-q 1"
|
||||
fi
|
||||
|
||||
CURL_OPT="-g -v --max-time 1 --retry 2 --retry-delay 1 --connect-timeout 1"
|
||||
|
||||
# Turn off proxies.
|
||||
unset http_proxy
|
||||
unset https_proxy
|
||||
|
@ -320,6 +320,7 @@ ct(commit,zone=5)
|
||||
ct(commit,mark=0xa0a0a0a0/0xfefefefe)
|
||||
ct(commit,label=0x1234567890abcdef1234567890abcdef/0xf1f2f3f4f5f6f7f8f9f0fafbfcfdfeff)
|
||||
ct(commit,helper=ftp)
|
||||
ct(commit,helper=tftp)
|
||||
ct(nat)
|
||||
ct(commit,nat(src))
|
||||
ct(commit,nat(dst))
|
||||
|
@ -201,6 +201,9 @@ ffff 0018 00002320 0007 001f 00010004 000000000000f009
|
||||
# actions=ct(alg=ftp)
|
||||
ffff 0018 00002320 0023 0000 00000000 0000 FF 000000 0015
|
||||
|
||||
# actions=ct(alg=tftp)
|
||||
ffff 0018 00002320 0023 0000 00000000 0000 FF 000000 0045
|
||||
|
||||
# actions=ct(commit,nat(src))
|
||||
ffff 0028 00002320 0023 0001 00000000 0000 FF 000000 0000 dnl
|
||||
ffff 0010 00002320 0024 00 00 0001 0000
|
||||
|
@ -1987,7 +1987,7 @@ OVS_TRAFFIC_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([conntrack - FTP])
|
||||
AT_SKIP_IF([test $HAVE_PYFTPDLIB = no])
|
||||
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||
CHECK_CONNTRACK()
|
||||
CHECK_CONNTRACK_ALG()
|
||||
OVS_TRAFFIC_VSWITCHD_START()
|
||||
@ -2072,7 +2072,7 @@ OVS_TRAFFIC_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([conntrack - FTP over IPv6])
|
||||
AT_SKIP_IF([test $HAVE_PYFTPDLIB = no])
|
||||
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||
CHECK_CONNTRACK()
|
||||
CHECK_CONNTRACK_ALG()
|
||||
OVS_TRAFFIC_VSWITCHD_START()
|
||||
@ -2127,7 +2127,7 @@ OVS_TRAFFIC_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([conntrack - FTP with multiple expectations])
|
||||
AT_SKIP_IF([test $HAVE_PYFTPDLIB = no])
|
||||
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||
CHECK_CONNTRACK()
|
||||
CHECK_CONNTRACK_ALG()
|
||||
OVS_TRAFFIC_VSWITCHD_START()
|
||||
@ -2192,6 +2192,80 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=
|
||||
OVS_TRAFFIC_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([conntrack - TFTP])
|
||||
AT_SKIP_IF([test $HAVE_TFTP = no])
|
||||
CHECK_CONNTRACK()
|
||||
CHECK_CONNTRACK_ALG()
|
||||
OVS_TRAFFIC_VSWITCHD_START()
|
||||
|
||||
ADD_NAMESPACES(at_ns0, at_ns1)
|
||||
|
||||
ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
|
||||
ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
|
||||
|
||||
dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0.
|
||||
AT_DATA([flows1.txt], [dnl
|
||||
table=0,priority=1,action=drop
|
||||
table=0,priority=10,arp,action=normal
|
||||
table=0,priority=10,icmp,action=normal
|
||||
table=0,priority=100,in_port=1,udp,action=ct(alg=tftp,commit),2
|
||||
table=0,priority=100,in_port=2,udp,action=ct(table=1)
|
||||
table=1,in_port=2,udp,ct_state=+trk+est,action=1
|
||||
table=1,in_port=2,udp,ct_state=+trk+rel,action=1
|
||||
])
|
||||
|
||||
dnl Similar policy but without allowing all traffic from ns0->ns1.
|
||||
AT_DATA([flows2.txt], [dnl
|
||||
table=0,priority=1,action=drop
|
||||
table=0,priority=10,arp,action=normal
|
||||
table=0,priority=10,icmp,action=normal
|
||||
|
||||
dnl Allow outgoing UDP connections, and treat them as TFTP
|
||||
table=0,priority=100,in_port=1,udp,action=ct(table=1)
|
||||
table=1,in_port=1,udp,ct_state=+trk+new-rel,action=ct(commit,alg=tftp),2
|
||||
table=1,in_port=1,udp,ct_state=+trk+new+rel,action=ct(commit),2
|
||||
table=1,in_port=1,udp,ct_state=+trk+est,action=2
|
||||
|
||||
dnl Allow incoming TFTP data connections and responses to existing connections
|
||||
table=0,priority=100,in_port=2,udp,action=ct(table=1)
|
||||
table=1,in_port=2,udp,ct_state=+trk+est,action=1
|
||||
table=1,in_port=2,udp,ct_state=+trk+new+rel,action=1
|
||||
])
|
||||
|
||||
AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows1.txt])
|
||||
|
||||
OVS_START_L7([at_ns0], [tftp])
|
||||
OVS_START_L7([at_ns1], [tftp])
|
||||
|
||||
dnl TFTP requests from p1->p0 should fail due to network failure.
|
||||
NS_CHECK_EXEC([at_ns1], [[curl $CURL_OPT tftp://10.1.1.1/flows1.txt -o foo 2>curl0.log]], [28])
|
||||
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl
|
||||
])
|
||||
|
||||
dnl TFTP requests from p0->p1 should work fine.
|
||||
NS_CHECK_EXEC([at_ns0], [[curl $CURL_OPT tftp://10.1.1.2/flows1.txt -o foo 2>curl1.log]])
|
||||
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
|
||||
udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),helper=tftp
|
||||
])
|
||||
|
||||
dnl Try the second set of flows.
|
||||
AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows2.txt])
|
||||
AT_CHECK([ovs-appctl dpctl/flush-conntrack])
|
||||
|
||||
dnl TFTP requests from p1->p0 should fail due to network failure.
|
||||
NS_CHECK_EXEC([at_ns1], [[curl $CURL_OPT tftp://10.1.1.1/flows1.txt -o foo 2>curl2.log]], [28])
|
||||
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl
|
||||
])
|
||||
|
||||
dnl TFTP requests from p0->p1 should work fine.
|
||||
NS_CHECK_EXEC([at_ns0], [[curl $CURL_OPT tftp://10.1.1.2/flows1.txt -o foo 2>curl3.log]])
|
||||
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl
|
||||
udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.1,sport=<cleared>,dport=<cleared>),helper=tftp
|
||||
])
|
||||
|
||||
OVS_TRAFFIC_VSWITCHD_STOP
|
||||
AT_CLEANUP
|
||||
|
||||
AT_BANNER([conntrack - NAT])
|
||||
|
||||
AT_SETUP([conntrack - simple SNAT])
|
||||
@ -2524,7 +2598,7 @@ dnl Checks the implementation of conntrack with FTP ALGs in combination with
|
||||
dnl NAT, using the provided flow table.
|
||||
m4_define([CHECK_FTP_NAT],
|
||||
[AT_SETUP([conntrack - FTP NAT $1])
|
||||
AT_SKIP_IF([test $HAVE_PYFTPDLIB = no])
|
||||
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||
CHECK_CONNTRACK()
|
||||
CHECK_CONNTRACK_NAT()
|
||||
|
||||
@ -2736,7 +2810,7 @@ AT_CLEANUP
|
||||
|
||||
|
||||
AT_SETUP([conntrack - IPv6 FTP with NAT])
|
||||
AT_SKIP_IF([test $HAVE_PYFTPDLIB = no])
|
||||
AT_SKIP_IF([test $HAVE_FTP = no])
|
||||
CHECK_CONNTRACK()
|
||||
CHECK_CONNTRACK_NAT()
|
||||
OVS_TRAFFIC_VSWITCHD_START()
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015 Nicira, Inc.
|
||||
# Copyright (c) 2015, 2016 Nicira, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -48,24 +48,42 @@ def get_ftpd():
|
||||
return server
|
||||
|
||||
|
||||
def get_tftpd():
|
||||
try:
|
||||
from tftpy import TftpServer, TftpShared
|
||||
|
||||
class OVSTFTPServer(TftpServer):
|
||||
def __init__(self, listen, handler=None):
|
||||
(ip, port) = listen
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
TftpServer.__init__(self, tftproot='./')
|
||||
|
||||
def serve_forever(self):
|
||||
self.listen(self.ip, self.port)
|
||||
server = [OVSTFTPServer, None, TftpShared.DEF_TFTP_PORT]
|
||||
except ImportError:
|
||||
server = None
|
||||
pass
|
||||
return server
|
||||
|
||||
|
||||
def main():
|
||||
SERVERS = {
|
||||
'http': [TCPServer, SimpleHTTPRequestHandler, 80],
|
||||
'http6': [TCPServerV6, SimpleHTTPRequestHandler, 80],
|
||||
'ftp': get_ftpd(),
|
||||
'tftp': get_tftpd(),
|
||||
}
|
||||
|
||||
ftpd = get_ftpd()
|
||||
if ftpd is not None:
|
||||
SERVERS['ftp'] = ftpd
|
||||
|
||||
protocols = [srv for srv in SERVERS]
|
||||
protocols = [srv for srv in SERVERS if SERVERS[srv] is not None]
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Run basic application servers.')
|
||||
parser.add_argument('proto', default='http', nargs='?',
|
||||
help='protocol to serve (%s)' % protocols)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.proto not in SERVERS:
|
||||
if args.proto not in protocols:
|
||||
parser.print_help()
|
||||
exit(1)
|
||||
|
||||
|
@ -1840,12 +1840,19 @@ The \fBcommit\fR parameter must be specified to use \fBexec(...)\fR.
|
||||
.
|
||||
.IP \fBalg=\fIalg\fR
|
||||
Specify application layer gateway \fIalg\fR to track specific connection
|
||||
types. Supported types include:
|
||||
types. If subsequent related connections are sent through the \fBct\fR
|
||||
action, then the \fBrel\fR flag in the \fBct_state\fR field will be set.
|
||||
Supported types include:
|
||||
.RS
|
||||
.IP \fBftp\fR
|
||||
Look for negotiation of FTP data connections. If a subsequent FTP data
|
||||
connection arrives which is related, the \fBct\fR action will set the
|
||||
\fBrel\fR flag in the \fBct_state\fR field for packets sent through \fBct\fR.
|
||||
Look for negotiation of FTP data connections. Specify this option for FTP
|
||||
control connections to detect related data connections and populate the
|
||||
\fBrel\fR flag for the data connections.
|
||||
.
|
||||
.IP \fBtftp\fR
|
||||
Look for negotiation of TFTP data connections. Specify this option for TFTP
|
||||
control connections to detect related data connections and populate the
|
||||
\fBrel\fR flag for the data connections.
|
||||
.RE
|
||||
.
|
||||
.IP
|
||||
|
Loading…
x
Reference in New Issue
Block a user