]>
Commit | Line | Data |
---|---|---|
cc08428b GS |
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 | |
e74d157a GS |
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 |