]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovn.at
ovn-controller: Incremental processing for address-set changes.
[mirror_ovs.git] / tests / ovn.at
1 # OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2 #
3 # This compares packets read from PCAP, in pcap format, to those read
4 # from EXPECTED, which is a text file containing packets as hex
5 # strings, one per line. If PCAP contains fewer packets than
6 # EXPECTED, it waits up to 10 seconds for more packets to appear.
7 #
8 # The implementation is an m4 macro that is mostly implemented in
9 # terms of a shell function. This reduces the size of the generated
10 # testsuite file since the shell function is only emitted once even
11 # when this macro is invoked many times.
12 m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 OVS_WAIT_UNTIL(
21 [$PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 echo "rcv_n=$rcv_n exp_n=$exp_n"
24 test $rcv_n -ge $exp_n])
25 sort $exp_text > expout
26 }
27 ])
28 m4_define([OVN_CHECK_PACKETS],
29 [ovn_check_packets__ "$1" "$2"
30 AT_CHECK([sort $rcv_text], [0], [expout])])
31
32 AT_BANNER([OVN components])
33
34 AT_SETUP([ovn -- lexer])
35 dnl For lines without =>, input and expected output are identical.
36 dnl For lines with =>, input precedes => and expected output follows =>.
37 AT_DATA([test-cases.txt], [dnl
38 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
39 "abc\u0020def" => "abc def"
40 " => error("Input ends inside quoted string.")dnl "
41
42 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
43 $1 => error("`$' must be followed by a valid identifier.") 1
44
45 a/*b*/c => a c
46 a//b c => a
47 a/**/b => a b
48 a/*/b => a error("`/*' without matching `*/'.")
49 a/*/**/b => a b
50 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
51
52 0 1 12345 18446744073709551615
53 18446744073709551616 => error("Decimal constants must be less than 2**64.")
54 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
55 01 => error("Decimal constants must not have leading zeros.")
56
57 0/0
58 0/1
59 1/0 => error("Value contains unmasked 1-bits.")
60 1/1
61 128/384
62 1/3
63 1/ => error("Integer constant expected.")
64
65 1/0x123 => error("Value and mask have incompatible formats.")
66
67 0x1234
68 0x01234 => 0x1234
69 0x0 => 0
70 0x000 => 0
71 0xfedcba9876543210
72 0XFEDCBA9876543210 => 0xfedcba9876543210
73 0xfedcba9876543210fedcba9876543210
74 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
75 0x => error("Hex digits expected following 0x.")
76 0X => error("Hex digits expected following 0X.")
77 0x0/0x0 => 0/0
78 0x0/0x1 => 0/0x1
79 0x1/0x0 => error("Value contains unmasked 1-bits.")
80 0xffff/0x1ffff
81 0x. => error("Invalid syntax in hexadecimal constant.")
82
83 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
84 256.1.2.3 => error("Invalid numeric constant.")
85 192.168.0.0/16
86 192.168.0.0/255.255.0.0 => 192.168.0.0/16
87 192.168.0.0/255.255.255.0 => 192.168.0.0/24
88 192.168.0.0/255.255.0.255
89 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
90 192.168.0.0/32
91 192.168.0.0/255.255.255.255 => 192.168.0.0/32
92 1.2.3.4:5 => 1.2.3.4 : 5
93
94 ::
95 ::1
96 ff00::1234 => ff00::1234
97 2001:db8:85a3::8a2e:370:7334
98 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
99 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
100 ::ffff:192.0.2.128
101 ::ffff:c000:0280 => ::ffff:192.0.2.128
102 ::1/::1
103 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
104 ::1/128
105 ff00::/8
106 ff00::/ff00:: => ff00::/8
107
108 01:23:45:67:ab:cd
109 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
110 fe:dc:ba:98:76:54
111 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
112 01:00:00:00:00:00/01:00:00:00:00:00
113 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
114 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
115 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
116 fe:x => error("Invalid numeric constant.")
117 00:01:02:03:04:x => error("Invalid numeric constant.")
118
119 # Test that operators are tokenized as expected, even without white space.
120 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
121 & => error("`&' is only valid as part of `&&'.")
122 | => error("`|' is only valid as part of `||'.")
123 - => error("`-' is only valid as part of `--'.")
124
125 ^ => error("Invalid character `^' in input.")
126 ])
127 AT_CAPTURE_FILE([input.txt])
128 sed 's/ =>.*//' test-cases.txt > input.txt
129 sed 's/.* => //' test-cases.txt > expout
130 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
131 AT_CLEANUP
132
133 dnl The OVN expression parser needs to know what fields overlap with one
134 dnl another. This test therefore verifies that all the smaller registers
135 dnl are defined as terms of subfields of the larger ones.
136 dnl
137 dnl When we add or remove registers this test needs to be updated, of course.
138 AT_SETUP([ovn -- registers])
139 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
140 [[reg0 = xxreg0[96..127]
141 reg1 = xxreg0[64..95]
142 reg2 = xxreg0[32..63]
143 reg3 = xxreg0[0..31]
144 reg4 = xxreg1[96..127]
145 reg5 = xxreg1[64..95]
146 reg6 = xxreg1[32..63]
147 reg7 = xxreg1[0..31]
148 reg8 = xreg4[32..63]
149 reg9 = xreg4[0..31]
150 xreg0 = xxreg0[64..127]
151 xreg1 = xxreg0[0..63]
152 xreg2 = xxreg1[64..127]
153 xreg3 = xxreg1[0..63]
154 xreg4 = OXM_OF_PKT_REG4
155 xxreg0 = NXM_NX_XXREG0
156 xxreg1 = NXM_NX_XXREG1
157 ]])
158 AT_CLEANUP
159
160 dnl Check that the OVN conntrack field definitions are correct.
161 AT_SETUP([ovn -- conntrack fields])
162 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
163 [[ct.dnat = ct_state[7]
164 ct.est = ct_state[1]
165 ct.inv = ct_state[4]
166 ct.new = ct_state[0]
167 ct.rel = ct_state[2]
168 ct.rpl = ct_state[3]
169 ct.snat = ct_state[6]
170 ct.trk = ct_state[5]
171 ct_label = NXM_NX_CT_LABEL
172 ct_label.blocked = ct_label[0]
173 ct_mark = NXM_NX_CT_MARK
174 ct_state = NXM_NX_CT_STATE
175 ]])
176 AT_CLEANUP
177
178 AT_SETUP([ovn -- composition])
179 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
180 AT_CLEANUP
181
182 AT_SETUP([ovn -- expression parser])
183 dnl For lines without =>, input and expected output are identical.
184 dnl For lines with =>, input precedes => and expected output follows =>.
185 AT_DATA([test-cases.txt], [[
186 eth.type == 0x800
187 eth.type==0x800 => eth.type == 0x800
188 eth.type[0..15] == 0x800 => eth.type == 0x800
189
190 vlan.present
191 vlan.present == 1 => vlan.present
192 !(vlan.present == 0) => vlan.present
193 !(vlan.present != 1) => vlan.present
194 !vlan.present
195 vlan.present == 0 => !vlan.present
196 vlan.present != 1 => !vlan.present
197 !(vlan.present == 1) => !vlan.present
198 !(vlan.present != 0) => !vlan.present
199
200 eth.dst[0]
201 eth.dst[0] == 1 => eth.dst[0]
202 eth.dst[0] != 0 => eth.dst[0]
203 !(eth.dst[0] == 0) => eth.dst[0]
204 !(eth.dst[0] != 1) => eth.dst[0]
205
206 !eth.dst[0]
207 eth.dst[0] == 0 => !eth.dst[0]
208 eth.dst[0] != 1 => !eth.dst[0]
209 !(eth.dst[0] == 1) => !eth.dst[0]
210 !(eth.dst[0] != 0) => !eth.dst[0]
211
212 vlan.tci[12..15] == 0x3
213 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
214 vlan.tci[12..15] != 0x3
215 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
216
217 !vlan.pcp => vlan.pcp == 0
218 !(vlan.pcp) => vlan.pcp == 0
219 vlan.pcp == 0x4
220 vlan.pcp != 0x4
221 vlan.pcp > 0x4
222 vlan.pcp >= 0x4
223 vlan.pcp < 0x4
224 vlan.pcp <= 0x4
225 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
226 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
227 !(vlan.pcp <= 0x4) => vlan.pcp > 0x4
228 !(vlan.pcp < 0x4) => vlan.pcp >= 0x4
229 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
230 !(vlan.pcp > 0x4) => vlan.pcp <= 0x4
231 0x4 == vlan.pcp => vlan.pcp == 0x4
232 0x4 != vlan.pcp => vlan.pcp != 0x4
233 0x4 < vlan.pcp => vlan.pcp > 0x4
234 0x4 <= vlan.pcp => vlan.pcp >= 0x4
235 0x4 > vlan.pcp => vlan.pcp < 0x4
236 0x4 >= vlan.pcp => vlan.pcp <= 0x4
237 !(0x4 != vlan.pcp) => vlan.pcp == 0x4
238 !(0x4 == vlan.pcp) => vlan.pcp != 0x4
239 !(0x4 >= vlan.pcp) => vlan.pcp > 0x4
240 !(0x4 > vlan.pcp) => vlan.pcp >= 0x4
241 !(0x4 <= vlan.pcp) => vlan.pcp < 0x4
242 !(0x4 < vlan.pcp) => vlan.pcp <= 0x4
243
244 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
245 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
246 1 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
247 1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
248 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
249 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
250 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
251 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
252 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
253 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
254 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
255 !(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
256 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
257 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
258 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
259 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
260 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
261 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
262
263 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
264 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
265
266 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
267 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
268
269 vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
270 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
271 vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
272
273 ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
274 ip6.src == ::1 => ip6.src == 0x1
275
276 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
277 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
278 ip6.src == ::1 => ip6.src == 0x1
279
280 1
281 0
282 !1 => 0
283 !0 => 1
284
285 inport == "eth0"
286 !(inport != "eth0") => inport == "eth0"
287
288 (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => 0
289
290 ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291 inport == 1 => String field inport is not compatible with integer constant.
292 ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
293
294 ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295 eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296 vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
297
298 inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299 !(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300 eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301 !(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
302 inport = "eth0" => Syntax error at `=' expecting relational operator.
303
304 123 == 123 => Syntax error at `123' expecting field name.
305
306 $name => Syntax error at `$name' expecting address set name.
307 @name => Syntax error at `@name' expecting port group name.
308
309 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311
312 inport[1] == 1 => Cannot select subfield of string field inport.
313
314 eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315 eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316 eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317
318 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319
320 eth.type[5..1] => Invalid bit range 5 to 1.
321
322 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323
324 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325
326 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327
328 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329
330 123 => Syntax error at end of input expecting relational operator.
331
332 123 x => Syntax error at `x' expecting relational operator.
333
334 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335
336 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337
338 (1 x) => Syntax error at `x' expecting `)'.
339
340 !0x800 != eth.type => Missing parentheses around operand of !.
341
342 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343
344 eth.dst == {} => Syntax error at `}' expecting constant.
345
346 eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
347
348 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
349
350 1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
351
352 eth.dst[40] x => Syntax error at `x' expecting end of input.
353
354 ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355 eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
356
357 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => Parentheses nested too deeply.
358
359 ct_label > $set4 => Only == and != operators may be used to compare a field against an empty value set.
360 ]])
361 sed 's/ =>.*//' test-cases.txt > input.txt
362 sed 's/.* => //' test-cases.txt > expout
363 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
364 AT_CLEANUP
365
366 AT_SETUP([ovn -- expression annotation])
367 dnl Input precedes =>, expected output follows =>.
368 dnl Empty lines and lines starting with # are ignored.
369 AT_DATA([test-cases.txt], [[
370 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
371 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
372 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
373 ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
374 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
375
376 # Nested expressions over a single symbol should be annotated with symbol's
377 # prerequisites only once, at the top level.
378 tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
379
380 ip => eth.type == 0x800 || eth.type == 0x86dd
381 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
382 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
383 ip > 0 => Only == and != operators may be used with nominal field ip.
384 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
385 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
386
387 vlan.present => vlan.tci[12]
388 !vlan.present => !vlan.tci[12]
389
390 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
391 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
392 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
393
394 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
395 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
396 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
397
398 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
399 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
400 mutual_recurse_1 != 0 => Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_1'.
401 mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
402 ]])
403 sed 's/ =>.*//' test-cases.txt > input.txt
404 sed 's/.* => //' test-cases.txt > expout
405 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
406 AT_CLEANUP
407
408 AT_SETUP([ovn -- 1-term expression conversion])
409 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
410 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
411 ])
412 AT_CLEANUP
413
414 AT_SETUP([ovn -- 2-term expression conversion])
415 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
416 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
417 ])
418 AT_CLEANUP
419
420 AT_SETUP([ovn -- 3-term expression conversion])
421 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
422 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
423 ])
424 AT_CLEANUP
425
426 AT_SETUP([ovn -- 3-term numeric expression simplification])
427 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
428 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
429 ])
430 AT_CLEANUP
431
432 AT_SETUP([ovn -- 4-term string expression simplification])
433 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
434 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
435 ])
436 AT_CLEANUP
437
438 AT_SETUP([ovn -- 3-term mixed expression simplification])
439 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
440 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
441 ])
442 AT_CLEANUP
443
444 AT_SETUP([ovn -- simplification special cases])
445 simplify() {
446 echo "$1" | ovstest test-ovn simplify-expr
447 }
448 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
449 ])
450 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
451 ])
452 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
453 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
454 ])
455 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
456 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
457 ])
458 AT_CHECK([simplify 'tcp.dst > 0'], [0],
459 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
460 ]])
461 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
462 [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
463 ]])
464 AT_CLEANUP
465
466 AT_SETUP([ovn -- is_chassis_resident simplification])
467 simplify() {
468 echo "$1" | ovstest test-ovn simplify-expr
469 }
470 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
471 ])
472 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
473 ])
474 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
475 ])
476 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
477 ])
478 AT_CLEANUP
479
480 AT_SETUP([ovn -- 4-term numeric expression normalization])
481 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
482 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
483 ])
484 AT_CLEANUP
485
486 AT_SETUP([ovn -- 4-term string expression normalization])
487 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
488 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
489 ])
490 AT_CLEANUP
491
492 AT_SETUP([ovn -- 4-term mixed expression normalization])
493 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
494 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
495 ])
496 AT_CLEANUP
497
498 AT_SETUP([ovn -- 5-term numeric expression normalization])
499 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
500 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
501 ])
502 AT_CLEANUP
503
504 AT_SETUP([ovn -- 5-term string expression normalization])
505 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
506 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
507 ])
508 AT_CLEANUP
509
510 AT_SETUP([ovn -- 5-term mixed expression normalization])
511 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
512 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
513 ])
514 AT_CLEANUP
515
516 AT_SETUP([ovn -- 4-term numeric expressions to flows])
517 AT_KEYWORDS([expression])
518 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
519 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
520 ])
521 AT_CLEANUP
522
523 AT_SETUP([ovn -- 4-term string expressions to flows])
524 AT_KEYWORDS([expression])
525 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
526 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
527 ])
528 AT_CLEANUP
529
530 AT_SETUP([ovn -- 4-term mixed expressions to flows])
531 AT_KEYWORDS([expression])
532 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
533 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
534 ])
535 AT_CLEANUP
536
537 AT_SETUP([ovn -- 3-term numeric expressions to flows])
538 AT_KEYWORDS([expression])
539 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
540 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
541 ])
542 AT_CLEANUP
543
544 AT_SETUP([ovn -- converting expressions to flows -- string fields])
545 AT_KEYWORDS([expression])
546 expr_to_flow () {
547 echo "$1" | ovstest test-ovn expr-to-flows | sort
548 }
549 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
550 ])
551 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
552 ])
553 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
554 ])
555 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
556 ip,reg14=0x5
557 ipv6,reg14=0x5
558 ])
559 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
560 ip,reg14=0x6
561 ipv6,reg14=0x6
562 ])
563 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
564 ])
565 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
566 [reg14=0x5
567 reg14=0x6
568 reg14=0xfffe
569 ])
570 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
571 ip,reg14=0x5
572 ip,reg14=0x6
573 ipv6,reg14=0x5
574 ipv6,reg14=0x6
575 ])
576 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
577 (no flows)
578 ])
579 AT_CLEANUP
580
581 AT_SETUP([ovn -- converting expressions to flows -- address sets])
582 AT_KEYWORDS([expression])
583 expr_to_flow () {
584 echo "$1" | ovstest test-ovn expr-to-flows | sort
585 }
586 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
587 ip,nw_src=10.0.0.1
588 ip,nw_src=10.0.0.2
589 ip,nw_src=10.0.0.3
590 ])
591 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
592 ip,nw_src=10.0.0.1
593 ip,nw_src=10.0.0.2
594 ip,nw_src=10.0.0.3
595 ])
596 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
597 ip,nw_src=1.2.3.4
598 ip,nw_src=10.0.0.1
599 ip,nw_src=10.0.0.2
600 ip,nw_src=10.0.0.3
601 ])
602 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
603 ip,nw_src=1.2.0.0/20
604 ip,nw_src=10.0.0.1
605 ip,nw_src=10.0.0.2
606 ip,nw_src=10.0.0.3
607 ip,nw_src=5.5.5.0/24
608 ])
609 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
610 ipv6,ipv6_src=::1
611 ipv6,ipv6_src=::2
612 ipv6,ipv6_src=::3
613 ])
614 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
615 ipv6,ipv6_src=::1
616 ipv6,ipv6_src=::2
617 ipv6,ipv6_src=::3
618 ipv6,ipv6_src=::4
619 ])
620 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, 00:00:00:00:00:02, 00:00:00:00:00:03}'], [0], [dnl
621 dl_src=00:00:00:00:00:01
622 dl_src=00:00:00:00:00:02
623 dl_src=00:00:00:00:00:03
624 ])
625 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
626 dl_src=00:00:00:00:00:01
627 dl_src=00:00:00:00:00:02
628 dl_src=00:00:00:00:00:03
629 ])
630 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
631 dl_src=00:00:00:00:00:01
632 dl_src=00:00:00:00:00:02
633 dl_src=00:00:00:00:00:03
634 dl_src=ba:be:be:ef:de:ad
635 ])
636 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
637 (no flows)
638 ])
639 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
640 ip,nw_src=1.2.3.4
641 ])
642 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
643 ip,nw_src=1.2.3.4
644 ])
645 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
646
647 ])
648 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
649 ip,nw_src=0.0.0.0/1.0.0.0
650 ip,nw_src=128.0.0.0/1
651 ip,nw_src=16.0.0.0/16.0.0.0
652 ip,nw_src=2.0.0.0/2.0.0.0
653 ip,nw_src=32.0.0.0/32.0.0.0
654 ip,nw_src=4.0.0.0/4.0.0.0
655 ip,nw_src=64.0.0.0/64.0.0.0
656 ip,nw_src=8.0.0.0/8.0.0.0
657 ])
658 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
659 ip,nw_src=0.0.0.0/1.0.0.0
660 ip,nw_src=128.0.0.0/1
661 ip,nw_src=16.0.0.0/16.0.0.0
662 ip,nw_src=2.0.0.0/2.0.0.0
663 ip,nw_src=32.0.0.0/32.0.0.0
664 ip,nw_src=4.0.0.0/4.0.0.0
665 ip,nw_src=64.0.0.0/64.0.0.0
666 ip,nw_src=8.0.0.0/8.0.0.0
667 ])
668 AT_CLEANUP
669
670 AT_SETUP([ovn -- converting expressions to flows -- port groups])
671 AT_KEYWORDS([expression])
672 expr_to_flow () {
673 echo "$1" | ovstest test-ovn expr-to-flows | sort
674 }
675 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
676 reg15=0x11
677 reg15=0x12
678 reg15=0x13
679 ])
680 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
681 (no flows)
682 ])
683 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
684 reg15=0x11
685 ])
686 AT_CLEANUP
687
688 AT_SETUP([ovn -- converting expressions to flows -- conjunction])
689 AT_KEYWORDS([conjunction])
690 expr_to_flow () {
691 echo "$1" | ovstest test-ovn expr-to-flows | sort
692 }
693
694 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
695 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
696 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
697 conj_id=1,ip
698 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
699 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
700 ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
701 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
702 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
703 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
704 ])
705
706 lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
707 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
708 ct_state=+est+trk,ct_label=0x1/0x1,ip
709 ct_state=+est+trk,ct_label=0x1/0x1,ipv6
710 ct_state=-est+trk,ip
711 ct_state=-est+trk,ipv6
712 ])
713
714 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
715 ip4.dst == {20.0.0.1, 20.0.0.2}"
716 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
717 conj_id=1,ip
718 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
719 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
720 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
721 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
722 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
723 ])
724
725 lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
726 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
727 tcp.dst >= 1000 && tcp.dst <= 1010"
728
729 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
730 conj_id=1,tcp
731 tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
732 tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
733 tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
734 tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
735 tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
736 tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
737 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
738 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
739 tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
740 tcp,tp_dst=1000: conjunction(1, 2/3)
741 tcp,tp_dst=1001: conjunction(1, 2/3)
742 tcp,tp_dst=1010: conjunction(1, 2/3)
743 ])
744
745 lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
746 ((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
747 tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
748 || ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
749
750 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
751 conj_id=1,tcp
752 ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
753 ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
754 ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
755 ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
756 ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
757 ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
758 tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
759 tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
760 tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
761 tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
762 tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
763 tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
764 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
765 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
766 tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
767 tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
768 tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
769 tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
770 tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
771 tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
772 tcp,tp_dst=1000: conjunction(1, 2/4)
773 tcp,tp_dst=1001: conjunction(1, 2/4)
774 tcp,tp_dst=2000: conjunction(1, 2/4)
775 tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
776 tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
777 tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
778 tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
779 tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
780 tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
781 tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
782 tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
783 tcp,tp_src=1000: conjunction(1, 3/4)
784 tcp,tp_src=1001: conjunction(1, 3/4)
785 tcp,tp_src=2000: conjunction(1, 3/4)
786 ])
787 AT_CLEANUP
788
789 AT_SETUP([ovn -- action parsing])
790 dnl Unindented text is input (a set of OVN logical actions).
791 dnl Indented text is expected output.
792 AT_DATA([test-cases.txt],
793 [[# drop
794 drop;
795 encodes as drop
796 drop; next;
797 Syntax error at `next' expecting end of input.
798 next; drop;
799 Syntax error at `drop' expecting action.
800
801 # output
802 output;
803 encodes as resubmit(,64)
804
805 # next
806 next;
807 encodes as resubmit(,19)
808 next(11);
809 formats as next;
810 encodes as resubmit(,19)
811 next(0);
812 encodes as resubmit(,8)
813 next(23);
814 encodes as resubmit(,31)
815
816 next();
817 Syntax error at `)' expecting "pipeline" or "table".
818 next(10;
819 Syntax error at `;' expecting `)'.
820 next(24);
821 "next" action cannot advance beyond table 23.
822
823 next(table=11);
824 formats as next;
825 encodes as resubmit(,19)
826 next(pipeline=ingress);
827 formats as next;
828 encodes as resubmit(,19)
829 next(table=11, pipeline=ingress);
830 formats as next;
831 encodes as resubmit(,19)
832 next(pipeline=ingress, table=11);
833 formats as next;
834 encodes as resubmit(,19)
835
836 next(pipeline=egress);
837 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
838
839 next(table=10);
840 formats as next(10);
841 encodes as resubmit(,18)
842
843 # Loading a constant value.
844 tcp.dst=80;
845 formats as tcp.dst = 80;
846 encodes as set_field:80->tcp_dst
847 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
848 eth.dst[40] = 1;
849 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
850 vlan.pcp = 2;
851 encodes as set_field:0x4000/0xe000->vlan_tci
852 has prereqs vlan.tci[12]
853 vlan.tci[13..15] = 2;
854 encodes as set_field:0x4000/0xe000->vlan_tci
855 inport = "";
856 encodes as set_field:0->reg14
857 ip.ttl=4;
858 formats as ip.ttl = 4;
859 encodes as set_field:4->nw_ttl
860 has prereqs eth.type == 0x800 || eth.type == 0x86dd
861 outport="eth0"; next; outport="LOCAL"; next;
862 formats as outport = "eth0"; next; outport = "LOCAL"; next;
863 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
864
865 inport[1] = 1;
866 Cannot select subfield of string field inport.
867 ip.proto[1] = 1;
868 Cannot select subfield of nominal field ip.proto.
869 eth.dst[40] == 1;
870 Syntax error at `==' expecting `=' or `<->'.
871 ip = 1;
872 Predicate symbol ip used where lvalue required.
873 ip.proto = 6;
874 Field ip.proto is not modifiable.
875 inport = {"a", "b"};
876 Syntax error at `{' expecting constant.
877 inport = {};
878 Syntax error at `{' expecting constant.
879 bad_prereq = 123;
880 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
881 self_recurse = 123;
882 Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
883 vlan.present = 0;
884 Predicate symbol vlan.present used where lvalue required.
885
886 # Moving one field into another.
887 reg0=reg1;
888 formats as reg0 = reg1;
889 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
890 vlan.pcp = reg0[0..2];
891 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
892 has prereqs vlan.tci[12]
893 reg0[10] = vlan.pcp[1];
894 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
895 has prereqs vlan.tci[12]
896 outport = inport;
897 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
898
899 reg0[0] = vlan.present;
900 Predicate symbol vlan.present used where lvalue required.
901 reg0 = reg1[0..10];
902 Can't assign 11-bit value to 32-bit destination.
903 inport = reg0;
904 Can't assign integer field (reg0) to string field (inport).
905 inport = big_string;
906 String fields inport and big_string are incompatible for assignment.
907 ip.proto = reg0[0..7];
908 Field ip.proto is not modifiable.
909
910 # Exchanging fields.
911 reg0 <-> reg1;
912 encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
913 vlan.pcp <-> reg0[0..2];
914 encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
915 has prereqs vlan.tci[12]
916 reg0[10] <-> vlan.pcp[1];
917 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
918 has prereqs vlan.tci[12]
919 outport <-> inport;
920 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
921
922 reg0[0] <-> vlan.present;
923 Predicate symbol vlan.present used where lvalue required.
924 reg0 <-> reg1[0..10];
925 Can't exchange 32-bit field with 11-bit field.
926 inport <-> reg0;
927 Can't exchange string field (inport) with integer field (reg0).
928 inport <-> big_string;
929 String fields inport and big_string are incompatible for exchange.
930 ip.proto <-> reg0[0..7];
931 Field ip.proto is not modifiable.
932 reg0[0..7] <-> ip.proto;
933 Field ip.proto is not modifiable.
934
935 # TTL decrement.
936 ip.ttl--;
937 encodes as dec_ttl
938 has prereqs ip
939 ip.ttl
940 Syntax error at end of input expecting `--'.
941
942 # load balancing.
943 ct_lb;
944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
945 has prereqs ip
946 ct_lb();
947 formats as ct_lb;
948 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
949 has prereqs ip
950 ct_lb(192.168.1.2:80, 192.168.1.3:80);
951 encodes as group:1
952 has prereqs ip
953 ct_lb(192.168.1.2, 192.168.1.3, );
954 formats as ct_lb(192.168.1.2, 192.168.1.3);
955 encodes as group:2
956 has prereqs ip
957 ct_lb(fd0f::2, fd0f::3, );
958 formats as ct_lb(fd0f::2, fd0f::3);
959 encodes as group:3
960 has prereqs ip
961
962 ct_lb(192.168.1.2:);
963 Syntax error at `)' expecting port number.
964 ct_lb(192.168.1.2:123456);
965 Syntax error at `123456' expecting port number.
966 ct_lb(foo);
967 Syntax error at `foo' expecting IP address.
968 ct_lb([192.168.1.2]);
969 Syntax error at `192.168.1.2' expecting IPv6 address.
970
971 # ct_next
972 ct_next;
973 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
974 has prereqs ip
975
976 # ct_commit
977 ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980 ct_commit();
981 formats as ct_commit;
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
983 has prereqs ip
984 ct_commit(ct_mark=1);
985 formats as ct_commit(ct_mark=0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
987 has prereqs ip
988 ct_commit(ct_mark=1/1);
989 formats as ct_commit(ct_mark=0x1/0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
991 has prereqs ip
992 ct_commit(ct_label=1);
993 formats as ct_commit(ct_label=0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
995 has prereqs ip
996 ct_commit(ct_label=1/1);
997 formats as ct_commit(ct_label=0x1/0x1);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
999 has prereqs ip
1000 ct_commit(ct_mark=1, ct_label=2);
1001 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
1002 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
1003 has prereqs ip
1004
1005 ct_commit(ct_label=0x01020304050607080910111213141516);
1006 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1008 has prereqs ip
1009 ct_commit(ct_label=0x181716151413121110090807060504030201);
1010 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1011 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1012 has prereqs ip
1013 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1015 has prereqs ip
1016 ct_commit(ct_label=18446744073709551615);
1017 formats as ct_commit(ct_label=0xffffffffffffffff);
1018 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1019 has prereqs ip
1020 ct_commit(ct_label=18446744073709551616);
1021 Decimal constants must be less than 2**64.
1022
1023 # ct_dnat
1024 ct_dnat;
1025 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
1026 has prereqs ip
1027 ct_dnat(192.168.1.2);
1028 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
1029 has prereqs ip
1030
1031 ct_dnat(192.168.1.2, 192.168.1.3);
1032 Syntax error at `,' expecting `)'.
1033 ct_dnat(foo);
1034 Syntax error at `foo' expecting IPv4 address.
1035 ct_dnat(foo, bar);
1036 Syntax error at `foo' expecting IPv4 address.
1037 ct_dnat();
1038 Syntax error at `)' expecting IPv4 address.
1039
1040 # ct_snat
1041 ct_snat;
1042 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
1043 has prereqs ip
1044 ct_snat(192.168.1.2);
1045 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
1046 has prereqs ip
1047
1048 ct_snat(192.168.1.2, 192.168.1.3);
1049 Syntax error at `,' expecting `)'.
1050 ct_snat(foo);
1051 Syntax error at `foo' expecting IPv4 address.
1052 ct_snat(foo, bar);
1053 Syntax error at `foo' expecting IPv4 address.
1054 ct_snat();
1055 Syntax error at `)' expecting IPv4 address.
1056
1057 # ct_clear
1058 ct_clear;
1059 encodes as ct_clear
1060
1061 # clone
1062 clone { ip4.dst = 255.255.255.255; output; }; next;
1063 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
1064 has prereqs eth.type == 0x800
1065
1066 # arp
1067 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1069 has prereqs ip4
1070 arp { };
1071 formats as arp { drop; };
1072 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1073 has prereqs ip4
1074
1075 # get_arp
1076 get_arp(outport, ip4.dst);
1077 encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
1078 has prereqs eth.type == 0x800
1079 get_arp(inport, reg0);
1080 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
1081
1082 get_arp;
1083 Syntax error at `;' expecting `('.
1084 get_arp();
1085 Syntax error at `)' expecting field name.
1086 get_arp(inport);
1087 Syntax error at `)' expecting `,'.
1088 get_arp(inport ip4.dst);
1089 Syntax error at `ip4.dst' expecting `,'.
1090 get_arp(inport, ip4.dst;
1091 Syntax error at `;' expecting `)'.
1092 get_arp(inport, eth.dst);
1093 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1094 get_arp(inport, outport);
1095 Cannot use string field outport where numeric field is required.
1096 get_arp(reg0, ip4.dst);
1097 Cannot use numeric field reg0 where string field is required.
1098
1099 # put_arp
1100 put_arp(inport, arp.spa, arp.sha);
1101 encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
1102 has prereqs eth.type == 0x806 && eth.type == 0x806
1103
1104 # put_dhcp_opts
1105 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1106 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
1107 reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot");
1108 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org", wpad = "https://example.org", bootfile_name = "https://127.0.0.1/boot.ipxe", path_prefix = "/tftpboot");
1109 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67.43.1b.68.74.74.70.73.3a.2f.2f.31.32.37.2e.30.2e.30.2e.31.2f.62.6f.6f.74.2e.69.70.78.65.d2.09.2f.74.66.74.70.62.6f.6f.74,pause)
1110 reg0[15] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,mtu=1400,ip_forward_enable=1,default_ttl=121,dns_server={8.8.8.8,7.7.7.7},classless_static_route={30.0.0.0/24,10.0.0.4,40.0.0.0/16,10.0.0.6,0.0.0.0/0,10.0.0.1},ethernet_encap=1,router_discovery=0,tftp_server_address={10.0.0.4,10.0.0.5});
1111 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0, tftp_server_address = {10.0.0.4, 10.0.0.5});
1112 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00.96.08.0a.00.00.04.0a.00.00.05,pause)
1113
1114 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1115 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1116 reg1[0] = put_dhcp_opts();
1117 put_dhcp_opts requires offerip to be specified.
1118 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1119 Syntax error at `x' expecting DHCPv4 option name.
1120 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1121 put_dhcp_opts requires offerip to be specified.
1122 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1123 Syntax error at `"hi"'.
1124 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1125 Syntax error at `xyzzy' expecting DHCPv4 option name.
1126 reg1[0] = put_dhcp_opts(offerip="xyzzy");
1127 DHCPv4 option offerip requires numeric value.
1128 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1129 DHCPv4 option domain requires string value.
1130
1131 # nd_ns
1132 nd_ns { nd.target = xxreg0; output; };
1133 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1134 has prereqs ip6
1135
1136 nd_ns { };
1137 formats as nd_ns { drop; };
1138 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1139 has prereqs ip6
1140
1141 # nd_na
1142 nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1143 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1144 encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1145 has prereqs nd_ns
1146 # nd_na_router
1147 nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1148 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1149 encodes as controller(userdata=00.00.00.0c.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1150 has prereqs nd_ns
1151
1152 # get_nd
1153 get_nd(outport, ip6.dst);
1154 encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
1155 has prereqs eth.type == 0x86dd
1156 get_nd(inport, xxreg0);
1157 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
1158 get_nd;
1159 Syntax error at `;' expecting `('.
1160 get_nd();
1161 Syntax error at `)' expecting field name.
1162 get_nd(inport);
1163 Syntax error at `)' expecting `,'.
1164 get_nd(inport ip6.dst);
1165 Syntax error at `ip6.dst' expecting `,'.
1166 get_nd(inport, ip6.dst;
1167 Syntax error at `;' expecting `)'.
1168 get_nd(inport, eth.dst);
1169 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1170 get_nd(inport, outport);
1171 Cannot use string field outport where numeric field is required.
1172 get_nd(xxreg0, ip6.dst);
1173 Cannot use numeric field xxreg0 where string field is required.
1174
1175 # put_nd
1176 put_nd(inport, nd.target, nd.sll);
1177 encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
1178 has prereqs (icmp6.type == 0x87 || icmp6.type == 0x88) && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
1179
1180 # put_dhcpv6_opts
1181 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1182 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.05.00.10.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.00.02.00.06.00.00.00.00.10.02,pause)
1183 reg1[0] = put_dhcpv6_opts();
1184 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1185 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1186 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1187 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
1188 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1189 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1190 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.02.00.06.12.34.56.78.9a.bc.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
1191 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1192 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.18.00.07.6f.76.6e.2e.6f.72.67,pause)
1193 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1194 Syntax error at `x' expecting DHCPv6 option name.
1195 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1196 Syntax error at `"hi"'.
1197 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1198 Syntax error at `xyzzy' expecting DHCPv6 option name.
1199 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1200 DHCPv6 option ia_addr requires numeric value.
1201 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1202 DHCPv6 option domain_search requires string value.
1203
1204 # set_queue
1205 set_queue(0);
1206 encodes as set_queue:0
1207 set_queue(61440);
1208 encodes as set_queue:61440
1209 set_queue(65535);
1210 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1211
1212 # dns_lookup
1213 reg1[0] = dns_lookup();
1214 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1215 has prereqs udp
1216 reg1[0] = dns_lookup("foo");
1217 dns_lookup doesn't take any parameters
1218
1219 # set_meter
1220 set_meter(0);
1221 Rate 0 for set_meter is not in valid.
1222 set_meter(1);
1223 encodes as meter:1
1224 set_meter(100, 1000);
1225 encodes as meter:2
1226 set_meter(100, 1000, );
1227 Syntax error at `,' expecting `)'.
1228 set_meter(4294967295, 4294967295);
1229 encodes as meter:3
1230
1231 # log
1232 log(verdict=allow, severity=warning);
1233 encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
1234 log(name="test1", verdict=drop, severity=info);
1235 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
1236 log(verdict=drop, severity=info, meter="meter1");
1237 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
1238 log(name="test1", verdict=drop, severity=info, meter="meter1");
1239 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
1240 log(verdict=drop);
1241 formats as log(verdict=drop, severity=info);
1242 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
1243 log(verdict=bad_verdict, severity=info);
1244 Syntax error at `bad_verdict' unknown verdict.
1245 log(verdict=drop, severity=bad_severity);
1246 Syntax error at `bad_severity' unknown severity.
1247 log(severity=notice);
1248 Syntax error at `;' expecting verdict.
1249
1250 # put_nd_ra_opts
1251 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1252 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1253 has prereqs ip6
1254 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1255 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1256 has prereqs ip6
1257 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1258 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1259 has prereqs ip6
1260 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1261 slla option not present
1262 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1263 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1264 has prereqs ip6
1265 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1266 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.aa.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1267 has prereqs ip6
1268 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1269 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1270 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1271 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1272 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1273 Syntax error at `dhcpv6_stateless' expecting constant.
1274 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1275 Invalid value for "prefix" option
1276 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1277 Invalid value for "addr_mode" option
1278 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1279 IPv6 ND RA option mtu requires numeric value.
1280 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1281 Invalid value for "mtu" option
1282
1283 # icmp4
1284 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1285 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1286 has prereqs ip4
1287
1288 icmp4 { };
1289 formats as icmp4 { drop; };
1290 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1291 has prereqs ip4
1292
1293 # icmp4 with icmp4.frag_mtu
1294 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1295 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1296 has prereqs ip4
1297
1298 # icmp4_error
1299 icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1300 encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1301 has prereqs ip4
1302
1303 icmp4_error { };
1304 formats as icmp4_error { drop; };
1305 encodes as controller(userdata=00.00.00.0e.00.00.00.00)
1306 has prereqs ip4
1307
1308 # icmp4_error with icmp4.frag_mtu
1309 icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1310 encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1311 has prereqs ip4
1312
1313 icmp4.frag_mtu = 1500;
1314 encodes as controller(userdata=00.00.00.0d.00.00.00.00.05.dc,pause)
1315
1316 # icmp6
1317 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1318 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1319 has prereqs ip6
1320
1321 icmp6 { };
1322 formats as icmp6 { drop; };
1323 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1324 has prereqs ip6
1325
1326 # tcp_reset
1327 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1328 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1329 has prereqs tcp
1330
1331 tcp_reset { };
1332 formats as tcp_reset { drop; };
1333 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1334 has prereqs tcp
1335
1336 # Contradictionary prerequisites (allowed but not useful):
1337 ip4.src = ip6.src[0..31];
1338 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1339 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1340 ip4.src <-> ip6.src[0..31];
1341 encodes as push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[]
1342 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1343
1344 # check_pkt_larger
1345 reg0[0] = check_pkt_larger(1500);
1346 encodes as check_pkt_larger(1500)->NXM_NX_XXREG0[96]
1347
1348 reg0 = check_pkt_larger(1500);
1349 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1350
1351 reg0 = check_pkt_larger(foo);
1352 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1353
1354 reg0[0] = check_pkt_larger(foo);
1355 Syntax error at `foo' expecting `;'.
1356
1357 # Miscellaneous negative tests.
1358 ;
1359 Syntax error at `;'.
1360 xyzzy;
1361 Syntax error at `xyzzy' expecting action.
1362 next; 123;
1363 Syntax error at `123'.
1364 next; xyzzy;
1365 Syntax error at `xyzzy' expecting action.
1366 next
1367 Syntax error at end of input expecting `;'.
1368 ]])
1369 sed '/^[[ ]]/d' test-cases.txt > input.txt
1370 cp test-cases.txt expout
1371 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1372 AT_CLEANUP
1373
1374 AT_BANNER([OVN end-to-end tests])
1375
1376 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1377 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1378 AT_KEYWORDS([ovnarp])
1379 AT_SKIP_IF([test $HAVE_PYTHON = no])
1380 ovn_start
1381
1382 # Create hypervisors hv[123].
1383 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1384 # Add all of the vifs to a single logical switch lsw0.
1385 # Turn on port security on all the vifs except vif[123]1.
1386 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1387 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1388 ovn-nbctl ls-add lsw0
1389 net_add n1
1390 for i in 1 2 3; do
1391 sim_add hv$i
1392 as hv$i
1393 ovs-vsctl add-br br-phys
1394 ovn_attach n1 br-phys 192.168.0.$i
1395
1396 for j in 1 2 3; do
1397 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
1398 ovn-nbctl lsp-add lsw0 lp$i$j
1399 if test $j = 1; then
1400 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1401 else
1402 if test $j = 3; then
1403 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1404 else
1405 ip_addrs="192.168.0.$i$j"
1406 fi
1407 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1408 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1409 fi
1410 done
1411 done
1412 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1413 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1414 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1415 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:11\",\"f0:00:00:00:00:21\",\"f0:00:00:00:00:31\"
1416 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1417
1418 get_lsp_uuid () {
1419 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1420 }
1421
1422 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1423 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1424
1425 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1426 # packets for ARP resolution (native tunneling doesn't queue packets
1427 # for ARP resolution).
1428 OVN_POPULATE_ARP
1429
1430 # Allow some time for ovn-northd and ovn-controller to catch up.
1431 # XXX This should be more systematic.
1432 sleep 1
1433
1434 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1435 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1436 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1437 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1438
1439 # Given the name of a logical port, prints the name of the hypervisor
1440 # on which it is located.
1441 vif_to_hv() {
1442 echo hv${1%?}
1443 }
1444
1445 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1446 #
1447 # This shell function causes a packet to be received on INPORT. The packet's
1448 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1449 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1450 # more) list the VIFs on which the packet should be received. INPORT and the
1451 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1452 for i in 1 2 3; do
1453 for j in 1 2 3; do
1454 : > $i$j.expected
1455 done
1456 done
1457 test_packet() {
1458 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1459 hv=`vif_to_hv $inport`
1460 vif=vif$inport
1461 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1462 for outport; do
1463 echo $packet >> $outport.expected
1464 done
1465 }
1466
1467 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1468 #
1469 # Causes a packet to be received on INPORT. The packet is an ARP
1470 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1471 # it should be the hardware address of the target to expect to receive in an
1472 # ARP reply; otherwise no reply is expected.
1473 #
1474 # INPORT is an logical switch port number, e.g. 11 for vif11.
1475 # SHA and REPLY_HA are each 12 hex digits.
1476 # SPA and TPA are each 8 hex digits.
1477 test_arp() {
1478 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1479 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1480 hv=`vif_to_hv $inport`
1481 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1482
1483 if test X$reply_ha = X; then
1484 # Expect to receive the broadcast ARP on the other logical switch ports
1485 # if no reply is expected.
1486 local i j
1487 for i in 1 2 3; do
1488 for j in 1 2 3; do
1489 if test $i$j != $inport; then
1490 echo $request >> $i$j.expected
1491 fi
1492 done
1493 done
1494 else
1495 # Expect to receive the reply, if any.
1496 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1497 echo $reply >> $inport.expected
1498 fi
1499 }
1500
1501 ip_to_hex() {
1502 printf "%02x%02x%02x%02x" "$@"
1503 }
1504
1505 # Send packets between all pairs of source and destination ports:
1506 #
1507 # 1. Unicast packets are delivered to exactly one logical switch port
1508 # (except that packets destined to their input ports are dropped).
1509 #
1510 # 2. Broadcast and multicast are delivered to all logical switch ports
1511 # except the input port.
1512 #
1513 # 3. When port security is turned on, the switch drops packets from the wrong
1514 # MAC address.
1515 #
1516 # 4. The switch drops all packets with a VLAN tag.
1517 #
1518 # 5. The switch drops all packets with a multicast source address. (This only
1519 # affects behavior when port security is turned off, since otherwise port
1520 # security would drop the packet anyway.)
1521 #
1522 # 6. The switch delivers packets with an unknown destination to logical
1523 # switch ports with "unknown" among their MAC addresses (and port
1524 # security disabled).
1525 #
1526 # 7. The switch drops unicast packets that violate an ACL.
1527 #
1528 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1529 #
1530 # 9. OVN generates responses to ARP requests for known IPs, except for
1531 # requests from a port for the port's own IP.
1532 #
1533 # 10. No response to ARP requests for unknown IPs.
1534
1535 for is in 1 2 3; do
1536 for js in 1 2 3; do
1537 s=$is$js
1538 bcast=
1539 unknown=
1540 bacl2=
1541 bacl3=
1542 for id in 1 2 3; do
1543 for jd in 1 2 3; do
1544 d=$id$jd
1545
1546 if test $d != $s; then unicast=$d; else unicast=; fi
1547 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1548
1549 if test $d != $s && test $js = 1; then
1550 impersonate=$d
1551 else
1552 impersonate=
1553 fi
1554 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1555
1556 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1557 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1558 if test $d = $s || (test $js = 1 && test $d = 33); then
1559 # Source of 11, 21, or 31 and dest of 33 should be dropped
1560 # due to the 4th ACL that uses address_set(set1).
1561 acl4=
1562 else
1563 acl4=$d
1564 fi
1565 if test $d = $s || test $d = 22 || test $d = 33; then
1566 # dest of 22 and 33 should be dropped
1567 # due to the 5th ACL that uses port_group(pg1).
1568 acl5=
1569 else
1570 acl5=$d
1571 fi
1572 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1573 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1574 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1575 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1576 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1577
1578 test_packet $s f000000000$d f00000000055 810000091234 #4
1579 test_packet $s f000000000$d 0100000000$s $s$d #5
1580
1581 if test $d != $s && test $jd = 1; then
1582 unknown="$unknown $d"
1583 fi
1584 bcast="$bcast $unicast"
1585 bacl2="$bacl2 $acl2"
1586 bacl3="$bacl3 $acl3"
1587
1588 sip=`ip_to_hex 192 168 0 $is$js`
1589 tip=`ip_to_hex 192 168 0 $id$jd`
1590 tip_unknown=`ip_to_hex 11 11 11 11`
1591 if test $d != $s; then
1592 reply_ha=f000000000$d
1593 else
1594 reply_ha=
1595 fi
1596 test_arp $s f000000000$s $sip $tip $reply_ha #9
1597 test_arp $s f000000000$s $sip $tip_unknown #10
1598
1599 if test $jd = 3; then
1600 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1601 tip=`ip_to_hex 192 169 0 $id$jd`
1602 test_arp $s f000000000$s $sip $tip $reply_ha #9
1603 fi
1604 done
1605 done
1606
1607 # Broadcast and multicast.
1608 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1609 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1610 if test $js = 1; then
1611 bcast_impersonate=$bcast
1612 else
1613 bcast_impersonate=
1614 fi
1615 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1616
1617 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1618
1619 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1620 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1621 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1622 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1623 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1624 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1625 done
1626 done
1627
1628 # set address for lp13 with invalid characters.
1629 # lp13 should be configured with only 192.168.0.13.
1630 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1631
1632 # Allow some time for ovn-northd and ovn-controller to catch up.
1633 # XXX This should be more systematic.
1634 sleep 1
1635
1636 sip=`ip_to_hex 192 168 0 11`
1637 tip=`ip_to_hex 192 168 0 13`
1638 test_arp 11 f00000000011 $sip $tip f00000000013
1639
1640 tip=`ip_to_hex 192 169 0 13`
1641 #arp request for 192.169.0.13 should be flooded
1642 test_arp 11 f00000000011 $sip $tip
1643
1644 # dump information and flows with counters
1645 ovn-sbctl dump-flows -- list multicast_group
1646
1647 echo "------ hv1 dump ------"
1648 as hv1 ovs-vsctl show
1649 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1650
1651 echo "------ hv2 dump ------"
1652 as hv2 ovs-vsctl show
1653 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1654
1655 echo "------ hv3 dump ------"
1656 as hv3 ovs-vsctl show
1657 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1658
1659 # Now check the packets actually received against the ones expected.
1660 for i in 1 2 3; do
1661 for j in 1 2 3; do
1662 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1663 done
1664 done
1665
1666 OVN_CLEANUP([hv1],[hv2],[hv3])
1667
1668 AT_CLEANUP
1669
1670 # 2 hypervisors, one logical switch, 2 logical ports per hypervisor
1671 # logical ports bound to chassis encap-ip.
1672 AT_SETUP([ovn -- 2 HVs, 1 LS, 2 lports/HV])
1673 AT_KEYWORDS([ovnarp])
1674 AT_SKIP_IF([test $HAVE_PYTHON = no])
1675 ovn_start
1676
1677 # Create hypervisors hv[12].
1678 # Add vif1[12] to hv1, vif2[12] to hv2
1679 ovn-nbctl ls-add lsw0
1680 net_add n1
1681 for i in 1 2; do
1682 sim_add hv$i
1683 as hv$i
1684 ovs-vsctl add-br br-phys
1685 ovn_attach n1 br-phys 192.168.0.$i
1686
1687 for j in 1 2; do
1688 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
1689 ovn-nbctl lsp-add lsw0 lp$i$j
1690 ip_addrs="192.168.0.$i$j"
1691 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1692 ovn-nbctl --wait=hv lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1693 done
1694 done
1695
1696 get_lsp_uuid () {
1697 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1698 }
1699
1700 # XXX-Check how to pass lp$i1 in AT_CHECK_UNQUOTED, for now just do it
1701 # explictly
1702
1703 # For Chassis hv1
1704 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1705 encap : [[]]
1706 ])
1707 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1708 encap : [[]]
1709 ])
1710
1711 # For Chassis hv2
1712 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1713 encap : [[]]
1714 ])
1715 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1716 encap : [[]]
1717 ])
1718
1719 # Bind the ports to the encap-ip
1720 for i in 1 2; do
1721 for j in 1 2; do
1722 as hv$i
1723 ovs-vsctl set Interface vif$i$j external-ids:encap-ip=192.168.0.$i
1724 done
1725 done
1726
1727 sleep 1
1728
1729 # dump port bindings; since we have vxlan and geneve tunnels, we expect the
1730 # ports to be bound to geneve tunnels.
1731
1732 # For Chassis 1
1733 encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv1 type=geneve ip=192.168.0.1`
1734
1735 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1736 encap : ${encap_rec}
1737 ])
1738
1739 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1740 encap : ${encap_rec}
1741 ])
1742
1743 # For Chassis 2
1744 encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv2 type=geneve ip=192.168.0.2`
1745
1746 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1747 encap : ${encap_rec}
1748 ])
1749
1750 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1751 encap : ${encap_rec}
1752 ])
1753
1754 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1755 # packets for ARP resolution (native tunneling doesn't queue packets
1756 # for ARP resolution).
1757 OVN_POPULATE_ARP
1758
1759 # Allow some time for ovn-northd and ovn-controller to catch up.
1760 # XXX This should be more systematic.
1761 sleep 1
1762
1763 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1764 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1765 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1766 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1767
1768 # Given the name of a logical port, prints the name of the hypervisor
1769 # on which it is located.
1770 vif_to_hv() {
1771 echo hv${1%?}
1772 }
1773
1774 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1775 #
1776 # This shell function causes a packet to be received on INPORT. The packet's
1777 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1778 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1779 # more) list the VIFs on which the packet should be received. INPORT and the
1780 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1781 for i in 1 2; do
1782 for j in 1 2; do
1783 : > $i$j.expected
1784 done
1785 done
1786 test_packet() {
1787 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1788 hv=`vif_to_hv $inport`
1789 vif=vif$inport
1790 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1791 for outport; do
1792 echo $packet >> $outport.expected
1793 done
1794 }
1795
1796 ip_to_hex() {
1797 printf "%02x%02x%02x%02x" "$@"
1798 }
1799
1800 # Send packets between all pairs of source and destination ports:
1801 #
1802 # 1. Unicast packets are delivered to exactly one logical switch port
1803 # (except that packets destined to their input ports are dropped).
1804
1805 for is in 1 2; do
1806 for js in 1 2; do
1807 s=$is$js
1808 bcast=
1809 unknown=
1810 bacl2=
1811 bacl3=
1812 for id in 1 2 3; do
1813 for jd in 1 2 3; do
1814 d=$id$jd
1815
1816 if test $d != $s; then unicast=$d; else unicast=; fi
1817 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1818 done
1819 done
1820
1821 done
1822 done
1823
1824 # dump information and flows with counters
1825 ovn-sbctl dump-flows -- list multicast_group
1826
1827 echo "------ hv1 dump ------"
1828 as hv1 ovs-vsctl show
1829 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1830
1831 echo "------ hv2 dump ------"
1832 as hv2 ovs-vsctl show
1833 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1834
1835 echo "------ hv3 dump ------"
1836 as hv3 ovs-vsctl show
1837 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1838
1839 # Now check the packets actually received against the ones expected.
1840 for i in 1 2; do
1841 for j in 1 2; do
1842 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1843 done
1844 done
1845
1846 OVN_CLEANUP([hv1],[hv2])
1847
1848 AT_CLEANUP
1849
1850 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1851 AT_SKIP_IF([test $HAVE_PYTHON = no])
1852 ovn_start
1853
1854 # Create a logical switch and some logical ports.
1855 # Turn on port security on all lports except ls1.
1856 # Make ls1 a destination for unknown MACs.
1857 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1858 ovn-nbctl ls-add lsw0
1859 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1860 for i in 1 2 3; do
1861 ovn-nbctl lsp-add lsw0 lp$i
1862 done
1863 ovn-nbctl --wait=sb sync
1864 for i in 1 2 3; do
1865 ovn-sbctl lsp-bind lp$i hv0
1866 if test $i = 1; then
1867 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1868 else
1869 if test $i = 3; then
1870 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1871 else
1872 ip_addrs="192.168.0.$i"
1873 fi
1874 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1875 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1876 fi
1877 done
1878 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1879 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1880 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1881 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1882 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1883
1884 ovn-nbctl --wait=sb sync
1885 on_exit 'kill `cat ovn-trace.pid`'
1886 ovn-trace --detach --pidfile --no-chdir
1887
1888 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1889 #
1890 # This shell function causes a packet to be received on INPORT. The packet's
1891 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1892 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1893 # more) list the VIFs on which the packet should be received. INPORT and the
1894 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1895 test_packet() {
1896 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1897 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1898 while :; do
1899 case $1 in # (
1900 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1901 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1902 *) break ;;
1903 esac
1904 done
1905 for outport; do
1906 echo "output(\"lp$outport\");"
1907 done > expout
1908
1909 AT_CAPTURE_FILE([trace])
1910 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1911 }
1912
1913 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1914 #
1915 # Causes a packet to be received on INPORT. The packet is an ARP
1916 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1917 # it should be the hardware address of the target to expect to receive in an
1918 # ARP reply; otherwise no reply is expected.
1919 #
1920 # INPORT is an logical switch port number, e.g. 11 for vif11.
1921 # SHA and REPLY_HA are each 12 hex digits.
1922 # SPA and TPA are each 8 hex digits.
1923 test_arp() {
1924 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1925
1926 local request="inport == \"lp$inport\"
1927 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1928 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1929 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1930
1931 if test -z "$reply_ha"; then
1932 reply=
1933 local i
1934 for i in 1 2 3; do
1935 if test $i != $inport; then
1936 reply="${reply}output(\"lp$i\");
1937 "
1938 fi
1939 done
1940 else
1941 reply="\
1942 eth.dst = $sha;
1943 eth.src = $reply_ha;
1944 arp.op = 2;
1945 arp.tha = $sha;
1946 arp.sha = $reply_ha;
1947 arp.tpa = $spa;
1948 arp.spa = $tpa;
1949 output(\"lp$inport\");
1950 "
1951 fi
1952
1953 AT_CAPTURE_FILE([trace])
1954 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1955 }
1956
1957 # Send packets between all pairs of source and destination ports:
1958 #
1959 # 1. Unicast packets are delivered to exactly one logical switch port
1960 # (except that packets destined to their input ports are dropped).
1961 #
1962 # 2. Broadcast and multicast are delivered to all logical switch ports
1963 # except the input port.
1964 #
1965 # 3. When port security is turned on, the switch drops packets from the wrong
1966 # MAC address.
1967 #
1968 # 4. The switch drops all packets with a VLAN tag.
1969 #
1970 # 5. The switch drops all packets with a multicast source address. (This only
1971 # affects behavior when port security is turned off, since otherwise port
1972 # security would drop the packet anyway.)
1973 #
1974 # 6. The switch delivers packets with an unknown destination to logical
1975 # switch ports with "unknown" among their MAC addresses (and port
1976 # security disabled).
1977 #
1978 # 7. The switch drops unicast packets that violate an ACL.
1979 #
1980 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1981 #
1982 # 9. OVN generates responses to ARP requests for known IPs, except for
1983 # requests from a port for the port's own IP.
1984 #
1985 # 10. No response to ARP requests for unknown IPs.
1986
1987 for s in 1 2 3; do
1988 bcast=
1989 unknown=
1990 bacl2=
1991 bacl3=
1992 for d in 1 2 3; do
1993 echo
1994 echo "lp$s -> lp$d"
1995 if test $d != $s; then unicast=$d; else unicast=; fi
1996 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1997
1998 if test $d != $s && test $s = 1; then
1999 impersonate=$d
2000 else
2001 impersonate=
2002 fi
2003 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
2004
2005 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
2006 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
2007 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
2008 # Source of 1 or 2 and dest of 3 should be dropped
2009 # due to the 4th ACL that uses address_set(set1).
2010 acl4=
2011 else
2012 acl4=$d
2013 fi
2014
2015 #7, acl1 to acl4:
2016 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
2017 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
2018 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
2019 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
2020
2021 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
2022 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
2023
2024 if test $d != $s && test $d = 1; then
2025 unknown="$unknown $d"
2026 fi
2027 bcast="$bcast $unicast"
2028 bacl2="$bacl2 $acl2"
2029 bacl3="$bacl3 $acl3"
2030
2031 sip=192.168.0.$s
2032 tip=192.168.0.$d
2033 tip_unknown=11.11.11.11
2034 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
2035 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
2036 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
2037
2038 if test $d = 3; then
2039 # lp3 has an additional ip 192.169.0.[123]3.
2040 tip=192.169.0.$d
2041 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
2042 fi
2043 done
2044
2045 # Broadcast and multicast.
2046 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
2047 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
2048 if test $s = 1; then
2049 bcast_impersonate=$bcast
2050 else
2051 bcast_impersonate=
2052 fi
2053 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
2054
2055 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
2056
2057 #8, acl1 to acl3:
2058 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
2059 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
2060 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
2061
2062 #8, acl1 to acl3:
2063 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
2064 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
2065 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
2066 done
2067
2068 AT_CLEANUP
2069
2070 # 2 hypervisors, 4 logical ports per HV
2071 # 2 locally attached networks (one flat, one vlan tagged over same device)
2072 # 2 ports per HV on each network
2073 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
2074 AT_SKIP_IF([test $HAVE_PYTHON = no])
2075 ovn_start
2076
2077 # In this test cases we create 3 switches, all connected to same
2078 # physical network (through br-phys on each HV). Each switch has
2079 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
2080 # of VIF port name indicates the hypervisor it is bound to, e.g.
2081 # lp23 means VIF 3 on hv2.
2082 #
2083 # Each switch's VLAN tag and their logical switch ports are:
2084 # - ls1:
2085 # - untagged
2086 # - ports: lp11, lp12, lp21, lp22
2087 #
2088 # - ls2:
2089 # - tagged with VLAN 101
2090 # - ports: lp13, lp14, lp23, lp24
2091 # - ls3:
2092 # - untagged
2093 # - ports: lp15, lp25
2094 #
2095 # Note: a localnet port is created for each switch to connect to
2096 # physical network.
2097
2098 for i in 1 2 3; do
2099 ls_name=ls$i
2100 ovn-nbctl ls-add $ls_name
2101 ln_port_name=ln$i
2102 if test $i -eq 2; then
2103 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
2104 else
2105 ovn-nbctl lsp-add $ls_name $ln_port_name
2106 fi
2107 ovn-nbctl lsp-set-addresses $ln_port_name unknown
2108 ovn-nbctl lsp-set-type $ln_port_name localnet
2109 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
2110 done
2111
2112 # lsp_to_ls LSP
2113 #
2114 # Prints the name of the logical switch that contains LSP.
2115 lsp_to_ls () {
2116 case $1 in dnl (
2117 lp?[[12]]) echo ls1 ;; dnl (
2118 lp?[[34]]) echo ls2 ;; dnl (
2119 lp?5) echo ls3 ;; dnl (
2120 *) AT_FAIL_IF([:]) ;;
2121 esac
2122 }
2123
2124 net_add n1
2125 for i in 1 2; do
2126 sim_add hv$i
2127 as hv$i
2128 ovs-vsctl add-br br-phys
2129 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
2130 ovn_attach n1 br-phys 192.168.0.$i
2131
2132 for j in 1 2 3 4 5; do
2133 ovs-vsctl add-port br-int vif$i$j -- \
2134 set Interface vif$i$j external-ids:iface-id=lp$i$j \
2135 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
2136 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
2137 ofport-request=$i$j
2138
2139 lsp_name=lp$i$j
2140 ls_name=$(lsp_to_ls $lsp_name)
2141
2142 ovn-nbctl lsp-add $ls_name $lsp_name
2143 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
2144 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
2145
2146 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
2147 done
2148 done
2149 ovn-nbctl --wait=sb sync
2150 ovn-sbctl dump-flows
2151
2152 OVN_POPULATE_ARP
2153
2154 # XXX This is now the 3rd copy of these functions in this file ...
2155
2156 # Given the name of a logical port, prints the name of the hypervisor
2157 # on which it is located.
2158 vif_to_hv() {
2159 echo hv${1%?}
2160 }
2161 #
2162 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
2163 #
2164 # This shell function causes a packet to be received on INPORT. The packet's
2165 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2166 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
2167 # logical switch port numbers, e.g. 11 for vif11.
2168 #
2169 # EOUT is the end-to-end output port, that is, where the packet will end up
2170 # after possibly bouncing through one or more localnet ports. LOUT is the
2171 # logical output port, which might be a localnet port, as seen by ovn-trace
2172 # (which doesn't know what localnet ports are connected to and therefore can't
2173 # figure out the end-to-end answer).
2174 for i in 1 2; do
2175 for j in 1 2 3 4 5; do
2176 : > $i$j.expected
2177 done
2178 done
2179 test_packet() {
2180 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
2181 echo "$@"
2182
2183 # First try tracing the packet.
2184 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
2185 if test $lout != drop; then
2186 echo "output(\"$lout\");"
2187 fi > expout
2188 AT_CAPTURE_FILE([trace])
2189 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
2190
2191 # Then actually send a packet, for an end-to-end test.
2192 local packet=$(echo $dst$src | sed 's/://g')${eth}
2193 hv=`vif_to_hv $inport`
2194 vif=vif$inport
2195 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2196 if test $eout != drop; then
2197 echo $packet >> ${eout#lp}.expected
2198 fi
2199 }
2200
2201 # lp11 and lp21 are on the same network (phys, untagged)
2202 # and on different hypervisors
2203 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
2204 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
2205
2206 # lp11 and lp12 are on the same network (phys, untagged)
2207 # and on the same hypervisor
2208 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
2209 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
2210
2211 # lp13 and lp23 are on the same network (phys, VLAN 101)
2212 # and on different hypervisors
2213 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
2214 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
2215
2216 # lp13 and lp14 are on the same network (phys, VLAN 101)
2217 # and on the same hypervisor
2218 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2219 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
2220
2221 # lp11 and lp15 are on the same network (phys, untagged),
2222 # same hypervisor, and on different switches
2223 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2224 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
2225
2226 # lp11 and lp25 are on the same network (phys, untagged),
2227 # different hypervisors, and on different switches
2228 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2229 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
2230
2231 # Ports that should not be able to communicate
2232 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2233 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2234 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2235 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2236 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2237 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2238 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2239 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
2240
2241 # Dump a bunch of info helpful for debugging if there's a failure.
2242
2243 echo "------ OVN dump ------"
2244 ovn-nbctl show
2245 ovn-sbctl show
2246
2247 echo "------ hv1 dump ------"
2248 as hv1 ovs-vsctl show
2249 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2250
2251 echo "------ hv2 dump ------"
2252 as hv2 ovs-vsctl show
2253 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2254
2255 # Now check the packets actually received against the ones expected.
2256 for i in 1 2; do
2257 for j in 1 2 3 4 5; do
2258 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2259 done
2260 done
2261
2262 OVN_CLEANUP([hv1],[hv2])
2263
2264 AT_CLEANUP
2265
2266 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2267 AT_KEYWORDS([vtep])
2268 AT_SKIP_IF([test $HAVE_PYTHON = no])
2269 ovn_start
2270
2271 # Configure the Northbound database
2272 ovn-nbctl ls-add lsw0
2273
2274 ovn-nbctl lsp-add lsw0 lp1
2275 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2276
2277 ovn-nbctl lsp-add lsw0 lp2
2278 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2279
2280 ovn-nbctl lsp-add lsw0 lp-vtep
2281 ovn-nbctl lsp-set-type lp-vtep vtep
2282 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2283 ovn-nbctl lsp-set-addresses lp-vtep unknown
2284
2285 # lpr, lr and lrp1 are used for the ARP request handling test only.
2286 ovn-nbctl lsp-add lsw0 lpr
2287 ovn-nbctl lr-add lr
2288 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2289 ovn-nbctl set Logical_Switch_Port lpr type=router \
2290 options:router-port=lrp1 \
2291 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2292
2293
2294 net_add n1 # Network to connect hv1, hv2, and vtep
2295 net_add n2 # Network to connect vtep and hv3
2296
2297 # Create hypervisor hv1 connected to n1
2298 sim_add hv1
2299 as hv1
2300 ovs-vsctl add-br br-phys
2301 ovn_attach n1 br-phys 192.168.0.1
2302 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
2303
2304 # Create hypervisor hv2 connected to n1
2305 sim_add hv2
2306 as hv2
2307 ovs-vsctl add-br br-phys
2308 ovn_attach n1 br-phys 192.168.0.2
2309 ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
2310
2311
2312 # Start the vtep emulator with a leg in both networks
2313 sim_add vtep
2314 as vtep
2315
2316 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2317 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2318
2319 ovs-vsctl add-br br-phys
2320 net_attach n1 br-phys
2321
2322 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2323 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2324 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2325 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2326
2327 ovs-vsctl add-br br-vtep
2328 net_attach n2 br-vtep
2329
2330 vtep-ctl add-ps br-vtep
2331 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2332 vtep-ctl add-ls lsw0
2333
2334 start_daemon ovs-vtep br-vtep
2335 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2336
2337 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2338
2339 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2340 grep -- source`"])
2341 # It takes more time for the update to be processed by ovs-vtep.
2342 sleep 1
2343
2344 # Add hv3 on the other side of the vtep
2345 sim_add hv3
2346 as hv3
2347 ovs-vsctl add-br br-phys
2348 net_attach n2 br-phys
2349
2350 ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
2351
2352 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2353 # packets for ARP resolution (native tunneling doesn't queue packets
2354 # for ARP resolution).
2355 OVN_POPULATE_ARP
2356
2357 # Allow some time for ovn-northd and ovn-controller to catch up.
2358 # XXX This should be more systematic.
2359 sleep 1
2360
2361 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2362 #
2363 # This shell function causes a packet to be received on INPORT. The packet's
2364 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2365 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2366 # more) list the VIFs on which the packet should be received. INPORT and the
2367 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2368 for i in 1 2 3; do
2369 : > $i.expected
2370 done
2371 test_packet() {
2372 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2373 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2374 hv=hv$inport
2375 vif=vif$inport
2376 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2377 for outport; do
2378 echo $packet >> $outport.expected
2379 done
2380 }
2381
2382 # Send packets between all pairs of source and destination ports:
2383 #
2384 # 1. Unicast packets are delivered to exactly one logical switch port
2385 # (except that packets destined to their input ports are dropped).
2386 #
2387 # 2. Broadcast and multicast are delivered to all logical switch ports
2388 # except the input port.
2389 #
2390 # 3. The switch delivers packets with an unknown destination to logical
2391 # switch ports with "unknown" among their MAC addresses (and port
2392 # security disabled).
2393 for s in 1 2 3; do
2394 bcast=
2395 unknown=
2396 for d in 1 2 3; do
2397 if test $d != $s; then unicast=$d; else unicast=; fi
2398 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2399
2400 # The vtep (vif3) is the only one configured for "unknown"
2401 if test $d != $s && test $d = 3; then
2402 unknown="$unknown $d"
2403 fi
2404 bcast="$bcast $unicast"
2405 done
2406
2407 # Broadcast and multicast.
2408 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2409 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2410
2411 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2412 done
2413
2414 # ARP request should not be responded to by logical switch router
2415 # type arp responder on HV1 and HV2 and should reach directly to
2416 # vif1 and vif2
2417 ip_to_hex() {
2418 printf "%02x%02x%02x%02x" "$@"
2419 }
2420 sha=f00000000003
2421 spa=`ip_to_hex 192 168 1 2`
2422 tpa=`ip_to_hex 192 168 1 1`
2423 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2424 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2425 echo $request >> 1.expected
2426 echo $request >> 2.expected
2427
2428 # dump information with counters
2429 echo "------ OVN dump ------"
2430 ovn-nbctl show
2431 ovn-sbctl show
2432
2433 echo "---------SB dump-----"
2434 ovn-sbctl list datapath_binding
2435 echo "---------------------"
2436 ovn-sbctl list port_binding
2437 echo "---------------------"
2438 ovn-sbctl dump-flows
2439
2440 echo "------ hv1 dump ------"
2441 as hv1 ovs-vsctl show
2442 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2443 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2444
2445 echo "------ hv2 dump ------"
2446 as hv2 ovs-vsctl show
2447 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2448 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2449
2450 echo "------ hv3 dump ------"
2451 as hv3 ovs-vsctl show
2452 # note: hv3 has no logical port bind, thus it should not have br-int
2453 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2454 [ovs-ofctl: br-int is not a bridge or a socket
2455 ])
2456
2457 # Now check the packets actually received against the ones expected.
2458 for i in 1 2 3; do
2459 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2460 done
2461
2462 # Gracefully terminate daemons
2463 OVN_CLEANUP([hv1],[hv2],[vtep])
2464 OVN_CLEANUP_VSWITCH([hv3])
2465
2466 AT_CLEANUP
2467
2468 # Similar test to "hardware GW"
2469 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2470 AT_SKIP_IF([test $HAVE_PYTHON = no])
2471 ovn_start
2472
2473 # Configure the Northbound database
2474 ovn-nbctl ls-add lsw0
2475
2476 ovn-nbctl lsp-add lsw0 lp1
2477 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2478
2479 ovn-nbctl lsp-add lsw0 lp2
2480 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2481
2482 ovn-nbctl lsp-add lsw0 lp-gw
2483 ovn-nbctl lsp-set-type lp-gw l2gateway
2484 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2485 ovn-nbctl lsp-set-addresses lp-gw unknown
2486
2487 net_add n1 # Network to connect hv1, hv2, and gw
2488 net_add n2 # Network to connect gw and hv3
2489
2490 # Create hypervisor hv1 connected to n1
2491 sim_add hv1
2492 as hv1
2493 ovs-vsctl add-br br-phys
2494 ovn_attach n1 br-phys 192.168.0.1
2495 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
2496
2497 # Create hypervisor hv2 connected to n1
2498 sim_add hv2
2499 as hv2
2500 ovs-vsctl add-br br-phys
2501 ovn_attach n1 br-phys 192.168.0.2
2502 ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv2/vif2-tx.pcap options:rxq_pcap=hv2/vif2-rx.pcap ofport-request=1
2503
2504 # Create hypervisor hv_gw connected to n1 and n2
2505 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2506 sim_add hv_gw
2507 as hv_gw
2508 ovs-vsctl add-br br-phys
2509 ovn_attach n1 br-phys 192.168.0.3
2510 ovs-vsctl add-br br-phys2
2511 net_attach n2 br-phys2
2512 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2513
2514 # Add hv3 on the other side of the GW
2515 sim_add hv3
2516 as hv3
2517 ovs-vsctl add-br br-phys
2518 net_attach n2 br-phys
2519 ovs-vsctl add-port br-phys vif3 -- set Interface vif3 options:tx_pcap=hv3/vif3-tx.pcap options:rxq_pcap=hv3/vif3-rx.pcap ofport-request=1
2520
2521
2522 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2523 # packets for ARP resolution (native tunneling doesn't queue packets
2524 # for ARP resolution).
2525 OVN_POPULATE_ARP
2526
2527 # Allow some time for ovn-northd and ovn-controller to catch up.
2528 # XXX This should be more systematic.
2529 sleep 1
2530
2531 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2532 #
2533 # This shell function causes a packet to be received on INPORT. The packet's
2534 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2535 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2536 # more) list the VIFs on which the packet should be received. INPORT and the
2537 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2538 for i in 1 2 3; do
2539 : > $i.expected
2540 done
2541 test_packet() {
2542 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2543 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2544 hv=hv$inport
2545 vif=vif$inport
2546 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2547 for outport; do
2548 echo $packet >> $outport.expected
2549 done
2550 }
2551
2552 # Send packets between all pairs of source and destination ports:
2553 #
2554 # 1. Unicast packets are delivered to exactly one lport (except that packets
2555 # destined to their input ports are dropped).
2556 #
2557 # 2. Broadcast and multicast are delivered to all lports except the input port.
2558 #
2559 # 3. The lswitch delivers packets with an unknown destination to lports with
2560 # "unknown" among their MAC addresses (and port security disabled).
2561 for s in 1 2 3 ; do
2562 bcast=
2563 unknown=
2564 for d in 1 2 3 ; do
2565 if test $d != $s; then unicast=$d; else unicast=; fi
2566 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2567
2568 # The vtep (vif3) is the only one configured for "unknown"
2569 if test $d != $s && test $d = 3; then
2570 unknown="$unknown $d"
2571 fi
2572 bcast="$bcast $unicast"
2573 done
2574
2575 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2576 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2577 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2578 done
2579
2580 echo "------ ovn-nbctl show ------"
2581 ovn-nbctl show
2582 echo "------ ovn-sbctl show ------"
2583 ovn-sbctl show
2584
2585 echo "------ hv1 ------"
2586 as hv1 ovs-vsctl show
2587 echo "------ hv1 br-int ------"
2588 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2589 echo "------ hv1 br-phys ------"
2590 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2591
2592 echo "------ hv2 ------"
2593 as hv2 ovs-vsctl show
2594 echo "------ hv2 br-int ------"
2595 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2596 echo "------ hv2 br-phys ------"
2597 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2598
2599 echo "------ hv_gw ------"
2600 as hv_gw ovs-vsctl show
2601 echo "------ hv_gw br-phys ------"
2602 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2603 echo "------ hv_gw br-phys2 ------"
2604 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2605
2606 echo "------ hv3 ------"
2607 as hv3 ovs-vsctl show
2608 echo "------ hv3 br-phys ------"
2609 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2610
2611 # Now check the packets actually received against the ones expected.
2612 for i in 1 2 3; do
2613 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2614 done
2615 AT_CLEANUP
2616
2617 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2618 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2619 AT_SKIP_IF([test $HAVE_PYTHON = no])
2620 ovn_start
2621
2622 # Logical network:
2623 #
2624 # Three logical switches ls1, ls2, ls3.
2625 # One logical router lr0 connected to ls[123],
2626 # with nine subnets, three per logical switch:
2627 #
2628 # lrp11 on ls1 for subnet 192.168.11.0/24
2629 # lrp12 on ls1 for subnet 192.168.12.0/24
2630 # lrp13 on ls1 for subnet 192.168.13.0/24
2631 # ...
2632 # lrp33 on ls3 for subnet 192.168.33.0/24
2633 #
2634 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2635 # digits are the subnet and the last digit distinguishes the VIF.
2636 for i in 1 2 3; do
2637 ovn-nbctl ls-add ls$i
2638 for j in 1 2 3; do
2639 for k in 1 2 3; do
2640 # Add "unknown" to MAC addresses for lp?11, so packets for
2641 # MAC-IP bindings discovered via ARP later have somewhere to go.
2642 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2643
2644 ovn-nbctl \
2645 -- lsp-add ls$i lp$i$j$k \
2646 -- lsp-set-addresses lp$i$j$k \
2647 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
2648 done
2649 done
2650 done
2651
2652 ovn-nbctl lr-add lr0
2653 for i in 1 2 3; do
2654 for j in 1 2 3; do
2655 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2656 ovn-nbctl \
2657 -- lsp-add ls$i lrp$i$j-attachment \
2658 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2659 options:router-port=lrp$i$j \
2660 addresses='"00:00:00:00:ff:'$i$j'"'
2661 done
2662 done
2663
2664 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2665 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2666
2667 # Physical network:
2668 #
2669 # Three hypervisors hv[123].
2670 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2671 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2672 # lp?3[123] all on hv3.
2673
2674
2675 # Given the name of a logical port, prints the name of the hypervisor
2676 # on which it is located.
2677 vif_to_hv() {
2678 case $1 in dnl (
2679 ?11) echo 1 ;; dnl (
2680 ?12 | ?21 | ?22) echo 2 ;; dnl (
2681 ?13 | ?23 | ?3?) echo 3 ;;
2682 esac
2683 }
2684
2685 # Given the name of a logical port, prints the name of its logical router
2686 # port, e.g. "vif_to_lrp 123" yields 12.
2687 vif_to_lrp() {
2688 echo ${1%?}
2689 }
2690
2691 # Given the name of a logical port, prints the name of its logical
2692 # switch, e.g. "vif_to_ls 123" yields 1.
2693 vif_to_ls() {
2694 echo ${1%??}
2695 }
2696
2697 net_add n1
2698 for i in 1 2 3; do
2699 sim_add hv$i
2700 as hv$i
2701 ovs-vsctl add-br br-phys
2702 ovn_attach n1 br-phys 192.168.0.$i
2703 done
2704 for i in 1 2 3; do
2705 for j in 1 2 3; do
2706 for k in 1 2 3; do
2707 hv=`vif_to_hv $i$j$k`
2708 as hv$hv ovs-vsctl \
2709 -- add-port br-int vif$i$j$k \
2710 -- set Interface vif$i$j$k \
2711 external-ids:iface-id=lp$i$j$k \
2712 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2713 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2714 ofport-request=$i$j$k
2715 done
2716 done
2717 done
2718
2719 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2720 # packets for ARP resolution (native tunneling doesn't queue packets
2721 # for ARP resolution).
2722 OVN_POPULATE_ARP
2723
2724 # Allow some time for ovn-northd and ovn-controller to catch up.
2725 # XXX This should be more systematic.
2726 sleep 1
2727
2728 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2729 #
2730 # This shell function causes a packet to be received on INPORT. The packet's
2731 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2732 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2733 # more) list the VIFs on which the packet should be received. INPORT and the
2734 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2735 for i in 1 2 3; do
2736 for j in 1 2 3; do
2737 for k in 1 2 3; do
2738 : > $i$j$k.expected
2739 done
2740 done
2741 done
2742 test_ip() {
2743 # This packet has bad checksums but logical L3 routing doesn't check.
2744 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2745 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2746 shift; shift; shift; shift; shift
2747 hv=hv`vif_to_hv $inport`
2748 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2749 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2750 in_ls=`vif_to_ls $inport`
2751 in_lrp=`vif_to_lrp $inport`
2752 for outport; do
2753 out_ls=`vif_to_ls $outport`
2754 if test $in_ls = $out_ls; then
2755 # Ports on the same logical switch receive exactly the same packet.
2756 echo $packet
2757 else
2758 # Routing decrements TTL and updates source and dest MAC
2759 # (and checksum).
2760 out_lrp=`vif_to_lrp $outport`
2761 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2762 fi >> $outport.expected
2763 done
2764 }
2765
2766 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2767 #
2768 # Causes a packet to be received on INPORT. The packet is an ARP
2769 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2770 # it should be the hardware address of the target to expect to receive in an
2771 # ARP reply; otherwise no reply is expected.
2772 #
2773 # INPORT is an logical switch port number, e.g. 11 for vif11.
2774 # SHA and REPLY_HA are each 12 hex digits.
2775 # SPA and TPA are each 8 hex digits.
2776 test_arp() {
2777 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2778 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2779 hv=hv`vif_to_hv $inport`
2780 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2781 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2782
2783 # Expect to receive the broadcast ARP on the other logical switch ports if
2784 # IP address is not configured to the switch patch port.
2785 local i=`vif_to_ls $inport`
2786 local j k
2787 for j in 1 2 3; do
2788 for k in 1 2 3; do
2789 # 192.168.33.254 is configured to the switch patch port for lrp33,
2790 # so no ARP flooding expected for it.
2791 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2792 echo $request >> $i$j$k.expected
2793 fi
2794 done
2795 done
2796
2797 # Expect to receive the reply, if any.
2798 if test X$reply_ha != X; then
2799 lrp=`vif_to_lrp $inport`
2800 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2801 echo $reply >> $inport.expected
2802 fi
2803 }
2804
2805 as hv1 ovs-vsctl --columns=name,ofport list interface
2806 as hv1 ovn-sbctl list port_binding
2807 as hv1 ovn-sbctl list datapath_binding
2808 as hv1 ovn-sbctl dump-flows
2809 as hv1 ovs-ofctl dump-flows br-int
2810
2811 # Send IP packets between all pairs of source and destination ports:
2812 #
2813 # 1. Unicast IP packets are delivered to exactly one logical switch port
2814 # (except that packets destined to their input ports are dropped).
2815 #
2816 # 2. Broadcast IP packets are delivered to all logical switch ports
2817 # except the input port.
2818 ip_to_hex() {
2819 printf "%02x%02x%02x%02x" "$@"
2820 }
2821 for is in 1 2 3; do
2822 for js in 1 2 3; do
2823 for ks in 1 2 3; do
2824 bcast=
2825 s=$is$js$ks
2826 smac=f00000000$s
2827 sip=`ip_to_hex 192 168 $is$js $ks`
2828 for id in 1 2 3; do
2829 for jd in 1 2 3; do
2830 for kd in 1 2 3; do
2831 d=$id$jd$kd
2832 dip=`ip_to_hex 192 168 $id$jd $kd`
2833 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2834 if test $d != $s; then unicast=$d; else unicast=; fi
2835
2836 test_ip $s $smac $dmac $sip $dip $unicast #1
2837
2838 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2839 done
2840 done
2841 done
2842 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2843 done
2844 done
2845 done
2846
2847 : > mac_bindings.expected
2848
2849 # 3. Send an IP packet from every logical port to every other subnet,
2850 # to an IP address that does not have a static IP-MAC binding.
2851 # This should generate a broadcast ARP request for the destination
2852 # IP address in the destination subnet.
2853 # Moreover generate an ARP reply for each of the IP addresses ARPed
2854 for is in 1 2 3; do
2855 for js in 1 2 3; do
2856 for ks in 1 2 3; do
2857 s=$is$js$ks
2858 smac=f00000000$s
2859 sip=`ip_to_hex 192 168 $is$js $ks`
2860 for id in 1 2 3; do
2861 for jd in 1 2 3; do
2862 if test $is$js = $id$jd; then
2863 continue
2864 fi
2865
2866 # Send the packet.
2867 dmac=00000000ff$is$js
2868 # Calculate a 4th octet for the destination that is
2869 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2870 # that have static MAC bindings, and fits in the range
2871 # 0-255.
2872 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2873 dip=`ip_to_hex 192 168 $id$jd $o4`
2874 test_ip $s $smac $dmac $sip $dip
2875
2876 # Every LP on the destination subnet's lswitch should
2877 # receive the ARP request.
2878 lrmac=00000000ff$id$jd
2879 lrip=`ip_to_hex 192 168 $id$jd 254`
2880 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2881 for jd2 in 1 2 3; do
2882 for kd in 1 2 3; do
2883 echo $arp >> $id$jd2$kd.expected
2884 done
2885 done
2886
2887 hmac=8000000000$o4
2888 rmac=00000000ff$id$jd
2889 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
2890
2891 host_mac=8000000000$o4
2892 lrmac=00000000ff$id$jd
2893
2894 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2895
2896 hv=hv`vif_to_hv ${id}${jd}1`
2897 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2898
2899 host_ip_pretty=192.168.$id$jd.$o4
2900 host_mac_pretty=80:00:00:00:00:$o4
2901 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2902 done
2903 done
2904 done
2905 done
2906 done
2907
2908 # Test router replies to ARP requests from all source ports:
2909 #
2910 # 4. Router replies to query for its MAC address from port's own IP address.
2911 #
2912 # 5. Router replies to query for its MAC address from any random IP address
2913 # in its subnet.
2914 #
2915 # 6. No reply to query for IP address other than router IP.
2916 #
2917 # 7. No reply to query from another subnet.
2918 for i in 1 2 3; do
2919 for j in 1 2 3; do
2920 for k in 1 2 3; do
2921 smac=f00000000$i$j$k # Source MAC
2922 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2923 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2924 rmac=00000000ff$i$j # Router MAC
2925 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2926 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2927
2928 test_arp $i$j$k $smac $sip $rip $rmac #4
2929 test_arp $i$j$k $smac $otherip $rip $rmac #5
2930 test_arp $i$j$k $smac $sip $otherip #6
2931
2932 # When rip is 192.168.33.254, ARP request from externalip won't be
2933 # filtered, because 192.168.33.254 is configured to switch peer port
2934 # for lrp33.
2935 lrp33_rsp=
2936 if test $i = 3 && test $j = 3; then
2937 lrp33_rsp=$rmac
2938 fi
2939 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2940
2941 # MAC binding should be learned from ARP request.
2942 host_mac_pretty=f0:00:00:00:0$i:$j$k
2943
2944 host_ip_pretty=192.168.$i$j.$k
2945 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2946
2947 # mac_binding is learned and overwritten so only the last one remains.
2948 if test $k = 3; then
2949 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2950 # configured to switch peer port for lrp33.
2951 if test $i != 3 || test $j != 3; then
2952 host_ip_pretty=192.168.$i$j.55
2953 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2954 fi
2955 fi
2956
2957 done
2958 done
2959 done
2960
2961
2962 # Allow some time for packet forwarding.
2963 # XXX This can be improved.
2964 sleep 1
2965
2966 # 8. Send an IP packet from every logical port to every other subnet. These
2967 # are the same packets already sent as #3, but now the destinations' IP-MAC
2968 # bindings have been discovered via ARP, so instead of provoking an ARP
2969 # request, these packets now get routed to their destinations (which don't
2970 # have static MAC bindings, so they go to the port we've designated as
2971 # accepting "unknown" MACs.)
2972 for is in 1 2 3; do
2973 for js in 1 2 3; do
2974 for ks in 1 2 3; do
2975 s=$is$js$ks
2976 smac=f00000000$s
2977 sip=`ip_to_hex 192 168 $is$js $ks`
2978 for id in 1 2 3; do
2979 for jd in 1 2 3; do
2980 if test $is$js = $id$jd; then
2981 continue
2982 fi
2983
2984 # Send the packet.
2985 dmac=00000000ff$is$js
2986 # Calculate a 4th octet for the destination that is
2987 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2988 # that have static MAC bindings, and fits in the range
2989 # 0-255.
2990 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2991 dip=`ip_to_hex 192 168 $id$jd $o4`
2992 test_ip $s $smac $dmac $sip $dip
2993
2994 # Expect the packet egress.
2995 host_mac=8000000000$o4
2996 outport=${id}11
2997 out_lrp=$id$jd
2998 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2999 done
3000 done
3001 done
3002 done
3003 done
3004
3005 ovn-sbctl -f csv -d bare --no-heading \
3006 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
3007
3008 # Now check the packets actually received against the ones expected.
3009 for i in 1 2 3; do
3010 for j in 1 2 3; do
3011 for k in 1 2 3; do
3012 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
3013 [$i$j$k.expected])
3014 done
3015 done
3016 done
3017
3018 # Check the MAC bindings against those expected.
3019 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
3020 ])
3021
3022 # Gracefully terminate daemons
3023 OVN_CLEANUP([hv1], [hv2], [hv3])
3024
3025 AT_CLEANUP
3026
3027 AT_SETUP([ovn -- IP relocation using GARP request])
3028 AT_SKIP_IF([test $HAVE_PYTHON = no])
3029 ovn_start
3030
3031 # Logical network:
3032 #
3033 # Two logical switches ls1, ls2.
3034 # One logical router lr0 connected to ls[12],
3035 # with 2 subnets, 1 per logical switch:
3036 #
3037 # lrp1 on ls1 for subnet 192.168.1.1/24
3038 # lrp2 on ls2 for subnet 192.168.2.1/24
3039 #
3040 # 4 VIFs, 2 per LS lp[12][12], first digit being LS.
3041 # VIFs' fixed IP addresses are 192.168.[12].1[12].
3042 #
3043 # There is a secondary IP 192.168.1.100 that is unknown in NB and learned
3044 # through ARP only, and it can move between lp11 and lp12.
3045 #
3046 ovn-nbctl lr-add lr0
3047 for i in 1 2 ; do
3048 ovn-nbctl ls-add ls$i
3049 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
3050 ovn-nbctl \
3051 -- lsp-add ls$i lrp$i-attachment \
3052 -- set Logical_Switch_Port lrp$i-attachment type=router \
3053 options:router-port=lrp$i \
3054 addresses=router
3055 for j in 1 2; do
3056 ovn-nbctl \
3057 -- lsp-add ls$i lp$i$j \
3058 -- lsp-set-addresses lp$i$j \
3059 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
3060 done
3061 done
3062
3063 # Physical network:
3064 # 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
3065
3066 # Given the name of a logical port, prints the name of the hypervisor
3067 # on which it is located, e.g. "vif_to_hv 12" yields 2.
3068 vif_to_hv() {
3069 echo ${1#?}
3070 }
3071
3072 # Given the name of a logical port, prints the name of its logical router
3073 # port, e.g. "vif_to_lrp 12" yields 1.
3074 vif_to_lrp() {
3075 echo ${1%?}
3076 }
3077
3078 # Given the name of a logical port, prints the name of its logical
3079 # switch, e.g. "vif_to_ls 12" yields 1.
3080 vif_to_ls() {
3081 echo ${1%?}
3082 }
3083
3084 net_add n1
3085 for i in 1 2; do
3086 sim_add hv$i
3087 as hv$i
3088 ovs-vsctl add-br br-phys
3089 ovn_attach n1 br-phys 192.168.0.$i
3090 done
3091 for i in 1 2; do
3092 for j in 1 2; do
3093 hv=`vif_to_hv $i$j`
3094 as hv$hv ovs-vsctl \
3095 -- add-port br-int vif$i$j \
3096 -- set Interface vif$i$j \
3097 external-ids:iface-id=lp$i$j \
3098 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
3099 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
3100 ofport-request=$i$j
3101 done
3102 done
3103
3104 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3105 # packets for ARP resolution (native tunneling doesn't queue packets
3106 # for ARP resolution).
3107 OVN_POPULATE_ARP
3108
3109 # Allow some time for ovn-northd and ovn-controller to catch up.
3110 # XXX This should be more systematic.
3111 sleep 1
3112
3113 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3114 #
3115 # This shell function causes a packet to be received on INPORT. The packet's
3116 # content has Ethernet destination DST and source SRC (each exactly 12 hex
3117 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
3118 # more) list the VIFs on which the packet should be received. INPORT and the
3119 # OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
3120 for i in 1 2; do
3121 for j in 1 2; do
3122 : > $i$j.expected
3123 done
3124 done
3125 test_ip() {
3126 # This packet has bad checksums but logical L3 routing doesn't check.
3127 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3128 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3129 shift; shift; shift; shift; shift
3130 hv=hv`vif_to_hv $inport`
3131 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3132 in_ls=`vif_to_ls $inport`
3133 in_lrp=`vif_to_lrp $inport`
3134 for outport; do
3135 out_ls=`vif_to_ls $outport`
3136 if test $in_ls = $out_ls; then
3137 # Ports on the same logical switch receive exactly the same packet.
3138 echo $packet
3139 else
3140 # Routing decrements TTL and updates source and dest MAC
3141 # (and checksum).
3142 out_lrp=`vif_to_lrp $outport`
3143 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
3144 fi >> $outport.expected
3145 done
3146 }
3147
3148 # test_arp INPORT SHA SPA TPA [REPLY_HA]
3149 #
3150 # Causes a packet to be received on INPORT. The packet is an ARP
3151 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3152 # it should be the hardware address of the target to expect to receive in an
3153 # ARP reply; otherwise no reply is expected.
3154 #
3155 # INPORT is an logical switch port number, e.g. 11 for vif11.
3156 # SHA and REPLY_HA are each 12 hex digits.
3157 # SPA and TPA are each 8 hex digits.
3158 test_arp() {
3159 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
3160 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3161 hv=hv`vif_to_hv $inport`
3162 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3163
3164 # Expect to receive the broadcast ARP on the other logical switch ports if
3165 # IP address is not configured to the switch patch port.
3166 local i=`vif_to_ls $inport`
3167 local j
3168 for j in 1 2; do
3169 if test $i$j != $inport; then
3170 echo $request >> $i$j$k.expected
3171 fi
3172 done
3173
3174 # Expect to receive the reply, if any.
3175 if test X$reply_ha != X; then
3176 lrp=`vif_to_lrp $inport`
3177 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3178 echo $reply >> $inport.expected
3179 fi
3180 }
3181
3182 ip_to_hex() {
3183 printf "%02x%02x%02x%02x" "$@"
3184 }
3185
3186 # lp11 send GARP request to announce ownership of 192.168.1.100.
3187
3188 sha=f00000000011
3189 spa=`ip_to_hex 192 168 1 100`
3190 tpa=$spa
3191 test_arp 11 $sha $spa $tpa
3192 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
3193 ovn-nbctl --wait=hv sync
3194
3195 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
3196
3197 smac=f00000000021
3198 dmac=00000000ff02
3199 sip=`ip_to_hex 192 168 2 11`
3200 dip=`ip_to_hex 192 168 1 100`
3201 test_ip 21 $smac $dmac $sip $dip 11
3202
3203 # lp12 send GARP request to announce ownership of 192.168.1.100.
3204
3205 sha=f00000000012
3206 test_arp 12 $sha $spa $tpa
3207 OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
3208 ovn-nbctl --wait=hv sync
3209 # give to the hv the time to send queued ip packets
3210 sleep 1
3211
3212 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
3213
3214 test_ip 21 $smac $dmac $sip $dip 12
3215
3216 # Now check the packets actually received against the ones expected.
3217 for i in 1 2; do
3218 for j in 1 2; do
3219 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3220 [$i$j.expected])
3221 done
3222 done
3223
3224 # Gracefully terminate daemons
3225 OVN_CLEANUP([hv1], [hv2])
3226
3227 AT_CLEANUP
3228
3229 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3230 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
3231 AT_SKIP_IF([test $HAVE_PYTHON = no])
3232 ovn_start
3233
3234 # Create hypervisors hv[123].
3235 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3236 # Add all of the vifs to a single logical switch lsw0.
3237 # Turn off port security on vifs vif[123]1
3238 # Turn on l2 port security on vifs vif[123]2
3239 # Turn of l2 and l3 port security on vifs vif[123]3
3240 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
3241 ovn-nbctl ls-add lsw0
3242 net_add n1
3243 for i in 1 2 3; do
3244 sim_add hv$i
3245 as hv$i
3246 ovs-vsctl add-br br-phys
3247 ovn_attach n1 br-phys 192.168.0.$i
3248
3249 for j in 1 2 3; do
3250 ovs-vsctl add-port br-int vif$i$j -- set Interface vif$i$j external-ids:iface-id=lp$i$j options:tx_pcap=hv$i/vif$i$j-tx.pcap options:rxq_pcap=hv$i/vif$i$j-rx.pcap ofport-request=$i$j
3251 ovn-nbctl lsp-add lsw0 lp$i$j
3252 if test $j = 1; then
3253 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
3254 elif test $j = 2; then
3255 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3256 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
3257 else
3258 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
3259 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3260 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3261 fi
3262 done
3263 done
3264
3265 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3266 # packets for ARP resolution (native tunneling doesn't queue packets
3267 # for ARP resolution).
3268 OVN_POPULATE_ARP
3269
3270 # Allow some time for ovn-northd and ovn-controller to catch up.
3271 # XXX This should be more systematic.
3272 sleep 1
3273
3274 # Given the name of a logical port, prints the name of the hypervisor
3275 # on which it is located.
3276 vif_to_hv() {
3277 echo hv${1%?}
3278 }
3279
3280 for i in 1 2 3; do
3281 for j in 1 2 3; do
3282 : > $i$j.expected
3283 done
3284 done
3285
3286 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3287 #
3288 # This shell function causes an ip packet to be received on INPORT.
3289 # The packet's content has Ethernet destination DST and source SRC
3290 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3291 # The OUTPORTs (zero or more) list the VIFs on which the packet should
3292 # be received. INPORT and the OUTPORTs are specified as logical switch
3293 # port numbers, e.g. 11 for vif11.
3294 test_ip() {
3295 # This packet has bad checksums but logical L3 routing doesn't check.
3296 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3297 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3298 shift; shift; shift; shift; shift
3299 hv=`vif_to_hv $inport`
3300 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3301 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3302 for outport; do
3303 echo $packet >> $outport.expected
3304 done
3305 }
3306
3307 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3308 #
3309 # Causes a packet to be received on INPORT. The packet is an ARP
3310 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3311 # it should be the hardware address of the target to expect to receive in an
3312 # ARP reply; otherwise no reply is expected.
3313 #
3314 # INPORT is an logical switch port number, e.g. 11 for vif11.
3315 # SHA and REPLY_HA are each 12 hex digits.
3316 # SPA and TPA are each 8 hex digits.
3317 test_arp() {
3318 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3319 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3320 hv=`vif_to_hv $inport`
3321 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3322 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3323 if test $drop != 1; then
3324 if test X$reply_ha = X; then
3325 # Expect to receive the broadcast ARP on the other logical switch ports
3326 # if no reply is expected.
3327 local i j
3328 for i in 1 2 3; do
3329 for j in 1 2 3; do
3330 if test $i$j != $inport; then
3331 echo $request >> $i$j.expected
3332 fi
3333 done
3334 done
3335 else
3336 # Expect to receive the reply, if any.
3337 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3338 echo $reply >> $inport.expected
3339 fi
3340 fi
3341 }
3342
3343 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3344 # This function is similar to test_ip() except that it sends
3345 # ipv6 packet
3346 test_ipv6() {
3347 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3348 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3349 shift; shift; shift; shift; shift
3350 hv=`vif_to_hv $inport`
3351 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3352 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3353 for outport; do
3354 echo $packet >> $outport.expected
3355 done
3356 }
3357
3358 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3359 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
3360 # of the test packet
3361 test_icmpv6() {
3362 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3363 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3364 shift; shift; shift; shift; shift; shift
3365 hv=`vif_to_hv $inport`
3366 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3367 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3368 for outport; do
3369 echo $packet >> $outport.expected
3370 done
3371 }
3372
3373 ip_to_hex() {
3374 printf "%02x%02x%02x%02x" "$@"
3375 }
3376
3377 # no port security
3378 sip=`ip_to_hex 192 168 0 12`
3379 tip=`ip_to_hex 192 168 0 13`
3380 # the arp packet should be allowed even if lp[123]1 is
3381 # not configured with mac f00000000023 and ip 192.168.0.12
3382 for i in 1 2 3; do
3383 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3384 for j in 1 2 3; do
3385 if test $i != $j; then
3386 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3387 fi
3388 done
3389 done
3390
3391 # l2 port security
3392 sip=`ip_to_hex 192 168 0 12`
3393 tip=`ip_to_hex 192 168 0 13`
3394
3395 # arp packet should be allowed since lp22 is configured with
3396 # mac f00000000022
3397 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3398
3399 # arp packet should not be allowed since lp32 is not configured with
3400 # mac f00000000021
3401 test_arp 32 f00000000021 f00000000021 $sip $tip 1
3402
3403 # arp packet with sha set to f00000000021 should not be allowed
3404 # for lp12
3405 test_arp 12 f00000000012 f00000000021 $sip $tip 1
3406
3407 # ip packets should be allowed and received since lp[123]2 do not
3408 # have l3 port security
3409 sip=`ip_to_hex 192 168 0 55`
3410 tip=`ip_to_hex 192 168 0 66`
3411 for i in 1 2 3; do
3412 for j in 1 2 3; do
3413 if test $i != $j; then
3414 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3415 fi
3416 done
3417 done
3418
3419 # ipv6 packets should be received by lp[123]2
3420 # lp[123]1 can send ipv6 traffic as there is no port security
3421 sip=fe800000000000000000000000000000
3422 tip=ff020000000000000000000000000000
3423
3424 for i in 1 2 3; do
3425 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3426 done
3427
3428
3429 # l2 and l3 port security
3430 sip=`ip_to_hex 192 168 0 13`
3431 tip=`ip_to_hex 192 168 0 22`
3432 # arp packet should be allowed since lp13 is configured with
3433 # f00000000013 and 192.168.0.13
3434 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3435
3436 # the arp packet should be dropped because lp23 is not configured
3437 # with mac f00000000022
3438 sip=`ip_to_hex 192 168 0 13`
3439 tip=`ip_to_hex 192 168 0 22`
3440 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3441
3442 # the arp packet should be dropped because lp33 is not configured
3443 # with ip 192.168.0.55
3444 spa=`ip_to_hex 192 168 0 55`
3445 tpa=`ip_to_hex 192 168 0 22`
3446 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3447
3448 # ip packets should not be received by lp[123]3 since
3449 # l3 port security is enabled
3450 sip=`ip_to_hex 192 168 0 55`
3451 tip=`ip_to_hex 192 168 0 66`
3452 for i in 1 2 3; do
3453 for j in 1 2 3; do
3454 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3455 done
3456 done
3457
3458 # ipv6 packets should be dropped for lp[123]3 since
3459 # it is configured with only ipv4 address
3460 sip=fe800000000000000000000000000000
3461 tip=ff020000000000000000000000000000
3462
3463 for i in 1 2 3; do
3464 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3465 done
3466
3467 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3468 # lp[123]1 can send ipv6 traffic as there is no port security
3469 for i in 1 2 3; do
3470 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3471 done
3472
3473 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3474 # fe80::ea2a:eaff:fe28:0012
3475
3476 # ipv4 packet should be dropped for lp13 with mac f0000000113
3477 sip=`ip_to_hex 192 168 0 13`
3478 tip=`ip_to_hex 192 168 0 23`
3479 test_ip 13 f00000000113 f00000000023 $sip $tip
3480
3481 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3482 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3483 # lp11 can send ipv6 traffic as there is no port security
3484 sip=ee800000000000000000000000000000
3485 for i in 1 2 3; do
3486 tip=fe80000000000000ea2aeafffe2800${i}3
3487 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3488 done
3489
3490
3491 # ipv6 packet should not be received by lp33 with mac f0000000333
3492 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3493 # configured with fe80::ea2a:eaff:fe28:0033
3494 # lp11 can send ipv6 traffic as there is no port security
3495
3496 sip=ee800000000000000000000000000000
3497 tip=fe80000000000000ea2aeafffe280023
3498 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3499
3500 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3501 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3502 # and should be dropped for any other ip6.src
3503 # lp21 can receive ipv6 traffic as there is no port security
3504
3505 tip=ee800000000000000000000000000000
3506 for i in 1 2 3; do
3507 sip=fe80000000000000ea2aeafffe2800${i}3
3508 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3509
3510 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3511 sip=00000000000000000000000000000000
3512 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3513 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3514 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3515 # Traffic to non-multicast traffic should be dropped
3516 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3517 # Traffic of other ICMPv6 types should be dropped
3518 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3519
3520 # should be dropped
3521 sip=ae80000000000000ea2aeafffe2800aa
3522 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3523 done
3524
3525 # configure lsp13 to send and received IPv4 packets with an address range
3526 ovn-nbctl lsp-set-port-security lp13 "f0:00:00:00:00:13 192.168.0.13 20.0.0.4/24 10.0.0.0/24"
3527
3528 sleep 2
3529
3530 sip=`ip_to_hex 10 0 0 13`
3531 tip=`ip_to_hex 192 168 0 22`
3532 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3533 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3534
3535 sip=`ip_to_hex 10 0 0 14`
3536 tip=`ip_to_hex 192 168 0 23`
3537 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3538 # with dst ip 192.168.0.23 should be allowed
3539 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3540
3541 sip=`ip_to_hex 192 168 0 33`
3542 tip=`ip_to_hex 10 0 0 15`
3543 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3544 # with dst ip 10.0.0.15 should be received by lsp13
3545 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3546
3547 sip=`ip_to_hex 192 168 0 33`
3548 tip=`ip_to_hex 20 0 0 4`
3549 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3550 # with dst ip 20.0.0.4 should be received by lsp13
3551 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3552
3553 sip=`ip_to_hex 192 168 0 33`
3554 tip=`ip_to_hex 20 0 0 5`
3555 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3556 # with dst ip 20.0.0.5 should not be received by lsp13
3557 test_ip 33 f00000000033 f00000000013 $sip $tip
3558
3559 sip=`ip_to_hex 192 168 0 33`
3560 tip=`ip_to_hex 20 0 0 255`
3561 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3562 # with dst ip 20.0.0.255 should be received by lsp13
3563 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3564
3565 sip=`ip_to_hex 192 168 0 33`
3566 tip=`ip_to_hex 192 168 0 255`
3567 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3568 # with dst ip 192.168.0.255 should not be received by lsp13
3569 test_ip 33 f00000000033 f00000000013 $sip $tip
3570
3571 sip=`ip_to_hex 192 168 0 33`
3572 tip=`ip_to_hex 224 0 0 4`
3573 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3574 # with dst ip 224.0.0.4 should be received by lsp13
3575 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3576
3577 #dump information including flow counters
3578 ovn-nbctl show
3579 ovn-sbctl dump-flows -- list multicast_group
3580
3581 echo "------ hv1 dump ------"
3582 as hv1 ovs-vsctl show
3583 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3584 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3585
3586 echo "------ hv2 dump ------"
3587 as hv2 ovs-vsctl show
3588 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3589 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3590
3591 echo "------ hv3 dump ------"
3592 as hv3 ovs-vsctl show
3593 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3594 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3595
3596 # Now check the packets actually received against the ones expected.
3597 for i in 1 2 3; do
3598 for j in 1 2 3; do
3599 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3600 done
3601 done
3602
3603 OVN_CLEANUP([hv1],[hv2],[hv3])
3604
3605 AT_CLEANUP
3606
3607 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3608 AT_SKIP_IF([test $HAVE_PYTHON = no])
3609 ovn_start
3610
3611 # Logical network:
3612 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3613 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3614 # R2 has ls2 (172.16.1.0/24) connected to it.
3615
3616 ls1_lp1_mac="f0:00:00:01:02:03"
3617 rp_ls1_mac="00:00:00:01:02:03"
3618 rp_ls2_mac="00:00:00:01:02:04"
3619 ls2_lp1_mac="f0:00:00:01:02:04"
3620
3621 ls1_lp1_ip="192.168.1.2"
3622 ls2_lp1_ip="172.16.1.2"
3623
3624 ovn-nbctl lr-add R1
3625 ovn-nbctl lr-add R2
3626
3627 ovn-nbctl ls-add ls1
3628 ovn-nbctl ls-add ls2
3629
3630 # Connect ls1 to R1
3631 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3632
3633 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3634 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3635
3636 # Connect ls2 to R2
3637 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3638
3639 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3640 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3641
3642 # Connect R1 to R2
3643 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3644 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3645
3646 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3647 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3648
3649 # Create logical port ls1-lp1 in ls1
3650 ovn-nbctl lsp-add ls1 ls1-lp1 \
3651 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3652
3653 # Create logical port ls2-lp1 in ls2
3654 ovn-nbctl lsp-add ls2 ls2-lp1 \
3655 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3656
3657 # Create two hypervisor and create OVS ports corresponding to logical ports.
3658 net_add n1
3659
3660 sim_add hv1
3661 as hv1
3662 ovs-vsctl add-br br-phys
3663 ovn_attach n1 br-phys 192.168.0.1
3664 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3665 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3666 options:tx_pcap=hv1/vif1-tx.pcap \
3667 options:rxq_pcap=hv1/vif1-rx.pcap \
3668 ofport-request=1
3669
3670 sim_add hv2
3671 as hv2
3672 ovs-vsctl add-br br-phys
3673 ovn_attach n1 br-phys 192.168.0.2
3674 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3675 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3676 options:tx_pcap=hv2/vif1-tx.pcap \
3677 options:rxq_pcap=hv2/vif1-rx.pcap \
3678 ofport-request=1
3679
3680
3681 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3682 # packets for ARP resolution (native tunneling doesn't queue packets
3683 # for ARP resolution).
3684 OVN_POPULATE_ARP
3685
3686 # Allow some time for ovn-northd and ovn-controller to catch up.
3687 # XXX This should be more systematic.
3688 sleep 1
3689
3690 # Packet to send.
3691 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3692 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3693 udp && udp.src==53 && udp.dst==4369"
3694 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3695
3696
3697 echo "---------NB dump-----"
3698 ovn-nbctl show
3699 echo "---------------------"
3700 ovn-nbctl list logical_router
3701 echo "---------------------"
3702 ovn-nbctl list logical_router_port
3703 echo "---------------------"
3704
3705 echo "---------SB dump-----"
3706 ovn-sbctl list datapath_binding
3707 echo "---------------------"
3708 ovn-sbctl list port_binding
3709 echo "---------------------"
3710
3711 echo "------ hv1 dump ----------"
3712 as hv1 ovs-ofctl show br-int
3713 as hv1 ovs-ofctl dump-flows br-int
3714 echo "------ hv2 dump ----------"
3715 as hv2 ovs-ofctl show br-int
3716 as hv2 ovs-ofctl dump-flows br-int
3717
3718 # Packet to Expect
3719 # The TTL should be decremented by 2.
3720 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3721 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3722 udp && udp.src==53 && udp.dst==4369"
3723 echo $packet | ovstest test-ovn expr-to-packets > expected
3724
3725 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3726
3727 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3728 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3729 ])
3730
3731 # Disable the ls2-lp1 port.
3732 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3733
3734 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3735 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3736 ])
3737
3738 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3739 # Packet to send.
3740 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3741 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3742 udp && udp.src==53 && udp.dst==4369"
3743
3744 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3745 # The 2nd packet sent shound not be received.
3746 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3747
3748 OVN_CLEANUP([hv1],[hv2])
3749
3750 AT_CLEANUP
3751
3752
3753 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3754 AT_KEYWORDS([router-admin-state])
3755 AT_SKIP_IF([test $HAVE_PYTHON = no])
3756 ovn_start
3757
3758 # Logical network:
3759 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3760 # and 172.16.1.0/24) connected to it.
3761
3762 ovn-nbctl lr-add R1
3763
3764 ovn-nbctl ls-add ls1
3765
3766 # Connect ls1 to R1
3767 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3768 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3769 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3770
3771 # Create logical port ls1-lp1 in ls1
3772 ovn-nbctl lsp-add ls1 ls1-lp1 \
3773 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3774
3775 # Create logical port ls1-lp2 in ls1
3776 ovn-nbctl lsp-add ls1 ls1-lp2 \
3777 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3778
3779 # Create one hypervisor and create OVS ports corresponding to logical ports.
3780 net_add n1
3781
3782 sim_add hv1
3783 as hv1
3784 ovs-vsctl add-br br-phys
3785 ovn_attach n1 br-phys 192.168.0.1
3786 ovs-vsctl -- add-port br-int vif1 -- \
3787 set interface vif1 external-ids:iface-id=ls1-lp1 \
3788 options:tx_pcap=hv1/vif1-tx.pcap \
3789 options:rxq_pcap=hv1/vif1-rx.pcap \
3790 ofport-request=1
3791
3792 ovs-vsctl -- add-port br-int vif2 -- \
3793 set interface vif2 external-ids:iface-id=ls1-lp2 \
3794 options:tx_pcap=hv1/vif2-tx.pcap \
3795 options:rxq_pcap=hv1/vif2-rx.pcap \
3796 ofport-request=1
3797
3798
3799 # Allow some time for ovn-northd and ovn-controller to catch up.
3800 # XXX This should be more systematic.
3801 sleep 1
3802
3803 # Send ip packets between the two ports.
3804 ip_to_hex() {
3805 printf "%02x%02x%02x%02x" "$@"
3806 }
3807
3808 # Packet to send.
3809 src_mac="f00000010203"
3810 dst_mac="000000010203"
3811 src_ip=`ip_to_hex 192 168 1 2`
3812 dst_ip=`ip_to_hex 172 16 1 2`
3813 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3814 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3815
3816
3817 echo "---------NB dump-----"
3818 ovn-nbctl show
3819 echo "---------------------"
3820 ovn-nbctl list logical_router
3821 echo "---------------------"
3822 ovn-nbctl list logical_router_port
3823 echo "---------------------"
3824
3825 echo "---------SB dump-----"
3826 ovn-sbctl list datapath_binding
3827 echo "---------------------"
3828 ovn-sbctl list logical_flow
3829 echo "---------------------"
3830
3831 echo "------ hv1 dump ----------"
3832 as hv1 ovs-ofctl dump-flows br-int
3833
3834
3835 #Disable router R1
3836 ovn-nbctl set Logical_Router R1 enabled=false
3837
3838 # Allow some time for ovn-northd and ovn-controller to catch up.
3839 # XXX This should be more systematic.
3840 sleep 1
3841
3842 echo "---------SB dump-----"
3843 ovn-sbctl list datapath_binding
3844 echo "---------------------"
3845 ovn-sbctl list logical_flow
3846 echo "---------------------"
3847
3848 echo "------ hv1 dump ----------"
3849 as hv1 ovs-ofctl dump-flows br-int
3850
3851 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3852
3853 # Packet to Expect
3854 expect_src_mac="000000010203"
3855 expect_dst_mac="f00000010204"
3856 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3857
3858 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3859
3860 OVN_CLEANUP([hv1])
3861
3862 AT_CLEANUP
3863
3864
3865 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3866 AT_KEYWORDS([router-admin-state])
3867 AT_SKIP_IF([test $HAVE_PYTHON = no])
3868 ovn_start
3869
3870 # Logical network:
3871 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3872 # and has switch ls2 (172.16.1.0/24) connected to it.
3873
3874 ovn-nbctl lr-add R1
3875
3876 ovn-nbctl ls-add ls1
3877 ovn-nbctl ls-add ls2
3878
3879 # Connect ls1 to R1
3880 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3881 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3882 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3883
3884 # Connect ls2 to R1
3885 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3886 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3887 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3888
3889 # Create logical port ls1-lp1 in ls1
3890 ovn-nbctl lsp-add ls1 ls1-lp1 \
3891 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3892
3893 # Create logical port ls2-lp1 in ls2
3894 ovn-nbctl lsp-add ls2 ls2-lp1 \
3895 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3896
3897 # Create one hypervisor and create OVS ports corresponding to logical ports.
3898 net_add n1
3899
3900 sim_add hv1
3901 as hv1
3902 ovs-vsctl add-br br-phys
3903 ovn_attach n1 br-phys 192.168.0.1
3904 ovs-vsctl -- add-port br-int vif1 -- \
3905 set interface vif1 external-ids:iface-id=ls1-lp1 \
3906 options:tx_pcap=hv1/vif1-tx.pcap \
3907 options:rxq_pcap=hv1/vif1-rx.pcap \
3908 ofport-request=1
3909
3910 ovs-vsctl -- add-port br-int vif2 -- \
3911 set interface vif2 external-ids:iface-id=ls2-lp1 \
3912 options:tx_pcap=hv1/vif2-tx.pcap \
3913 options:rxq_pcap=hv1/vif2-rx.pcap \
3914 ofport-request=1
3915
3916
3917 # Allow some time for ovn-northd and ovn-controller to catch up.
3918 # XXX This should be more systematic.
3919 sleep 1
3920
3921 # Send ip packets between the two ports.
3922 ip_to_hex() {
3923 printf "%02x%02x%02x%02x" "$@"
3924 }
3925
3926 # Packet to send.
3927 src_mac="f00000010203"
3928 dst_mac="000000010203"
3929 src_ip=`ip_to_hex 192 168 1 2`
3930 dst_ip=`ip_to_hex 172 16 1 2`
3931 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3932 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3933
3934
3935 echo "---------NB dump-----"
3936 ovn-nbctl show
3937 echo "---------------------"
3938 ovn-nbctl list logical_router
3939 echo "---------------------"
3940 ovn-nbctl list logical_router_port
3941 echo "---------------------"
3942
3943 echo "---------SB dump-----"
3944 ovn-sbctl list datapath_binding
3945 echo "---------------------"
3946 ovn-sbctl list logical_flow
3947 echo "---------------------"
3948
3949 echo "------ hv1 dump ----------"
3950 as hv1 ovs-ofctl dump-flows br-int
3951
3952 #Disable router R1
3953 ovn-nbctl set Logical_Router R1 enabled=false
3954
3955 echo "---------SB dump-----"
3956 ovn-sbctl list datapath_binding
3957 echo "---------------------"
3958 ovn-sbctl list logical_flow
3959 echo "---------------------"
3960
3961 echo "------ hv1 dump ----------"
3962 as hv1 ovs-ofctl dump-flows br-int
3963
3964 # Allow some time for the disabling of logical router R1 to propagate.
3965 # XXX This should be more systematic.
3966 sleep 1
3967
3968 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3969
3970 # Packet to Expect
3971 expect_src_mac="000000010204"
3972 expect_dst_mac="f00000010204"
3973 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3974
3975 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3976
3977 OVN_CLEANUP([hv1])
3978
3979 AT_CLEANUP
3980
3981 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3982 AT_SKIP_IF([test $HAVE_PYTHON = no])
3983 ovn_start
3984
3985 # Logical network:
3986 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3987 # network. R1 has switchess foo (192.168.1.0/24)
3988 # connected to it.
3989 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3990
3991 ovn-nbctl lr-add R1
3992 ovn-nbctl lr-add R2
3993
3994 ovn-nbctl ls-add foo
3995 ovn-nbctl ls-add alice
3996 ovn-nbctl ls-add bob
3997
3998 # Connect foo to R1
3999 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4000 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4001 options:router-port=foo addresses=\"00:00:00:01:02:03\"
4002
4003 # Connect alice to R2
4004 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
4005 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4006 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
4007
4008 # Connect bob to R2
4009 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
4010 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
4011 options:router-port=bob addresses=\"00:00:00:01:02:05\"
4012
4013 # Connect R1 to R2
4014 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
4015 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
4016
4017 #install static routes
4018 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4019 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
4020 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4021
4022 # Create logical port foo1 in foo
4023 ovn-nbctl lsp-add foo foo1 \
4024 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4025
4026 # Create logical port alice1 in alice
4027 ovn-nbctl lsp-add alice alice1 \
4028 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4029
4030 # Create logical port bob1 in bob
4031 ovn-nbctl lsp-add bob bob1 \
4032 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
4033
4034 # Create two hypervisor and create OVS ports corresponding to logical ports.
4035 net_add n1
4036
4037 sim_add hv1
4038 as hv1
4039 ovs-vsctl add-br br-phys
4040 ovn_attach n1 br-phys 192.168.0.1
4041 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4042 set interface hv1-vif1 external-ids:iface-id=foo1 \
4043 options:tx_pcap=hv1/vif1-tx.pcap \
4044 options:rxq_pcap=hv1/vif1-rx.pcap \
4045 ofport-request=1
4046
4047 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4048 set interface hv1-vif2 external-ids:iface-id=alice1 \
4049 options:tx_pcap=hv1/vif2-tx.pcap \
4050 options:rxq_pcap=hv1/vif2-rx.pcap \
4051 ofport-request=2
4052
4053 sim_add hv2
4054 as hv2
4055 ovs-vsctl add-br br-phys
4056 ovn_attach n1 br-phys 192.168.0.2
4057 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4058 set interface hv2-vif1 external-ids:iface-id=bob1 \
4059 options:tx_pcap=hv2/vif1-tx.pcap \
4060 options:rxq_pcap=hv2/vif1-rx.pcap \
4061 ofport-request=1
4062
4063
4064 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4065 # packets for ARP resolution (native tunneling doesn't queue packets
4066 # for ARP resolution).
4067 OVN_POPULATE_ARP
4068
4069 # Allow some time for ovn-northd and ovn-controller to catch up.
4070 # XXX This should be more systematic.
4071 sleep 1
4072
4073 ip_to_hex() {
4074 printf "%02x%02x%02x%02x" "$@"
4075 }
4076
4077 # Send ip packets between foo1 and alice1
4078 src_mac="f00000010203"
4079 dst_mac="000000010203"
4080 src_ip=`ip_to_hex 192 168 1 2`
4081 dst_ip=`ip_to_hex 172 16 1 2`
4082 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4083 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4084
4085 # Send ip packets between foo1 and bob1
4086 src_mac="f00000010203"
4087 dst_mac="000000010203"
4088 src_ip=`ip_to_hex 192 168 1 2`
4089 dst_ip=`ip_to_hex 172 16 2 2`
4090 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4091 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4092
4093 echo "---------NB dump-----"
4094 ovn-nbctl show
4095 echo "---------------------"
4096 ovn-nbctl list logical_router
4097 echo "---------------------"
4098 ovn-nbctl list logical_router_port
4099 echo "---------------------"
4100
4101 echo "---------SB dump-----"
4102 ovn-sbctl list datapath_binding
4103 echo "---------------------"
4104 ovn-sbctl list port_binding
4105 echo "---------------------"
4106
4107 echo "------ hv1 dump ----------"
4108 as hv1 ovs-ofctl dump-flows br-int
4109 echo "------ hv2 dump ----------"
4110 as hv2 ovs-ofctl dump-flows br-int
4111
4112 # Packet to Expect at bob1
4113 src_mac="000000010205"
4114 dst_mac="f00000010205"
4115 src_ip=`ip_to_hex 192 168 1 2`
4116 dst_ip=`ip_to_hex 172 16 2 2`
4117 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4118
4119 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4120
4121 # Packet to Expect at alice1
4122 src_mac="000000010204"
4123 dst_mac="f00000010204"
4124 src_ip=`ip_to_hex 192 168 1 2`
4125 dst_ip=`ip_to_hex 172 16 1 2`
4126 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4127
4128 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4129
4130 OVN_CLEANUP([hv1],[hv2])
4131
4132 AT_CLEANUP
4133
4134 AT_SETUP([ovn -- send gratuitous arp on localnet])
4135 AT_SKIP_IF([test $HAVE_PYTHON = no])
4136 ovn_start
4137 ovn-nbctl ls-add lsw0
4138 net_add n1
4139 sim_add hv
4140 as hv
4141 ovs-vsctl \
4142 -- add-br br-phys \
4143 -- add-br br-eth0
4144
4145 ovn_attach n1 br-phys 192.168.0.1
4146
4147 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
4148 AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv/snoopvif-tx.pcap options:rxq_pcap=hv/snoopvif-rx.pcap])
4149
4150 # Create a vif.
4151 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
4152 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
4153 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
4154
4155 # Create a localnet port.
4156 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
4157 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
4158 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
4159 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
4160
4161 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
4162
4163 # Wait for packet to be received.
4164 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4165 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4166
4167 # Check GARP packet when restart openflow connection.
4168 as hv
4169 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4170
4171 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
4172
4173 as hv
4174 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4175
4176 # Wait for packet to be received.
4177 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4178 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4179
4180 # Delete the localnet ports.
4181 AT_CHECK([ovs-vsctl del-port localvif1])
4182 AT_CHECK([ovn-nbctl lsp-del ln_port])
4183
4184 OVN_CLEANUP([hv])
4185
4186 AT_CLEANUP
4187
4188 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
4189 AT_SKIP_IF([test $HAVE_PYTHON = no])
4190 ovn_start
4191
4192 # Logical network:
4193 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
4194 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4195 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
4196 # connected to it.
4197
4198 ovn-nbctl lr-add R1
4199 ovn-nbctl lr-add R2
4200 ovn-nbctl lr-add R3
4201
4202 ovn-nbctl ls-add foo
4203 ovn-nbctl ls-add alice
4204 ovn-nbctl ls-add bob
4205 ovn-nbctl ls-add join
4206
4207 # Connect foo to R1
4208 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4209 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4210 options:router-port=foo addresses=\"00:00:01:01:02:03\"
4211
4212 # Connect alice to R2
4213 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4214 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4215 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4216
4217 # Connect bob to R3
4218 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
4219 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
4220 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
4221
4222 # Connect R1 to join
4223 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4224 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4225 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4226
4227 # Connect R2 to join
4228 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4229 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4230 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4231
4232 # Connect R3 to join
4233 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
4234 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
4235 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
4236
4237 #install static routes
4238 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4239 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
4240
4241 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4242 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
4243
4244 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4245 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
4246
4247 # Create logical port foo1 in foo
4248 ovn-nbctl lsp-add foo foo1 \
4249 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4250
4251 # Create logical port alice1 in alice
4252 ovn-nbctl lsp-add alice alice1 \
4253 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4254
4255 # Create logical port bob1 in bob
4256 ovn-nbctl lsp-add bob bob1 \
4257 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
4258
4259 # Create two hypervisor and create OVS ports corresponding to logical ports.
4260 net_add n1
4261
4262 sim_add hv1
4263 as hv1
4264 ovs-vsctl add-br br-phys
4265 ovn_attach n1 br-phys 192.168.0.1
4266 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4267 set interface hv1-vif1 external-ids:iface-id=foo1 \
4268 options:tx_pcap=hv1/vif1-tx.pcap \
4269 options:rxq_pcap=hv1/vif1-rx.pcap \
4270 ofport-request=1
4271
4272 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4273 set interface hv1-vif2 external-ids:iface-id=alice1 \
4274 options:tx_pcap=hv1/vif2-tx.pcap \
4275 options:rxq_pcap=hv1/vif2-rx.pcap \
4276 ofport-request=2
4277
4278 sim_add hv2
4279 as hv2
4280 ovs-vsctl add-br br-phys
4281 ovn_attach n1 br-phys 192.168.0.2
4282 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4283 set interface hv2-vif1 external-ids:iface-id=bob1 \
4284 options:tx_pcap=hv2/vif1-tx.pcap \
4285 options:rxq_pcap=hv2/vif1-rx.pcap \
4286 ofport-request=1
4287
4288
4289 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4290 # packets for ARP resolution (native tunneling doesn't queue packets
4291 # for ARP resolution).
4292 OVN_POPULATE_ARP
4293
4294 # Allow some time for ovn-northd and ovn-controller to catch up.
4295 # XXX This should be more systematic.
4296 sleep 1
4297
4298 ip_to_hex() {
4299 printf "%02x%02x%02x%02x" "$@"
4300 }
4301
4302 # Send ip packets between foo1 and alice1
4303 src_mac="f00000010203"
4304 dst_mac="000001010203"
4305 src_ip=`ip_to_hex 192 168 1 2`
4306 dst_ip=`ip_to_hex 172 16 1 2`
4307 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4308 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4309 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4310
4311 # Send ip packets between foo1 and bob1
4312 src_mac="f00000010203"
4313 dst_mac="000001010203"
4314 src_ip=`ip_to_hex 192 168 1 2`
4315 dst_ip=`ip_to_hex 10 32 1 2`
4316 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4317 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4318
4319 echo "---------NB dump-----"
4320 ovn-nbctl show
4321 echo "---------------------"
4322 ovn-nbctl list logical_router
4323 echo "---------------------"
4324 ovn-nbctl list logical_router_port
4325 echo "---------------------"
4326
4327 echo "---------SB dump-----"
4328 ovn-sbctl list datapath_binding
4329 echo "---------------------"
4330 ovn-sbctl list port_binding
4331 echo "---------------------"
4332 ovn-sbctl dump-flows
4333 echo "---------------------"
4334
4335 echo "------ hv1 dump ----------"
4336 as hv1 ovs-ofctl show br-int
4337 as hv1 ovs-ofctl dump-flows br-int
4338 echo "------ hv2 dump ----------"
4339 as hv2 ovs-ofctl show br-int
4340 as hv2 ovs-ofctl dump-flows br-int
4341 echo "----------------------------"
4342
4343 # Packet to Expect at bob1
4344 src_mac="000003010203"
4345 dst_mac="f00000010205"
4346 src_ip=`ip_to_hex 192 168 1 2`
4347 dst_ip=`ip_to_hex 10 32 1 2`
4348 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4349
4350 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4351
4352 # Packet to Expect at alice1
4353 src_mac="000002010203"
4354 dst_mac="f00000010204"
4355 src_ip=`ip_to_hex 192 168 1 2`
4356 dst_ip=`ip_to_hex 172 16 1 2`
4357 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4358
4359 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4360
4361 OVN_CLEANUP([hv1],[hv2])
4362
4363 AT_CLEANUP
4364
4365 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
4366 AT_SKIP_IF([test $HAVE_PYTHON = no])
4367 ovn_start
4368
4369 ovn-nbctl ls-add ls1
4370
4371 ovn-nbctl lsp-add ls1 ls1-lp1 \
4372 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4373
4374 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4375
4376 ovn-nbctl lsp-add ls1 ls1-lp2 \
4377 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4378
4379 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4380
4381 ovn-nbctl ls-add ls2
4382 ovn-nbctl lsp-add ls2 ls2-lp1 \
4383 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4384 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4385 ovn-nbctl lsp-add ls2 ls2-lp2 \
4386 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4387 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4388
4389 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
4390 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
4391 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
4392
4393 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4394 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4395
4396 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
4397 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
4398 \"lease_time\"=\"3600\"")"
4399
4400 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
4401
4402 net_add n1
4403 sim_add hv1
4404
4405 as hv1
4406 ovs-vsctl add-br br-phys
4407 ovn_attach n1 br-phys 192.168.0.1
4408 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4409 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4410 options:tx_pcap=hv1/vif1-tx.pcap \
4411 options:rxq_pcap=hv1/vif1-rx.pcap \
4412 ofport-request=1
4413
4414 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4415 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4416 options:tx_pcap=hv1/vif2-tx.pcap \
4417 options:rxq_pcap=hv1/vif2-rx.pcap \
4418 ofport-request=2
4419
4420 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4421 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4422 options:tx_pcap=hv1/vif3-tx.pcap \
4423 options:rxq_pcap=hv1/vif3-rx.pcap \
4424 ofport-request=3
4425
4426 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4427 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4428 options:tx_pcap=hv1/vif4-tx.pcap \
4429 options:rxq_pcap=hv1/vif4-rx.pcap \
4430 ofport-request=4
4431
4432 OVN_POPULATE_ARP
4433
4434 sleep 2
4435
4436 as hv1 ovs-vsctl show
4437
4438 # This shell function sends a DHCP request packet
4439 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP REQUEST_IP ...
4440 test_dhcp() {
4441 local inport=$1 src_mac=$2 dhcp_type=$3 ciaddr=$4 offer_ip=$5 request_ip=$6 use_ip=$7
4442 shift; shift; shift; shift; shift; shift; shift;
4443 if test $use_ip != 0; then
4444 src_ip=$1
4445 dst_ip=$2
4446 shift; shift;
4447 else
4448 src_ip=`ip_to_hex 0 0 0 0`
4449 dst_ip=`ip_to_hex 255 255 255 255`
4450 fi
4451 if test $request_ip != 0; then
4452 ip_len=0120
4453 udp_len=010b
4454 else
4455 ip_len=011a
4456 udp_len=0106
4457 fi
4458 local request=ffffffffffff${src_mac}08004510${ip_len}0000000080110000${src_ip}${dst_ip}
4459 # udp header and dhcp header
4460 request=${request}00440043${udp_len}0000
4461 request=${request}010106006359aa7600000000${ciaddr}000000000000000000000000${src_mac}
4462 # client hardware padding
4463 request=${request}00000000000000000000
4464 # server hostname
4465 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4466 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4467 # boot file name
4468 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4469 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4470 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4471 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4472 # dhcp magic cookie
4473 request=${request}63825363
4474 # dhcp message type
4475 request=${request}3501${dhcp_type}
4476 # dhcp unknown option
4477 request=${request}d70701020304050607
4478 # dhcp pad option
4479 request=${request}00
4480 if test $request_ip != 0; then
4481 # dhcp requested ip
4482 request=${request}3204${request_ip}
4483 fi
4484 # dhcp end option
4485 request=${request}ff
4486
4487 for port in $inport "$@"; do
4488 : >> $port.expected
4489 done
4490 if test $offer_ip != 0; then
4491 local srv_mac=$1 srv_ip=$2 dhcp_reply_type=$3 expected_dhcp_opts=$4
4492 # total IP length will be the IP length of the request packet
4493 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4494 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4495 udp_len=`expr $ip_len - 20`
4496 ip_len=$(printf "%x" $ip_len)
4497 udp_len=$(printf "%x" $udp_len)
4498 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4499 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4500 # udp header and dhcp header.
4501 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4502 reply=${reply}004300440${udp_len}0000020106006359aa7600000000${ciaddr}
4503 # your ip address; 0 for NAK
4504 if test $dhcp_reply_type = 06; then
4505 reply=${reply}00000000
4506 else
4507 reply=${reply}${offer_ip}
4508 fi
4509 # next server ip address, relay agent ip address, client mac address
4510 reply=${reply}0000000000000000${src_mac}
4511 # client hardware padding
4512 reply=${reply}00000000000000000000
4513 # server hostname
4514 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4515 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4516 # boot file name
4517 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4518 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4519 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4520 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4521 # dhcp magic cookie
4522 reply=${reply}63825363
4523 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4524 echo $reply >> $inport.expected
4525 else
4526 for outport; do
4527 echo $request >> $outport.expected
4528 done
4529 fi
4530 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4531 }
4532
4533 reset_pcap_file() {
4534 local iface=$1
4535 local pcap_file=$2
4536 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4537 options:rxq_pcap=dummy-rx.pcap
4538 rm -f ${pcap_file}*.pcap
4539 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4540 options:rxq_pcap=${pcap_file}-rx.pcap
4541 }
4542
4543 ip_to_hex() {
4544 printf "%02x%02x%02x%02x" "$@"
4545 }
4546
4547 AT_CAPTURE_FILE([ofctl_monitor0.log])
4548 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4549 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4550
4551 echo "---------NB dump-----"
4552 ovn-nbctl show
4553 echo "---------------------"
4554 echo "---------SB dump-----"
4555 ovn-sbctl list datapath_binding
4556 echo "---------------------"
4557 ovn-sbctl list logical_flow
4558 echo "---------------------"
4559
4560 echo "---------------------"
4561 ovn-sbctl dump-flows
4562 echo "---------------------"
4563
4564 echo "------ hv1 dump ----------"
4565 as hv1 ovs-ofctl dump-flows br-int
4566
4567 # Send DHCPDISCOVER.
4568 offer_ip=`ip_to_hex 10 0 0 4`
4569 server_ip=`ip_to_hex 10 0 0 1`
4570 ciaddr=`ip_to_hex 0 0 0 0`
4571 request_ip=0
4572 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4573 test_dhcp 1 f00000000001 01 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
4574
4575 # NXT_RESUMEs should be 1.
4576 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4577
4578 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4579 cat 1.expected | cut -c -48 > expout
4580 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4581 # Skipping the IPv4 checksum.
4582 cat 1.expected | cut -c 53- > expout
4583 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4584
4585 # ovs-ofctl also resumes the packets and this causes other ports to receive
4586 # the DHCP request packet. So reset the pcap files so that its easier to test.
4587 reset_pcap_file hv1-vif1 hv1/vif1
4588 reset_pcap_file hv1-vif2 hv1/vif2
4589 rm -f 1.expected
4590 rm -f 2.expected
4591
4592 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
4593 # address in the Requested IP Address option.
4594 offer_ip=`ip_to_hex 10 0 0 6`
4595 server_ip=`ip_to_hex 10 0 0 1`
4596 ciaddr=`ip_to_hex 0 0 0 0`
4597 request_ip=$offer_ip
4598 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4599 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
4600
4601 # NXT_RESUMEs should be 2.
4602 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4603
4604 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4605 cat 2.expected | cut -c -48 > expout
4606 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4607 # Skipping the IPv4 checksum.
4608 cat 2.expected | cut -c 53- > expout
4609 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4610
4611 reset_pcap_file hv1-vif1 hv1/vif1
4612 reset_pcap_file hv1-vif2 hv1/vif2
4613 rm -f 1.expected
4614 rm -f 2.expected
4615
4616 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with a mismatched IP in
4617 # the Requested IP Address option, expect a DHCPNAK.
4618 offer_ip=`ip_to_hex 10 0 0 6`
4619 server_ip=`ip_to_hex 10 0 0 1`
4620 ciaddr=`ip_to_hex 0 0 0 0`
4621 request_ip=`ip_to_hex 10 0 0 7`
4622 expected_dhcp_opts=""
4623 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 06 $expected_dhcp_opts
4624
4625 # NXT_RESUMEs should be 3.
4626 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4627
4628 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4629 cat 2.expected | cut -c -48 > expout
4630 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4631 # Skipping the IPv4 checksum.
4632 cat 2.expected | cut -c 53- > expout
4633 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4634
4635 reset_pcap_file hv1-vif1 hv1/vif1
4636 reset_pcap_file hv1-vif2 hv1/vif2
4637 rm -f 1.expected
4638 rm -f 2.expected
4639
4640 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4641 # but should be resumed without the reply.
4642 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4643 # one from ovn-controller and the other from "ovs-ofctl resume."
4644 ciaddr=`ip_to_hex 0 0 0 0`
4645 offer_ip=0
4646 request_ip=0
4647 test_dhcp 2 f00000000002 08 $ciaddr $offer_ip $request_ip 0 1 1
4648
4649 # NXT_RESUMEs should be 4.
4650 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4651
4652 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4653 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4654
4655 reset_pcap_file hv1-vif1 hv1/vif1
4656 reset_pcap_file hv1-vif2 hv1/vif2
4657 rm -f 1.expected
4658 rm -f 2.expected
4659
4660 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4661 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4662
4663 ciaddr=`ip_to_hex 0 0 0 0`
4664 test_dhcp 3 f00000000003 01 $ciaddr 0 0 4 0
4665
4666 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4667 # this lport.
4668 ciaddr=`ip_to_hex 0 0 0 0`
4669 test_dhcp 4 f00000000004 01 $ciaddr 0 0 3 0
4670
4671 # NXT_RESUMEs should be 4.
4672 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4673
4674 #OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4675 #OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4676
4677 # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4678 # and ip4.dst set to 10.0.0.1.
4679 offer_ip=`ip_to_hex 10 0 0 6`
4680 server_ip=`ip_to_hex 10 0 0 1`
4681 ciaddr=$offer_ip
4682 request_ip=0
4683 src_ip=$offer_ip
4684 dst_ip=$server_ip
4685 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4686 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4687
4688 # NXT_RESUMEs should be 5.
4689 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4690
4691 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4692 cat 2.expected | cut -c -48 > expout
4693 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4694 # Skipping the IPv4 checksum.
4695 cat 2.expected | cut -c 53- > expout
4696 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4697
4698 reset_pcap_file hv1-vif1 hv1/vif1
4699 reset_pcap_file hv1-vif2 hv1/vif2
4700 rm -f 1.expected
4701 rm -f 2.expected
4702
4703 # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4704 # and ip4.dst set to 255.255.255.255.
4705 offer_ip=`ip_to_hex 10 0 0 6`
4706 server_ip=`ip_to_hex 10 0 0 1`
4707 ciaddr=$offer_ip
4708 request_ip=0
4709 src_ip=$offer_ip
4710 dst_ip=`ip_to_hex 255 255 255 255`
4711 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4712 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4713
4714 # NXT_RESUMEs should be 6.
4715 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4716
4717 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4718 cat 2.expected | cut -c -48 > expout
4719 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4720 # Skipping the IPv4 checksum.
4721 cat 2.expected | cut -c 53- > expout
4722 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4723
4724 reset_pcap_file hv1-vif1 hv1/vif1
4725 reset_pcap_file hv1-vif2 hv1/vif2
4726 rm -f 1.expected
4727 rm -f 2.expected
4728
4729 # Send DHCPREQUEST in the RENEWING/REBINDING state with a mismatched IP in the
4730 # ciaddr, expect a DHCPNAK.
4731 offer_ip=`ip_to_hex 10 0 0 6`
4732 server_ip=`ip_to_hex 10 0 0 1`
4733 ciaddr=`ip_to_hex 10 0 0 7`
4734 request_ip=0
4735 src_ip=$offer_ip
4736 dst_ip=`ip_to_hex 255 255 255 255`
4737 expected_dhcp_opts=""
4738 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4739
4740 # NXT_RESUMEs should be 7.
4741 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4742
4743 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4744 cat 2.expected | cut -c -48 > expout
4745 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4746 # Skipping the IPv4 checksum.
4747 cat 2.expected | cut -c 53- > expout
4748 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4749
4750 reset_pcap_file hv1-vif1 hv1/vif1
4751 reset_pcap_file hv1-vif2 hv1/vif2
4752 rm -f 1.expected
4753 rm -f 2.expected
4754
4755 # Send DHCPREQUEST in the RENEWING/REBINDING state without a specifyied ciaddr,
4756 # expect a DHCPNAK.
4757 offer_ip=`ip_to_hex 10 0 0 6`
4758 server_ip=`ip_to_hex 10 0 0 1`
4759 ciaddr=`ip_to_hex 0 0 0 0`
4760 request_ip=0
4761 src_ip=$offer_ip
4762 dst_ip=`ip_to_hex 255 255 255 255`
4763 expected_dhcp_opts=""
4764 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4765
4766 # NXT_RESUMEs should be 8.
4767 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4768
4769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4770 cat 2.expected | cut -c -48 > expout
4771 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4772 # Skipping the IPv4 checksum.
4773 cat 2.expected | cut -c 53- > expout
4774 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4775
4776 reset_pcap_file hv1-vif1 hv1/vif1
4777 reset_pcap_file hv1-vif2 hv1/vif2
4778 rm -f 1.expected
4779 rm -f 2.expected
4780
4781 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4782 # The packet should not be received by ovn-controller.
4783 ciaddr=`ip_to_hex 0 0 0 0`
4784 src_ip=`ip_to_hex 10 0 0 6`
4785 dst_ip=`ip_to_hex 10 0 0 4`
4786 test_dhcp 2 f00000000002 03 $ciaddr 0 0 1 $src_ip $dst_ip 1
4787
4788 # NXT_RESUMEs should be 8.
4789 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4790
4791 # vif1-tx.pcap should have received the DHCPv4 request packet
4792 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4793
4794 OVN_CLEANUP([hv1])
4795
4796 AT_CLEANUP
4797
4798 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4799 AT_SKIP_IF([test $HAVE_PYTHON = no])
4800 ovn_start
4801
4802 ovn-nbctl ls-add ls1
4803 ovn-nbctl lsp-add ls1 ls1-lp1 \
4804 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4805
4806 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4807
4808 ovn-nbctl lsp-add ls1 ls1-lp2 \
4809 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4810
4811 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4812
4813 ovn-nbctl lsp-add ls1 ls1-lp3 \
4814 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4815
4816 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4817
4818 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4819 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4820
4821 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4822 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4823
4824 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4825 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4826
4827 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4828
4829 ovn-nbctl ls-add ls2
4830 ovn-nbctl lsp-add ls2 ls2-lp1 \
4831 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4832 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4833 ovn-nbctl lsp-add ls2 ls2-lp2 \
4834 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4835 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4836
4837 net_add n1
4838 sim_add hv1
4839
4840 as hv1
4841 ovs-vsctl add-br br-phys
4842 ovn_attach n1 br-phys 192.168.0.1
4843 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4844 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4845 options:tx_pcap=hv1/vif1-tx.pcap \
4846 options:rxq_pcap=hv1/vif1-rx.pcap \
4847 ofport-request=1
4848
4849 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4850 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4851 options:tx_pcap=hv1/vif2-tx.pcap \
4852 options:rxq_pcap=hv1/vif2-rx.pcap \
4853 ofport-request=2
4854
4855 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4856 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4857 options:tx_pcap=hv1/vif3-tx.pcap \
4858 options:rxq_pcap=hv1/vif3-rx.pcap \
4859 ofport-request=3
4860
4861 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4862 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4863 options:tx_pcap=hv1/vif4-tx.pcap \
4864 options:rxq_pcap=hv1/vif4-rx.pcap \
4865 ofport-request=4
4866
4867 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4868 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4869 options:tx_pcap=hv1/vif5-tx.pcap \
4870 options:rxq_pcap=hv1/vif5-rx.pcap \
4871 ofport-request=5
4872
4873 OVN_POPULATE_ARP
4874
4875 sleep 2
4876
4877 trim_zeros() {
4878 sed 's/\(00\)\{1,\}$//'
4879 }
4880
4881 # This shell function sends a DHCPv6 request packet
4882 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4883 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4884 # packet should be received twice (one from ovn-controller and the other
4885 # from the "ovs-ofctl monitor br-int resume"
4886 test_dhcpv6() {
4887 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4888 if test $msg_code != 0b; then
4889 req_len=2a
4890 else
4891 req_len=1a
4892 fi
4893 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
4894 # dst ip ff02::1:2
4895 request=${request}ff020000000000000000000000010002
4896 # udp header and dhcpv6 header
4897 request=${request}0222022300${req_len}ffff${msg_code}010203
4898 # Client identifier
4899 request=${request}0001000a00030001${src_mac}
4900 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4901 # is not 11 (information request packet)
4902 if test $msg_code != 0b; then
4903 request=${request}0003000c0102030400000e1000001518
4904 fi
4905 shift; shift; shift; shift; shift;
4906 if test $offer_ip != 0; then
4907 local server_mac=000000100001
4908 local server_lla=fe80000000000000020000fffe100001
4909 local reply_code=07
4910 if test $msg_code = 01; then
4911 reply_code=02
4912 fi
4913 local msg_len=54
4914 if test $offer_ip = 1; then
4915 msg_len=28
4916 fi
4917 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4918 # udp header and dhcpv6 header
4919 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4920 # Client identifier
4921 reply=${reply}0001000a00030001${src_mac}
4922 # IA-NA
4923 if test $offer_ip != 1; then
4924 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4925 fi
4926 # Server identifier
4927 reply=${reply}0002000a00030001${server_mac}
4928 echo $reply | trim_zeros >> $inport.expected
4929 else
4930 for outport; do
4931 echo $request | trim_zeros >> $outport.expected
4932 done
4933 fi
4934
4935 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4936 }
4937
4938 reset_pcap_file() {
4939 local iface=$1
4940 local pcap_file=$2
4941 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4942 options:rxq_pcap=dummy-rx.pcap
4943 rm -f ${pcap_file}*.pcap
4944 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4945 options:rxq_pcap=${pcap_file}-rx.pcap
4946 }
4947
4948 AT_CAPTURE_FILE([ofctl_monitor0.log])
4949 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4950 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4951
4952 echo "---------NB dump-----"
4953 ovn-nbctl show
4954 echo "---------------------"
4955 echo "---------SB dump-----"
4956 ovn-sbctl list datapath_binding
4957 echo "---------------------"
4958 ovn-sbctl list logical_flow
4959 echo "---------------------"
4960
4961 echo "---------------------"
4962 ovn-sbctl dump-flows
4963 echo "---------------------"
4964
4965 echo "------ hv1 dump ----------"
4966 as hv1 ovs-ofctl dump-flows br-int
4967
4968 src_mac=f00000000001
4969 src_lla=fe80000000000000f20000fffe000001
4970 offer_ip=ae700000000000000000000000000004
4971 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4972
4973 # NXT_RESUMEs should be 1.
4974 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4975
4976 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4977 # cat 1.expected | trim_zeros > expout
4978 cat 1.expected | cut -c -120 > expout
4979 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4980 # Skipping the UDP checksum
4981 cat 1.expected | cut -c 125- > expout
4982 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4983
4984 rm 1.expected
4985
4986 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4987 # without any modifications and the packet should be received by ls1-lp1.
4988 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4989 # resume and the other from ovs-ofctl monitor resume.
4990
4991 reset_pcap_file hv1-vif1 hv1/vif1
4992 reset_pcap_file hv1-vif2 hv1/vif2
4993
4994 src_mac=f00000000002
4995 src_lla=fe80000000000000f20000fffe000002
4996 offer_ip=ae700000000000000000000000000005
4997 # Set invalid msg_type
4998
4999 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
5000
5001 # NXT_RESUMEs should be 2.
5002 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5003
5004 # vif2-tx.pcap should not have received the DHCPv6 reply packet
5005 rm 2.packets
5006 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
5007 AT_CHECK([cat 2.packets], [0], [])
5008
5009 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
5010 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
5011 cat 1.expected > expout
5012 AT_CHECK([cat 1.packets], [0], [expout])
5013
5014 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
5015 # There should be no DHCPv6 reply from ovn-controller and the request packet
5016 # should be received by ls2-lp2.
5017
5018 src_mac=f00000000003
5019 src_lla=fe80000000000000f20000fffe000003
5020 test_dhcpv6 3 $src_mac $src_lla 01 0 4
5021
5022 # NXT_RESUMEs should be 2 only.
5023 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5024
5025 # vif3-tx.pcap should not have received the DHCPv6 reply packet
5026 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
5027 AT_CHECK([cat 3.packets], [0], [])
5028
5029 # vif4-tx.pcap should have received the DHCPv6 request packet
5030 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
5031 cat 4.expected > expout
5032 AT_CHECK([cat 4.packets], [0], [expout])
5033
5034 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
5035 # The DHCPv6 reply shouldn't contain offer_ip.
5036 src_mac=f00000000022
5037 src_lla=fe80000000000000f20000fffe000022
5038 reset_pcap_file hv1-vif5 hv1/vif5
5039 test_dhcpv6 5 $src_mac $src_lla 01 1 5
5040
5041 # NXT_RESUMEs should be 3.
5042 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5043
5044 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
5045 # Skipping the UDP checksum
5046 cat 5.expected | cut -c 1-120,125- > expout
5047 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5048
5049 # Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
5050 # shouldn't contain offer_ip
5051 src_mac=f00000000022
5052 src_lla=fe80000000000000f20000fffe000022
5053 reset_pcap_file hv1-vif5 hv1/vif5
5054 rm -f 5.expected
5055 test_dhcpv6 5 $src_mac $src_lla 0b 1 5
5056
5057 # NXT_RESUMEs should be 4.
5058 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5059
5060 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
5061 trim_zeros > 5.packets
5062 # Skipping the UDP checksum
5063 cat 5.expected | cut -c 1-120,125- > expout
5064 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5065
5066 OVN_CLEANUP([hv1])
5067
5068 AT_CLEANUP
5069
5070 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
5071 AT_SKIP_IF([test $HAVE_PYTHON = no])
5072 ovn_start
5073
5074 # Logical network:
5075 # Two LRs - R1 and R2 that are connected to each other via LS "join"
5076 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
5077 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
5078 # R2 is a gateway router.
5079
5080
5081
5082 # Create two hypervisor and create OVS ports corresponding to logical ports.
5083 net_add n1
5084
5085 sim_add hv1
5086 as hv1
5087 ovs-vsctl add-br br-phys
5088 ovn_attach n1 br-phys 192.168.0.1
5089 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5090 set interface hv1-vif1 external-ids:iface-id=foo1 \
5091 options:tx_pcap=hv1/vif1-tx.pcap \
5092 options:rxq_pcap=hv1/vif1-rx.pcap \
5093 ofport-request=1
5094
5095
5096 sim_add hv2
5097 as hv2
5098 ovs-vsctl add-br br-phys
5099 ovn_attach n1 br-phys 192.168.0.2
5100 ovs-vsctl -- add-port br-int hv2-vif1 -- \
5101 set interface hv2-vif1 external-ids:iface-id=alice1 \
5102 options:tx_pcap=hv2/vif1-tx.pcap \
5103 options:rxq_pcap=hv2/vif1-rx.pcap \
5104 ofport-request=1
5105
5106 # Pre-populate the hypervisors' ARP tables so that we don't lose any
5107 # packets for ARP resolution (native tunneling doesn't queue packets
5108 # for ARP resolution).
5109 OVN_POPULATE_ARP
5110
5111 ovn-nbctl create Logical_Router name=R1
5112 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5113
5114 ovn-nbctl ls-add foo
5115 ovn-nbctl ls-add alice
5116 ovn-nbctl ls-add join
5117
5118 # Connect foo to R1
5119 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5120 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5121 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5122
5123 # Connect alice to R2
5124 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5125 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
5126 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
5127
5128 # Connect R1 to join
5129 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
5130 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
5131 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
5132
5133 # Connect R2 to join
5134 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5135 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
5136 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
5137
5138
5139 #install static routes
5140 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5141 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
5142 R1 static_routes @lrt
5143
5144 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5145 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5146 R2 static_routes @lrt
5147
5148 # Create logical port foo1 in foo
5149 ovn-nbctl lsp-add foo foo1 \
5150 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5151
5152 # Create logical port alice1 in alice
5153 ovn-nbctl lsp-add alice alice1 \
5154 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
5155
5156
5157 # Allow some time for ovn-northd and ovn-controller to catch up.
5158 # XXX This should be more systematic.
5159 sleep 2
5160
5161 ip_to_hex() {
5162 printf "%02x%02x%02x%02x" "$@"
5163 }
5164
5165 # Send ip packets between foo1 and alice1
5166 src_mac="f00000010203"
5167 dst_mac="000001010203"
5168 src_ip=`ip_to_hex 192 168 1 2`
5169 dst_ip=`ip_to_hex 172 16 1 2`
5170 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5171
5172 echo "---------NB dump-----"
5173 ovn-nbctl show
5174 echo "---------------------"
5175 ovn-nbctl list logical_router
5176 echo "---------------------"
5177 ovn-nbctl list logical_router_port
5178 echo "---------------------"
5179
5180 echo "---------SB dump-----"
5181 ovn-sbctl list datapath_binding
5182 echo "---------------------"
5183 ovn-sbctl list port_binding
5184 echo "---------------------"
5185 ovn-sbctl dump-flows
5186 echo "---------------------"
5187 ovn-sbctl list chassis
5188 ovn-sbctl list encap
5189 echo "---------------------"
5190
5191 # Packet to Expect at alice1
5192 src_mac="000002010203"
5193 dst_mac="f00000010204"
5194 src_ip=`ip_to_hex 192 168 1 2`
5195 dst_ip=`ip_to_hex 172 16 1 2`
5196 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
5197
5198
5199 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5200 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
5201
5202 echo "------ hv1 dump after packet 1 ----------"
5203 as hv1 ovs-ofctl show br-int
5204 as hv1 ovs-ofctl dump-flows br-int
5205 echo "------ hv2 dump after packet 1 ----------"
5206 as hv2 ovs-ofctl show br-int
5207 as hv2 ovs-ofctl dump-flows br-int
5208 echo "----------------------------"
5209
5210 echo $expected > expected
5211 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
5212
5213 # Delete the router and re-create it. Things should work as before.
5214 ovn-nbctl lr-del R2
5215 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5216 # Connect alice to R2
5217 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5218 # Connect R2 to join
5219 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5220
5221 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5222 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5223 R2 static_routes @lrt
5224
5225 # Wait for ovn-controller to catch up.
5226 sleep 1
5227
5228 # Send the packet again.
5229 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5230
5231 echo "------ hv1 dump after packet 2 ----------"
5232 as hv1 ovs-ofctl show br-int
5233 as hv1 ovs-ofctl dump-flows br-int
5234 echo "------ hv2 dump after packet 2 ----------"
5235 as hv2 ovs-ofctl show br-int
5236 as hv2 ovs-ofctl dump-flows br-int
5237 echo "----------------------------"
5238
5239 echo $expected >> expected
5240 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
5241
5242 OVN_CLEANUP([hv1],[hv2])
5243
5244 AT_CLEANUP
5245
5246 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5247 AT_KEYWORDS([router-icmp-reply])
5248 AT_SKIP_IF([test $HAVE_PYTHON = no])
5249 ovn_start
5250
5251 # Logical network:
5252 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5253 # and has switch ls2 (172.16.1.0/24) connected to it.
5254
5255 ovn-nbctl lr-add R1
5256
5257 ovn-nbctl ls-add ls1
5258 ovn-nbctl ls-add ls2
5259
5260 # Connect ls1 to R1
5261 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5262 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5263 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5264
5265 # Connect ls2 to R1
5266 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5267 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5268 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5269
5270 # Create logical port ls1-lp1 in ls1
5271 ovn-nbctl lsp-add ls1 ls1-lp1 \
5272 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5273
5274 # Create logical port ls2-lp1 in ls2
5275 ovn-nbctl lsp-add ls2 ls2-lp1 \
5276 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5277
5278 # Create one hypervisor and create OVS ports corresponding to logical ports.
5279 net_add n1
5280
5281 sim_add hv1
5282 as hv1
5283 ovs-vsctl add-br br-phys
5284 ovn_attach n1 br-phys 192.168.0.1
5285 ovs-vsctl -- add-port br-int vif1 -- \
5286 set interface vif1 external-ids:iface-id=ls1-lp1 \
5287 options:tx_pcap=hv1/vif1-tx.pcap \
5288 options:rxq_pcap=hv1/vif1-rx.pcap \
5289 ofport-request=1
5290
5291 ovs-vsctl -- add-port br-int vif2 -- \
5292 set interface vif2 external-ids:iface-id=ls2-lp1 \
5293 options:tx_pcap=hv1/vif2-tx.pcap \
5294 options:rxq_pcap=hv1/vif2-rx.pcap \
5295 ofport-request=1
5296
5297
5298 # Allow some time for ovn-northd and ovn-controller to catch up.
5299 # XXX This should be more systematic.
5300 sleep 1
5301
5302
5303 ip_to_hex() {
5304 printf "%02x%02x%02x%02x" "$@"
5305 }
5306 for i in 1 2; do
5307 : > vif$i.expected
5308 done
5309 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5310 #
5311 # Causes a packet to be received on INPORT. The packet is an ICMPv4
5312 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5313 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5314 # provided, then it should be the ip and icmp checksums of the packet
5315 # responded; otherwise, no reply is expected.
5316 # In the absence of an ip checksum calculation helpers, this relies
5317 # on the caller to provide the checksums for the ip and icmp headers.
5318 # XXX This should be more systematic.
5319 #
5320 # INPORT is an lport number, e.g. 11 for vif11.
5321 # ETH_SRC and ETH_DST are each 12 hex digits.
5322 # IPV4_SRC and IPV4_DST are each 8 hex digits.
5323 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5324 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5325 test_ipv4_icmp_request() {
5326 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5327 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5328 shift; shift; shift; shift; shift; shift; shift
5329 shift; shift
5330
5331 # Use ttl to exercise section 4.2.2.9 of RFC1812
5332 local ip_ttl=01
5333 local icmp_id=5fbf
5334 local icmp_seq=0001
5335 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5336 local icmp_type_code_request=0800
5337 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5338 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5339
5340 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5341 if test X$exp_icmp_chksum != X; then
5342 # Expect to receive the reply, if any. In same port where packet was sent.
5343 # Note: src and dst fields are expected to be reversed.
5344 local icmp_type_code_response=0000
5345 local reply_icmp_ttl=fe
5346 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5347 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5348 echo $reply >> vif$inport.expected
5349 fi
5350 }
5351
5352 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
5353 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5354 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5355 l1_ip=$(ip_to_hex 192 168 1 2)
5356 l2_ip=$(ip_to_hex 172 16 1 2)
5357
5358 # Ping router ip address that is on same subnet as the logical port
5359 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5360 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5361
5362 # Ping router ip address that is on the other side of the logical ports
5363 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5364 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5365
5366
5367 echo "---------NB dump-----"
5368 ovn-nbctl show
5369 echo "---------------------"
5370 ovn-nbctl list logical_router
5371 echo "---------------------"
5372 ovn-nbctl list logical_router_port
5373 echo "---------------------"
5374
5375 echo "---------SB dump-----"
5376 ovn-sbctl list datapath_binding
5377 echo "---------------------"
5378 ovn-sbctl list logical_flow
5379 echo "---------------------"
5380
5381 echo "------ hv1 dump ----------"
5382 as hv1 ovs-ofctl dump-flows br-int
5383
5384 # Now check the packets actually received against the ones expected.
5385 for inport in 1 2; do
5386 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
5387 done
5388
5389 OVN_CLEANUP([hv1])
5390 AT_CLEANUP
5391
5392 AT_SETUP([ovn -- policy-based routing: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5393 AT_KEYWORDS([policy-based-routing])
5394 AT_SKIP_IF([test $HAVE_PYTHON = no])
5395 ovn_start
5396
5397 # Logical network:
5398 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5399 # and has switch ls2 (172.16.1.0/24) connected to it.
5400
5401 ovn-nbctl lr-add R1
5402
5403 ovn-nbctl ls-add ls1
5404 ovn-nbctl ls-add ls2
5405 ovn-nbctl ls-add ls3
5406
5407 # Connect ls1 to R1
5408 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5409 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5410 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5411
5412 # Connect ls2 to R1
5413 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5414 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5415 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5416
5417 # Connect ls3 to R1
5418 ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 20.20.1.1/24
5419 ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5420 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5421
5422 # Create logical port ls1-lp1 in ls1
5423 ovn-nbctl lsp-add ls1 ls1-lp1 \
5424 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5425
5426 # Create logical port ls2-lp1 in ls2
5427 ovn-nbctl lsp-add ls2 ls2-lp1 \
5428 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5429
5430 # Create logical port ls3-lp1 in ls3
5431 ovn-nbctl lsp-add ls3 ls3-lp1 \
5432 -- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 20.20.1.2"
5433
5434 # Create one hypervisor and create OVS ports corresponding to logical ports.
5435 net_add n1
5436
5437 sim_add pbr-hv
5438 as pbr-hv
5439 ovs-vsctl add-br br-phys
5440 ovn_attach n1 br-phys 192.168.0.1
5441
5442 ovs-vsctl -- add-port br-int vif1 -- \
5443 set interface vif1 external-ids:iface-id=ls1-lp1 \
5444 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5445 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5446 ofport-request=1
5447
5448 ovs-vsctl -- add-port br-int vif2 -- \
5449 set interface vif2 external-ids:iface-id=ls2-lp1 \
5450 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5451 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5452 ofport-request=1
5453
5454 ovs-vsctl -- add-port br-int vif3 -- \
5455 set interface vif3 external-ids:iface-id=ls3-lp1 \
5456 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5457 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5458 ofport-request=1
5459
5460 # Allow some time for ovn-northd and ovn-controller to catch up.
5461 # XXX This should be more systematic.
5462 sleep 1
5463
5464 ls1_ro_mac=00:00:00:01:02:f1
5465 ls1_ro_ip=192.168.1.1
5466
5467 ls2_ro_mac=00:00:00:01:02:f2
5468 ls2_ro_ip=172.16.1.1
5469
5470 ls3_ro_mac=00:00:00:01:02:f3
5471
5472 ls1_p1_mac=00:00:00:01:02:03
5473 ls1_p1_ip=192.168.1.2
5474
5475 ls2_p1_mac=00:00:00:01:02:04
5476 ls2_p1_ip=172.16.1.2
5477
5478 ls3_p1_mac=00:00:00:01:02:05
5479
5480 # Create a drop policy
5481 ovn-nbctl lr-policy-add R1 10 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" drop
5482
5483 # Check logical flow
5484 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
5485 1
5486 ])
5487
5488 # Send packet.
5489 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5490 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5491 udp && udp.src==53 && udp.dst==4369"
5492
5493 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5494
5495 # Check if packet hit the drop policy
5496 AT_CHECK([ovs-ofctl dump-flows br-int | \
5497 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24 actions=drop" | \
5498 grep "priority=10" | \
5499 grep "n_packets=1" | wc -l], [0], [dnl
5500 1
5501 ])
5502
5503 # Expected to drop the packet.
5504 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5505 rcvd_packet=`cat vif2.packets`
5506 AT_FAIL_IF([rcvd_packet = ""])
5507
5508 # Override drop policy with allow
5509 ovn-nbctl lr-policy-add R1 20 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" allow
5510
5511 # Check logical flow
5512 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
5513 2
5514 ])
5515
5516 # Send packet.
5517 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5518 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5519 udp && udp.src==53 && udp.dst==4369"
5520 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5521
5522 # Check if packet hit the allow policy
5523 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5524 grep "192.168.1.0" | \
5525 grep "priority=20" | wc -l], [0], [dnl
5526 1
5527 ])
5528
5529 # Expected packet has TTL decreased by 1
5530 expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5531 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5532 udp && udp.src==53 && udp.dst==4369"
5533 echo $expected | ovstest test-ovn expr-to-packets > expected
5534
5535 OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5536
5537 # Override allow policy with reroute
5538 ovn-nbctl lr-policy-add R1 30 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" reroute 20.20.1.2
5539
5540 # Check logical flow
5541 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5542 grep "192.168.1.0" | \
5543 grep "priority=30" | wc -l], [0], [dnl
5544 1
5545 ])
5546
5547 # Send packet.
5548 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5549 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5550 udp && udp.src==53 && udp.dst==4369"
5551 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5552
5553 echo "southbound flows"
5554
5555 ovn-sbctl dump-flows | grep lr_in_policy
5556 echo "ovs flows"
5557 ovs-ofctl dump-flows br-int
5558 # Check if packet hit the allow policy
5559 AT_CHECK([ovs-ofctl dump-flows br-int | \
5560 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24" | \
5561 grep "priority=30" | \
5562 grep "n_packets=1" | wc -l], [0], [dnl
5563 1
5564 ])
5565 echo "packet hit reroute policy"
5566
5567 # Expected packet has TTL decreased by 1
5568 expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5569 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5570 udp && udp.src==53 && udp.dst==4369"
5571 echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5572
5573 OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5574
5575 OVN_CLEANUP([pbr-hv])
5576 AT_CLEANUP
5577
5578 AT_SETUP([ovn -- policy-based routing IPv6: 1 HVs, 3 LSs, 1 lport/LS, 1 LR])
5579 AT_KEYWORDS([policy-based-routing])
5580 AT_SKIP_IF([test $HAVE_PYTHON = no])
5581 ovn_start
5582
5583 # Logical network:
5584 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5585 # and has switch ls2 (172.16.1.0/24) connected to it.
5586
5587 ovn-nbctl lr-add R1
5588
5589 ovn-nbctl ls-add ls1
5590 ovn-nbctl ls-add ls2
5591 ovn-nbctl ls-add ls3
5592
5593 # Connect ls1 to R1
5594 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 2001::1/64
5595 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5596 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5597
5598 # Connect ls2 to R1
5599 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 2002::1/64
5600 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5601 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5602
5603 # Connect ls3 to R1
5604 ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 2003::1/64
5605 ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5606 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5607
5608 # Create logical port ls1-lp1 in ls1
5609 ovn-nbctl lsp-add ls1 ls1-lp1 \
5610 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 2001::2"
5611
5612 # Create logical port ls2-lp1 in ls2
5613 ovn-nbctl lsp-add ls2 ls2-lp1 \
5614 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 2002::2"
5615
5616 # Create logical port ls3-lp1 in ls3
5617 ovn-nbctl lsp-add ls3 ls3-lp1 \
5618 -- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 2003::2"
5619
5620 # Create one hypervisor and create OVS ports corresponding to logical ports.
5621 net_add n1
5622
5623 sim_add pbr-hv
5624 as pbr-hv
5625 ovs-vsctl add-br br-phys
5626 ovn_attach n1 br-phys 192.168.0.1
5627
5628 ovs-vsctl -- add-port br-int vif1 -- \
5629 set interface vif1 external-ids:iface-id=ls1-lp1 \
5630 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5631 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5632 ofport-request=1
5633
5634 ovs-vsctl -- add-port br-int vif2 -- \
5635 set interface vif2 external-ids:iface-id=ls2-lp1 \
5636 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5637 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5638 ofport-request=1
5639
5640 ovs-vsctl -- add-port br-int vif3 -- \
5641 set interface vif3 external-ids:iface-id=ls3-lp1 \
5642 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5643 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5644 ofport-request=1
5645
5646 # Allow some time for ovn-northd and ovn-controller to catch up.
5647 # XXX This should be more systematic.
5648 sleep 1
5649
5650 ls1_ro_mac=00:00:00:01:02:f1
5651 ls1_ro_ip=2001::1
5652
5653 ls2_ro_mac=00:00:00:01:02:f2
5654 ls2_ro_ip=2002::1
5655
5656 ls3_ro_mac=00:00:00:01:02:f3
5657
5658 ls1_p1_mac=00:00:00:01:02:03
5659 ls1_p1_ip=2001::2
5660
5661 ls2_p1_mac=00:00:00:01:02:04
5662 ls2_p1_ip=2002::2
5663
5664 ls3_p1_mac=00:00:00:01:02:05
5665
5666 # Create a drop policy
5667 ovn-nbctl lr-policy-add R1 10 "ip6.src==2001::/64 && ip6.dst==2002::/64" drop
5668
5669 # Check logical flow
5670 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
5671 1
5672 ])
5673
5674 # Send packet.
5675 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5676 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5677 udp && udp.src==53 && udp.dst==4369"
5678
5679 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5680
5681 # Check if packet hit the drop policy
5682 AT_CHECK([ovs-ofctl dump-flows br-int | \
5683 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64 actions=drop" | \
5684 grep "priority=10" | \
5685 grep "n_packets=1" | wc -l], [0], [dnl
5686 1
5687 ])
5688
5689 # Expected to drop the packet.
5690 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5691 rcvd_packet=`cat vif2.packets`
5692 AT_FAIL_IF([rcvd_packet = ""])
5693
5694 # Override drop policy with allow
5695 ovn-nbctl lr-policy-add R1 20 "ip6.src==2001::/64 && ip6.dst==2002::/64" allow
5696
5697 # Check logical flow
5698 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
5699 2
5700 ])
5701
5702 # Send packet.
5703 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5704 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5705 udp && udp.src==53 && udp.dst==4369"
5706 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5707
5708 # Check if packet hit the allow policy
5709 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5710 grep "2001" | \
5711 grep "priority=20" | wc -l], [0], [dnl
5712 1
5713 ])
5714
5715 # Expected packet has TTL decreased by 1
5716 expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5717 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5718 udp && udp.src==53 && udp.dst==4369"
5719 echo $expected | ovstest test-ovn expr-to-packets > expected
5720
5721 OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5722
5723 # Override allow policy with reroute
5724 ovn-nbctl lr-policy-add R1 30 "ip6.src==2001::/64 && ip6.dst==2002::/64" reroute 2003::2
5725
5726 # Check logical flow
5727 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5728 grep "2001" | \
5729 grep "priority=30" | wc -l], [0], [dnl
5730 1
5731 ])
5732
5733 # Send packet.
5734 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5735 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5736 udp && udp.src==53 && udp.dst==4369"
5737 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5738
5739 echo "southbound flows"
5740
5741 ovn-sbctl dump-flows | grep lr_in_policy
5742 echo "ovs flows"
5743 ovs-ofctl dump-flows br-int
5744 # Check if packet hit the allow policy
5745 AT_CHECK([ovs-ofctl dump-flows br-int | \
5746 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" | \
5747 grep "priority=30" | \
5748 grep "n_packets=1" | wc -l], [0], [dnl
5749 1
5750 ])
5751 echo "packet hit reroute policy"
5752
5753 # Expected packet has TTL decreased by 1
5754 expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5755 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5756 udp && udp.src==53 && udp.dst==4369"
5757 echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5758
5759 OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5760
5761 OVN_CLEANUP([pbr-hv])
5762 AT_CLEANUP
5763
5764 # 1 hypervisor, 1 port
5765 # make sure that the port state is properly set to up and back down
5766 # when created and deleted.
5767 AT_SETUP([ovn -- port state up and down])
5768 ovn_start
5769
5770 ovn-nbctl ls-add ls1
5771 ovn-nbctl lsp-add ls1 lp1
5772 ovn-nbctl lsp-set-addresses lp1 unknown
5773
5774 net_add n1
5775 sim_add hv1
5776 as hv1 ovs-vsctl add-br br-phys
5777 as hv1 ovn_attach n1 br-phys 192.168.0.1
5778
5779 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5780 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5781
5782 as hv1 ovs-vsctl del-port br-int vif1
5783 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5784
5785 OVN_CLEANUP([hv1])
5786
5787 AT_CLEANUP
5788
5789 # 1 hypervisor, 1 port
5790 # make sure that the OF rules created to support a datapath are added/cleared
5791 # when logical switch is created and removed.
5792 AT_SETUP([ovn -- datapath rules added/removed])
5793 AT_KEYWORDS([cleanup])
5794 ovn_start
5795
5796 net_add n1
5797 sim_add hv1
5798 as hv1 ovs-vsctl add-br br-phys
5799 as hv1 ovn_attach n1 br-phys 192.168.0.1
5800
5801 # This shell function checks if OF rules in br-int have clauses
5802 # related to OVN datapaths. The caller determines if it should find
5803 # a match in the output, or not.
5804 #
5805 # EXPECT_DATAPATH param determines whether flows that refer to
5806 # datapath to should be present or not. 0 means
5807 # they should not be.
5808 # STAGE_INFO param is a simple string to help identify the stage
5809 # in the test when this function was invoked.
5810 test_datapath_in_of_rules() {
5811 local expect_datapath=$1 stage_info=$2
5812 echo "------ ovn-nbctl show ${stage_info} ------"
5813 ovn-nbctl show
5814 echo "------ ovn-sbctl show ${stage_info} ------"
5815 ovn-sbctl show
5816 echo "------ OF rules ${stage_info} ------"
5817 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5818 # if there is a datapath mentioned in the output, check for the
5819 # magic keyword that represents one, based on the exit status of
5820 # a quiet grep
5821 if test $expect_datapath != 0; then
5822 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
5823 else
5824 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
5825 fi
5826 }
5827
5828 test_datapath_in_of_rules 0 "before ls+port create"
5829
5830 ovn-nbctl ls-add ls1
5831 ovn-nbctl lsp-add ls1 lp1
5832 ovn-nbctl lsp-set-addresses lp1 unknown
5833
5834 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5835 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5836
5837 test_datapath_in_of_rules 1 "after port is bound"
5838
5839 as hv1 ovs-vsctl del-port br-int vif1
5840 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5841
5842 ovn-nbctl lsp-set-addresses lp1
5843 ovn-nbctl lsp-del lp1
5844 ovn-nbctl ls-del ls1
5845
5846 # wait for earlier changes to take effect
5847 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5848
5849 # ensure OF rules are no longer present. There used to be a bug here.
5850 test_datapath_in_of_rules 0 "after lport+ls removal"
5851
5852 OVN_CLEANUP([hv1])
5853
5854 AT_CLEANUP
5855
5856 AT_SETUP([ovn -- nd_na ])
5857 AT_SKIP_IF([test $HAVE_PYTHON = no])
5858 ovn_start
5859
5860 #TODO: since patch port for IPv6 logical router port is not ready not,
5861 # so we are not going to test vifs on different lswitches cases. Try
5862 # to update for that once relevant stuff implemented.
5863
5864 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
5865 # with. NS packet we test, from one VIF for another VIF, will be replied
5866 # by local ovn-controller, but not by target VIF.
5867
5868 # Create hypervisors and logical switch lsw0.
5869 ovn-nbctl ls-add lsw0
5870 net_add n1
5871 sim_add hv1
5872 as hv1
5873 ovs-vsctl add-br br-phys
5874 ovn_attach n1 br-phys 192.168.0.2
5875
5876 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5877 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=hv1/vif1-tx.pcap options:rxq_pcap=hv1/vif1-rx.pcap ofport-request=1
5878 ovn-nbctl lsp-add lsw0 lp1
5879 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5880 ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5881
5882 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5883 ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=hv1/vif2-tx.pcap options:rxq_pcap=hv1/vif2-rx.pcap ofport-request=2
5884 ovn-nbctl lsp-add lsw0 lp2
5885 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5886 ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5887
5888 # Add ACL rule for ICMPv6 on lsw0
5889 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5890 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5891 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5892
5893 # Allow some time for ovn-northd and ovn-controller to catch up.
5894 # XXX This should be more systematic.
5895 sleep 1
5896
5897 # Given the name of a logical port, prints the name of the hypervisor
5898 # on which it is located.
5899 vif_to_hv() {
5900 echo hv1${1%?}
5901 }
5902 for i in 1 2; do
5903 : > $i.expected
5904 done
5905
5906 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5907 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5908 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5909 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5910 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5911
5912 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5913 echo $na_packet >> 1.expected
5914
5915 echo "------ hv1 dump ------"
5916 as hv1 ovs-vsctl show
5917 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5918 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5919
5920 for i in 1 2; do
5921 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5922 done
5923
5924 OVN_CLEANUP([hv1])
5925
5926 AT_CLEANUP
5927
5928 AT_SETUP([ovn -- address sets modification/removal smoke test])
5929 ovn_start
5930
5931 net_add n1
5932
5933 sim_add hv1
5934 as hv1
5935 ovs-vsctl add-br br-phys
5936 ovn_attach n1 br-phys 192.168.0.1
5937
5938 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5939 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5940 ovn-nbctl destroy Address_Set $row
5941
5942 sleep 1
5943
5944 # A bug previously existed in the address set support code
5945 # that caused ovn-controller to crash after an address set
5946 # was updated and then removed. This test case ensures
5947 # that ovn-controller is at least still running after
5948 # creating, updating, and deleting an address set.
5949 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5950
5951 OVN_CLEANUP([hv1])
5952
5953 AT_CLEANUP
5954
5955 AT_SETUP([ovn -- ipam])
5956 AT_SKIP_IF([test $HAVE_PYTHON = no])
5957 ovn_start
5958
5959 # Add a port to a switch that does not have a subnet set, then set the
5960 # subnet which should result in an address being allocated for the port.
5961 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
5962 ovn-nbctl ls-add sw0
5963 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5964 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5965 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5966 ["0a:00:00:a8:01:03 192.168.1.2"
5967 ])
5968
5969 # Add 9 more ports to sw0, addresses should all be unique.
5970 for n in `seq 1 9`; do
5971 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5972 done
5973 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5974 ["0a:00:00:a8:01:04 192.168.1.3"
5975 ])
5976 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5977 ["0a:00:00:a8:01:05 192.168.1.4"
5978 ])
5979 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5980 ["0a:00:00:a8:01:06 192.168.1.5"
5981 ])
5982 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5983 ["0a:00:00:a8:01:07 192.168.1.6"
5984 ])
5985 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5986 ["0a:00:00:a8:01:08 192.168.1.7"
5987 ])
5988 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5989 ["0a:00:00:a8:01:09 192.168.1.8"
5990 ])
5991 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5992 ["0a:00:00:a8:01:0a 192.168.1.9"
5993 ])
5994 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5995 ["0a:00:00:a8:01:0b 192.168.1.10"
5996 ])
5997 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5998 ["0a:00:00:a8:01:0c 192.168.1.11"
5999 ])
6000
6001 # Trying similar tests with a second switch. MAC addresses should be unique
6002 # across both switches but IP's only need to be unique within the same switch.
6003 ovn-nbctl ls-add sw1
6004 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
6005 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
6006 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
6007 ["0a:00:00:a8:01:0d 192.168.1.2"
6008 ])
6009
6010 for n in `seq 11 19`; do
6011 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
6012 done
6013 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
6014 ["0a:00:00:a8:01:0e 192.168.1.3"
6015 ])
6016 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
6017 ["0a:00:00:a8:01:0f 192.168.1.4"
6018 ])
6019 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
6020 ["0a:00:00:a8:01:10 192.168.1.5"
6021 ])
6022 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
6023 ["0a:00:00:a8:01:11 192.168.1.6"
6024 ])
6025 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
6026 ["0a:00:00:a8:01:12 192.168.1.7"
6027 ])
6028 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
6029 ["0a:00:00:a8:01:13 192.168.1.8"
6030 ])
6031 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
6032 ["0a:00:00:a8:01:14 192.168.1.9"
6033 ])
6034 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
6035 ["0a:00:00:a8:01:15 192.168.1.10"
6036 ])
6037 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
6038 ["0a:00:00:a8:01:16 192.168.1.11"
6039 ])
6040
6041 # Change a port's address to test for multiple ip's for a single address entry
6042 # and addresses set by the user.
6043 ovn-nbctl lsp-set-addresses p0 "0a:00:00:a8:01:17 192.168.1.2 192.168.1.12 192.168.1.14"
6044 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
6045 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
6046 ["0a:00:00:a8:01:18 192.168.1.13"
6047 ])
6048
6049 # Test for logical router port address management.
6050 ovn-nbctl create Logical_Router name=R1
6051 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
6052 network="192.168.1.1/24" mac=\"0a:00:00:a8:01:19\" \
6053 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
6054 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
6055 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
6056 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
6057 ["0a:00:00:a8:01:1a 192.168.1.15"
6058 ])
6059
6060 # Test for address reuse after logical port is deleted.
6061 ovn-nbctl lsp-del p0
6062 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
6063 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
6064 ["0a:00:00:a8:01:03 192.168.1.2"
6065 ])
6066
6067 # Test for multiple addresses to one logical port.
6068 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
6069 "0a:00:00:a8:01:1b 192.168.1.12" "0a:00:00:a8:01:1c 192.168.1.14"
6070 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
6071 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
6072 ["0a:00:00:a8:01:17 192.168.1.16"
6073 ])
6074
6075 # Test for exhausting subnet address space.
6076 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
6077 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
6078 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
6079 ["0a:00:00:10:01:03 172.16.1.2"
6080 ])
6081
6082 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
6083 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
6084 ["0a:00:00:00:00:01"
6085 ])
6086
6087 # Test that address management does not add duplicate MAC for lsp/lrp peers.
6088 ovn-nbctl create Logical_Router name=R2
6089 ovn-nbctl ls-add sw3
6090 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
6091 "0a:00:00:a8:01:18"
6092 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
6093 network="192.168.2.1/24" mac=\"0a:00:00:a8:01:18\" \
6094 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
6095 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
6096 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
6097 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
6098 ["0a:00:00:a8:01:1d 192.168.1.17"
6099 ])
6100
6101 # Test static MAC address with dynamically allocated IP
6102 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
6103 "fe:dc:ba:98:76:54 dynamic"
6104 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6105 ["fe:dc:ba:98:76:54 192.168.1.18"
6106 ])
6107
6108 # Update the static MAC address with dynamically allocated IP and check
6109 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
6110 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6111
6112 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6113 ["fe:dc:ba:98:76:55 192.168.1.18"
6114 ])
6115
6116 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
6117 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6118 ["0a:00:00:a8:01:1e 192.168.1.18"
6119 ])
6120
6121 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
6122 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6123 ["fe:dc:ba:98:76:56 192.168.1.18"
6124 ])
6125
6126
6127 # Test the exclude_ips from the IPAM list
6128 ovn-nbctl --wait=sb set logical_switch sw0 \
6129 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
6130
6131 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
6132 "dynamic"
6133 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
6134 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
6135 ["0a:00:00:a8:01:1e 192.168.1.20"
6136 ])
6137
6138 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
6139 "dynamic"
6140 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
6141 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
6142 ["0a:00:00:a8:01:1f 192.168.1.22"
6143 ])
6144
6145 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
6146 "dynamic"
6147 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
6148 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
6149 ["0a:00:00:a8:01:34 192.168.1.51"
6150 ])
6151
6152 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
6153 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
6154 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
6155 "dynamic"
6156 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
6157 ["0a:00:00:a8:01:20 192.168.1.19"
6158 ])
6159
6160 # Set invalid data in exclude_ips list. It should be ignored.
6161 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
6162 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
6163 "dynamic"
6164 # 192.168.1.21 should be assigned as that's the next free one.
6165 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6166 ["0a:00:00:a8:01:21 192.168.1.21"
6167 ])
6168
6169 # Clear the dynamic addresses assignment request.
6170 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
6171 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6172 [[[]]
6173 ])
6174
6175 # Set IPv6 prefix
6176 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
6177 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
6178 "dynamic"
6179
6180 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
6181 # - aef0::800:ff:fe00:26 (EUI64)
6182 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
6183 ["0a:00:00:a8:01:21 192.168.1.21 aef0::800:ff:fea8:121"
6184 ])
6185
6186 ovn-nbctl --wait=sb ls-add sw4
6187 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
6188 -- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
6189 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
6190 "dynamic"
6191
6192 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
6193 ["0a:00:00:a8:02:03 192.168.2.2 bef0::800:ff:fea8:203"
6194 ])
6195
6196 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
6197 "f0:00:00:00:10:12 dynamic"
6198
6199 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
6200 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
6201 ])
6202
6203 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
6204 # p40 should not have an IPv4 address since the pool is exhausted
6205 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
6206 "dynamic"
6207 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
6208 ["0a:00:00:00:00:02 bef0::800:ff:fe00:2"
6209 ])
6210
6211 # Test dynamic changes on switch ports.
6212 #
6213 ovn-nbctl --wait=sb ls-add sw5
6214 ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
6215 "dynamic"
6216 # p41 will start with nothing
6217 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6218 [[[]]
6219 ])
6220
6221 # Set a subnet. Now p41 should have an ipv4 address, too
6222 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6223 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6224 ["0a:00:00:a8:01:22 192.168.1.2"
6225 ])
6226
6227 # Clear the other_config. The IPv4 address should be gone
6228 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6229 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6230 [[[]]
6231 ])
6232
6233 # Set an IPv6 prefix. Now p41 should have an IPv6 address.
6234 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
6235 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6236 ["0a:00:00:00:00:03 aef0::800:ff:fe00:3"
6237 ])
6238
6239 # Change the MAC address to a static one. The IPv6 address should update.
6240 ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
6241 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6242 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
6243 ])
6244
6245 # Change the IPv6 prefix. The IPv6 address should update.
6246 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
6247 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6248 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
6249 ])
6250
6251 # Clear the other_config. The IPv6 address should be gone
6252 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6253 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6254 [[[]]
6255 ])
6256
6257 # Set the subnet again. Now p41 should get the IPv4 address again.
6258 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6259 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6260 ["f0:00:00:00:10:2b 192.168.1.2"
6261 ])
6262
6263 # Add an excluded IP address that conflicts with p41. p41 should update.
6264 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
6265 exclude_ips="192.168.1.2"
6266 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6267 ["f0:00:00:00:10:2b 192.168.1.3"
6268 ])
6269
6270 # Add static ip address
6271 ovn-nbctl --wait=sb lsp-set-addresses p41 "dynamic 192.168.1.100"
6272 ovn-nbctl list Logical-Switch-Port p41
6273 ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
6274 "dynamic 192.168.1.101"
6275 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6276 ["0a:00:00:a8:01:65 192.168.1.100"
6277 ])
6278 AT_CHECK([ovn-nbctl get Logical-Switch-Port p42 dynamic_addresses], [0],
6279 ["0a:00:00:a8:01:66 192.168.1.101"
6280 ])
6281
6282 # define a mac address prefix
6283 ovn-nbctl ls-add sw6
6284 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
6285 ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
6286 for n in $(seq 1 3); do
6287 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
6288 done
6289 AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
6290 ["00:11:22:a8:64:03 192.168.100.2"
6291 ])
6292 AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
6293 ["00:11:22:a8:64:04 192.168.100.3"
6294 ])
6295 AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
6296 ["00:11:22:a8:64:05 192.168.100.4"
6297 ])
6298
6299 # verify configuration order does not break IPAM/MACAM
6300 ovn-nbctl ls-add sw7
6301 for n in $(seq 1 3); do
6302 ovn-nbctl --wait=sb lsp-add sw7 "p7$n" -- lsp-set-addresses "p7$n" dynamic
6303 done
6304 ovn-nbctl --wait=sb set Logical-Switch sw7 other_config:ipv6_prefix="bef0::"
6305 p71_addr=$(ovn-nbctl get Logical-Switch-Port p71 dynamic_addresses)
6306 p72_addr=$(ovn-nbctl get Logical-Switch-Port p72 dynamic_addresses)
6307 p73_addr=$(ovn-nbctl get Logical-Switch-Port p73 dynamic_addresses)
6308 AT_CHECK([test "$p71_addr" != "$p72_addr"], [0], [])
6309 AT_CHECK([test "$p71_addr" != "$p73_addr"], [0], [])
6310 AT_CHECK([test "$p72_addr" != "$p73_addr"], [0], [])
6311
6312 # request to assign mac only
6313 #
6314 ovn-nbctl ls-add sw8
6315 ovn-nbctl --wait=sb set Logical-Switch sw8 other_config:mac_only=true
6316 for n in $(seq 1 3); do
6317 ovn-nbctl --wait=sb lsp-add sw8 "p8$n" -- lsp-set-addresses "p8$n" dynamic
6318 done
6319 AT_CHECK([ovn-nbctl get Logical-Switch-Port p81 dynamic_addresses], [0],
6320 ["00:11:22:00:00:06"
6321 ])
6322 AT_CHECK([ovn-nbctl get Logical-Switch-Port p82 dynamic_addresses], [0],
6323 ["00:11:22:00:00:07"
6324 ])
6325 AT_CHECK([ovn-nbctl get Logical-Switch-Port p83 dynamic_addresses], [0],
6326 ["00:11:22:00:00:08"
6327 ])
6328
6329 # clear mac_prefix and check it is allocated in a random manner
6330 ovn-nbctl --wait=hv remove NB_Global . options mac_prefix
6331 ovn-nbctl ls-add sw9
6332 ovn-nbctl --wait=sb set Logical-Switch sw9 other_config:mac_only=true
6333 ovn-nbctl --wait=sb lsp-add sw9 p91 -- lsp-set-addresses p91 dynamic
6334
6335 mac_prefix=$(ovn-nbctl --wait=sb get NB_Global . options:mac_prefix | tr -d \")
6336 port_addr=$(ovn-nbctl get Logical-Switch-Port p91 dynamic_addresses | tr -d \")
6337 AT_CHECK([test "$port_addr" = "${mac_prefix}:00:00:09"], [0], [])
6338
6339 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22"
6340 ovn-nbctl ls-add sw10
6341 ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:ipv6_prefix="ae01::"
6342 ovn-nbctl --wait=sb lsp-add sw10 p101 -- lsp-set-addresses p101 "dynamic ae01::1"
6343 AT_CHECK([ovn-nbctl get Logical-Switch-Port p101 dynamic_addresses], [0],
6344 ["00:11:22:00:00:0a ae01::1"
6345 ])
6346
6347 ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:subnet=192.168.110.0/24
6348 ovn-nbctl --wait=sb lsp-add sw10 p102 -- lsp-set-addresses p102 "dynamic 192.168.110.10 ae01::2"
6349 AT_CHECK([ovn-nbctl get Logical-Switch-Port p102 dynamic_addresses], [0],
6350 ["00:11:22:a8:6e:0b 192.168.110.10 ae01::2"
6351 ])
6352
6353 as ovn-sb
6354 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6355
6356 as ovn-nb
6357 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6358
6359 as northd
6360 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6361
6362 as northd-backup
6363 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6364
6365 AT_CLEANUP
6366
6367 AT_SETUP([ovn -- ipam connectivity])
6368 AT_SKIP_IF([test $HAVE_PYTHON = no])
6369 ovn_start
6370
6371 ovn-nbctl lr-add R1
6372
6373 # Test for a ping using dynamically allocated addresses.
6374 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
6375 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
6376 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
6377
6378 # Connect foo to R1
6379 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6380 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6381 options:router-port=foo \
6382 -- lsp-set-addresses rp-foo router
6383
6384 # Connect alice to R1
6385 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
6386 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
6387 options:router-port=alice addresses=\"00:00:00:01:02:04\"
6388
6389 # Create logical port foo1 in foo
6390 ovn-nbctl --wait=sb lsp-add foo foo1 \
6391 -- lsp-set-addresses foo1 "dynamic"
6392 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:a8:01:03 192.168.1.2"'], [0])
6393
6394 # Create logical port alice1 in alice
6395 ovn-nbctl --wait=sb lsp-add alice alice1 \
6396 -- lsp-set-addresses alice1 "dynamic"
6397 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:a8:02:03 192.168.2.2"'])
6398
6399 # Create logical port foo2 in foo
6400 ovn-nbctl --wait=sb lsp-add foo foo2 \
6401 -- lsp-set-addresses foo2 "dynamic"
6402 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:a8:01:04 192.168.1.3"'])
6403
6404 # Create a hypervisor and create OVS ports corresponding to logical ports.
6405 net_add n1
6406
6407 sim_add hv1
6408 as hv1
6409 ovs-vsctl add-br br-phys
6410 ovn_attach n1 br-phys 192.168.0.1
6411 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6412 set interface hv1-vif1 external-ids:iface-id=foo1 \
6413 options:tx_pcap=hv1/vif1-tx.pcap \
6414 options:rxq_pcap=hv1/vif1-rx.pcap \
6415 ofport-request=1
6416
6417 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6418 set interface hv1-vif2 external-ids:iface-id=foo2 \
6419 options:tx_pcap=hv1/vif2-tx.pcap \
6420 options:rxq_pcap=hv1/vif2-rx.pcap \
6421 ofport-request=2
6422
6423 ovs-vsctl -- add-port br-int hv1-vif3 -- \
6424 set interface hv1-vif3 external-ids:iface-id=alice1 \
6425 options:tx_pcap=hv1/vif3-tx.pcap \
6426 options:rxq_pcap=hv1/vif3-rx.pcap \
6427 ofport-request=3
6428
6429 # Allow some time for ovn-northd and ovn-controller to catch up.
6430 # XXX This should be more systematic.
6431 sleep 1
6432
6433 ip_to_hex() {
6434 printf "%02x%02x%02x%02x" "$@"
6435 }
6436
6437 # Send ip packets between foo1 and foo2
6438 src_mac="0a0000a80103"
6439 dst_mac="0a0000a80104"
6440 src_ip=`ip_to_hex 192 168 1 2`
6441 dst_ip=`ip_to_hex 192 168 1 3`
6442 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6443 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6444
6445 # Send ip packets between foo1 and alice1
6446 src_mac="0a0000a80103"
6447 dst_mac="000000010203"
6448 src_ip=`ip_to_hex 192 168 1 2`
6449 dst_ip=`ip_to_hex 192 168 2 2`
6450 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6451 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6452
6453 echo "---------NB dump-----"
6454 ovn-nbctl show
6455 echo "---------------------"
6456 ovn-nbctl list logical_router
6457 echo "---------------------"
6458 ovn-nbctl list logical_router_port
6459 echo "---------------------"
6460
6461 echo "---------SB dump-----"
6462 ovn-sbctl list datapath_binding
6463 echo "---------------------"
6464 ovn-sbctl list port_binding
6465 echo "---------------------"
6466
6467 echo "------ hv1 dump ----------"
6468 as hv1 ovs-ofctl dump-flows br-int
6469
6470 # Packet to Expect at foo2
6471 src_mac="0a0000a80103"
6472 dst_mac="0a0000a80104"
6473 src_ip=`ip_to_hex 192 168 1 2`
6474 dst_ip=`ip_to_hex 192 168 1 3`
6475 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6476
6477 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
6478 echo $expected > expout
6479 AT_CHECK([cat received1.packets], [0], [expout])
6480
6481 # Packet to Expect at alice1
6482 src_mac="000000010204"
6483 dst_mac="0a0000a80203"
6484 src_ip=`ip_to_hex 192 168 1 2`
6485 dst_ip=`ip_to_hex 192 168 2 2`
6486 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6487
6488 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
6489 echo $expected > expout
6490 AT_CHECK([cat received2.packets], [0], [expout])
6491
6492 OVN_CLEANUP([hv1])
6493
6494 AT_CLEANUP
6495
6496 AT_SETUP([ovn -- ovs-vswitchd restart])
6497 AT_KEYWORDS([vswitchd])
6498 AT_SKIP_IF([test $HAVE_PYTHON = no])
6499 ovn_start
6500
6501 ovn-nbctl ls-add ls1
6502
6503 ovn-nbctl lsp-add ls1 ls1-lp1 \
6504 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6505
6506 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6507
6508 net_add n1
6509 sim_add hv1
6510
6511 as hv1
6512 ovs-vsctl add-br br-phys
6513 ovn_attach n1 br-phys 192.168.0.1
6514 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6515 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6516 options:tx_pcap=hv1/vif1-tx.pcap \
6517 options:rxq_pcap=hv1/vif1-rx.pcap \
6518 ofport-request=1
6519
6520 OVN_POPULATE_ARP
6521 sleep 2
6522
6523 as hv1 ovs-vsctl show
6524
6525 echo "---------------------"
6526 ovn-sbctl dump-flows
6527 echo "---------------------"
6528
6529 echo "------ hv1 dump ----------"
6530 as hv1 ovs-ofctl dump-flows br-int
6531 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6532
6533 echo "Total flows before vswitchd restart = " $total_flows
6534
6535 # Code taken from ovs-save utility
6536 save_flows () {
6537 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
6538 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
6539 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
6540 echo "EOF" >> restore_flows.sh
6541 }
6542
6543 restart_vswitchd () {
6544 restore_flows=$1
6545
6546 if test $restore_flows = true; then
6547 save_flows
6548 fi
6549
6550 as hv1
6551 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6552
6553 if test $restore_flows = true; then
6554 as hv1
6555 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
6556 fi
6557
6558 as hv1
6559 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
6560 ovs-ofctl dump-flows br-int
6561
6562 if test $restore_flows = true; then
6563 sh ./restore_flows.sh
6564 echo "Flows after restore"
6565 as hv1
6566 ovs-ofctl dump-flows br-int
6567 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
6568 flow-restore-wait="true"
6569 fi
6570 }
6571
6572 # Save the flows, restart vswitchd and restore the flows
6573 restart_vswitchd true
6574 OVS_WAIT_UNTIL([
6575 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6576 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6577 test "${total_flows}" = "${total_flows_after_restart}"
6578 ])
6579
6580 # Restart vswitchd without restoring
6581 restart_vswitchd false
6582 OVS_WAIT_UNTIL([
6583 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6584 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6585 test "${total_flows}" = "${total_flows_after_restart}"
6586 ])
6587
6588 OVN_CLEANUP([hv1])
6589 AT_CLEANUP
6590
6591 AT_SETUP([ovn -- send arp for nexthop])
6592 AT_SKIP_IF([test $HAVE_PYTHON = no])
6593 ovn_start
6594
6595 # Topology: Two LSs - ls1 and ls2 are connected via router r0
6596
6597 # Create logical switches
6598 ovn-nbctl ls-add ls1
6599 ovn-nbctl ls-add ls2
6600
6601 # Create router
6602 ovn-nbctl create Logical_Router name=lr0
6603
6604 # Add router ls1p1 port to gateway router
6605 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
6606 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
6607 type=router options:router-port=lrp-ls1lp1 \
6608 addresses='"f0:00:00:00:00:01 192.168.0.1"'
6609
6610 # Add router ls2p2 port to gateway router
6611 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
6612 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
6613 type=router options:router-port=lrp-ls2lp1 \
6614 addresses='"f0:00:00:00:00:02 192.168.1.1"'
6615
6616 # Set default gateway (nexthop) to 192.168.1.254
6617 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
6618
6619 # Create logical port ls1lp2 in ls1
6620 ovn-nbctl lsp-add ls1 ls1lp2 \
6621 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
6622
6623 # Create logical port ls2lp2 in ls2
6624 ovn-nbctl lsp-add ls2 ls2lp2 \
6625 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
6626
6627 net_add n1
6628 sim_add hv1
6629 as hv1
6630 ovs-vsctl add-br br-phys
6631 ovn_attach n1 br-phys 192.168.0.1
6632 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
6633 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
6634 options:tx_pcap=hv1/ls1lp2-tx.pcap \
6635 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
6636 ofport-request=1
6637 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
6638 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
6639 options:tx_pcap=hv1/ls2lp2-tx.pcap \
6640 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
6641 ofport-request=2
6642
6643 # Allow some time for ovn-northd and ovn-controller to catch up.
6644 # XXX This should be more systematic.
6645 sleep 1
6646
6647 echo "---------NB dump-----"
6648 ovn-nbctl show
6649 echo "---------------------"
6650 ovn-nbctl list logical_router
6651 echo "---------------------"
6652 ovn-nbctl list logical_router_port
6653 echo "---------------------"
6654
6655 echo "---------SB dump-----"
6656 ovn-sbctl list datapath_binding
6657 echo "---------------------"
6658 ovn-sbctl list port_binding
6659 echo "---------------------"
6660 ovn-sbctl dump-flows
6661 echo "---------------------"
6662 ovn-sbctl list chassis
6663 ovn-sbctl list encap
6664 echo "---------------------"
6665
6666 echo "------Flows dump-----"
6667 as hv1
6668 ovs-ofctl dump-flows
6669 echo "---------------------"
6670
6671 ip_to_hex() {
6672 printf "%02x%02x%02x%02x" "$@"
6673 }
6674
6675 src_mac="f00000000003"
6676 dst_mac="f00000000001"
6677 src_ip=`ip_to_hex 192 168 0 2`
6678 dst_ip=`ip_to_hex 8 8 8 8`
6679 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6680
6681 # Send IP packet destined to 8.8.8.8 from lsp1lp2
6682 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
6683
6684 trim_zeros() {
6685 sed 's/\(00\)\{1,\}$//'
6686 }
6687
6688 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
6689 # not 8.8.8.8
6690
6691 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
6692 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
6693 echo $expected > expout
6694 AT_CHECK([cat packets], [0], [expout])
6695 cat packets
6696
6697 OVN_CLEANUP([hv1])
6698
6699 AT_CLEANUP
6700
6701 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
6702 AT_SKIP_IF([test $HAVE_PYTHON = no])
6703 ovn_start
6704 # Create logical switch
6705 ovn-nbctl ls-add ls0
6706 # Create gateway router
6707 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6708 # Add router port to gateway router
6709 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6710 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6711 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6712 # Add nat-address option
6713 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6714
6715 net_add n1
6716 sim_add hv1
6717 as hv1
6718 ovs-vsctl \
6719 -- add-br br-phys \
6720 -- add-br br-eth0
6721
6722 ovn_attach n1 br-phys 192.168.0.1
6723
6724 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6725 AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
6726
6727 # Create a localnet port.
6728 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6729 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6730 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6731 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6732
6733
6734 # Wait for packet to be received.
6735 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6736 trim_zeros() {
6737 sed 's/\(00\)\{1,\}$//'
6738 }
6739 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6740 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6741 echo $expected > expout
6742 AT_CHECK([sort packets], [0], [expout])
6743 cat packets
6744
6745 OVN_CLEANUP([hv1])
6746
6747 AT_CLEANUP
6748
6749 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6750 AT_SKIP_IF([test $HAVE_PYTHON = no])
6751 ovn_start
6752 # Create logical switch
6753 ovn-nbctl ls-add ls0
6754 # Create gateway router
6755 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6756 # Add router port to gateway router
6757 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6758 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6759 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6760 # Add nat-address option
6761 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6762 # Add NAT rules
6763 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6764 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6765 # Add load balancers
6766 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6767 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6768 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6769 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6770
6771 net_add n1
6772 sim_add hv1
6773 as hv1
6774 ovs-vsctl \
6775 -- add-br br-phys \
6776 -- add-br br-eth0
6777
6778 ovn_attach n1 br-phys 192.168.0.1
6779
6780 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6781 AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
6782
6783 # Create a localnet port.
6784 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6785 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6786 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6787 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6788
6789
6790 # Wait for packet to be received.
6791 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6792 trim_zeros() {
6793 sed 's/\(00\)\{1,\}$//'
6794 }
6795 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6796 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6797 echo $expected > expout
6798 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6799 echo $expected >> expout
6800 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6801 echo $expected >> expout
6802 AT_CHECK([sort packets], [0], [expout])
6803 cat packets
6804
6805 OVN_CLEANUP([hv1])
6806
6807 AT_CLEANUP
6808
6809 AT_SETUP([ovn -- delete mac bindings])
6810 ovn_start
6811 net_add n1
6812 sim_add hv1
6813 as hv1
6814 ovs-vsctl -- add-br br-phys
6815 ovn_attach n1 br-phys 192.168.0.1
6816 # Create logical switch ls0
6817 ovn-nbctl ls-add ls0
6818 # Create ports lp0, lp1 in ls0
6819 ovn-nbctl lsp-add ls0 lp0
6820 ovn-nbctl lsp-add ls0 lp1
6821 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6822 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6823 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6824 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6825 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6826 ovn-sbctl find MAC_Binding
6827 # Delete port lp0 and check that its MAC_Binding is deleted.
6828 ovn-nbctl lsp-del lp0
6829 ovn-sbctl find MAC_Binding
6830 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6831 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
6832 ovn-nbctl ls-del ls0
6833 ovn-sbctl find MAC_Binding
6834 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6835
6836 OVN_CLEANUP([hv1])
6837
6838 AT_CLEANUP
6839
6840 AT_SETUP([ovn -- conntrack zone allocation])
6841 AT_SKIP_IF([test $HAVE_PYTHON = no])
6842 ovn_start
6843
6844 # Logical network:
6845 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6846 # connected to a router R1.
6847 # foo has foo1 to act as a client.
6848 # bar has bar1, bar2, bar3 to act as servers.
6849
6850 net_add n1
6851
6852 sim_add hv1
6853 as hv1
6854 ovs-vsctl add-br br-phys
6855 ovn_attach n1 br-phys 192.168.0.1
6856 for i in foo1 bar1 bar2 bar3; do
6857 ovs-vsctl -- add-port br-int $i -- \
6858 set interface $i external-ids:iface-id=$i \
6859 options:tx_pcap=hv1/$i-tx.pcap \
6860 options:rxq_pcap=hv1/$i-rx.pcap
6861 done
6862
6863 ovn-nbctl create Logical_Router name=R1
6864 ovn-nbctl ls-add foo
6865 ovn-nbctl ls-add bar
6866
6867 # Connect foo to R1
6868 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6869 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6870 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6871
6872 # Connect bar to R1
6873 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6874 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6875 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6876
6877 # Create logical port foo1 in foo
6878 ovn-nbctl lsp-add foo foo1 \
6879 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6880
6881 # Create logical port bar1, bar2 and bar3 in bar
6882 for i in `seq 1 3`; do
6883 ip=`expr $i + 1`
6884 ovn-nbctl lsp-add bar bar$i \
6885 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6886 done
6887
6888 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6889
6890 OVN_CLEANUP([hv1])
6891
6892 AT_CLEANUP
6893
6894 AT_SETUP([ovn -- tag allocation])
6895 ovn_start
6896
6897 AT_CHECK([ovn-nbctl ls-add ls0])
6898 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6899 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6900 AT_CHECK([ovn-nbctl ls-add ls1])
6901
6902 dnl When a tag is provided, no allocation is done
6903 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6904 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6905 ])
6906 dnl The same 'tag' gets created in southbound database.
6907 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6908 logical_port="c0"], [0], [3
6909 ])
6910
6911 dnl Allocate tags and see it getting created in both NB and SB
6912 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6913 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6914 ])
6915 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6916 logical_port="c1"], [0], [1
6917 ])
6918
6919 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6920 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6921 ])
6922 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6923 logical_port="c2"], [0], [2
6924 ])
6925 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6926 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6927 ])
6928 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6929 logical_port="c3"], [0], [4
6930 ])
6931
6932 dnl A different parent.
6933 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6934 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6935 ])
6936 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6937 logical_port="c4"], [0], [1
6938 ])
6939
6940 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6941 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6942 ])
6943 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6944 logical_port="c5"], [0], [2
6945 ])
6946
6947 dnl Delete a logical port and create a new one.
6948 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6949 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6950 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6951 ])
6952 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6953 logical_port="c6"], [0], [1
6954 ])
6955
6956 dnl Restart northd to see that the same allocation remains.
6957 as northd
6958 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6959 start_daemon ovn-northd \
6960 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6961 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6962
6963 dnl Create a switch to make sure that ovn-northd has run through the main loop.
6964 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6965 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6966 ])
6967 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6968 ])
6969 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6970 ])
6971 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6972 ])
6973 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6974 ])
6975 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6976 ])
6977
6978 dnl Create a switch port with a tag that has already been allocated.
6979 dnl It should go through fine with a duplicate tag.
6980 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6981 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6982 ])
6983 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6984 logical_port="c7"], [0], [2
6985 ])
6986 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6987 ])
6988
6989 AT_CHECK([ovn-nbctl ls-add ls2])
6990 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6991 dnl gets copied to 'tag'
6992 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6993 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6994 ])
6995 dnl The same 'tag' gets created in southbound database.
6996 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6997 logical_port="local0"], [0], [25
6998 ])
6999 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
7000 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
7001 AT_CHECK([ovn-nbctl lsp-get-tag local1])
7002 dnl change the tag_request.
7003 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
7004 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
7005 ])
7006
7007 AT_CLEANUP
7008
7009 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
7010 ovn_start
7011 ovn-nbctl ls-add lsw0
7012 net_add n1
7013 for i in 1 2; do
7014 sim_add hv$i
7015 as hv$i
7016 ovs-vsctl add-br br-phys
7017 ovn_attach n1 br-phys 192.168.0.$i
7018 ovs-vsctl add-br br-eth0
7019 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
7020 done
7021
7022 # Create a localnet port.
7023 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
7024 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7025 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7026 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7027
7028
7029 # Create 3 vifs.
7030 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
7031 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
7032 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
7033 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
7034 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
7035 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
7036 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
7037 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
7038 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
7039
7040 # Bind the localvif1 to hv1.
7041 as hv1
7042 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
7043
7044 # On hv1, check that there are no flows outputting bcast to tunnel
7045 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7046
7047 # On hv2, check that no flow outputs bcast to tunnel to hv1.
7048 as hv2
7049 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7050
7051 # Now bind vif2 on hv2.
7052 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
7053
7054 # At this point, the broadcast flow on vif2 should be deleted.
7055 # because, there is now a localnet vif bound (table=32 programming logic)
7056 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7057
7058 # Verify that the local net patch port exists on hv2.
7059 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7060
7061 # Now bind vif3 on hv2.
7062 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
7063
7064 # Verify that the local net patch port still exists on hv2
7065 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7066
7067 # Delete localvif2
7068 AT_CHECK([ovn-nbctl lsp-del localvif2])
7069
7070 # Verify that the local net patch port still exists on hv2,
7071 # because, localvif3 is still bound.
7072 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7073
7074 OVN_CLEANUP([hv1],[hv2])
7075
7076 AT_CLEANUP
7077
7078
7079 AT_SETUP([ovn -- ACL logging])
7080 AT_KEYWORDS([ovn])
7081 ovn_start
7082
7083 net_add n1
7084
7085 sim_add hv
7086 as hv
7087 ovs-vsctl add-br br-phys
7088 ovn_attach n1 br-phys 192.168.0.1
7089 for i in lp1 lp2; do
7090 ovs-vsctl -- add-port br-int $i -- \
7091 set interface $i external-ids:iface-id=$i \
7092 options:tx_pcap=hv/$i-tx.pcap \
7093 options:rxq_pcap=hv/$i-rx.pcap
7094 done
7095
7096 lp1_mac="f0:00:00:00:00:01"
7097 lp1_ip="192.168.1.2"
7098
7099 lp2_mac="f0:00:00:00:00:02"
7100 lp2_ip="192.168.1.3"
7101
7102 ovn-nbctl ls-add lsw0
7103 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7104 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7105 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7106 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7107 ovn-nbctl --wait=sb sync
7108
7109 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7110 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
7111
7112 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
7113 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
7114
7115 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
7116 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
7117
7118 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
7119 ovn-nbctl --wait=hv --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
7120
7121 ovn-sbctl dump-flows
7122
7123
7124 # Send packet that should be dropped without logging.
7125 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7126 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7127 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
7128 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7129
7130 # Send packet that should be dropped with logging.
7131 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7132 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7133 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
7134 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7135
7136 # Send packet that should be allowed without logging.
7137 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7138 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7139 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
7140 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7141
7142 # Send packet that should be allowed with logging.
7143 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7144 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7145 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
7146 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7147
7148 # Send packet that should allow related flows without logging.
7149 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7150 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7151 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
7152 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7153
7154 # Send packet that should allow related flows with logging.
7155 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7156 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7157 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
7158 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7159
7160 # Send packet that should be rejected without logging.
7161 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7162 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7163 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
7164 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7165
7166 # Send packet that should be rejected with logging.
7167 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7168 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7169 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
7170 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7171
7172 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
7173
7174 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
7175 name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
7176 name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
7177 name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
7178 name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
7179 ])
7180
7181 OVN_CLEANUP([hv])
7182 AT_CLEANUP
7183
7184
7185 AT_SETUP([ovn -- ACL rate-limited logging])
7186 AT_KEYWORDS([ovn])
7187 ovn_start
7188
7189 net_add n1
7190
7191 sim_add hv
7192 as hv
7193 ovs-vsctl add-br br-phys
7194 ovn_attach n1 br-phys 192.168.0.1
7195 for i in lp1 lp2; do
7196 ovs-vsctl -- add-port br-int $i -- \
7197 set interface $i external-ids:iface-id=$i \
7198 options:tx_pcap=hv/$i-tx.pcap \
7199 options:rxq_pcap=hv/$i-rx.pcap
7200 done
7201
7202 lp1_mac="f0:00:00:00:00:01"
7203 lp1_ip="192.168.1.2"
7204
7205 lp2_mac="f0:00:00:00:00:02"
7206 lp2_ip="192.168.1.3"
7207
7208 ovn-nbctl ls-add lsw0
7209 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7210 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7211 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7212 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7213 ovn-nbctl --wait=sb sync
7214
7215
7216 # Add an ACL that rate-limits logs at 10 per second.
7217 ovn-nbctl meter-add http-rl1 drop 10 pktps
7218 ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7219
7220 # Add an ACL that rate-limits logs at 5 per second.
7221 ovn-nbctl meter-add http-rl2 drop 5 pktps
7222 ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
7223
7224 # Add an ACL that doesn't rate-limit logs.
7225 ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
7226 ovn-nbctl --wait=hv sync
7227
7228 # For each ACL, send 100 packets.
7229 for i in `seq 1 100`; do
7230 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
7231
7232 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
7233
7234 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
7235 done
7236
7237 # The rate at which packets are sent is highly system-dependent, so we
7238 # can't count on precise drop counts. To work around that, we just
7239 # check that exactly 100 "http-acl3" actions were logged and that there
7240 # were more "http-acl1" actions than "http-acl2" ones.
7241 OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
7242
7243 # On particularly slow or overloaded systems, the transmission rate may
7244 # be lower than the configured meter rate. To prevent false test
7245 # failures, we check the duration count of the meter, and if it's
7246 # greater than nine seconds, just skip the test.
7247 d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
7248
7249 echo "Meter duration: $d_secs"
7250 AT_SKIP_IF([test $d_secs -gt 9])
7251
7252 # Print some information that may help debugging.
7253 as hv ovs-appctl -t ovn-controller meter-table-list
7254 as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
7255
7256 n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
7257 n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
7258 n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
7259
7260 AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
7261 AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
7262
7263 OVN_CLEANUP([hv])
7264 AT_CLEANUP
7265
7266
7267 AT_SETUP([ovn -- DSCP marking and meter check])
7268 AT_KEYWORDS([ovn])
7269 ovn_start
7270
7271 ovn-nbctl ls-add lsw0
7272 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7273 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7274 ovn-nbctl --wait=sb lsp-add lsw0 lp3
7275 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
7276 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
7277 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
7278 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
7279 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
7280 ovn-nbctl --wait=sb sync
7281 net_add n1
7282 sim_add hv
7283 as hv
7284 ovs-vsctl add-br br-phys
7285 ovn_attach n1 br-phys 192.168.0.1
7286 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=vif1-tx.pcap options:rxq_pcap=vif1-rx.pcap ofport-request=1
7287 ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=vif2-tx.pcap options:rxq_pcap=vif2-rx.pcap ofport-request=2
7288
7289 AT_CAPTURE_FILE([trace])
7290 ovn_trace () {
7291 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7292 }
7293
7294 # Extracts nw_tos from the final flow from ofproto/trace output and prints
7295 # it on stdout. Prints "none" if no nw_tos was included.
7296 get_final_nw_tos() {
7297 if flow=$(grep '^Final flow:' stdout); then :; else
7298 # The output didn't have a final flow.
7299 return 99
7300 fi
7301
7302 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
7303 case $tos in
7304 '') echo none ;;
7305 *) echo $tos ;;
7306 esac
7307 }
7308
7309 # check_tos TOS
7310 #
7311 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
7312 check_tos() {
7313 # First check with ovn-trace for logical flows.
7314 echo "checking for tos $1"
7315 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
7316 echo 'output("lp2");') > expout
7317 AT_CHECK_UNQUOTED([ovn_trace lsw0 'inport == "lp1" && eth.src == f0:00:00:00:00:01 && eth.dst == f0:00:00:00:00:02 && ip4.src == 1.1.1.1 && ip4.dst == 1.1.1.2'], [0], [expout])
7318
7319 # Then re-check with ofproto/trace for a physical packet.
7320 AT_CHECK([ovs-appctl ofproto/trace br-int 'in_port=1,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,dl_type=0x800,nw_src=1.1.1.1,nw_dst=1.1.1.2'], [0], [stdout-nolog])
7321 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
7322 ])
7323 }
7324
7325 # check at L2
7326 AT_CHECK([ovn_trace lsw0 'inport == "lp1" && eth.src == f0:00:00:00:00:01 && eth.dst == f0:00:00:00:00:02'], [0], [output("lp2");
7327 ])
7328 AT_CHECK([ovs-appctl ofproto/trace br-int 'in_port=1,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02'], [0], [stdout-nolog])
7329 AT_CHECK([get_final_nw_tos], [0], [none
7330 ])
7331
7332 # check at L3 without dscp marking
7333 check_tos 0
7334
7335 # Mark DSCP with a valid value
7336 qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"\ &&\ is_chassis_resident(\"lp1\")" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
7337 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7338 ])
7339 check_tos 48
7340
7341 # check at hv without qos meter
7342 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7343 ])
7344
7345 # Update the meter rate
7346 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
7347
7348 # check at hv with a qos meter table
7349 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
7350 ])
7351 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7352 ])
7353
7354 # Update the DSCP marking
7355 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
7356 check_tos 63
7357
7358 # Update the meter rate
7359 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
7360
7361 # check at hv with a qos meter table
7362 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
7363 ])
7364 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7365 ])
7366
7367 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
7368 check_tos 63
7369
7370 # Disable DSCP marking
7371 ovn-nbctl --wait=hv qos-del lsw0
7372 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
7373 ])
7374 check_tos 0
7375
7376 # check at hv without qos meter
7377 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7378 ])
7379
7380 # check meter with chassis not resident
7381 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
7382 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7383 ])
7384
7385 # check no meter table
7386 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7387 ])
7388 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
7389 ])
7390
7391 OVN_CLEANUP([hv])
7392 AT_CLEANUP
7393
7394 AT_SETUP([ovn -- read-only sb db:ptcp access])
7395 AT_SKIP_IF([test $HAVE_PYTHON = no])
7396
7397 : > .$1.db.~lock~
7398 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7399
7400 # Add read-only remote to sb ovsdb-server
7401 AT_CHECK(
7402 [ovsdb-tool transact ovn-sb.db \
7403 ['["OVN_Southbound",
7404 {"op": "insert",
7405 "table": "SB_Global",
7406 "row": {
7407 "connections": ["set", [["named-uuid", "xyz"]]]}},
7408 {"op": "insert",
7409 "table": "Connection",
7410 "uuid-name": "xyz",
7411 "row": {"target": "ptcp:0:127.0.0.1",
7412 "read_only": true}}]']], [0], [ignore], [ignore])
7413
7414 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
7415
7416 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7417
7418 # read-only accesses should succeed
7419 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
7420 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
7421
7422 # write access should fail
7423 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7424 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7425 ])
7426
7427 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7428 AT_CLEANUP
7429
7430 AT_SETUP([ovn -- read-only sb db:pssl access])
7431 AT_SKIP_IF([test $HAVE_PYTHON = no])
7432 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7433 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7434 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7435 \\]"])
7436
7437 : > .$1.db.~lock~
7438 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7439
7440 # Add read-only remote to sb ovsdb-server
7441 AT_CHECK(
7442 [ovsdb-tool transact ovn-sb.db \
7443 ['["OVN_Southbound",
7444 {"op": "insert",
7445 "table": "SB_Global",
7446 "row": {
7447 "connections": ["set", [["named-uuid", "xyz"]]]}},
7448 {"op": "insert",
7449 "table": "Connection",
7450 "uuid-name": "xyz",
7451 "row": {"target": "pssl:0:127.0.0.1",
7452 "read_only": true}}]']], [0], [ignore], [ignore])
7453
7454 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
7455 --remote=db:OVN_Southbound,SB_Global,connections \
7456 --private-key="$PKIDIR/testpki-privkey2.pem" \
7457 --certificate="$PKIDIR/testpki-cert2.pem" \
7458 --ca-cert="$PKIDIR/testpki-cacert.pem" \
7459 ovn-sb.db
7460
7461 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7462
7463 # read-only accesses should succeed
7464 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7465 --private-key=$PKIDIR/testpki-privkey.pem \
7466 --certificate=$PKIDIR/testpki-cert.pem \
7467 --ca-cert=$PKIDIR/testpki-cacert.pem \
7468 list SB_Global], [0], [stdout], [ignore])
7469 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7470 --private-key=$PKIDIR/testpki-privkey.pem \
7471 --certificate=$PKIDIR/testpki-cert.pem \
7472 --ca-cert=$PKIDIR/testpki-cacert.pem \
7473 list Connection], [0], [stdout], [ignore])
7474
7475 # write access should fail
7476 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7477 --private-key=$PKIDIR/testpki-privkey.pem \
7478 --certificate=$PKIDIR/testpki-cert.pem \
7479 --ca-cert=$PKIDIR/testpki-cacert.pem \
7480 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7481 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7482 ])
7483
7484 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7485 AT_CLEANUP
7486
7487 AT_SETUP([ovn -- nb connection/ssl commands])
7488 AT_SKIP_IF([test $HAVE_PYTHON = no])
7489 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7490 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7491 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7492 \\]"])
7493
7494 : > .$1.db.~lock~
7495 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
7496
7497 # Start nb db server using db connection/ssl entries (unpopulated initially)
7498 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
7499 --remote=db:OVN_Northbound,NB_Global,connections \
7500 --private-key=db:OVN_Northbound,SSL,private_key \
7501 --certificate=db:OVN_Northbound,SSL,certificate \
7502 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
7503 ovn-nb.db
7504
7505 # Populate SSL configuration entries in nb db
7506 AT_CHECK(
7507 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
7508 $PKIDIR/testpki-cert.pem \
7509 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7510
7511 # Populate a passive SSL connection in nb db
7512 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7513
7514 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7515
7516 # Verify SSL connetivity to nb db server
7517 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7518 --private-key=$PKIDIR/testpki-privkey.pem \
7519 --certificate=$PKIDIR/testpki-cert.pem \
7520 --ca-cert=$PKIDIR/testpki-cacert.pem \
7521 list NB_Global],
7522 [0], [stdout], [ignore])
7523 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7524 --private-key=$PKIDIR/testpki-privkey.pem \
7525 --certificate=$PKIDIR/testpki-cert.pem \
7526 --ca-cert=$PKIDIR/testpki-cacert.pem \
7527 list Connection],
7528 [0], [stdout], [ignore])
7529 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7530 --private-key=$PKIDIR/testpki-privkey.pem \
7531 --certificate=$PKIDIR/testpki-cert.pem \
7532 --ca-cert=$PKIDIR/testpki-cacert.pem \
7533 get-connection],
7534 [0], [stdout], [ignore])
7535
7536 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7537 AT_CLEANUP
7538
7539 AT_SETUP([ovn -- sb connection/ssl commands])
7540 AT_SKIP_IF([test $HAVE_PYTHON = no])
7541 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7542 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7543 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7544 \\]"])
7545
7546 : > .$1.db.~lock~
7547 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7548
7549 # Start sb db server using db connection/ssl entries (unpopulated initially)
7550 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
7551 --remote=db:OVN_Southbound,SB_Global,connections \
7552 --private-key=db:OVN_Southbound,SSL,private_key \
7553 --certificate=db:OVN_Southbound,SSL,certificate \
7554 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
7555 ovn-sb.db
7556
7557 # Populate SSL configuration entries in sb db
7558 AT_CHECK(
7559 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
7560 $PKIDIR/testpki-cert.pem \
7561 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7562
7563 # Populate a passive SSL connection in sb db
7564 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7565
7566 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7567
7568 # Verify SSL connetivity to sb db server
7569 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7570 --private-key=$PKIDIR/testpki-privkey.pem \
7571 --certificate=$PKIDIR/testpki-cert.pem \
7572 --ca-cert=$PKIDIR/testpki-cacert.pem \
7573 list SB_Global],
7574 [0], [stdout], [ignore])
7575 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7576 --private-key=$PKIDIR/testpki-privkey.pem \
7577 --certificate=$PKIDIR/testpki-cert.pem \
7578 --ca-cert=$PKIDIR/testpki-cacert.pem \
7579 list Connection],
7580 [0], [stdout], [ignore])
7581 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7582 --private-key=$PKIDIR/testpki-privkey.pem \
7583 --certificate=$PKIDIR/testpki-cert.pem \
7584 --ca-cert=$PKIDIR/testpki-cacert.pem \
7585 get-connection],
7586 [0], [stdout], [ignore])
7587
7588 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7589 AT_CLEANUP
7590
7591 AT_SETUP([ovn -- nested containers])
7592 ovn_start
7593
7594 # Physical network:
7595 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
7596
7597 # Logical network:
7598 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
7599 # and "bar" (192.168.2.0/24). They are all connected to router R1.
7600
7601 ovn-nbctl lr-add R1
7602 ovn-nbctl ls-add mgmt
7603 ovn-nbctl ls-add foo
7604 ovn-nbctl ls-add bar
7605
7606 # Connect mgmt to R1
7607 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
7608 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
7609 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
7610
7611 # Connect foo to R1
7612 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7613 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7614 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7615
7616 # Connect bar to R1
7617 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
7618 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7619 options:router-port=bar addresses=\"00:00:00:01:02:04\"
7620
7621 # "mgmt" has VM1 and VM2 connected
7622 ovn-nbctl lsp-add mgmt vm1 \
7623 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
7624
7625 ovn-nbctl lsp-add mgmt vm2 \
7626 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
7627
7628 # "foo1" and "foo2" are containers belonging to switch "foo"
7629 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
7630 ovn-nbctl lsp-add foo foo1 vm1 1 \
7631 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
7632
7633 ovn-nbctl lsp-add foo foo2 vm2 2 \
7634 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7635
7636 # "bar1" and "bar2" are containers belonging to switch "bar"
7637 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
7638 ovn-nbctl lsp-add bar bar1 vm1 2 \
7639 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
7640
7641 ovn-nbctl lsp-add bar bar2 vm2 1 \
7642 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
7643
7644 # bar3 is a standalone VM belonging to switch "bar"
7645 ovn-nbctl lsp-add bar bar3 \
7646 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
7647
7648 # Create two hypervisor and create OVS ports corresponding to logical ports.
7649 net_add n1
7650
7651 sim_add hv1
7652 as hv1
7653 ovs-vsctl add-br br-phys
7654 ovn_attach n1 br-phys 192.168.0.1
7655 ovs-vsctl -- add-port br-int vm1 -- \
7656 set interface vm1 external-ids:iface-id=vm1 \
7657 options:tx_pcap=hv1/vm1-tx.pcap \
7658 options:rxq_pcap=hv1/vm1-rx.pcap \
7659 ofport-request=1
7660
7661 ovs-vsctl -- add-port br-int bar3 -- \
7662 set interface bar3 external-ids:iface-id=bar3 \
7663 options:tx_pcap=hv1/bar3-tx.pcap \
7664 options:rxq_pcap=hv1/bar3-rx.pcap \
7665 ofport-request=2
7666
7667 sim_add hv2
7668 as hv2
7669 ovs-vsctl add-br br-phys
7670 ovn_attach n1 br-phys 192.168.0.2
7671 ovs-vsctl -- add-port br-int vm2 -- \
7672 set interface vm2 external-ids:iface-id=vm2 \
7673 options:tx_pcap=hv2/vm2-tx.pcap \
7674 options:rxq_pcap=hv2/vm2-rx.pcap \
7675 ofport-request=1
7676
7677 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7678 # packets for ARP resolution (native tunneling doesn't queue packets
7679 # for ARP resolution).
7680 OVN_POPULATE_ARP
7681
7682 # Allow some time for ovn-northd and ovn-controller to catch up.
7683 # XXX This should be more systematic.
7684 sleep 1
7685
7686 ip_to_hex() {
7687 printf "%02x%02x%02x%02x" "$@"
7688 }
7689
7690 # Send ip packets between foo1 and foo2 (same switch, different HVs and
7691 # different VLAN tags).
7692 src_mac="f00000010205"
7693 dst_mac="f00000010206"
7694 src_ip=`ip_to_hex 192 168 1 2`
7695 dst_ip=`ip_to_hex 192 168 1 3`
7696 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7697 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7698
7699 # expected packet at foo2
7700 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7701 echo $packet > expected
7702 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7703
7704 # Send ip packets between foo1 and bar2 (different switch, different HV)
7705 src_mac="f00000010205"
7706 dst_mac="000000010203"
7707 src_ip=`ip_to_hex 192 168 1 2`
7708 dst_ip=`ip_to_hex 192 168 2 3`
7709 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7710 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7711
7712 # expected packet at bar2
7713 src_mac="000000010204"
7714 dst_mac="f00000010208"
7715 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7716 echo $packet >> expected
7717 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7718
7719 # Send ip packets between foo1 and bar1
7720 # (different switch, loopback to same vm but different tag)
7721 src_mac="f00000010205"
7722 dst_mac="000000010203"
7723 src_ip=`ip_to_hex 192 168 1 2`
7724 dst_ip=`ip_to_hex 192 168 2 2`
7725 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7726 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7727
7728 # expected packet at bar1
7729 src_mac="000000010204"
7730 dst_mac="f00000010207"
7731 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7732 echo $packet > expected1
7733 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7734
7735 # Send ip packets between bar1 and bar3
7736 # (same switch. But one is container and another is a standalone VM)
7737 src_mac="f00000010207"
7738 dst_mac="f00000010209"
7739 src_ip=`ip_to_hex 192 168 2 2`
7740 dst_ip=`ip_to_hex 192 168 2 3`
7741 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7742 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7743
7744 # expected packet at bar3
7745 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7746 echo $packet > expected
7747 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7748
7749 # Send ip packets between foo1 and vm1.
7750 (different switch, container to the VM hosting it.)
7751 src_mac="f00000010205"
7752 dst_mac="000000010203"
7753 src_ip=`ip_to_hex 192 168 1 2`
7754 dst_ip=`ip_to_hex 172 16 1 2`
7755 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7756 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7757
7758 # expected packet at vm1
7759 src_mac="000000010202"
7760 dst_mac="f00000010203"
7761 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7762 echo $packet >> expected1
7763 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7764
7765 # Send packets from vm1 to bar1.
7766 (different switch, A hosting VM to a container inside it)
7767 src_mac="f00000010203"
7768 dst_mac="000000010202"
7769 src_ip=`ip_to_hex 172 16 1 2`
7770 dst_ip=`ip_to_hex 192 168 2 2`
7771 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7772 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7773
7774 # expected packet at vm1
7775 src_mac="000000010204"
7776 dst_mac="f00000010207"
7777 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7778 echo $packet >> expected1
7779 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7780
7781 # Send broadcast packet from foo1. foo1 should not receive the same packet.
7782 src_mac="f00000010205"
7783 dst_mac="ffffffffffff"
7784 src_ip=`ip_to_hex 192 168 1 2`
7785 dst_ip=`ip_to_hex 255 255 255 255`
7786 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7787 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7788
7789 # expected packet at VM1
7790 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7791
7792 OVN_CLEANUP([hv1],[hv2])
7793
7794 AT_CLEANUP
7795
7796 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7797 AT_SKIP_IF([test $HAVE_PYTHON = no])
7798 ovn_start
7799
7800 # Logical network:
7801 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7802 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7803 # (192.168.2.0/24) connected to it.
7804 #
7805 # R2 and R3 are gateway routers.
7806 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7807 # connected to it. Note how both alice and bob have the same subnet behind it.
7808 # We are trying to simulate external network via those 2 switches. In real
7809 # world the switch ports of these switches will have addresses set as "unknown"
7810 # to make them learning switches. Or those switches will be "localnet" ones.
7811
7812 # Create three hypervisors and create OVS ports corresponding to logical ports.
7813 net_add n1
7814
7815 sim_add hv1
7816 as hv1
7817 ovs-vsctl add-br br-phys
7818 ovn_attach n1 br-phys 192.168.0.1
7819 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7820 set interface hv1-vif1 external-ids:iface-id=foo1 \
7821 options:tx_pcap=hv1/vif1-tx.pcap \
7822 options:rxq_pcap=hv1/vif1-rx.pcap \
7823 ofport-request=1
7824
7825 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7826 set interface hv1-vif2 external-ids:iface-id=bar1 \
7827 options:tx_pcap=hv1/vif2-tx.pcap \
7828 options:rxq_pcap=hv1/vif2-rx.pcap \
7829 ofport-request=2
7830
7831 sim_add hv2
7832 as hv2
7833 ovs-vsctl add-br br-phys
7834 ovn_attach n1 br-phys 192.168.0.2
7835 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7836 set interface hv2-vif1 external-ids:iface-id=alice1 \
7837 options:tx_pcap=hv2/vif1-tx.pcap \
7838 options:rxq_pcap=hv2/vif1-rx.pcap \
7839 ofport-request=1
7840
7841 sim_add hv3
7842 as hv3
7843 ovs-vsctl add-br br-phys
7844 ovn_attach n1 br-phys 192.168.0.3
7845 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7846 set interface hv3-vif1 external-ids:iface-id=bob1 \
7847 options:tx_pcap=hv3/vif1-tx.pcap \
7848 options:rxq_pcap=hv3/vif1-rx.pcap \
7849 ofport-request=1
7850
7851
7852 ovn-nbctl create Logical_Router name=R1
7853 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7854 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7855
7856 ovn-nbctl ls-add foo
7857 ovn-nbctl ls-add bar
7858 ovn-nbctl ls-add alice
7859 ovn-nbctl ls-add bob
7860 ovn-nbctl ls-add join
7861
7862 # Connect foo to R1
7863 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7864 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7865 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7866
7867 # Connect bar to R1
7868 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7869 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7870 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7871
7872 # Connect alice to R2
7873 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7874 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7875 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7876
7877 # Connect bob to R3
7878 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7879 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7880 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7881
7882 # Connect R1 to join
7883 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7884 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7885 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7886
7887 # Connect R2 to join
7888 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7889 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7890 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7891
7892 # Connect R3 to join
7893 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7894 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7895 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7896
7897 # Install static routes with source ip address as the policy for routing.
7898 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7899 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7900 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7901
7902 # Install static routes with destination ip address as the policy for routing.
7903 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7904
7905 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7906
7907 # Create logical port foo1 in foo
7908 ovn-nbctl lsp-add foo foo1 \
7909 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7910
7911 # Create logical port bar1 in bar
7912 ovn-nbctl lsp-add bar bar1 \
7913 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7914
7915 # Create logical port alice1 in alice
7916 ovn-nbctl lsp-add alice alice1 \
7917 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7918
7919 # Create logical port bob1 in bob
7920 ovn-nbctl lsp-add bob bob1 \
7921 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7922
7923 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7924 # packets for ARP resolution (native tunneling doesn't queue packets
7925 # for ARP resolution).
7926 OVN_POPULATE_ARP
7927
7928 # Allow some time for ovn-northd and ovn-controller to catch up.
7929 # XXX This should be more systematic.
7930 sleep 1
7931
7932 ip_to_hex() {
7933 printf "%02x%02x%02x%02x" "$@"
7934 }
7935 trim_zeros() {
7936 sed 's/\(00\)\{1,\}$//'
7937 }
7938
7939 # Send ip packets between foo1 and bar1
7940 # (East-west traffic should flow normally)
7941 src_mac="f00000010203"
7942 dst_mac="000001010203"
7943 src_ip=`ip_to_hex 192 168 1 2`
7944 dst_ip=`ip_to_hex 192 168 2 2`
7945 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7946 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7947
7948 # Send ip packets between foo1 and alice1
7949 src_mac="f00000010203"
7950 dst_mac="000001010203"
7951 src_ip=`ip_to_hex 192 168 1 2`
7952 dst_ip=`ip_to_hex 172 16 1 3`
7953 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7954 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7955 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
7956
7957 # Send ip packets between bar1 and bob1
7958 src_mac="f00000010204"
7959 dst_mac="000001010204"
7960 src_ip=`ip_to_hex 192 168 2 2`
7961 dst_ip=`ip_to_hex 172 16 1 4`
7962 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7963 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7964 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7965
7966 # Packet to expect at bar1
7967 src_mac="000001010204"
7968 dst_mac="f00000010204"
7969 src_ip=`ip_to_hex 192 168 1 2`
7970 dst_ip=`ip_to_hex 192 168 2 2`
7971 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7972 echo $expected > expected
7973 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7974
7975 # Packet to Expect at alice1
7976 src_mac="000002010203"
7977 dst_mac="f00000010205"
7978 src_ip=`ip_to_hex 192 168 1 2`
7979 dst_ip=`ip_to_hex 172 16 1 3`
7980 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7981 echo $expected > expected
7982 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7983
7984 # Packet to Expect at bob1
7985 src_mac="000003010203"
7986 dst_mac="f00000010206"
7987 src_ip=`ip_to_hex 192 168 2 2`
7988 dst_ip=`ip_to_hex 172 16 1 4`
7989 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7990 echo $expected > expected
7991 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7992
7993 OVN_CLEANUP([hv1],[hv2],[hv3])
7994
7995 AT_CLEANUP
7996
7997 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7998 AT_SKIP_IF([test $HAVE_PYTHON = no])
7999 ovn_start
8000
8001 ovn-nbctl ls-add ls1
8002
8003 ovn-nbctl lsp-add ls1 ls1-lp1 \
8004 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8005
8006 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8007
8008 ovn-nbctl lsp-add ls1 ls1-lp2 \
8009 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8010
8011 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8012
8013 DNS1=`ovn-nbctl create DNS records={}`
8014 DNS2=`ovn-nbctl create DNS records={}`
8015
8016 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8017 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
8018 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
8019
8020 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
8021
8022 net_add n1
8023 sim_add hv1
8024
8025 as hv1
8026 ovs-vsctl add-br br-phys
8027 ovn_attach n1 br-phys 192.168.0.1
8028 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8029 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
8030 options:tx_pcap=hv1/vif1-tx.pcap \
8031 options:rxq_pcap=hv1/vif1-rx.pcap \
8032 ofport-request=1
8033
8034 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8035 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
8036 options:tx_pcap=hv1/vif2-tx.pcap \
8037 options:rxq_pcap=hv1/vif2-rx.pcap \
8038 ofport-request=2
8039
8040 OVN_POPULATE_ARP
8041 sleep 2
8042 as hv1 ovs-vsctl show
8043
8044 echo "*************************"
8045 ovn-sbctl list DNS
8046 echo "*************************"
8047
8048 ip_to_hex() {
8049 printf "%02x%02x%02x%02x" "$@"
8050 }
8051
8052 reset_pcap_file() {
8053 local iface=$1
8054 local pcap_file=$2
8055 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8056 options:rxq_pcap=dummy-rx.pcap
8057 rm -f ${pcap_file}*.pcap
8058 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8059 options:rxq_pcap=${pcap_file}-rx.pcap
8060 }
8061
8062 # set_dns_params host_name
8063 # Sets the dns_req_data and dns_resp_data
8064 set_dns_params() {
8065 local hname=$1
8066 local ttl=00000e10
8067 an_count=0001
8068 type=0001
8069 case $hname in
8070 vm1)
8071 # vm1.ovn.org
8072 query_name=03766d31036f766e036f726700
8073 # IPv4 address - 10.0.0.4
8074 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8075 ;;
8076 vm2)
8077 # vm2.ovn.org
8078 query_name=03766d32036f766e036f726700
8079 # IPv4 address - 10.0.0.6
8080 expected_dns_answer=${query_name}00010001${ttl}00040a000006
8081 # IPv4 address - 20.0.0.4
8082 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
8083 an_count=0002
8084 ;;
8085 vm3)
8086 # vm3.ovn.org
8087 query_name=03766d33036f766e036f726700
8088 # IPv4 address - 40.0.0.4
8089 expected_dns_answer=${query_name}00010001${ttl}000428000004
8090 ;;
8091 vm1_ipv6_only)
8092 # vm1.ovn.org
8093 query_name=03766d31036f766e036f726700
8094 # IPv6 address - aef0::4
8095 type=001c
8096 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
8097 ;;
8098 vm1_ipv4_v6)
8099 # vm1.ovn.org
8100 query_name=03766d31036f766e036f726700
8101 type=00ff
8102 an_count=0002
8103 # IPv4 address - 10.0.0.4
8104 # IPv6 address - aef0::4
8105 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8106 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
8107 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
8108 ;;
8109 vm1_invalid_type)
8110 # vm1.ovn.org
8111 query_name=03766d31036f766e036f726700
8112 # IPv6 address - aef0::4
8113 type=0002
8114 ;;
8115 vm1_incomplete)
8116 # set type to none
8117 type=''
8118 esac
8119 # TTL - 3600
8120 local dns_req_header=010201200001000000000000
8121 local dns_resp_header=010281200001${an_count}00000000
8122 dns_req_data=${dns_req_header}${query_name}${type}0001
8123 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
8124 }
8125
8126 # This shell function sends a DNS request packet
8127 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
8128 test_dns() {
8129 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8130 local dns_query_data=$7
8131 shift; shift; shift; shift; shift; shift; shift;
8132 # Packet size => IPv4 header (20) + UDP header (8) +
8133 # DNS data (header + query)
8134 ip_len=`expr 28 + ${#dns_query_data} / 2`
8135 udp_len=`expr $ip_len - 20`
8136 ip_len=$(printf "%x" $ip_len)
8137 udp_len=$(printf "%x" $udp_len)
8138 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
8139 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
8140 # dns data
8141 request=${request}${dns_query_data}
8142
8143 if test $dns_reply != 0; then
8144 local dns_reply=$1
8145 ip_len=`expr 28 + ${#dns_reply} / 2`
8146 udp_len=`expr $ip_len - 20`
8147 ip_len=$(printf "%x" $ip_len)
8148 udp_len=$(printf "%x" $udp_len)
8149 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
8150 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
8151 echo $reply >> $inport.expected
8152 else
8153 for outport; do
8154 echo $request >> $outport.expected
8155 done
8156 fi
8157 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8158 }
8159
8160 test_dns6() {
8161 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8162 local dns_query_data=$7
8163 shift; shift; shift; shift; shift; shift; shift;
8164 # Packet size => UDP header (8) +
8165 # DNS data (header + query)
8166 ip_len=`expr 8 + ${#dns_query_data} / 2`
8167 udp_len=$ip_len
8168 ip_len=$(printf "%x" $ip_len)
8169 udp_len=$(printf "%x" $udp_len)
8170 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
8171 request=${request}9234003500${udp_len}0000
8172 #dns data
8173 request=${request}${dns_query_data}
8174
8175 if test $dns_reply != 0; then
8176 local dns_reply=$1
8177 ip_len=`expr 8 + ${#dns_reply} / 2`
8178 udp_len=$ip_len
8179 ip_len=$(printf "%x" $ip_len)
8180 udp_len=$(printf "%x" $udp_len)
8181 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
8182 reply=${reply}0035923400${udp_len}0000${dns_reply}
8183 echo $reply >> $inport.expected
8184 else
8185 for outport; do
8186 echo $request >> $outport.expected
8187 done
8188 fi
8189 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8190 }
8191
8192 AT_CAPTURE_FILE([ofctl_monitor0.log])
8193 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8194 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8195
8196 set_dns_params vm2
8197 src_ip=`ip_to_hex 10 0 0 4`
8198 dst_ip=`ip_to_hex 10 0 0 1`
8199 dns_reply=1
8200 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8201
8202 # NXT_RESUMEs should be 1.
8203 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8204
8205 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8206 cat 1.expected | cut -c -48 > expout
8207 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8208 # Skipping the IPv4 checksum.
8209 cat 1.expected | cut -c 53- > expout
8210 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8211
8212 reset_pcap_file hv1-vif1 hv1/vif1
8213 reset_pcap_file hv1-vif2 hv1/vif2
8214 rm -f 1.expected
8215 rm -f 2.expected
8216
8217 set_dns_params vm1
8218 src_ip=`ip_to_hex 10 0 0 6`
8219 dst_ip=`ip_to_hex 10 0 0 1`
8220 dns_reply=1
8221 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8222
8223 # NXT_RESUMEs should be 2.
8224 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8225
8226 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8227 cat 2.expected | cut -c -48 > expout
8228 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8229 # Skipping the IPv4 checksum.
8230 cat 2.expected | cut -c 53- > expout
8231 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8232
8233 reset_pcap_file hv1-vif1 hv1/vif1
8234 reset_pcap_file hv1-vif2 hv1/vif2
8235 rm -f 1.expected
8236 rm -f 2.expected
8237
8238 # Clear the query name options for ls1-lp2
8239 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
8240
8241 set_dns_params vm2
8242 src_ip=`ip_to_hex 10 0 0 4`
8243 dst_ip=`ip_to_hex 10 0 0 1`
8244 dns_reply=0
8245 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
8246
8247 # NXT_RESUMEs should be 3.
8248 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8249
8250 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8251 AT_CHECK([cat 1.packets], [0], [])
8252
8253 reset_pcap_file hv1-vif1 hv1/vif1
8254 reset_pcap_file hv1-vif2 hv1/vif2
8255 rm -f 1.expected
8256 rm -f 2.expected
8257
8258 # Clear the query name for ls1-lp1
8259 # Since ls1 has no query names configued,
8260 # ovn-northd should not add the DNS flows.
8261 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
8262
8263 set_dns_params vm1
8264 src_ip=`ip_to_hex 10 0 0 6`
8265 dst_ip=`ip_to_hex 10 0 0 1`
8266 dns_reply=0
8267 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8268
8269 # NXT_RESUMEs should be 3 only.
8270 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8271
8272 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8273 AT_CHECK([cat 2.packets], [0], [])
8274
8275 reset_pcap_file hv1-vif1 hv1/vif1
8276 reset_pcap_file hv1-vif2 hv1/vif2
8277 rm -f 1.expected
8278 rm -f 2.expected
8279
8280 # Test IPv6 (AAAA records) using IPv4 packet.
8281 # Add back the DNS options for ls1-lp1.
8282 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8283
8284 set_dns_params vm1_ipv6_only
8285 src_ip=`ip_to_hex 10 0 0 6`
8286 dst_ip=`ip_to_hex 10 0 0 1`
8287 dns_reply=1
8288 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8289
8290 # NXT_RESUMEs should be 4.
8291 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8292
8293 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8294 cat 2.expected | cut -c -48 > expout
8295 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8296 # Skipping the IPv4 checksum.
8297 cat 2.expected | cut -c 53- > expout
8298 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8299
8300 reset_pcap_file hv1-vif1 hv1/vif1
8301 reset_pcap_file hv1-vif2 hv1/vif2
8302 rm -f 1.expected
8303 rm -f 2.expected
8304
8305 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
8306 set_dns_params vm1_ipv4_v6
8307 src_ip=`ip_to_hex 10 0 0 6`
8308 dst_ip=`ip_to_hex 10 0 0 1`
8309 dns_reply=1
8310 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8311
8312 # NXT_RESUMEs should be 5.
8313 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8314
8315 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8316 cat 2.expected | cut -c -48 > expout
8317 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8318 # Skipping the IPv4 checksum.
8319 cat 2.expected | cut -c 53- > expout
8320 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8321
8322 reset_pcap_file hv1-vif1 hv1/vif1
8323 reset_pcap_file hv1-vif2 hv1/vif2
8324 rm -f 1.expected
8325 rm -f 2.expected
8326
8327 # Invalid type.
8328 set_dns_params vm1_invalid_type
8329 src_ip=`ip_to_hex 10 0 0 6`
8330 dst_ip=`ip_to_hex 10 0 0 1`
8331 dns_reply=0
8332 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8333
8334 # NXT_RESUMEs should be 6.
8335 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8336
8337 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8338 AT_CHECK([cat 2.packets], [0], [])
8339
8340 reset_pcap_file hv1-vif1 hv1/vif1
8341 reset_pcap_file hv1-vif2 hv1/vif2
8342 rm -f 1.expected
8343 rm -f 2.expected
8344
8345 # Incomplete DNS packet.
8346 set_dns_params vm1_incomplete
8347 src_ip=`ip_to_hex 10 0 0 6`
8348 dst_ip=`ip_to_hex 10 0 0 1`
8349 dns_reply=0
8350 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8351
8352 # NXT_RESUMEs should be 7.
8353 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8354
8355 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8356 AT_CHECK([cat 2.packets], [0], [])
8357
8358 reset_pcap_file hv1-vif1 hv1/vif1
8359 reset_pcap_file hv1-vif2 hv1/vif2
8360 rm -f 1.expected
8361 rm -f 2.expected
8362
8363 # Add one more DNS record to the ls1.
8364 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
8365
8366 set_dns_params vm3
8367 src_ip=`ip_to_hex 10 0 0 4`
8368 dst_ip=`ip_to_hex 10 0 0 1`
8369 dns_reply=1
8370 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8371
8372 # NXT_RESUMEs should be 8.
8373 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8374
8375 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8376 cat 1.expected | cut -c -48 > expout
8377 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8378 # Skipping the IPv4 checksum.
8379 cat 1.expected | cut -c 53- > expout
8380 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8381
8382 reset_pcap_file hv1-vif1 hv1/vif1
8383 reset_pcap_file hv1-vif2 hv1/vif2
8384 rm -f 1.expected
8385 rm -f 2.expected
8386
8387 # Try DNS query over IPv6
8388 set_dns_params vm1
8389 src_ip=aef00000000000000000000000000004
8390 dst_ip=aef00000000000000000000000000001
8391 dns_reply=1
8392 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8393
8394 # NXT_RESUMEs should be 9.
8395 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8396
8397 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8398 # Skipping the UDP checksum.
8399 cat 1.expected | cut -c 1-120,125- > expout
8400 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
8401
8402 reset_pcap_file hv1-vif1 hv1/vif1
8403 reset_pcap_file hv1-vif2 hv1/vif2
8404 rm -f 1.expected
8405 rm -f 2.expected
8406
8407 OVN_CLEANUP([hv1])
8408
8409 AT_CLEANUP
8410
8411 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
8412 AT_SKIP_IF([test $HAVE_PYTHON = no])
8413 ovn_start
8414
8415 net_add n1
8416
8417 sim_add hv1
8418 as hv1
8419 ovs-vsctl add-br br-phys
8420 ovn_attach n1 br-phys 192.168.0.1
8421 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8422 set interface hv1-vif1 external-ids:iface-id=foo1 \
8423 options:tx_pcap=hv1/vif1-tx.pcap \
8424 options:rxq_pcap=hv1/vif1-rx.pcap \
8425 ofport-request=1
8426
8427 sim_add gw1
8428 as gw1
8429 ovs-vsctl add-br br-phys
8430 ovn_attach n1 br-phys 192.168.0.2
8431
8432 sim_add gw2
8433 as gw2
8434 ovs-vsctl add-br br-phys
8435 ovn_attach n1 br-phys 192.168.0.4
8436
8437 sim_add ext1
8438 as ext1
8439 ovs-vsctl add-br br-phys
8440 ovn_attach n1 br-phys 192.168.0.3
8441 ovs-vsctl -- add-port br-int ext1-vif1 -- \
8442 set interface ext1-vif1 external-ids:iface-id=outside1 \
8443 options:tx_pcap=ext1/vif1-tx.pcap \
8444 options:rxq_pcap=ext1/vif1-rx.pcap \
8445 ofport-request=1
8446
8447 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8448 # packets for ARP resolution (native tunneling doesn't queue packets
8449 # for ARP resolution).
8450 OVN_POPULATE_ARP
8451
8452 ovn-nbctl create Logical_Router name=R1
8453
8454 ovn-nbctl ls-add foo
8455 ovn-nbctl ls-add alice
8456 ovn-nbctl ls-add outside
8457
8458 # Connect foo to R1
8459 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8460 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8461 type=router options:router-port=foo \
8462 -- lsp-set-addresses rp-foo router
8463
8464 # Connect alice to R1 as distributed router gateway port on gw1
8465 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8466
8467 ovn-nbctl \
8468 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8469 chassis_name=gw1 \
8470 priority=20 -- \
8471 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8472 chassis_name=gw2 \
8473 priority=10 -- \
8474 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8475
8476 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8477 type=router options:router-port=alice \
8478 -- lsp-set-addresses rp-alice router
8479
8480 # Create logical port foo1 in foo
8481 ovn-nbctl lsp-add foo foo1 \
8482 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8483
8484 # Create logical port outside1 in outside
8485 ovn-nbctl lsp-add outside outside1 \
8486 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8487
8488 # Create localnet port in alice
8489 ovn-nbctl lsp-add alice ln-alice
8490 ovn-nbctl lsp-set-addresses ln-alice unknown
8491 ovn-nbctl lsp-set-type ln-alice localnet
8492 ovn-nbctl lsp-set-options ln-alice network_name=phys
8493
8494 # Create localnet port in outside
8495 ovn-nbctl lsp-add outside ln-outside
8496 ovn-nbctl lsp-set-addresses ln-outside unknown
8497 ovn-nbctl lsp-set-type ln-outside localnet
8498 ovn-nbctl lsp-set-options ln-outside network_name=phys
8499
8500 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8501 # mapping to the external network, is the one generating packets
8502 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8503 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8504 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8505
8506 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8507
8508 # Allow some time for ovn-northd and ovn-controller to catch up.
8509 # XXX This should be more systematic.
8510 sleep 2
8511
8512 ip_to_hex() {
8513 printf "%02x%02x%02x%02x" "$@"
8514 }
8515
8516 reset_pcap_file() {
8517 local iface=$1
8518 local pcap_file=$2
8519 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8520 options:rxq_pcap=dummy-rx.pcap
8521 rm -f ${pcap_file}*.pcap
8522 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8523 options:rxq_pcap=${pcap_file}-rx.pcap
8524 }
8525
8526 test_ip_packet()
8527 {
8528 local active_gw=$1
8529 local backup_gw=$2
8530 local backup_vswitchd_dead=$3
8531
8532 # Send ip packet between foo1 and outside1
8533 src_mac="f00000010203" # foo1 mac
8534 dst_mac="000001010203" # rp-foo mac (internal router leg)
8535 src_ip=`ip_to_hex 192 168 1 2`
8536 dst_ip=`ip_to_hex 172 16 1 3`
8537 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8538
8539 # ARP request packet to expect at outside1
8540 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8541
8542 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8543
8544 # Send ARP reply from outside1 back to the router
8545 # XXX: note, we could avoid this if we plug this port into a netns
8546 # and setup the IP address into the port, so the kernel would simply reply
8547 src_mac="000002010203"
8548 reply_mac="f00000010204"
8549 dst_ip=`ip_to_hex 172 16 1 3`
8550 src_ip=`ip_to_hex 172 16 1 1`
8551 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8552
8553 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8554
8555 OVS_WAIT_UNTIL([
8556 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8557 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8558 ])
8559
8560 # Packet to Expect at ext1 chassis, outside1 port
8561 src_mac="000002010203"
8562 dst_mac="f00000010204"
8563 src_ip=`ip_to_hex 192 168 1 2`
8564 dst_ip=`ip_to_hex 172 16 1 3`
8565 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8566 echo $expected > ext1-vif1.expected
8567
8568 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8569
8570 if test $backup_vswitchd_dead != 1; then
8571 # Reset the file only if vswitchd in backup gw is alive
8572 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8573 fi
8574 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8575
8576 # Resend packet from foo1 to outside1
8577 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8578
8579 sleep 1
8580
8581 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8582 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8583 AT_CHECK([grep $expected packets | sort], [0], [expout])
8584 if test $backup_vswitchd_dead != 1; then
8585 # Check for backup gw only if vswitchd is alive
8586 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8587 AT_CHECK([grep $expected packets | sort], [0], [])
8588 fi
8589 }
8590
8591 test_ip_packet gw1 gw2 0
8592
8593 ovn-nbctl --timeout=3 --wait=hv \
8594 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8595 chassis_name=gw1 \
8596 priority=10 -- \
8597 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8598 chassis_name=gw2 \
8599 priority=20 -- \
8600 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8601
8602 test_ip_packet gw2 gw1 0
8603
8604 # Get the claim count of both gw1 and gw2.
8605 gw1_claim_ct=`grep "cr-alice: Claiming" gw1/ovn-controller.log | wc -l`
8606 gw2_claim_ct=`grep "cr-alice: Claiming" gw2/ovn-controller.log | wc -l`
8607
8608 # Stop ovs-vswitchd in gw2. gw1 should claim the gateway port.
8609 as gw2
8610 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
8611
8612 # gw1 should claim the cr-alice and the claim count of gw1 should be
8613 # incremented by 1.
8614 gw1_claim_ct=$((gw1_claim_ct+1))
8615
8616 OVS_WAIT_UNTIL([test $gw1_claim_ct = `cat gw1/ovn-controller.log \
8617 | grep -c "cr-alice: Claiming"`])
8618
8619 AT_CHECK([test $gw2_claim_ct = `cat gw2/ovn-controller.log | \
8620 grep -c "cr-alice: Claiming"`])
8621
8622 test_ip_packet gw1 gw2 1
8623
8624 as gw2
8625 OVS_APP_EXIT_AND_WAIT([ovn-controller])
8626 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
8627
8628 OVN_CLEANUP([hv1],[gw1],[ext1])
8629
8630 AT_CLEANUP
8631
8632 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
8633 AT_SKIP_IF([test $HAVE_PYTHON = no])
8634 ovn_start
8635
8636 net_add n1
8637
8638 sim_add hv1
8639 as hv1
8640 ovs-vsctl add-br br-phys
8641 ovn_attach n1 br-phys 192.168.0.1
8642 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8643 set interface hv1-vif1 external-ids:iface-id=foo1 \
8644 options:tx_pcap=hv1/vif1-tx.pcap \
8645 options:rxq_pcap=hv1/vif1-rx.pcap \
8646 ofport-request=1
8647
8648 sim_add gw1
8649 as gw1
8650 ovs-vsctl add-br br-phys
8651 ovn_attach n1 br-phys 192.168.0.2
8652
8653 sim_add gw2
8654 as gw2
8655 ovs-vsctl add-br br-phys
8656 ovn_attach n1 br-phys 192.168.0.4
8657
8658 sim_add ext1
8659 as ext1
8660 ovs-vsctl add-br br-phys
8661 ovn_attach n1 br-phys 192.168.0.3
8662 ovs-vsctl -- add-port br-int ext1-vif1 -- \
8663 set interface ext1-vif1 external-ids:iface-id=outside1 \
8664 options:tx_pcap=ext1/vif1-tx.pcap \
8665 options:rxq_pcap=ext1/vif1-rx.pcap \
8666 ofport-request=1
8667
8668 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8669 # packets for ARP resolution (native tunneling doesn't queue packets
8670 # for ARP resolution).
8671 OVN_POPULATE_ARP
8672
8673 ovn-nbctl create Logical_Router name=R0
8674 ovn-nbctl create Logical_Router name=R1
8675
8676 ovn-nbctl ls-add foo
8677 ovn-nbctl ls-add join
8678 ovn-nbctl ls-add alice
8679 ovn-nbctl ls-add outside
8680
8681 #Connect foo to R0
8682 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
8683 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
8684 type=router options:router-port=R0-foo \
8685 -- lsp-set-addresses foo-R0 router
8686
8687 #Connect R0 to join
8688 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
8689 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
8690 type=router options:router-port=R0-join \
8691 -- lsp-set-addresses join-R0 router
8692
8693 #Connect join to R1
8694 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
8695 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
8696 type=router options:router-port=R1-join \
8697 -- lsp-set-addresses join-R1 router
8698
8699 #add route rules
8700 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
8701 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
8702
8703 # Connect alice to R1 as distributed router gateway port on gw1
8704 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8705
8706 ovn-nbctl \
8707 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8708 chassis_name=gw1 \
8709 priority=20 -- \
8710 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8711 chassis_name=gw2 \
8712 priority=10 -- \
8713 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8714
8715 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8716 type=router options:router-port=alice \
8717 -- lsp-set-addresses rp-alice router
8718
8719 # Create logical port foo1 in foo
8720 ovn-nbctl lsp-add foo foo1 \
8721 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8722
8723 # Create logical port outside1 in outside
8724 ovn-nbctl lsp-add outside outside1 \
8725 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8726
8727 # Create localnet port in alice
8728 ovn-nbctl lsp-add alice ln-alice
8729 ovn-nbctl lsp-set-addresses ln-alice unknown
8730 ovn-nbctl lsp-set-type ln-alice localnet
8731 ovn-nbctl lsp-set-options ln-alice network_name=phys
8732
8733 # Create localnet port in outside
8734 ovn-nbctl lsp-add outside ln-outside
8735 ovn-nbctl lsp-set-addresses ln-outside unknown
8736 ovn-nbctl lsp-set-type ln-outside localnet
8737 ovn-nbctl lsp-set-options ln-outside network_name=phys
8738
8739 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8740 # mapping to the external network, is the one generating packets
8741 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8742 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8743 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8744
8745 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8746
8747 # hv1 should be in 'ref_chassis' of the ha_chasssi_group as logical
8748 # switch 'foo' can reach the router 'R1' (which has gw router port)
8749 # via foo1 -> foo -> R0 -> join -> R1
8750 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
8751 OVS_WAIT_UNTIL(
8752 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
8753 # Trim the spaces.
8754 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
8755 test "$hv1_ch_uuid" = "$ref_ch_list"])
8756
8757 # Allow some time for ovn-northd and ovn-controller to catch up.
8758 # XXX This should be more systematic.
8759 sleep 2
8760
8761 ip_to_hex() {
8762 printf "%02x%02x%02x%02x" "$@"
8763 }
8764
8765 reset_pcap_file() {
8766 local iface=$1
8767 local pcap_file=$2
8768 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8769 options:rxq_pcap=dummy-rx.pcap
8770 rm -f ${pcap_file}*.pcap
8771 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8772 options:rxq_pcap=${pcap_file}-rx.pcap
8773 }
8774
8775 test_ip_packet()
8776 {
8777 local active_gw=$1
8778 local backup_gw=$2
8779
8780 # Send ip packet between foo1 and outside1
8781 src_mac="f00000010203" # foo1 mac
8782 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8783 src_ip=`ip_to_hex 192 168 1 2`
8784 dst_ip=`ip_to_hex 172 16 1 3`
8785 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8786
8787 # ARP request packet to expect at outside1
8788 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8789
8790 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8791
8792 # Send ARP reply from outside1 back to the router
8793 # XXX: note, we could avoid this if we plug this port into a netns
8794 # and setup the IP address into the port, so the kernel would simply reply
8795 src_mac="000002010203"
8796 reply_mac="f00000010204"
8797 dst_ip=`ip_to_hex 172 16 1 3`
8798 src_ip=`ip_to_hex 172 16 1 1`
8799 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8800
8801 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8802
8803 OVS_WAIT_UNTIL([
8804 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8805 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8806 ])
8807
8808 # Packet to Expect at ext1 chassis, outside1 port
8809 src_mac="000002010203"
8810 dst_mac="f00000010204"
8811 src_ip=`ip_to_hex 192 168 1 2`
8812 dst_ip=`ip_to_hex 172 16 1 3`
8813 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8814 echo $expected > ext1-vif1.expected
8815
8816 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8817 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8818 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8819
8820 # Resend packet from foo1 to outside1
8821 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8822
8823 sleep 1
8824
8825 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8826 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8827 AT_CHECK([grep $expected packets | sort], [0], [expout])
8828 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8829 AT_CHECK([grep $expected packets | sort], [0], [])
8830 }
8831
8832 test_ip_packet gw1 gw2
8833
8834 ovn-nbctl --timeout=3 --wait=hv \
8835 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8836 chassis_name=gw1 \
8837 priority=10 -- \
8838 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8839 chassis_name=gw2 \
8840 priority=20 -- \
8841 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8842
8843 test_ip_packet gw2 gw1
8844
8845 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8846 AT_CLEANUP
8847
8848 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8849 AT_SKIP_IF([test $HAVE_PYTHON = no])
8850 ovn_start
8851
8852 # Logical network:
8853 # One LR R1 that has switches foo (192.168.1.0/24) and
8854 # alice (172.16.1.0/24) connected to it. The logical port
8855 # between R1 and alice has a "redirect-chassis" specified,
8856 # i.e. it is the distributed router gateway port.
8857 # Switch alice also has a localnet port defined.
8858 # An additional switch outside has a localnet port and the
8859 # same subnet as alice (172.16.1.0/24).
8860
8861 # Physical network:
8862 # Three hypervisors hv[123].
8863 # hv1 hosts vif foo1.
8864 # hv2 is the "redirect-chassis" that hosts the distributed
8865 # router gateway port.
8866 # hv3 hosts vif outside1.
8867 # In order to show that connectivity works only through hv2,
8868 # an initial round of tests is run without any bridge-mapping
8869 # defined for the localnet on hv2. These tests are expected
8870 # to fail.
8871 # Subsequent tests are run after defining the bridge-mapping
8872 # for the localnet on hv2. These tests are expected to succeed.
8873
8874 # Create three hypervisors and create OVS ports corresponding
8875 # to logical ports.
8876 net_add n1
8877
8878 sim_add hv1
8879 as hv1
8880 ovs-vsctl add-br br-phys
8881 ovn_attach n1 br-phys 192.168.0.1
8882 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8883 set interface hv1-vif1 external-ids:iface-id=foo1 \
8884 options:tx_pcap=hv1/vif1-tx.pcap \
8885 options:rxq_pcap=hv1/vif1-rx.pcap \
8886 ofport-request=1
8887
8888 sim_add hv2
8889 as hv2
8890 ovs-vsctl add-br br-phys
8891 ovn_attach n1 br-phys 192.168.0.2
8892
8893 sim_add hv3
8894 as hv3
8895 ovs-vsctl add-br br-phys
8896 ovn_attach n1 br-phys 192.168.0.3
8897 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8898 set interface hv3-vif1 external-ids:iface-id=outside1 \
8899 options:tx_pcap=hv3/vif1-tx.pcap \
8900 options:rxq_pcap=hv3/vif1-rx.pcap \
8901 ofport-request=1
8902
8903 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8904 # packets for ARP resolution (native tunneling doesn't queue packets
8905 # for ARP resolution).
8906 OVN_POPULATE_ARP
8907
8908 ovn-nbctl create Logical_Router name=R1
8909
8910 ovn-nbctl ls-add foo
8911 ovn-nbctl ls-add alice
8912 ovn-nbctl ls-add outside
8913
8914 # Connect foo to R1
8915 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8916 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8917 type=router options:router-port=foo \
8918 -- lsp-set-addresses rp-foo router
8919
8920 # Connect alice to R1 as distributed router gateway port on hv2
8921 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8922 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8923 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8924 type=router options:router-port=alice \
8925 -- lsp-set-addresses rp-alice router
8926
8927 # Create logical port foo1 in foo
8928 ovn-nbctl lsp-add foo foo1 \
8929 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8930
8931 # Create logical port outside1 in outside
8932 ovn-nbctl lsp-add outside outside1 \
8933 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8934
8935 # Create localnet port in alice
8936 ovn-nbctl lsp-add alice ln-alice
8937 ovn-nbctl lsp-set-addresses ln-alice unknown
8938 ovn-nbctl lsp-set-type ln-alice localnet
8939 ovn-nbctl lsp-set-options ln-alice network_name=phys
8940
8941 # Create localnet port in outside
8942 ovn-nbctl lsp-add outside ln-outside
8943 ovn-nbctl lsp-set-addresses ln-outside unknown
8944 ovn-nbctl lsp-set-type ln-outside localnet
8945 ovn-nbctl lsp-set-options ln-outside network_name=phys
8946
8947 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8948 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8949 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8950
8951
8952 # Allow some time for ovn-northd and ovn-controller to catch up.
8953 # XXX This should be more systematic.
8954 sleep 2
8955
8956 echo "---------NB dump-----"
8957 ovn-nbctl show
8958 echo "---------------------"
8959 ovn-nbctl list logical_router
8960 echo "---------------------"
8961 ovn-nbctl list logical_router_port
8962 echo "---------------------"
8963
8964 echo "---------SB dump-----"
8965 ovn-sbctl list datapath_binding
8966 echo "---------------------"
8967 ovn-sbctl list port_binding
8968 echo "---------------------"
8969 ovn-sbctl dump-flows
8970 echo "---------------------"
8971 ovn-sbctl list chassis
8972 ovn-sbctl list encap
8973 echo "------ Gateway_Chassis dump (SBDB) -------"
8974 ovn-sbctl list Gateway_Chassis
8975 echo "------ Port_Binding chassisredirect -------"
8976 ovn-sbctl find Port_Binding type=chassisredirect
8977 echo "-------------------------------------------"
8978
8979 echo "------ hv1 dump ----------"
8980 as hv1 ovs-ofctl show br-int
8981 as hv1 ovs-ofctl dump-flows br-int
8982 echo "------ hv2 dump ----------"
8983 as hv2 ovs-ofctl show br-int
8984 as hv2 ovs-ofctl dump-flows br-int
8985 echo "------ hv3 dump ----------"
8986 as hv3 ovs-ofctl show br-int
8987 as hv3 ovs-ofctl dump-flows br-int
8988 echo "--------------------------"
8989
8990
8991 # Check that redirect mapping is programmed only on hv2
8992 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8993 ])
8994 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8995 ])
8996 # Check that hv1 sends chassisredirect port traffic to hv2
8997 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8998 ])
8999 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9000 ])
9001 # Check that arp reply on distributed gateway port is only programmed on hv2
9002 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
9003 ])
9004 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
9005 ])
9006
9007
9008 ip_to_hex() {
9009 printf "%02x%02x%02x%02x" "$@"
9010 }
9011
9012
9013 : > hv2-vif1.expected
9014 : > hv3-vif1.expected
9015
9016 # test_arp INPORT SHA SPA TPA [REPLY_HA]
9017 #
9018 # Causes a packet to be received on INPORT. The packet is an ARP
9019 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
9020 # it should be the hardware address of the target to expect to receive in an
9021 # ARP reply; otherwise no reply is expected.
9022 #
9023 # INPORT is an logical switch port number, e.g. 11 for vif11.
9024 # SHA and REPLY_HA are each 12 hex digits.
9025 # SPA and TPA are each 8 hex digits.
9026 test_arp() {
9027 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
9028 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
9029 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
9030
9031 if test X$reply_ha != X; then
9032 # Expect to receive the reply, if any.
9033 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
9034 echo $reply >> hv${hv}-vif$inport.expected
9035 fi
9036 }
9037
9038 rtr_ip=$(ip_to_hex 172 16 1 1)
9039 foo_ip=$(ip_to_hex 192 168 1 2)
9040 outside_ip=$(ip_to_hex 172 16 1 3)
9041
9042 echo $rtr_ip
9043 echo $foo_ip
9044 echo $outside_ip
9045
9046 # ARP for router IP address from outside1, no response expected
9047 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
9048
9049 # Now check the packets actually received against the ones expected.
9050 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9051
9052 # Send ip packet between foo1 and outside1
9053 src_mac="f00000010203"
9054 dst_mac="000001010203"
9055 src_ip=`ip_to_hex 192 168 1 2`
9056 dst_ip=`ip_to_hex 172 16 1 3`
9057 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9058
9059 # Now check the packets actually received against the ones expected.
9060 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9061
9062 # Now add bridge-mappings on hv2, which should make everything work
9063 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9064
9065 # Allow some time for ovn-northd and ovn-controller to catch up.
9066 # XXX This should be more systematic.
9067 sleep 2
9068
9069 # ARP for router IP address from outside1
9070 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
9071
9072 # Now check the packets actually received against the ones expected.
9073 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9074
9075 # Send ip packet between foo1 and outside1
9076 src_mac="f00000010203"
9077 dst_mac="000001010203"
9078 src_ip=`ip_to_hex 192 168 1 2`
9079 dst_ip=`ip_to_hex 172 16 1 3`
9080 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9081
9082 # Packet to Expect at outside1
9083 src_mac="000002010203"
9084 dst_mac="f00000010204"
9085 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9086
9087 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9088
9089 echo "------ hv1 dump ----------"
9090 as hv1 ovs-ofctl show br-int
9091 as hv1 ovs-ofctl dump-flows br-int
9092 echo "------ hv2 dump ----------"
9093 as hv2 ovs-ofctl show br-int
9094 as hv2 ovs-ofctl dump-flows br-int
9095 echo "------ hv3 dump ----------"
9096 as hv3 ovs-ofctl show br-int
9097 as hv3 ovs-ofctl dump-flows br-int
9098 echo "----------------------------"
9099
9100 echo $expected >> hv3-vif1.expected
9101 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9102
9103 #Check ovn-trace over "chassisredirect" port
9104 AT_CAPTURE_FILE([trace])
9105 ovn_trace () {
9106 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
9107 }
9108
9109 echo 'ip.ttl--;' > expout
9110 echo 'eth.src = 00:00:02:01:02:03;' >> expout
9111 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
9112 echo 'output("ln-alice");' >> expout
9113 AT_CHECK_UNQUOTED([ovn_trace foo 'inport == "foo1" && eth.src == f0:00:00:01:02:03 && eth.dst == 00:00:01:01:02:03 && ip4.src == 192.168.1.2 && ip4.dst == 172.16.1.3 && ip.ttl == 0xff'], [0], [expout])
9114
9115 # Create logical port alice1 in alice on hv1
9116 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9117 set interface hv1-vif2 external-ids:iface-id=alice1 \
9118 options:tx_pcap=hv1/vif2-tx.pcap \
9119 options:rxq_pcap=hv1/vif2-rx.pcap \
9120 ofport-request=1
9121
9122 ovn-nbctl lsp-add alice alice1 \
9123 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
9124
9125 # Create logical port foo2 in foo on hv2
9126 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9127 set interface hv2-vif1 external-ids:iface-id=foo2 \
9128 options:tx_pcap=hv2/vif1-tx.pcap \
9129 options:rxq_pcap=hv2/vif1-rx.pcap \
9130 ofport-request=1
9131
9132 ovn-nbctl lsp-add foo foo2 \
9133 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
9134
9135 # Allow some time for ovn-northd and ovn-controller to catch up.
9136 # XXX This should be more systematic.
9137 sleep 1
9138
9139 : > hv1-vif2.expected
9140
9141 # Send ip packet between alice1 and foo2
9142 src_mac="f00000010205"
9143 dst_mac="000002010203"
9144 src_ip=`ip_to_hex 172 16 1 4`
9145 dst_ip=`ip_to_hex 192 168 1 3`
9146 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9147
9148 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
9149
9150 # Packet to Expect at foo2
9151 src_mac="000001010203"
9152 dst_mac="f00000010206"
9153 src_ip=`ip_to_hex 172 16 1 4`
9154 dst_ip=`ip_to_hex 192 168 1 3`
9155 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9156
9157 echo $expected >> hv2-vif1.expected
9158 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
9159
9160 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
9161 ])
9162
9163 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
9164
9165 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
9166 ])
9167
9168 OVN_CLEANUP([hv1],[hv2],[hv3])
9169
9170 AT_CLEANUP
9171
9172 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
9173 AT_SKIP_IF([test $HAVE_PYTHON = no])
9174 ovn_start
9175 # Create logical switches
9176 ovn-nbctl ls-add ls0
9177 ovn-nbctl ls-add ls1
9178 # Create distributed router
9179 ovn-nbctl create Logical_Router name=lr0
9180 # Add distributed gateway port to distributed router
9181 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
9182 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
9183 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9184 type=router options:router-port=lrp0 addresses="router"
9185 # Add router port to ls1
9186 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9187 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9188 type=router options:router-port=lrp1 addresses="router"
9189 # Add logical ports for NAT rules
9190 ovn-nbctl lsp-add ls1 foo1 \
9191 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
9192 ovn-nbctl lsp-add ls1 foo2 \
9193 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
9194 # Add nat-addresses option
9195 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9196 # Add NAT rules
9197 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
9198 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
9199 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.3 10.0.0.3 foo1 f0:00:00:00:00:03])
9200 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.4 10.0.0.4 foo2 f0:00:00:00:00:04])
9201
9202 net_add n1
9203 sim_add hv1
9204 as hv1
9205 ovs-vsctl add-br br-phys
9206 ovn_attach n1 br-phys 192.168.0.1
9207
9208 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9209 AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
9210
9211 sim_add hv2
9212 as hv2
9213 ovs-vsctl add-br br-phys
9214 ovn_attach n1 br-phys 192.168.0.2
9215 # Initially test with no bridge-mapping on hv2, expect to receive no packets
9216
9217 sim_add hv3
9218 as hv3
9219 ovs-vsctl add-br br-phys
9220 ovn_attach n1 br-phys 192.168.0.3
9221 # Initially test with no bridge-mapping on hv3
9222
9223 # Create a localnet port.
9224 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9225 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9226 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9227 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9228
9229 # Allow some time for ovn-northd and ovn-controller to catch up.
9230 # XXX This should be more systematic.
9231 sleep 2
9232
9233 # Expect no packets when hv2 bridge-mapping is not present
9234 : > packets
9235 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
9236
9237 # Add bridge-mapping on hv2
9238 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9239
9240 # Wait for packets to be received.
9241 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9242 trim_zeros() {
9243 sed 's/\(00\)\{1,\}$//'
9244 }
9245 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9246 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
9247 echo $expected > expout
9248 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
9249 echo $expected >> expout
9250 AT_CHECK([sort packets], [0], [expout])
9251 sort packets | cat
9252
9253 # Temporarily remove nat-addresses option to avoid race conditions
9254 # due to GARP backoff
9255 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
9256
9257 reset_pcap_file() {
9258 local iface=$1
9259 local pcap_file=$2
9260 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9261 options:rxq_pcap=dummy-rx.pcap
9262 rm -f ${pcap_file}*.pcap
9263 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9264 options:rxq_pcap=${pcap_file}-rx.pcap
9265 }
9266
9267 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9268
9269 # Add OVS ports for foo1 and foo2 on hv3
9270 ovs-vsctl -- add-port br-int hv3-vif1 -- \
9271 set interface hv3-vif1 external-ids:iface-id=foo1 \
9272 ofport-request=1
9273 ovs-vsctl -- add-port br-int hv3-vif2 -- \
9274 set interface hv3-vif2 external-ids:iface-id=foo2 \
9275 ofport-request=2
9276
9277 # Add bridge-mapping on hv3
9278 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9279
9280 # Re-add nat-addresses option
9281 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9282
9283 # Wait for packets to be received.
9284 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
9285 trim_zeros() {
9286 sed 's/\(00\)\{1,\}$//'
9287 }
9288
9289 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9290 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
9291 echo $expected >> expout
9292 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
9293 echo $expected >> expout
9294 AT_CHECK([sort packets], [0], [expout])
9295 sort packets | cat
9296
9297 OVN_CLEANUP([hv1],[hv2],[hv3])
9298
9299 AT_CLEANUP
9300
9301 # VLAN traffic for external network redirected through distributed router
9302 # gateway port should use vlans(i.e input network vlan tag) across hypervisors
9303 # instead of tunneling.
9304 AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
9305 AT_SKIP_IF([test $HAVE_PYTHON = no])
9306 ovn_start
9307
9308 # Logical network:
9309 # # One LR R1 that has switches foo (192.168.1.0/24) and
9310 # # alice (172.16.1.0/24) connected to it. The logical port
9311 # # between R1 and alice has a "redirect-chassis" specified,
9312 # # i.e. it is the distributed router gateway port(172.16.1.6).
9313 # # Switch alice also has a localnet port defined.
9314 # # An additional switch outside has the same subnet as alice
9315 # # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
9316 # # which will receive the packet destined for external network
9317 # # (i.e 8.8.8.8 as destination ip).
9318
9319 # Physical network:
9320 # # Three hypervisors hv[123].
9321 # # hv1 hosts vif foo1.
9322 # # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
9323 # # hv3 hosts nexthop port vif outside1.
9324 # # All other tests connect hypervisors to network n1 through br-phys for tunneling.
9325 # # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
9326 # # in order to show vlans(instead of tunneling) used between hv1 and hv2,
9327 # # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
9328 # # hv2 and hv3 are still connected to n1 network through br-phys.
9329 net_add n1
9330
9331 # We are not calling ovn_attach for hv1, to avoid adding br-phys.
9332 # Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
9333 sim_add hv1
9334 as hv1
9335 ovs-vsctl \
9336 -- set Open_vSwitch . external-ids:system-id=hv1 \
9337 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
9338 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
9339 -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
9340 -- add-br br-int \
9341 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
9342 -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
9343
9344 start_daemon ovn-controller
9345 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9346 set interface hv1-vif1 external-ids:iface-id=foo1 \
9347 ofport-request=1
9348
9349 sim_add hv2
9350 as hv2
9351 ovs-vsctl add-br br-phys
9352 ovn_attach n1 br-phys 192.168.0.2
9353 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9354
9355 sim_add hv3
9356 as hv3
9357 ovs-vsctl add-br br-phys
9358 ovn_attach n1 br-phys 192.168.0.3
9359 ovs-vsctl -- add-port br-int hv3-vif1 -- \
9360 set interface hv3-vif1 external-ids:iface-id=outside1 \
9361 options:tx_pcap=hv3/vif1-tx.pcap \
9362 options:rxq_pcap=hv3/vif1-rx.pcap \
9363 ofport-request=1
9364 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
9365
9366 # Create network n2 for vlan connectivity between hv1 and hv2
9367 net_add n2
9368
9369 as hv1
9370 ovs-vsctl add-br br-ex
9371 net_attach n2 br-ex
9372
9373 as hv2
9374 ovs-vsctl add-br br-ex
9375 net_attach n2 br-ex
9376
9377 OVN_POPULATE_ARP
9378
9379 ovn-nbctl create Logical_Router name=R1
9380
9381 ovn-nbctl ls-add foo
9382 ovn-nbctl ls-add alice
9383 ovn-nbctl ls-add outside
9384
9385 # Connect foo to R1
9386 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
9387 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
9388 type=router options:router-port=foo \
9389 -- lsp-set-addresses rp-foo router
9390
9391 # Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
9392 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
9393 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
9394 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9395 type=router options:router-port=alice \
9396 -- lsp-set-addresses rp-alice router \
9397
9398 # Create logical port foo1 in foo
9399 ovn-nbctl lsp-add foo foo1 \
9400 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9401
9402 # Create logical port outside1 in outside, which is a nexthop address
9403 # for 172.16.1.0/24
9404 ovn-nbctl lsp-add outside outside1 \
9405 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
9406
9407 # Set default gateway (nexthop) to 172.16.1.1
9408 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
9409 AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
9410 ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
9411
9412 ovn-nbctl lsp-add foo ln-foo
9413 ovn-nbctl lsp-set-addresses ln-foo unknown
9414 ovn-nbctl lsp-set-options ln-foo network_name=public
9415 ovn-nbctl lsp-set-type ln-foo localnet
9416 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
9417
9418 # Create localnet port in alice
9419 ovn-nbctl lsp-add alice ln-alice
9420 ovn-nbctl lsp-set-addresses ln-alice unknown
9421 ovn-nbctl lsp-set-type ln-alice localnet
9422 ovn-nbctl lsp-set-options ln-alice network_name=phys
9423
9424 # Create localnet port in outside
9425 ovn-nbctl lsp-add outside ln-outside
9426 ovn-nbctl lsp-set-addresses ln-outside unknown
9427 ovn-nbctl lsp-set-type ln-outside localnet
9428 ovn-nbctl lsp-set-options ln-outside network_name=phys
9429
9430 # Allow some time for ovn-northd and ovn-controller to catch up.
9431 # XXX This should be more systematic.
9432 ovn-nbctl --wait=hv --timeout=3 sync
9433
9434 # Check that there is a logical flow in logical switch foo's pipeline
9435 # to set the outport to rp-foo (which is expected).
9436 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9437 grep rp-foo | grep -v is_chassis_resident | wc -l`])
9438
9439 # Set the option 'reside-on-redirect-chassis' for foo
9440 ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
9441 # Check that there is a logical flow in logical switch foo's pipeline
9442 # to set the outport to rp-foo with the condition is_chassis_redirect.
9443 ovn-sbctl dump-flows foo
9444 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9445 grep rp-foo | grep is_chassis_resident | wc -l`])
9446
9447 echo "---------NB dump-----"
9448 ovn-nbctl show
9449 echo "---------------------"
9450 ovn-nbctl list logical_router
9451 echo "---------------------"
9452 ovn-nbctl list nat
9453 echo "---------------------"
9454 ovn-nbctl list logical_router_port
9455 echo "---------------------"
9456
9457 echo "---------SB dump-----"
9458 ovn-sbctl list datapath_binding
9459 echo "---------------------"
9460 ovn-sbctl list port_binding
9461 echo "---------------------"
9462 ovn-sbctl dump-flows
9463 echo "---------------------"
9464 ovn-sbctl list chassis
9465 echo "---------------------"
9466
9467 for chassis in hv1 hv2 hv3; do
9468 as $chassis
9469 echo "------ $chassis dump ----------"
9470 ovs-vsctl show br-int
9471 ovs-ofctl show br-int
9472 ovs-ofctl dump-flows br-int
9473 echo "--------------------------"
9474 done
9475
9476 ip_to_hex() {
9477 printf "%02x%02x%02x%02x" "$@"
9478 }
9479
9480 foo1_ip=$(ip_to_hex 192 168 1 2)
9481 gw_ip=$(ip_to_hex 172 16 1 6)
9482 dst_ip=$(ip_to_hex 8 8 8 8)
9483 nexthop_ip=$(ip_to_hex 172 16 1 1)
9484
9485 foo1_mac="f00000010203"
9486 foo_mac="000001010203"
9487 gw_mac="000002010203"
9488 nexthop_mac="f00000010204"
9489
9490 # Send ip packet from foo1 to 8.8.8.8
9491 src_mac="f00000010203"
9492 dst_mac="000001010203"
9493 packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9494
9495 # Wait for GARPs announcing gw IP to arrive
9496 OVS_WAIT_UNTIL([
9497 test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
9498 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
9499 ])
9500
9501 # VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
9502 # is expected on bridge connecting hv1 and hv2
9503 expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9504 echo $expected > hv1-br-ex_n2.expected
9505
9506 # Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
9507 # As connection tracking not enabled for this test, snat can't be done on the packet.
9508 # We still see foo1 as the source ip address. But source mac(gateway MAC) and
9509 # dest mac(nexthop mac) are properly configured.
9510 expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
9511 echo $expected > hv3-vif1.expected
9512
9513 reset_pcap_file() {
9514 local iface=$1
9515 local pcap_file=$2
9516 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9517 options:rxq_pcap=dummy-rx.pcap
9518 rm -f ${pcap_file}*.pcap
9519 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9520 options:rxq_pcap=${pcap_file}-rx.pcap
9521 }
9522
9523 as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
9524 as hv3 reset_pcap_file hv3-vif1 hv3/vif1
9525 sleep 2
9526 # Take note of how many packets arrived on the VLAN switch before generating
9527 # further traffic
9528 n_packets=`as hv1 ovs-ofctl dump-flows br-int table=65 | grep "priority=100,reg15=0x1,metadata=0x2" | grep actions=clone | sed 's/.*n_packets=\([[0-9]]*\),.*/\1/'`
9529 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9530 sleep 2
9531
9532 # On hv1, the packet should not go from vlan switch pipleline to router
9533 # pipeline
9534 as hv1 ovs-ofctl dump-flows br-int
9535 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep "priority=100,reg15=0x1,metadata=0x2" \
9536 | grep actions=clone | grep -v n_packets=$n_packets | wc -l], [0], [[0
9537 ]])
9538
9539 # On hv1, table 32 check that no packet goes via the tunnel port
9540 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
9541 | grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
9542 ]])
9543
9544 ip_packet() {
9545 grep "1010203f00000010203"
9546 }
9547
9548 # Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
9549 # foo1's mac.
9550 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
9551 cat hv1-br-ex_n2.expected > expout
9552 AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
9553
9554 # Check expected packet on nexthop interface
9555 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
9556 cat hv3-vif1.expected > expout
9557 AT_CHECK([sort hv3-vif1], [0], [expout])
9558
9559 OVN_CLEANUP([hv1],[hv2],[hv3])
9560 AT_CLEANUP
9561
9562 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
9563 AT_KEYWORDS([ovn-nd_ra])
9564 AT_SKIP_IF([test $HAVE_PYTHON = no])
9565 ovn_start
9566
9567 # In this test case we create 1 lswitch with 3 VIF ports attached,
9568 # and a lrouter connected to the lswitch.
9569 # We generate the Router solicitation packet and verify the Router Advertisement
9570 # reply packet from the ovn-controller.
9571
9572 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
9573 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
9574 # 'slaac' to allow lrp0 send RA for SLAAC mode.
9575 ovn-nbctl ls-add lsw0
9576 ovn-nbctl lr-add lr0
9577 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
9578 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
9579 ovn-nbctl \
9580 -- lsp-add lsw0 lsp0 \
9581 -- set Logical_Switch_Port lsp0 type=router \
9582 options:router-port=lrp0 \
9583 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
9584 net_add n1
9585 sim_add hv1
9586 as hv1
9587 ovs-vsctl add-br br-phys
9588 ovn_attach n1 br-phys 192.168.0.2
9589
9590 ovn-nbctl lsp-add lsw0 lp1
9591 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9592 ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9593
9594 ovn-nbctl lsp-add lsw0 lp2
9595 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9596 ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9597
9598 ovn-nbctl lsp-add lsw0 lp3
9599 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9600 ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9601
9602 # Add ACL rule for ICMPv6 on lsw0
9603 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
9604 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
9605 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
9606 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
9607
9608 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9609 set interface hv1-vif1 external-ids:iface-id=lp1 \
9610 options:tx_pcap=hv1/vif1-tx.pcap \
9611 options:rxq_pcap=hv1/vif1-rx.pcap \
9612 ofport-request=1
9613
9614 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9615 set interface hv1-vif2 external-ids:iface-id=lp2 \
9616 options:tx_pcap=hv1/vif2-tx.pcap \
9617 options:rxq_pcap=hv1/vif2-rx.pcap \
9618 ofport-request=2
9619
9620 ovs-vsctl -- add-port br-int hv1-vif3 -- \
9621 set interface hv1-vif3 external-ids:iface-id=lp3 \
9622 options:tx_pcap=hv1/vif3-tx.pcap \
9623 options:rxq_pcap=hv1/vif3-rx.pcap \
9624 ofport-request=3
9625
9626 # Allow some time for ovn-northd and ovn-controller to catch up.
9627 # XXX This should be more systematic.
9628 sleep 1
9629
9630 reset_pcap_file() {
9631 local iface=$1
9632 local pcap_file=$2
9633 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9634 options:rxq_pcap=dummy-rx.pcap
9635 rm -f ${pcap_file}*.pcap
9636 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9637 options:rxq_pcap=${pcap_file}-rx.pcap
9638 }
9639
9640 # Make sure that ovn-controller has installed the corresponding OF Flow.
9641 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9642
9643 # This shell function sends a Router Solicitation packet.
9644 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
9645 test_ipv6_ra() {
9646 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
9647 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
9648
9649 local len=24
9650 local mtu_opt=""
9651 if test $mtu != 0; then
9652 len=`expr $len + 8`
9653 mtu_opt=05010000${mtu}
9654 fi
9655
9656 if test ${#prefix_opt} != 0; then
9657 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
9658 len=`expr $len + ${#prefix_opt} / 2`
9659 fi
9660
9661 len=$(printf "%x" $len)
9662 local lrp_mac=fa163e000001
9663 local lrp_lla=fe80000000000000f8163efffe000001
9664 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
9665 echo $reply >> $inport.expected
9666
9667 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
9668 }
9669
9670 AT_CAPTURE_FILE([ofctl_monitor0.log])
9671 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
9672 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
9673
9674 # MTU is not set and the address mode is set to slaac
9675 addr_mode=00
9676 default_prefix_option_config=030440c0ffffffffffffffff00000000
9677 src_mac=fa163e000002
9678 src_lla=fe80000000000000f8163efffe000002
9679 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
9680
9681 # NXT_RESUME should be 1.
9682 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9683
9684 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9685
9686 cat 1.expected | cut -c -112 > expout
9687 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9688
9689 # Skipping the ICMPv6 checksum.
9690 cat 1.expected | cut -c 117- > expout
9691 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9692
9693 rm -f *.expected
9694 reset_pcap_file hv1-vif1 hv1/vif1
9695 reset_pcap_file hv1-vif2 hv1/vif2
9696 reset_pcap_file hv1-vif3 hv1/vif3
9697
9698 # Set the MTU to 1500
9699 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
9700
9701 # Make sure that ovn-controller has installed the corresponding OF Flow.
9702 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9703
9704 addr_mode=00
9705 default_prefix_option_config=030440c0ffffffffffffffff00000000
9706 src_mac=fa163e000003
9707 src_lla=fe80000000000000f8163efffe000003
9708 mtu=000005dc
9709
9710 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9711
9712 # NXT_RESUME should be 2.
9713 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9714
9715 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
9716
9717 cat 2.expected | cut -c -112 > expout
9718 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9719
9720 # Skipping the ICMPv6 checksum.
9721 cat 2.expected | cut -c 117- > expout
9722 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9723
9724 rm -f *.expected
9725 reset_pcap_file hv1-vif1 hv1/vif1
9726 reset_pcap_file hv1-vif2 hv1/vif2
9727 reset_pcap_file hv1-vif3 hv1/vif3
9728
9729 # Set the address mode to dhcpv6_stateful
9730 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
9731 # Make sure that ovn-controller has installed the corresponding OF Flow.
9732 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9733
9734 addr_mode=80
9735 default_prefix_option_config=03044080ffffffffffffffff00000000
9736 src_mac=fa163e000004
9737 src_lla=fe80000000000000f8163efffe000004
9738 mtu=000005dc
9739
9740 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9741
9742 # NXT_RESUME should be 3.
9743 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9744
9745 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
9746
9747 cat 3.expected | cut -c -112 > expout
9748 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
9749
9750 # Skipping the ICMPv6 checksum.
9751 cat 3.expected | cut -c 117- > expout
9752 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
9753
9754 rm -f *.expected
9755 reset_pcap_file hv1-vif1 hv1/vif1
9756 reset_pcap_file hv1-vif2 hv1/vif2
9757 reset_pcap_file hv1-vif3 hv1/vif3
9758
9759 # Set the address mode to dhcpv6_stateless
9760 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
9761 # Make sure that ovn-controller has installed the corresponding OF Flow.
9762 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9763
9764 addr_mode=40
9765 default_prefix_option_config=030440c0ffffffffffffffff00000000
9766 src_mac=fa163e000002
9767 src_lla=fe80000000000000f8163efffe000002
9768 mtu=000005dc
9769
9770 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9771
9772 # NXT_RESUME should be 4.
9773 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9774
9775 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9776
9777 cat 1.expected | cut -c -112 > expout
9778 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9779
9780 # Skipping the ICMPv6 checksum.
9781 cat 1.expected | cut -c 117- > expout
9782 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9783
9784 rm -f *.expected
9785 reset_pcap_file hv1-vif1 hv1/vif1
9786 reset_pcap_file hv1-vif2 hv1/vif2
9787 reset_pcap_file hv1-vif3 hv1/vif3
9788
9789 # Set the address mode to invalid.
9790 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
9791 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
9792 OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
9793
9794 addr_mode=40
9795 default_prefix_option_config=""
9796 src_mac=fa163e000002
9797 src_lla=fe80000000000000f8163efffe000002
9798 mtu=000005dc
9799
9800 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9801
9802 # NXT_RESUME should be 4 only.
9803 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9804
9805 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9806 AT_CHECK([cat 1.packets], [0], [])
9807
9808 OVN_CLEANUP([hv1])
9809 AT_CLEANUP
9810
9811 AT_SETUP([ovn -- /32 router IP address])
9812 AT_SKIP_IF([test $HAVE_PYTHON = no])
9813 ovn_start
9814
9815 # Logical network:
9816 # 2 LS 'foo' and 'alice' connected via router R1.
9817 # R1 connects to 'alice' with a /32 IP address. We use static routes and
9818 # nexthop to push traffic to a logical port in switch 'alice'
9819
9820 ovn-nbctl lr-add R1
9821
9822 ovn-nbctl ls-add foo
9823 ovn-nbctl ls-add alice
9824
9825 # Connect foo to R1
9826 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
9827 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
9828 options:router-port=foo addresses=\"00:00:00:01:02:03\"
9829
9830 # Connect alice to R1.
9831 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
9832 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9833 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
9834
9835 # Create logical port foo1 in foo
9836 ovn-nbctl lsp-add foo foo1 \
9837 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9838
9839 # Create logical port alice1 in alice
9840 ovn-nbctl lsp-add alice alice1 \
9841 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
9842
9843 #install default route in R1 to use alice1's IP address as nexthop
9844 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
9845
9846 # Create two hypervisor and create OVS ports corresponding to logical ports.
9847 net_add n1
9848
9849 sim_add hv1
9850 as hv1
9851 ovs-vsctl add-br br-phys
9852 ovn_attach n1 br-phys 192.168.0.1
9853 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9854 set interface hv1-vif1 external-ids:iface-id=foo1 \
9855 options:tx_pcap=hv1/vif1-tx.pcap \
9856 options:rxq_pcap=hv1/vif1-rx.pcap \
9857 ofport-request=1
9858
9859 sim_add hv2
9860 as hv2
9861 ovs-vsctl add-br br-phys
9862 ovn_attach n1 br-phys 192.168.0.2
9863 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9864 set interface hv2-vif1 external-ids:iface-id=alice1 \
9865 options:tx_pcap=hv2/vif1-tx.pcap \
9866 options:rxq_pcap=hv2/vif1-rx.pcap \
9867 ofport-request=1
9868
9869
9870 # Pre-populate the hypervisors' ARP tables so that we don't lose any
9871 # packets for ARP resolution (native tunneling doesn't queue packets
9872 # for ARP resolution).
9873 OVN_POPULATE_ARP
9874
9875 # Allow some time for ovn-northd and ovn-controller to catch up.
9876 # XXX This should be more systematic.
9877 sleep 1
9878
9879 ip_to_hex() {
9880 printf "%02x%02x%02x%02x" "$@"
9881 }
9882
9883 # Send ip packets between foo1 and alice1
9884 src_mac="f00000010203"
9885 dst_mac="000000010203"
9886 src_ip=`ip_to_hex 192 168 1 2`
9887 dst_ip=`ip_to_hex 10 0 0 2`
9888 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9889
9890 # Send the first packet to trigger a ARP response and population of
9891 # mac_bindings table.
9892 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9893 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
9894 ovn-nbctl --wait=hv sync
9895
9896 # Packet to Expect at 'alice1'
9897 src_mac="000000010204"
9898 dst_mac="f00000010204"
9899 src_ip=`ip_to_hex 192 168 1 2`
9900 dst_ip=`ip_to_hex 10 0 0 2`
9901 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
9902
9903 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
9904
9905 OVN_CLEANUP([hv1],[hv2])
9906
9907 AT_CLEANUP
9908
9909 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
9910 AT_SKIP_IF([test $HAVE_PYTHON = no])
9911 ovn_start
9912
9913 ovn-nbctl ls-add ls1
9914
9915 # Add localport to the switch
9916 ovn-nbctl lsp-add ls1 lp01
9917 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
9918 ovn-nbctl lsp-set-type lp01 localport
9919
9920 net_add n1
9921
9922 for i in 1 2; do
9923 sim_add hv$i
9924 as hv$i
9925 ovs-vsctl add-br br-phys
9926 ovn_attach n1 br-phys 192.168.0.$i
9927 ovs-vsctl add-port br-int vif01 -- \
9928 set Interface vif01 external-ids:iface-id=lp01 \
9929 options:tx_pcap=hv${i}/vif01-tx.pcap \
9930 options:rxq_pcap=hv${i}/vif01-rx.pcap \
9931 ofport-request=${i}0
9932
9933 ovs-vsctl add-port br-int vif${i}1 -- \
9934 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
9935 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
9936 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
9937 ofport-request=${i}1
9938
9939 ovn-nbctl lsp-add ls1 lp${i}1
9940 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
9941 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
9942
9943 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
9944 done
9945
9946 ovn-nbctl --wait=sb sync
9947 ovn-sbctl dump-flows
9948
9949 OVN_POPULATE_ARP
9950
9951 # Given the name of a logical port, prints the name of the hypervisor
9952 # on which it is located.
9953 vif_to_hv() {
9954 echo hv${1%?}
9955 }
9956 #
9957 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
9958 #
9959 # This shell function causes a packet to be received on INPORT. The packet's
9960 # content has Ethernet destination DST and source SRC (each exactly 12 hex
9961 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
9962 # logical switch port numbers, e.g. 11 for vif11.
9963 #
9964 # EOUT is the end-to-end output port, that is, where the packet will end up
9965 # after possibly bouncing through one or more localnet ports. LOUT is the
9966 # logical output port, which might be a localnet port, as seen by ovn-trace
9967 # (which doesn't know what localnet ports are connected to and therefore can't
9968 # figure out the end-to-end answer).
9969 #
9970 # DEFHV is the default hypervisor from where the packet is going to be sent
9971 # if the source port is a localport.
9972 for i in 1 2; do
9973 for j in 0 1; do
9974 : > $i$j.expected
9975 done
9976 done
9977 test_packet() {
9978 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
9979 echo "$@"
9980
9981 # First try tracing the packet.
9982 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
9983 if test $lout != drop; then
9984 echo "output(\"$lout\");"
9985 fi > expout
9986 AT_CAPTURE_FILE([trace])
9987 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
9988
9989 # Then actually send a packet, for an end-to-end test.
9990 local packet=$(echo $dst$src | sed 's/://g')${eth}
9991 hv=`vif_to_hv $inport`
9992 # If hypervisor 0 (localport) use the defhv parameter
9993 if test $hv = hv0; then
9994 hv=$defhv
9995 fi
9996 vif=vif$inport
9997 as $hv ovs-appctl netdev-dummy/receive $vif $packet
9998 if test $eout != drop; then
9999 echo $packet >> ${eout#lp}.expected
10000 fi
10001 }
10002
10003
10004 # lp11 and lp21 are on different hypervisors
10005 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
10006 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
10007
10008 # Both VIFs should be able to reach the localport on their own HV
10009 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
10010 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
10011
10012 # Packet sent from localport on same hv should reach the vif
10013 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
10014 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
10015
10016 # Packet sent from localport on different hv should be dropped
10017 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
10018 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
10019
10020 # Now check the packets actually received against the ones expected.
10021 for i in 1 2; do
10022 for j in 0 1; do
10023 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
10024 done
10025 done
10026
10027 OVN_CLEANUP([hv1],[hv2])
10028
10029 AT_CLEANUP
10030
10031 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
10032 AT_SKIP_IF([test $HAVE_PYTHON = no])
10033 ovn_start
10034
10035 net_add n1
10036
10037 # create gateways with external network connectivity
10038
10039 for i in 1 2; do
10040 sim_add gw$i
10041 as gw$i
10042 ovs-vsctl add-br br-phys
10043 ovn_attach n1 br-phys 192.168.0.$i
10044 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10045 done
10046
10047 ovn-nbctl ls-add inside
10048 ovn-nbctl ls-add outside
10049
10050 # create hypervisors with a vif port each to an internal network
10051
10052 for i in 1 2; do
10053 sim_add hv$i
10054 as hv$i
10055 ovs-vsctl add-br br-phys
10056 ovn_attach n1 br-phys 192.168.0.1$i
10057 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10058 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10059 options:tx_pcap=hv$i/vif1-tx.pcap \
10060 options:rxq_pcap=hv$i/vif1-rx.pcap \
10061 ofport-request=1
10062
10063 ovn-nbctl lsp-add inside inside$i \
10064 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
10065
10066 done
10067
10068 OVN_POPULATE_ARP
10069
10070 ovn-nbctl create Logical_Router name=R1
10071
10072 # Connect inside to R1
10073 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10074 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10075 type=router options:router-port=inside \
10076 -- lsp-set-addresses rp-inside router
10077
10078 # Connect outside to R1 as distributed router gateway port on gw1+gw2
10079 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10080
10081 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10082 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10083 --id=@gc1 create Gateway_Chassis \
10084 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10085 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10086
10087 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10088 type=router options:router-port=outside \
10089 -- lsp-set-addresses rp-outside router
10090
10091 # Create localnet port in outside
10092 ovn-nbctl lsp-add outside ln-outside
10093 ovn-nbctl lsp-set-addresses ln-outside unknown
10094 ovn-nbctl lsp-set-type ln-outside localnet
10095 ovn-nbctl lsp-set-options ln-outside network_name=phys
10096
10097 # Allow some time for ovn-northd and ovn-controller to catch up.
10098 # XXX This should be more systematic.
10099 ovn-nbctl --wait=hv --timeout=3 sync
10100
10101 echo "---------NB dump-----"
10102 ovn-nbctl show
10103 echo "---------------------"
10104 ovn-nbctl list logical_router
10105 echo "---------------------"
10106 ovn-nbctl list logical_router_port
10107 echo "---------------------"
10108
10109 echo "---------SB dump-----"
10110 ovn-sbctl list datapath_binding
10111 echo "---------------------"
10112 ovn-sbctl list port_binding
10113 echo "---------------------"
10114 ovn-sbctl dump-flows
10115 echo "---------------------"
10116 ovn-sbctl list chassis
10117 ovn-sbctl list encap
10118 echo "---------------------"
10119 echo "------ Gateway_Chassis dump (SBDB) -------"
10120 ovn-sbctl list Gateway_Chassis
10121 echo "------ Port_Binding chassisredirect -------"
10122 ovn-sbctl find Port_Binding type=chassisredirect
10123 echo "-------------------------------------------"
10124
10125 # There should be one ha_chassis_group with the name "outside"
10126 ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
10127 ha_chassis_group name="outside"`
10128
10129 AT_CHECK([test $ha_chassi_grp_name = outside])
10130
10131 # There should be 2 ha_chassis rows in SB DB.
10132 AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | \
10133 grep -v chassis-name | awk '{print $3}' \
10134 | grep '-' | wc -l ], [0], [2
10135 ])
10136
10137 ha_ch=`ovn-sbctl --bare --columns ha_chassis find ha_chassis_group`
10138 # Trim the spaces.
10139 ha_ch=`echo $ha_ch | sed 's/ //g'`
10140
10141 ha_ch_list=''
10142 for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
10143 do
10144 ha_ch_list="$ha_ch_list $i"
10145 done
10146
10147 # Trim the spaces.
10148 ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
10149
10150 AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
10151
10152 for chassis in gw1 gw2 hv1 hv2; do
10153 as $chassis
10154 echo "------ $chassis dump ----------"
10155 ovs-ofctl show br-int
10156 ovs-ofctl dump-flows br-int
10157 echo "--------------------------"
10158 done
10159 bfd_dump() {
10160 for chassis in gw1 gw2 hv1 hv2; do
10161 as $chassis
10162 echo "------ $chassis dump (BFD)----"
10163 echo "BFD (from $chassis):"
10164 # dump BFD config and status to the other chassis
10165 for chassis2 in gw1 gw2 hv1 hv2; do
10166 if [[ "$chassis" != "$chassis2" ]]; then
10167 echo " -> $chassis2:"
10168 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
10169 fi
10170 done
10171 echo "--------------------------"
10172 done
10173 }
10174
10175 bfd_dump
10176
10177 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10178 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10179 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10180 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10181
10182 echo $hv1_gw1_ofport
10183 echo $hv1_gw2_ofport
10184 echo $hv2_gw1_ofport
10185 echo $hv2_gw2_ofport
10186
10187 echo "--- hv1 ---"
10188 as hv1 ovs-ofctl dump-flows br-int table=32
10189
10190 echo "--- hv2 ---"
10191 as hv2 ovs-ofctl dump-flows br-int table=32
10192
10193 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
10194 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10195
10196 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10197 grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10198 | wc -l], [0], [1
10199 ])
10200
10201 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10202 grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10203 | wc -l], [0], [1
10204 ])
10205
10206 # make sure that flows for handling the outside router port reside on gw1
10207 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10208 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10209 ]])
10210 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10211 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10212 ]])
10213
10214 # make sure ARP responder flows for outside router port reside on gw1 too
10215 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10216 grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10217 ]])
10218 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10219 ]])
10220
10221 # check that the chassis redirect port has been claimed by the gw1 chassis
10222 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10223 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10224 ]])
10225
10226 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10227 hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10228
10229 exp_ref_ch_list=''
10230 for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10231 do
10232 if test $i = $hv1_ch_uuid; then
10233 exp_ref_ch_list="${exp_ref_ch_list}$i"
10234 elif test $i = $hv2_ch_uuid; then
10235 exp_ref_ch_list="${exp_ref_ch_list}$i"
10236 fi
10237 done
10238
10239 OVS_WAIT_UNTIL(
10240 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10241 # Trim the spaces.
10242 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10243 test "$exp_ref_ch_list" = "$ref_ch_list"])
10244
10245
10246 # at this point, we invert the priority of the gw chassis between gw1 and gw2
10247
10248 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10249 name=outside_gw1 chassis_name=gw1 priority=10 -- \
10250 --id=@gc1 create Gateway_Chassis \
10251 name=outside_gw2 chassis_name=gw2 priority=20 -- \
10252 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10253
10254
10255 # XXX: Let the change propagate down to the ovn-controllers
10256 ovn-nbctl --wait=hv --timeout=3 sync
10257
10258 # we make sure that the hypervisors noticed, and inverted the slave ports
10259 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10260 grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10261 | wc -l], [0], [1
10262 ])
10263
10264 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10265 grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10266 | wc -l], [0], [1
10267 ])
10268
10269 # check that the chassis redirect port has been reclaimed by the gw2 chassis
10270 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10271 logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10272 ]])
10273
10274 # check BFD enablement on tunnel ports from gw1 #########
10275 as gw1
10276 for chassis in gw2 hv1 hv2; do
10277 echo "checking gw1 -> $chassis"
10278 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10279 [[enable=true
10280 ]])
10281 done
10282
10283
10284 # check BFD enablement on tunnel ports from gw2 ##########
10285 as gw2
10286 for chassis in gw1 hv1 hv2; do
10287 echo "checking gw2 -> $chassis"
10288 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10289 [[enable=true
10290 ]])
10291 done
10292
10293 # check BFD enablement on tunnel ports from hv1 ###########
10294 as hv1
10295 for chassis in gw1 gw2; do
10296 echo "checking hv1 -> $chassis"
10297 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10298 [[enable=true
10299 ]])
10300 done
10301 # make sure BFD is not enabled to hv2, we don't need it
10302 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10303 [[
10304 ]])
10305
10306
10307 # check BFD enablement on tunnel ports from hv2 ##########
10308 as hv2
10309 for chassis in gw1 gw2; do
10310 echo "checking hv2 -> $chassis"
10311 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10312 [[enable=true
10313 ]])
10314 done
10315 # make sure BFD is not enabled to hv1, we don't need it
10316 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10317 [[
10318 ]])
10319
10320 # make sure that flows for handling the outside router port reside on gw2 now
10321 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10322 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10323 ]])
10324 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10325 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10326 ]])
10327
10328 # disconnect GW2 from the network, GW1 should take over
10329 as gw2
10330 port=${sandbox}_br-phys
10331 as main ovs-vsctl del-port n1 $port
10332
10333 bfd_dump
10334
10335 # make sure that flows for handling the outside router port reside on gw2 now
10336 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10337 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10338 ]])
10339 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10340 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10341 ]])
10342
10343 # check that the chassis redirect port has been reclaimed by the gw1 chassis
10344 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10345 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10346 ]])
10347
10348 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
10349 as gw2
10350 for chassis in gw1 hv1 hv2; do
10351 echo "checking gw2 -> $chassis"
10352 OVS_WAIT_UNTIL([
10353 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10354 test "$bfd_cfg" = "enable=true min_rx=2000"
10355 ])
10356 done
10357 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
10358 for chassis in gw1 hv1 hv2; do
10359 echo "checking gw2 -> $chassis"
10360 OVS_WAIT_UNTIL([
10361 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10362 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
10363 ])
10364 done
10365 ovn-nbctl remove NB_Global . options "bfd-min-rx"
10366 ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
10367 for chassis in gw1 hv1 hv2; do
10368 echo "checking gw2 -> $chassis"
10369 OVS_WAIT_UNTIL([
10370 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10371 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
10372 ])
10373 done
10374
10375 # Delete the inside1 vif. The ref_chassis in ha_chassis_group shouldn't have
10376 # reference to hv1.
10377 as hv1 ovs-vsctl del-port hv1-vif1
10378
10379 OVS_WAIT_UNTIL(
10380 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10381 # Trim the spaces.
10382 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10383 test "$hv2_ch_uuid" = "$ref_ch_list"])
10384
10385 # Delete the inside2 vif.
10386 ovn-sbctl show
10387
10388 echo "Deleting hv2-vif1"
10389 as hv2 ovs-vsctl del-port hv2-vif1
10390
10391 # ref_chassis of ha_chassis_group should be empty
10392 OVS_WAIT_UNTIL(
10393 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10394 # Trim the spaces.
10395 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10396 exp_ref_ch_list=""
10397 test "$exp_ref_ch_list" = "$ref_ch_list"])
10398
10399 # Delete the Gateway_Chassis for lrp - outside
10400 ovn-nbctl clear Logical_Router_Port outside gateway_chassis
10401
10402 # There shoud be no ha_chassis_group rows in SB DB.
10403 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group | wc -l`])
10404 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10405
10406 ovn-nbctl remove NB_Global . options "bfd-min-rx"
10407 ovn-nbctl remove NB_Global . options "bfd-min-tx"
10408 ovn-nbctl remove NB_Global . options "bfd-mult"
10409
10410 # Now test with HA chassis group instead of Gateway chassis in NB DB
10411 ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
10412
10413 ovn-nbctl list ha_chassis_group
10414 ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1
10415 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
10416 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw1 30
10417 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 20
10418
10419 # ovn-northd should not create HA chassis group and HA chassis rows
10420 # unless the HA chassis group in OVN NB DB is associated to
10421 # a logical router port.
10422 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10423
10424 # Associate hagrp1 to outside logical router port
10425 ovn-nbctl set Logical_Router_Port outside ha_chassis_group=$hagrp1_uuid
10426
10427 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns _uuid \
10428 find ha_chassis_group | wc -l`])
10429
10430 OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
10431 grep -v chassis-name | wc -l`])
10432
10433 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10434 grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10435 | wc -l], [0], [1
10436 ])
10437
10438 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10439 grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10440 | wc -l], [0], [1
10441 ])
10442
10443 # make sure that flows for handling the outside router port reside on gw1
10444 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10445 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10446 ]])
10447 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10448 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10449 ]])
10450
10451 # make sure ARP responder flows for outside router port reside on gw1 too
10452 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10453 grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10454 ]])
10455 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10456 ]])
10457
10458 # check that the chassis redirect port has been claimed by the gw1 chassis
10459 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10460 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10461 ]])
10462
10463 # Re add the ovs ports.
10464 for i in 1 2; do
10465 as hv$i
10466 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10467 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10468 options:tx_pcap=hv$i/vif1-tx.pcap \
10469 options:rxq_pcap=hv$i/vif1-rx.pcap \
10470 ofport-request=1
10471 done
10472
10473 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10474 hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10475
10476 exp_ref_ch_list=''
10477 for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10478 do
10479 if test $i = $hv1_ch_uuid; then
10480 exp_ref_ch_list="${exp_ref_ch_list}$i"
10481 elif test $i = $hv2_ch_uuid; then
10482 exp_ref_ch_list="${exp_ref_ch_list}$i"
10483 fi
10484 done
10485
10486 OVS_WAIT_UNTIL(
10487 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10488 # Trim the spaces.
10489 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10490 test "$exp_ref_ch_list" = "$ref_ch_list"])
10491
10492 # Increase the priority of gw2
10493 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 40
10494
10495 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10496 grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10497 | wc -l], [0], [1
10498 ])
10499
10500 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10501 grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10502 | wc -l], [0], [1
10503 ])
10504
10505 # check that the chassis redirect port has been reclaimed by the gw2 chassis
10506 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10507 logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10508 ]])
10509
10510 # check BFD enablement on tunnel ports from gw1 #########
10511 as gw1
10512 for chassis in gw2 hv1 hv2; do
10513 echo "checking gw1 -> $chassis"
10514 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10515 [[enable=true
10516 ]])
10517 done
10518
10519 # check BFD enablement on tunnel ports from gw2 ##########
10520 as gw2
10521 for chassis in gw1 hv1 hv2; do
10522 echo "checking gw2 -> $chassis"
10523 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10524 [[enable=true
10525 ]])
10526 done
10527
10528 # check BFD enablement on tunnel ports from hv1 ###########
10529 as hv1
10530 for chassis in gw1 gw2; do
10531 echo "checking hv1 -> $chassis"
10532 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10533 [[enable=true
10534 ]])
10535 done
10536 # make sure BFD is not enabled to hv2, we don't need it
10537 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10538 [[
10539 ]])
10540
10541 # check BFD enablement on tunnel ports from hv2 ##########
10542 as hv2
10543 for chassis in gw1 gw2; do
10544 echo "checking hv2 -> $chassis"
10545 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10546 [[enable=true
10547 ]])
10548 done
10549 # make sure BFD is not enabled to hv1, we don't need it
10550 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10551 [[
10552 ]])
10553
10554 # make sure that flows for handling the outside router port reside on gw2 now
10555 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10556 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10557 ]])
10558 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10559 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10560 ]])
10561
10562 # disconnect GW2 from the network, GW1 should take over
10563 as gw2
10564 port=${sandbox}_br-phys
10565 as main ovs-vsctl del-port n1 $port
10566
10567 bfd_dump
10568
10569 # make sure that flows for handling the outside router port reside on gw2 now
10570 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10571 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10572 ]])
10573 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10574 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10575 ]])
10576
10577 # check that the chassis redirect port has been reclaimed by the gw1 chassis
10578 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10579 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10580 ]])
10581
10582 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
10583
10584 AT_CLEANUP
10585
10586 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
10587 AT_SKIP_IF([test $HAVE_PYTHON = no])
10588 ovn_start
10589 ovn-nbctl ls-add ls0
10590 ovn-nbctl ls-add ls1
10591 ovn-nbctl create Logical_Router name=lr0
10592 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
10593
10594 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10595 name=outside_gw1 chassis_name=hv2 priority=10 -- \
10596 --id=@gc1 create Gateway_Chassis \
10597 name=outside_gw2 chassis_name=hv3 priority=1 -- \
10598 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10599
10600 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
10601 type=router options:router-port=lrp0 addresses="router"
10602 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
10603 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
10604 type=router options:router-port=lrp1 addresses="router"
10605
10606 # Add NAT rules
10607 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
10608
10609 net_add n1
10610 sim_add hv1
10611 as hv1
10612 ovs-vsctl add-br br-phys
10613 ovn_attach n1 br-phys 192.168.0.1
10614 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10615 AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
10616
10617 sim_add hv2
10618 as hv2
10619 ovs-vsctl add-br br-phys
10620 ovn_attach n1 br-phys 192.168.0.2
10621 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10622
10623 sim_add hv3
10624 as hv3
10625 ovs-vsctl add-br br-phys
10626 ovn_attach n1 br-phys 192.168.0.3
10627 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10628
10629 # Create a localnet port.
10630 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
10631 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
10632 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
10633 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
10634
10635 # wait for earlier changes to take effect
10636 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
10637
10638 reset_pcap_file() {
10639 local iface=$1
10640 local pcap_file=$2
10641 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10642 options:rxq_pcap=dummy-rx.pcap
10643 rm -f ${pcap_file}*.pcap
10644 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10645 options:rxq_pcap=${pcap_file}-rx.pcap
10646 }
10647
10648 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10649 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10650 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10651 # add nat-addresses option
10652 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10653
10654 # Wait for packets to be received through hv2.
10655 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10656 trim_zeros() {
10657 sed 's/\(00\)\{1,\}$//'
10658 }
10659
10660 only_broadcast_from_lrp1() {
10661 grep "fffffffffffff00000000001"
10662 }
10663
10664 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
10665 echo $garp > expout
10666
10667 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
10668 echo "packets on hv1-snoopvif:"
10669 cat hv1_snoop_tx
10670 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
10671 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10672 echo "packets on hv2 br-phys tx"
10673 cat hv2_br_phys_tx
10674 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
10675 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10676 echo "packets on hv3 br-phys tx"
10677 cat hv3_br_phys_tx
10678 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
10679
10680
10681 # at this point, we invert the priority of the gw chassis between hv2 and hv3
10682
10683 ovn-nbctl --wait=hv \
10684 --id=@gc0 create Gateway_Chassis \
10685 name=outside_gw1 chassis_name=hv2 priority=1 -- \
10686 --id=@gc1 create Gateway_Chassis \
10687 name=outside_gw2 chassis_name=hv3 priority=10 -- \
10688 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10689
10690
10691 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10692 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10693 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10694
10695 # Wait for packets to be received.
10696 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10697 trim_zeros() {
10698 sed 's/\(00\)\{1,\}$//'
10699 }
10700
10701 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10702 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10703 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10704 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10705 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10706 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10707
10708 # change localnet port tag.
10709 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
10710
10711 # wait for earlier changes to take effect
10712 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
10713
10714 # update nat-addresses option
10715 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
10716 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10717
10718 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10719 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10720 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10721
10722 # Wait for packets to be received.
10723 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10724 trim_zeros() {
10725 sed 's/\(00\)\{1,\}$//'
10726 }
10727
10728 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
10729 echo $garp > expout
10730
10731 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10732 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10733 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10734 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10735 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10736 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10737
10738 OVN_CLEANUP([hv1],[hv2],[hv3])
10739
10740 AT_CLEANUP
10741
10742 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
10743 AT_SKIP_IF([test $HAVE_PYTHON = no])
10744 ovn_start
10745
10746 net_add n1
10747
10748 # create two gateways with external network connectivity
10749 for i in 1 2; do
10750 sim_add gw$i
10751 as gw$i
10752 ovs-vsctl add-br br-phys
10753 ovn_attach n1 br-phys 192.168.0.$i
10754 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10755 done
10756
10757 ovn-nbctl ls-add inside
10758 ovn-nbctl ls-add outside
10759
10760 # create one hypervisors with a vif port the internal network
10761 sim_add hv1
10762 as hv1
10763 ovs-vsctl add-br br-phys
10764 ovn_attach n1 br-phys 192.168.0.11
10765 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10766 set interface hv1-vif1 external-ids:iface-id=inside1 \
10767 options:tx_pcap=hv1/vif1-tx.pcap \
10768 options:rxq_pcap=hv1/vif1-rx.pcap \
10769 ofport-request=1
10770
10771 ovn-nbctl lsp-add inside inside1 \
10772 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
10773
10774
10775 OVN_POPULATE_ARP
10776
10777 ovn-nbctl create Logical_Router name=R1
10778
10779 # Connect inside to R1
10780 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10781 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10782 type=router options:router-port=inside \
10783 -- lsp-set-addresses rp-inside router
10784
10785 # Connect outside to R1 as distributed router gateway port on gw1+gw2
10786 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10787
10788 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10789 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10790 --id=@gc1 create Gateway_Chassis \
10791 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10792 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10793
10794 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10795 type=router options:router-port=outside \
10796 -- lsp-set-addresses rp-outside router
10797
10798 # Create localnet port in outside
10799 ovn-nbctl lsp-add outside ln-outside
10800 ovn-nbctl lsp-set-addresses ln-outside unknown
10801 ovn-nbctl lsp-set-type ln-outside localnet
10802 ovn-nbctl lsp-set-options ln-outside network_name=phys
10803
10804 # Allow some time for ovn-northd and ovn-controller to catch up.
10805 ovn-nbctl --wait=hv --timeout=3 sync
10806
10807 # currently when ovn-controller is restarted, the old entry is deleted
10808 # and a new one is created, which leaves the Gateway_Chassis with
10809 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
10810 # doesn't have the same effect because "name" is conserved, and the
10811 # Chassis entry is not replaced.
10812
10813 > gw1/ovn-controller.log
10814
10815 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10816 ovn-sbctl destroy Chassis $gw2_chassis
10817
10818 OVS_WAIT_UNTIL([test 0 = `grep -c "Releasing lport" gw1/ovn-controller.log`])
10819
10820 OVN_CLEANUP([gw1],[gw2],[hv1])
10821
10822 AT_CLEANUP
10823
10824 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
10825 AT_KEYWORDS([ovn-nd_ns for unknown mac])
10826 AT_SKIP_IF([test $HAVE_PYTHON = no])
10827 ovn_start
10828
10829 ovn-nbctl ls-add sw0_ip6
10830 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
10831 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
10832 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10833
10834 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
10835 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10836
10837 ovn-nbctl lr-add lr0_ip6
10838 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
10839 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
10840 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
10841 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
10842 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
10843 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
10844
10845 ovn-nbctl ls-add public
10846 ovn-nbctl lsp-add public ln-public
10847 ovn-nbctl lsp-set-addresses ln-public unknown
10848 ovn-nbctl lsp-set-type ln-public localnet
10849 ovn-nbctl lsp-set-options ln-public network_name=phys
10850
10851 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
10852 2001:db8:1:0:200:02ff:fe01:0204/64 \
10853 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
10854
10855 #install static route
10856 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
10857 ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
10858 -- add Logical_Router lr0_ip6 static_routes @lrt
10859
10860 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
10861 rp-ip6_public type=router options:router-port=ip6_public \
10862 -- lsp-set-addresses rp-ip6_public router
10863
10864 net_add n1
10865 sim_add hv1
10866 as hv1
10867 ovs-vsctl add-br br-phys
10868 ovn_attach n1 br-phys 192.168.0.2
10869
10870 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10871 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
10872 options:tx_pcap=hv1/vif1-tx.pcap \
10873 options:rxq_pcap=hv1/vif1-rx.pcap \
10874 ofport-request=1
10875 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10876
10877 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
10878
10879 # There should be 2 Neighbor Advertisement flows for the router port
10880 # aef0:: ip address in logical switch pipeline with action nd_na_router.
10881 AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
10882 grep "nd_na_router" | wc -l], [0], [2
10883 ])
10884
10885 # There should be 4 Neighbor Advertisement flows with action nd_na_router
10886 # in the router pipeline for the router lr0_ip6.
10887 AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
10888 wc -l], [0], [4
10889 ])
10890
10891 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
10892
10893 # There is only one chassis.
10894 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
10895 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
10896
10897 trim_zeros() {
10898 sed 's/\(00\)\{1,\}$//'
10899 }
10900
10901 reset_pcap_file() {
10902 local iface=$1
10903 local pcap_file=$2
10904 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10905 options:rxq_pcap=dummy-rx.pcap
10906 rm -f ${pcap_file}*.pcap
10907 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10908 options:rxq_pcap=${pcap_file}-rx.pcap
10909 }
10910
10911 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
10912 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
10913 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
10914 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10915 # This function sends ipv6 packet
10916 test_ipv6() {
10917 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10918 local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
10919
10920 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
10921 packet=${packet}8000000000000000
10922
10923 src_mac=000002010204
10924 expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
10925 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
10926 expected_packet=${expected_packet}${nd_target}0101${src_mac}
10927
10928 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
10929 rm -f ipv6_ns.expected
10930 echo $expected_packet >> ipv6_ns.expected
10931 }
10932
10933 src_mac=506400000002
10934 dst_mac=00000000af01
10935 src_ip=aef0000000000000526400fffe000002
10936 dst_ip=20010db800010000020002fffe010205
10937 dst_mcast_mac=3333ff010205
10938 mcast_node_ip=ff0200000000000000000001ff010205
10939 nd_target=20010db800010000020002fffe010205
10940 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
10941 # should be received by the ports attached to br-phys.
10942 test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
10943 $mcast_node_ip $nd_target
10944
10945 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
10946 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
10947
10948 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
10949 trim_zeros > 1.packets
10950 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
10951 trim_zeros > 2.packets
10952
10953 cat ipv6_ns.expected | cut -c -112 > expout
10954 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
10955 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
10956
10957 # Skipping the ICMPv6 checksum
10958 cat ipv6_ns.expected | cut -c 117- > expout
10959 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
10960 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
10961
10962 # Now send a packet with destination ip other than
10963 # 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
10964 reset_pcap_file br-phys_n1 hv1/br-phys_n1
10965 reset_pcap_file br-phys hv1/br-phys
10966
10967 src_mac=506400000002
10968 dst_mac=00000000af01
10969 src_ip=aef0000000000000526400fffe000002
10970 dst_ip=20020ab8000100000200020000020306
10971 # multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
10972 dst_mcast_mac=3333ff011305
10973 mcast_node_ip=ff0200000000000000000001ff011305
10974 nd_target=20010db800010000020002fffe011305
10975 test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
10976 $mcast_node_ip $nd_target
10977
10978 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
10979 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
10980
10981 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
10982 trim_zeros > 1.packets
10983 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
10984 trim_zeros > 2.packets
10985
10986 cat ipv6_ns.expected | cut -c -112 > expout
10987 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
10988 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
10989
10990 # Skipping the ICMPv6 checksum
10991 cat ipv6_ns.expected | cut -c 117- > expout
10992 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
10993 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
10994
10995 OVN_CLEANUP([hv1])
10996
10997 AT_CLEANUP
10998
10999 AT_SETUP([ovn -- options:requested-chassis for logical port])
11000 ovn_start
11001
11002 net_add n1
11003
11004 ovn-nbctl ls-add ls0
11005 ovn-nbctl lsp-add ls0 lsp0
11006
11007 # create two hypervisors, each with one vif port
11008 sim_add hv1
11009 as hv1
11010 ovs-vsctl add-br br-phys
11011 ovn_attach n1 br-phys 192.168.0.11
11012 ovs-vsctl -- add-port br-int hv1-vif0 -- \
11013 set Interface hv1-vif0 ofport-request=1
11014
11015 sim_add hv2
11016 as hv2
11017 ovs-vsctl add-br br-phys
11018 ovn_attach n1 br-phys 192.168.0.12
11019 ovs-vsctl -- add-port br-int hv2-vif0 -- \
11020 set Interface hv2-vif0 ofport-request=1
11021
11022 # Allow only chassis hv1 to bind logical port lsp0.
11023 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
11024
11025 # Allow some time for ovn-northd and ovn-controller to catch up.
11026 ovn-nbctl --wait=hv --timeout=3 sync
11027
11028 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
11029 ovn-sbctl wait-until chassis hv1
11030 ovn-sbctl wait-until chassis hv2
11031 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
11032 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
11033
11034 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
11035 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
11036 as hv2
11037 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
11038
11039 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
11040 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11041
11042 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11043 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11044 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11045
11046 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
11047 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
11048 as hv1
11049 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11050
11051 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11052 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
11053
11054 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11055 as hv1 ovs-ofctl dump-flows br-int
11056 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11057 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11058
11059 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
11060 # the requested chassis for lsp0 is changed from hv1 to hv2.
11061 echo "verifying that lsp0 binding moves when requested-chassis is changed"
11062
11063 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
11064 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11065 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
11066
11067 # (6) Chassis hv2 should add flows and hv1 should not.
11068 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11069 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11070
11071 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11072 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11073
11074 OVN_CLEANUP([hv1],[hv2])
11075
11076 AT_CLEANUP
11077
11078 AT_SETUP([ovn -- options:requested-chassis with hostname])
11079
11080 ovn_start
11081
11082 ovn-nbctl ls-add ls0
11083 ovn-nbctl lsp-add ls0 lsp0
11084
11085 net_add n1
11086 sim_add hv1
11087 as hv1
11088 ovs-vsctl add-br br-phys
11089 ovn_attach n1 br-phys 192.168.0.11
11090 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
11091
11092 ovn-sbctl wait-until chassis hv1
11093 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
11094 echo "hv1_hostname=${hv1_hostname}"
11095 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
11096 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11097
11098 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
11099 echo "hv1_uuid=${hv1_uuid}"
11100 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11101 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
11102 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11103 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11104
11105 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
11106 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11107 ovn-nbctl --wait=hv --timeout=3 sync
11108 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11109 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11110 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11111
11112 OVN_CLEANUP([hv1])
11113
11114 AT_CLEANUP
11115
11116 AT_SETUP([ovn -- IPv6 periodic RA])
11117 ovn_start
11118
11119 # This test sets up two hypervisors.
11120 # hv1 and hv2 run ovn-controllers, and
11121 # each has a VIF connected to the same
11122 # logical switch in OVN. The logical
11123 # switch is connected to a logical
11124 # router port that is configured to send
11125 # periodic router advertisements.
11126 #
11127 # The reason for having two ovn-controller
11128 # hypervisors is to ensure that the
11129 # periodic RAs being sent by each ovn-controller
11130 # are kept to their local hypervisors. If the
11131 # packets are not kept local, then each port
11132 # will receive too many RAs.
11133
11134 net_add n1
11135 sim_add hv1
11136 sim_add hv2
11137 as hv1
11138 ovs-vsctl add-br br-phys
11139 ovn_attach n1 br-phys 192.168.0.2
11140 as hv2
11141 ovs-vsctl add-br br-phys
11142 ovn_attach n1 br-phys 192.168.0.3
11143
11144 ovn-nbctl lr-add ro
11145 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
11146
11147 ovn-nbctl ls-add sw
11148 ovn-nbctl lsp-add sw sw-ro
11149 ovn-nbctl lsp-set-type sw-ro router
11150 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
11151 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
11152 ovn-nbctl lsp-add sw sw-p1
11153 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
11154 ovn-nbctl lsp-add sw sw-p2
11155 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
11156
11157 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
11158 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
11159 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
11160 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
11161
11162 for i in 1 2 ; do
11163 as hv$i
11164 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
11165 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
11166 options:tx_pcap=hv$i/vif1-tx.pcap \
11167 options:rxq_pcap=hv$i/vif1-rx.pcap \
11168 ofport-request=1
11169 done
11170
11171 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
11172 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
11173
11174 reset_pcap_file() {
11175 local iface=$1
11176 local pcap_file=$2
11177 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11178 options:rxq_pcap=dummy-rx.pcap
11179 rm -f ${pcap_file}*.pcap
11180 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11181 options:rxq_pcap=${pcap_file}-rx.pcap
11182
11183 }
11184
11185 construct_expected_ra() {
11186 local src_mac=000000000001
11187 local dst_mac=333300000001
11188 local src_addr=fe80000000000000020000fffe000001
11189 local dst_addr=ff020000000000000000000000000001
11190
11191 local mtu=$1
11192 local ra_mo=$2
11193 local ra_prefix_la=$3
11194
11195 local slla=0101${src_mac}
11196 local mtu_opt=""
11197 if test $mtu != 0; then
11198 mtu_opt=05010000${mtu}
11199 fi
11200 shift 3
11201
11202 local prefix=""
11203 while [[ $# -gt 0 ]] ; do
11204 local size=$1
11205 local net=$2
11206 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
11207 shift 2
11208 done
11209
11210 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
11211 local icmp=8600XXXX${ra}
11212
11213 local ip_len=$(expr ${#icmp} / 2)
11214 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
11215
11216 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
11217 local eth=${dst_mac}${src_mac}86dd${ip}
11218 local packet=${eth}
11219 echo $packet >> expected
11220 }
11221
11222 ra_test() {
11223 construct_expected_ra $@
11224
11225 for i in hv1 hv2 ; do
11226 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
11227
11228 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
11229
11230 cat expected | cut -c -112 > expout
11231 AT_CHECK([cat packets | cut -c -112], [0], [expout])
11232
11233 # Skip ICMPv6 checksum.
11234 cat expected | cut -c 117- > expout
11235 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
11236
11237 rm -f packets
11238 as $i reset_pcap_file $i-vif1 $i/vif1
11239 done
11240
11241 rm -f expected
11242 }
11243
11244 # Baseline test with no MTU
11245 ra_test 0 00 c0 40 aef00000000000000000000000000000
11246
11247 # Now make sure an MTU option makes it
11248 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
11249 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
11250
11251 # Now test for multiple network prefixes
11252 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
11253 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11254
11255 # Test a different address mode now
11256 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
11257 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11258
11259 # And the other address mode
11260 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
11261 ra_test 000005dc 40 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11262
11263 OVN_CLEANUP([hv1],[hv2])
11264 AT_CLEANUP
11265
11266 AT_SETUP([ovn -- ACL reject rule test])
11267 AT_KEYWORDS([acl-reject])
11268 AT_SKIP_IF([test $HAVE_PYTHON = no])
11269 ovn_start
11270
11271 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
11272 #
11273 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11274 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
11275 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
11276 # unreachable frame generated from ACL rule hit
11277 #
11278 # INPORT is a lport number, e.g. 11 for vif11.
11279 # HV is a hypervisor number
11280 # ETH_SRC and ETH_DST are each 12 hex digits.
11281 # IPV4_SRC and IPV4_DST are each 8 hex digits.
11282 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11283 test_ip_packet() {
11284 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11285 local exp_ip_chksum=$8 exp_icmp_chksum=$9
11286 shift 9
11287
11288 local ip_ttl=ff
11289 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
11290
11291 local reply_icmp_ttl=ff
11292 local icmp_type_code_response=0301
11293 local icmp_data=00000000
11294 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
11295 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
11296 echo $reply >> vif$inport.expected
11297
11298 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11299 }
11300
11301 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
11302 #
11303 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
11304 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
11305 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
11306 test_ipv6_packet() {
11307 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
11308 shift 7
11309
11310 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11311 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
11312
11313 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
11314 echo $reply >> vif$inport.expected
11315
11316 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11317 }
11318
11319 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
11320 #
11321 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
11322 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
11323 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
11324 #
11325 # INPORT is an lport number, e.g. 11 for vif11.
11326 # HV is an hypervisor number
11327 # ETH_SRC and ETH_DST are each 12 hex digits.
11328 # IPV4_SRC and IPV4_DST are each 8 hex digits.
11329 # TCP_SPORT and TCP_DPORT are 4 hex digits.
11330 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
11331 test_tcp_syn_packet() {
11332 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11333 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
11334 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
11335 shift 12
11336
11337 local ip_ttl=ff
11338 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11339
11340 local tcp_rst_ttl=ff
11341 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
11342 echo $reply >> vif$inport.expected
11343
11344 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11345 }
11346
11347 # Create hypervisors hv[123].
11348 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
11349 # Add all of the vifs to a single logical switch sw0.
11350
11351 net_add n1
11352 ovn-nbctl ls-add sw0
11353 for i in 1 2 3; do
11354 sim_add hv$i
11355 as hv$i
11356 ovs-vsctl add-br br-phys
11357 ovn_attach n1 br-phys 192.168.0.$i
11358
11359 for j in 1 2 3; do
11360 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
11361 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
11362
11363 ovs-vsctl -- add-port br-int vif$i$j -- \
11364 set interface vif$i$j \
11365 external-ids:iface-id=sw0-p$i$j \
11366 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
11367 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
11368 ofport-request=$i$j
11369 done
11370 done
11371
11372 OVN_POPULATE_ARP
11373 # allow some time for ovn-northd and ovn-controller to catch up.
11374 sleep 1
11375
11376 ip_to_hex() {
11377 printf "%02x%02x%02x%02x" "$@"
11378 }
11379
11380 for i in 1 2 3; do
11381 : > vif${i}1.expected
11382 done
11383
11384 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
11385 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
11386 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
11387
11388 # Allow some time for ovn-northd and ovn-controller to catch up.
11389 ovn-nbctl --timeout=3 --wait=hv sync
11390
11391 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
11392 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
11393 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
11394
11395 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
11396
11397 test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
11398 test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
11399 test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486
11400
11401 for i in 1 2 3; do
11402 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
11403 done
11404
11405 OVN_CLEANUP([hv1], [hv2], [hv3])
11406 AT_CLEANUP
11407
11408 AT_SETUP([ovn -- Port Groups])
11409 AT_KEYWORDS([ovnpg])
11410 AT_SKIP_IF([test $HAVE_PYTHON = no])
11411 ovn_start
11412
11413 # Logical network:
11414 #
11415 # Three logical switches ls1, ls2, ls3.
11416 # One logical router lr0 connected to ls[123],
11417 # with nine subnets, three per logical switch:
11418 #
11419 # lrp11 on ls1 for subnet 192.168.11.0/24
11420 # lrp12 on ls1 for subnet 192.168.12.0/24
11421 # lrp13 on ls1 for subnet 192.168.13.0/24
11422 # ...
11423 # lrp33 on ls3 for subnet 192.168.33.0/24
11424 #
11425 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11426 # digits are the subnet and the last digit distinguishes the VIF.
11427 #
11428 # This test will create two port groups and uses them in ACL.
11429
11430 get_lsp_uuid () {
11431 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11432 }
11433
11434 pg1_ports=
11435 pg2_ports=
11436 for i in 1 2 3; do
11437 ovn-nbctl ls-add ls$i
11438 for j in 1 2 3; do
11439 for k in 1 2 3; do
11440 ovn-nbctl \
11441 -- lsp-add ls$i lp$i$j$k \
11442 -- lsp-set-addresses lp$i$j$k \
11443 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
11444 # logical ports lp[12]?1 belongs to port group pg1
11445 if test $i != 3 && test $k == 1; then
11446 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11447 fi
11448 # logical ports lp[23]?2 belongs to port group pg2
11449 if test $i != 1 && test $k == 2; then
11450 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11451 fi
11452 done
11453 done
11454 done
11455
11456 ovn-nbctl lr-add lr0
11457 for i in 1 2 3; do
11458 for j in 1 2 3; do
11459 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11460 ovn-nbctl \
11461 -- lsp-add ls$i lrp$i$j-attachment \
11462 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11463 options:router-port=lrp$i$j \
11464 addresses='"00:00:00:00:ff:'$i$j'"'
11465 done
11466 done
11467
11468 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11469 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11470
11471 # create ACLs on all lswitches to drop traffic from pg2 to pg1
11472 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11473 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11474 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11475
11476 # Physical network:
11477 #
11478 # Three hypervisors hv[123].
11479 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11480 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11481 # lp?3[123] all on hv3.
11482
11483 # Given the name of a logical port, prints the name of the hypervisor
11484 # on which it is located.
11485 vif_to_hv() {
11486 case $1 in dnl (
11487 ?11) echo 1 ;; dnl (
11488 ?12 | ?21 | ?22) echo 2 ;; dnl (
11489 ?13 | ?23 | ?3?) echo 3 ;;
11490 esac
11491 }
11492
11493 # Given the name of a logical port, prints the name of its logical router
11494 # port, e.g. "vif_to_lrp 123" yields 12.
11495 vif_to_lrp() {
11496 echo ${1%?}
11497 }
11498
11499 # Given the name of a logical port, prints the name of its logical
11500 # switch, e.g. "vif_to_ls 123" yields 1.
11501 vif_to_ls() {
11502 echo ${1%??}
11503 }
11504
11505 net_add n1
11506 for i in 1 2 3; do
11507 sim_add hv$i
11508 as hv$i
11509 ovs-vsctl add-br br-phys
11510 ovn_attach n1 br-phys 192.168.0.$i
11511 done
11512 for i in 1 2 3; do
11513 for j in 1 2 3; do
11514 for k in 1 2 3; do
11515 hv=`vif_to_hv $i$j$k`
11516 as hv$hv ovs-vsctl \
11517 -- add-port br-int vif$i$j$k \
11518 -- set Interface vif$i$j$k \
11519 external-ids:iface-id=lp$i$j$k \
11520 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11521 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11522 ofport-request=$i$j$k
11523 done
11524 done
11525 done
11526
11527 # Pre-populate the hypervisors' ARP tables so that we don't lose any
11528 # packets for ARP resolution (native tunneling doesn't queue packets
11529 # for ARP resolution).
11530 OVN_POPULATE_ARP
11531
11532 # Allow some time for ovn-northd and ovn-controller to catch up.
11533 # XXX This should be more systematic.
11534 sleep 1
11535
11536 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11537 #
11538 # This shell function causes a packet to be received on INPORT. The packet's
11539 # content has Ethernet destination DST and source SRC (each exactly 12 hex
11540 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
11541 # more) list the VIFs on which the packet should be received. INPORT and the
11542 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
11543 for i in 1 2 3; do
11544 for j in 1 2 3; do
11545 for k in 1 2 3; do
11546 : > $i$j$k.expected
11547 done
11548 done
11549 done
11550 test_ip() {
11551 # This packet has bad checksums but logical L3 routing doesn't check.
11552 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11553 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
11554 shift; shift; shift; shift; shift
11555 hv=hv`vif_to_hv $inport`
11556 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
11557 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
11558 in_ls=`vif_to_ls $inport`
11559 in_lrp=`vif_to_lrp $inport`
11560 for outport; do
11561 out_ls=`vif_to_ls $outport`
11562 if test $in_ls = $out_ls; then
11563 # Ports on the same logical switch receive exactly the same packet.
11564 echo $packet
11565 else
11566 # Routing decrements TTL and updates source and dest MAC
11567 # (and checksum).
11568 out_lrp=`vif_to_lrp $outport`
11569 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
11570 fi >> $outport.expected
11571 done
11572 }
11573
11574 as hv1 ovs-vsctl --columns=name,ofport list interface
11575 as hv1 ovn-sbctl list port_binding
11576 as hv1 ovn-sbctl list datapath_binding
11577 as hv1 ovn-sbctl list port_group
11578 as hv1 ovn-sbctl list address_set
11579 as hv1 ovn-sbctl dump-flows
11580 as hv1 ovs-ofctl dump-flows br-int
11581
11582 # Send IP packets between all pairs of source and destination ports,
11583 # packets matches ACL (pg2 to pg1) should be dropped
11584 ip_to_hex() {
11585 printf "%02x%02x%02x%02x" "$@"
11586 }
11587 for is in 1 2 3; do
11588 for js in 1 2 3; do
11589 for ks in 1 2 3; do
11590 bcast=
11591 s=$is$js$ks
11592 smac=f00000000$s
11593 sip=`ip_to_hex 192 168 $is$js $ks`
11594 for id in 1 2 3; do
11595 for jd in 1 2 3; do
11596 for kd in 1 2 3; do
11597 d=$id$jd$kd
11598 dip=`ip_to_hex 192 168 $id$jd $kd`
11599 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
11600 if test $d != $s; then unicast=$d; else unicast=; fi
11601
11602 # packets matches ACL should be dropped
11603 if test $id != 3 && test $kd == 1; then
11604 if test $is != 1 && test $ks == 2; then
11605 unicast=
11606 fi
11607 fi
11608 test_ip $s $smac $dmac $sip $dip $unicast #1
11609 done
11610 done
11611 done
11612 done
11613 done
11614 done
11615
11616 # Allow some time for packet forwarding.
11617 # XXX This can be improved.
11618 sleep 1
11619
11620 # Now check the packets actually received against the ones expected.
11621 for i in 1 2 3; do
11622 for j in 1 2 3; do
11623 for k in 1 2 3; do
11624 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11625 [$i$j$k.expected])
11626 done
11627 done
11628 done
11629
11630 # Gracefully terminate daemons
11631 OVN_CLEANUP([hv1], [hv2], [hv3])
11632 AT_CLEANUP
11633
11634 AT_SETUP([ovn -- ACLs on Port Groups])
11635 AT_KEYWORDS([ovnpg_acl])
11636 AT_SKIP_IF([test $HAVE_PYTHON = no])
11637 ovn_start
11638
11639 # Logical network:
11640 #
11641 # Three logical switches ls1, ls2, ls3.
11642 # One logical router lr0 connected to ls[123],
11643 # with nine subnets, three per logical switch:
11644 #
11645 # lrp11 on ls1 for subnet 192.168.11.0/24
11646 # lrp12 on ls1 for subnet 192.168.12.0/24
11647 # lrp13 on ls1 for subnet 192.168.13.0/24
11648 # ...
11649 # lrp33 on ls3 for subnet 192.168.33.0/24
11650 #
11651 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11652 # digits are the subnet and the last digit distinguishes the VIF.
11653 #
11654 # This test will create two port groups and ACLs will be applied on them.
11655
11656 get_lsp_uuid () {
11657 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11658 }
11659
11660 pg1_ports=
11661 pg2_ports=
11662 for i in 1 2 3; do
11663 ovn-nbctl ls-add ls$i
11664 for j in 1 2 3; do
11665 for k in 1 2 3; do
11666 ovn-nbctl \
11667 -- lsp-add ls$i lp$i$j$k \
11668 -- lsp-set-addresses lp$i$j$k \
11669 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
11670 # logical ports lp[12]?1 belongs to port group pg1
11671 if test $i != 3 && test $k == 1; then
11672 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11673 fi
11674 # logical ports lp[23]?2 belongs to port group pg2
11675 if test $i != 1 && test $k == 2; then
11676 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11677 fi
11678 done
11679 done
11680 done
11681
11682 ovn-nbctl lr-add lr0
11683 for i in 1 2 3; do
11684 for j in 1 2 3; do
11685 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11686 ovn-nbctl \
11687 -- lsp-add ls$i lrp$i$j-attachment \
11688 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11689 options:router-port=lrp$i$j \
11690 addresses='"00:00:00:00:ff:'$i$j'"'
11691 done
11692 done
11693
11694 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11695 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11696
11697 # create ACLs on pg1 to drop traffic from pg2 to pg1
11698 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
11699 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
11700 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
11701
11702 # Physical network:
11703 #
11704 # Three hypervisors hv[123].
11705 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11706 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11707 # lp?3[123] all on hv3.
11708
11709 # Given the name of a logical port, prints the name of the hypervisor
11710 # on which it is located.
11711 vif_to_hv() {
11712 case $1 in dnl (
11713 ?11) echo 1 ;; dnl (
11714 ?12 | ?21 | ?22) echo 2 ;; dnl (
11715 ?13 | ?23 | ?3?) echo 3 ;;
11716 esac
11717 }
11718
11719 # Given the name of a logical port, prints the name of its logical router
11720 # port, e.g. "vif_to_lrp 123" yields 12.
11721 vif_to_lrp() {
11722 echo ${1%?}
11723 }
11724
11725 # Given the name of a logical port, prints the name of its logical
11726 # switch, e.g. "vif_to_ls 123" yields 1.
11727 vif_to_ls() {
11728 echo ${1%??}
11729 }
11730
11731 net_add n1
11732 for i in 1 2 3; do
11733 sim_add hv$i
11734 as hv$i
11735 ovs-vsctl add-br br-phys
11736 ovn_attach n1 br-phys 192.168.0.$i
11737 done
11738 for i in 1 2 3; do
11739 for j in 1 2 3; do
11740 for k in 1 2 3; do
11741 hv=`vif_to_hv $i$j$k`
11742 as hv$hv ovs-vsctl \
11743 -- add-port br-int vif$i$j$k \
11744 -- set Interface vif$i$j$k \
11745 external-ids:iface-id=lp$i$j$k \
11746 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11747 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11748 ofport-request=$i$j$k
11749 done
11750 done
11751 done
11752
11753 # Pre-populate the hypervisors' ARP tables so that we don't lose any
11754 # packets for ARP resolution (native tunneling doesn't queue packets
11755 # for ARP resolution).
11756 OVN_POPULATE_ARP
11757
11758 # Allow some time for ovn-northd and ovn-controller to catch up.
11759 # XXX This should be more systematic.
11760 sleep 1
11761
11762 lsp_to_mac() {
11763 echo f0:00:00:00:0${1:0:1}:${1:1:2}
11764 }
11765
11766 lrp_to_mac() {
11767 echo 00:00:00:00:ff:$1
11768 }
11769
11770 # test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
11771 #
11772 # This shell function causes a ICMP packet to be received on INPORT.
11773 # The OUTPORTs (zero or more) list the VIFs on which the packet should
11774 # be received. INPORT and the OUTPORTs are specified as logical switch
11775 # port numbers, e.g. 123 for vif123.
11776 for i in 1 2 3; do
11777 for j in 1 2 3; do
11778 for k in 1 2 3; do
11779 : > $i$j$k.expected
11780 done
11781 done
11782 done
11783
11784 test_icmp() {
11785 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
11786 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
11787 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
11788 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
11789 icmp4.code==0"
11790 shift; shift; shift; shift; shift; shift
11791 hv=hv`vif_to_hv $inport`
11792 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
11793 in_ls=`vif_to_ls $inport`
11794 in_lrp=`vif_to_lrp $inport`
11795 for outport; do
11796 out_ls=`vif_to_ls $outport`
11797 if test $in_ls = $out_ls; then
11798 # Ports on the same logical switch receive exactly the same packet.
11799 echo $packet | ovstest test-ovn expr-to-packets
11800 else
11801 # Routing decrements TTL and updates source and dest MAC
11802 # (and checksum).
11803 out_lrp=`vif_to_lrp $outport`
11804 exp_smac=`lrp_to_mac $out_lrp`
11805 exp_dmac=`lsp_to_mac $outport`
11806 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
11807 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
11808 icmp4.type==$icmp_type && icmp4.code==0"
11809 echo $exp_packet | ovstest test-ovn expr-to-packets
11810
11811 fi >> $outport.expected
11812 done
11813 }
11814
11815 as hv1 ovs-vsctl --columns=name,ofport list interface
11816 as hv1 ovn-sbctl list port_binding
11817 as hv1 ovn-sbctl list datapath_binding
11818 as hv1 ovn-sbctl list port_group
11819 as hv1 ovn-sbctl list address_set
11820 as hv1 ovn-sbctl dump-flows
11821 as hv1 ovs-ofctl dump-flows br-int
11822
11823 # Send IP packets between all pairs of source and destination ports,
11824 # packets matches ACL1 but not ACL2 should be dropped
11825 ip_to_hex() {
11826 printf "%02x%02x%02x%02x" "$@"
11827 }
11828 for is in 1 2 3; do
11829 for js in 1 2 3; do
11830 for ks in 1 2 3; do
11831 bcast=
11832 s=$is$js$ks
11833 slsp_mac=`lsp_to_mac $s`
11834 slrp_mac=`lrp_to_mac $is$js`
11835 sip=192.168.$is$js.$ks
11836 for id in 1 2 3; do
11837 for jd in 1 2 3; do
11838 for kd in 1 2 3; do
11839 d=$id$jd$kd
11840 dlsp_mac=`lsp_to_mac $d`
11841 dlrp_mac=`lrp_to_mac $id$jd`
11842 dip=192.168.$id$jd.$kd
11843 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
11844 if test $d != $s; then unicast=$d; else unicast=; fi
11845
11846 # packets matches ACL1 but not ACL2 should be dropped
11847 if test $id != 3 && test $kd == 1; then
11848 if test $is == 1 || test $ks != 2; then
11849 unicast=
11850 fi
11851 fi
11852 # icmp request (type = 8)
11853 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
11854
11855 # if packets are not dropped, test the return traffic (icmp echo)
11856 # to make sure stateful works, too.
11857 if test x$unicast != x; then
11858 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
11859 # icmp echo (type = 0)
11860 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
11861 fi
11862 done
11863 done
11864 done
11865 done
11866 done
11867 done
11868
11869 # Allow some time for packet forwarding.
11870 # XXX This can be improved.
11871 sleep 1
11872
11873 # Now check the packets actually received against the ones expected.
11874 for i in 1 2 3; do
11875 for j in 1 2 3; do
11876 for k in 1 2 3; do
11877 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11878 [$i$j$k.expected])
11879 done
11880 done
11881 done
11882
11883 # Gracefully terminate daemons
11884 OVN_CLEANUP([hv1], [hv2], [hv3])
11885 AT_CLEANUP
11886
11887 AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
11888 ovn_start
11889
11890 ovn-nbctl ls-add ls1
11891
11892 ovn-nbctl lsp-add ls1 lp1
11893 ovn-nbctl lsp-add ls1 lp2
11894 ovn-nbctl lsp-add ls1 lp3
11895
11896 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
11897 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
11898 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
11899
11900 ovn-nbctl create Port_Group name=pg1
11901 ovn-nbctl create Port_Group name=pg2
11902
11903 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
11904 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
11905 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
11906 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
11907
11908 ovn-nbctl --wait=sb sync
11909
11910 dnl Check if port group address sets were populated with ports' addresses
11911 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11912 [0], [[["10.0.0.1", "10.0.0.2"]]
11913 ])
11914 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
11915 [0], [[["10.0.0.2", "10.0.0.3"]]
11916 ])
11917 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11918 [0], [[["2001:db8::1", "2001:db8::2"]]
11919 ])
11920 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
11921 [0], [[["2001:db8::2", "2001:db8::3"]]
11922 ])
11923
11924 ovn-nbctl --wait=sb lsp-set-addresses lp1 \
11925 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
11926
11927 dnl Check if updated address got propagated to the port group address sets
11928 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11929 [0], [[["10.0.0.11", "10.0.0.2"]]
11930 ])
11931 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11932 [0], [[["2001:db8::11", "2001:db8::2"]]
11933 ])
11934
11935 AT_CLEANUP
11936
11937 AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
11938 ovn_start
11939
11940 ovn-nbctl ls-add ls1
11941 ovn-nbctl ls-add ls2
11942 ovn-nbctl ls-add ls3
11943
11944 ovn-nbctl set Logical_Switch ls1 \
11945 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
11946 ovn-nbctl set Logical_Switch ls2 \
11947 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
11948 ovn-nbctl set Logical_Switch ls3 \
11949 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
11950
11951 ovn-nbctl lsp-add ls1 lp1
11952 ovn-nbctl lsp-add ls2 lp2
11953 ovn-nbctl lsp-add ls3 lp3
11954
11955 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
11956 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
11957 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
11958
11959 ovn-nbctl create Port_Group name=pg1
11960 ovn-nbctl create Port_Group name=pg2
11961
11962 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
11963 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
11964 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
11965 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
11966
11967 ovn-nbctl --wait=sb sync
11968
11969 dnl Check if port group address sets were populated with ports' addresses
11970 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11971 [0], [[["10.1.0.2", "10.2.0.2"]]
11972 ])
11973 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
11974 [0], [[["10.2.0.2", "10.3.0.2"]]
11975 ])
11976 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11977 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
11978 ])
11979 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
11980 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
11981 ])
11982
11983 ovn-nbctl --wait=sb set Logical_Switch ls1 \
11984 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
11985
11986 dnl Check if updated address got propagated to the port group address sets
11987 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
11988 [0], [[["10.11.0.2", "10.2.0.2"]]
11989 ])
11990 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
11991 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
11992 ])
11993
11994 AT_CLEANUP
11995
11996 AT_SETUP([ovn -- ACL conjunction])
11997 ovn_start
11998
11999 ovn-nbctl ls-add ls1
12000
12001 ovn-nbctl lsp-add ls1 ls1-lp1 \
12002 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12003
12004 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12005
12006 ovn-nbctl lsp-add ls1 ls1-lp2 \
12007 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12008
12009 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12010
12011 net_add n1
12012 sim_add hv1
12013
12014 as hv1
12015 ovs-vsctl add-br br-phys
12016 ovn_attach n1 br-phys 192.168.0.1
12017 ovs-vsctl -- add-port br-int hv1-vif1 -- \
12018 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
12019 options:tx_pcap=hv1/vif1-tx.pcap \
12020 options:rxq_pcap=hv1/vif1-rx.pcap \
12021 ofport-request=1
12022
12023 ovs-vsctl -- add-port br-int hv1-vif2 -- \
12024 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
12025 options:tx_pcap=hv1/vif2-tx.pcap \
12026 options:rxq_pcap=hv1/vif2-rx.pcap \
12027 ofport-request=2
12028
12029 ovn-nbctl create Address_Set name=set1 \
12030 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
12031 ovn-nbctl create Address_Set name=set2 \
12032 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
12033 ovn-nbctl acl-add ls1 to-lport 1002 \
12034 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
12035 ovn-nbctl acl-add ls1 to-lport 1001 \
12036 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
12037
12038 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
12039 #
12040 # This shell function causes an ip packet to be received on INPORT.
12041 # The packet's content has Ethernet destination DST and source SRC
12042 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
12043 # The OUTPORTs (zero or more) list the VIFs on which the packet should
12044 # be received. INPORT and the OUTPORTs are specified as logical switch
12045 # port numbers, e.g. 11 for vif11.
12046 test_ip() {
12047 # This packet has bad checksums but logical L3 routing doesn't check.
12048 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
12049 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
12050 ${dst_ip}0035111100080000
12051 shift; shift; shift; shift; shift
12052 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
12053 for outport; do
12054 echo $packet >> $outport.expected
12055 done
12056 }
12057
12058 ip_to_hex() {
12059 printf "%02x%02x%02x%02x" "$@"
12060 }
12061
12062 reset_pcap_file() {
12063 local iface=$1
12064 local pcap_file=$2
12065 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12066 options:rxq_pcap=dummy-rx.pcap
12067 rm -f ${pcap_file}*.pcap
12068 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12069 options:rxq_pcap=${pcap_file}-rx.pcap
12070 }
12071
12072
12073 sip=`ip_to_hex 10 0 0 4`
12074 dip=`ip_to_hex 10 0 0 6`
12075
12076 test_ip 1 f00000000001 f00000000002 $sip $dip 2
12077
12078 cat 2.expected > expout
12079 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12080 AT_CHECK([cat 2.packets], [0], [expout])
12081
12082 # There should be total of 12 flows present with conjunction action and 2 flows
12083 # with conj match. Eg.
12084 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
12085 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
12086 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
12087 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
12088 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
12089 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
12090 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
12091 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
12092 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
12093 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
12094 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
12095 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
12096 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
12097 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
12098
12099 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
12100 grep conjunction | wc -l`])
12101 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
12102 grep conj_id | wc -l`])
12103
12104 as hv1 ovs-ofctl dump-flows br-int
12105
12106 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
12107 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12108 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12109
12110 reset_pcap_file hv1-vif2 hv1/vif2
12111
12112 rm -f 2.packets
12113
12114 sip=`ip_to_hex 10 0 0 4`
12115 dip=`ip_to_hex 10 0 0 7`
12116
12117 test_ip 1 f00000000001 f00000000002 $sip $dip
12118 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12119 AT_CHECK([cat 2.packets], [0], [])
12120
12121 AT_CLEANUP
12122
12123 AT_SETUP([ovn -- TTL exceeded])
12124 AT_KEYWORDS([ttl-exceeded])
12125 AT_SKIP_IF([test $HAVE_PYTHON = no])
12126 ovn_start
12127
12128 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
12129 #
12130 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12131 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
12132 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
12133 # generated by OVN logical router
12134 #
12135 # INPORT is a lport number, e.g. 11 for vif11.
12136 # HV is a hypervisor number
12137 # ETH_SRC and ETH_DST are each 12 hex digits.
12138 # IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
12139 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12140 test_ip_packet() {
12141 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
12142 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
12143 shift 10
12144
12145 local ip_ttl=01
12146 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
12147
12148 local reply_icmp_ttl=fe
12149 local icmp_type_code_response=0b00
12150 local icmp_data=00000000
12151 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
12152 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12153 echo $reply >> vif$inport.expected
12154
12155 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12156 }
12157
12158 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
12159 #
12160 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12161 # packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
12162 # IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
12163 # packet sent by OVN logical router
12164 test_ip6_packet() {
12165 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
12166 shift 8
12167
12168 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
12169 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
12170
12171 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
12172 echo $reply >> vif$inport.expected
12173
12174 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12175 }
12176
12177 ip_to_hex() {
12178 printf "%02x%02x%02x%02x" "$@"
12179 }
12180
12181 for i in 1 2; do
12182 net_add n$i
12183 ovn-nbctl ls-add sw$i
12184
12185 sim_add hv$i
12186 as hv$i
12187 ovs-vsctl add-br br-phys
12188 ovn_attach n$i br-phys 192.168.$i.1
12189
12190 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
12191 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
12192
12193 ovs-vsctl -- add-port br-int vif$i -- \
12194 set interface vif$i \
12195 external-ids:iface-id=sw$i-p${i}0 \
12196 options:tx_pcap=hv$i/vif$i-tx.pcap \
12197 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12198 ofport-request=$i
12199 done
12200
12201 ovn-nbctl lr-add lr0
12202 for i in 1 2; do
12203 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
12204 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12205 -- set Logical_Switch_Port lrp$i-attachment type=router \
12206 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
12207 done
12208
12209 OVN_POPULATE_ARP
12210 # allow some time for ovn-northd and ovn-controller to catch up.
12211 ovn-nbctl --wait=hv sync
12212
12213 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
12214 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
12215 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12216
12217 OVN_CLEANUP([hv1], [hv2])
12218 AT_CLEANUP
12219
12220 AT_SETUP([ovn -- router port unreachable])
12221 AT_KEYWORDS([router-port-unreachable])
12222 AT_SKIP_IF([test $HAVE_PYTHON = no])
12223 ovn_start
12224
12225 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
12226 #
12227 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12228 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
12229 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
12230 # EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
12231 #
12232 # INPORT is a lport number, e.g. 11 for vif11.
12233 # HV is a hypervisor number
12234 # ETH_SRC and ETH_DST are each 12 hex digits.
12235 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12236 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12237 test_ip_packet() {
12238 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
12239 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
12240 shift 11
12241
12242 local ip_ttl=ff
12243 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
12244
12245 local reply_icmp_ttl=fe
12246 local icmp_data=00000000
12247 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
12248 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12249 echo $reply >> vif$inport.expected
12250
12251 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12252 }
12253
12254 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
12255 #
12256 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
12257 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
12258 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
12259 #
12260 # INPORT is an lport number, e.g. 11 for vif11.
12261 # HV is an hypervisor number
12262 # ETH_SRC and ETH_DST are each 12 hex digits.
12263 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12264 # TCP_SPORT and TCP_DPORT are 4 hex digits.
12265 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
12266 test_tcp_syn_packet() {
12267 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
12268 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
12269 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
12270 shift 12
12271
12272 local ip_ttl=ff
12273 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12274
12275 local tcp_rst_ttl=fe
12276 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
12277 echo $reply >> vif$inport.expected
12278
12279 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12280 }
12281
12282 # test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
12283 #
12284 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
12285 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
12286 # EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
12287 test_tcp6_packet() {
12288 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
12289 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
12290 local exp_tcp_rst_chksum=${10}
12291 shift 10
12292
12293 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
12294 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12295
12296 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
12297 echo $reply >> vif$inport.expected
12298
12299 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12300 }
12301
12302 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
12303 #
12304 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12305 # packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
12306 # EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
12307 test_ip6_packet() {
12308 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
12309 local exp_icmp_code=${10} exp_icmp_chksum=${11}
12310 shift 11
12311
12312 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
12313 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
12314
12315 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
12316 echo $reply >> vif$inport.expected
12317
12318 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12319 }
12320
12321 ip_to_hex() {
12322 printf "%02x%02x%02x%02x" "$@"
12323 }
12324
12325 for i in 1 2; do
12326 net_add n$i
12327 ovn-nbctl ls-add sw$i
12328
12329 sim_add hv$i
12330 as hv$i
12331 ovs-vsctl add-br br-phys
12332 ovn_attach n$i br-phys 192.168.$i.1
12333
12334 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
12335 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
12336
12337 ovs-vsctl -- add-port br-int vif$i -- \
12338 set interface vif$i \
12339 external-ids:iface-id=sw$i-p${i}0 \
12340 options:tx_pcap=hv$i/vif$i-tx.pcap \
12341 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12342 ofport-request=$i
12343 done
12344
12345 ovn-nbctl lr-add lr0
12346 for i in 1 2; do
12347 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
12348 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12349 -- set Logical_Switch_Port lrp$i-attachment type=router \
12350 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
12351 done
12352
12353 OVN_POPULATE_ARP
12354 # allow some time for ovn-northd and ovn-controller to catch up.
12355 ovn-nbctl --wait=hv sync
12356
12357 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
12358 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
12359 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
12360 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12361
12362 test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
12363 test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
12364 test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
12365 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
12366
12367 OVN_CLEANUP([hv1], [hv2])
12368 AT_CLEANUP
12369
12370 AT_SETUP([ovn -- ovn-controller exit])
12371 AT_SKIP_IF([test $HAVE_PYTHON = no])
12372 ovn_start
12373 # Logical network:
12374 # One Logical Router: ro, with two logical switches sw1 and sw2.
12375 # sw1 is for subnet 10.0.0.0/8
12376 # sw2 is for subnet 20.0.0.0/8
12377 # sw1 has a single port bound on hv1
12378 # sw2 has a single port bound on hv2
12379
12380 ovn-nbctl lr-add ro
12381 ovn-nbctl ls-add sw1
12382 ovn-nbctl ls-add sw2
12383
12384 sw1_ro_mac=00:00:10:00:00:01
12385 sw1_ro_ip=10.0.0.1
12386 sw2_ro_mac=00:00:20:00:00:01
12387 sw2_ro_ip=20.0.0.1
12388 sw1_p1_mac=00:00:10:00:00:02
12389 sw1_p1_ip=10.0.0.2
12390 sw2_p1_mac=00:00:20:00:00:02
12391 sw2_p1_ip=20.0.0.2
12392
12393 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
12394 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
12395 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
12396 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
12397 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
12398 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
12399
12400 ovn-nbctl lsp-add sw1 sw1-p1 \
12401 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
12402
12403 ovn-nbctl lsp-add sw2 sw2-p1 \
12404 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
12405
12406 net_add n1
12407
12408 sim_add hv1
12409 as hv1
12410 ovs-vsctl add-br br-phys
12411 ovn_attach n1 br-phys 192.168.0.1
12412 ovs-vsctl -- add-port br-int hv1-vif1 -- \
12413 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
12414 options:tx_pcap=hv1/vif1-tx.pcap \
12415 options:rxq_pcap=hv1/vif1-rx.pcap \
12416 ofport-request=1
12417
12418 sim_add hv2
12419 as hv2
12420 ovs-vsctl add-br br-phys
12421 ovn_attach n1 br-phys 192.168.0.2
12422 ovs-vsctl -- add-port br-int hv2-vif1 -- \
12423 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
12424 options:tx_pcap=hv2/vif1-tx.pcap \
12425 options:rxq_pcap=hv2/vif1-rx.pcap \
12426 ofport-request=1
12427
12428 OVN_POPULATE_ARP
12429
12430 sleep 1
12431
12432 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
12433 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12434 udp && udp.src==53 && udp.dst==4369"
12435
12436 # Start by Sending the packet and make sure it makes it there as expected
12437 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12438
12439 # Expected packet has TTL decreased by 1
12440 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
12441 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12442 udp && udp.src==53 && udp.dst==4369"
12443 echo $expected | ovstest test-ovn expr-to-packets > expected
12444
12445 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12446
12447 # Stop ovn-controller on hv2
12448 as hv2 ovs-appctl -t ovn-controller exit
12449
12450 # Now send the packet again. This time, it should not arrive.
12451 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12452
12453 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12454
12455 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
12456 as hv2 start_daemon ovn-controller
12457
12458 OVN_CLEANUP([hv1],[hv2])
12459 AT_CLEANUP
12460
12461 AT_SETUP([ovn -- external logical port])
12462 AT_SKIP_IF([test $HAVE_PYTHON = no])
12463 ovn_start
12464
12465 net_add n1
12466 sim_add hv1
12467 sim_add hv2
12468 sim_add hv3
12469
12470 ovn-nbctl ls-add ls1
12471 ovn-nbctl lsp-add ls1 ls1-lp1 \
12472 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
12473
12474 # Add a couple of external logical port
12475 ovn-nbctl lsp-add ls1 ls1-lp_ext1 \
12476 -- lsp-set-addresses ls1-lp_ext1 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12477 ovn-nbctl lsp-set-port-security ls1-lp_ext1 \
12478 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12479 ovn-nbctl lsp-set-type ls1-lp_ext1 external
12480
12481 ovn-nbctl lsp-add ls1 ls1-lp_ext2 \
12482 -- lsp-set-addresses ls1-lp_ext2 "f0:00:00:00:00:04 10.0.0.7 ae70::7"
12483 ovn-nbctl lsp-set-port-security ls1-lp_ext2 \
12484 "f0:00:00:00:00:04 10.0.0.7 ae70::8"
12485 ovn-nbctl lsp-set-type ls1-lp_ext2 external
12486
12487 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
12488 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
12489 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
12490
12491 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
12492 options="\"server_id\"=\"00:00:00:10:00:01\"")"
12493
12494 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
12495 ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext1 ${d1}
12496 ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext2 ${d1}
12497
12498 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d2}
12499 ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext1 ${d2}
12500 ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext2 ${d2}
12501
12502 # Create a logical router and connect it to ls1
12503 ovn-nbctl lr-add lr0
12504 ovn-nbctl lrp-add lr0 lr0-ls1 a0:10:00:00:00:01 10.0.0.1/24
12505 ovn-nbctl lsp-add ls1 ls1-lr0
12506 ovn-nbctl set Logical_Switch_Port ls1-lr0 type=router \
12507 options:router-port=lr0-ls1 addresses=router
12508
12509 # Create HA chassis group
12510 ovn-nbctl ha-chassis-group-add hagrp1
12511 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
12512
12513 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name="hagrp1"`
12514
12515 # There should be 1 HA_Chassis rows with chassis sets
12516 OVS_WAIT_UNTIL([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
12517 | grep '-' | wc -l ], [0], [1
12518 ])
12519
12520 as hv1
12521 ovs-vsctl add-br br-phys
12522 ovn_attach n1 br-phys 192.168.0.1
12523 ovs-vsctl -- add-port br-phys hv1-ext1 -- \
12524 set interface hv1-ext1 options:tx_pcap=hv1/ext1-tx.pcap \
12525 options:rxq_pcap=hv1/ext1-rx.pcap \
12526 ofport-request=2
12527 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12528
12529 as hv2
12530 ovs-vsctl add-br br-phys
12531 ovn_attach n1 br-phys 192.168.0.2
12532 ovs-vsctl -- add-port br-phys hv2-ext2 -- \
12533 set interface hv2-ext2 options:tx_pcap=hv2/ext2-tx.pcap \
12534 options:rxq_pcap=hv2/ext2-rx.pcap \
12535 ofport-request=2
12536 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12537
12538 as hv3
12539 ovs-vsctl add-br br-phys
12540 ovn_attach n1 br-phys 192.168.0.3
12541 ovs-vsctl -- add-port br-phys hv3-ext3 -- \
12542 set interface hv3-ext3 options:tx_pcap=hv3/ext3-tx.pcap \
12543 options:rxq_pcap=hv3/ext3-rx.pcap \
12544 ofport-request=2
12545 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12546
12547 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and
12548 # hv2 as ha-chassis-group is not set and no localnet port added to ls1.
12549 AT_CHECK([ovn-sbctl dump-flows ls1 | grep "offerip = 10.0.0.6" | \
12550 wc -l], [0], [0
12551 ])
12552 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12553 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12554 ])
12555 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12556 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12557 ])
12558 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12559 grep controller | grep tp_src=546 | grep \
12560 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12561 ])
12562 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12563 grep controller | grep tp_src=546 | grep \
12564 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12565 ])
12566
12567 hv1_uuid=$(ovn-sbctl list chassis hv1 | grep uuid | awk '{print $3}')
12568 hv2_uuid=$(ovn-sbctl list chassis hv2 | grep uuid | awk '{print $3}')
12569 hv3_uuid=$(ovn-sbctl list chassis hv3 | grep uuid | awk '{print $3}')
12570
12571 # The port_binding row for ls1-lp_ext1 should have empty chassis
12572 chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12573 logical_port=ls1-lp_ext1`
12574
12575 AT_CHECK([test x$chassis == x], [0], [])
12576
12577 # Associate hagrp1 ha-chassis-group to ls1-lp_ext1
12578 ovn-nbctl --wait=hv set Logical_Switch_Port ls1-lp_ext1 \
12579 ha-chassis-group=$hagrp1_uuid
12580
12581 # Get the hagrp1 uuid in SB DB.
12582 sb_hagrp1_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group \
12583 name="hagrp1"`
12584
12585 # Wait till ls1-lp_ext1 port_binding has ha_chassis_group set
12586 OVS_WAIT_UNTIL(
12587 [sb_pb_hagrp=`ovn-sbctl --bare --columns ha_chassis_group find \
12588 port_binding logical_port=ls1-lp_ext1`
12589 test "$sb_pb_hagrp" = "$sb_hagrp1_uuid"])
12590
12591 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and hv2
12592 # as no localnet port added to ls1 yet.
12593 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12594 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12595 ])
12596 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12597 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12598 ])
12599 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12600 grep controller | grep tp_src=546 | grep \
12601 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12602 ])
12603 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12604 grep controller | grep tp_src=546 | grep \
12605 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12606 ])
12607
12608 # Add the localnet port to the logical switch ls1
12609 ovn-nbctl lsp-add ls1 ln-public
12610 ovn-nbctl lsp-set-addresses ln-public unknown
12611 ovn-nbctl lsp-set-type ln-public localnet
12612 ovn-nbctl --wait=hv lsp-set-options ln-public network_name=phys
12613
12614 ln_public_key=$(ovn-sbctl list port_binding ln-public | grep tunnel_key | \
12615 awk '{print $3}')
12616
12617 # The ls1-lp_ext1 should be bound to hv1 as only hv1 is part of the
12618 # ha chassis group.
12619 OVS_WAIT_UNTIL(
12620 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12621 logical_port=ls1-lp_ext1`
12622 test "$chassis" = "$hv1_uuid"])
12623
12624 # There should be DHCPv4/v6 OF flows for the ls1-lp_ext1 port in hv1
12625 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12626 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
12627 wc -l], [0], [3
12628 ])
12629 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12630 grep controller | grep tp_src=546 | grep \
12631 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
12632 grep reg14=0x$ln_public_key | wc -l], [0], [1
12633 ])
12634
12635 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv2
12636 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12637 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12638 ])
12639 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12640 grep controller | grep tp_src=546 | grep \
12641 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12642 ])
12643
12644 # No DHCPv4/v6 flows for the external port - ls1-lp_ext2 - 10.0.0.7 in hv1 and
12645 # hv2 as requested-chassis option is not set.
12646 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12647 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12648 ])
12649 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12650 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12651 ])
12652 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12653 grep controller | grep tp_src=546 | grep \
12654 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12655 ])
12656 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12657 grep controller | grep tp_src=546 | grep \
12658 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12659 ])
12660
12661 as hv1
12662 ovs-vsctl show
12663
12664 # This shell function sends a DHCP request packet
12665 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
12666 test_dhcp() {
12667 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
12668 shift; shift; shift; shift; shift;
12669 if test $use_ip != 0; then
12670 src_ip=$1
12671 dst_ip=$2
12672 shift; shift;
12673 else
12674 src_ip=`ip_to_hex 0 0 0 0`
12675 dst_ip=`ip_to_hex 255 255 255 255`
12676 fi
12677 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
12678 # udp header and dhcp header
12679 request=${request}0044004300fc0000
12680 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
12681 # client hardware padding
12682 request=${request}00000000000000000000
12683 # server hostname
12684 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12685 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12686 # boot file name
12687 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12688 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12689 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12690 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12691 # dhcp magic cookie
12692 request=${request}63825363
12693 # dhcp message type
12694 request=${request}3501${dhcp_type}ff
12695
12696 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
12697 # total IP length will be the IP length of the request packet
12698 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
12699 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
12700 udp_len=`expr $ip_len - 20`
12701 ip_len=$(printf "%x" $ip_len)
12702 udp_len=$(printf "%x" $udp_len)
12703 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
12704 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
12705 # udp header and dhcp header.
12706 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
12707 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
12708 # your ip address
12709 reply=${reply}${offer_ip}
12710 # next server ip address, relay agent ip address, client mac address
12711 reply=${reply}0000000000000000${src_mac}
12712 # client hardware padding
12713 reply=${reply}00000000000000000000
12714 # server hostname
12715 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12716 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12717 # boot file name
12718 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12719 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12720 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12721 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12722 # dhcp magic cookie
12723 reply=${reply}63825363
12724 # dhcp message type
12725 local dhcp_reply_type=02
12726 if test $dhcp_type = 03; then
12727 dhcp_reply_type=05
12728 fi
12729 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
12730 echo $reply >> ext1_v4.expected
12731
12732 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12733 }
12734
12735
12736 trim_zeros() {
12737 sed 's/\(00\)\{1,\}$//'
12738 }
12739
12740 # This shell function sends a DHCPv6 request packet
12741 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
12742 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
12743 # packet should be received twice (one from ovn-controller and the other
12744 # from the "ovs-ofctl monitor br-int resume"
12745 test_dhcpv6() {
12746 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
12747 local req_pkt_in_expected=$6
12748 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
12749 # dst ip ff02::1:2
12750 request=${request}ff020000000000000000000000010002
12751 # udp header and dhcpv6 header
12752 request=${request}02220223002affff${msg_code}010203
12753 # Client identifier
12754 request=${request}0001000a00030001${src_mac}
12755 # IA-NA (Identity Association for Non Temporary Address)
12756 request=${request}0003000c0102030400000e1000001518
12757 shift; shift; shift; shift; shift;
12758
12759 local server_mac=000000100001
12760 local server_lla=fe80000000000000020000fffe100001
12761 local reply_code=07
12762 if test $msg_code = 01; then
12763 reply_code=02
12764 fi
12765 local msg_len=54
12766 if test $offer_ip = 1; then
12767 msg_len=28
12768 fi
12769 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101
12770 reply=${reply}${server_lla}${src_lla}
12771
12772 # udp header and dhcpv6 header
12773 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
12774 # Client identifier
12775 reply=${reply}0001000a00030001${src_mac}
12776 # IA-NA
12777 if test $offer_ip != 1; then
12778 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}
12779 reply=${reply}ffffffffffffffff
12780 fi
12781 # Server identifier
12782 reply=${reply}0002000a00030001${server_mac}
12783
12784 echo $reply | trim_zeros >> ext${inport}_v6.expected
12785 # The inport also receives the request packet since it is connected
12786 # to the br-phys.
12787 #echo $request >> ext${inport}_v6.expected
12788
12789 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12790 }
12791
12792 reset_pcap_file() {
12793 local iface=$1
12794 local pcap_file=$2
12795 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12796 options:rxq_pcap=dummy-rx.pcap
12797 rm -f ${pcap_file}*.pcap
12798 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12799 options:rxq_pcap=${pcap_file}-rx.pcap
12800 }
12801
12802 ip_to_hex() {
12803 printf "%02x%02x%02x%02x" "$@"
12804 }
12805
12806 AT_CAPTURE_FILE([ofctl_monitor0_hv1.log])
12807 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
12808 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv1.log
12809
12810 AT_CAPTURE_FILE([ofctl_monitor0_hv2.log])
12811 as hv2 ovs-ofctl monitor br-int resume --detach --no-chdir \
12812 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv2.log
12813
12814 AT_CAPTURE_FILE([ofctl_monitor0_hv3.log])
12815 as hv3 ovs-ofctl monitor br-int resume --detach --no-chdir \
12816 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv3.log
12817
12818 as hv1
12819 reset_pcap_file hv1-ext1 hv1/ext1
12820
12821 # Send DHCPDISCOVER.
12822 offer_ip=`ip_to_hex 10 0 0 6`
12823 server_ip=`ip_to_hex 10 0 0 1`
12824 server_mac=ff1000000001
12825 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
12826 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
12827 $expected_dhcp_opts
12828
12829 # NXT_RESUMEs should be 1 in hv1.
12830 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12831
12832 # NXT_RESUMEs should be 0 in hv2.
12833 OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12834
12835 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
12836 cat ext1_v4.expected | cut -c -48 > expout
12837 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
12838 # Skipping the IPv4 checksum.
12839 cat ext1_v4.expected | cut -c 53- > expout
12840 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
12841
12842 # ovs-ofctl also resumes the packets and this causes other ports to receive
12843 # the DHCP request packet. So reset the pcap files so that its easier to test.
12844 as hv1
12845 reset_pcap_file hv1-ext1 hv1/ext1
12846
12847 rm -f ext1_v4.expected
12848 rm -f ext1_v4.packets
12849
12850 # Send DHCPv6 request
12851 src_mac=f00000000003
12852 src_lla=fe80000000000000f20000fffe000003
12853 offer_ip=ae700000000000000000000000000006
12854 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
12855
12856 # NXT_RESUMEs should be 2 in hv1.
12857 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12858
12859 # NXT_RESUMEs should be 0 in hv2.
12860 OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12861
12862 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
12863 sort > ext1_v6.packets
12864 cat ext1_v6.expected | cut -c -120 > expout
12865 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
12866 # Skipping the UDP checksum
12867 cat ext1_v6.expected | cut -c 125- > expout
12868 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
12869
12870 rm -f ext1_v6.expected
12871 rm -f ext1_v6.packets
12872
12873 as hv1
12874 reset_pcap_file hv1-ext1 hv1/ext1
12875
12876 # Delete the ha-chassis hv1.
12877 ovn-nbctl ha-chassis-group-remove-chassis hagrp1 hv1
12878 OVS_WAIT_UNTIL(
12879 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12880 logical_port=ls1-lp_ext1`
12881 test "$chassis" = ""])
12882
12883 # Add hv2 to the ha chassis group
12884 ovn-nbctl --wait=hv ha-chassis-group-add-chassis hagrp1 hv2 20
12885
12886 ovn-sbctl list ha_chassis_group
12887 ovn-sbctl list ha_chassis
12888
12889 ovn-sbctl find port_binding logical_port=ls1-lp_ext1
12890
12891 # The ls1-lp_ext1 should be bound to hv2
12892 OVS_WAIT_UNTIL(
12893 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12894 logical_port=ls1-lp_ext1`
12895 test "$chassis" = "$hv2_uuid"])
12896
12897 # There should be OF flows for DHCP4/v6 for the ls1-lp_ext1 port in hv2
12898 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12899 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
12900 wc -l], [0], [3
12901 ])
12902 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12903 grep controller | grep tp_src=546 | grep \
12904 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
12905 grep reg14=0x$ln_public_key | wc -l], [0], [1
12906 ])
12907
12908 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv1
12909 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12910 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12911 ])
12912 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12913 grep controller | grep tp_src=546 | grep \
12914 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
12915 grep reg14=0x$ln_public_key | wc -l], [0], [0
12916 ])
12917
12918 # Send DHCPDISCOVER again for hv1/ext1. The DHCP response should come from
12919 # hv2 ovn-controller.
12920 offer_ip=`ip_to_hex 10 0 0 6`
12921 server_ip=`ip_to_hex 10 0 0 1`
12922 server_mac=ff1000000001
12923 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
12924 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
12925 $expected_dhcp_opts
12926
12927 # NXT_RESUMEs should be 2 in hv1.
12928 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12929
12930 # NXT_RESUMEs should be 1 in hv2.
12931 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12932
12933 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
12934 cat ext1_v4.expected | cut -c -48 > expout
12935 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
12936 # Skipping the IPv4 checksum.
12937 cat ext1_v4.expected | cut -c 53- > expout
12938 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
12939
12940 # ovs-ofctl also resumes the packets and this causes other ports to receive
12941 # the DHCP request packet. So reset the pcap files so that its easier to test.
12942 as hv1
12943 reset_pcap_file hv1-ext1 hv1/ext1
12944
12945 rm -f ext1_v4.expected
12946
12947 # Send DHCPv6 request again
12948 src_mac=f00000000003
12949 src_lla=fe80000000000000f20000fffe000003
12950 offer_ip=ae700000000000000000000000000006
12951 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip 1
12952
12953 # NXT_RESUMEs should be 2 in hv1.
12954 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12955
12956 # NXT_RESUMEs should be 2 in hv2.
12957 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12958
12959 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
12960 sort > ext1_v6.packets
12961 cat ext1_v6.expected | cut -c -120 > expout
12962 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
12963 # Skipping the UDP checksum
12964 cat ext1_v6.expected | cut -c 125- > expout
12965 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
12966
12967 rm -f ext1_v6.expected
12968 rm -f ext1_v6.packets
12969
12970 as hv1
12971 ovs-vsctl show
12972 reset_pcap_file hv1-ext1 hv1/ext1
12973 reset_pcap_file br-phys_n1 hv1/br-phys_n1
12974 reset_pcap_file br-phys hv1/br-phys
12975
12976 as hv2
12977 ovs-vsctl show
12978 reset_pcap_file hv2-ext2 hv2/ext2
12979 reset_pcap_file br-phys_n1 hv2/br-phys_n1
12980 reset_pcap_file br-phys hv2/br-phys
12981
12982 # From ls1-lp_ext1, send ARP request for the router ip. The ARP
12983 # response should come from the router pipeline of hv2.
12984 ext1_mac=f00000000003
12985 router_mac=a01000000001
12986 ext1_ip=`ip_to_hex 10 0 0 6`
12987 router_ip=`ip_to_hex 10 0 0 1`
12988 arp_request=ffffffffffff${ext1_mac}08060001080006040001${ext1_mac}${ext1_ip}000000000000${router_ip}
12989
12990 as hv1 ovs-appctl netdev-dummy/receive hv1-ext1 $arp_request
12991 expected_response=${src_mac}${router_mac}08060001080006040002${router_mac}${router_ip}${ext1_mac}${ext1_ip}
12992 echo $expected_response > expout
12993 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_arp_resp
12994 AT_CHECK([cat ext1_arp_resp], [0], [expout])
12995
12996 # Verify that the response came from hv2
12997 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > ext1_arp_resp
12998 AT_CHECK([cat ext1_arp_resp], [0], [expout])
12999
13000 # Now add 3 ha chassis to the ha chassis group
13001 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
13002 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv2 20
13003 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 10
13004
13005 # hv1 should be master and claim ls1-lp_ext1
13006 OVS_WAIT_UNTIL(
13007 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13008 logical_port=ls1-lp_ext1`
13009 test "$chassis" = "$hv1_uuid"])
13010
13011 as hv1
13012 ovs-vsctl show
13013 reset_pcap_file hv1-ext1 hv1/ext1
13014 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13015 reset_pcap_file br-phys hv1/br-phys
13016
13017 as hv2
13018 ovs-vsctl show
13019 reset_pcap_file hv2-ext2 hv2/ext2
13020 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13021 reset_pcap_file br-phys hv2/br-phys
13022
13023 as hv3
13024 ovs-vsctl show
13025 reset_pcap_file hv3-ext3 hv3/ext3
13026 reset_pcap_file br-phys_n1 hv3/br-phys_n1
13027 reset_pcap_file br-phys hv3/br-phys
13028
13029 # Send DHCPDISCOVER.
13030 offer_ip=`ip_to_hex 10 0 0 6`
13031 server_ip=`ip_to_hex 10 0 0 1`
13032 server_mac=ff1000000001
13033 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13034 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13035 $expected_dhcp_opts
13036
13037 # NXT_RESUMEs should be 3 in hv1.
13038 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13039
13040 # NXT_RESUMEs should be 2 in hv2.
13041 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13042
13043 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13044 cat ext1_v4.expected | cut -c -48 > expout
13045 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13046 # Skipping the IPv4 checksum.
13047 cat ext1_v4.expected | cut -c 53- > expout
13048 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13049
13050 # ovs-ofctl also resumes the packets and this causes other ports to receive
13051 # the DHCP request packet. So reset the pcap files so that its easier to test.
13052 as hv1
13053 reset_pcap_file hv1-ext1 hv1/ext1
13054
13055 rm -f ext1_v4.expected
13056 rm -f ext1_v4.packets
13057
13058 # Send DHCPv6 request
13059 src_mac=f00000000003
13060 src_lla=fe80000000000000f20000fffe000003
13061 offer_ip=ae700000000000000000000000000006
13062 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13063
13064 # NXT_RESUMEs should be 4 in hv1.
13065 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13066
13067 # NXT_RESUMEs should be 2 in hv2.
13068 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13069
13070 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13071 sort > ext1_v6.packets
13072 cat ext1_v6.expected | cut -c -120 > expout
13073 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13074 # Skipping the UDP checksum
13075 cat ext1_v6.expected | cut -c 125- > expout
13076 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13077
13078 rm -f ext1_v6.expected
13079 rm -f ext1_v6.packets
13080 as hv1 reset_pcap_file hv1-ext1 hv1/ext1
13081
13082 # Now increase the priority of hv3 so it becomes master.
13083 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 50
13084
13085 # hv3 should be master and claim ls1-lp_ext1
13086 OVS_WAIT_UNTIL(
13087 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13088 logical_port=ls1-lp_ext1`
13089 test "$chassis" = "$hv3_uuid"])
13090
13091 as hv1
13092 ovs-vsctl show
13093 reset_pcap_file hv1-ext1 hv1/ext1
13094 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13095 reset_pcap_file br-phys hv1/br-phys
13096
13097 as hv2
13098 ovs-vsctl show
13099 reset_pcap_file hv2-ext2 hv2/ext2
13100 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13101 reset_pcap_file br-phys hv2/br-phys
13102
13103 as hv2
13104 ovs-vsctl show
13105 reset_pcap_file hv3-ext3 hv3/ext3
13106 reset_pcap_file br-phys_n1 hv3/br-phys_n1
13107 reset_pcap_file br-phys hv3/br-phys
13108
13109 # Send DHCPDISCOVER.
13110 offer_ip=`ip_to_hex 10 0 0 6`
13111 server_ip=`ip_to_hex 10 0 0 1`
13112 server_mac=ff1000000001
13113 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13114 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13115 $expected_dhcp_opts
13116
13117 # NXT_RESUMEs should be 4 in hv1.
13118 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13119
13120 # NXT_RESUMEs should be 2 in hv2.
13121 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13122
13123 # NXT_RESUMEs should be 1 in hv3.
13124 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13125
13126 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13127 cat ext1_v4.expected | cut -c -48 > expout
13128 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13129 # Skipping the IPv4 checksum.
13130 cat ext1_v4.expected | cut -c 53- > expout
13131 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13132
13133 # ovs-ofctl also resumes the packets and this causes other ports to receive
13134 # the DHCP request packet. So reset the pcap files so that its easier to test.
13135 as hv1
13136 reset_pcap_file hv1-ext1 hv1/ext1
13137
13138 rm -f ext1_v4.expected
13139 rm -f ext1_v4.packets
13140
13141 # Send DHCPv6 request
13142 src_mac=f00000000003
13143 src_lla=fe80000000000000f20000fffe000003
13144 offer_ip=ae700000000000000000000000000006
13145 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13146
13147 # NXT_RESUMEs should be 4 in hv1.
13148 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13149
13150 # NXT_RESUMEs should be 2 in hv2.
13151 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13152
13153 # NXT_RESUMEs should be 2 in hv3.
13154 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13155
13156 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13157 sort > ext1_v6.packets
13158 cat ext1_v6.expected | cut -c -120 > expout
13159 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13160 # Skipping the UDP checksum
13161 cat ext1_v6.expected | cut -c 125- > expout
13162 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13163
13164 # disconnect hv3 from the network, hv1 should take over
13165 as hv3
13166 port=${sandbox}_br-phys
13167 as main ovs-vsctl del-port n1 $port
13168
13169 # hv1 should be master and claim ls1-lp_ext1
13170 OVS_WAIT_UNTIL(
13171 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13172 logical_port=ls1-lp_ext1`
13173 test "$chassis" = "$hv1_uuid"])
13174
13175 OVN_CLEANUP([hv1],[hv2],[hv3])
13176 AT_CLEANUP
13177
13178 AT_SETUP([ovn -- Address Set Incremental Processing])
13179 AT_KEYWORDS([ovn_as_inc])
13180 AT_SKIP_IF([test $HAVE_PYTHON = no])
13181 ovn_start
13182
13183 net_add n1
13184 sim_add hv1
13185 as hv1
13186 ovs-vsctl add-br br-phys
13187 ovn_attach n1 br-phys 192.168.0.10
13188
13189 ovn-nbctl ls-add ls1
13190 for i in 1 2; do
13191 ovn-nbctl lsp-add ls1 lp$i \
13192 -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i"
13193 as hv1 ovs-vsctl \
13194 -- add-port br-int vif$i \
13195 -- set Interface vif$i \
13196 external-ids:iface-id=lp$i
13197 done
13198
13199 for i in 1 2 3; do
13200 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13201 as2_uuid=`ovn-nbctl --wait=hv create addr name=as2`
13202 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13203 'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related
13204 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10"
13205 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore])
13206
13207 # Update address set as1
13208 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11"
13209 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore])
13210
13211 # Update address set as2
13212 ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13"
13213 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13214
13215 # Add another ACL referencing as1
13216 n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13217 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13218 'outport=="lp2" && ip4 && ip4.src == $as1' allow-related
13219 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13220 AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore])
13221
13222 # Remove an ACL
13223 ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \
13224 'outport=="lp2" && ip4 && ip4.src == $as1'
13225 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13226 AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore])
13227
13228 # Remove as1 while it is still used by an ACL, the lflows should be reparsed and
13229 # parsing should fail.
13230 echo "before del as1"
13231 ovn-nbctl list addr | grep as1
13232 ovn-nbctl --wait=hv destroy addr $as1_uuid
13233 echo "after del as1"
13234 ovn-nbctl list addr | grep as1
13235 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore])
13236 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13237
13238 # Recreate as1
13239 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13240 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13241
13242 # Remove ACLs and address sets
13243 ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid
13244 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13245
13246 ovn-nbctl --wait=hv acl-del ls1
13247 done
13248
13249 # Gracefully terminate daemons
13250 OVN_CLEANUP([hv1])
13251 AT_CLEANUP
13252
13253 AT_SETUP([ovn -- ovn-controller restart])
13254 AT_SKIP_IF([test $HAVE_PYTHON = no])
13255 ovn_start
13256
13257 # Logical network:
13258 # One Logical Router: ro, with two logical switches sw1 and sw2.
13259 # sw1 is for subnet 10.0.0.0/8
13260 # sw2 is for subnet 20.0.0.0/8
13261 # sw1 has a single port bound on hv1
13262 # sw2 has a single port bound on hv2
13263
13264 ovn-nbctl lr-add ro
13265 ovn-nbctl ls-add sw1
13266 ovn-nbctl ls-add sw2
13267
13268 sw1_ro_mac=00:00:10:00:00:01
13269 sw1_ro_ip=10.0.0.1
13270 sw2_ro_mac=00:00:20:00:00:01
13271 sw2_ro_ip=20.0.0.1
13272 sw1_p1_mac=00:00:10:00:00:02
13273 sw1_p1_ip=10.0.0.2
13274 sw2_p1_mac=00:00:20:00:00:02
13275 sw2_p1_ip=20.0.0.2
13276
13277 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
13278 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
13279 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
13280 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
13281 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
13282 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
13283
13284 ovn-nbctl lsp-add sw1 sw1-p1 \
13285 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
13286
13287 ovn-nbctl lsp-add sw2 sw2-p1 \
13288 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
13289
13290 net_add n1
13291
13292 sim_add hv1
13293 as hv1
13294 ovs-vsctl add-br br-phys
13295 ovn_attach n1 br-phys 192.168.0.1
13296 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13297 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
13298 options:tx_pcap=hv1/vif1-tx.pcap \
13299 options:rxq_pcap=hv1/vif1-rx.pcap \
13300 ofport-request=1
13301
13302 sim_add hv2
13303 as hv2
13304 ovs-vsctl add-br br-phys
13305 ovn_attach n1 br-phys 192.168.0.2
13306 ovs-vsctl -- add-port br-int hv2-vif1 -- \
13307 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
13308 options:tx_pcap=hv2/vif1-tx.pcap \
13309 options:rxq_pcap=hv2/vif1-rx.pcap \
13310 ofport-request=1
13311
13312 OVN_POPULATE_ARP
13313
13314 sleep 1
13315
13316 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
13317 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13318 udp && udp.src==53 && udp.dst==4369"
13319
13320 # Start by Sending the packet and make sure it makes it there as expected
13321 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13322
13323 # Expected packet has TTL decreased by 1
13324 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
13325 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13326 udp && udp.src==53 && udp.dst==4369"
13327 echo $expected | ovstest test-ovn expr-to-packets > expected
13328
13329 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13330
13331 # Stop ovn-controller on hv2 with --restart flag
13332 as hv2 ovs-appctl -t ovn-controller exit --restart
13333
13334 # Now send the packet again. This time, it should still arrive
13335 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13336
13337 cat expected expected > expected2
13338
13339 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
13340
13341 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
13342 as hv2 start_daemon ovn-controller
13343
13344 OVN_CLEANUP([hv1],[hv2])
13345
13346
13347 AT_CLEANUP
13348
13349 AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
13350 ovn_start
13351
13352 # Set up a switch with some switch ports of varying address types
13353 ovn-nbctl ls-add sw1
13354 ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
13355
13356 ovn-nbctl lsp-add sw1 sw1-p1
13357 ovn-nbctl lsp-add sw1 sw1-p2
13358 ovn-nbctl lsp-add sw1 sw1-p3
13359 ovn-nbctl lsp-add sw1 sw1-p4
13360
13361 ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1" "00:00:00:00:00:02 10.0.0.2 aef0::2"
13362 ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
13363 ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
13364 ovn-nbctl lsp-set-addresses sw1-p4 "router"
13365 ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
13366
13367 ovn-nbctl list logical_switch_port
13368
13369 # Now try to add duplicate addresses on a new port. These should all fail
13370 ovn-nbctl --wait=sb lsp-add sw1 sw1-p5
13371 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
13372 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
13373 ])
13374 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
13375 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
13376 ])
13377 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
13378 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
13379 ])
13380 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
13381 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
13382 ])
13383 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
13384 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
13385 ])
13386 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
13387 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
13388 ])
13389
13390 # Now try re-setting sw1-p1. This should succeed
13391 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
13392
13393 # Now create a new switch and try setting IP addresses the same as the
13394 # first switch. This should succeed.
13395 ovn-nbctl ls-add sw2
13396 ovn-nbctl lsp-add sw2 sw2-p1
13397
13398 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
13399 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
13400 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
13401 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
13402
13403 AT_CLEANUP
13404
13405 AT_SETUP([ovn -- router - check packet length - icmp defrag])
13406 AT_KEYWORDS([check packet length])
13407 AT_SKIP_IF([test $HAVE_PYTHON = no])
13408 ovn_start
13409
13410 ovn-nbctl ls-add sw0
13411 ovn-nbctl lsp-add sw0 sw0-port1
13412 ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 10.0.0.3"
13413
13414 ovn-nbctl lr-add lr0
13415 ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
13416 ovn-nbctl lsp-add sw0 sw0-lr0
13417 ovn-nbctl lsp-set-type sw0-lr0 router
13418 ovn-nbctl lsp-set-addresses sw0-lr0 router
13419 ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
13420
13421 ovn-nbctl ls-add public
13422 ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
13423 ovn-nbctl lsp-add public public-lr0
13424 ovn-nbctl lsp-set-type public-lr0 router
13425 ovn-nbctl lsp-set-addresses public-lr0 router
13426 ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
13427
13428 # localnet port
13429 ovn-nbctl lsp-add public ln-public
13430 ovn-nbctl lsp-set-type ln-public localnet
13431 ovn-nbctl lsp-set-addresses ln-public unknown
13432 ovn-nbctl lsp-set-options ln-public network_name=phys
13433
13434 ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
13435 ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
13436
13437 net_add n1
13438
13439 sim_add hv1
13440 as hv1
13441 ovs-vsctl add-br br-phys
13442 ovn_attach n1 br-phys 192.168.0.1
13443 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13444 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13445 set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
13446 options:tx_pcap=hv1/vif1-tx.pcap \
13447 options:rxq_pcap=hv1/vif1-rx.pcap \
13448 ofport-request=1
13449
13450 reset_pcap_file() {
13451 local iface=$1
13452 local pcap_file=$2
13453 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
13454 options:rxq_pcap=dummy-rx.pcap
13455 rm -f ${pcap_file}*.pcap
13456 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
13457 options:rxq_pcap=${pcap_file}-rx.pcap
13458 }
13459
13460 ip_to_hex() {
13461 printf "%02x%02x%02x%02x" "$@"
13462 }
13463
13464 test_ip_packet_larger() {
13465 local icmp_pmtu_reply_expected=$1
13466
13467 # Send ip packet from sw0-port1 to outside
13468 src_mac="505400000001" # sw-port1 mac
13469 dst_mac="00000000ff01" # sw0-lr0 mac (internal router leg)
13470 src_ip=`ip_to_hex 10 0 0 3`
13471 dst_ip=`ip_to_hex 172 168 0 3`
13472 # Set the packet length to 100.
13473 pkt_len=0064
13474 packet=${dst_mac}${src_mac}08004500${pkt_len}0000000040010000
13475 orig_packet_l3=${src_ip}${dst_ip}0304000000000000
13476 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13477 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13478 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13479 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13480 packet=${packet}${orig_packet_l3}
13481
13482 # If icmp_pmtu_reply_expected is 0, it means the packet is lesser than
13483 # the gateway mtu and should be delivered to the provider bridge via the
13484 # localnet port.
13485 # If icmp_pmtu_reply_expected is 1, it means the packet is larger than
13486 # the gateway mtu and ovn-controller should drop the packet and instead
13487 # generate ICMPv4 Destination Unreachable message with pmtu set to 42.
13488 if test $icmp_pmtu_reply_expected = 0; then
13489 # Packet to expect at br-phys.
13490 src_mac="000020201213"
13491 dst_mac="00000012af11"
13492 src_ip=`ip_to_hex 10 0 0 3`
13493 dst_ip=`ip_to_hex 172 168 0 3`
13494 expected=${dst_mac}${src_mac}08004500${pkt_len}000000003f010100
13495 expected=${expected}${src_ip}${dst_ip}0304000000000000
13496 expected=${expected}000000000000000000000000000000000000
13497 expected=${expected}000000000000000000000000000000000000
13498 expected=${expected}000000000000000000000000000000000000
13499 expected=${expected}000000000000000000000000000000000000
13500 echo $expected > br_phys_n1.expected
13501 else
13502 # MTU would be 100 - 18 = 82 (hex 0052)
13503 mtu=0052
13504 src_ip=`ip_to_hex 10 0 0 1`
13505 dst_ip=`ip_to_hex 10 0 0 3`
13506 # pkt len should be 128 (28 (icmp packet) + 100 (orig ip + payload))
13507 reply_pkt_len=0080
13508 ip_csum=bd91
13509 icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe016879
13510 icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000${mtu}
13511 icmp_reply=${icmp_reply}4500${pkt_len}000000003f010100
13512 icmp_reply=${icmp_reply}${orig_packet_l3}
13513 echo $icmp_reply > hv1-vif1.expected
13514 fi
13515
13516 as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13517 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
13518
13519 # Send packet from sw0-port1 to outside
13520 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
13521
13522 if test $icmp_pmtu_reply_expected = 0; then
13523 OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br_phys_n1.expected])
13524 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > packets
13525 AT_CHECK([cat packets], [0], [])
13526 else
13527 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [hv1-vif1.expected])
13528 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap > \
13529 packets
13530 AT_CHECK([cat packets], [0], [])
13531 fi
13532 }
13533
13534 ovn-nbctl show
13535 ovn-sbctl show
13536
13537 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int \
13538 | grep "check_pkt_larger" | wc -l], [0], [[0
13539 ]])
13540 dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep _uuid | \
13541 awk '{print $3}')
13542 ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
13543 logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
13544
13545 # Set the gateway mtu to 100. If the packet length is > 100, ovn-controller
13546 # should send icmp host not reachable with pmtu set to 100.
13547 ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
13548 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13549 OVS_WAIT_UNTIL([
13550 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(100)" | \
13551 wc -l` -eq 1
13552 ])
13553
13554 icmp_reply_expected=1
13555 test_ip_packet_larger $icmp_reply_expected
13556
13557 # Set the gateway mtu to 500.
13558 ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=500
13559 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13560 OVS_WAIT_UNTIL([
13561 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(500)" | \
13562 wc -l` -eq 1
13563 ])
13564
13565 # Now the packet should be sent via the localnet port to br-phys.
13566 icmp_reply_expected=0
13567 test_ip_packet_larger $icmp_reply_expected
13568 OVN_CLEANUP([hv1])
13569 AT_CLEANUP
13570
13571 AT_SETUP([ovn -- IP packet buffering])
13572 AT_KEYWORDS([ip-buffering])
13573 AT_SKIP_IF([test $HAVE_PYTHON = no])
13574 ovn_start
13575
13576 # Logical network:
13577 # One LR lr0 that has switches sw0 (192.168.1.0/24) and
13578 # sw1 (172.16.1.0/24) connected to it.
13579 #
13580 # Physical network:
13581 # Tw0 hypervisors hv[12].
13582 # hv1 hosts vif sw0-p0.
13583 # hv1 hosts vif sw1-p0.
13584
13585 send_icmp_packet() {
13586 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
13587 shift 8
13588
13589 local ip_ttl=ff
13590 local ip_len=001c
13591 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
13592 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13593 }
13594
13595 send_icmp6_packet() {
13596 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
13597 shift 8
13598
13599 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
13600 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
13601
13602 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13603 }
13604
13605 get_arp_req() {
13606 local eth_src=$1 spa=$2 tpa=$3
13607 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
13608 echo $request
13609 }
13610
13611 send_arp_reply() {
13612 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
13613 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
13614 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13615 }
13616
13617 send_na() {
13618 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
13619 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13620 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
13621
13622 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13623 }
13624
13625 get_nd() {
13626 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
13627 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13628 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
13629
13630 echo $request
13631 }
13632
13633 net_add n1
13634
13635 sim_add hv1
13636 as hv1
13637 ovs-vsctl add-br br-phys
13638 ovn_attach n1 br-phys 192.168.0.1
13639 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13640 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
13641 options:tx_pcap=hv1/vif1-tx.pcap \
13642 options:rxq_pcap=hv1/vif1-rx.pcap \
13643 ofport-request=1
13644
13645 sim_add hv2
13646 as hv2
13647 ovs-vsctl add-br br-phys
13648 ovn_attach n1 br-phys 192.168.0.2
13649 ovs-vsctl -- add-port br-int hv2-vif1 -- \
13650 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
13651 options:tx_pcap=hv2/vif1-tx.pcap \
13652 options:rxq_pcap=hv2/vif1-rx.pcap \
13653 ofport-request=1
13654
13655 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
13656 ovn-nbctl ls-add sw0
13657 ovn-nbctl ls-add sw1
13658
13659 ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001:0:0:0:0:0:0:1/64
13660 ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
13661 type=router options:router-port=sw0 \
13662 -- lsp-set-addresses rp-sw0 router
13663
13664 ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64
13665 ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
13666 type=router options:router-port=sw1 \
13667 -- lsp-set-addresses rp-sw1 router
13668
13669 ovn-nbctl lsp-add sw0 sw0-p0 \
13670 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
13671
13672 ovn-nbctl lsp-add sw1 sw1-p0 \
13673 -- lsp-set-addresses sw1-p0 unknown
13674
13675 OVN_POPULATE_ARP
13676 ovn-nbctl --wait=hv sync
13677
13678 ip_to_hex() {
13679 printf "%02x%02x%02x%02x" "$@"
13680 }
13681
13682 src_mac=f00000010203
13683 src_ip=$(ip_to_hex 192 168 1 2)
13684 src_ip6=20010000000000000000000000000002
13685
13686 router_mac0=000001010203
13687 router_mac1=000002010203
13688 router_ip=$(ip_to_hex 172 16 1 1)
13689 router_ip6=20020000000000000000000000000001
13690
13691 dst_mac=001122334455
13692 dst_ip=$(ip_to_hex 172 16 1 10)
13693 dst_ip6=20020000000000000000000000000010
13694
13695 data=0800bee4391a0001
13696
13697 send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
13698 send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
13699 echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
13700 echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
13701
13702 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13703
13704 nd_ip=ff0200000000000000000001ff000010
13705 ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
13706
13707 send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
13708 echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
13709 echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
13710 send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
13711
13712 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13713
13714 OVN_CLEANUP([hv1],[hv2])
13715 AT_CLEANUP
13716
13717 AT_SETUP([ovn -- neighbor update on same HV])
13718 AT_SKIP_IF([test $HAVE_PYTHON = no])
13719 ovn_start
13720
13721 # Logical network:
13722 # A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
13723 # each with a distributed gateway port.
13724 # Two VMs: lp0 on sw0 connected to lr0
13725 # lp1 on sw1 connected to lr1
13726 #
13727 # This test adds a floating IP to each VM so when they are bound to the same
13728 # hypervisor, it checks that the GARP sent by ovn-controller causes the
13729 # MAC_Binding entries to be updated properly on each logical router.
13730 # It will also capture packets on the physical interface to make sure that the
13731 # GARPs have been sent out to the external network as well.
13732
13733 # Create logical switches
13734 ovn-nbctl ls-add sw0
13735 ovn-nbctl ls-add sw1
13736 ovn-nbctl ls-add pub
13737
13738 # Created localnet port on public switch
13739 ovn-nbctl lsp-add pub ln-pub
13740 ovn-nbctl lsp-set-type ln-pub localnet
13741 ovn-nbctl lsp-set-addresses ln-pub unknown
13742 ovn-nbctl lsp-set-options ln-pub network_name=phys
13743
13744 # Create logical routers and connect them to public switch
13745 ovn-nbctl create Logical_Router name=lr0
13746 ovn-nbctl create Logical_Router name=lr1
13747
13748 ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
13749 ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
13750 type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
13751 ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
13752 ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
13753 type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
13754
13755 ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
13756 ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
13757
13758 # Connect sw0 and sw1 to lr0 and lr1
13759 ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
13760 ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
13761 options:router-port=lr0-sw0 addresses="router"
13762 ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
13763 ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
13764 options:router-port=lr1-sw1 addresses="router"
13765
13766
13767 # Add SNAT rules
13768 ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
13769 ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
13770
13771 net_add n1
13772 sim_add hv1
13773 as hv1
13774 ovs-vsctl add-br br-phys
13775 ovn_attach n1 br-phys 172.24.4.1
13776 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13777
13778 ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
13779 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
13780
13781 ovn-nbctl lsp-add sw0 lp0
13782 ovn-nbctl lsp-add sw1 lp1
13783 ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
13784 ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
13785
13786 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
13787 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
13788
13789 # Create two floating IPs, one for each VIF
13790 ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
13791 ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
13792
13793 # Check that the MAC_Binding entries have been properly created
13794 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
13795 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
13796
13797 # Check that the GARPs went also to the external physical network
13798 # Wait until at least 4 packets have arrived and copy them to a separate file as
13799 # more GARPs are expected in the capture in order to avoid race conditions.
13800 OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
13801 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
13802
13803 # GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
13804 echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
13805 # GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
13806 echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
13807 # GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
13808 echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
13809 # GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
13810 echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
13811 AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
13812 #OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
13813
13814 OVN_CLEANUP([hv1])
13815 AT_CLEANUP
13816
13817 AT_SETUP([ovn -- ipam to non-ipam])
13818 ovn_start
13819
13820 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
13821 ovn-nbctl ls-add sw0
13822 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
13823 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
13824
13825 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
13826 ["0a:00:00:a8:01:03 192.168.1.2"
13827 ])
13828
13829 ovn-nbctl --wait=sb lsp-set-addresses p0 router
13830
13831 ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses
13832
13833 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0], [[[]]
13834 ])
13835 AT_CLEANUP
13836
13837 AT_SETUP([ovn -- ipam router ports])
13838 ovn_start
13839
13840 ovn-nbctl ls-add sw
13841 ovn-nbctl set logical_switch sw other-config:subnet=192.168.1.0/24
13842
13843 for i in 2 3 4; do
13844 ovn-nbctl lr-add ro$i
13845 ovn-nbctl lsp-add sw swp$i
13846 ovn-nbctl --wait=sb lsp-set-addresses swp$i "02:00:00:00:00:0$i dynamic"
13847 cidr=$(ovn-nbctl get logical_switch_port swp$i dynamic_addresses |cut -f2 -d' '|cut -f1 -d\")
13848 ovn-nbctl lrp-add ro$i rop$i 02:00:00:00:00:0$i $cidr/24 -- set logical_switch_port swp$i type=router options:router-port=rop$i addresses=router;
13849 AT_CHECK_UNQUOTED([ovn-nbctl get logical_router_port rop$i networks], [0], [[["192.168.1.$i/24"]]
13850 ])
13851 done
13852
13853 ovn-nbctl list logical_switch_port
13854 ovn-nbctl list logical_router_port
13855
13856 AT_CLEANUP
13857
13858 AT_SETUP([ovn -- test transport zones])
13859 ovn_start
13860
13861 net_add n1
13862 for i in 1 2 3 4 5; do
13863 sim_add hv$i
13864 as hv$i
13865 ovs-vsctl add-br br-phys
13866 ovn_attach n1 br-phys 192.168.$i.1
13867 done
13868
13869 dnl Wait for the changes to be propagated
13870 ovn-nbctl --wait=sb --timeout=3 sync
13871 ovn-nbctl --wait=hv --timeout=3 sync
13872
13873 dnl Assert that each Chassis has a tunnel formed to every other Chassis
13874 as hv1
13875 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13876 [[ovn-hv2-0
13877 ovn-hv3-0
13878 ovn-hv4-0
13879 ovn-hv5-0
13880 ]])
13881
13882 as hv2
13883 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13884 [[ovn-hv1-0
13885 ovn-hv3-0
13886 ovn-hv4-0
13887 ovn-hv5-0
13888 ]])
13889
13890 as hv3
13891 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13892 [[ovn-hv1-0
13893 ovn-hv2-0
13894 ovn-hv4-0
13895 ovn-hv5-0
13896 ]])
13897
13898 as hv4
13899 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13900 [[ovn-hv1-0
13901 ovn-hv2-0
13902 ovn-hv3-0
13903 ovn-hv5-0
13904 ]])
13905
13906 as hv5
13907 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13908 [[ovn-hv1-0
13909 ovn-hv2-0
13910 ovn-hv3-0
13911 ovn-hv4-0
13912 ]])
13913
13914 dnl Let's now add some Chassis to different transport zones
13915 dnl * hv1: Will be part of two transport zones: tz1 and tz2 so it
13916 dnl should have tunnels formed between the other two Chassis (hv2 and hv3)
13917 dnl
13918 dnl * hv2: Will be part of one transport zone: tz1. It should have a tunnel
13919 dnl to hv1 but not to hv3
13920 dnl
13921 dnl * hv3: Will be part of one transport zone: tz2. It should have a tunnel
13922 dnl to hv1 but not to hv2
13923 dnl
13924 dnl * hv4 and hv5: Will not have any TZ set so they will keep the tunnels
13925 dnl between themselves and remove the tunnels to other Chassis which now
13926 dnl belongs to some TZs
13927 dnl
13928 as hv1
13929 ovs-vsctl set open . external-ids:ovn-transport-zones=tz1,tz2
13930
13931 as hv2
13932 ovs-vsctl set open . external-ids:ovn-transport-zones=tz1
13933
13934 as hv3
13935 ovs-vsctl set open . external-ids:ovn-transport-zones=tz2
13936
13937 dnl Wait for the changes to be propagated
13938 ovn-nbctl --wait=sb --timeout=3 sync
13939 ovn-nbctl --wait=hv --timeout=3 sync
13940
13941 as hv1
13942 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13943 [[ovn-hv2-0
13944 ovn-hv3-0
13945 ]])
13946
13947 as hv2
13948 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13949 [[ovn-hv1-0
13950 ]])
13951
13952 as hv3
13953 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13954 [[ovn-hv1-0
13955 ]])
13956
13957 as hv4
13958 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13959 [[ovn-hv5-0
13960 ]])
13961
13962 as hv5
13963 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13964 [[ovn-hv4-0
13965 ]])
13966
13967 dnl Removing the transport zones should make all Chassis to create
13968 dnl tunnels between every other Chassis again
13969 for i in 1 2 3; do
13970 as hv$i
13971 ovs-vsctl remove open . external-ids ovn-transport-zones
13972 done
13973
13974 dnl Wait for the changes to be propagated
13975 ovn-nbctl --wait=sb --timeout=3 sync
13976 ovn-nbctl --wait=hv --timeout=3 sync
13977
13978 as hv1
13979 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13980 [[ovn-hv2-0
13981 ovn-hv3-0
13982 ovn-hv4-0
13983 ovn-hv5-0
13984 ]])
13985
13986 as hv2
13987 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13988 [[ovn-hv1-0
13989 ovn-hv3-0
13990 ovn-hv4-0
13991 ovn-hv5-0
13992 ]])
13993
13994 as hv3
13995 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
13996 [[ovn-hv1-0
13997 ovn-hv2-0
13998 ovn-hv4-0
13999 ovn-hv5-0
14000 ]])
14001
14002 as hv4
14003 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14004 [[ovn-hv1-0
14005 ovn-hv2-0
14006 ovn-hv3-0
14007 ovn-hv5-0
14008 ]])
14009
14010 as hv5
14011 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14012 [[ovn-hv1-0
14013 ovn-hv2-0
14014 ovn-hv3-0
14015 ovn-hv4-0
14016 ]])
14017
14018 OVN_CLEANUP([hv1], [hv2], [hv3])
14019 AT_CLEANUP