Skip to content

Commit

Permalink
system-ovn.at: Add a OVN NAT test using OVN gateway.
Browse files Browse the repository at this point in the history
This unit test adds a basic OVN NAT test that tests north-south
DNAT, south-north SNAT and east-west DNAT and SNAT. It uses network
namespaces connected to br-int using veth pairs to act as logical
ports. This test does not cover multi-host scenarios, so there is
a gap. But userspace OVN tests do multi-host scenarios (without NAT
testing), so it should still be a decent coverage.

Signed-off-by: Gurucharan Shetty <[email protected]>
Acked-by: Joe Stringer <[email protected]>
  • Loading branch information
shettyg committed Jul 18, 2016
1 parent bdcbce8 commit cc08428
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tests/automake.mk
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ SYSTEM_KMOD_TESTSUITE_AT = \

SYSTEM_USERSPACE_TESTSUITE_AT = \
tests/system-userspace-testsuite.at \
tests/system-ovn.at \
tests/system-userspace-macros.at

SYSTEM_TESTSUITE_AT = \
tests/system-common-macros.at \
tests/system-ovn.at \
tests/system-traffic.at

TESTSUITE = $(srcdir)/tests/testsuite
Expand Down
1 change: 1 addition & 0 deletions tests/system-kmod-testsuite.at
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ m4_include([tests/system-common-macros.at])
m4_include([tests/system-kmod-macros.at])

m4_include([tests/system-traffic.at])
m4_include([tests/system-ovn.at])
169 changes: 169 additions & 0 deletions tests/system-ovn.at
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, NAT])
AT_KEYWORDS([ovnnat])

CHECK_CONNTRACK()
ovn_start
OVS_TRAFFIC_VSWITCHD_START()
ADD_BR([br-int])

# Set external-ids in br-int needed for ovn-controller
ovs-vsctl \
-- set Open_vSwitch . external-ids:system-id=hv1 \
-- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
-- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
-- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
-- set bridge br-int fail-mode=secure other-config:disable-in-band=true

# Start ovn-controller
start_daemon ovn-controller

# Logical network:
# Two LRs - R1 and R2 that are connected to each other via LS "join"
# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
# to it. R2 is a gateway router on which we add NAT rules.
#
# foo -- R1 -- join - R2 -- alice
# |
# bar ----

ovn-nbctl create Logical_Router name=R1
ovn-nbctl create Logical_Router name=R2 options:chassis=hv1

ovn-nbctl ls-add foo
ovn-nbctl ls-add bar
ovn-nbctl ls-add alice
ovn-nbctl ls-add join

# Connect foo to R1
ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"

# Connect bar to R1
ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"

# Connect alice to R2
ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"

# Connect R1 to join
ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'

# Connect R2 to join
ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'

# Static routes.
ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1

# Logical port 'foo1' in switch 'foo'.
ADD_NAMESPACES(foo1)
ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
"192.168.1.1")
ovn-nbctl lsp-add foo foo1 \
-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"

# Logical port 'alice1' in switch 'alice'.
ADD_NAMESPACES(alice1)
ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
"172.16.1.1")
ovn-nbctl lsp-add alice alice1 \
-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"

# Logical port 'bar1' in switch 'bar'.
ADD_NAMESPACES(bar1)
ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
"192.168.2.1")
ovn-nbctl lsp-add bar bar1 \
-- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"

# Add a DNAT rule.
ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
external_ip=30.0.0.2 -- add logical_router R2 nat @nat

# Add a SNAT rule
ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
external_ip=30.0.0.1 -- add logical_router R2 nat @nat

# wait for ovn-controller to catch up.
OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])

# 'alice1' should be able to ping 'foo1' directly.
NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \
[0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])

# North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2
NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
[0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])

# Check conntrack entries.
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \
sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>),zone=<cleared>
])

# South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
# from 30.0.0.1
NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
[0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])

# We verify that SNAT indeed happened via 'dump-conntrack' command.
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>),reply=(src=172.16.1.2,dst=30.0.0.1,id=<cleared>),zone=<cleared>
])

# Add static routes to handle east-west NAT.
ovn-nbctl lr-route-add R1 30.0.0.0/24 20.0.0.2

# Flush conntrack entries for easier output parsing of next test.
AT_CHECK([ovs-appctl dpctl/flush-conntrack])

# East-west DNAT and SNAT: 'bar1' pings 30.0.0.2. 'foo1' receives it.
NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
[0], [dnl
3 packets transmitted, 3 received, 0% packet loss, time 0ms
])

# As we have a static route that sends all packets with destination
# 30.0.0.2 to R2, it hits the DNAT rule and converts 30.0.0.2 to 192.168.1.2
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
icmp,orig=(src=192.168.2.2,dst=30.0.0.2,id=<cleared>),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>),zone=<cleared>
])

# As we have a SNAT rule that converts 192.168.2.2 to 30.0.0.1, the source is
# SNATted and 'foo1' receives it.
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>),reply=(src=192.168.1.2,dst=30.0.0.1,id=<cleared>),zone=<cleared>
])

OVS_APP_EXIT_AND_WAIT([ovn-controller])

as ovn-sb
OVS_APP_EXIT_AND_WAIT([ovsdb-server])

as ovn-nb
OVS_APP_EXIT_AND_WAIT([ovsdb-server])

as northd
OVS_APP_EXIT_AND_WAIT([ovn-northd])

as
OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
AT_CLEANUP
1 change: 1 addition & 0 deletions tests/system-userspace-testsuite.at
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ m4_include([tests/system-userspace-macros.at])
m4_include([tests/system-common-macros.at])

m4_include([tests/system-traffic.at])
m4_include([tests/system-ovn.at])

0 comments on commit cc08428

Please sign in to comment.