]> git.proxmox.com Git - ovs.git/blame - tests/system-ovn.at
system-ovn.at: Add a OVN NAT test using OVN gateway.
[ovs.git] / tests / system-ovn.at
CommitLineData
cc08428b
GS
1AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, NAT])
2AT_KEYWORDS([ovnnat])
3
4CHECK_CONNTRACK()
5ovn_start
6OVS_TRAFFIC_VSWITCHD_START()
7ADD_BR([br-int])
8
9# Set external-ids in br-int needed for ovn-controller
10ovs-vsctl \
11 -- set Open_vSwitch . external-ids:system-id=hv1 \
12 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
13 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
14 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
15 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
16
17# Start ovn-controller
18start_daemon ovn-controller
19
20# Logical network:
21# Two LRs - R1 and R2 that are connected to each other via LS "join"
22# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
23# bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
24# to it. R2 is a gateway router on which we add NAT rules.
25#
26# foo -- R1 -- join - R2 -- alice
27# |
28# bar ----
29
30ovn-nbctl create Logical_Router name=R1
31ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
32
33ovn-nbctl ls-add foo
34ovn-nbctl ls-add bar
35ovn-nbctl ls-add alice
36ovn-nbctl ls-add join
37
38# Connect foo to R1
39ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
40ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
41 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
42
43# Connect bar to R1
44ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
45ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
46 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
47
48# Connect alice to R2
49ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
50ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
51 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
52
53# Connect R1 to join
54ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
55ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
56 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
57
58# Connect R2 to join
59ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
60ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
61 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
62
63# Static routes.
64ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
65ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
66
67# Logical port 'foo1' in switch 'foo'.
68ADD_NAMESPACES(foo1)
69ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
70 "192.168.1.1")
71ovn-nbctl lsp-add foo foo1 \
72-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
73
74# Logical port 'alice1' in switch 'alice'.
75ADD_NAMESPACES(alice1)
76ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
77 "172.16.1.1")
78ovn-nbctl lsp-add alice alice1 \
79-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
80
81# Logical port 'bar1' in switch 'bar'.
82ADD_NAMESPACES(bar1)
83ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
84"192.168.2.1")
85ovn-nbctl lsp-add bar bar1 \
86-- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
87
88# Add a DNAT rule.
89ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
90 external_ip=30.0.0.2 -- add logical_router R2 nat @nat
91
92# Add a SNAT rule
93ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
94 external_ip=30.0.0.1 -- add logical_router R2 nat @nat
95
96# wait for ovn-controller to catch up.
97OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
98
99# 'alice1' should be able to ping 'foo1' directly.
100NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \
101[0], [dnl
1023 packets transmitted, 3 received, 0% packet loss, time 0ms
103])
104
105# North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2
106NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
107[0], [dnl
1083 packets transmitted, 3 received, 0% packet loss, time 0ms
109])
110
111# Check conntrack entries.
112AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \
113sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
114icmp,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>
115])
116
117# South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
118# from 30.0.0.1
119NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
120[0], [dnl
1213 packets transmitted, 3 received, 0% packet loss, time 0ms
122])
123
124# We verify that SNAT indeed happened via 'dump-conntrack' command.
125AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
126sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
127icmp,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>
128])
129
130# Add static routes to handle east-west NAT.
131ovn-nbctl lr-route-add R1 30.0.0.0/24 20.0.0.2
132
133# Flush conntrack entries for easier output parsing of next test.
134AT_CHECK([ovs-appctl dpctl/flush-conntrack])
135
136# East-west DNAT and SNAT: 'bar1' pings 30.0.0.2. 'foo1' receives it.
137NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
138[0], [dnl
1393 packets transmitted, 3 received, 0% packet loss, time 0ms
140])
141
142# As we have a static route that sends all packets with destination
143# 30.0.0.2 to R2, it hits the DNAT rule and converts 30.0.0.2 to 192.168.1.2
144AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
145sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
146icmp,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>
147])
148
149# As we have a SNAT rule that converts 192.168.2.2 to 30.0.0.1, the source is
150# SNATted and 'foo1' receives it.
151AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
152sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
153icmp,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>
154])
155
156OVS_APP_EXIT_AND_WAIT([ovn-controller])
157
158as ovn-sb
159OVS_APP_EXIT_AND_WAIT([ovsdb-server])
160
161as ovn-nb
162OVS_APP_EXIT_AND_WAIT([ovsdb-server])
163
164as northd
165OVS_APP_EXIT_AND_WAIT([ovn-northd])
166
167as
168OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
169AT_CLEANUP