debian: Fix OVS upgrade dependencies.
[cascardo/ovs.git] / tests / system-ovn.at
1 AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, NAT])
2 AT_KEYWORDS([ovnnat])
3
4 CHECK_CONNTRACK()
5 ovn_start
6 OVS_TRAFFIC_VSWITCHD_START()
7 ADD_BR([br-int])
8
9 # Set external-ids in br-int needed for ovn-controller
10 ovs-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
18 start_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
30 ovn-nbctl create Logical_Router name=R1
31 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
32
33 ovn-nbctl ls-add foo
34 ovn-nbctl ls-add bar
35 ovn-nbctl ls-add alice
36 ovn-nbctl ls-add join
37
38 # Connect foo to R1
39 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
40 ovn-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
44 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
45 ovn-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
49 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
50 ovn-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
54 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
55 ovn-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
59 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
60 ovn-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.
64 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
65 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
66
67 # Logical port 'foo1' in switch 'foo'.
68 ADD_NAMESPACES(foo1)
69 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
70          "192.168.1.1")
71 ovn-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'.
75 ADD_NAMESPACES(alice1)
76 ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
77          "172.16.1.1")
78 ovn-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'.
82 ADD_NAMESPACES(bar1)
83 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
84 "192.168.2.1")
85 ovn-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.
89 ovn-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
93 ovn-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.
97 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
98
99 # 'alice1' should be able to ping 'foo1' directly.
100 NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \
101 [0], [dnl
102 3 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
106 NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
107 [0], [dnl
108 3 packets transmitted, 3 received, 0% packet loss, time 0ms
109 ])
110
111 # Check conntrack entries.
112 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \
113 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
114 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>
115 ])
116
117 # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
118 # from 30.0.0.1
119 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
120 [0], [dnl
121 3 packets transmitted, 3 received, 0% packet loss, time 0ms
122 ])
123
124 # We verify that SNAT indeed happened via 'dump-conntrack' command.
125 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
126 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
127 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>
128 ])
129
130 # Add static routes to handle east-west NAT.
131 ovn-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.
134 AT_CHECK([ovs-appctl dpctl/flush-conntrack])
135
136 # East-west DNAT and SNAT: 'bar1' pings 30.0.0.2. 'foo1' receives it.
137 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
138 [0], [dnl
139 3 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
144 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
145 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
146 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>
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.
151 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
152 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
153 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>
154 ])
155
156 OVS_APP_EXIT_AND_WAIT([ovn-controller])
157
158 as ovn-sb
159 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
160
161 as ovn-nb
162 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
163
164 as northd
165 OVS_APP_EXIT_AND_WAIT([ovn-northd])
166
167 as
168 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
169 AT_CLEANUP
170
171
172 AT_SETUP([ovn -- load-balancing])
173 AT_KEYWORDS([ovnlb])
174
175 CHECK_CONNTRACK()
176 ovn_start
177 OVS_TRAFFIC_VSWITCHD_START()
178 ADD_BR([br-int])
179
180 # Set external-ids in br-int needed for ovn-controller
181 ovs-vsctl \
182         -- set Open_vSwitch . external-ids:system-id=hv1 \
183         -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
184         -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
185         -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
186         -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
187
188 # Start ovn-controller
189 start_daemon ovn-controller
190
191 # Logical network:
192 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
193 # connected to a router R1.
194 # foo has foo1 to act as a client.
195 # bar has bar1, bar2, bar3 to act as servers.
196 #
197 # Loadbalancer VIPs in 30.0.0.0/24 network.
198
199 ovn-nbctl create Logical_Router name=R1
200 ovn-nbctl ls-add foo
201 ovn-nbctl ls-add bar
202
203 # Connect foo to R1
204 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
205 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
206     type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
207
208 # Connect bar to R1
209 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
210 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
211     type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
212
213 # Create logical port 'foo1' in switch 'foo'.
214 ADD_NAMESPACES(foo1)
215 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
216          "192.168.1.1")
217 ovn-nbctl lsp-add foo foo1 \
218 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
219
220 # Create logical ports 'bar1', 'bar2', 'bar3' in switch 'bar'.
221 ADD_NAMESPACES(bar1)
222 ADD_VETH(bar1, bar1, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \
223          "172.16.1.1")
224 ovn-nbctl lsp-add bar bar1 \
225 -- lsp-set-addresses bar1 "f0:00:0f:01:02:03 172.16.1.2"
226
227 ADD_NAMESPACES(bar2)
228 ADD_VETH(bar2, bar2, br-int, "172.16.1.3/24", "f0:00:0f:01:02:04", \
229          "172.16.1.1")
230 ovn-nbctl lsp-add bar bar2 \
231 -- lsp-set-addresses bar2 "f0:00:0f:01:02:04 172.16.1.3"
232
233 ADD_NAMESPACES(bar3)
234 ADD_VETH(bar3, bar3, br-int, "172.16.1.4/24", "f0:00:0f:01:02:05", \
235          "172.16.1.1")
236 ovn-nbctl lsp-add bar bar3 \
237 -- lsp-set-addresses bar3 "f0:00:0f:01:02:05 172.16.1.4"
238
239 # Config OVN load-balancer with a VIP.
240 uuid=`ovn-nbctl  create load_balancer vips:30.0.0.1="172.16.1.2,172.16.1.3,172.16.1.4"`
241 ovn-nbctl set logical_switch foo load_balancer=$uuid
242
243 # Config OVN load-balancer with another VIP (this time with ports).
244 ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"172.16.1.2:80,172.16.1.3:80,172.16.1.4:80"'
245
246 # Wait for ovn-controller to catch up.
247 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
248
249 # Start webservers in 'bar1', 'bar2' and 'bar3'.
250 NETNS_DAEMONIZE([bar1], [[$PYTHON $srcdir/test-l7.py]], [http1.pid])
251 NETNS_DAEMONIZE([bar2], [[$PYTHON $srcdir/test-l7.py]], [http2.pid])
252 NETNS_DAEMONIZE([bar3], [[$PYTHON $srcdir/test-l7.py]], [http3.pid])
253
254 dnl Should work with the virtual IP address through NAT
255 for i in 1 2 3 4 5 6 7 8 9 10 11 12; do
256     echo Request $i
257     NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
258 done
259
260 dnl Each server should have at least one connection.
261 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1)], [0], [dnl
262 tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
263 tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
264 tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
265 ])
266
267 dnl Test load-balancing that includes L4 ports in NAT.
268 for i in 1 2 3 4 5 6 7 8 9 10 11 12; do
269     echo Request $i
270     NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
271 done
272
273 dnl Each server should have at least one connection.
274 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2)], [0], [dnl
275 tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
276 tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
277 tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),protoinfo=(state=<cleared>)
278 ])
279
280
281 OVS_APP_EXIT_AND_WAIT([ovn-controller])
282
283 as ovn-sb
284 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
285
286 as ovn-nb
287 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
288
289 as northd
290 OVS_APP_EXIT_AND_WAIT([ovn-northd])
291
292 as
293 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
294 AT_CLEANUP