1 AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, SNAT and DNAT])
7 OVS_TRAFFIC_VSWITCHD_START()
10 # Set external-ids in br-int needed for ovn-controller
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
18 # Start ovn-controller
19 start_daemon ovn-controller
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.
27 # foo -- R1 -- join - R2 -- alice
31 ovn-nbctl create Logical_Router name=R1
32 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
36 ovn-nbctl ls-add alice
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\"
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\"
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\"
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"'
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"'
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
68 # Logical port 'foo1' in switch 'foo'.
70 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
72 ovn-nbctl lsp-add foo foo1 \
73 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
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", \
79 ovn-nbctl lsp-add alice alice1 \
80 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
82 # Logical port 'bar1' in switch 'bar'.
84 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
86 ovn-nbctl lsp-add bar bar1 \
87 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
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
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
97 # wait for ovn-controller to catch up.
98 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
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], \
103 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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], \
109 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
118 # South-North SNAT: 'bar1' pings 'alice1'. But 'alice1' receives traffic
120 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
122 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
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
134 # Flush conntrack entries for easier output parsing of next test.
135 AT_CHECK([ovs-appctl dpctl/flush-conntrack])
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], \
140 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
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>
157 OVS_APP_EXIT_AND_WAIT([ovn-controller])
160 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
163 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
166 OVS_APP_EXIT_AND_WAIT([ovn-northd])
169 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
170 /connection dropped.*/d"])
173 AT_SETUP([ovn -- 2 LRs connected via LS, gateway router, easy SNAT])
174 AT_KEYWORDS([ovnnat])
177 CHECK_CONNTRACK_NAT()
179 OVS_TRAFFIC_VSWITCHD_START()
182 # Set external-ids in br-int needed for ovn-controller
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
190 # Start ovn-controller
191 start_daemon ovn-controller
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.
199 # foo -- R1 -- join - R2 -- alice
202 ovn-nbctl lr-add R2 -- set Logical_Router R2 options:chassis=hv1
205 ovn-nbctl ls-add alice
206 ovn-nbctl ls-add join
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
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\"
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\"
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"'
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"'
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
233 # Logical port 'foo1' in switch 'foo'.
235 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
237 ovn-nbctl lsp-add foo foo1 \
238 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
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", \
244 ovn-nbctl lsp-add alice alice1 \
245 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
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
251 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
253 # South-North SNAT: 'foo1' pings 'alice1'. But 'alice1' receives traffic
255 NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.2 | FORMAT_PING], \
257 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
266 OVS_APP_EXIT_AND_WAIT([ovn-controller])
269 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
272 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
275 OVS_APP_EXIT_AND_WAIT([ovn-northd])
278 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
279 /connection dropped.*/d"])
282 AT_SETUP([ovn -- multiple gateway routers, SNAT and DNAT])
283 AT_KEYWORDS([ovnnat])
286 CHECK_CONNTRACK_NAT()
288 OVS_TRAFFIC_VSWITCHD_START()
291 # Set external-ids in br-int needed for ovn-controller
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
299 # Start ovn-controller
300 start_daemon ovn-controller
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.
312 # foo -- R1 -- join - R2 -- alice
314 # bar ---- - R3 --- bob
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
322 ovn-nbctl ls-add alice
324 ovn-nbctl ls-add join
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\"
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\"
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\"
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\"
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"'
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"'
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"'
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
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
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
374 # Logical port 'foo1' in switch 'foo'.
376 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
378 ovn-nbctl lsp-add foo foo1 \
379 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
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", \
385 ovn-nbctl lsp-add alice alice1 \
386 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
388 # Logical port 'bar1' in switch 'bar'.
390 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
392 ovn-nbctl lsp-add bar bar1 \
393 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
395 # Logical port 'bob1' in switch 'bob'.
397 ADD_VETH(bob1, bob1, br-int, "172.16.1.4/24", "f0:00:00:01:02:06", \
399 ovn-nbctl lsp-add bob bob1 \
400 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
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
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
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
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
420 # wait for ovn-controller to catch up.
421 OVS_WAIT_UNTIL([ovs-ofctl dump-flows br-int | grep ct\( | grep nat])
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], \
426 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
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>
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], \
444 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
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>
459 # South-North SNAT: 'bar1' pings 'bob1'. But 'bob1' receives traffic
461 NS_CHECK_EXEC([bar1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.4 | FORMAT_PING], \
463 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
472 # South-North SNAT: 'foo1' pings 'alice1'. But 'alice1' receives traffic
474 NS_CHECK_EXEC([foo1], [ping -q -c 3 -i 0.3 -w 2 172.16.1.3 | FORMAT_PING], \
476 3 packets transmitted, 3 received, 0% packet loss, time 0ms
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>
485 OVS_APP_EXIT_AND_WAIT([ovn-controller])
488 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
491 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
494 OVS_APP_EXIT_AND_WAIT([ovn-northd])
497 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
498 /connection dropped.*/d"])
501 AT_SETUP([ovn -- load-balancing])
505 CHECK_CONNTRACK_NAT()
507 OVS_TRAFFIC_VSWITCHD_START()
510 # Set external-ids in br-int needed for ovn-controller
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
518 # Start ovn-controller
519 start_daemon ovn-controller
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.
527 # Loadbalancer VIPs in 30.0.0.0/24 network.
529 ovn-nbctl create Logical_Router name=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\"
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\"
543 # Create logical port 'foo1' in switch 'foo'.
545 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
547 ovn-nbctl lsp-add foo foo1 \
548 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
550 # Create logical ports 'bar1', 'bar2', 'bar3' in switch 'bar'.
552 ADD_VETH(bar1, bar1, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \
554 ovn-nbctl lsp-add bar bar1 \
555 -- lsp-set-addresses bar1 "f0:00:0f:01:02:03 172.16.1.2"
558 ADD_VETH(bar2, bar2, br-int, "172.16.1.3/24", "f0:00:0f:01:02:04", \
560 ovn-nbctl lsp-add bar bar2 \
561 -- lsp-set-addresses bar2 "f0:00:0f:01:02:04 172.16.1.3"
564 ADD_VETH(bar3, bar3, br-int, "172.16.1.4/24", "f0:00:0f:01:02:05", \
566 ovn-nbctl lsp-add bar bar3 \
567 -- lsp-set-addresses bar3 "f0:00:0f:01:02:05 172.16.1.4"
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
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
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"'
580 # Wait for ovn-controller to catch up.
581 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
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])
588 dnl Should work with the virtual IP 30.0.0.1 address through NAT
589 for i in `seq 1 20`; do
591 NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
602 dnl Should work with the virtual IP 30.0.0.3 address through NAT
603 for i in `seq 1 20`; do
605 NS_CHECK_EXEC([foo1], [wget 30.0.0.3 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
616 dnl Test load-balancing that includes L4 ports in NAT.
617 for i in `seq 1 20`; do
619 NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
631 OVS_APP_EXIT_AND_WAIT([ovn-controller])
634 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
637 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
640 OVS_APP_EXIT_AND_WAIT([ovn-northd])
643 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
646 AT_SETUP([ovn -- load-balancing - same subnet.])
650 CHECK_CONNTRACK_NAT()
652 OVS_TRAFFIC_VSWITCHD_START()
655 # Set external-ids in br-int needed for ovn-controller
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
663 # Start ovn-controller
664 start_daemon ovn-controller
667 # 1 logical switch "foo" (192.168.1.0/24) connected to router R1.
668 # foo has foo1, foo2, foo3, foo4 as logical ports.
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
674 ovn-nbctl create Logical_Router name=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\"
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
686 ADD_VETH(foo$i, foo$i, br-int, "192.168.1.$j/24", "f0:00:00:01:02:0$j", \
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"
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
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"'
699 # Wait for ovn-controller to catch up.
700 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
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])
707 dnl Should work with the virtual IP address through NAT
708 for i in `seq 1 20`; do
710 NS_CHECK_EXEC([foo1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
721 dnl Test load-balancing that includes L4 ports in NAT.
722 for i in `seq 1 20`; do
724 NS_CHECK_EXEC([foo1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
736 OVS_APP_EXIT_AND_WAIT([ovn-controller])
739 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
742 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
745 OVS_APP_EXIT_AND_WAIT([ovn-northd])
748 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d"])
751 AT_SETUP([ovn -- load balancing in gateway router])
755 CHECK_CONNTRACK_NAT()
757 OVS_TRAFFIC_VSWITCHD_START()
760 # Set external-ids in br-int needed for ovn-controller
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
768 # Start ovn-controller
769 start_daemon ovn-controller
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.
777 # foo -- R1 -- join - R2 -- alice
781 ovn-nbctl create Logical_Router name=R1
782 ovn-nbctl create Logical_Router name=R2 options:chassis=hv1
786 ovn-nbctl ls-add alice
787 ovn-nbctl ls-add join
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\"
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\"
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\"
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"'
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"'
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
818 # Logical port 'foo1' in switch 'foo'.
820 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
822 ovn-nbctl lsp-add foo foo1 \
823 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
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", \
829 ovn-nbctl lsp-add alice alice1 \
830 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
832 # Logical port 'bar1' in switch 'bar'.
834 ADD_VETH(bar1, bar1, br-int, "192.168.2.2/24", "f0:00:00:01:02:05", \
836 ovn-nbctl lsp-add bar bar1 \
837 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
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
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"'
846 # Wait for ovn-controller to catch up.
847 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
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])
853 dnl Should work with the virtual IP address through NAT
854 for i in `seq 1 20`; do
856 NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
866 dnl Test load-balancing that includes L4 ports in NAT.
867 for i in `seq 1 20`; do
869 NS_CHECK_EXEC([alice1], [wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
879 OVS_APP_EXIT_AND_WAIT([ovn-controller])
882 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
885 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
888 OVS_APP_EXIT_AND_WAIT([ovn-northd])
891 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
892 /connection dropped.*/d"])
895 AT_SETUP([ovn -- multiple gateway routers, load-balancing])
899 CHECK_CONNTRACK_NAT()
901 OVS_TRAFFIC_VSWITCHD_START()
904 # Set external-ids in br-int needed for ovn-controller
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
912 # Start ovn-controller
913 start_daemon ovn-controller
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.
925 # foo -- R1 -- join - R2 -- alice
927 # bar ---- - R3 --- bob
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
935 ovn-nbctl ls-add alice
937 ovn-nbctl ls-add join
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\"
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\"
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\"
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\"
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"'
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"'
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"'
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
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
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
987 # Logical port 'foo1' in switch 'foo'.
989 ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \
991 ovn-nbctl lsp-add foo foo1 \
992 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
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", \
998 ovn-nbctl lsp-add alice alice1 \
999 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.3"
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", \
1005 ovn-nbctl lsp-add bar bar1 \
1006 -- lsp-set-addresses bar1 "f0:00:00:01:02:05 192.168.2.2"
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", \
1012 ovn-nbctl lsp-add bob bob1 \
1013 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
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
1020 # Wait for ovn-controller to catch up.
1021 OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | grep ct\(])
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])
1027 dnl Should work with the virtual IP address through NAT
1028 for i in `seq 1 20`; do
1030 NS_CHECK_EXEC([alice1], [wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log])
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>)
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>)
1046 OVS_APP_EXIT_AND_WAIT([ovn-controller])
1049 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1052 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1055 OVS_APP_EXIT_AND_WAIT([ovn-northd])
1058 OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
1059 /connection dropped.*/d"])