Skip to content

Commit

Permalink
conntrack: document NULL SNAT behavior and add a test case
Browse files Browse the repository at this point in the history
Currently, conntrack in the kernel has an undocumented feature referred
to as NULL SNAT. Basically, when a source port collision is detected
during the commit, the source port will be translated to an ephemeral
port. If there is no collision, no SNAT is performed.

This patchset documents this behavior and adds a self-test to verify
it's not changing.

Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
chaudron authored and ovsrobot committed Mar 30, 2021
1 parent af0ce38 commit 5c69d0e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
10 changes: 10 additions & 0 deletions lib/ovs-actions.xml
Expand Up @@ -1833,6 +1833,16 @@ for <var>i</var> in [1,<var>n_members</var>]:
connection, will behave the same as a bare <code>nat</code>.
</p>

<p>
For SNAT, there is a special case when the <code>src</code> IP
address is configured as all 0's, i.e.,
<code>nat(src=0.0.0.0)</code>. In this case, when a source port
collision is detected during the commit, the source port will be
translated to an ephemeral port. If there is no collision, no SNAT
is performed. Note that this is currently only implemented in the
Linux kernel datapath.
</p>

<p>
Open vSwitch 2.6 introduced <code>nat</code>. Linux 4.6 was the
earliest upstream kernel that implemented <code>ct</code> support for
Expand Down
7 changes: 7 additions & 0 deletions tests/system-kmod-macros.at
Expand Up @@ -99,6 +99,13 @@ m4_define([CHECK_CONNTRACK_FRAG_OVERLAP],
#
m4_define([CHECK_CONNTRACK_NAT])

# CHECK_CONNTRACK_NULL_SNAT()
#
# Perform requirements checks for running conntrack SNAT NULL tests.
# The kernel always supports NULL SNAT, so no check is needed.
#
m4_define([CHECK_CONNTRACK_NULL_SNAT])

# CHECK_CONNTRACK_TIMEOUT()
#
# Perform requirements checks for running conntrack customized timeout tests.
Expand Down
46 changes: 46 additions & 0 deletions tests/system-traffic.at
Expand Up @@ -4433,6 +4433,52 @@ 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 - NULL SNAT])
AT_SKIP_IF([test $HAVE_NC = no])
CHECK_CONNTRACK()
CHECK_CONNTRACK_NULL_SNAT()
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")
NS_CHECK_EXEC([at_ns0], [ip route add 172.1.1.0/24 via 10.1.1.2])

OVS_START_L7([at_ns1], [http])

AT_DATA([flows.txt], [dnl
table=0,priority=30,ct_state=-trk,ip,action=ct(table=0)
table=0,priority=20,ct_state=-rpl,ip,nw_dst=10.1.1.0/24,actions=ct(commit,nat(src=0.0.0.0),table=10)
table=0,priority=20,ct_state=+rpl,ip,nw_dst=10.1.1.0/24,actions=resubmit(,10)
table=0,priority=20,ip,nw_dst=172.1.1.2,actions=ct(commit,nat(dst=10.1.1.2),table=10)
table=0,priority=10,arp,action=normal
table=0,priority=1,action=drop
table=10,priority=20,ct_state=+rpl,ip,nw_dst=10.1.1.0/24 actions=ct(table=20,nat)
table=10,priority=10,ip,nw_dst=10.1.1.0/24 actions=resubmit(,20)
table=20,priority=10,ip,nw_dst=10.1.1.1,action=1
table=20,priority=10,ip,nw_dst=10.1.1.2,action=2
])
AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])

dnl - Test to make sure src nat is NOT done when not needed
NS_CHECK_EXEC([at_ns0], [echo "TEST" | nc -p 30000 10.1.1.2 80 > nc-1.log])
AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.1,"], [0], [dnl
tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=30000,dport=80),reply=(src=10.1.1.2,dst=10.1.1.1,sport=80,dport=30000),protoinfo=(state=TIME_WAIT)
])

dnl - Test to make sure src nat is done when needed
NS_CHECK_EXEC([at_ns0], [echo "TEST2" | nc -p 30001 172.1.1.2 80 > nc-2.log])
NS_CHECK_EXEC([at_ns0], [echo "TEST3" | nc -p 30001 10.1.1.2 80 > nc-3.log])
AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep 30001 | grep "orig=.src=10\.1\.1\.1," | sed -e 's/port=30001/port=<clnt_s_port>/g' -e 's/sport=80,dport=[[0-9]]\+/sport=80,dport=<rnd_port>/g' | sort], [0], [dnl
tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<clnt_s_port>,dport=80),reply=(src=10.1.1.2,dst=10.1.1.1,sport=80,dport=<rnd_port>),protoinfo=(state=TIME_WAIT)
tcp,orig=(src=10.1.1.1,dst=172.1.1.2,sport=<clnt_s_port>,dport=80),reply=(src=10.1.1.2,dst=10.1.1.1,sport=80,dport=<clnt_s_port>),protoinfo=(state=TIME_WAIT)
])

OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP


AT_SETUP([conntrack - simple DNAT])
CHECK_CONNTRACK()
CHECK_CONNTRACK_NAT()
Expand Down
10 changes: 10 additions & 0 deletions tests/system-userspace-macros.at
Expand Up @@ -96,6 +96,16 @@ m4_define([CHECK_CONNTRACK_FRAG_OVERLAP])
#
m4_define([CHECK_CONNTRACK_NAT])

# CHECK_CONNTRACK_NULL_SNAT()
#
# Perform requirements checks for running conntrack SNAT NULL tests.
# The userspace datapath does not support NULL SNAT.
#
m4_define([CHECK_CONNTRACK_NULL_SNAT],
[
AT_SKIP_IF([:])
])

# CHECK_CONNTRACK_TIMEOUT()
#
# Perform requirements checks for running conntrack customized timeout tests.
Expand Down

0 comments on commit 5c69d0e

Please sign in to comment.