]> git.proxmox.com Git - ovs.git/blob - tests/system-ovn.at
9e323424a2a102095f29bd3d48330a4aec0a5330
[ovs.git] / tests / system-ovn.at
1 AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, SNAT and DNAT])
2 AT_KEYWORDS([ovnnat])
3
4 CHECK_CONNTRACK()
5 CHECK_CONNTRACK_NAT()
6 ovn_start
7 OVS_TRAFFIC_VSWITCHD_START()
8 ADD_BR([br-int])
9
10 # Set external-ids in br-int needed for ovn-controller
11 ovs-vsctl \
12 -- set Open_vSwitch . external-ids:system-id=hv1 \
13 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
14 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
15 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
16 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
17
18 # Start ovn-controller
19 start_daemon ovn-controller
20
21 # Logical network:
22 # Two LRs - R1 and R2 that are connected to each other via LS "join"
23 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
24 # bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
25 # to it. R2 is a gateway router on which we add NAT rules.
26 #
27 # foo -- R1 -- join - R2 -- alice
28 # |
29 # bar ----
30
31 ovn-nbctl create Logical_Router name=R1
32 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
33
34 ovn-nbctl ls-add foo
35 ovn-nbctl ls-add bar
36 ovn-nbctl ls-add alice
37 ovn-nbctl ls-add join
38
39 # Connect foo to R1
40 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
41 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
42 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
43
44 # Connect bar to R1
45 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
46 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
47 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
48
49 # Connect alice to R2
50 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
51 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
52 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
53
54 # Connect R1 to join
55 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
56 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
57 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
58
59 # Connect R2 to join
60 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
61 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
62 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
63
64 # Static routes.
65 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
66 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
67
68 # Logical port 'foo1' in switch 'foo'.
69 ADD_NAMESPACES(foo1)
70 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
71 "192.168.1.1")
72 ovn-nbctl lsp-add foo foo1 \
73 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
74
75 # Logical port 'alice1' in switch 'alice'.
76 ADD_NAMESPACES(alice1)
77 ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
78 "172.16.1.1")
79 ovn-nbctl lsp-add alice alice1 \
80 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
81
82 # Logical port 'bar1' in switch 'bar'.
83 ADD_NAMESPACES(bar1)
84 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
85 "192.168.2.1")
86 ovn-nbctl lsp-add bar bar1 \
87 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
88
89 # Add a DNAT rule.
90 ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
91 external_ip=30.0.0.2 -- add logical_router R2 nat @nat
92
93 # Add a SNAT rule
94 ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
95 external_ip=30.0.0.1 -- add logical_router R2 nat @nat
96
97 # wait for ovn-controller to catch up.
98 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
99
100 # 'alice1' should be able to ping 'foo1' directly.
101 NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 192.168.1.2 | FORMAT_PING], \
102 [0], [dnl
103 3 packets transmitted, 3 received, 0% packet loss, time 0ms
104 ])
105
106 # North-South DNAT: 'alice1' should also be able to ping 'foo1' via 30.0.0.2
107 NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
108 [0], [dnl
109 3 packets transmitted, 3 received, 0% packet loss, time 0ms
110 ])
111
112 # Check conntrack entries.
113 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.2) | \
114 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
115 icmp,orig=(src=172.16.1.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=0,code=0),zone=<cleared>
116 ])
117
118 # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
119 # from 30.0.0.1
120 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
121 [0], [dnl
122 3 packets transmitted, 3 received, 0% packet loss, time 0ms
123 ])
124
125 # We verify that SNAT indeed happened via 'dump-conntrack' command.
126 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
127 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
128 icmp,orig=(src=192.168.2.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=30.0.0.1,id=<cleared>,type=0,code=0),zone=<cleared>
129 ])
130
131 # Add static routes to handle east-west NAT.
132 ovn-nbctl lr-route-add R1 30.0.0.0/24 20.0.0.2
133
134 # Flush conntrack entries for easier output parsing of next test.
135 AT_CHECK([ovs-appctl dpctl/flush-conntrack])
136
137 # East-west DNAT and SNAT: 'bar1' pings 30.0.0.2. 'foo1' receives it.
138 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
139 [0], [dnl
140 3 packets transmitted, 3 received, 0% packet loss, time 0ms
141 ])
142
143 # As we have a static route that sends all packets with destination
144 # 30.0.0.2 to R2, it hits the DNAT rule and converts 30.0.0.2 to 192.168.1.2
145 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
146 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
147 icmp,orig=(src=192.168.2.2,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=192.168.2.2,id=<cleared>,type=0,code=0),zone=<cleared>
148 ])
149
150 # As we have a SNAT rule that converts 192.168.2.2 to 30.0.0.1, the source is
151 # SNATted and 'foo1' receives it.
152 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
153 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
154 icmp,orig=(src=192.168.2.2,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=30.0.0.1,id=<cleared>,type=0,code=0),zone=<cleared>
155 ])
156
157 OVS_APP_EXIT_AND_WAIT([ovn-controller])
158
159 as ovn-sb
160 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
161
162 as ovn-nb
163 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
164
165 as northd
166 OVS_APP_EXIT_AND_WAIT([ovn-northd])
167
168 as
169 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
170 /connection dropped.*/d"])
171 AT_CLEANUP
172
173 AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, easy SNAT])
174 AT_KEYWORDS([ovnnat])
175
176 CHECK_CONNTRACK()
177 CHECK_CONNTRACK_NAT()
178 ovn_start
179 OVS_TRAFFIC_VSWITCHD_START()
180 ADD_BR([br-int])
181
182 # Set external-ids in br-int needed for ovn-controller
183 ovs-vsctl \
184 -- set Open_vSwitch . external-ids:system-id=hv1 \
185 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
186 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
187 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
188 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
189
190 # Start ovn-controller
191 start_daemon ovn-controller
192
193 # Logical network:
194 # Two LRs - R1 and R2 that are connected to each other via LS "join"
195 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) connected
196 # to it. R2 has alice (172.16.1.0/24) connected to it.
197 # R2 is a gateway router on which we add NAT rules.
198 #
199 # foo -- R1 -- join - R2 -- alice
200
201 ovn-nbctl lr-add R1
202 ovn-nbctl lr-add R2 -- set Logical_Router R2 options:chassis=hv1
203
204 ovn-nbctl ls-add foo
205 ovn-nbctl ls-add alice
206 ovn-nbctl ls-add join
207
208 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
209 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
210 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
211 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
212
213 # Connect foo to R1
214 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
215 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
216
217 # Connect alice to R2
218 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
219 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
220
221 # Connect R1 to join
222 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
223 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
224
225 # Connect R2 to join
226 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
227 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
228
229 # Static routes.
230 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
231 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
232
233 # Logical port 'foo1' in switch 'foo'.
234 ADD_NAMESPACES(foo1)
235 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
236 "192.168.1.1")
237 ovn-nbctl lsp-add foo foo1 \
238 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
239
240 # Logical port 'alice1' in switch 'alice'.
241 ADD_NAMESPACES(alice1)
242 ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
243 "172.16.1.1")
244 ovn-nbctl lsp-add alice alice1 \
245 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
246
247 # Add a SNAT rule
248 ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.1.2 \
249 external_ip=172.16.1.1 -- add logical_router R2 nat @nat
250
251 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
252
253 # South-North SNAT: 'foo1' pings 'alice1'. But 'alice1' receives traffic
254 # from 172.16.1.1
255 NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
256 [0], [dnl
257 3 packets transmitted, 3 received, 0% packet loss, time 0ms
258 ])
259
260 # We verify that SNAT indeed happened via 'dump-conntrack' command.
261 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.1) | \
262 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
263 icmp,orig=(src=192.168.1.2,dst=172.16.1.2,id=<cleared>,type=8,code=0),reply=(src=172.16.1.2,dst=172.16.1.1,id=<cleared>,type=0,code=0),zone=<cleared>
264 ])
265
266 OVS_APP_EXIT_AND_WAIT([ovn-controller])
267
268 as ovn-sb
269 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
270
271 as ovn-nb
272 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
273
274 as northd
275 OVS_APP_EXIT_AND_WAIT([ovn-northd])
276
277 as
278 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
279 /connection dropped.*/d"])
280 AT_CLEANUP
281
282 AT_SETUP([ovn -- multiple gateway routers, SNAT and DNAT])
283 AT_KEYWORDS([ovnnat])
284
285 CHECK_CONNTRACK()
286 CHECK_CONNTRACK_NAT()
287 ovn_start
288 OVS_TRAFFIC_VSWITCHD_START()
289 ADD_BR([br-int])
290
291 # Set external-ids in br-int needed for ovn-controller
292 ovs-vsctl \
293 -- set Open_vSwitch . external-ids:system-id=hv1 \
294 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
295 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
296 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
297 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
298
299 # Start ovn-controller
300 start_daemon ovn-controller
301
302 # Logical network:
303 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
304 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
305 # bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
306 # to it. R3 has bob (172.16.1.0/24) connected to it. Note how both alice and
307 # bob have the same subnet behind it. We are trying to simulate external
308 # network via those 2 switches. In real world the switch ports of these
309 # switches will have addresses set as "unknown" to make them learning switches.
310 # Or those switches will be "localnet" ones.
311 #
312 # foo -- R1 -- join - R2 -- alice
313 # | |
314 # bar ---- - R3 --- bob
315
316 ovn-nbctl create Logical_Router name=R1
317 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
318 ovn-nbctl create Logical_Router name=R3 options:chassis=hv1
319
320 ovn-nbctl ls-add foo
321 ovn-nbctl ls-add bar
322 ovn-nbctl ls-add alice
323 ovn-nbctl ls-add bob
324 ovn-nbctl ls-add join
325
326 # Connect foo to R1
327 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
328 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
329 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
330
331 # Connect bar to R1
332 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
333 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
334 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
335
336 # Connect alice to R2
337 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
338 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
339 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
340
341 # Connect bob to R3
342 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
343 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
344 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
345
346 # Connect R1 to join
347 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
348 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
349 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
350
351 # Connect R2 to join
352 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
353 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
354 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
355
356 # Connect R3 to join
357 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
358 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
359 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
360
361 # Install static routes with source ip address as the policy for routing.
362 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
363 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
364 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
365
366 # Static routes.
367 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
368 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
369
370 # For gateway routers R2 and R3, set a force SNAT rule.
371 ovn-nbctl set logical_router R2 options:dnat_force_snat_ip=20.0.0.2
372 ovn-nbctl set logical_router R3 options:dnat_force_snat_ip=20.0.0.3
373
374 # Logical port 'foo1' in switch 'foo'.
375 ADD_NAMESPACES(foo1)
376 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
377 "192.168.1.1")
378 ovn-nbctl lsp-add foo foo1 \
379 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
380
381 # Logical port 'alice1' in switch 'alice'.
382 ADD_NAMESPACES(alice1)
383 ADD_VETH(alice1, alice1, br-int, "172.16.1.3/24", "f0:00:00:01:02:04", \
384 "172.16.1.1")
385 ovn-nbctl lsp-add alice alice1 \
386 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
387
388 # Logical port 'bar1' in switch 'bar'.
389 ADD_NAMESPACES(bar1)
390 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
391 "192.168.2.1")
392 ovn-nbctl lsp-add bar bar1 \
393 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
394
395 # Logical port 'bob1' in switch 'bob'.
396 ADD_NAMESPACES(bob1)
397 ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
398 "172.16.1.2")
399 ovn-nbctl lsp-add bob bob1 \
400 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
401
402 # Router R2
403 # Add a DNAT rule.
404 ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
405 external_ip=30.0.0.2 -- add logical_router R2 nat @nat
406
407 # Add a SNAT rule
408 ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.1.2 \
409 external_ip=30.0.0.1 -- add logical_router R2 nat @nat
410
411 # Router R3
412 # Add a DNAT rule.
413 ovn-nbctl -- --id=@nat create nat type="dnat" logical_ip=192.168.1.2 \
414 external_ip=30.0.0.3 -- add logical_router R3 nat @nat
415
416 # Add a SNAT rule
417 ovn-nbctl -- --id=@nat create nat type="snat" logical_ip=192.168.2.2 \
418 external_ip=30.0.0.4 -- add logical_router R3 nat @nat
419
420 # wait for ovn-controller to catch up.
421 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
422
423 # North-South DNAT: 'alice1' should be able to ping 'foo1' via 30.0.0.2
424 NS_CHECK_EXEC([alice1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.2 | FORMAT_PING], \
425 [0], [dnl
426 3 packets transmitted, 3 received, 0% packet loss, time 0ms
427 ])
428
429 # Check conntrack entries.
430 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.3) | \
431 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
432 icmp,orig=(src=172.16.1.3,dst=30.0.0.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.3,id=<cleared>,type=0,code=0),zone=<cleared>
433 ])
434
435 # But foo1 should receive traffic from 20.0.0.2
436 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.2) | \
437 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
438 icmp,orig=(src=172.16.1.3,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=20.0.0.2,id=<cleared>,type=0,code=0),zone=<cleared>
439 ])
440
441 # North-South DNAT: 'bob1' should be able to ping 'foo1' via 30.0.0.3
442 NS_CHECK_EXEC([bob1], [ping -q -c 3 -i 0.3 -w 2 30.0.0.3 | FORMAT_PING], \
443 [0], [dnl
444 3 packets transmitted, 3 received, 0% packet loss, time 0ms
445 ])
446
447 # Check conntrack entries.
448 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.1.4) | \
449 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
450 icmp,orig=(src=172.16.1.4,dst=30.0.0.3,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=172.16.1.4,id=<cleared>,type=0,code=0),zone=<cleared>
451 ])
452
453 # But foo1 should receive traffic from 20.0.0.3
454 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0.3) | \
455 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
456 icmp,orig=(src=172.16.1.4,dst=192.168.1.2,id=<cleared>,type=8,code=0),reply=(src=192.168.1.2,dst=20.0.0.3,id=<cleared>,type=0,code=0),zone=<cleared>
457 ])
458
459 # South-North SNAT: 'bar1' pings 'bob1'. But 'bob1' receives traffic
460 # from 30.0.0.4
461 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \
462 [0], [dnl
463 3 packets transmitted, 3 received, 0% packet loss, time 0ms
464 ])
465
466 # We verify that SNAT indeed happened via 'dump-conntrack' command.
467 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.4) | \
468 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
469 icmp,orig=(src=192.168.2.2,dst=172.16.1.4,id=<cleared>,type=8,code=0),reply=(src=172.16.1.4,dst=30.0.0.4,id=<cleared>,type=0,code=0),zone=<cleared>
470 ])
471
472 # South-North SNAT: 'foo1' pings 'alice1'. But 'alice1' receives traffic
473 # from 30.0.0.1
474 NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.3 | FORMAT_PING], \
475 [0], [dnl
476 3 packets transmitted, 3 received, 0% packet loss, time 0ms
477 ])
478
479 # We verify that SNAT indeed happened via 'dump-conntrack' command.
480 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
481 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
482 icmp,orig=(src=192.168.1.2,dst=172.16.1.3,id=<cleared>,type=8,code=0),reply=(src=172.16.1.3,dst=30.0.0.1,id=<cleared>,type=0,code=0),zone=<cleared>
483 ])
484
485 OVS_APP_EXIT_AND_WAIT([ovn-controller])
486
487 as ovn-sb
488 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
489
490 as ovn-nb
491 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
492
493 as northd
494 OVS_APP_EXIT_AND_WAIT([ovn-northd])
495
496 as
497 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
498 /connection dropped.*/d"])
499 AT_CLEANUP
500
501 AT_SETUP([ovn -- load-balancing])
502 AT_KEYWORDS([ovnlb])
503
504 CHECK_CONNTRACK()
505 CHECK_CONNTRACK_NAT()
506 ovn_start
507 OVS_TRAFFIC_VSWITCHD_START()
508 ADD_BR([br-int])
509
510 # Set external-ids in br-int needed for ovn-controller
511 ovs-vsctl \
512 -- set Open_vSwitch . external-ids:system-id=hv1 \
513 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
514 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
515 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
516 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
517
518 # Start ovn-controller
519 start_daemon ovn-controller
520
521 # Logical network:
522 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
523 # connected to a router R1.
524 # foo has foo1 to act as a client.
525 # bar has bar1, bar2, bar3 to act as servers.
526 #
527 # Loadbalancer VIPs in 30.0.0.0/24 network.
528
529 ovn-nbctl create Logical_Router name=R1
530 ovn-nbctl ls-add foo
531 ovn-nbctl ls-add bar
532
533 # Connect foo to R1
534 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
535 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
536 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
537
538 # Connect bar to R1
539 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
540 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
541 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
542
543 # Create logical port 'foo1' in switch 'foo'.
544 ADD_NAMESPACES(foo1)
545 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
546 "192.168.1.1")
547 ovn-nbctl lsp-add foo foo1 \
548 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
549
550 # Create logical ports 'bar1', 'bar2', 'bar3' in switch 'bar'.
551 ADD_NAMESPACES(bar1)
552 ADD_VETH(bar1, bar1, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \
553 "172.16.1.1")
554 ovn-nbctl lsp-add bar bar1 \
555 -- lsp-set-addresses bar1 "f0:00:0f:01:02:03 172.16.1.2"
556
557 ADD_NAMESPACES(bar2)
558 ADD_VETH(bar2, bar2, br-int, "172.16.1.3/24", "f0:00:0f:01:02:04", \
559 "172.16.1.1")
560 ovn-nbctl lsp-add bar bar2 \
561 -- lsp-set-addresses bar2 "f0:00:0f:01:02:04 172.16.1.3"
562
563 ADD_NAMESPACES(bar3)
564 ADD_VETH(bar3, bar3, br-int, "172.16.1.4/24", "f0:00:0f:01:02:05", \
565 "172.16.1.1")
566 ovn-nbctl lsp-add bar bar3 \
567 -- lsp-set-addresses bar3 "f0:00:0f:01:02:05 172.16.1.4"
568
569 # Config OVN load-balancer with a VIP.
570 uuid=`ovn-nbctl create load_balancer vips:30.0.0.1="172.16.1.2,172.16.1.3,172.16.1.4"`
571 ovn-nbctl set logical_switch foo load_balancer=$uuid
572
573 # Create another load-balancer with another VIP.
574 uuid=`ovn-nbctl create load_balancer vips:30.0.0.3="172.16.1.2,172.16.1.3,172.16.1.4"`
575 ovn-nbctl add logical_switch foo load_balancer $uuid
576
577 # Config OVN load-balancer with another VIP (this time with ports).
578 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"'
579
580 # Wait for ovn-controller to catch up.
581 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
582
583 # Start webservers in 'bar1', 'bar2' and 'bar3'.
584 NETNS_DAEMONIZE([bar1], [[$PYTHON $srcdir/test-l7.py]], [http1.pid])
585 NETNS_DAEMONIZE([bar2], [[$PYTHON $srcdir/test-l7.py]], [http2.pid])
586 NETNS_DAEMONIZE([bar3], [[$PYTHON $srcdir/test-l7.py]], [http3.pid])
587
588 dnl Should work with the virtual IP 30.0.0.1 address through NAT
589 for i in `seq 1 20`; do
590 echo Request $i
591 NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
592 done
593
594 dnl Each server should have at least one connection.
595 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
596 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
597 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>),zone=<cleared>,protoinfo=(state=<cleared>)
598 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>),zone=<cleared>,protoinfo=(state=<cleared>)
599 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>),zone=<cleared>,protoinfo=(state=<cleared>)
600 ])
601
602 dnl Should work with the virtual IP 30.0.0.3 address through NAT
603 for i in `seq 1 20`; do
604 echo Request $i
605 NS_CHECK_EXEC([foo1], [wget 30.0.0.3 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
606 done
607
608 dnl Each server should have at least one connection.
609 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | \
610 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
611 tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
612 tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
613 tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
614 ])
615
616 dnl Test load-balancing that includes L4 ports in NAT.
617 for i in `seq 1 20`; do
618 echo Request $i
619 NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
620 done
621
622 dnl Each server should have at least one connection.
623 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
624 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
625 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>),zone=<cleared>,protoinfo=(state=<cleared>)
626 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>),zone=<cleared>,protoinfo=(state=<cleared>)
627 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>),zone=<cleared>,protoinfo=(state=<cleared>)
628 ])
629
630
631 OVS_APP_EXIT_AND_WAIT([ovn-controller])
632
633 as ovn-sb
634 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
635
636 as ovn-nb
637 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
638
639 as northd
640 OVS_APP_EXIT_AND_WAIT([ovn-northd])
641
642 as
643 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
644 AT_CLEANUP
645
646 AT_SETUP([ovn -- load-balancing - same subnet.])
647 AT_KEYWORDS([ovnlb])
648
649 CHECK_CONNTRACK()
650 CHECK_CONNTRACK_NAT()
651 ovn_start
652 OVS_TRAFFIC_VSWITCHD_START()
653 ADD_BR([br-int])
654
655 # Set external-ids in br-int needed for ovn-controller
656 ovs-vsctl \
657 -- set Open_vSwitch . external-ids:system-id=hv1 \
658 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
659 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
660 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
661 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
662
663 # Start ovn-controller
664 start_daemon ovn-controller
665
666 # Logical network:
667 # 1 logical switch "foo" (192.168.1.0/24) connected to router R1.
668 # foo has foo1, foo2, foo3, foo4 as logical ports.
669 #
670 # Loadbalancer VIPs in 30.0.0.0/24 network. Router is needed for default
671 # gateway. We will test load-balancing with foo1 as a client and foo2, foo3 and
672 # foo4 as servers.
673
674 ovn-nbctl create Logical_Router name=R1
675 ovn-nbctl ls-add foo
676
677 # Connect foo to R1
678 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
679 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
680 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
681
682 # Create logical port 'foo1', 'foo2', 'foo3' and 'foo4' in switch 'foo'.
683 ADD_NAMESPACES(foo1, foo2, foo3, foo4)
684 for i in `seq 1 4`; do
685 j=`expr $i + 1`
686 ADD_VETH(foo$i, foo$i, br-int, "192.168.1.$j/24", "f0:00:00:01:02:0$j", \
687 "192.168.1.1")
688 ovn-nbctl lsp-add foo foo$i \
689 -- lsp-set-addresses foo$i "f0:00:00:01:02:0$j 192.168.1.$j"
690 done
691
692 # Config OVN load-balancer with a VIP.
693 uuid=`ovn-nbctl create load_balancer vips:30.0.0.1="192.168.1.3,192.168.1.4,192.168.1.5"`
694 ovn-nbctl set logical_switch foo load_balancer=$uuid
695
696 # Config OVN load-balancer with another VIP (this time with ports).
697 ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.3:80,192.168.1.4:80,192.168.1.5:80"'
698
699 # Wait for ovn-controller to catch up.
700 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
701
702 # Start webservers in 'foo2', 'foo3' and 'foo4'.
703 NETNS_DAEMONIZE([foo2], [[$PYTHON $srcdir/test-l7.py]], [http1.pid])
704 NETNS_DAEMONIZE([foo3], [[$PYTHON $srcdir/test-l7.py]], [http2.pid])
705 NETNS_DAEMONIZE([foo4], [[$PYTHON $srcdir/test-l7.py]], [http3.pid])
706
707 dnl Should work with the virtual IP address through NAT
708 for i in `seq 1 20`; do
709 echo Request $i
710 NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
711 done
712
713 dnl Each server should have at least one connection.
714 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | \
715 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
716 tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
717 tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
718 tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.5,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
719 ])
720
721 dnl Test load-balancing that includes L4 ports in NAT.
722 for i in `seq 1 20`; do
723 echo Request $i
724 NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
725 done
726
727 dnl Each server should have at least one connection.
728 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | \
729 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
730 tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
731 tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
732 tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.5,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
733 ])
734
735
736 OVS_APP_EXIT_AND_WAIT([ovn-controller])
737
738 as ovn-sb
739 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
740
741 as ovn-nb
742 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
743
744 as northd
745 OVS_APP_EXIT_AND_WAIT([ovn-northd])
746
747 as
748 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
749 AT_CLEANUP
750
751 AT_SETUP([ovn -- load balancing in gateway router])
752 AT_KEYWORDS([ovnlb])
753
754 CHECK_CONNTRACK()
755 CHECK_CONNTRACK_NAT()
756 ovn_start
757 OVS_TRAFFIC_VSWITCHD_START()
758 ADD_BR([br-int])
759
760 # Set external-ids in br-int needed for ovn-controller
761 ovs-vsctl \
762 -- set Open_vSwitch . external-ids:system-id=hv1 \
763 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
764 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
765 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
766 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
767
768 # Start ovn-controller
769 start_daemon ovn-controller
770
771 # Logical network:
772 # Two LRs - R1 and R2 that are connected to each other via LS "join"
773 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
774 # bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
775 # to it. R2 is a gateway router on which we add load-balancing rules.
776 #
777 # foo -- R1 -- join - R2 -- alice
778 # |
779 # bar ----
780
781 ovn-nbctl create Logical_Router name=R1
782 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
783
784 ovn-nbctl ls-add foo
785 ovn-nbctl ls-add bar
786 ovn-nbctl ls-add alice
787 ovn-nbctl ls-add join
788
789 # Connect foo to R1
790 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
791 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
792 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
793
794 # Connect bar to R1
795 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
796 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
797 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
798
799 # Connect alice to R2
800 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
801 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
802 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
803
804 # Connect R1 to join
805 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
806 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
807 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
808
809 # Connect R2 to join
810 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
811 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
812 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
813
814 # Static routes.
815 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
816 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
817
818 # Logical port 'foo1' in switch 'foo'.
819 ADD_NAMESPACES(foo1)
820 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
821 "192.168.1.1")
822 ovn-nbctl lsp-add foo foo1 \
823 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
824
825 # Logical port 'alice1' in switch 'alice'.
826 ADD_NAMESPACES(alice1)
827 ADD_VETH(alice1, alice1, br-int, "172.16.1.2/24", "f0:00:00:01:02:04", \
828 "172.16.1.1")
829 ovn-nbctl lsp-add alice alice1 \
830 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
831
832 # Logical port 'bar1' in switch 'bar'.
833 ADD_NAMESPACES(bar1)
834 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
835 "192.168.2.1")
836 ovn-nbctl lsp-add bar bar1 \
837 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
838
839 # Config OVN load-balancer with a VIP.
840 uuid=`ovn-nbctl create load_balancer vips:30.0.0.1="192.168.1.2,192.168.2.2"`
841 ovn-nbctl set logical_router R2 load_balancer=$uuid
842
843 # Config OVN load-balancer with another VIP (this time with ports).
844 ovn-nbctl set load_balancer $uuid vips:'"30.0.0.2:8000"'='"192.168.1.2:80,192.168.2.2:80"'
845
846 # Wait for ovn-controller to catch up.
847 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
848
849 # Start webservers in 'foo1', 'bar1'.
850 NETNS_DAEMONIZE([foo1], [[$PYTHON $srcdir/test-l7.py]], [http1.pid])
851 NETNS_DAEMONIZE([bar1], [[$PYTHON $srcdir/test-l7.py]], [http2.pid])
852
853 dnl Should work with the virtual IP address through NAT
854 for i in `seq 1 20`; do
855 echo Request $i
856 NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
857 done
858
859 dnl Each server should have at least one connection.
860 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
861 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
862 tcp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
863 tcp,orig=(src=172.16.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
864 ])
865
866 dnl Test load-balancing that includes L4 ports in NAT.
867 for i in `seq 1 20`; do
868 echo Request $i
869 NS_CHECK_EXEC([alice1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
870 done
871
872 dnl Each server should have at least one connection.
873 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) |
874 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
875 tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
876 tcp,orig=(src=172.16.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
877 ])
878
879 OVS_APP_EXIT_AND_WAIT([ovn-controller])
880
881 as ovn-sb
882 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
883
884 as ovn-nb
885 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
886
887 as northd
888 OVS_APP_EXIT_AND_WAIT([ovn-northd])
889
890 as
891 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
892 /connection dropped.*/d"])
893 AT_CLEANUP
894
895 AT_SETUP([ovn -- multiple gateway routers, load-balancing])
896 AT_KEYWORDS([ovnlb])
897
898 CHECK_CONNTRACK()
899 CHECK_CONNTRACK_NAT()
900 ovn_start
901 OVS_TRAFFIC_VSWITCHD_START()
902 ADD_BR([br-int])
903
904 # Set external-ids in br-int needed for ovn-controller
905 ovs-vsctl \
906 -- set Open_vSwitch . external-ids:system-id=hv1 \
907 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
908 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
909 -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
910 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true
911
912 # Start ovn-controller
913 start_daemon ovn-controller
914
915 # Logical network:
916 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
917 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and
918 # bar (192.168.2.0/24) connected to it. R2 has alice (172.16.1.0/24) connected
919 # to it. R3 has bob (172.16.1.0/24) connected to it. Note how both alice and
920 # bob have the same subnet behind it. We are trying to simulate external
921 # network via those 2 switches. In real world the switch ports of these
922 # switches will have addresses set as "unknown" to make them learning switches.
923 # Or those switches will be "localnet" ones.
924 #
925 # foo -- R1 -- join - R2 -- alice
926 # | |
927 # bar ---- - R3 --- bob
928
929 ovn-nbctl create Logical_Router name=R1
930 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
931 ovn-nbctl create Logical_Router name=R3 options:chassis=hv1
932
933 ovn-nbctl ls-add foo
934 ovn-nbctl ls-add bar
935 ovn-nbctl ls-add alice
936 ovn-nbctl ls-add bob
937 ovn-nbctl ls-add join
938
939 # Connect foo to R1
940 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
941 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
942 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
943
944 # Connect bar to R1
945 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
946 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
947 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
948
949 # Connect alice to R2
950 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
951 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
952 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
953
954 # Connect bob to R3
955 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
956 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
957 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
958
959 # Connect R1 to join
960 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
961 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
962 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
963
964 # Connect R2 to join
965 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
966 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
967 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
968
969 # Connect R3 to join
970 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
971 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
972 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
973
974 # Install static routes with source ip address as the policy for routing.
975 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
976 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
977 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
978
979 # Static routes.
980 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
981 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
982
983 # For gateway routers R2 and R3, set a force SNAT rule.
984 ovn-nbctl set logical_router R2 options:lb_force_snat_ip=20.0.0.2
985 ovn-nbctl set logical_router R3 options:lb_force_snat_ip=20.0.0.3
986
987 # Logical port 'foo1' in switch 'foo'.
988 ADD_NAMESPACES(foo1)
989 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
990 "192.168.1.1")
991 ovn-nbctl lsp-add foo foo1 \
992 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
993
994 # Logical port 'alice1' in switch 'alice'.
995 ADD_NAMESPACES(alice1)
996 ADD_VETH(alice1, alice1, br-int, "172.16.1.3/24", "f0:00:00:01:02:04", \
997 "172.16.1.1")
998 ovn-nbctl lsp-add alice alice1 \
999 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
1000
1001 # Logical port 'bar1' in switch 'bar'.
1002 ADD_NAMESPACES(bar1)
1003 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
1004 "192.168.2.1")
1005 ovn-nbctl lsp-add bar bar1 \
1006 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
1007
1008 # Logical port 'bob1' in switch 'bob'.
1009 ADD_NAMESPACES(bob1)
1010 ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
1011 "172.16.1.2")
1012 ovn-nbctl lsp-add bob bob1 \
1013 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
1014
1015 # Config OVN load-balancer with a VIP.
1016 uuid=`ovn-nbctl create load_balancer vips:30.0.0.1="192.168.1.2,192.168.2.2"`
1017 ovn-nbctl set logical_router R2 load_balancer=$uuid
1018 ovn-nbctl set logical_router R3 load_balancer=$uuid
1019
1020 # Wait for ovn-controller to catch up.
1021 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
1022
1023 # Start webservers in 'foo1', 'bar1'.
1024 NETNS_DAEMONIZE([foo1], [[$PYTHON $srcdir/test-l7.py]], [http1.pid])
1025 NETNS_DAEMONIZE([bar1], [[$PYTHON $srcdir/test-l7.py]], [http2.pid])
1026
1027 dnl Should work with the virtual IP address through NAT
1028 for i in `seq 1 20`; do
1029 echo Request $i
1030 NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
1031 done
1032
1033 dnl Each server should have at least one connection.
1034 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) |
1035 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
1036 tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
1037 tcp,orig=(src=172.16.1.3,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=172.16.1.3,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
1038 ])
1039
1040 dnl Force SNAT should have worked.
1041 AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(20.0.0) |
1042 sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
1043 tcp,orig=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
1044 tcp,orig=(src=172.16.1.3,dst=192.168.2.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.2.2,dst=20.0.0.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,protoinfo=(state=<cleared>)
1045 ])
1046 OVS_APP_EXIT_AND_WAIT([ovn-controller])
1047
1048 as ovn-sb
1049 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1050
1051 as ovn-nb
1052 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1053
1054 as northd
1055 OVS_APP_EXIT_AND_WAIT([ovn-northd])
1056
1057 as
1058 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
1059 /connection dropped.*/d"])
1060 AT_CLEANUP