]> git.proxmox.com Git - mirror_ovs.git/blob - tests/ovn.at
ovn.at: fix occasional dns lookup test failure
[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_cond () {
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
27 sort $exp_text > expout
28 }
29 ])
30 m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
34 AT_BANNER([OVN components])
35
36 AT_SETUP([ovn -- lexer])
37 dnl For lines without =>, input and expected output are identical.
38 dnl For lines with =>, input precedes => and expected output follows =>.
39 AT_DATA([test-cases.txt], [dnl
40 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41 "abc\u0020def" => "abc def"
42 " => error("Input ends inside quoted string.")dnl "
43
44 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45 $1 => error("`$' must be followed by a valid identifier.") 1
46
47 a/*b*/c => a c
48 a//b c => a
49 a/**/b => a b
50 a/*/b => a error("`/*' without matching `*/'.")
51 a/*/**/b => a b
52 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
54 0 1 12345 18446744073709551615
55 18446744073709551616 => error("Decimal constants must be less than 2**64.")
56 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
57 01 => error("Decimal constants must not have leading zeros.")
58
59 0/0
60 0/1
61 1/0 => error("Value contains unmasked 1-bits.")
62 1/1
63 128/384
64 1/3
65 1/ => error("Integer constant expected.")
66
67 1/0x123 => error("Value and mask have incompatible formats.")
68
69 0x1234
70 0x01234 => 0x1234
71 0x0 => 0
72 0x000 => 0
73 0xfedcba9876543210
74 0XFEDCBA9876543210 => 0xfedcba9876543210
75 0xfedcba9876543210fedcba9876543210
76 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
77 0x => error("Hex digits expected following 0x.")
78 0X => error("Hex digits expected following 0X.")
79 0x0/0x0 => 0/0
80 0x0/0x1 => 0/0x1
81 0x1/0x0 => error("Value contains unmasked 1-bits.")
82 0xffff/0x1ffff
83 0x. => error("Invalid syntax in hexadecimal constant.")
84
85 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86 256.1.2.3 => error("Invalid numeric constant.")
87 192.168.0.0/16
88 192.168.0.0/255.255.0.0 => 192.168.0.0/16
89 192.168.0.0/255.255.255.0 => 192.168.0.0/24
90 192.168.0.0/255.255.0.255
91 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92 192.168.0.0/32
93 192.168.0.0/255.255.255.255 => 192.168.0.0/32
94 1.2.3.4:5 => 1.2.3.4 : 5
95
96 ::
97 ::1
98 ff00::1234 => ff00::1234
99 2001:db8:85a3::8a2e:370:7334
100 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
101 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102 ::ffff:192.0.2.128
103 ::ffff:c000:0280 => ::ffff:192.0.2.128
104 ::1/::1
105 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106 ::1/128
107 ff00::/8
108 ff00::/ff00:: => ff00::/8
109
110 01:23:45:67:ab:cd
111 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
112 fe:dc:ba:98:76:54
113 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
114 01:00:00:00:00:00/01:00:00:00:00:00
115 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118 fe:x => error("Invalid numeric constant.")
119 00:01:02:03:04:x => error("Invalid numeric constant.")
120
121 # Test that operators are tokenized as expected, even without white space.
122 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
123 & => error("`&' is only valid as part of `&&'.")
124 | => error("`|' is only valid as part of `||'.")
125 - => error("`-' is only valid as part of `--'.")
126
127 ^ => error("Invalid character `^' in input.")
128 ])
129 AT_CAPTURE_FILE([input.txt])
130 sed 's/ =>.*//' test-cases.txt > input.txt
131 sed 's/.* => //' test-cases.txt > expout
132 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133 AT_CLEANUP
134
135 dnl The OVN expression parser needs to know what fields overlap with one
136 dnl another. This test therefore verifies that all the smaller registers
137 dnl are defined as terms of subfields of the larger ones.
138 dnl
139 dnl When we add or remove registers this test needs to be updated, of course.
140 AT_SETUP([ovn -- registers])
141 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142 [[reg0 = xxreg0[96..127]
143 reg1 = xxreg0[64..95]
144 reg2 = xxreg0[32..63]
145 reg3 = xxreg0[0..31]
146 reg4 = xxreg1[96..127]
147 reg5 = xxreg1[64..95]
148 reg6 = xxreg1[32..63]
149 reg7 = xxreg1[0..31]
150 reg8 = xreg4[32..63]
151 reg9 = xreg4[0..31]
152 xreg0 = xxreg0[64..127]
153 xreg1 = xxreg0[0..63]
154 xreg2 = xxreg1[64..127]
155 xreg3 = xxreg1[0..63]
156 xreg4 = OXM_OF_PKT_REG4
157 xxreg0 = NXM_NX_XXREG0
158 xxreg1 = NXM_NX_XXREG1
159 ]])
160 AT_CLEANUP
161
162 dnl Check that the OVN conntrack field definitions are correct.
163 AT_SETUP([ovn -- conntrack fields])
164 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
165 [[ct.dnat = ct_state[7]
166 ct.est = ct_state[1]
167 ct.inv = ct_state[4]
168 ct.new = ct_state[0]
169 ct.rel = ct_state[2]
170 ct.rpl = ct_state[3]
171 ct.snat = ct_state[6]
172 ct.trk = ct_state[5]
173 ct_label = NXM_NX_CT_LABEL
174 ct_label.blocked = ct_label[0]
175 ct_mark = NXM_NX_CT_MARK
176 ct_state = NXM_NX_CT_STATE
177 ]])
178 AT_CLEANUP
179
180 AT_SETUP([ovn -- compsition])
181 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
182 AT_CLEANUP
183
184 AT_SETUP([ovn -- expression parser])
185 dnl For lines without =>, input and expected output are identical.
186 dnl For lines with =>, input precedes => and expected output follows =>.
187 AT_DATA([test-cases.txt], [[
188 eth.type == 0x800
189 eth.type==0x800 => eth.type == 0x800
190 eth.type[0..15] == 0x800 => eth.type == 0x800
191
192 vlan.present
193 vlan.present == 1 => vlan.present
194 !(vlan.present == 0) => vlan.present
195 !(vlan.present != 1) => vlan.present
196 !vlan.present
197 vlan.present == 0 => !vlan.present
198 vlan.present != 1 => !vlan.present
199 !(vlan.present == 1) => !vlan.present
200 !(vlan.present != 0) => !vlan.present
201
202 eth.dst[0]
203 eth.dst[0] == 1 => eth.dst[0]
204 eth.dst[0] != 0 => eth.dst[0]
205 !(eth.dst[0] == 0) => eth.dst[0]
206 !(eth.dst[0] != 1) => eth.dst[0]
207
208 !eth.dst[0]
209 eth.dst[0] == 0 => !eth.dst[0]
210 eth.dst[0] != 1 => !eth.dst[0]
211 !(eth.dst[0] == 1) => !eth.dst[0]
212 !(eth.dst[0] != 0) => !eth.dst[0]
213
214 vlan.tci[12..15] == 0x3
215 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216 vlan.tci[12..15] != 0x3
217 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
218
219 !vlan.pcp => vlan.pcp == 0
220 !(vlan.pcp) => vlan.pcp == 0
221 vlan.pcp == 0x4
222 vlan.pcp != 0x4
223 vlan.pcp > 0x4
224 vlan.pcp >= 0x4
225 vlan.pcp < 0x4
226 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 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232 !(vlan.pcp > 0x4) => 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 !(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244 !(0x4 < vlan.pcp) => vlan.pcp <= 0x4
245
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 1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
250 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
251 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
252 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
253 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
254 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
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 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
264
265 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
267
268 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
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
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 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273 vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
274
275 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
276 ip6.src == ::1 => ip6.src == 0x1
277
278 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280 ip6.src == ::1 => ip6.src == 0x1
281
282 1
283 0
284 !1 => 0
285 !0 => 1
286
287 inport == "eth0"
288 !(inport != "eth0") => inport == "eth0"
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 sed 's/ =>.*//' test-cases.txt > input.txt
358 sed 's/.* => //' test-cases.txt > expout
359 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
360 AT_CLEANUP
361
362 AT_SETUP([ovn -- expression annotation])
363 dnl Input precedes =>, expected output follows =>.
364 AT_DATA([test-cases.txt], [[
365 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
366 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
367 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
368 ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
369 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
370
371 ip => eth.type == 0x800 || eth.type == 0x86dd
372 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
373 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
374 ip > 0 => Only == and != operators may be used with nominal field ip.
375 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
376 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
377
378 vlan.present => vlan.tci[12]
379 !vlan.present => !vlan.tci[12]
380
381 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
382 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
383 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
384
385 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
386 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
387 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
388
389 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
390 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
391 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'.
392 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'.
393 ]])
394 sed 's/ =>.*//' test-cases.txt > input.txt
395 sed 's/.* => //' test-cases.txt > expout
396 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
397 AT_CLEANUP
398
399 AT_SETUP([ovn -- 1-term expression conversion])
400 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
401 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
402 ])
403 AT_CLEANUP
404
405 AT_SETUP([ovn -- 2-term expression conversion])
406 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
407 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
408 ])
409 AT_CLEANUP
410
411 AT_SETUP([ovn -- 3-term expression conversion])
412 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
413 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
414 ])
415 AT_CLEANUP
416
417 AT_SETUP([ovn -- 3-term numeric expression simplification])
418 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
419 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
420 ])
421 AT_CLEANUP
422
423 AT_SETUP([ovn -- 4-term string expression simplification])
424 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
425 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
426 ])
427 AT_CLEANUP
428
429 AT_SETUP([ovn -- 3-term mixed expression simplification])
430 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
431 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
432 ])
433 AT_CLEANUP
434
435 AT_SETUP([ovn -- simplification special cases])
436 simplify() {
437 echo "$1" | ovstest test-ovn simplify-expr
438 }
439 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
440 ])
441 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
442 ])
443 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
444 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
445 ])
446 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
447 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
448 ])
449 AT_CHECK([simplify 'tcp.dst > 0'], [0],
450 [[(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)
451 ]])
452 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
453 [[(!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)
454 ]])
455 AT_CLEANUP
456
457 AT_SETUP([ovn -- is_chassis_resident simplification])
458 simplify() {
459 echo "$1" | ovstest test-ovn simplify-expr
460 }
461 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
462 ])
463 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
464 ])
465 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
466 ])
467 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
468 ])
469 AT_CLEANUP
470
471 AT_SETUP([ovn -- 4-term numeric expression normalization])
472 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
473 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
474 ])
475 AT_CLEANUP
476
477 AT_SETUP([ovn -- 4-term string expression normalization])
478 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
479 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
480 ])
481 AT_CLEANUP
482
483 AT_SETUP([ovn -- 4-term mixed expression normalization])
484 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
485 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
486 ])
487 AT_CLEANUP
488
489 AT_SETUP([ovn -- 5-term numeric expression normalization])
490 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
491 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
492 ])
493 AT_CLEANUP
494
495 AT_SETUP([ovn -- 5-term string expression normalization])
496 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
497 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
498 ])
499 AT_CLEANUP
500
501 AT_SETUP([ovn -- 5-term mixed expression normalization])
502 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
503 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
504 ])
505 AT_CLEANUP
506
507 AT_SETUP([ovn -- 4-term numeric expressions to flows])
508 AT_KEYWORDS([expression])
509 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
510 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
511 ])
512 AT_CLEANUP
513
514 AT_SETUP([ovn -- 4-term string expressions to flows])
515 AT_KEYWORDS([expression])
516 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
517 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
518 ])
519 AT_CLEANUP
520
521 AT_SETUP([ovn -- 4-term mixed expressions to flows])
522 AT_KEYWORDS([expression])
523 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
524 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
525 ])
526 AT_CLEANUP
527
528 AT_SETUP([ovn -- 3-term numeric expressions to flows])
529 AT_KEYWORDS([expression])
530 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
531 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
532 ])
533 AT_CLEANUP
534
535 AT_SETUP([ovn -- converting expressions to flows -- string fields])
536 AT_KEYWORDS([expression])
537 expr_to_flow () {
538 echo "$1" | ovstest test-ovn expr-to-flows | sort
539 }
540 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
541 ])
542 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
543 ])
544 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
545 ])
546 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
547 ip,reg14=0x5
548 ipv6,reg14=0x5
549 ])
550 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
551 ip,reg14=0x6
552 ipv6,reg14=0x6
553 ])
554 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
555 ])
556 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
557 [reg14=0x5
558 reg14=0x6
559 reg14=0xfffe
560 ])
561 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
562 ip,reg14=0x5
563 ip,reg14=0x6
564 ipv6,reg14=0x5
565 ipv6,reg14=0x6
566 ])
567 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
568 (no flows)
569 ])
570 AT_CLEANUP
571
572 AT_SETUP([ovn -- converting expressions to flows -- address sets])
573 AT_KEYWORDS([expression])
574 expr_to_flow () {
575 echo "$1" | ovstest test-ovn expr-to-flows | sort
576 }
577 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
578 ip,nw_src=10.0.0.1
579 ip,nw_src=10.0.0.2
580 ip,nw_src=10.0.0.3
581 ])
582 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
583 ip,nw_src=10.0.0.1
584 ip,nw_src=10.0.0.2
585 ip,nw_src=10.0.0.3
586 ])
587 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
588 ip,nw_src=1.2.3.4
589 ip,nw_src=10.0.0.1
590 ip,nw_src=10.0.0.2
591 ip,nw_src=10.0.0.3
592 ])
593 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
594 ip,nw_src=1.2.0.0/20
595 ip,nw_src=10.0.0.1
596 ip,nw_src=10.0.0.2
597 ip,nw_src=10.0.0.3
598 ip,nw_src=5.5.5.0/24
599 ])
600 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
601 ipv6,ipv6_src=::1
602 ipv6,ipv6_src=::2
603 ipv6,ipv6_src=::3
604 ])
605 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
606 ipv6,ipv6_src=::1
607 ipv6,ipv6_src=::2
608 ipv6,ipv6_src=::3
609 ipv6,ipv6_src=::4
610 ])
611 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
612 dl_src=00:00:00:00:00:01
613 dl_src=00:00:00:00:00:02
614 dl_src=00:00:00:00:00:03
615 ])
616 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
617 dl_src=00:00:00:00:00:01
618 dl_src=00:00:00:00:00:02
619 dl_src=00:00:00:00:00:03
620 ])
621 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
622 dl_src=00:00:00:00:00:01
623 dl_src=00:00:00:00:00:02
624 dl_src=00:00:00:00:00:03
625 dl_src=ba:be:be:ef:de:ad
626 ])
627 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
628 (no flows)
629 ])
630 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
631 ip,nw_src=1.2.3.4
632 ])
633 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
634 ip,nw_src=1.2.3.4
635 ])
636 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
637
638 ])
639 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
640 ip,nw_src=0.0.0.0/1.0.0.0
641 ip,nw_src=128.0.0.0/1
642 ip,nw_src=16.0.0.0/16.0.0.0
643 ip,nw_src=2.0.0.0/2.0.0.0
644 ip,nw_src=32.0.0.0/32.0.0.0
645 ip,nw_src=4.0.0.0/4.0.0.0
646 ip,nw_src=64.0.0.0/64.0.0.0
647 ip,nw_src=8.0.0.0/8.0.0.0
648 ])
649 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
650 ip,nw_src=0.0.0.0/1.0.0.0
651 ip,nw_src=128.0.0.0/1
652 ip,nw_src=16.0.0.0/16.0.0.0
653 ip,nw_src=2.0.0.0/2.0.0.0
654 ip,nw_src=32.0.0.0/32.0.0.0
655 ip,nw_src=4.0.0.0/4.0.0.0
656 ip,nw_src=64.0.0.0/64.0.0.0
657 ip,nw_src=8.0.0.0/8.0.0.0
658 ])
659 AT_CLEANUP
660
661 AT_SETUP([ovn -- converting expressions to flows -- port groups])
662 AT_KEYWORDS([expression])
663 expr_to_flow () {
664 echo "$1" | ovstest test-ovn expr-to-flows | sort
665 }
666 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
667 reg15=0x11
668 reg15=0x12
669 reg15=0x13
670 ])
671 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
672 (no flows)
673 ])
674 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
675 reg15=0x11
676 ])
677 AT_CLEANUP
678
679 AT_SETUP([ovn -- action parsing])
680 dnl Unindented text is input (a set of OVN logical actions).
681 dnl Indented text is expected output.
682 AT_DATA([test-cases.txt],
683 [[# drop
684 drop;
685 encodes as drop
686 drop; next;
687 Syntax error at `next' expecting end of input.
688 next; drop;
689 Syntax error at `drop' expecting action.
690
691 # output
692 output;
693 encodes as resubmit(,64)
694
695 # next
696 next;
697 encodes as resubmit(,19)
698 next(11);
699 formats as next;
700 encodes as resubmit(,19)
701 next(0);
702 encodes as resubmit(,8)
703 next(23);
704 encodes as resubmit(,31)
705
706 next();
707 Syntax error at `)' expecting "pipeline" or "table".
708 next(10;
709 Syntax error at `;' expecting `)'.
710 next(24);
711 "next" action cannot advance beyond table 23.
712
713 next(table=11);
714 formats as next;
715 encodes as resubmit(,19)
716 next(pipeline=ingress);
717 formats as next;
718 encodes as resubmit(,19)
719 next(table=11, pipeline=ingress);
720 formats as next;
721 encodes as resubmit(,19)
722 next(pipeline=ingress, table=11);
723 formats as next;
724 encodes as resubmit(,19)
725
726 next(pipeline=egress);
727 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
728
729 next(table=10);
730 formats as next(10);
731 encodes as resubmit(,18)
732
733 # Loading a constant value.
734 tcp.dst=80;
735 formats as tcp.dst = 80;
736 encodes as set_field:80->tcp_dst
737 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
738 eth.dst[40] = 1;
739 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
740 vlan.pcp = 2;
741 encodes as set_field:0x4000/0xe000->vlan_tci
742 has prereqs vlan.tci[12]
743 vlan.tci[13..15] = 2;
744 encodes as set_field:0x4000/0xe000->vlan_tci
745 inport = "";
746 encodes as set_field:0->reg14
747 ip.ttl=4;
748 formats as ip.ttl = 4;
749 encodes as set_field:4->nw_ttl
750 has prereqs eth.type == 0x800 || eth.type == 0x86dd
751 outport="eth0"; next; outport="LOCAL"; next;
752 formats as outport = "eth0"; next; outport = "LOCAL"; next;
753 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
754
755 inport[1] = 1;
756 Cannot select subfield of string field inport.
757 ip.proto[1] = 1;
758 Cannot select subfield of nominal field ip.proto.
759 eth.dst[40] == 1;
760 Syntax error at `==' expecting `=' or `<->'.
761 ip = 1;
762 Predicate symbol ip used where lvalue required.
763 ip.proto = 6;
764 Field ip.proto is not modifiable.
765 inport = {"a", "b"};
766 Syntax error at `{' expecting constant.
767 inport = {};
768 Syntax error at `{' expecting constant.
769 bad_prereq = 123;
770 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
771 self_recurse = 123;
772 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'.
773 vlan.present = 0;
774 Predicate symbol vlan.present used where lvalue required.
775
776 # Moving one field into another.
777 reg0=reg1;
778 formats as reg0 = reg1;
779 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
780 vlan.pcp = reg0[0..2];
781 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
782 has prereqs vlan.tci[12]
783 reg0[10] = vlan.pcp[1];
784 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
785 has prereqs vlan.tci[12]
786 outport = inport;
787 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
788
789 reg0[0] = vlan.present;
790 Predicate symbol vlan.present used where lvalue required.
791 reg0 = reg1[0..10];
792 Can't assign 11-bit value to 32-bit destination.
793 inport = reg0;
794 Can't assign integer field (reg0) to string field (inport).
795 inport = big_string;
796 String fields inport and big_string are incompatible for assignment.
797 ip.proto = reg0[0..7];
798 Field ip.proto is not modifiable.
799
800 # Exchanging fields.
801 reg0 <-> reg1;
802 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]
803 vlan.pcp <-> reg0[0..2];
804 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]
805 has prereqs vlan.tci[12]
806 reg0[10] <-> vlan.pcp[1];
807 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
808 has prereqs vlan.tci[12]
809 outport <-> inport;
810 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
811
812 reg0[0] <-> vlan.present;
813 Predicate symbol vlan.present used where lvalue required.
814 reg0 <-> reg1[0..10];
815 Can't exchange 32-bit field with 11-bit field.
816 inport <-> reg0;
817 Can't exchange string field (inport) with integer field (reg0).
818 inport <-> big_string;
819 String fields inport and big_string are incompatible for exchange.
820 ip.proto <-> reg0[0..7];
821 Field ip.proto is not modifiable.
822 reg0[0..7] <-> ip.proto;
823 Field ip.proto is not modifiable.
824
825 # TTL decrement.
826 ip.ttl--;
827 encodes as dec_ttl
828 has prereqs ip
829 ip.ttl
830 Syntax error at end of input expecting `--'.
831
832 # load balancing.
833 ct_lb;
834 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
835 has prereqs ip
836 ct_lb();
837 formats as ct_lb;
838 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
839 has prereqs ip
840 ct_lb(192.168.1.2:80, 192.168.1.3:80);
841 encodes as group:1
842 has prereqs ip
843 ct_lb(192.168.1.2, 192.168.1.3, );
844 formats as ct_lb(192.168.1.2, 192.168.1.3);
845 encodes as group:2
846 has prereqs ip
847 ct_lb(fd0f::2, fd0f::3, );
848 formats as ct_lb(fd0f::2, fd0f::3);
849 encodes as group:3
850 has prereqs ip
851
852 ct_lb(192.168.1.2:);
853 Syntax error at `)' expecting port number.
854 ct_lb(192.168.1.2:123456);
855 Syntax error at `123456' expecting port number.
856 ct_lb(foo);
857 Syntax error at `foo' expecting IP address.
858 ct_lb([192.168.1.2]);
859 Syntax error at `192.168.1.2' expecting IPv6 address.
860
861 # ct_next
862 ct_next;
863 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
864 has prereqs ip
865
866 # ct_commit
867 ct_commit;
868 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
869 has prereqs ip
870 ct_commit();
871 formats as ct_commit;
872 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
873 has prereqs ip
874 ct_commit(ct_mark=1);
875 formats as ct_commit(ct_mark=0x1);
876 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
877 has prereqs ip
878 ct_commit(ct_mark=1/1);
879 formats as ct_commit(ct_mark=0x1/0x1);
880 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
881 has prereqs ip
882 ct_commit(ct_label=1);
883 formats as ct_commit(ct_label=0x1);
884 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
885 has prereqs ip
886 ct_commit(ct_label=1/1);
887 formats as ct_commit(ct_label=0x1/0x1);
888 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
889 has prereqs ip
890 ct_commit(ct_mark=1, ct_label=2);
891 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
892 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
893 has prereqs ip
894
895 ct_commit(ct_label=0x01020304050607080910111213141516);
896 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
897 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
898 has prereqs ip
899 ct_commit(ct_label=0x181716151413121110090807060504030201);
900 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
901 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
902 has prereqs ip
903 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
904 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
905 has prereqs ip
906 ct_commit(ct_label=18446744073709551615);
907 formats as ct_commit(ct_label=0xffffffffffffffff);
908 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
909 has prereqs ip
910 ct_commit(ct_label=18446744073709551616);
911 Decimal constants must be less than 2**64.
912
913 # ct_dnat
914 ct_dnat;
915 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
916 has prereqs ip
917 ct_dnat(192.168.1.2);
918 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
919 has prereqs ip
920
921 ct_dnat(192.168.1.2, 192.168.1.3);
922 Syntax error at `,' expecting `)'.
923 ct_dnat(foo);
924 Syntax error at `foo' expecting IPv4 address.
925 ct_dnat(foo, bar);
926 Syntax error at `foo' expecting IPv4 address.
927 ct_dnat();
928 Syntax error at `)' expecting IPv4 address.
929
930 # ct_snat
931 ct_snat;
932 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
933 has prereqs ip
934 ct_snat(192.168.1.2);
935 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
936 has prereqs ip
937
938 ct_snat(192.168.1.2, 192.168.1.3);
939 Syntax error at `,' expecting `)'.
940 ct_snat(foo);
941 Syntax error at `foo' expecting IPv4 address.
942 ct_snat(foo, bar);
943 Syntax error at `foo' expecting IPv4 address.
944 ct_snat();
945 Syntax error at `)' expecting IPv4 address.
946
947 # ct_clear
948 ct_clear;
949 encodes as ct_clear
950
951 # clone
952 clone { ip4.dst = 255.255.255.255; output; }; next;
953 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
954 has prereqs eth.type == 0x800
955
956 # arp
957 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
958 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)
959 has prereqs ip4
960 arp { };
961 formats as arp { drop; };
962 encodes as controller(userdata=00.00.00.00.00.00.00.00)
963 has prereqs ip4
964
965 # get_arp
966 get_arp(outport, ip4.dst);
967 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[]
968 has prereqs eth.type == 0x800
969 get_arp(inport, reg0);
970 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[]
971
972 get_arp;
973 Syntax error at `;' expecting `('.
974 get_arp();
975 Syntax error at `)' expecting field name.
976 get_arp(inport);
977 Syntax error at `)' expecting `,'.
978 get_arp(inport ip4.dst);
979 Syntax error at `ip4.dst' expecting `,'.
980 get_arp(inport, ip4.dst;
981 Syntax error at `;' expecting `)'.
982 get_arp(inport, eth.dst);
983 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
984 get_arp(inport, outport);
985 Cannot use string field outport where numeric field is required.
986 get_arp(reg0, ip4.dst);
987 Cannot use numeric field reg0 where string field is required.
988
989 # put_arp
990 put_arp(inport, arp.spa, arp.sha);
991 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[]
992 has prereqs eth.type == 0x806 && eth.type == 0x806
993
994 # put_dhcp_opts
995 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
996 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)
997 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");
998 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");
999 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,pause)
1000 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);
1001 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);
1002 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,pause)
1003
1004 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1005 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1006 reg1[0] = put_dhcp_opts();
1007 put_dhcp_opts requires offerip to be specified.
1008 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1009 Syntax error at `x' expecting DHCPv4 option name.
1010 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1011 put_dhcp_opts requires offerip to be specified.
1012 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1013 Syntax error at `"hi"'.
1014 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1015 Syntax error at `xyzzy' expecting DHCPv4 option name.
1016 reg1[0] = put_dhcp_opts(offerip="xyzzy");
1017 DHCPv4 option offerip requires numeric value.
1018 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1019 DHCPv4 option domain requires string value.
1020
1021 # nd_ns
1022 nd_ns { nd.target = xxreg0; output; };
1023 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)
1024 has prereqs ip6
1025
1026 nd_ns { };
1027 formats as nd_ns { drop; };
1028 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1029 has prereqs ip6
1030
1031 # nd_na
1032 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; };
1033 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1034 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)
1035 has prereqs nd_ns
1036
1037 # get_nd
1038 get_nd(outport, ip6.dst);
1039 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[]
1040 has prereqs eth.type == 0x86dd
1041 get_nd(inport, xxreg0);
1042 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[]
1043 get_nd;
1044 Syntax error at `;' expecting `('.
1045 get_nd();
1046 Syntax error at `)' expecting field name.
1047 get_nd(inport);
1048 Syntax error at `)' expecting `,'.
1049 get_nd(inport ip6.dst);
1050 Syntax error at `ip6.dst' expecting `,'.
1051 get_nd(inport, ip6.dst;
1052 Syntax error at `;' expecting `)'.
1053 get_nd(inport, eth.dst);
1054 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1055 get_nd(inport, outport);
1056 Cannot use string field outport where numeric field is required.
1057 get_nd(xxreg0, ip6.dst);
1058 Cannot use numeric field xxreg0 where string field is required.
1059
1060 # put_nd
1061 put_nd(inport, nd.target, nd.sll);
1062 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[]
1063 has prereqs ((icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd)) || (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)
1064
1065 # put_dhcpv6_opts
1066 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1067 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)
1068 reg1[0] = put_dhcpv6_opts();
1069 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1070 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1071 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1072 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)
1073 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1074 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1075 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)
1076 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1077 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)
1078 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1079 Syntax error at `x' expecting DHCPv6 option name.
1080 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1081 Syntax error at `"hi"'.
1082 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1083 Syntax error at `xyzzy' expecting DHCPv6 option name.
1084 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1085 DHCPv6 option ia_addr requires numeric value.
1086 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1087 DHCPv6 option domain_search requires string value.
1088
1089 # set_queue
1090 set_queue(0);
1091 encodes as set_queue:0
1092 set_queue(61440);
1093 encodes as set_queue:61440
1094 set_queue(65535);
1095 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1096
1097 # dns_lookup
1098 reg1[0] = dns_lookup();
1099 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1100 has prereqs udp
1101 reg1[0] = dns_lookup("foo");
1102 dns_lookup doesn't take any parameters
1103
1104 # set_meter
1105 set_meter(0);
1106 Rate 0 for set_meter is not in valid.
1107 set_meter(1);
1108 encodes as meter:1
1109 set_meter(100, 1000);
1110 encodes as meter:2
1111 set_meter(100, 1000, );
1112 Syntax error at `,' expecting `)'.
1113 set_meter(4294967295, 4294967295);
1114 encodes as meter:3
1115
1116 # put_nd_ra_opts
1117 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1118 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)
1119 has prereqs ip6
1120 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1121 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)
1122 has prereqs ip6
1123 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1124 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)
1125 has prereqs ip6
1126 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1127 slla option not present
1128 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);
1129 prefix option can't be set when address mode is dhcpv6_stateful.
1130 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);
1131 prefix option can't be set when address mode is dhcpv6_stateful.
1132 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1133 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1134 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1135 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1136 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1137 Syntax error at `dhcpv6_stateless' expecting constant.
1138 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1139 Invalid value for "prefix" option
1140 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1141 Invalid value for "addr_mode" option
1142 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1143 IPv6 ND RA option mtu requires numeric value.
1144 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1145 Invalid value for "mtu" option
1146
1147 # icmp4
1148 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1149 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)
1150 has prereqs ip4
1151
1152 icmp4 { };
1153 formats as icmp4 { drop; };
1154 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1155 has prereqs ip4
1156
1157 # icmp6
1158 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1159 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)
1160 has prereqs ip6
1161
1162 icmp6 { };
1163 formats as icmp6 { drop; };
1164 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1165 has prereqs ip6
1166
1167 # tcp_reset
1168 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1169 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)
1170 has prereqs tcp
1171
1172 tcp_reset { };
1173 formats as tcp_reset { drop; };
1174 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1175 has prereqs tcp
1176
1177 # Contradictionary prerequisites (allowed but not useful):
1178 ip4.src = ip6.src[0..31];
1179 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1180 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1181 ip4.src <-> ip6.src[0..31];
1182 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[]
1183 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1184
1185 # Miscellaneous negative tests.
1186 ;
1187 Syntax error at `;'.
1188 xyzzy;
1189 Syntax error at `xyzzy' expecting action.
1190 next; 123;
1191 Syntax error at `123'.
1192 next; xyzzy;
1193 Syntax error at `xyzzy' expecting action.
1194 next
1195 Syntax error at end of input expecting `;'.
1196 ]])
1197 sed '/^[[ ]]/d' test-cases.txt > input.txt
1198 cp test-cases.txt expout
1199 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1200 AT_CLEANUP
1201
1202 AT_BANNER([OVN end-to-end tests])
1203
1204 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1205 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1206 AT_KEYWORDS([ovnarp])
1207 AT_SKIP_IF([test $HAVE_PYTHON = no])
1208 ovn_start
1209
1210 # Create hypervisors hv[123].
1211 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1212 # Add all of the vifs to a single logical switch lsw0.
1213 # Turn on port security on all the vifs except vif[123]1.
1214 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1215 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1216 ovn-nbctl ls-add lsw0
1217 net_add n1
1218 for i in 1 2 3; do
1219 sim_add hv$i
1220 as hv$i
1221 ovs-vsctl add-br br-phys
1222 ovn_attach n1 br-phys 192.168.0.$i
1223
1224 for j in 1 2 3; do
1225 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
1226 ovn-nbctl lsp-add lsw0 lp$i$j
1227 if test $j = 1; then
1228 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1229 else
1230 if test $j = 3; then
1231 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1232 else
1233 ip_addrs="192.168.0.$i$j"
1234 fi
1235 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1236 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1237 fi
1238 done
1239 done
1240 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1241 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1242 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1243 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\"
1244 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1245
1246 get_lsp_uuid () {
1247 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1248 }
1249
1250 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1251 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1252
1253 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1254 # packets for ARP resolution (native tunneling doesn't queue packets
1255 # for ARP resolution).
1256 OVN_POPULATE_ARP
1257
1258 # Allow some time for ovn-northd and ovn-controller to catch up.
1259 # XXX This should be more systematic.
1260 sleep 1
1261
1262 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1263 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1264 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1265 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1266
1267 # Given the name of a logical port, prints the name of the hypervisor
1268 # on which it is located.
1269 vif_to_hv() {
1270 echo hv${1%?}
1271 }
1272
1273 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1274 #
1275 # This shell function causes a packet to be received on INPORT. The packet's
1276 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1277 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1278 # more) list the VIFs on which the packet should be received. INPORT and the
1279 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1280 for i in 1 2 3; do
1281 for j in 1 2 3; do
1282 : > $i$j.expected
1283 done
1284 done
1285 test_packet() {
1286 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1287 hv=`vif_to_hv $inport`
1288 vif=vif$inport
1289 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1290 for outport; do
1291 echo $packet >> $outport.expected
1292 done
1293 }
1294
1295 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1296 #
1297 # Causes a packet to be received on INPORT. The packet is an ARP
1298 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1299 # it should be the hardware address of the target to expect to receive in an
1300 # ARP reply; otherwise no reply is expected.
1301 #
1302 # INPORT is an logical switch port number, e.g. 11 for vif11.
1303 # SHA and REPLY_HA are each 12 hex digits.
1304 # SPA and TPA are each 8 hex digits.
1305 test_arp() {
1306 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1307 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1308 hv=`vif_to_hv $inport`
1309 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1310
1311 if test X$reply_ha = X; then
1312 # Expect to receive the broadcast ARP on the other logical switch ports
1313 # if no reply is expected.
1314 local i j
1315 for i in 1 2 3; do
1316 for j in 1 2 3; do
1317 if test $i$j != $inport; then
1318 echo $request >> $i$j.expected
1319 fi
1320 done
1321 done
1322 else
1323 # Expect to receive the reply, if any.
1324 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1325 echo $reply >> $inport.expected
1326 fi
1327 }
1328
1329 ip_to_hex() {
1330 printf "%02x%02x%02x%02x" "$@"
1331 }
1332
1333 # Send packets between all pairs of source and destination ports:
1334 #
1335 # 1. Unicast packets are delivered to exactly one logical switch port
1336 # (except that packets destined to their input ports are dropped).
1337 #
1338 # 2. Broadcast and multicast are delivered to all logical switch ports
1339 # except the input port.
1340 #
1341 # 3. When port security is turned on, the switch drops packets from the wrong
1342 # MAC address.
1343 #
1344 # 4. The switch drops all packets with a VLAN tag.
1345 #
1346 # 5. The switch drops all packets with a multicast source address. (This only
1347 # affects behavior when port security is turned off, since otherwise port
1348 # security would drop the packet anyway.)
1349 #
1350 # 6. The switch delivers packets with an unknown destination to logical
1351 # switch ports with "unknown" among their MAC addresses (and port
1352 # security disabled).
1353 #
1354 # 7. The switch drops unicast packets that violate an ACL.
1355 #
1356 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1357 #
1358 # 9. OVN generates responses to ARP requests for known IPs, except for
1359 # requests from a port for the port's own IP.
1360 #
1361 # 10. No response to ARP requests for unknown IPs.
1362
1363 for is in 1 2 3; do
1364 for js in 1 2 3; do
1365 s=$is$js
1366 bcast=
1367 unknown=
1368 bacl2=
1369 bacl3=
1370 for id in 1 2 3; do
1371 for jd in 1 2 3; do
1372 d=$id$jd
1373
1374 if test $d != $s; then unicast=$d; else unicast=; fi
1375 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1376
1377 if test $d != $s && test $js = 1; then
1378 impersonate=$d
1379 else
1380 impersonate=
1381 fi
1382 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1383
1384 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1385 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1386 if test $d = $s || (test $js = 1 && test $d = 33); then
1387 # Source of 11, 21, or 31 and dest of 33 should be dropped
1388 # due to the 4th ACL that uses address_set(set1).
1389 acl4=
1390 else
1391 acl4=$d
1392 fi
1393 if test $d = $s || test $d = 22 || test $d = 33; then
1394 # dest of 22 and 33 should be dropped
1395 # due to the 5th ACL that uses port_group(pg1).
1396 acl5=
1397 else
1398 acl5=$d
1399 fi
1400 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1401 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1402 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1403 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1404 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1405
1406 test_packet $s f000000000$d f00000000055 810000091234 #4
1407 test_packet $s f000000000$d 0100000000$s $s$d #5
1408
1409 if test $d != $s && test $jd = 1; then
1410 unknown="$unknown $d"
1411 fi
1412 bcast="$bcast $unicast"
1413 bacl2="$bacl2 $acl2"
1414 bacl3="$bacl3 $acl3"
1415
1416 sip=`ip_to_hex 192 168 0 $is$js`
1417 tip=`ip_to_hex 192 168 0 $id$jd`
1418 tip_unknown=`ip_to_hex 11 11 11 11`
1419 if test $d != $s; then
1420 reply_ha=f000000000$d
1421 else
1422 reply_ha=
1423 fi
1424 test_arp $s f000000000$s $sip $tip $reply_ha #9
1425 test_arp $s f000000000$s $sip $tip_unknown #10
1426
1427 if test $jd = 3; then
1428 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1429 tip=`ip_to_hex 192 169 0 $id$jd`
1430 test_arp $s f000000000$s $sip $tip $reply_ha #9
1431 fi
1432 done
1433 done
1434
1435 # Broadcast and multicast.
1436 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1437 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1438 if test $js = 1; then
1439 bcast_impersonate=$bcast
1440 else
1441 bcast_impersonate=
1442 fi
1443 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1444
1445 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1446
1447 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1448 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1449 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1450 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1451 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1452 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1453 done
1454 done
1455
1456 # set address for lp13 with invalid characters.
1457 # lp13 should be configured with only 192.168.0.13.
1458 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1459
1460 # Allow some time for ovn-northd and ovn-controller to catch up.
1461 # XXX This should be more systematic.
1462 sleep 1
1463
1464 sip=`ip_to_hex 192 168 0 11`
1465 tip=`ip_to_hex 192 168 0 13`
1466 test_arp 11 f00000000011 $sip $tip f00000000013
1467
1468 tip=`ip_to_hex 192 169 0 13`
1469 #arp request for 192.169.0.13 should be flooded
1470 test_arp 11 f00000000011 $sip $tip
1471
1472 # dump information and flows with counters
1473 ovn-sbctl dump-flows -- list multicast_group
1474
1475 echo "------ hv1 dump ------"
1476 as hv1 ovs-vsctl show
1477 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1478
1479 echo "------ hv2 dump ------"
1480 as hv2 ovs-vsctl show
1481 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1482
1483 echo "------ hv3 dump ------"
1484 as hv3 ovs-vsctl show
1485 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1486
1487 # Now check the packets actually received against the ones expected.
1488 for i in 1 2 3; do
1489 for j in 1 2 3; do
1490 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1491 done
1492 done
1493
1494 OVN_CLEANUP([hv1],[hv2],[hv3])
1495
1496 AT_CLEANUP
1497
1498 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1499 AT_SKIP_IF([test $HAVE_PYTHON = no])
1500 ovn_start
1501
1502 # Create a logical switch and some logical ports.
1503 # Turn on port security on all lports except ls1.
1504 # Make ls1 a destination for unknown MACs.
1505 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1506 ovn-nbctl ls-add lsw0
1507 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1508 for i in 1 2 3; do
1509 ovn-nbctl lsp-add lsw0 lp$i
1510 done
1511 ovn-nbctl --wait=sb sync
1512 for i in 1 2 3; do
1513 ovn-sbctl lsp-bind lp$i hv0
1514 if test $i = 1; then
1515 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1516 else
1517 if test $i = 3; then
1518 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1519 else
1520 ip_addrs="192.168.0.$i"
1521 fi
1522 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1523 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1524 fi
1525 done
1526 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1527 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1528 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1529 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1530 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1531
1532 ovn-nbctl --wait=sb sync
1533 on_exit 'kill `cat ovn-trace.pid`'
1534 ovn-trace --detach --pidfile --no-chdir
1535
1536 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1537 #
1538 # This shell function causes a packet to be received on INPORT. The packet's
1539 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1540 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1541 # more) list the VIFs on which the packet should be received. INPORT and the
1542 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1543 test_packet() {
1544 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1545 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1546 while :; do
1547 case $1 in # (
1548 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1549 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1550 *) break ;;
1551 esac
1552 done
1553 for outport; do
1554 echo "output(\"lp$outport\");"
1555 done > expout
1556
1557 AT_CAPTURE_FILE([trace])
1558 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1559 }
1560
1561 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1562 #
1563 # Causes a packet to be received on INPORT. The packet is an ARP
1564 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1565 # it should be the hardware address of the target to expect to receive in an
1566 # ARP reply; otherwise no reply is expected.
1567 #
1568 # INPORT is an logical switch port number, e.g. 11 for vif11.
1569 # SHA and REPLY_HA are each 12 hex digits.
1570 # SPA and TPA are each 8 hex digits.
1571 test_arp() {
1572 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1573
1574 local request="inport == \"lp$inport\"
1575 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1576 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1577 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1578
1579 if test -z "$reply_ha"; then
1580 reply=
1581 local i
1582 for i in 1 2 3; do
1583 if test $i != $inport; then
1584 reply="${reply}output(\"lp$i\");
1585 "
1586 fi
1587 done
1588 else
1589 reply="\
1590 eth.dst = $sha;
1591 eth.src = $reply_ha;
1592 arp.op = 2;
1593 arp.tha = $sha;
1594 arp.sha = $reply_ha;
1595 arp.tpa = $spa;
1596 arp.spa = $tpa;
1597 output(\"lp$inport\");
1598 "
1599 fi
1600
1601 AT_CAPTURE_FILE([trace])
1602 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1603 }
1604
1605 # Send packets between all pairs of source and destination ports:
1606 #
1607 # 1. Unicast packets are delivered to exactly one logical switch port
1608 # (except that packets destined to their input ports are dropped).
1609 #
1610 # 2. Broadcast and multicast are delivered to all logical switch ports
1611 # except the input port.
1612 #
1613 # 3. When port security is turned on, the switch drops packets from the wrong
1614 # MAC address.
1615 #
1616 # 4. The switch drops all packets with a VLAN tag.
1617 #
1618 # 5. The switch drops all packets with a multicast source address. (This only
1619 # affects behavior when port security is turned off, since otherwise port
1620 # security would drop the packet anyway.)
1621 #
1622 # 6. The switch delivers packets with an unknown destination to logical
1623 # switch ports with "unknown" among their MAC addresses (and port
1624 # security disabled).
1625 #
1626 # 7. The switch drops unicast packets that violate an ACL.
1627 #
1628 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1629 #
1630 # 9. OVN generates responses to ARP requests for known IPs, except for
1631 # requests from a port for the port's own IP.
1632 #
1633 # 10. No response to ARP requests for unknown IPs.
1634
1635 for s in 1 2 3; do
1636 bcast=
1637 unknown=
1638 bacl2=
1639 bacl3=
1640 for d in 1 2 3; do
1641 echo
1642 echo "lp$s -> lp$d"
1643 if test $d != $s; then unicast=$d; else unicast=; fi
1644 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1645
1646 if test $d != $s && test $s = 1; then
1647 impersonate=$d
1648 else
1649 impersonate=
1650 fi
1651 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1652
1653 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1654 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1655 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1656 # Source of 1 or 2 and dest of 3 should be dropped
1657 # due to the 4th ACL that uses address_set(set1).
1658 acl4=
1659 else
1660 acl4=$d
1661 fi
1662
1663 #7, acl1 to acl4:
1664 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1665 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1666 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1667 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1668
1669 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1670 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1671
1672 if test $d != $s && test $d = 1; then
1673 unknown="$unknown $d"
1674 fi
1675 bcast="$bcast $unicast"
1676 bacl2="$bacl2 $acl2"
1677 bacl3="$bacl3 $acl3"
1678
1679 sip=192.168.0.$s
1680 tip=192.168.0.$d
1681 tip_unknown=11.11.11.11
1682 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1683 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1684 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1685
1686 if test $d = 3; then
1687 # lp3 has an additional ip 192.169.0.[123]3.
1688 tip=192.169.0.$d
1689 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1690 fi
1691 done
1692
1693 # Broadcast and multicast.
1694 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1695 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1696 if test $s = 1; then
1697 bcast_impersonate=$bcast
1698 else
1699 bcast_impersonate=
1700 fi
1701 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1702
1703 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1704
1705 #8, acl1 to acl3:
1706 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1707 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1708 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1709
1710 #8, acl1 to acl3:
1711 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1712 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1713 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1714 done
1715
1716 AT_CLEANUP
1717
1718 # 2 hypervisors, 4 logical ports per HV
1719 # 2 locally attached networks (one flat, one vlan tagged over same device)
1720 # 2 ports per HV on each network
1721 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1722 AT_SKIP_IF([test $HAVE_PYTHON = no])
1723 ovn_start
1724
1725 # In this test cases we create 3 switches, all connected to same
1726 # physical network (through br-phys on each HV). Each switch has
1727 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1728 # of VIF port name indicates the hypervisor it is bound to, e.g.
1729 # lp23 means VIF 3 on hv2.
1730 #
1731 # Each switch's VLAN tag and their logical switch ports are:
1732 # - ls1:
1733 # - untagged
1734 # - ports: lp11, lp12, lp21, lp22
1735 #
1736 # - ls2:
1737 # - tagged with VLAN 101
1738 # - ports: lp13, lp14, lp23, lp24
1739 # - ls3:
1740 # - untagged
1741 # - ports: lp15, lp25
1742 #
1743 # Note: a localnet port is created for each switch to connect to
1744 # physical network.
1745
1746 for i in 1 2 3; do
1747 ls_name=ls$i
1748 ovn-nbctl ls-add $ls_name
1749 ln_port_name=ln$i
1750 if test $i -eq 2; then
1751 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1752 else
1753 ovn-nbctl lsp-add $ls_name $ln_port_name
1754 fi
1755 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1756 ovn-nbctl lsp-set-type $ln_port_name localnet
1757 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1758 done
1759
1760 # lsp_to_ls LSP
1761 #
1762 # Prints the name of the logical switch that contains LSP.
1763 lsp_to_ls () {
1764 case $1 in dnl (
1765 lp?[[12]]) echo ls1 ;; dnl (
1766 lp?[[34]]) echo ls2 ;; dnl (
1767 lp?5) echo ls3 ;; dnl (
1768 *) AT_FAIL_IF([:]) ;;
1769 esac
1770 }
1771
1772 net_add n1
1773 for i in 1 2; do
1774 sim_add hv$i
1775 as hv$i
1776 ovs-vsctl add-br br-phys
1777 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1778 ovn_attach n1 br-phys 192.168.0.$i
1779
1780 for j in 1 2 3 4 5; do
1781 ovs-vsctl add-port br-int vif$i$j -- \
1782 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1783 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1784 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1785 ofport-request=$i$j
1786
1787 lsp_name=lp$i$j
1788 ls_name=$(lsp_to_ls $lsp_name)
1789
1790 ovn-nbctl lsp-add $ls_name $lsp_name
1791 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1792 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1793
1794 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1795 done
1796 done
1797 ovn-nbctl --wait=sb sync
1798 ovn-sbctl dump-flows
1799
1800 OVN_POPULATE_ARP
1801
1802 # XXX This is now the 3rd copy of these functions in this file ...
1803
1804 # Given the name of a logical port, prints the name of the hypervisor
1805 # on which it is located.
1806 vif_to_hv() {
1807 echo hv${1%?}
1808 }
1809 #
1810 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1811 #
1812 # This shell function causes a packet to be received on INPORT. The packet's
1813 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1814 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1815 # logical switch port numbers, e.g. 11 for vif11.
1816 #
1817 # EOUT is the end-to-end output port, that is, where the packet will end up
1818 # after possibly bouncing through one or more localnet ports. LOUT is the
1819 # logical output port, which might be a localnet port, as seen by ovn-trace
1820 # (which doesn't know what localnet ports are connected to and therefore can't
1821 # figure out the end-to-end answer).
1822 for i in 1 2; do
1823 for j in 1 2 3 4 5; do
1824 : > $i$j.expected
1825 done
1826 done
1827 test_packet() {
1828 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1829 echo "$@"
1830
1831 # First try tracing the packet.
1832 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1833 if test $lout != drop; then
1834 echo "output(\"$lout\");"
1835 fi > expout
1836 AT_CAPTURE_FILE([trace])
1837 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1838
1839 # Then actually send a packet, for an end-to-end test.
1840 local packet=$(echo $dst$src | sed 's/://g')${eth}
1841 hv=`vif_to_hv $inport`
1842 vif=vif$inport
1843 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1844 if test $eout != drop; then
1845 echo $packet >> ${eout#lp}.expected
1846 fi
1847 }
1848
1849 # lp11 and lp21 are on the same network (phys, untagged)
1850 # and on different hypervisors
1851 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1852 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1853
1854 # lp11 and lp12 are on the same network (phys, untagged)
1855 # and on the same hypervisor
1856 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1857 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1858
1859 # lp13 and lp23 are on the same network (phys, VLAN 101)
1860 # and on different hypervisors
1861 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1862 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1863
1864 # lp13 and lp14 are on the same network (phys, VLAN 101)
1865 # and on the same hypervisor
1866 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1867 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1868
1869 # lp11 and lp15 are on the same network (phys, untagged),
1870 # same hypervisor, and on different switches
1871 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1872 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1873
1874 # lp11 and lp25 are on the same network (phys, untagged),
1875 # different hypervisors, and on different switches
1876 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1877 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1878
1879 # Ports that should not be able to communicate
1880 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1881 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1882 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1883 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1884 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1885 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1886 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1887 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1888
1889 # Dump a bunch of info helpful for debugging if there's a failure.
1890
1891 echo "------ OVN dump ------"
1892 ovn-nbctl show
1893 ovn-sbctl show
1894
1895 echo "------ hv1 dump ------"
1896 as hv1 ovs-vsctl show
1897 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1898
1899 echo "------ hv2 dump ------"
1900 as hv2 ovs-vsctl show
1901 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1902
1903 # Now check the packets actually received against the ones expected.
1904 for i in 1 2; do
1905 for j in 1 2 3 4 5; do
1906 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1907 done
1908 done
1909
1910 OVN_CLEANUP([hv1],[hv2])
1911
1912 AT_CLEANUP
1913
1914 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1915 AT_KEYWORDS([vtep])
1916 AT_SKIP_IF([test $HAVE_PYTHON = no])
1917 ovn_start
1918
1919 # Configure the Northbound database
1920 ovn-nbctl ls-add lsw0
1921
1922 ovn-nbctl lsp-add lsw0 lp1
1923 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1924
1925 ovn-nbctl lsp-add lsw0 lp2
1926 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1927
1928 ovn-nbctl lsp-add lsw0 lp-vtep
1929 ovn-nbctl lsp-set-type lp-vtep vtep
1930 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1931 ovn-nbctl lsp-set-addresses lp-vtep unknown
1932
1933 # lpr, lr and lrp1 are used for the ARP request handling test only.
1934 ovn-nbctl lsp-add lsw0 lpr
1935 ovn-nbctl lr-add lr
1936 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1937 ovn-nbctl set Logical_Switch_Port lpr type=router \
1938 options:router-port=lrp1 \
1939 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1940
1941
1942 net_add n1 # Network to connect hv1, hv2, and vtep
1943 net_add n2 # Network to connect vtep and hv3
1944
1945 # Create hypervisor hv1 connected to n1
1946 sim_add hv1
1947 as hv1
1948 ovs-vsctl add-br br-phys
1949 ovn_attach n1 br-phys 192.168.0.1
1950 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
1951
1952 # Create hypervisor hv2 connected to n1
1953 sim_add hv2
1954 as hv2
1955 ovs-vsctl add-br br-phys
1956 ovn_attach n1 br-phys 192.168.0.2
1957 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
1958
1959
1960 # Start the vtep emulator with a leg in both networks
1961 sim_add vtep
1962 as vtep
1963
1964 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1965 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1966
1967 ovs-vsctl add-br br-phys
1968 net_attach n1 br-phys
1969
1970 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1971 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1972 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1973 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1974
1975 ovs-vsctl add-br br-vtep
1976 net_attach n2 br-vtep
1977
1978 vtep-ctl add-ps br-vtep
1979 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1980 vtep-ctl add-ls lsw0
1981
1982 start_daemon ovs-vtep br-vtep
1983 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1984
1985 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1986
1987 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1988 grep -- source`"])
1989 # It takes more time for the update to be processed by ovs-vtep.
1990 sleep 1
1991
1992 # Add hv3 on the other side of the vtep
1993 sim_add hv3
1994 as hv3
1995 ovs-vsctl add-br br-phys
1996 net_attach n2 br-phys
1997
1998 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
1999
2000 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2001 # packets for ARP resolution (native tunneling doesn't queue packets
2002 # for ARP resolution).
2003 OVN_POPULATE_ARP
2004
2005 # Allow some time for ovn-northd and ovn-controller to catch up.
2006 # XXX This should be more systematic.
2007 sleep 1
2008
2009 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2010 #
2011 # This shell function causes a packet to be received on INPORT. The packet's
2012 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2013 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2014 # more) list the VIFs on which the packet should be received. INPORT and the
2015 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2016 for i in 1 2 3; do
2017 : > $i.expected
2018 done
2019 test_packet() {
2020 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2021 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2022 hv=hv$inport
2023 vif=vif$inport
2024 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2025 for outport; do
2026 echo $packet >> $outport.expected
2027 done
2028 }
2029
2030 # Send packets between all pairs of source and destination ports:
2031 #
2032 # 1. Unicast packets are delivered to exactly one logical switch port
2033 # (except that packets destined to their input ports are dropped).
2034 #
2035 # 2. Broadcast and multicast are delivered to all logical switch ports
2036 # except the input port.
2037 #
2038 # 3. The switch delivers packets with an unknown destination to logical
2039 # switch ports with "unknown" among their MAC addresses (and port
2040 # security disabled).
2041 for s in 1 2 3; do
2042 bcast=
2043 unknown=
2044 for d in 1 2 3; do
2045 if test $d != $s; then unicast=$d; else unicast=; fi
2046 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2047
2048 # The vtep (vif3) is the only one configured for "unknown"
2049 if test $d != $s && test $d = 3; then
2050 unknown="$unknown $d"
2051 fi
2052 bcast="$bcast $unicast"
2053 done
2054
2055 # Broadcast and multicast.
2056 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2057 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2058
2059 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2060 done
2061
2062 # ARP request should not be responded to by logical switch router
2063 # type arp responder on HV1 and HV2 and should reach directly to
2064 # vif1 and vif2
2065 ip_to_hex() {
2066 printf "%02x%02x%02x%02x" "$@"
2067 }
2068 sha=f00000000003
2069 spa=`ip_to_hex 192 168 1 2`
2070 tpa=`ip_to_hex 192 168 1 1`
2071 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2072 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2073 echo $request >> 1.expected
2074 echo $request >> 2.expected
2075
2076 # dump information with counters
2077 echo "------ OVN dump ------"
2078 ovn-nbctl show
2079 ovn-sbctl show
2080
2081 echo "---------SB dump-----"
2082 ovn-sbctl list datapath_binding
2083 echo "---------------------"
2084 ovn-sbctl list port_binding
2085 echo "---------------------"
2086 ovn-sbctl dump-flows
2087
2088 echo "------ hv1 dump ------"
2089 as hv1 ovs-vsctl show
2090 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2091 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2092
2093 echo "------ hv2 dump ------"
2094 as hv2 ovs-vsctl show
2095 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2096 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2097
2098 echo "------ hv3 dump ------"
2099 as hv3 ovs-vsctl show
2100 # note: hv3 has no logical port bind, thus it should not have br-int
2101 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2102 [ovs-ofctl: br-int is not a bridge or a socket
2103 ])
2104
2105 # Now check the packets actually received against the ones expected.
2106 for i in 1 2 3; do
2107 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2108 done
2109
2110 # Gracefully terminate daemons
2111 OVN_CLEANUP([hv1],[hv2],[vtep])
2112 OVN_CLEANUP_VSWITCH([hv3])
2113
2114 AT_CLEANUP
2115
2116 # Similar test to "hardware GW"
2117 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2118 AT_SKIP_IF([test $HAVE_PYTHON = no])
2119 ovn_start
2120
2121 # Configure the Northbound database
2122 ovn-nbctl ls-add lsw0
2123
2124 ovn-nbctl lsp-add lsw0 lp1
2125 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2126
2127 ovn-nbctl lsp-add lsw0 lp2
2128 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2129
2130 ovn-nbctl lsp-add lsw0 lp-gw
2131 ovn-nbctl lsp-set-type lp-gw l2gateway
2132 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2133 ovn-nbctl lsp-set-addresses lp-gw unknown
2134
2135 net_add n1 # Network to connect hv1, hv2, and gw
2136 net_add n2 # Network to connect gw and hv3
2137
2138 # Create hypervisor hv1 connected to n1
2139 sim_add hv1
2140 as hv1
2141 ovs-vsctl add-br br-phys
2142 ovn_attach n1 br-phys 192.168.0.1
2143 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
2144
2145 # Create hypervisor hv2 connected to n1
2146 sim_add hv2
2147 as hv2
2148 ovs-vsctl add-br br-phys
2149 ovn_attach n1 br-phys 192.168.0.2
2150 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
2151
2152 # Create hypervisor hv_gw connected to n1 and n2
2153 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2154 sim_add hv_gw
2155 as hv_gw
2156 ovs-vsctl add-br br-phys
2157 ovn_attach n1 br-phys 192.168.0.3
2158 ovs-vsctl add-br br-phys2
2159 net_attach n2 br-phys2
2160 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2161
2162 # Add hv3 on the other side of the GW
2163 sim_add hv3
2164 as hv3
2165 ovs-vsctl add-br br-phys
2166 net_attach n2 br-phys
2167 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
2168
2169
2170 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2171 # packets for ARP resolution (native tunneling doesn't queue packets
2172 # for ARP resolution).
2173 OVN_POPULATE_ARP
2174
2175 # Allow some time for ovn-northd and ovn-controller to catch up.
2176 # XXX This should be more systematic.
2177 sleep 1
2178
2179 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2180 #
2181 # This shell function causes a packet to be received on INPORT. The packet's
2182 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2183 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2184 # more) list the VIFs on which the packet should be received. INPORT and the
2185 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2186 for i in 1 2 3; do
2187 : > $i.expected
2188 done
2189 test_packet() {
2190 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2191 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2192 hv=hv$inport
2193 vif=vif$inport
2194 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2195 for outport; do
2196 echo $packet >> $outport.expected
2197 done
2198 }
2199
2200 # Send packets between all pairs of source and destination ports:
2201 #
2202 # 1. Unicast packets are delivered to exactly one lport (except that packets
2203 # destined to their input ports are dropped).
2204 #
2205 # 2. Broadcast and multicast are delivered to all lports except the input port.
2206 #
2207 # 3. The lswitch delivers packets with an unknown destination to lports with
2208 # "unknown" among their MAC addresses (and port security disabled).
2209 for s in 1 2 3 ; do
2210 bcast=
2211 unknown=
2212 for d in 1 2 3 ; do
2213 if test $d != $s; then unicast=$d; else unicast=; fi
2214 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2215
2216 # The vtep (vif3) is the only one configured for "unknown"
2217 if test $d != $s && test $d = 3; then
2218 unknown="$unknown $d"
2219 fi
2220 bcast="$bcast $unicast"
2221 done
2222
2223 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2224 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2225 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2226 done
2227
2228 echo "------ ovn-nbctl show ------"
2229 ovn-nbctl show
2230 echo "------ ovn-sbctl show ------"
2231 ovn-sbctl show
2232
2233 echo "------ hv1 ------"
2234 as hv1 ovs-vsctl show
2235 echo "------ hv1 br-int ------"
2236 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2237 echo "------ hv1 br-phys ------"
2238 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2239
2240 echo "------ hv2 ------"
2241 as hv2 ovs-vsctl show
2242 echo "------ hv2 br-int ------"
2243 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2244 echo "------ hv2 br-phys ------"
2245 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2246
2247 echo "------ hv_gw ------"
2248 as hv_gw ovs-vsctl show
2249 echo "------ hv_gw br-phys ------"
2250 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2251 echo "------ hv_gw br-phys2 ------"
2252 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2253
2254 echo "------ hv3 ------"
2255 as hv3 ovs-vsctl show
2256 echo "------ hv3 br-phys ------"
2257 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2258
2259 # Now check the packets actually received against the ones expected.
2260 for i in 1 2 3; do
2261 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2262 done
2263 AT_CLEANUP
2264
2265 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2266 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2267 AT_SKIP_IF([test $HAVE_PYTHON = no])
2268 ovn_start
2269
2270 # Logical network:
2271 #
2272 # Three logical switches ls1, ls2, ls3.
2273 # One logical router lr0 connected to ls[123],
2274 # with nine subnets, three per logical switch:
2275 #
2276 # lrp11 on ls1 for subnet 192.168.11.0/24
2277 # lrp12 on ls1 for subnet 192.168.12.0/24
2278 # lrp13 on ls1 for subnet 192.168.13.0/24
2279 # ...
2280 # lrp33 on ls3 for subnet 192.168.33.0/24
2281 #
2282 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2283 # digits are the subnet and the last digit distinguishes the VIF.
2284 for i in 1 2 3; do
2285 ovn-nbctl ls-add ls$i
2286 for j in 1 2 3; do
2287 for k in 1 2 3; do
2288 # Add "unknown" to MAC addresses for lp?11, so packets for
2289 # MAC-IP bindings discovered via ARP later have somewhere to go.
2290 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2291
2292 ovn-nbctl \
2293 -- lsp-add ls$i lp$i$j$k \
2294 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2295 192.168.$i$j.$k" $unknown
2296 done
2297 done
2298 done
2299
2300 ovn-nbctl lr-add lr0
2301 for i in 1 2 3; do
2302 for j in 1 2 3; do
2303 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2304 ovn-nbctl \
2305 -- lsp-add ls$i lrp$i$j-attachment \
2306 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2307 options:router-port=lrp$i$j \
2308 addresses='"00:00:00:00:ff:'$i$j'"'
2309 done
2310 done
2311
2312 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2313 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2314
2315 # Physical network:
2316 #
2317 # Three hypervisors hv[123].
2318 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2319 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2320 # lp?3[123] all on hv3.
2321
2322
2323 # Given the name of a logical port, prints the name of the hypervisor
2324 # on which it is located.
2325 vif_to_hv() {
2326 case $1 in dnl (
2327 ?11) echo 1 ;; dnl (
2328 ?12 | ?21 | ?22) echo 2 ;; dnl (
2329 ?13 | ?23 | ?3?) echo 3 ;;
2330 esac
2331 }
2332
2333 # Given the name of a logical port, prints the name of its logical router
2334 # port, e.g. "vif_to_lrp 123" yields 12.
2335 vif_to_lrp() {
2336 echo ${1%?}
2337 }
2338
2339 # Given the name of a logical port, prints the name of its logical
2340 # switch, e.g. "vif_to_ls 123" yields 1.
2341 vif_to_ls() {
2342 echo ${1%??}
2343 }
2344
2345 net_add n1
2346 for i in 1 2 3; do
2347 sim_add hv$i
2348 as hv$i
2349 ovs-vsctl add-br br-phys
2350 ovn_attach n1 br-phys 192.168.0.$i
2351 done
2352 for i in 1 2 3; do
2353 for j in 1 2 3; do
2354 for k in 1 2 3; do
2355 hv=`vif_to_hv $i$j$k`
2356 as hv$hv ovs-vsctl \
2357 -- add-port br-int vif$i$j$k \
2358 -- set Interface vif$i$j$k \
2359 external-ids:iface-id=lp$i$j$k \
2360 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2361 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2362 ofport-request=$i$j$k
2363 done
2364 done
2365 done
2366
2367 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2368 # packets for ARP resolution (native tunneling doesn't queue packets
2369 # for ARP resolution).
2370 OVN_POPULATE_ARP
2371
2372 # Allow some time for ovn-northd and ovn-controller to catch up.
2373 # XXX This should be more systematic.
2374 sleep 1
2375
2376 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2377 #
2378 # This shell function causes a packet to be received on INPORT. The packet's
2379 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2380 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2381 # more) list the VIFs on which the packet should be received. INPORT and the
2382 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2383 for i in 1 2 3; do
2384 for j in 1 2 3; do
2385 for k in 1 2 3; do
2386 : > $i$j$k.expected
2387 done
2388 done
2389 done
2390 test_ip() {
2391 # This packet has bad checksums but logical L3 routing doesn't check.
2392 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2393 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2394 shift; shift; shift; shift; shift
2395 hv=hv`vif_to_hv $inport`
2396 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2397 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2398 in_ls=`vif_to_ls $inport`
2399 in_lrp=`vif_to_lrp $inport`
2400 for outport; do
2401 out_ls=`vif_to_ls $outport`
2402 if test $in_ls = $out_ls; then
2403 # Ports on the same logical switch receive exactly the same packet.
2404 echo $packet
2405 else
2406 # Routing decrements TTL and updates source and dest MAC
2407 # (and checksum).
2408 out_lrp=`vif_to_lrp $outport`
2409 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2410 fi >> $outport.expected
2411 done
2412 }
2413
2414 as hv1 ovs-vsctl --columns=name,ofport list interface
2415 as hv1 ovn-sbctl list port_binding
2416 as hv1 ovn-sbctl list datapath_binding
2417 as hv1 ovn-sbctl dump-flows
2418 as hv1 ovs-ofctl dump-flows br-int
2419
2420 # Send IP packets between all pairs of source and destination ports:
2421 #
2422 # 1. Unicast IP packets are delivered to exactly one logical switch port
2423 # (except that packets destined to their input ports are dropped).
2424 #
2425 # 2. Broadcast IP packets are delivered to all logical switch ports
2426 # except the input port.
2427 ip_to_hex() {
2428 printf "%02x%02x%02x%02x" "$@"
2429 }
2430 for is in 1 2 3; do
2431 for js in 1 2 3; do
2432 for ks in 1 2 3; do
2433 bcast=
2434 s=$is$js$ks
2435 smac=f00000000$s
2436 sip=`ip_to_hex 192 168 $is$js $ks`
2437 for id in 1 2 3; do
2438 for jd in 1 2 3; do
2439 for kd in 1 2 3; do
2440 d=$id$jd$kd
2441 dip=`ip_to_hex 192 168 $id$jd $kd`
2442 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2443 if test $d != $s; then unicast=$d; else unicast=; fi
2444
2445 test_ip $s $smac $dmac $sip $dip $unicast #1
2446
2447 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2448 done
2449 done
2450 done
2451 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2452 done
2453 done
2454 done
2455
2456 # 3. Send an IP packet from every logical port to every other subnet,
2457 # to an IP address that does not have a static IP-MAC binding.
2458 # This should generate a broadcast ARP request for the destination
2459 # IP address in the destination subnet.
2460 for is in 1 2 3; do
2461 for js in 1 2 3; do
2462 for ks in 1 2 3; do
2463 s=$is$js$ks
2464 smac=f00000000$s
2465 sip=`ip_to_hex 192 168 $is$js $ks`
2466 for id in 1 2 3; do
2467 for jd in 1 2 3; do
2468 if test $is$js = $id$jd; then
2469 continue
2470 fi
2471
2472 # Send the packet.
2473 dmac=00000000ff$is$js
2474 # Calculate a 4th octet for the destination that is
2475 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2476 # that have static MAC bindings, and fits in the range
2477 # 0-255.
2478 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2479 dip=`ip_to_hex 192 168 $id$jd $o4`
2480 test_ip $s $smac $dmac $sip $dip
2481
2482 # Every LP on the destination subnet's lswitch should
2483 # receive the ARP request.
2484 lrmac=00000000ff$id$jd
2485 lrip=`ip_to_hex 192 168 $id$jd 254`
2486 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2487 for jd2 in 1 2 3; do
2488 for kd in 1 2 3; do
2489 echo $arp >> $id$jd2$kd.expected
2490 done
2491 done
2492 done
2493 done
2494 done
2495 done
2496 done
2497
2498 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2499 #
2500 # Causes a packet to be received on INPORT. The packet is an ARP
2501 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2502 # it should be the hardware address of the target to expect to receive in an
2503 # ARP reply; otherwise no reply is expected.
2504 #
2505 # INPORT is an logical switch port number, e.g. 11 for vif11.
2506 # SHA and REPLY_HA are each 12 hex digits.
2507 # SPA and TPA are each 8 hex digits.
2508 test_arp() {
2509 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2510 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2511 hv=hv`vif_to_hv $inport`
2512 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2513 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2514
2515 # Expect to receive the broadcast ARP on the other logical switch ports if
2516 # IP address is not configured to the switch patch port.
2517 local i=`vif_to_ls $inport`
2518 local j k
2519 for j in 1 2 3; do
2520 for k in 1 2 3; do
2521 # 192.168.33.254 is configured to the switch patch port for lrp33,
2522 # so no ARP flooding expected for it.
2523 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2524 echo $request >> $i$j$k.expected
2525 fi
2526 done
2527 done
2528
2529 # Expect to receive the reply, if any.
2530 if test X$reply_ha != X; then
2531 lrp=`vif_to_lrp $inport`
2532 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2533 echo $reply >> $inport.expected
2534 fi
2535 }
2536
2537 # Test router replies to ARP requests from all source ports:
2538 #
2539 # 4. Router replies to query for its MAC address from port's own IP address.
2540 #
2541 # 5. Router replies to query for its MAC address from any random IP address
2542 # in its subnet.
2543 #
2544 # 6. Router replies to query for its MAC address from another subnet.
2545 #
2546 # 7. No reply to query for IP address other than router IP.
2547 for i in 1 2 3; do
2548 for j in 1 2 3; do
2549 for k in 1 2 3; do
2550 smac=f00000000$i$j$k # Source MAC
2551 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2552 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2553 rmac=00000000ff$i$j # Router MAC
2554 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2555 test_arp $i$j$k $smac $sip $rip $rmac #4
2556 test_arp $i$j$k $smac $otherip $rip $rmac #5
2557 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2558 test_arp $i$j$k $smac $sip $otherip #7
2559 done
2560 done
2561 done
2562
2563 # Allow some time for packet forwarding.
2564 # XXX This can be improved.
2565 sleep 1
2566
2567 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2568 # earlier as #3.
2569 #
2570 # Here, the $s is the VIF that originated the ARP request and $d is
2571 # the VIF that sends the ARP reply, which is somewhat backward but
2572 # it means that $s and $d are the same as #3.
2573 : > mac_bindings.expected
2574 for is in 1 2 3; do
2575 for js in 1 2 3; do
2576 for ks in 1 2 3; do
2577 s=$is$js$ks
2578 for id in 1 2 3; do
2579 for jd in 1 2 3; do
2580 if test $is$js = $id$jd; then
2581 continue
2582 fi
2583
2584 kd=1
2585 d=$id$jd$kd
2586
2587 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2588 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2589 host_mac=8000000000$o4
2590
2591 lrmac=00000000ff$id$jd
2592 lrip=`ip_to_hex 192 168 $id$jd 254`
2593
2594 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2595
2596 echo
2597 echo
2598 echo
2599 hv=hv`vif_to_hv $d`
2600 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2601 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2602 #as $hv ovs-ofctl dump-flows br-int table=19
2603
2604 host_ip_pretty=192.168.$id$jd.$o4
2605 host_mac_pretty=80:00:00:00:00:$o4
2606 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2607 done
2608 done
2609 done
2610 done
2611 done
2612
2613 # Allow some time for packet forwarding.
2614 # XXX This can be improved.
2615 sleep 1
2616
2617 # 9. Send an IP packet from every logical port to every other subnet. These
2618 # are the same packets already sent as #3, but now the destinations' IP-MAC
2619 # bindings have been discovered via ARP, so instead of provoking an ARP
2620 # request, these packets now get routed to their destinations (which don't
2621 # have static MAC bindings, so they go to the port we've designated as
2622 # accepting "unknown" MACs.)
2623 for is in 1 2 3; do
2624 for js in 1 2 3; do
2625 for ks in 1 2 3; do
2626 s=$is$js$ks
2627 smac=f00000000$s
2628 sip=`ip_to_hex 192 168 $is$js $ks`
2629 for id in 1 2 3; do
2630 for jd in 1 2 3; do
2631 if test $is$js = $id$jd; then
2632 continue
2633 fi
2634
2635 # Send the packet.
2636 dmac=00000000ff$is$js
2637 # Calculate a 4th octet for the destination that is
2638 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2639 # that have static MAC bindings, and fits in the range
2640 # 0-255.
2641 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2642 dip=`ip_to_hex 192 168 $id$jd $o4`
2643 test_ip $s $smac $dmac $sip $dip
2644
2645 # Expect the packet egress.
2646 host_mac=8000000000$o4
2647 outport=${id}11
2648 out_lrp=$id$jd
2649 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2650 done
2651 done
2652 done
2653 done
2654 done
2655
2656 ovn-sbctl -f csv -d bare --no-heading \
2657 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2658
2659 # Now check the packets actually received against the ones expected.
2660 for i in 1 2 3; do
2661 for j in 1 2 3; do
2662 for k in 1 2 3; do
2663 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2664 [$i$j$k.expected])
2665 done
2666 done
2667 done
2668
2669 # Check the MAC bindings against those expected.
2670 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2671 ])
2672
2673 # Gracefully terminate daemons
2674 OVN_CLEANUP([hv1], [hv2], [hv3])
2675
2676 AT_CLEANUP
2677
2678 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2679 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2680 AT_SKIP_IF([test $HAVE_PYTHON = no])
2681 ovn_start
2682
2683 # Create hypervisors hv[123].
2684 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2685 # Add all of the vifs to a single logical switch lsw0.
2686 # Turn off port security on vifs vif[123]1
2687 # Turn on l2 port security on vifs vif[123]2
2688 # Turn of l2 and l3 port security on vifs vif[123]3
2689 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2690 ovn-nbctl ls-add lsw0
2691 net_add n1
2692 for i in 1 2 3; do
2693 sim_add hv$i
2694 as hv$i
2695 ovs-vsctl add-br br-phys
2696 ovn_attach n1 br-phys 192.168.0.$i
2697
2698 for j in 1 2 3; do
2699 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
2700 ovn-nbctl lsp-add lsw0 lp$i$j
2701 if test $j = 1; then
2702 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2703 elif test $j = 2; then
2704 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2705 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2706 else
2707 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2708 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2709 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2710 fi
2711 done
2712 done
2713
2714 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2715 # packets for ARP resolution (native tunneling doesn't queue packets
2716 # for ARP resolution).
2717 OVN_POPULATE_ARP
2718
2719 # Allow some time for ovn-northd and ovn-controller to catch up.
2720 # XXX This should be more systematic.
2721 sleep 1
2722
2723 # Given the name of a logical port, prints the name of the hypervisor
2724 # on which it is located.
2725 vif_to_hv() {
2726 echo hv${1%?}
2727 }
2728
2729 for i in 1 2 3; do
2730 for j in 1 2 3; do
2731 : > $i$j.expected
2732 done
2733 done
2734
2735 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2736 #
2737 # This shell function causes an ip packet to be received on INPORT.
2738 # The packet's content has Ethernet destination DST and source SRC
2739 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2740 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2741 # be received. INPORT and the OUTPORTs are specified as logical switch
2742 # port numbers, e.g. 11 for vif11.
2743 test_ip() {
2744 # This packet has bad checksums but logical L3 routing doesn't check.
2745 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2746 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2747 shift; shift; shift; shift; shift
2748 hv=`vif_to_hv $inport`
2749 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2750 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2751 for outport; do
2752 echo $packet >> $outport.expected
2753 done
2754 }
2755
2756 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2757 #
2758 # Causes a packet to be received on INPORT. The packet is an ARP
2759 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2760 # it should be the hardware address of the target to expect to receive in an
2761 # ARP reply; otherwise no reply is expected.
2762 #
2763 # INPORT is an logical switch port number, e.g. 11 for vif11.
2764 # SHA and REPLY_HA are each 12 hex digits.
2765 # SPA and TPA are each 8 hex digits.
2766 test_arp() {
2767 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2768 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2769 hv=`vif_to_hv $inport`
2770 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2771 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2772 if test $drop != 1; then
2773 if test X$reply_ha = X; then
2774 # Expect to receive the broadcast ARP on the other logical switch ports
2775 # if no reply is expected.
2776 local i j
2777 for i in 1 2 3; do
2778 for j in 1 2 3; do
2779 if test $i$j != $inport; then
2780 echo $request >> $i$j.expected
2781 fi
2782 done
2783 done
2784 else
2785 # Expect to receive the reply, if any.
2786 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2787 echo $reply >> $inport.expected
2788 fi
2789 fi
2790 }
2791
2792 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2793 # This function is similar to test_ip() except that it sends
2794 # ipv6 packet
2795 test_ipv6() {
2796 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2797 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2798 shift; shift; shift; shift; shift
2799 hv=`vif_to_hv $inport`
2800 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2801 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2802 for outport; do
2803 echo $packet >> $outport.expected
2804 done
2805 }
2806
2807 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2808 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2809 # of the test packet
2810 test_icmpv6() {
2811 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2812 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2813 shift; shift; shift; shift; shift; shift
2814 hv=`vif_to_hv $inport`
2815 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2816 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2817 for outport; do
2818 echo $packet >> $outport.expected
2819 done
2820 }
2821
2822 ip_to_hex() {
2823 printf "%02x%02x%02x%02x" "$@"
2824 }
2825
2826 # no port security
2827 sip=`ip_to_hex 192 168 0 12`
2828 tip=`ip_to_hex 192 168 0 13`
2829 # the arp packet should be allowed even if lp[123]1 is
2830 # not configured with mac f00000000023 and ip 192.168.0.12
2831 for i in 1 2 3; do
2832 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2833 for j in 1 2 3; do
2834 if test $i != $j; then
2835 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2836 fi
2837 done
2838 done
2839
2840 # l2 port security
2841 sip=`ip_to_hex 192 168 0 12`
2842 tip=`ip_to_hex 192 168 0 13`
2843
2844 # arp packet should be allowed since lp22 is configured with
2845 # mac f00000000022
2846 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2847
2848 # arp packet should not be allowed since lp32 is not configured with
2849 # mac f00000000021
2850 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2851
2852 # arp packet with sha set to f00000000021 should not be allowed
2853 # for lp12
2854 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2855
2856 # ip packets should be allowed and received since lp[123]2 do not
2857 # have l3 port security
2858 sip=`ip_to_hex 192 168 0 55`
2859 tip=`ip_to_hex 192 168 0 66`
2860 for i in 1 2 3; do
2861 for j in 1 2 3; do
2862 if test $i != $j; then
2863 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2864 fi
2865 done
2866 done
2867
2868 # ipv6 packets should be received by lp[123]2
2869 # lp[123]1 can send ipv6 traffic as there is no port security
2870 sip=fe800000000000000000000000000000
2871 tip=ff020000000000000000000000000000
2872
2873 for i in 1 2 3; do
2874 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2875 done
2876
2877
2878 # l2 and l3 port security
2879 sip=`ip_to_hex 192 168 0 13`
2880 tip=`ip_to_hex 192 168 0 22`
2881 # arp packet should be allowed since lp13 is configured with
2882 # f00000000013 and 192.168.0.13
2883 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2884
2885 # the arp packet should be dropped because lp23 is not configured
2886 # with mac f00000000022
2887 sip=`ip_to_hex 192 168 0 13`
2888 tip=`ip_to_hex 192 168 0 22`
2889 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2890
2891 # the arp packet should be dropped because lp33 is not configured
2892 # with ip 192.168.0.55
2893 spa=`ip_to_hex 192 168 0 55`
2894 tpa=`ip_to_hex 192 168 0 22`
2895 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2896
2897 # ip packets should not be received by lp[123]3 since
2898 # l3 port security is enabled
2899 sip=`ip_to_hex 192 168 0 55`
2900 tip=`ip_to_hex 192 168 0 66`
2901 for i in 1 2 3; do
2902 for j in 1 2 3; do
2903 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2904 done
2905 done
2906
2907 # ipv6 packets should be dropped for lp[123]3 since
2908 # it is configured with only ipv4 address
2909 sip=fe800000000000000000000000000000
2910 tip=ff020000000000000000000000000000
2911
2912 for i in 1 2 3; do
2913 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2914 done
2915
2916 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2917 # lp[123]1 can send ipv6 traffic as there is no port security
2918 for i in 1 2 3; do
2919 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2920 done
2921
2922 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2923 # fe80::ea2a:eaff:fe28:0012
2924
2925 # ipv4 packet should be dropped for lp13 with mac f0000000113
2926 sip=`ip_to_hex 192 168 0 13`
2927 tip=`ip_to_hex 192 168 0 23`
2928 test_ip 13 f00000000113 f00000000023 $sip $tip
2929
2930 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2931 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2932 # lp11 can send ipv6 traffic as there is no port security
2933 sip=ee800000000000000000000000000000
2934 for i in 1 2 3; do
2935 tip=fe80000000000000ea2aeafffe2800${i}3
2936 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2937 done
2938
2939
2940 # ipv6 packet should not be received by lp33 with mac f0000000333
2941 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2942 # configured with fe80::ea2a:eaff:fe28:0033
2943 # lp11 can send ipv6 traffic as there is no port security
2944
2945 sip=ee800000000000000000000000000000
2946 tip=fe80000000000000ea2aeafffe280023
2947 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2948
2949 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2950 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2951 # and should be dropped for any other ip6.src
2952 # lp21 can receive ipv6 traffic as there is no port security
2953
2954 tip=ee800000000000000000000000000000
2955 for i in 1 2 3; do
2956 sip=fe80000000000000ea2aeafffe2800${i}3
2957 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2958
2959 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2960 sip=00000000000000000000000000000000
2961 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2962 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2963 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2964 # Traffic to non-multicast traffic should be dropped
2965 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2966 # Traffic of other ICMPv6 types should be dropped
2967 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2968
2969 # should be dropped
2970 sip=ae80000000000000ea2aeafffe2800aa
2971 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2972 done
2973
2974 # configure lsp13 to send and received IPv4 packets with an address range
2975 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"
2976
2977 sleep 2
2978
2979 sip=`ip_to_hex 10 0 0 13`
2980 tip=`ip_to_hex 192 168 0 22`
2981 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2982 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2983
2984 sip=`ip_to_hex 10 0 0 14`
2985 tip=`ip_to_hex 192 168 0 23`
2986 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2987 # with dst ip 192.168.0.23 should be allowed
2988 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2989
2990 sip=`ip_to_hex 192 168 0 33`
2991 tip=`ip_to_hex 10 0 0 15`
2992 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2993 # with dst ip 10.0.0.15 should be received by lsp13
2994 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2995
2996 sip=`ip_to_hex 192 168 0 33`
2997 tip=`ip_to_hex 20 0 0 4`
2998 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2999 # with dst ip 20.0.0.4 should be received by lsp13
3000 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3001
3002 sip=`ip_to_hex 192 168 0 33`
3003 tip=`ip_to_hex 20 0 0 5`
3004 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3005 # with dst ip 20.0.0.5 should not be received by lsp13
3006 test_ip 33 f00000000033 f00000000013 $sip $tip
3007
3008 sip=`ip_to_hex 192 168 0 33`
3009 tip=`ip_to_hex 20 0 0 255`
3010 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3011 # with dst ip 20.0.0.255 should be received by lsp13
3012 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3013
3014 sip=`ip_to_hex 192 168 0 33`
3015 tip=`ip_to_hex 192 168 0 255`
3016 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3017 # with dst ip 192.168.0.255 should not be received by lsp13
3018 test_ip 33 f00000000033 f00000000013 $sip $tip
3019
3020 sip=`ip_to_hex 192 168 0 33`
3021 tip=`ip_to_hex 224 0 0 4`
3022 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3023 # with dst ip 224.0.0.4 should be received by lsp13
3024 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3025
3026 #dump information including flow counters
3027 ovn-nbctl show
3028 ovn-sbctl dump-flows -- list multicast_group
3029
3030 echo "------ hv1 dump ------"
3031 as hv1 ovs-vsctl show
3032 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3033 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3034
3035 echo "------ hv2 dump ------"
3036 as hv2 ovs-vsctl show
3037 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3038 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3039
3040 echo "------ hv3 dump ------"
3041 as hv3 ovs-vsctl show
3042 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3043 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3044
3045 # Now check the packets actually received against the ones expected.
3046 for i in 1 2 3; do
3047 for j in 1 2 3; do
3048 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3049 done
3050 done
3051
3052 OVN_CLEANUP([hv1],[hv2],[hv3])
3053
3054 AT_CLEANUP
3055
3056 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3057 AT_SKIP_IF([test $HAVE_PYTHON = no])
3058 ovn_start
3059
3060 # Logical network:
3061 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3062 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3063 # R2 has ls2 (172.16.1.0/24) connected to it.
3064
3065 ls1_lp1_mac="f0:00:00:01:02:03"
3066 rp_ls1_mac="00:00:00:01:02:03"
3067 rp_ls2_mac="00:00:00:01:02:04"
3068 ls2_lp1_mac="f0:00:00:01:02:04"
3069
3070 ls1_lp1_ip="192.168.1.2"
3071 ls2_lp1_ip="172.16.1.2"
3072
3073 ovn-nbctl lr-add R1
3074 ovn-nbctl lr-add R2
3075
3076 ovn-nbctl ls-add ls1
3077 ovn-nbctl ls-add ls2
3078
3079 # Connect ls1 to R1
3080 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3081
3082 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3083 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3084
3085 # Connect ls2 to R2
3086 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3087
3088 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3089 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3090
3091 # Connect R1 to R2
3092 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3093 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3094
3095 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3096 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3097
3098 # Create logical port ls1-lp1 in ls1
3099 ovn-nbctl lsp-add ls1 ls1-lp1 \
3100 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3101
3102 # Create logical port ls2-lp1 in ls2
3103 ovn-nbctl lsp-add ls2 ls2-lp1 \
3104 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3105
3106 # Create two hypervisor and create OVS ports corresponding to logical ports.
3107 net_add n1
3108
3109 sim_add hv1
3110 as hv1
3111 ovs-vsctl add-br br-phys
3112 ovn_attach n1 br-phys 192.168.0.1
3113 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3114 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3115 options:tx_pcap=hv1/vif1-tx.pcap \
3116 options:rxq_pcap=hv1/vif1-rx.pcap \
3117 ofport-request=1
3118
3119 sim_add hv2
3120 as hv2
3121 ovs-vsctl add-br br-phys
3122 ovn_attach n1 br-phys 192.168.0.2
3123 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3124 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3125 options:tx_pcap=hv2/vif1-tx.pcap \
3126 options:rxq_pcap=hv2/vif1-rx.pcap \
3127 ofport-request=1
3128
3129
3130 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3131 # packets for ARP resolution (native tunneling doesn't queue packets
3132 # for ARP resolution).
3133 OVN_POPULATE_ARP
3134
3135 # Allow some time for ovn-northd and ovn-controller to catch up.
3136 # XXX This should be more systematic.
3137 sleep 1
3138
3139 # Packet to send.
3140 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3141 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3142 udp && udp.src==53 && udp.dst==4369"
3143 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3144
3145
3146 echo "---------NB dump-----"
3147 ovn-nbctl show
3148 echo "---------------------"
3149 ovn-nbctl list logical_router
3150 echo "---------------------"
3151 ovn-nbctl list logical_router_port
3152 echo "---------------------"
3153
3154 echo "---------SB dump-----"
3155 ovn-sbctl list datapath_binding
3156 echo "---------------------"
3157 ovn-sbctl list port_binding
3158 echo "---------------------"
3159
3160 echo "------ hv1 dump ----------"
3161 as hv1 ovs-ofctl show br-int
3162 as hv1 ovs-ofctl dump-flows br-int
3163 echo "------ hv2 dump ----------"
3164 as hv2 ovs-ofctl show br-int
3165 as hv2 ovs-ofctl dump-flows br-int
3166
3167 # Packet to Expect
3168 # The TTL should be decremented by 2.
3169 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3170 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3171 udp && udp.src==53 && udp.dst==4369"
3172 echo $packet | ovstest test-ovn expr-to-packets > expected
3173
3174 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3175
3176 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3177 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3178 ])
3179
3180 # Disable the ls2-lp1 port.
3181 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3182
3183 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3184 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3185 ])
3186
3187 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3188 # Packet to send.
3189 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3190 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3191 udp && udp.src==53 && udp.dst==4369"
3192
3193 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3194 # The 2nd packet sent shound not be received.
3195 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3196
3197 OVN_CLEANUP([hv1],[hv2])
3198
3199 AT_CLEANUP
3200
3201
3202 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3203 AT_KEYWORDS([router-admin-state])
3204 AT_SKIP_IF([test $HAVE_PYTHON = no])
3205 ovn_start
3206
3207 # Logical network:
3208 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3209 # and 172.16.1.0/24) connected to it.
3210
3211 ovn-nbctl lr-add R1
3212
3213 ovn-nbctl ls-add ls1
3214
3215 # Connect ls1 to R1
3216 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3217 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3218 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3219
3220 # Create logical port ls1-lp1 in ls1
3221 ovn-nbctl lsp-add ls1 ls1-lp1 \
3222 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3223
3224 # Create logical port ls1-lp2 in ls1
3225 ovn-nbctl lsp-add ls1 ls1-lp2 \
3226 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3227
3228 # Create one hypervisor and create OVS ports corresponding to logical ports.
3229 net_add n1
3230
3231 sim_add hv1
3232 as hv1
3233 ovs-vsctl add-br br-phys
3234 ovn_attach n1 br-phys 192.168.0.1
3235 ovs-vsctl -- add-port br-int vif1 -- \
3236 set interface vif1 external-ids:iface-id=ls1-lp1 \
3237 options:tx_pcap=hv1/vif1-tx.pcap \
3238 options:rxq_pcap=hv1/vif1-rx.pcap \
3239 ofport-request=1
3240
3241 ovs-vsctl -- add-port br-int vif2 -- \
3242 set interface vif2 external-ids:iface-id=ls1-lp2 \
3243 options:tx_pcap=hv1/vif2-tx.pcap \
3244 options:rxq_pcap=hv1/vif2-rx.pcap \
3245 ofport-request=1
3246
3247
3248 # Allow some time for ovn-northd and ovn-controller to catch up.
3249 # XXX This should be more systematic.
3250 sleep 1
3251
3252 # Send ip packets between the two ports.
3253 ip_to_hex() {
3254 printf "%02x%02x%02x%02x" "$@"
3255 }
3256
3257 # Packet to send.
3258 src_mac="f00000010203"
3259 dst_mac="000000010203"
3260 src_ip=`ip_to_hex 192 168 1 2`
3261 dst_ip=`ip_to_hex 172 16 1 2`
3262 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3263 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3264
3265
3266 echo "---------NB dump-----"
3267 ovn-nbctl show
3268 echo "---------------------"
3269 ovn-nbctl list logical_router
3270 echo "---------------------"
3271 ovn-nbctl list logical_router_port
3272 echo "---------------------"
3273
3274 echo "---------SB dump-----"
3275 ovn-sbctl list datapath_binding
3276 echo "---------------------"
3277 ovn-sbctl list logical_flow
3278 echo "---------------------"
3279
3280 echo "------ hv1 dump ----------"
3281 as hv1 ovs-ofctl dump-flows br-int
3282
3283
3284 #Disable router R1
3285 ovn-nbctl set Logical_Router R1 enabled=false
3286
3287 # Allow some time for ovn-northd and ovn-controller to catch up.
3288 # XXX This should be more systematic.
3289 sleep 1
3290
3291 echo "---------SB dump-----"
3292 ovn-sbctl list datapath_binding
3293 echo "---------------------"
3294 ovn-sbctl list logical_flow
3295 echo "---------------------"
3296
3297 echo "------ hv1 dump ----------"
3298 as hv1 ovs-ofctl dump-flows br-int
3299
3300 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3301
3302 # Packet to Expect
3303 expect_src_mac="000000010203"
3304 expect_dst_mac="f00000010204"
3305 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3306
3307 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3308
3309
3310 as hv1
3311 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3312 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3313 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3314
3315 as ovn-sb
3316 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3317
3318 as ovn-nb
3319 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3320
3321 as northd
3322 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3323
3324 as main
3325 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3326 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3327
3328 AT_CLEANUP
3329
3330
3331 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3332 AT_KEYWORDS([router-admin-state])
3333 AT_SKIP_IF([test $HAVE_PYTHON = no])
3334 ovn_start
3335
3336 # Logical network:
3337 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3338 # and has switch ls2 (172.16.1.0/24) connected to it.
3339
3340 ovn-nbctl lr-add R1
3341
3342 ovn-nbctl ls-add ls1
3343 ovn-nbctl ls-add ls2
3344
3345 # Connect ls1 to R1
3346 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3347 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3348 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3349
3350 # Connect ls2 to R1
3351 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3352 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3353 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3354
3355 # Create logical port ls1-lp1 in ls1
3356 ovn-nbctl lsp-add ls1 ls1-lp1 \
3357 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3358
3359 # Create logical port ls2-lp1 in ls2
3360 ovn-nbctl lsp-add ls2 ls2-lp1 \
3361 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3362
3363 # Create one hypervisor and create OVS ports corresponding to logical ports.
3364 net_add n1
3365
3366 sim_add hv1
3367 as hv1
3368 ovs-vsctl add-br br-phys
3369 ovn_attach n1 br-phys 192.168.0.1
3370 ovs-vsctl -- add-port br-int vif1 -- \
3371 set interface vif1 external-ids:iface-id=ls1-lp1 \
3372 options:tx_pcap=hv1/vif1-tx.pcap \
3373 options:rxq_pcap=hv1/vif1-rx.pcap \
3374 ofport-request=1
3375
3376 ovs-vsctl -- add-port br-int vif2 -- \
3377 set interface vif2 external-ids:iface-id=ls2-lp1 \
3378 options:tx_pcap=hv1/vif2-tx.pcap \
3379 options:rxq_pcap=hv1/vif2-rx.pcap \
3380 ofport-request=1
3381
3382
3383 # Allow some time for ovn-northd and ovn-controller to catch up.
3384 # XXX This should be more systematic.
3385 sleep 1
3386
3387 # Send ip packets between the two ports.
3388 ip_to_hex() {
3389 printf "%02x%02x%02x%02x" "$@"
3390 }
3391
3392 # Packet to send.
3393 src_mac="f00000010203"
3394 dst_mac="000000010203"
3395 src_ip=`ip_to_hex 192 168 1 2`
3396 dst_ip=`ip_to_hex 172 16 1 2`
3397 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3398 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3399
3400
3401 echo "---------NB dump-----"
3402 ovn-nbctl show
3403 echo "---------------------"
3404 ovn-nbctl list logical_router
3405 echo "---------------------"
3406 ovn-nbctl list logical_router_port
3407 echo "---------------------"
3408
3409 echo "---------SB dump-----"
3410 ovn-sbctl list datapath_binding
3411 echo "---------------------"
3412 ovn-sbctl list logical_flow
3413 echo "---------------------"
3414
3415 echo "------ hv1 dump ----------"
3416 as hv1 ovs-ofctl dump-flows br-int
3417
3418 #Disable router R1
3419 ovn-nbctl set Logical_Router R1 enabled=false
3420
3421 echo "---------SB dump-----"
3422 ovn-sbctl list datapath_binding
3423 echo "---------------------"
3424 ovn-sbctl list logical_flow
3425 echo "---------------------"
3426
3427 echo "------ hv1 dump ----------"
3428 as hv1 ovs-ofctl dump-flows br-int
3429
3430 # Allow some time for the disabling of logical router R1 to propagate.
3431 # XXX This should be more systematic.
3432 sleep 1
3433
3434 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3435
3436 # Packet to Expect
3437 expect_src_mac="000000010204"
3438 expect_dst_mac="f00000010204"
3439 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3440
3441 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3442
3443 OVN_CLEANUP([hv1])
3444
3445 AT_CLEANUP
3446
3447 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3448 AT_SKIP_IF([test $HAVE_PYTHON = no])
3449 ovn_start
3450
3451 # Logical network:
3452 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3453 # network. R1 has switchess foo (192.168.1.0/24)
3454 # connected to it.
3455 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3456
3457 ovn-nbctl lr-add R1
3458 ovn-nbctl lr-add R2
3459
3460 ovn-nbctl ls-add foo
3461 ovn-nbctl ls-add alice
3462 ovn-nbctl ls-add bob
3463
3464 # Connect foo to R1
3465 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3466 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3467 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3468
3469 # Connect alice to R2
3470 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3471 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3472 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3473
3474 # Connect bob to R2
3475 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3476 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3477 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3478
3479 # Connect R1 to R2
3480 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3481 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3482
3483 #install static routes
3484 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3485 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3486 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3487
3488 # Create logical port foo1 in foo
3489 ovn-nbctl lsp-add foo foo1 \
3490 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3491
3492 # Create logical port alice1 in alice
3493 ovn-nbctl lsp-add alice alice1 \
3494 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3495
3496 # Create logical port bob1 in bob
3497 ovn-nbctl lsp-add bob bob1 \
3498 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3499
3500 # Create two hypervisor and create OVS ports corresponding to logical ports.
3501 net_add n1
3502
3503 sim_add hv1
3504 as hv1
3505 ovs-vsctl add-br br-phys
3506 ovn_attach n1 br-phys 192.168.0.1
3507 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3508 set interface hv1-vif1 external-ids:iface-id=foo1 \
3509 options:tx_pcap=hv1/vif1-tx.pcap \
3510 options:rxq_pcap=hv1/vif1-rx.pcap \
3511 ofport-request=1
3512
3513 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3514 set interface hv1-vif2 external-ids:iface-id=alice1 \
3515 options:tx_pcap=hv1/vif2-tx.pcap \
3516 options:rxq_pcap=hv1/vif2-rx.pcap \
3517 ofport-request=2
3518
3519 sim_add hv2
3520 as hv2
3521 ovs-vsctl add-br br-phys
3522 ovn_attach n1 br-phys 192.168.0.2
3523 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3524 set interface hv2-vif1 external-ids:iface-id=bob1 \
3525 options:tx_pcap=hv2/vif1-tx.pcap \
3526 options:rxq_pcap=hv2/vif1-rx.pcap \
3527 ofport-request=1
3528
3529
3530 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3531 # packets for ARP resolution (native tunneling doesn't queue packets
3532 # for ARP resolution).
3533 OVN_POPULATE_ARP
3534
3535 # Allow some time for ovn-northd and ovn-controller to catch up.
3536 # XXX This should be more systematic.
3537 sleep 1
3538
3539 ip_to_hex() {
3540 printf "%02x%02x%02x%02x" "$@"
3541 }
3542
3543 # Send ip packets between foo1 and alice1
3544 src_mac="f00000010203"
3545 dst_mac="000000010203"
3546 src_ip=`ip_to_hex 192 168 1 2`
3547 dst_ip=`ip_to_hex 172 16 1 2`
3548 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3549 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3550
3551 # Send ip packets between foo1 and bob1
3552 src_mac="f00000010203"
3553 dst_mac="000000010203"
3554 src_ip=`ip_to_hex 192 168 1 2`
3555 dst_ip=`ip_to_hex 172 16 2 2`
3556 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3557 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3558
3559 echo "---------NB dump-----"
3560 ovn-nbctl show
3561 echo "---------------------"
3562 ovn-nbctl list logical_router
3563 echo "---------------------"
3564 ovn-nbctl list logical_router_port
3565 echo "---------------------"
3566
3567 echo "---------SB dump-----"
3568 ovn-sbctl list datapath_binding
3569 echo "---------------------"
3570 ovn-sbctl list port_binding
3571 echo "---------------------"
3572
3573 echo "------ hv1 dump ----------"
3574 as hv1 ovs-ofctl dump-flows br-int
3575 echo "------ hv2 dump ----------"
3576 as hv2 ovs-ofctl dump-flows br-int
3577
3578 # Packet to Expect at bob1
3579 src_mac="000000010205"
3580 dst_mac="f00000010205"
3581 src_ip=`ip_to_hex 192 168 1 2`
3582 dst_ip=`ip_to_hex 172 16 2 2`
3583 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3584
3585 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3586
3587 # Packet to Expect at alice1
3588 src_mac="000000010204"
3589 dst_mac="f00000010204"
3590 src_ip=`ip_to_hex 192 168 1 2`
3591 dst_ip=`ip_to_hex 172 16 1 2`
3592 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3593
3594 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3595
3596 OVN_CLEANUP([hv1],[hv2])
3597
3598 AT_CLEANUP
3599
3600 AT_SETUP([ovn -- send gratuitous arp on localnet])
3601 AT_SKIP_IF([test $HAVE_PYTHON = no])
3602 ovn_start
3603 ovn-nbctl ls-add lsw0
3604 net_add n1
3605 sim_add hv
3606 as hv
3607 ovs-vsctl \
3608 -- add-br br-phys \
3609 -- add-br br-eth0
3610
3611 ovn_attach n1 br-phys 192.168.0.1
3612
3613 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3614 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])
3615
3616 # Create a vif.
3617 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3618 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3619 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3620
3621 # Create a localnet port.
3622 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3623 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3624 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3625 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3626
3627 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3628
3629 # Wait for packet to be received.
3630 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3631 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3632
3633 # Check GARP packet when restart openflow connection.
3634 as hv
3635 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3636
3637 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3638
3639 as hv
3640 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3641
3642 # Wait for packet to be received.
3643 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3644 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3645
3646 # Delete the localnet ports.
3647 AT_CHECK([ovs-vsctl del-port localvif1])
3648 AT_CHECK([ovn-nbctl lsp-del ln_port])
3649
3650 OVN_CLEANUP([hv])
3651
3652 AT_CLEANUP
3653
3654 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3655 AT_SKIP_IF([test $HAVE_PYTHON = no])
3656 ovn_start
3657
3658 # Logical network:
3659 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3660 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3661 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3662 # connected to it.
3663
3664 ovn-nbctl lr-add R1
3665 ovn-nbctl lr-add R2
3666 ovn-nbctl lr-add R3
3667
3668 ovn-nbctl ls-add foo
3669 ovn-nbctl ls-add alice
3670 ovn-nbctl ls-add bob
3671 ovn-nbctl ls-add join
3672
3673 # Connect foo to R1
3674 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3675 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3676 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3677
3678 # Connect alice to R2
3679 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3680 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3681 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3682
3683 # Connect bob to R3
3684 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3685 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3686 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3687
3688 # Connect R1 to join
3689 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3690 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3691 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3692
3693 # Connect R2 to join
3694 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3695 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3696 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3697
3698 # Connect R3 to join
3699 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3700 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3701 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3702
3703 #install static routes
3704 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3705 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3706
3707 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3708 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3709
3710 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3711 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3712
3713 # Create logical port foo1 in foo
3714 ovn-nbctl lsp-add foo foo1 \
3715 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3716
3717 # Create logical port alice1 in alice
3718 ovn-nbctl lsp-add alice alice1 \
3719 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3720
3721 # Create logical port bob1 in bob
3722 ovn-nbctl lsp-add bob bob1 \
3723 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3724
3725 # Create two hypervisor and create OVS ports corresponding to logical ports.
3726 net_add n1
3727
3728 sim_add hv1
3729 as hv1
3730 ovs-vsctl add-br br-phys
3731 ovn_attach n1 br-phys 192.168.0.1
3732 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3733 set interface hv1-vif1 external-ids:iface-id=foo1 \
3734 options:tx_pcap=hv1/vif1-tx.pcap \
3735 options:rxq_pcap=hv1/vif1-rx.pcap \
3736 ofport-request=1
3737
3738 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3739 set interface hv1-vif2 external-ids:iface-id=alice1 \
3740 options:tx_pcap=hv1/vif2-tx.pcap \
3741 options:rxq_pcap=hv1/vif2-rx.pcap \
3742 ofport-request=2
3743
3744 sim_add hv2
3745 as hv2
3746 ovs-vsctl add-br br-phys
3747 ovn_attach n1 br-phys 192.168.0.2
3748 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3749 set interface hv2-vif1 external-ids:iface-id=bob1 \
3750 options:tx_pcap=hv2/vif1-tx.pcap \
3751 options:rxq_pcap=hv2/vif1-rx.pcap \
3752 ofport-request=1
3753
3754
3755 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3756 # packets for ARP resolution (native tunneling doesn't queue packets
3757 # for ARP resolution).
3758 OVN_POPULATE_ARP
3759
3760 # Allow some time for ovn-northd and ovn-controller to catch up.
3761 # XXX This should be more systematic.
3762 sleep 1
3763
3764 ip_to_hex() {
3765 printf "%02x%02x%02x%02x" "$@"
3766 }
3767
3768 # Send ip packets between foo1 and alice1
3769 src_mac="f00000010203"
3770 dst_mac="000001010203"
3771 src_ip=`ip_to_hex 192 168 1 2`
3772 dst_ip=`ip_to_hex 172 16 1 2`
3773 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3774 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3775 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3776
3777 # Send ip packets between foo1 and bob1
3778 src_mac="f00000010203"
3779 dst_mac="000001010203"
3780 src_ip=`ip_to_hex 192 168 1 2`
3781 dst_ip=`ip_to_hex 10 32 1 2`
3782 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3783 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3784
3785 echo "---------NB dump-----"
3786 ovn-nbctl show
3787 echo "---------------------"
3788 ovn-nbctl list logical_router
3789 echo "---------------------"
3790 ovn-nbctl list logical_router_port
3791 echo "---------------------"
3792
3793 echo "---------SB dump-----"
3794 ovn-sbctl list datapath_binding
3795 echo "---------------------"
3796 ovn-sbctl list port_binding
3797 echo "---------------------"
3798 ovn-sbctl dump-flows
3799 echo "---------------------"
3800
3801 echo "------ hv1 dump ----------"
3802 as hv1 ovs-ofctl show br-int
3803 as hv1 ovs-ofctl dump-flows br-int
3804 echo "------ hv2 dump ----------"
3805 as hv2 ovs-ofctl show br-int
3806 as hv2 ovs-ofctl dump-flows br-int
3807 echo "----------------------------"
3808
3809 # Packet to Expect at bob1
3810 src_mac="000003010203"
3811 dst_mac="f00000010205"
3812 src_ip=`ip_to_hex 192 168 1 2`
3813 dst_ip=`ip_to_hex 10 32 1 2`
3814 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3815
3816 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3817
3818 # Packet to Expect at alice1
3819 src_mac="000002010203"
3820 dst_mac="f00000010204"
3821 src_ip=`ip_to_hex 192 168 1 2`
3822 dst_ip=`ip_to_hex 172 16 1 2`
3823 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3824
3825 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3826
3827 OVN_CLEANUP([hv1],[hv2])
3828
3829 AT_CLEANUP
3830
3831 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3832 AT_SKIP_IF([test $HAVE_PYTHON = no])
3833 ovn_start
3834
3835 ovn-nbctl ls-add ls1
3836
3837 ovn-nbctl lsp-add ls1 ls1-lp1 \
3838 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3839
3840 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3841
3842 ovn-nbctl lsp-add ls1 ls1-lp2 \
3843 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3844
3845 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3846
3847 ovn-nbctl ls-add ls2
3848 ovn-nbctl lsp-add ls2 ls2-lp1 \
3849 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3850 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3851 ovn-nbctl lsp-add ls2 ls2-lp2 \
3852 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3853 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3854
3855 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3856 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3857 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3858
3859 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3860 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3861
3862 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3863 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3864 \"lease_time\"=\"3600\"")"
3865
3866 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3867
3868 net_add n1
3869 sim_add hv1
3870
3871 as hv1
3872 ovs-vsctl add-br br-phys
3873 ovn_attach n1 br-phys 192.168.0.1
3874 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3875 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3876 options:tx_pcap=hv1/vif1-tx.pcap \
3877 options:rxq_pcap=hv1/vif1-rx.pcap \
3878 ofport-request=1
3879
3880 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3881 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3882 options:tx_pcap=hv1/vif2-tx.pcap \
3883 options:rxq_pcap=hv1/vif2-rx.pcap \
3884 ofport-request=2
3885
3886 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3887 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3888 options:tx_pcap=hv1/vif3-tx.pcap \
3889 options:rxq_pcap=hv1/vif3-rx.pcap \
3890 ofport-request=3
3891
3892 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3893 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3894 options:tx_pcap=hv1/vif4-tx.pcap \
3895 options:rxq_pcap=hv1/vif4-rx.pcap \
3896 ofport-request=4
3897
3898 OVN_POPULATE_ARP
3899
3900 sleep 2
3901
3902 as hv1 ovs-vsctl show
3903
3904 # This shell function sends a DHCP request packet
3905 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3906 test_dhcp() {
3907 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3908 shift; shift; shift; shift; shift;
3909 if test $use_ip != 0; then
3910 src_ip=$1
3911 dst_ip=$2
3912 shift; shift;
3913 else
3914 src_ip=`ip_to_hex 0 0 0 0`
3915 dst_ip=`ip_to_hex 255 255 255 255`
3916 fi
3917 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
3918 # udp header and dhcp header
3919 request=${request}0044004300fc0000
3920 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3921 # client hardware padding
3922 request=${request}00000000000000000000
3923 # server hostname
3924 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3925 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3926 # boot file name
3927 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3928 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3929 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3930 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3931 # dhcp magic cookie
3932 request=${request}63825363
3933 # dhcp message type
3934 request=${request}3501${dhcp_type}ff
3935
3936 if test $offer_ip != 0; then
3937 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
3938 # total IP length will be the IP length of the request packet
3939 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3940 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3941 udp_len=`expr $ip_len - 20`
3942 ip_len=$(printf "%x" $ip_len)
3943 udp_len=$(printf "%x" $udp_len)
3944 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3945 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3946 # udp header and dhcp header.
3947 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3948 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3949 # your ip address
3950 reply=${reply}${offer_ip}
3951 # next server ip address, relay agent ip address, client mac address
3952 reply=${reply}0000000000000000${src_mac}
3953 # client hardware padding
3954 reply=${reply}00000000000000000000
3955 # server hostname
3956 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3957 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3958 # boot file name
3959 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3960 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3961 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3962 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3963 # dhcp magic cookie
3964 reply=${reply}63825363
3965 # dhcp message type
3966 local dhcp_reply_type=02
3967 if test $dhcp_type = 03; then
3968 dhcp_reply_type=05
3969 fi
3970 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3971 echo $reply >> $inport.expected
3972 else
3973 for outport; do
3974 echo $request >> $outport.expected
3975 done
3976 fi
3977 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3978 }
3979
3980 reset_pcap_file() {
3981 local iface=$1
3982 local pcap_file=$2
3983 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3984 options:rxq_pcap=dummy-rx.pcap
3985 rm -f ${pcap_file}*.pcap
3986 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3987 options:rxq_pcap=${pcap_file}-rx.pcap
3988 }
3989
3990 ip_to_hex() {
3991 printf "%02x%02x%02x%02x" "$@"
3992 }
3993
3994 AT_CAPTURE_FILE([ofctl_monitor0.log])
3995 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3996 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3997
3998 echo "---------NB dump-----"
3999 ovn-nbctl show
4000 echo "---------------------"
4001 echo "---------SB dump-----"
4002 ovn-sbctl list datapath_binding
4003 echo "---------------------"
4004 ovn-sbctl list logical_flow
4005 echo "---------------------"
4006
4007 echo "---------------------"
4008 ovn-sbctl dump-flows
4009 echo "---------------------"
4010
4011 echo "------ hv1 dump ----------"
4012 as hv1 ovs-ofctl dump-flows br-int
4013
4014 # Send DHCPDISCOVER.
4015 offer_ip=`ip_to_hex 10 0 0 4`
4016 server_ip=`ip_to_hex 10 0 0 1`
4017 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4018 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4019
4020 # NXT_RESUMEs should be 1.
4021 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4022
4023 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4024 cat 1.expected | cut -c -48 > expout
4025 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4026 # Skipping the IPv4 checksum.
4027 cat 1.expected | cut -c 53- > expout
4028 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4029
4030 # ovs-ofctl also resumes the packets and this causes other ports to receive
4031 # the DHCP request packet. So reset the pcap files so that its easier to test.
4032 reset_pcap_file hv1-vif1 hv1/vif1
4033 reset_pcap_file hv1-vif2 hv1/vif2
4034 rm -f 1.expected
4035 rm -f 2.expected
4036
4037 # Send DHCPREQUEST.
4038 offer_ip=`ip_to_hex 10 0 0 6`
4039 server_ip=`ip_to_hex 10 0 0 1`
4040 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4041 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4042
4043 # NXT_RESUMEs should be 2.
4044 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4045
4046 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4047 cat 2.expected | cut -c -48 > expout
4048 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4049 # Skipping the IPv4 checksum.
4050 cat 2.expected | cut -c 53- > expout
4051 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4052
4053 reset_pcap_file hv1-vif1 hv1/vif1
4054 reset_pcap_file hv1-vif2 hv1/vif2
4055 rm -f 1.expected
4056 rm -f 2.expected
4057
4058 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4059 # but should be resumed without the reply.
4060 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4061 # one from ovn-controller and the other from "ovs-ofctl resume."
4062 offer_ip=0
4063 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4064
4065 # NXT_RESUMEs should be 3.
4066 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4067
4068 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4069 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4070
4071 reset_pcap_file hv1-vif1 hv1/vif1
4072 reset_pcap_file hv1-vif2 hv1/vif2
4073 rm -f 1.expected
4074 rm -f 2.expected
4075
4076 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4077 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4078
4079 test_dhcp 3 f00000000003 01 0 4 0
4080
4081 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4082 # this lport.
4083 test_dhcp 4 f00000000004 01 0 3 0
4084
4085 # NXT_RESUMEs should be 3.
4086 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4087
4088 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4089 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4090
4091 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4092 offer_ip=`ip_to_hex 10 0 0 6`
4093 server_ip=`ip_to_hex 10 0 0 1`
4094 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4095 src_ip=$offer_ip
4096 dst_ip=$server_ip
4097 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4098
4099 # NXT_RESUMEs should be 4.
4100 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4101
4102 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4103 cat 2.expected | cut -c -48 > expout
4104 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4105 # Skipping the IPv4 checksum.
4106 cat 2.expected | cut -c 53- > expout
4107 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4108
4109 reset_pcap_file hv1-vif1 hv1/vif1
4110 reset_pcap_file hv1-vif2 hv1/vif2
4111 rm -f 1.expected
4112 rm -f 2.expected
4113
4114 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4115 offer_ip=`ip_to_hex 10 0 0 6`
4116 server_ip=`ip_to_hex 10 0 0 1`
4117 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4118 src_ip=$offer_ip
4119 dst_ip=`ip_to_hex 255 255 255 255`
4120 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4121
4122 # NXT_RESUMEs should be 5.
4123 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4124
4125 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4126 cat 2.expected | cut -c -48 > expout
4127 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4128 # Skipping the IPv4 checksum.
4129 cat 2.expected | cut -c 53- > expout
4130 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4131
4132 reset_pcap_file hv1-vif1 hv1/vif1
4133 reset_pcap_file hv1-vif2 hv1/vif2
4134 rm -f 1.expected
4135 rm -f 2.expected
4136
4137 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4138 # The packet should not be received by ovn-controller.
4139 src_ip=`ip_to_hex 10 0 0 6`
4140 dst_ip=`ip_to_hex 10 0 0 4`
4141 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4142
4143 # NXT_RESUMEs should be 5.
4144 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4145
4146 # vif1-tx.pcap should have received the DHCPv4 request packet
4147 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4148
4149 as hv1
4150 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4151 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4152 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4153
4154 as ovn-sb
4155 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4156
4157 as ovn-nb
4158 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4159
4160 as northd
4161 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4162
4163 as main
4164 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4165 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4166
4167 AT_CLEANUP
4168
4169 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4170 AT_SKIP_IF([test $HAVE_PYTHON = no])
4171 ovn_start
4172
4173 ovn-nbctl ls-add ls1
4174 ovn-nbctl lsp-add ls1 ls1-lp1 \
4175 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4176
4177 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4178
4179 ovn-nbctl lsp-add ls1 ls1-lp2 \
4180 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4181
4182 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4183
4184 ovn-nbctl lsp-add ls1 ls1-lp3 \
4185 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4186
4187 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4188
4189 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4190 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4191
4192 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4193 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4194
4195 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4196 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4197
4198 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4199
4200 ovn-nbctl ls-add ls2
4201 ovn-nbctl lsp-add ls2 ls2-lp1 \
4202 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4203 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4204 ovn-nbctl lsp-add ls2 ls2-lp2 \
4205 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4206 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4207
4208 net_add n1
4209 sim_add hv1
4210
4211 as hv1
4212 ovs-vsctl add-br br-phys
4213 ovn_attach n1 br-phys 192.168.0.1
4214 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4215 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4216 options:tx_pcap=hv1/vif1-tx.pcap \
4217 options:rxq_pcap=hv1/vif1-rx.pcap \
4218 ofport-request=1
4219
4220 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4221 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4222 options:tx_pcap=hv1/vif2-tx.pcap \
4223 options:rxq_pcap=hv1/vif2-rx.pcap \
4224 ofport-request=2
4225
4226 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4227 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4228 options:tx_pcap=hv1/vif3-tx.pcap \
4229 options:rxq_pcap=hv1/vif3-rx.pcap \
4230 ofport-request=3
4231
4232 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4233 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4234 options:tx_pcap=hv1/vif4-tx.pcap \
4235 options:rxq_pcap=hv1/vif4-rx.pcap \
4236 ofport-request=4
4237
4238 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4239 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4240 options:tx_pcap=hv1/vif5-tx.pcap \
4241 options:rxq_pcap=hv1/vif5-rx.pcap \
4242 ofport-request=5
4243
4244 OVN_POPULATE_ARP
4245
4246 sleep 2
4247
4248 trim_zeros() {
4249 sed 's/\(00\)\{1,\}$//'
4250 }
4251
4252 # This shell function sends a DHCPv6 request packet
4253 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4254 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4255 # packet should be received twice (one from ovn-controller and the other
4256 # from the "ovs-ofctl monitor br-int resume"
4257 test_dhcpv6() {
4258 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4259 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4260 # dst ip ff02::1:2
4261 request=${request}ff020000000000000000000000010002
4262 # udp header and dhcpv6 header
4263 request=${request}02220223002affff${msg_code}010203
4264 # Client identifier
4265 request=${request}0001000a00030001${src_mac}
4266 # IA-NA (Identity Association for Non Temporary Address)
4267 request=${request}0003000c0102030400000e1000001518
4268 shift; shift; shift; shift; shift;
4269 if test $offer_ip != 0; then
4270 local server_mac=000000100001
4271 local server_lla=fe80000000000000020000fffe100001
4272 local reply_code=07
4273 if test $msg_code = 01; then
4274 reply_code=02
4275 fi
4276 local msg_len=54
4277 if test $offer_ip = 1; then
4278 msg_len=28
4279 fi
4280 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4281 # udp header and dhcpv6 header
4282 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4283 # Client identifier
4284 reply=${reply}0001000a00030001${src_mac}
4285 # IA-NA
4286 if test $offer_ip != 1; then
4287 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4288 fi
4289 # Server identifier
4290 reply=${reply}0002000a00030001${server_mac}
4291 echo $reply | trim_zeros >> $inport.expected
4292 else
4293 for outport; do
4294 echo $request | trim_zeros >> $outport.expected
4295 done
4296 fi
4297
4298 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4299 }
4300
4301 reset_pcap_file() {
4302 local iface=$1
4303 local pcap_file=$2
4304 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4305 options:rxq_pcap=dummy-rx.pcap
4306 rm -f ${pcap_file}*.pcap
4307 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4308 options:rxq_pcap=${pcap_file}-rx.pcap
4309 }
4310
4311 AT_CAPTURE_FILE([ofctl_monitor0.log])
4312 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4313 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4314
4315 echo "---------NB dump-----"
4316 ovn-nbctl show
4317 echo "---------------------"
4318 echo "---------SB dump-----"
4319 ovn-sbctl list datapath_binding
4320 echo "---------------------"
4321 ovn-sbctl list logical_flow
4322 echo "---------------------"
4323
4324 echo "---------------------"
4325 ovn-sbctl dump-flows
4326 echo "---------------------"
4327
4328 echo "------ hv1 dump ----------"
4329 as hv1 ovs-ofctl dump-flows br-int
4330
4331 src_mac=f00000000001
4332 src_lla=fe80000000000000f20000fffe000001
4333 offer_ip=ae700000000000000000000000000004
4334 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4335
4336 # NXT_RESUMEs should be 1.
4337 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4338
4339 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4340 # cat 1.expected | trim_zeros > expout
4341 cat 1.expected | cut -c -120 > expout
4342 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4343 # Skipping the UDP checksum
4344 cat 1.expected | cut -c 125- > expout
4345 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4346
4347 rm 1.expected
4348
4349 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4350 # without any modifications and the packet should be received by ls1-lp1.
4351 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4352 # resume and the other from ovs-ofctl monitor resume.
4353
4354 reset_pcap_file hv1-vif1 hv1/vif1
4355 reset_pcap_file hv1-vif2 hv1/vif2
4356
4357 src_mac=f00000000002
4358 src_lla=fe80000000000000f20000fffe000002
4359 offer_ip=ae700000000000000000000000000005
4360 # Set invalid msg_type
4361
4362 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4363
4364 # NXT_RESUMEs should be 2.
4365 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4366
4367 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4368 rm 2.packets
4369 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4370 AT_CHECK([cat 2.packets], [0], [])
4371
4372 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4373 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4374 cat 1.expected > expout
4375 AT_CHECK([cat 1.packets], [0], [expout])
4376
4377 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4378 # There should be no DHCPv6 reply from ovn-controller and the request packet
4379 # should be received by ls2-lp2.
4380
4381 src_mac=f00000000003
4382 src_lla=fe80000000000000f20000fffe000003
4383 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4384
4385 # NXT_RESUMEs should be 2 only.
4386 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4387
4388 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4389 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4390 AT_CHECK([cat 3.packets], [0], [])
4391
4392 # vif4-tx.pcap should have received the DHCPv6 request packet
4393 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4394 cat 4.expected > expout
4395 AT_CHECK([cat 4.packets], [0], [expout])
4396
4397 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4398 # The DHCPv6 reply should doesn't contian offer_ip.
4399 src_mac=f00000000022
4400 src_lla=fe80000000000000f20000fffe000022
4401 reset_pcap_file hv1-vif5 hv1/vif5
4402 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4403
4404 # NXT_RESUMEs should be 3.
4405 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4406
4407 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4408 # Skipping the UDP checksum
4409 cat 5.expected | cut -c 1-120,125- > expout
4410 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4411
4412 as hv1
4413 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4414 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4415 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4416
4417 as ovn-sb
4418 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4419
4420 as ovn-nb
4421 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4422
4423 as northd
4424 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4425
4426 as main
4427 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4428 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4429
4430 AT_CLEANUP
4431
4432 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4433 AT_SKIP_IF([test $HAVE_PYTHON = no])
4434 ovn_start
4435
4436 # Logical network:
4437 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4438 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4439 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4440 # R2 is a gateway router.
4441
4442
4443
4444 # Create two hypervisor and create OVS ports corresponding to logical ports.
4445 net_add n1
4446
4447 sim_add hv1
4448 as hv1
4449 ovs-vsctl add-br br-phys
4450 ovn_attach n1 br-phys 192.168.0.1
4451 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4452 set interface hv1-vif1 external-ids:iface-id=foo1 \
4453 options:tx_pcap=hv1/vif1-tx.pcap \
4454 options:rxq_pcap=hv1/vif1-rx.pcap \
4455 ofport-request=1
4456
4457
4458 sim_add hv2
4459 as hv2
4460 ovs-vsctl add-br br-phys
4461 ovn_attach n1 br-phys 192.168.0.2
4462 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4463 set interface hv2-vif1 external-ids:iface-id=alice1 \
4464 options:tx_pcap=hv2/vif1-tx.pcap \
4465 options:rxq_pcap=hv2/vif1-rx.pcap \
4466 ofport-request=1
4467
4468 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4469 # packets for ARP resolution (native tunneling doesn't queue packets
4470 # for ARP resolution).
4471 OVN_POPULATE_ARP
4472
4473 ovn-nbctl create Logical_Router name=R1
4474 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4475
4476 ovn-nbctl ls-add foo
4477 ovn-nbctl ls-add alice
4478 ovn-nbctl ls-add join
4479
4480 # Connect foo to R1
4481 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4482 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4483 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4484
4485 # Connect alice to R2
4486 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4487 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4488 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4489
4490 # Connect R1 to join
4491 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4492 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4493 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4494
4495 # Connect R2 to join
4496 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4497 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4498 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4499
4500
4501 #install static routes
4502 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4503 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4504 R1 static_routes @lrt
4505
4506 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4507 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4508 R2 static_routes @lrt
4509
4510 # Create logical port foo1 in foo
4511 ovn-nbctl lsp-add foo foo1 \
4512 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4513
4514 # Create logical port alice1 in alice
4515 ovn-nbctl lsp-add alice alice1 \
4516 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4517
4518
4519 # Allow some time for ovn-northd and ovn-controller to catch up.
4520 # XXX This should be more systematic.
4521 sleep 2
4522
4523 ip_to_hex() {
4524 printf "%02x%02x%02x%02x" "$@"
4525 }
4526
4527 # Send ip packets between foo1 and alice1
4528 src_mac="f00000010203"
4529 dst_mac="000001010203"
4530 src_ip=`ip_to_hex 192 168 1 2`
4531 dst_ip=`ip_to_hex 172 16 1 2`
4532 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4533
4534 echo "---------NB dump-----"
4535 ovn-nbctl show
4536 echo "---------------------"
4537 ovn-nbctl list logical_router
4538 echo "---------------------"
4539 ovn-nbctl list logical_router_port
4540 echo "---------------------"
4541
4542 echo "---------SB dump-----"
4543 ovn-sbctl list datapath_binding
4544 echo "---------------------"
4545 ovn-sbctl list port_binding
4546 echo "---------------------"
4547 ovn-sbctl dump-flows
4548 echo "---------------------"
4549 ovn-sbctl list chassis
4550 ovn-sbctl list encap
4551 echo "---------------------"
4552
4553 # Packet to Expect at alice1
4554 src_mac="000002010203"
4555 dst_mac="f00000010204"
4556 src_ip=`ip_to_hex 192 168 1 2`
4557 dst_ip=`ip_to_hex 172 16 1 2`
4558 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4559
4560
4561 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4562 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4563
4564 echo "------ hv1 dump after packet 1 ----------"
4565 as hv1 ovs-ofctl show br-int
4566 as hv1 ovs-ofctl dump-flows br-int
4567 echo "------ hv2 dump after packet 1 ----------"
4568 as hv2 ovs-ofctl show br-int
4569 as hv2 ovs-ofctl dump-flows br-int
4570 echo "----------------------------"
4571
4572 echo $expected > expected
4573 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4574
4575 # Delete the router and re-create it. Things should work as before.
4576 ovn-nbctl lr-del R2
4577 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4578 # Connect alice to R2
4579 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4580 # Connect R2 to join
4581 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4582
4583 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4584 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4585 R2 static_routes @lrt
4586
4587 # Wait for ovn-controller to catch up.
4588 sleep 1
4589
4590 # Send the packet again.
4591 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4592
4593 echo "------ hv1 dump after packet 2 ----------"
4594 as hv1 ovs-ofctl show br-int
4595 as hv1 ovs-ofctl dump-flows br-int
4596 echo "------ hv2 dump after packet 2 ----------"
4597 as hv2 ovs-ofctl show br-int
4598 as hv2 ovs-ofctl dump-flows br-int
4599 echo "----------------------------"
4600
4601 echo $expected >> expected
4602 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4603
4604 OVN_CLEANUP([hv1],[hv2])
4605
4606 AT_CLEANUP
4607
4608 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4609 AT_KEYWORDS([router-icmp-reply])
4610 AT_SKIP_IF([test $HAVE_PYTHON = no])
4611 ovn_start
4612
4613 # Logical network:
4614 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4615 # and has switch ls2 (172.16.1.0/24) connected to it.
4616
4617 ovn-nbctl lr-add R1
4618
4619 ovn-nbctl ls-add ls1
4620 ovn-nbctl ls-add ls2
4621
4622 # Connect ls1 to R1
4623 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4624 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4625 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4626
4627 # Connect ls2 to R1
4628 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4629 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4630 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4631
4632 # Create logical port ls1-lp1 in ls1
4633 ovn-nbctl lsp-add ls1 ls1-lp1 \
4634 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4635
4636 # Create logical port ls2-lp1 in ls2
4637 ovn-nbctl lsp-add ls2 ls2-lp1 \
4638 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4639
4640 # Create one hypervisor and create OVS ports corresponding to logical ports.
4641 net_add n1
4642
4643 sim_add hv1
4644 as hv1
4645 ovs-vsctl add-br br-phys
4646 ovn_attach n1 br-phys 192.168.0.1
4647 ovs-vsctl -- add-port br-int vif1 -- \
4648 set interface vif1 external-ids:iface-id=ls1-lp1 \
4649 options:tx_pcap=hv1/vif1-tx.pcap \
4650 options:rxq_pcap=hv1/vif1-rx.pcap \
4651 ofport-request=1
4652
4653 ovs-vsctl -- add-port br-int vif2 -- \
4654 set interface vif2 external-ids:iface-id=ls2-lp1 \
4655 options:tx_pcap=hv1/vif2-tx.pcap \
4656 options:rxq_pcap=hv1/vif2-rx.pcap \
4657 ofport-request=1
4658
4659
4660 # Allow some time for ovn-northd and ovn-controller to catch up.
4661 # XXX This should be more systematic.
4662 sleep 1
4663
4664
4665 ip_to_hex() {
4666 printf "%02x%02x%02x%02x" "$@"
4667 }
4668 for i in 1 2; do
4669 : > vif$i.expected
4670 done
4671 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4672 #
4673 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4674 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4675 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4676 # provided, then it should be the ip and icmp checksums of the packet
4677 # responded; otherwise, no reply is expected.
4678 # In the absence of an ip checksum calculation helpers, this relies
4679 # on the caller to provide the checksums for the ip and icmp headers.
4680 # XXX This should be more systematic.
4681 #
4682 # INPORT is an lport number, e.g. 11 for vif11.
4683 # ETH_SRC and ETH_DST are each 12 hex digits.
4684 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4685 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4686 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4687 test_ipv4_icmp_request() {
4688 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4689 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4690 shift; shift; shift; shift; shift; shift; shift
4691 shift; shift
4692
4693 # Use ttl to exercise section 4.2.2.9 of RFC1812
4694 local ip_ttl=01
4695 local icmp_id=5fbf
4696 local icmp_seq=0001
4697 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4698 local icmp_type_code_request=0800
4699 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4700 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4701
4702 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4703 if test X$exp_icmp_chksum != X; then
4704 # Expect to receive the reply, if any. In same port where packet was sent.
4705 # Note: src and dst fields are expected to be reversed.
4706 local icmp_type_code_response=0000
4707 local reply_icmp_ttl=fe
4708 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4709 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4710 echo $reply >> vif$inport.expected
4711 fi
4712 }
4713
4714 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4715 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4716 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4717 l1_ip=$(ip_to_hex 192 168 1 2)
4718 l2_ip=$(ip_to_hex 172 16 1 2)
4719
4720 # Ping router ip address that is on same subnet as the logical port
4721 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4722 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4723
4724 # Ping router ip address that is on the other side of the logical ports
4725 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4726 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4727
4728 echo "---------NB dump-----"
4729 ovn-nbctl show
4730 echo "---------------------"
4731 ovn-nbctl list logical_router
4732 echo "---------------------"
4733 ovn-nbctl list logical_router_port
4734 echo "---------------------"
4735
4736 echo "---------SB dump-----"
4737 ovn-sbctl list datapath_binding
4738 echo "---------------------"
4739 ovn-sbctl list logical_flow
4740 echo "---------------------"
4741
4742 echo "------ hv1 dump ----------"
4743 as hv1 ovs-ofctl dump-flows br-int
4744
4745 # Now check the packets actually received against the ones expected.
4746 for inport in 1 2; do
4747 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4748 done
4749
4750 OVN_CLEANUP([hv1])
4751
4752 AT_CLEANUP
4753
4754 # 1 hypervisor, 1 port
4755 # make sure that the port state is properly set to up and back down
4756 # when created and deleted.
4757 AT_SETUP([ovn -- port state up and down])
4758 ovn_start
4759
4760 ovn-nbctl ls-add ls1
4761 ovn-nbctl lsp-add ls1 lp1
4762 ovn-nbctl lsp-set-addresses lp1 unknown
4763
4764 net_add n1
4765 sim_add hv1
4766 as hv1 ovs-vsctl add-br br-phys
4767 as hv1 ovn_attach n1 br-phys 192.168.0.1
4768
4769 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4770 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4771
4772 as hv1 ovs-vsctl del-port br-int vif1
4773 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4774
4775 OVN_CLEANUP([hv1])
4776
4777 AT_CLEANUP
4778
4779 # 1 hypervisor, 1 port
4780 # make sure that the OF rules created to support a datapath are added/cleared
4781 # when logical switch is created and removed.
4782 AT_SETUP([ovn -- datapath rules added/removed])
4783 AT_KEYWORDS([cleanup])
4784 ovn_start
4785
4786 net_add n1
4787 sim_add hv1
4788 as hv1 ovs-vsctl add-br br-phys
4789 as hv1 ovn_attach n1 br-phys 192.168.0.1
4790
4791 # This shell function checks if OF rules in br-int have clauses
4792 # related to OVN datapaths. The caller determines if it should find
4793 # a match in the output, or not.
4794 #
4795 # EXPECT_DATAPATH param determines whether flows that refer to
4796 # datapath to should be present or not. 0 means
4797 # they should not be.
4798 # STAGE_INFO param is a simple string to help identify the stage
4799 # in the test when this function was invoked.
4800 test_datapath_in_of_rules() {
4801 local expect_datapath=$1 stage_info=$2
4802 echo "------ ovn-nbctl show ${stage_info} ------"
4803 ovn-nbctl show
4804 echo "------ ovn-sbctl show ${stage_info} ------"
4805 ovn-sbctl show
4806 echo "------ OF rules ${stage_info} ------"
4807 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4808 # if there is a datapath mentioned in the output, check for the
4809 # magic keyword that represents one, based on the exit status of
4810 # a quiet grep
4811 if test $expect_datapath != 0; then
4812 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4813 else
4814 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4815 fi
4816 }
4817
4818 test_datapath_in_of_rules 0 "before ls+port create"
4819
4820 ovn-nbctl ls-add ls1
4821 ovn-nbctl lsp-add ls1 lp1
4822 ovn-nbctl lsp-set-addresses lp1 unknown
4823
4824 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4825 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4826
4827 test_datapath_in_of_rules 1 "after port is bound"
4828
4829 as hv1 ovs-vsctl del-port br-int vif1
4830 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4831
4832 ovn-nbctl lsp-set-addresses lp1
4833 ovn-nbctl lsp-del lp1
4834 ovn-nbctl ls-del ls1
4835
4836 # wait for earlier changes to take effect
4837 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4838
4839 # ensure OF rules are no longer present. There used to be a bug here.
4840 test_datapath_in_of_rules 0 "after lport+ls removal"
4841
4842 OVN_CLEANUP([hv1])
4843
4844 AT_CLEANUP
4845
4846 AT_SETUP([ovn -- nd_na ])
4847 AT_SKIP_IF([test $HAVE_PYTHON = no])
4848 ovn_start
4849
4850 #TODO: since patch port for IPv6 logical router port is not ready not,
4851 # so we are not going to test vifs on different lswitches cases. Try
4852 # to update for that once relevant stuff implemented.
4853
4854 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4855 # with. NS packet we test, from one VIF for another VIF, will be replied
4856 # by local ovn-controller, but not by target VIF.
4857
4858 # Create hypervisors and logical switch lsw0.
4859 ovn-nbctl ls-add lsw0
4860 net_add n1
4861 sim_add hv1
4862 as hv1
4863 ovs-vsctl add-br br-phys
4864 ovn_attach n1 br-phys 192.168.0.2
4865
4866 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4867 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
4868 ovn-nbctl lsp-add lsw0 lp1
4869 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4870 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"
4871
4872 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4873 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
4874 ovn-nbctl lsp-add lsw0 lp2
4875 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4876 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"
4877
4878 # Add ACL rule for ICMPv6 on lsw0
4879 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4880 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4881 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4882
4883 # Allow some time for ovn-northd and ovn-controller to catch up.
4884 # XXX This should be more systematic.
4885 sleep 1
4886
4887 # Given the name of a logical port, prints the name of the hypervisor
4888 # on which it is located.
4889 vif_to_hv() {
4890 echo hv1${1%?}
4891 }
4892 for i in 1 2; do
4893 : > $i.expected
4894 done
4895
4896 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4897 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4898 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4899 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4900 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4901
4902 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4903 echo $na_packet >> 1.expected
4904
4905 echo "------ hv1 dump ------"
4906 as hv1 ovs-vsctl show
4907 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4908 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4909
4910 for i in 1 2; do
4911 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4912 done
4913
4914 OVN_CLEANUP([hv1])
4915
4916 AT_CLEANUP
4917
4918 AT_SETUP([ovn -- address sets modification/removal smoke test])
4919 ovn_start
4920
4921 net_add n1
4922
4923 sim_add hv1
4924 as hv1
4925 ovs-vsctl add-br br-phys
4926 ovn_attach n1 br-phys 192.168.0.1
4927
4928 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4929 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4930 ovn-nbctl destroy Address_Set $row
4931
4932 sleep 1
4933
4934 # A bug previously existed in the address set support code
4935 # that caused ovn-controller to crash after an address set
4936 # was updated and then removed. This test case ensures
4937 # that ovn-controller is at least still running after
4938 # creating, updating, and deleting an address set.
4939 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4940
4941 OVN_CLEANUP([hv1])
4942
4943 AT_CLEANUP
4944
4945 AT_SETUP([ovn -- ipam])
4946 AT_SKIP_IF([test $HAVE_PYTHON = no])
4947 ovn_start
4948
4949 # Add a port to a switch that does not have a subnet set, then set the
4950 # subnet which should result in an address being allocated for the port.
4951 ovn-nbctl ls-add sw0
4952 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4953 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4954 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4955 ["0a:00:00:00:00:01 192.168.1.2"
4956 ])
4957
4958 # Add 9 more ports to sw0, addresses should all be unique.
4959 for n in `seq 1 9`; do
4960 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4961 done
4962 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4963 ["0a:00:00:00:00:02 192.168.1.3"
4964 ])
4965 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4966 ["0a:00:00:00:00:03 192.168.1.4"
4967 ])
4968 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4969 ["0a:00:00:00:00:04 192.168.1.5"
4970 ])
4971 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4972 ["0a:00:00:00:00:05 192.168.1.6"
4973 ])
4974 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4975 ["0a:00:00:00:00:06 192.168.1.7"
4976 ])
4977 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4978 ["0a:00:00:00:00:07 192.168.1.8"
4979 ])
4980 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4981 ["0a:00:00:00:00:08 192.168.1.9"
4982 ])
4983 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4984 ["0a:00:00:00:00:09 192.168.1.10"
4985 ])
4986 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4987 ["0a:00:00:00:00:0a 192.168.1.11"
4988 ])
4989
4990 # Trying similar tests with a second switch. MAC addresses should be unique
4991 # across both switches but IP's only need to be unique within the same switch.
4992 ovn-nbctl ls-add sw1
4993 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4994 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4995 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4996 ["0a:00:00:00:00:0b 192.168.1.2"
4997 ])
4998
4999 for n in `seq 11 19`; do
5000 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
5001 done
5002 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5003 ["0a:00:00:00:00:0c 192.168.1.3"
5004 ])
5005 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5006 ["0a:00:00:00:00:0d 192.168.1.4"
5007 ])
5008 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5009 ["0a:00:00:00:00:0e 192.168.1.5"
5010 ])
5011 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5012 ["0a:00:00:00:00:0f 192.168.1.6"
5013 ])
5014 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5015 ["0a:00:00:00:00:10 192.168.1.7"
5016 ])
5017 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5018 ["0a:00:00:00:00:11 192.168.1.8"
5019 ])
5020 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5021 ["0a:00:00:00:00:12 192.168.1.9"
5022 ])
5023 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5024 ["0a:00:00:00:00:13 192.168.1.10"
5025 ])
5026 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5027 ["0a:00:00:00:00:14 192.168.1.11"
5028 ])
5029
5030 # Change a port's address to test for multiple ip's for a single address entry
5031 # and addresses set by the user.
5032 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
5033 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
5034 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5035 ["0a:00:00:00:00:16 192.168.1.13"
5036 ])
5037
5038 # Test for logical router port address management.
5039 ovn-nbctl create Logical_Router name=R1
5040 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5041 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5042 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5043 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
5044 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
5045 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5046 ["0a:00:00:00:00:18 192.168.1.15"
5047 ])
5048
5049 # Test for address reuse after logical port is deleted.
5050 ovn-nbctl lsp-del p0
5051 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
5052 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5053 ["0a:00:00:00:00:19 192.168.1.2"
5054 ])
5055
5056 # Test for multiple addresses to one logical port.
5057 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5058 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
5059 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
5060 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5061 ["0a:00:00:00:00:1c 192.168.1.16"
5062 ])
5063
5064 # Test for exhausting subnet address space.
5065 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
5066 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
5067 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5068 ["0a:00:00:00:00:1d 172.16.1.2"
5069 ])
5070
5071 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
5072 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
5073 ["0a:00:00:00:00:1e"
5074 ])
5075
5076 # Test that address management does not add duplicate MAC for lsp/lrp peers.
5077 ovn-nbctl create Logical_Router name=R2
5078 ovn-nbctl ls-add sw3
5079 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
5080 "0a:00:00:00:00:1f"
5081 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5082 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5083 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5084 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
5085 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
5086 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5087 ["0a:00:00:00:00:20 192.168.1.17"
5088 ])
5089
5090 # Test static MAC address with dynamically allocated IP
5091 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5092 "fe:dc:ba:98:76:54 dynamic"
5093 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5094 ["fe:dc:ba:98:76:54 192.168.1.18"
5095 ])
5096
5097 # Update the static MAC address with dynamically allocated IP and check
5098 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5099 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5100 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5101
5102 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5103 ["fe:dc:ba:98:76:55 192.168.1.18"
5104 ])
5105
5106 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5107 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5108 ["fe:dc:ba:98:76:55 192.168.1.18"
5109 ])
5110
5111 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5112 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5113 ["fe:dc:ba:98:76:56 192.168.1.18"
5114 ])
5115
5116
5117 # Test the exclude_ips from the IPAM list
5118 ovn-nbctl --wait=sb set logical_switch sw0 \
5119 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5120
5121 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5122 "dynamic"
5123 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5124 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5125 ["0a:00:00:00:00:21 192.168.1.20"
5126 ])
5127
5128 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5129 "dynamic"
5130 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5131 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5132 ["0a:00:00:00:00:22 192.168.1.22"
5133 ])
5134
5135 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5136 "dynamic"
5137 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5138 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5139 ["0a:00:00:00:00:23 192.168.1.51"
5140 ])
5141
5142 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5143 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5144 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5145 "dynamic"
5146 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5147 ["0a:00:00:00:00:24 192.168.1.19"
5148 ])
5149
5150 # Set invalid data in exclude_ips list. It should be ignored.
5151 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5152 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5153 "dynamic"
5154 # 192.168.1.21 should be assigned as that's the next free one.
5155 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5156 ["0a:00:00:00:00:25 192.168.1.21"
5157 ])
5158
5159 # Clear the dynamic addresses assignment request.
5160 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5161 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5162 [[[]]
5163 ])
5164
5165 # Set IPv6 prefix
5166 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5167 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5168 "dynamic"
5169
5170 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5171 # - aef0::800:ff:fe00:26 (EUI64)
5172 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5173 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5174 ])
5175
5176 ovn-nbctl --wait=sb ls-add sw4
5177 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5178 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5179 "dynamic"
5180
5181 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5182 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5183 ])
5184
5185 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5186 "f0:00:00:00:10:12 dynamic"
5187
5188 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5189 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5190 ])
5191
5192 # Clear the other_config for sw4. No dynamic ip should be assigned.
5193 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5194 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5195 "dynamic"
5196
5197 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5198 [[[]]
5199 ])
5200
5201 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5202 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5203 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5204
5205 # Now p40 should be assigned with dynamic addresses.
5206 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5207 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5208 ])
5209
5210 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5211 "dynamic"
5212 # p41 should not have IPv4 address (as the pool is exhausted).
5213 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5214 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5215 ])
5216
5217 as ovn-sb
5218 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5219
5220 as ovn-nb
5221 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5222
5223 as northd
5224 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5225
5226 AT_CLEANUP
5227
5228 AT_SETUP([ovn -- ipam connectivity])
5229 AT_SKIP_IF([test $HAVE_PYTHON = no])
5230 ovn_start
5231
5232 ovn-nbctl lr-add R1
5233
5234 # Test for a ping using dynamically allocated addresses.
5235 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5236 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5237
5238 # Connect foo to R1
5239 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5240 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5241 options:router-port=foo \
5242 -- lsp-set-addresses rp-foo router
5243
5244 # Connect alice to R1
5245 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5246 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5247 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5248
5249 # Create logical port foo1 in foo
5250 ovn-nbctl --wait=sb lsp-add foo foo1 \
5251 -- lsp-set-addresses foo1 "dynamic"
5252 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:00:00:01 192.168.1.2"'], [0])
5253
5254 # Create logical port alice1 in alice
5255 ovn-nbctl --wait=sb lsp-add alice alice1 \
5256 -- lsp-set-addresses alice1 "dynamic"
5257 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5258
5259 # Create logical port foo2 in foo
5260 ovn-nbctl --wait=sb lsp-add foo foo2 \
5261 -- lsp-set-addresses foo2 "dynamic"
5262 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5263
5264 # Create a hypervisor and create OVS ports corresponding to logical ports.
5265 net_add n1
5266
5267 sim_add hv1
5268 as hv1
5269 ovs-vsctl add-br br-phys
5270 ovn_attach n1 br-phys 192.168.0.1
5271 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5272 set interface hv1-vif1 external-ids:iface-id=foo1 \
5273 options:tx_pcap=hv1/vif1-tx.pcap \
5274 options:rxq_pcap=hv1/vif1-rx.pcap \
5275 ofport-request=1
5276
5277 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5278 set interface hv1-vif2 external-ids:iface-id=foo2 \
5279 options:tx_pcap=hv1/vif2-tx.pcap \
5280 options:rxq_pcap=hv1/vif2-rx.pcap \
5281 ofport-request=2
5282
5283 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5284 set interface hv1-vif3 external-ids:iface-id=alice1 \
5285 options:tx_pcap=hv1/vif3-tx.pcap \
5286 options:rxq_pcap=hv1/vif3-rx.pcap \
5287 ofport-request=3
5288
5289 # Allow some time for ovn-northd and ovn-controller to catch up.
5290 # XXX This should be more systematic.
5291 sleep 1
5292
5293 ip_to_hex() {
5294 printf "%02x%02x%02x%02x" "$@"
5295 }
5296
5297 # Send ip packets between foo1 and foo2
5298 src_mac="0a0000000001"
5299 dst_mac="0a0000000003"
5300 src_ip=`ip_to_hex 192 168 1 2`
5301 dst_ip=`ip_to_hex 192 168 1 3`
5302 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5303 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5304
5305 # Send ip packets between foo1 and alice1
5306 src_mac="0a0000000001"
5307 dst_mac="000000010203"
5308 src_ip=`ip_to_hex 192 168 1 2`
5309 dst_ip=`ip_to_hex 192 168 2 2`
5310 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5311 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5312
5313 echo "---------NB dump-----"
5314 ovn-nbctl show
5315 echo "---------------------"
5316 ovn-nbctl list logical_router
5317 echo "---------------------"
5318 ovn-nbctl list logical_router_port
5319 echo "---------------------"
5320
5321 echo "---------SB dump-----"
5322 ovn-sbctl list datapath_binding
5323 echo "---------------------"
5324 ovn-sbctl list port_binding
5325 echo "---------------------"
5326
5327 echo "------ hv1 dump ----------"
5328 as hv1 ovs-ofctl dump-flows br-int
5329
5330 # Packet to Expect at foo2
5331 src_mac="0a0000000001"
5332 dst_mac="0a0000000003"
5333 src_ip=`ip_to_hex 192 168 1 2`
5334 dst_ip=`ip_to_hex 192 168 1 3`
5335 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5336
5337 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5338 echo $expected > expout
5339 AT_CHECK([cat received1.packets], [0], [expout])
5340
5341 # Packet to Expect at alice1
5342 src_mac="000000010204"
5343 dst_mac="0a0000000002"
5344 src_ip=`ip_to_hex 192 168 1 2`
5345 dst_ip=`ip_to_hex 192 168 2 2`
5346 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5347
5348 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5349 echo $expected > expout
5350 AT_CHECK([cat received2.packets], [0], [expout])
5351
5352 OVN_CLEANUP([hv1])
5353
5354 AT_CLEANUP
5355
5356 AT_SETUP([ovn -- ovs-vswitchd restart])
5357 AT_KEYWORDS([vswitchd])
5358 AT_SKIP_IF([test $HAVE_PYTHON = no])
5359 ovn_start
5360
5361 ovn-nbctl ls-add ls1
5362
5363 ovn-nbctl lsp-add ls1 ls1-lp1 \
5364 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5365
5366 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5367
5368 net_add n1
5369 sim_add hv1
5370
5371 as hv1
5372 ovs-vsctl add-br br-phys
5373 ovn_attach n1 br-phys 192.168.0.1
5374 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5375 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5376 options:tx_pcap=hv1/vif1-tx.pcap \
5377 options:rxq_pcap=hv1/vif1-rx.pcap \
5378 ofport-request=1
5379
5380 OVN_POPULATE_ARP
5381 sleep 2
5382
5383 as hv1 ovs-vsctl show
5384
5385 echo "---------------------"
5386 ovn-sbctl dump-flows
5387 echo "---------------------"
5388
5389 echo "------ hv1 dump ----------"
5390 as hv1 ovs-ofctl dump-flows br-int
5391 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5392
5393 echo "Total flows before vswitchd restart = " $total_flows
5394
5395 # Code taken from ovs-save utility
5396 save_flows () {
5397 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5398 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5399 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5400 echo "EOF" >> restore_flows.sh
5401 }
5402
5403 restart_vswitchd () {
5404 restore_flows=$1
5405
5406 if test $restore_flows = true; then
5407 save_flows
5408 fi
5409
5410 as hv1
5411 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5412
5413 if test $restore_flows = true; then
5414 as hv1
5415 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5416 fi
5417
5418 as hv1
5419 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5420 ovs-ofctl dump-flows br-int
5421
5422 if test $restore_flows = true; then
5423 sh ./restore_flows.sh
5424 echo "Flows after restore"
5425 as hv1
5426 ovs-ofctl dump-flows br-int
5427 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5428 flow-restore-wait="true"
5429 fi
5430 }
5431
5432 # Save the flows, restart vswitchd and restore the flows
5433 restart_vswitchd true
5434 OVS_WAIT_UNTIL([
5435 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5436 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5437 test "${total_flows}" = "${total_flows_after_restart}"
5438 ])
5439
5440 # Restart vswitchd without restoring
5441 restart_vswitchd false
5442 OVS_WAIT_UNTIL([
5443 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5444 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5445 test "${total_flows}" = "${total_flows_after_restart}"
5446 ])
5447
5448 OVN_CLEANUP([hv1])
5449 AT_CLEANUP
5450
5451 AT_SETUP([ovn -- send arp for nexthop])
5452 AT_SKIP_IF([test $HAVE_PYTHON = no])
5453 ovn_start
5454
5455 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5456
5457 # Create logical switches
5458 ovn-nbctl ls-add ls1
5459 ovn-nbctl ls-add ls2
5460
5461 # Create router
5462 ovn-nbctl create Logical_Router name=lr0
5463
5464 # Add router ls1p1 port to gateway router
5465 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5466 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5467 type=router options:router-port=lrp-ls1lp1 \
5468 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5469
5470 # Add router ls2p2 port to gateway router
5471 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5472 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5473 type=router options:router-port=lrp-ls2lp1 \
5474 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5475
5476 # Set default gateway (nexthop) to 192.168.1.254
5477 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5478
5479 # Create logical port ls1lp2 in ls1
5480 ovn-nbctl lsp-add ls1 ls1lp2 \
5481 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5482
5483 # Create logical port ls2lp2 in ls2
5484 ovn-nbctl lsp-add ls2 ls2lp2 \
5485 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5486
5487 net_add n1
5488 sim_add hv1
5489 as hv1
5490 ovs-vsctl add-br br-phys
5491 ovn_attach n1 br-phys 192.168.0.1
5492 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5493 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5494 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5495 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5496 ofport-request=1
5497 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5498 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5499 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5500 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5501 ofport-request=2
5502
5503 # Allow some time for ovn-northd and ovn-controller to catch up.
5504 # XXX This should be more systematic.
5505 sleep 1
5506
5507 echo "---------NB dump-----"
5508 ovn-nbctl show
5509 echo "---------------------"
5510 ovn-nbctl list logical_router
5511 echo "---------------------"
5512 ovn-nbctl list logical_router_port
5513 echo "---------------------"
5514
5515 echo "---------SB dump-----"
5516 ovn-sbctl list datapath_binding
5517 echo "---------------------"
5518 ovn-sbctl list port_binding
5519 echo "---------------------"
5520 ovn-sbctl dump-flows
5521 echo "---------------------"
5522 ovn-sbctl list chassis
5523 ovn-sbctl list encap
5524 echo "---------------------"
5525
5526 echo "------Flows dump-----"
5527 as hv1
5528 ovs-ofctl dump-flows
5529 echo "---------------------"
5530
5531 ip_to_hex() {
5532 printf "%02x%02x%02x%02x" "$@"
5533 }
5534
5535 src_mac="f00000000003"
5536 dst_mac="f00000000001"
5537 src_ip=`ip_to_hex 192 168 0 2`
5538 dst_ip=`ip_to_hex 8 8 8 8`
5539 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5540
5541 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5542 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5543
5544 trim_zeros() {
5545 sed 's/\(00\)\{1,\}$//'
5546 }
5547
5548 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5549 # not 8.8.8.8
5550
5551 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5552 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5553 echo $expected > expout
5554 AT_CHECK([cat packets], [0], [expout])
5555 cat packets
5556
5557 OVN_CLEANUP([hv1])
5558
5559 AT_CLEANUP
5560
5561 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5562 AT_SKIP_IF([test $HAVE_PYTHON = no])
5563 ovn_start
5564 # Create logical switch
5565 ovn-nbctl ls-add ls0
5566 # Create gateway router
5567 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5568 # Add router port to gateway router
5569 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5570 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5571 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5572 # Add nat-address option
5573 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5574
5575 net_add n1
5576 sim_add hv1
5577 as hv1
5578 ovs-vsctl \
5579 -- add-br br-phys \
5580 -- add-br br-eth0
5581
5582 ovn_attach n1 br-phys 192.168.0.1
5583
5584 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5585 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])
5586
5587 # Create a localnet port.
5588 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5589 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5590 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5591 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5592
5593
5594 # Wait for packet to be received.
5595 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5596 trim_zeros() {
5597 sed 's/\(00\)\{1,\}$//'
5598 }
5599 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5600 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5601 echo $expected > expout
5602 AT_CHECK([sort packets], [0], [expout])
5603 cat packets
5604
5605 OVN_CLEANUP([hv1])
5606
5607 AT_CLEANUP
5608
5609 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5610 AT_SKIP_IF([test $HAVE_PYTHON = no])
5611 ovn_start
5612 # Create logical switch
5613 ovn-nbctl ls-add ls0
5614 # Create gateway router
5615 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5616 # Add router port to gateway router
5617 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5618 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5619 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5620 # Add nat-address option
5621 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5622 # Add NAT rules
5623 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5624 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5625 # Add load balancers
5626 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5627 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5628 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5629 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5630
5631 net_add n1
5632 sim_add hv1
5633 as hv1
5634 ovs-vsctl \
5635 -- add-br br-phys \
5636 -- add-br br-eth0
5637
5638 ovn_attach n1 br-phys 192.168.0.1
5639
5640 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5641 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])
5642
5643 # Create a localnet port.
5644 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5645 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5646 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5647 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5648
5649
5650 # Wait for packet to be received.
5651 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5652 trim_zeros() {
5653 sed 's/\(00\)\{1,\}$//'
5654 }
5655 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5656 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5657 echo $expected > expout
5658 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5659 echo $expected >> expout
5660 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5661 echo $expected >> expout
5662 AT_CHECK([sort packets], [0], [expout])
5663 cat packets
5664
5665 OVN_CLEANUP([hv1])
5666
5667 AT_CLEANUP
5668
5669 AT_SETUP([ovn -- delete mac bindings])
5670 ovn_start
5671 net_add n1
5672 sim_add hv1
5673 as hv1
5674 ovs-vsctl -- add-br br-phys
5675 ovn_attach n1 br-phys 192.168.0.1
5676 # Create logical switch ls0
5677 ovn-nbctl ls-add ls0
5678 # Create ports lp0, lp1 in ls0
5679 ovn-nbctl lsp-add ls0 lp0
5680 ovn-nbctl lsp-add ls0 lp1
5681 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5682 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5683 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5684 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5685 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5686 ovn-sbctl find MAC_Binding
5687 # Delete port lp0 and check that its MAC_Binding is deleted.
5688 ovn-nbctl lsp-del lp0
5689 ovn-sbctl find MAC_Binding
5690 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5691 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5692 ovn-nbctl ls-del ls0
5693 ovn-sbctl find MAC_Binding
5694 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5695
5696 OVN_CLEANUP([hv1])
5697
5698 AT_CLEANUP
5699
5700 AT_SETUP([ovn -- conntrack zone allocation])
5701 AT_SKIP_IF([test $HAVE_PYTHON = no])
5702 ovn_start
5703
5704 # Logical network:
5705 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5706 # connected to a router R1.
5707 # foo has foo1 to act as a client.
5708 # bar has bar1, bar2, bar3 to act as servers.
5709
5710 net_add n1
5711
5712 sim_add hv1
5713 as hv1
5714 ovs-vsctl add-br br-phys
5715 ovn_attach n1 br-phys 192.168.0.1
5716 for i in foo1 bar1 bar2 bar3; do
5717 ovs-vsctl -- add-port br-int $i -- \
5718 set interface $i external-ids:iface-id=$i \
5719 options:tx_pcap=hv1/$i-tx.pcap \
5720 options:rxq_pcap=hv1/$i-rx.pcap
5721 done
5722
5723 ovn-nbctl create Logical_Router name=R1
5724 ovn-nbctl ls-add foo
5725 ovn-nbctl ls-add bar
5726
5727 # Connect foo to R1
5728 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5729 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5730 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5731
5732 # Connect bar to R1
5733 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5734 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5735 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5736
5737 # Create logical port foo1 in foo
5738 ovn-nbctl lsp-add foo foo1 \
5739 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5740
5741 # Create logical port bar1, bar2 and bar3 in bar
5742 for i in `seq 1 3`; do
5743 ip=`expr $i + 1`
5744 ovn-nbctl lsp-add bar bar$i \
5745 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5746 done
5747
5748 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5749
5750 OVN_CLEANUP([hv1])
5751
5752 AT_CLEANUP
5753
5754 AT_SETUP([ovn -- tag allocation])
5755 ovn_start
5756
5757 AT_CHECK([ovn-nbctl ls-add ls0])
5758 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5759 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5760 AT_CHECK([ovn-nbctl ls-add ls1])
5761
5762 dnl When a tag is provided, no allocation is done
5763 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5764 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5765 ])
5766 dnl The same 'tag' gets created in southbound database.
5767 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5768 logical_port="c0"], [0], [3
5769 ])
5770
5771 dnl Allocate tags and see it getting created in both NB and SB
5772 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5773 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5774 ])
5775 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5776 logical_port="c1"], [0], [1
5777 ])
5778
5779 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5780 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5781 ])
5782 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5783 logical_port="c2"], [0], [2
5784 ])
5785 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5786 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5787 ])
5788 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5789 logical_port="c3"], [0], [4
5790 ])
5791
5792 dnl A different parent.
5793 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5794 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5795 ])
5796 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5797 logical_port="c4"], [0], [1
5798 ])
5799
5800 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5801 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5802 ])
5803 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5804 logical_port="c5"], [0], [2
5805 ])
5806
5807 dnl Delete a logical port and create a new one.
5808 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5809 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5810 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5811 ])
5812 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5813 logical_port="c6"], [0], [1
5814 ])
5815
5816 dnl Restart northd to see that the same allocation remains.
5817 as northd
5818 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5819 start_daemon ovn-northd \
5820 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5821 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5822
5823 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5824 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5825 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5826 ])
5827 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5828 ])
5829 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5830 ])
5831 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5832 ])
5833 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5834 ])
5835 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5836 ])
5837
5838 dnl Create a switch port with a tag that has already been allocated.
5839 dnl It should go through fine with a duplicate tag.
5840 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5841 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5842 ])
5843 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5844 logical_port="c7"], [0], [2
5845 ])
5846 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5847 ])
5848
5849 AT_CHECK([ovn-nbctl ls-add ls2])
5850 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5851 dnl gets copied to 'tag'
5852 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5853 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5854 ])
5855 dnl The same 'tag' gets created in southbound database.
5856 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5857 logical_port="local0"], [0], [25
5858 ])
5859 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5860 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5861 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5862 dnl change the tag_request.
5863 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5864 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5865 ])
5866
5867 AT_CLEANUP
5868
5869 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5870 ovn_start
5871 ovn-nbctl ls-add lsw0
5872 net_add n1
5873 for i in 1 2; do
5874 sim_add hv$i
5875 as hv$i
5876 ovs-vsctl add-br br-phys
5877 ovn_attach n1 br-phys 192.168.0.$i
5878 ovs-vsctl add-br br-eth0
5879 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5880 done
5881
5882 # Create a localnet port.
5883 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5884 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5885 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5886 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5887
5888
5889 # Create 3 vifs.
5890 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5891 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5892 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5893 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5894 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5895 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5896 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5897 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5898 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5899
5900 # Bind the localvif1 to hv1.
5901 as hv1
5902 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5903
5904 # On hv1, check that there are no flows outputting bcast to tunnel
5905 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5906
5907 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5908 as hv2
5909 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5910
5911 # Now bind vif2 on hv2.
5912 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5913
5914 # At this point, the broadcast flow on vif2 should be deleted.
5915 # because, there is now a localnet vif bound (table=32 programming logic)
5916 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5917
5918 # Verify that the local net patch port exists on hv2.
5919 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5920
5921 # Now bind vif3 on hv2.
5922 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5923
5924 # Verify that the local net patch port still exists on hv2
5925 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5926
5927 # Delete localvif2
5928 AT_CHECK([ovn-nbctl lsp-del localvif2])
5929
5930 # Verify that the local net patch port still exists on hv2,
5931 # because, localvif3 is still bound.
5932 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5933
5934 OVN_CLEANUP([hv1],[hv2])
5935
5936 AT_CLEANUP
5937
5938
5939 AT_SETUP([ovn -- ACL logging])
5940 AT_KEYWORDS([ovn])
5941 ovn_start
5942
5943 net_add n1
5944
5945 sim_add hv
5946 as hv
5947 ovs-vsctl add-br br-phys
5948 ovn_attach n1 br-phys 192.168.0.1
5949 for i in lp1 lp2; do
5950 ovs-vsctl -- add-port br-int $i -- \
5951 set interface $i external-ids:iface-id=$i \
5952 options:tx_pcap=hv/$i-tx.pcap \
5953 options:rxq_pcap=hv/$i-rx.pcap
5954 done
5955
5956 lp1_mac="f0:00:00:00:00:01"
5957 lp1_ip="192.168.1.2"
5958
5959 lp2_mac="f0:00:00:00:00:02"
5960 lp2_ip="192.168.1.3"
5961
5962 ovn-nbctl ls-add lsw0
5963 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5964 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5965 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5966 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5967 ovn-nbctl --wait=sb sync
5968
5969 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5970 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5971
5972 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5973 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5974
5975 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5976 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5977
5978 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5979 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5980
5981 ovn-sbctl dump-flows
5982
5983
5984 # Send packet that should be dropped without logging.
5985 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5986 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5987 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5988 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5989
5990 # Send packet that should be dropped with logging.
5991 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5992 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5993 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5994 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5995
5996 # Send packet that should be allowed without logging.
5997 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5998 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5999 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6000 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6001
6002 # Send packet that should be allowed with logging.
6003 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6004 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6005 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6006 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6007
6008 # Send packet that should allow related flows without logging.
6009 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6010 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6011 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6012 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6013
6014 # Send packet that should allow related flows with logging.
6015 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6016 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6017 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6018 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6019
6020 # Send packet that should be rejected without logging.
6021 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6022 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6023 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6024 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6025
6026 # Send packet that should be rejected with logging.
6027 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6028 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6029 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6030 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6031
6032 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6033
6034 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6035 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
6036 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
6037 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
6038 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
6039 ])
6040
6041 OVN_CLEANUP([hv])
6042 AT_CLEANUP
6043
6044
6045 AT_SETUP([ovn -- DSCP marking and meter check])
6046 AT_KEYWORDS([ovn])
6047 ovn_start
6048
6049 ovn-nbctl ls-add lsw0
6050 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6051 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6052 ovn-nbctl --wait=sb lsp-add lsw0 lp3
6053 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6054 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
6055 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
6056 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6057 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6058 ovn-nbctl --wait=sb sync
6059 net_add n1
6060 sim_add hv
6061 as hv
6062 ovs-vsctl add-br br-phys
6063 ovn_attach n1 br-phys 192.168.0.1
6064 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
6065 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
6066
6067 AT_CAPTURE_FILE([trace])
6068 ovn_trace () {
6069 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6070 }
6071
6072 # Extracts nw_tos from the final flow from ofproto/trace output and prints
6073 # it on stdout. Prints "none" if no nw_tos was included.
6074 get_final_nw_tos() {
6075 if flow=$(grep '^Final flow:' stdout); then :; else
6076 # The output didn't have a final flow.
6077 return 99
6078 fi
6079
6080 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6081 case $tos in
6082 '') echo none ;;
6083 *) echo $tos ;;
6084 esac
6085 }
6086
6087 # check_tos TOS
6088 #
6089 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6090 check_tos() {
6091 # First check with ovn-trace for logical flows.
6092 echo "checking for tos $1"
6093 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6094 echo 'output("lp2");') > expout
6095 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])
6096
6097 # Then re-check with ofproto/trace for a physical packet.
6098 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])
6099 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6100 ])
6101 }
6102
6103 # check at L2
6104 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");
6105 ])
6106 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])
6107 AT_CHECK([get_final_nw_tos], [0], [none
6108 ])
6109
6110 # check at L3 without dscp marking
6111 check_tos 0
6112
6113 # Mark DSCP with a valid value
6114 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)
6115 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6116 ])
6117 check_tos 48
6118
6119 # check at hv without qos meter
6120 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6121 ])
6122
6123 # Update the meter rate
6124 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6125
6126 # check at hv with a qos meter table
6127 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6128 ])
6129 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6130 ])
6131
6132 # Update the DSCP marking
6133 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6134 check_tos 63
6135
6136 # Update the meter rate
6137 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6138
6139 # check at hv with a qos meter table
6140 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6141 ])
6142 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6143 ])
6144
6145 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6146 check_tos 63
6147
6148 # Disable DSCP marking
6149 ovn-nbctl --wait=hv qos-del lsw0
6150 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6151 ])
6152 check_tos 0
6153
6154 # check at hv without qos meter
6155 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6156 ])
6157
6158 # check meter with chassis not resident
6159 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6160 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6161 ])
6162
6163 # check no meter table
6164 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6165 ])
6166 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6167 ])
6168
6169 OVN_CLEANUP([hv])
6170 AT_CLEANUP
6171
6172 AT_SETUP([ovn -- read-only sb db:ptcp access])
6173 AT_SKIP_IF([test $HAVE_PYTHON = no])
6174
6175 : > .$1.db.~lock~
6176 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6177
6178 # Add read-only remote to sb ovsdb-server
6179 AT_CHECK(
6180 [ovsdb-tool transact ovn-sb.db \
6181 ['["OVN_Southbound",
6182 {"op": "insert",
6183 "table": "SB_Global",
6184 "row": {
6185 "connections": ["set", [["named-uuid", "xyz"]]]}},
6186 {"op": "insert",
6187 "table": "Connection",
6188 "uuid-name": "xyz",
6189 "row": {"target": "ptcp:0:127.0.0.1",
6190 "read_only": true}}]']], [0], [ignore], [ignore])
6191
6192 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6193
6194 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6195
6196 # read-only accesses should succeed
6197 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6198 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6199
6200 # write access should fail
6201 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6202 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6203 ])
6204
6205 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6206 AT_CLEANUP
6207
6208 AT_SETUP([ovn -- read-only sb db:pssl access])
6209 AT_SKIP_IF([test $HAVE_PYTHON = no])
6210 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6211 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6212 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6213 \\]"])
6214
6215 : > .$1.db.~lock~
6216 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6217
6218 # Add read-only remote to sb ovsdb-server
6219 AT_CHECK(
6220 [ovsdb-tool transact ovn-sb.db \
6221 ['["OVN_Southbound",
6222 {"op": "insert",
6223 "table": "SB_Global",
6224 "row": {
6225 "connections": ["set", [["named-uuid", "xyz"]]]}},
6226 {"op": "insert",
6227 "table": "Connection",
6228 "uuid-name": "xyz",
6229 "row": {"target": "pssl:0:127.0.0.1",
6230 "read_only": true}}]']], [0], [ignore], [ignore])
6231
6232 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6233 --remote=db:OVN_Southbound,SB_Global,connections \
6234 --private-key="$PKIDIR/testpki-privkey2.pem" \
6235 --certificate="$PKIDIR/testpki-cert2.pem" \
6236 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6237 ovn-sb.db
6238
6239 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6240
6241 # read-only accesses should succeed
6242 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6243 --private-key=$PKIDIR/testpki-privkey.pem \
6244 --certificate=$PKIDIR/testpki-cert.pem \
6245 --ca-cert=$PKIDIR/testpki-cacert.pem \
6246 list SB_Global], [0], [stdout], [ignore])
6247 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6248 --private-key=$PKIDIR/testpki-privkey.pem \
6249 --certificate=$PKIDIR/testpki-cert.pem \
6250 --ca-cert=$PKIDIR/testpki-cacert.pem \
6251 list Connection], [0], [stdout], [ignore])
6252
6253 # write access should fail
6254 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6255 --private-key=$PKIDIR/testpki-privkey.pem \
6256 --certificate=$PKIDIR/testpki-cert.pem \
6257 --ca-cert=$PKIDIR/testpki-cacert.pem \
6258 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6259 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6260 ])
6261
6262 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6263 AT_CLEANUP
6264
6265 AT_SETUP([ovn -- nb connection/ssl commands])
6266 AT_SKIP_IF([test $HAVE_PYTHON = no])
6267 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6268 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6269 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6270 \\]"])
6271
6272 : > .$1.db.~lock~
6273 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6274
6275 # Start nb db server using db connection/ssl entries (unpopulated initially)
6276 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6277 --remote=db:OVN_Northbound,NB_Global,connections \
6278 --private-key=db:OVN_Northbound,SSL,private_key \
6279 --certificate=db:OVN_Northbound,SSL,certificate \
6280 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6281 ovn-nb.db
6282
6283 # Populate SSL configuration entries in nb db
6284 AT_CHECK(
6285 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6286 $PKIDIR/testpki-cert.pem \
6287 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6288
6289 # Populate a passive SSL connection in nb db
6290 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6291
6292 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6293
6294 # Verify SSL connetivity to nb db server
6295 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6296 --private-key=$PKIDIR/testpki-privkey.pem \
6297 --certificate=$PKIDIR/testpki-cert.pem \
6298 --ca-cert=$PKIDIR/testpki-cacert.pem \
6299 list NB_Global],
6300 [0], [stdout], [ignore])
6301 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6302 --private-key=$PKIDIR/testpki-privkey.pem \
6303 --certificate=$PKIDIR/testpki-cert.pem \
6304 --ca-cert=$PKIDIR/testpki-cacert.pem \
6305 list Connection],
6306 [0], [stdout], [ignore])
6307 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6308 --private-key=$PKIDIR/testpki-privkey.pem \
6309 --certificate=$PKIDIR/testpki-cert.pem \
6310 --ca-cert=$PKIDIR/testpki-cacert.pem \
6311 get-connection],
6312 [0], [stdout], [ignore])
6313
6314 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6315 AT_CLEANUP
6316
6317 AT_SETUP([ovn -- sb connection/ssl commands])
6318 AT_SKIP_IF([test $HAVE_PYTHON = no])
6319 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6320 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6321 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6322 \\]"])
6323
6324 : > .$1.db.~lock~
6325 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6326
6327 # Start sb db server using db connection/ssl entries (unpopulated initially)
6328 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6329 --remote=db:OVN_Southbound,SB_Global,connections \
6330 --private-key=db:OVN_Southbound,SSL,private_key \
6331 --certificate=db:OVN_Southbound,SSL,certificate \
6332 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6333 ovn-sb.db
6334
6335 # Populate SSL configuration entries in sb db
6336 AT_CHECK(
6337 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6338 $PKIDIR/testpki-cert.pem \
6339 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6340
6341 # Populate a passive SSL connection in sb db
6342 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6343
6344 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6345
6346 # Verify SSL connetivity to sb db server
6347 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6348 --private-key=$PKIDIR/testpki-privkey.pem \
6349 --certificate=$PKIDIR/testpki-cert.pem \
6350 --ca-cert=$PKIDIR/testpki-cacert.pem \
6351 list SB_Global],
6352 [0], [stdout], [ignore])
6353 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6354 --private-key=$PKIDIR/testpki-privkey.pem \
6355 --certificate=$PKIDIR/testpki-cert.pem \
6356 --ca-cert=$PKIDIR/testpki-cacert.pem \
6357 list Connection],
6358 [0], [stdout], [ignore])
6359 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6360 --private-key=$PKIDIR/testpki-privkey.pem \
6361 --certificate=$PKIDIR/testpki-cert.pem \
6362 --ca-cert=$PKIDIR/testpki-cacert.pem \
6363 get-connection],
6364 [0], [stdout], [ignore])
6365
6366 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6367 AT_CLEANUP
6368
6369 AT_SETUP([ovn -- nested containers])
6370 ovn_start
6371
6372 # Physical network:
6373 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6374
6375 # Logical network:
6376 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6377 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6378
6379 ovn-nbctl lr-add R1
6380 ovn-nbctl ls-add mgmt
6381 ovn-nbctl ls-add foo
6382 ovn-nbctl ls-add bar
6383
6384 # Connect mgmt to R1
6385 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6386 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6387 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6388
6389 # Connect foo to R1
6390 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6391 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6392 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6393
6394 # Connect bar to R1
6395 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6396 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6397 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6398
6399 # "mgmt" has VM1 and VM2 connected
6400 ovn-nbctl lsp-add mgmt vm1 \
6401 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6402
6403 ovn-nbctl lsp-add mgmt vm2 \
6404 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6405
6406 # "foo1" and "foo2" are containers belonging to switch "foo"
6407 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6408 ovn-nbctl lsp-add foo foo1 vm1 1 \
6409 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6410
6411 ovn-nbctl lsp-add foo foo2 vm2 2 \
6412 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6413
6414 # "bar1" and "bar2" are containers belonging to switch "bar"
6415 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6416 ovn-nbctl lsp-add bar bar1 vm1 2 \
6417 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6418
6419 ovn-nbctl lsp-add bar bar2 vm2 1 \
6420 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6421
6422 # bar3 is a standalone VM belonging to switch "bar"
6423 ovn-nbctl lsp-add bar bar3 \
6424 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6425
6426 # Create two hypervisor and create OVS ports corresponding to logical ports.
6427 net_add n1
6428
6429 sim_add hv1
6430 as hv1
6431 ovs-vsctl add-br br-phys
6432 ovn_attach n1 br-phys 192.168.0.1
6433 ovs-vsctl -- add-port br-int vm1 -- \
6434 set interface vm1 external-ids:iface-id=vm1 \
6435 options:tx_pcap=hv1/vm1-tx.pcap \
6436 options:rxq_pcap=hv1/vm1-rx.pcap \
6437 ofport-request=1
6438
6439 ovs-vsctl -- add-port br-int bar3 -- \
6440 set interface bar3 external-ids:iface-id=bar3 \
6441 options:tx_pcap=hv1/bar3-tx.pcap \
6442 options:rxq_pcap=hv1/bar3-rx.pcap \
6443 ofport-request=2
6444
6445 sim_add hv2
6446 as hv2
6447 ovs-vsctl add-br br-phys
6448 ovn_attach n1 br-phys 192.168.0.2
6449 ovs-vsctl -- add-port br-int vm2 -- \
6450 set interface vm2 external-ids:iface-id=vm2 \
6451 options:tx_pcap=hv2/vm2-tx.pcap \
6452 options:rxq_pcap=hv2/vm2-rx.pcap \
6453 ofport-request=1
6454
6455 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6456 # packets for ARP resolution (native tunneling doesn't queue packets
6457 # for ARP resolution).
6458 OVN_POPULATE_ARP
6459
6460 # Allow some time for ovn-northd and ovn-controller to catch up.
6461 # XXX This should be more systematic.
6462 sleep 1
6463
6464 ip_to_hex() {
6465 printf "%02x%02x%02x%02x" "$@"
6466 }
6467
6468 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6469 # different VLAN tags).
6470 src_mac="f00000010205"
6471 dst_mac="f00000010206"
6472 src_ip=`ip_to_hex 192 168 1 2`
6473 dst_ip=`ip_to_hex 192 168 1 3`
6474 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6475 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6476
6477 # expected packet at foo2
6478 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6479 echo $packet > expected
6480 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6481
6482 # Send ip packets between foo1 and bar2 (different switch, different HV)
6483 src_mac="f00000010205"
6484 dst_mac="000000010203"
6485 src_ip=`ip_to_hex 192 168 1 2`
6486 dst_ip=`ip_to_hex 192 168 2 3`
6487 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6488 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6489
6490 # expected packet at bar2
6491 src_mac="000000010204"
6492 dst_mac="f00000010208"
6493 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6494 echo $packet >> expected
6495 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6496
6497 # Send ip packets between foo1 and bar1
6498 # (different switch, loopback to same vm but different tag)
6499 src_mac="f00000010205"
6500 dst_mac="000000010203"
6501 src_ip=`ip_to_hex 192 168 1 2`
6502 dst_ip=`ip_to_hex 192 168 2 2`
6503 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6504 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6505
6506 # expected packet at bar1
6507 src_mac="000000010204"
6508 dst_mac="f00000010207"
6509 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6510 echo $packet > expected1
6511 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6512
6513 # Send ip packets between bar1 and bar3
6514 # (same switch. But one is container and another is a standalone VM)
6515 src_mac="f00000010207"
6516 dst_mac="f00000010209"
6517 src_ip=`ip_to_hex 192 168 2 2`
6518 dst_ip=`ip_to_hex 192 168 2 3`
6519 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6520 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6521
6522 # expected packet at bar3
6523 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6524 echo $packet > expected
6525 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6526
6527 # Send ip packets between foo1 and vm1.
6528 (different switch, container to the VM hosting it.)
6529 src_mac="f00000010205"
6530 dst_mac="000000010203"
6531 src_ip=`ip_to_hex 192 168 1 2`
6532 dst_ip=`ip_to_hex 172 16 1 2`
6533 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6534 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6535
6536 # expected packet at vm1
6537 src_mac="000000010202"
6538 dst_mac="f00000010203"
6539 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6540 echo $packet >> expected1
6541 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6542
6543 # Send packets from vm1 to bar1.
6544 (different switch, A hosting VM to a container inside it)
6545 src_mac="f00000010203"
6546 dst_mac="000000010202"
6547 src_ip=`ip_to_hex 172 16 1 2`
6548 dst_ip=`ip_to_hex 192 168 2 2`
6549 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6550 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6551
6552 # expected packet at vm1
6553 src_mac="000000010204"
6554 dst_mac="f00000010207"
6555 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6556 echo $packet >> expected1
6557 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6558
6559 OVN_CLEANUP([hv1],[hv2])
6560
6561 AT_CLEANUP
6562
6563 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6564 AT_SKIP_IF([test $HAVE_PYTHON = no])
6565 ovn_start
6566
6567 # Logical network:
6568 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6569 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6570 # (192.168.2.0/24) connected to it.
6571 #
6572 # R2 and R3 are gateway routers.
6573 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6574 # connected to it. Note how both alice and bob have the same subnet behind it.
6575 # We are trying to simulate external network via those 2 switches. In real
6576 # world the switch ports of these switches will have addresses set as "unknown"
6577 # to make them learning switches. Or those switches will be "localnet" ones.
6578
6579 # Create three hypervisors and create OVS ports corresponding to logical ports.
6580 net_add n1
6581
6582 sim_add hv1
6583 as hv1
6584 ovs-vsctl add-br br-phys
6585 ovn_attach n1 br-phys 192.168.0.1
6586 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6587 set interface hv1-vif1 external-ids:iface-id=foo1 \
6588 options:tx_pcap=hv1/vif1-tx.pcap \
6589 options:rxq_pcap=hv1/vif1-rx.pcap \
6590 ofport-request=1
6591
6592 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6593 set interface hv1-vif2 external-ids:iface-id=bar1 \
6594 options:tx_pcap=hv1/vif2-tx.pcap \
6595 options:rxq_pcap=hv1/vif2-rx.pcap \
6596 ofport-request=2
6597
6598 sim_add hv2
6599 as hv2
6600 ovs-vsctl add-br br-phys
6601 ovn_attach n1 br-phys 192.168.0.2
6602 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6603 set interface hv2-vif1 external-ids:iface-id=alice1 \
6604 options:tx_pcap=hv2/vif1-tx.pcap \
6605 options:rxq_pcap=hv2/vif1-rx.pcap \
6606 ofport-request=1
6607
6608 sim_add hv3
6609 as hv3
6610 ovs-vsctl add-br br-phys
6611 ovn_attach n1 br-phys 192.168.0.3
6612 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6613 set interface hv3-vif1 external-ids:iface-id=bob1 \
6614 options:tx_pcap=hv3/vif1-tx.pcap \
6615 options:rxq_pcap=hv3/vif1-rx.pcap \
6616 ofport-request=1
6617
6618
6619 ovn-nbctl create Logical_Router name=R1
6620 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6621 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6622
6623 ovn-nbctl ls-add foo
6624 ovn-nbctl ls-add bar
6625 ovn-nbctl ls-add alice
6626 ovn-nbctl ls-add bob
6627 ovn-nbctl ls-add join
6628
6629 # Connect foo to R1
6630 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6631 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6632 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6633
6634 # Connect bar to R1
6635 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6636 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6637 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6638
6639 # Connect alice to R2
6640 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6641 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6642 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6643
6644 # Connect bob to R3
6645 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6646 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6647 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6648
6649 # Connect R1 to join
6650 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6651 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6652 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6653
6654 # Connect R2 to join
6655 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6656 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6657 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6658
6659 # Connect R3 to join
6660 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6661 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6662 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6663
6664 # Install static routes with source ip address as the policy for routing.
6665 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6666 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6667 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6668
6669 # Install static routes with destination ip address as the policy for routing.
6670 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6671
6672 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6673
6674 # Create logical port foo1 in foo
6675 ovn-nbctl lsp-add foo foo1 \
6676 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6677
6678 # Create logical port bar1 in bar
6679 ovn-nbctl lsp-add bar bar1 \
6680 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6681
6682 # Create logical port alice1 in alice
6683 ovn-nbctl lsp-add alice alice1 \
6684 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6685
6686 # Create logical port bob1 in bob
6687 ovn-nbctl lsp-add bob bob1 \
6688 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6689
6690 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6691 # packets for ARP resolution (native tunneling doesn't queue packets
6692 # for ARP resolution).
6693 OVN_POPULATE_ARP
6694
6695 # Allow some time for ovn-northd and ovn-controller to catch up.
6696 # XXX This should be more systematic.
6697 sleep 1
6698
6699 ip_to_hex() {
6700 printf "%02x%02x%02x%02x" "$@"
6701 }
6702 trim_zeros() {
6703 sed 's/\(00\)\{1,\}$//'
6704 }
6705
6706 # Send ip packets between foo1 and bar1
6707 # (East-west traffic should flow normally)
6708 src_mac="f00000010203"
6709 dst_mac="000001010203"
6710 src_ip=`ip_to_hex 192 168 1 2`
6711 dst_ip=`ip_to_hex 192 168 2 2`
6712 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6713 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6714
6715 # Send ip packets between foo1 and alice1
6716 src_mac="f00000010203"
6717 dst_mac="000001010203"
6718 src_ip=`ip_to_hex 192 168 1 2`
6719 dst_ip=`ip_to_hex 172 16 1 3`
6720 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6721 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6722 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6723
6724 # Send ip packets between bar1 and bob1
6725 src_mac="f00000010204"
6726 dst_mac="000001010204"
6727 src_ip=`ip_to_hex 192 168 2 2`
6728 dst_ip=`ip_to_hex 172 16 1 4`
6729 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6730 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6731 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6732
6733 # Packet to expect at bar1
6734 src_mac="000001010204"
6735 dst_mac="f00000010204"
6736 src_ip=`ip_to_hex 192 168 1 2`
6737 dst_ip=`ip_to_hex 192 168 2 2`
6738 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6739 echo $expected > expected
6740 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6741
6742 # Packet to Expect at alice1
6743 src_mac="000002010203"
6744 dst_mac="f00000010205"
6745 src_ip=`ip_to_hex 192 168 1 2`
6746 dst_ip=`ip_to_hex 172 16 1 3`
6747 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6748 echo $expected > expected
6749 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6750
6751 # Packet to Expect at bob1
6752 src_mac="000003010203"
6753 dst_mac="f00000010206"
6754 src_ip=`ip_to_hex 192 168 2 2`
6755 dst_ip=`ip_to_hex 172 16 1 4`
6756 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6757 echo $expected > expected
6758 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6759
6760 for sim in hv1 hv2 hv3; do
6761 as $sim
6762 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6763 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6764 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6765 done
6766
6767 as ovn-sb
6768 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6769
6770 as ovn-nb
6771 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6772
6773 as northd
6774 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6775
6776 as main
6777 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6778 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6779
6780 AT_CLEANUP
6781
6782 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6783 AT_SKIP_IF([test $HAVE_PYTHON = no])
6784 ovn_start
6785
6786 ovn-nbctl ls-add ls1
6787
6788 ovn-nbctl lsp-add ls1 ls1-lp1 \
6789 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6790
6791 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6792
6793 ovn-nbctl lsp-add ls1 ls1-lp2 \
6794 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6795
6796 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6797
6798 DNS1=`ovn-nbctl create DNS records={}`
6799 DNS2=`ovn-nbctl create DNS records={}`
6800
6801 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6802 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6803 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6804
6805 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6806
6807 net_add n1
6808 sim_add hv1
6809
6810 as hv1
6811 ovs-vsctl add-br br-phys
6812 ovn_attach n1 br-phys 192.168.0.1
6813 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6814 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6815 options:tx_pcap=hv1/vif1-tx.pcap \
6816 options:rxq_pcap=hv1/vif1-rx.pcap \
6817 ofport-request=1
6818
6819 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6820 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6821 options:tx_pcap=hv1/vif2-tx.pcap \
6822 options:rxq_pcap=hv1/vif2-rx.pcap \
6823 ofport-request=2
6824
6825 OVN_POPULATE_ARP
6826 sleep 2
6827 as hv1 ovs-vsctl show
6828
6829 echo "*************************"
6830 ovn-sbctl list DNS
6831 echo "*************************"
6832
6833 ip_to_hex() {
6834 printf "%02x%02x%02x%02x" "$@"
6835 }
6836
6837 reset_pcap_file() {
6838 local iface=$1
6839 local pcap_file=$2
6840 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6841 options:rxq_pcap=dummy-rx.pcap
6842 rm -f ${pcap_file}*.pcap
6843 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6844 options:rxq_pcap=${pcap_file}-rx.pcap
6845 }
6846
6847 # set_dns_params host_name
6848 # Sets the dns_req_data and dns_resp_data
6849 set_dns_params() {
6850 local hname=$1
6851 local ttl=00000e10
6852 an_count=0001
6853 type=0001
6854 case $hname in
6855 vm1)
6856 # vm1.ovn.org
6857 query_name=03766d31036f766e036f726700
6858 # IPv4 address - 10.0.0.4
6859 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6860 ;;
6861 vm2)
6862 # vm2.ovn.org
6863 query_name=03766d32036f766e036f726700
6864 # IPv4 address - 10.0.0.6
6865 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6866 # IPv4 address - 20.0.0.4
6867 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6868 an_count=0002
6869 ;;
6870 vm3)
6871 # vm3.ovn.org
6872 query_name=03766d33036f766e036f726700
6873 # IPv4 address - 40.0.0.4
6874 expected_dns_answer=${query_name}00010001${ttl}000428000004
6875 ;;
6876 vm1_ipv6_only)
6877 # vm1.ovn.org
6878 query_name=03766d31036f766e036f726700
6879 # IPv6 address - aef0::4
6880 type=001c
6881 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6882 ;;
6883 vm1_ipv4_v6)
6884 # vm1.ovn.org
6885 query_name=03766d31036f766e036f726700
6886 type=00ff
6887 an_count=0002
6888 # IPv4 address - 10.0.0.4
6889 # IPv6 address - aef0::4
6890 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6891 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6892 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6893 ;;
6894 vm1_invalid_type)
6895 # vm1.ovn.org
6896 query_name=03766d31036f766e036f726700
6897 # IPv6 address - aef0::4
6898 type=0002
6899 ;;
6900 vm1_incomplete)
6901 # set type to none
6902 type=''
6903 esac
6904 # TTL - 3600
6905 local dns_req_header=010201200001000000000000
6906 local dns_resp_header=010281200001${an_count}00000000
6907 dns_req_data=${dns_req_header}${query_name}${type}0001
6908 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6909 }
6910
6911 # This shell function sends a DNS request packet
6912 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6913 test_dns() {
6914 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6915 local dns_query_data=$7
6916 shift; shift; shift; shift; shift; shift; shift;
6917 # Packet size => IPv4 header (20) + UDP header (8) +
6918 # DNS data (header + query)
6919 ip_len=`expr 28 + ${#dns_query_data} / 2`
6920 udp_len=`expr $ip_len - 20`
6921 ip_len=$(printf "%x" $ip_len)
6922 udp_len=$(printf "%x" $udp_len)
6923 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6924 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6925 # dns data
6926 request=${request}${dns_query_data}
6927
6928 if test $dns_reply != 0; then
6929 local dns_reply=$1
6930 ip_len=`expr 28 + ${#dns_reply} / 2`
6931 udp_len=`expr $ip_len - 20`
6932 ip_len=$(printf "%x" $ip_len)
6933 udp_len=$(printf "%x" $udp_len)
6934 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6935 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6936 echo $reply >> $inport.expected
6937 else
6938 for outport; do
6939 echo $request >> $outport.expected
6940 done
6941 fi
6942 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6943 }
6944
6945 test_dns6() {
6946 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6947 local dns_query_data=$7
6948 shift; shift; shift; shift; shift; shift; shift;
6949 # Packet size => UDP header (8) +
6950 # DNS data (header + query)
6951 ip_len=`expr 8 + ${#dns_query_data} / 2`
6952 udp_len=$ip_len
6953 ip_len=$(printf "%x" $ip_len)
6954 udp_len=$(printf "%x" $udp_len)
6955 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
6956 request=${request}9234003500${udp_len}0000
6957 #dns data
6958 request=${request}${dns_query_data}
6959
6960 if test $dns_reply != 0; then
6961 local dns_reply=$1
6962 ip_len=`expr 8 + ${#dns_reply} / 2`
6963 udp_len=$ip_len
6964 ip_len=$(printf "%x" $ip_len)
6965 udp_len=$(printf "%x" $udp_len)
6966 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
6967 reply=${reply}0035923400${udp_len}0000${dns_reply}
6968 echo $reply >> $inport.expected
6969 else
6970 for outport; do
6971 echo $request >> $outport.expected
6972 done
6973 fi
6974 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6975 }
6976
6977 AT_CAPTURE_FILE([ofctl_monitor0.log])
6978 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6979 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6980
6981 set_dns_params vm2
6982 src_ip=`ip_to_hex 10 0 0 4`
6983 dst_ip=`ip_to_hex 10 0 0 1`
6984 dns_reply=1
6985 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6986
6987 # NXT_RESUMEs should be 1.
6988 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6989
6990 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6991 cat 1.expected | cut -c -48 > expout
6992 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6993 # Skipping the IPv4 checksum.
6994 cat 1.expected | cut -c 53- > expout
6995 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6996
6997 reset_pcap_file hv1-vif1 hv1/vif1
6998 reset_pcap_file hv1-vif2 hv1/vif2
6999 rm -f 1.expected
7000 rm -f 2.expected
7001
7002 set_dns_params vm1
7003 src_ip=`ip_to_hex 10 0 0 6`
7004 dst_ip=`ip_to_hex 10 0 0 1`
7005 dns_reply=1
7006 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7007
7008 # NXT_RESUMEs should be 2.
7009 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7010
7011 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7012 cat 2.expected | cut -c -48 > expout
7013 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7014 # Skipping the IPv4 checksum.
7015 cat 2.expected | cut -c 53- > expout
7016 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7017
7018 reset_pcap_file hv1-vif1 hv1/vif1
7019 reset_pcap_file hv1-vif2 hv1/vif2
7020 rm -f 1.expected
7021 rm -f 2.expected
7022
7023 # Clear the query name options for ls1-lp2
7024 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7025
7026 set_dns_params vm2
7027 src_ip=`ip_to_hex 10 0 0 4`
7028 dst_ip=`ip_to_hex 10 0 0 1`
7029 dns_reply=0
7030 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7031
7032 # NXT_RESUMEs should be 3.
7033 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7034
7035 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7036 AT_CHECK([cat 1.packets], [0], [])
7037
7038 reset_pcap_file hv1-vif1 hv1/vif1
7039 reset_pcap_file hv1-vif2 hv1/vif2
7040 rm -f 1.expected
7041 rm -f 2.expected
7042
7043 # Clear the query name for ls1-lp1
7044 # Since ls1 has no query names configued,
7045 # ovn-northd should not add the DNS flows.
7046 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7047
7048 set_dns_params vm1
7049 src_ip=`ip_to_hex 10 0 0 6`
7050 dst_ip=`ip_to_hex 10 0 0 1`
7051 dns_reply=0
7052 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7053
7054 # NXT_RESUMEs should be 3 only.
7055 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7056
7057 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7058 AT_CHECK([cat 2.packets], [0], [])
7059
7060 reset_pcap_file hv1-vif1 hv1/vif1
7061 reset_pcap_file hv1-vif2 hv1/vif2
7062 rm -f 1.expected
7063 rm -f 2.expected
7064
7065 # Test IPv6 (AAAA records) using IPv4 packet.
7066 # Add back the DNS options for ls1-lp1.
7067 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7068
7069 set_dns_params vm1_ipv6_only
7070 src_ip=`ip_to_hex 10 0 0 6`
7071 dst_ip=`ip_to_hex 10 0 0 1`
7072 dns_reply=1
7073 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7074
7075 # NXT_RESUMEs should be 4.
7076 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7077
7078 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7079 cat 2.expected | cut -c -48 > expout
7080 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7081 # Skipping the IPv4 checksum.
7082 cat 2.expected | cut -c 53- > expout
7083 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7084
7085 reset_pcap_file hv1-vif1 hv1/vif1
7086 reset_pcap_file hv1-vif2 hv1/vif2
7087 rm -f 1.expected
7088 rm -f 2.expected
7089
7090 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7091 set_dns_params vm1_ipv4_v6
7092 src_ip=`ip_to_hex 10 0 0 6`
7093 dst_ip=`ip_to_hex 10 0 0 1`
7094 dns_reply=1
7095 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7096
7097 # NXT_RESUMEs should be 5.
7098 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7099
7100 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7101 cat 2.expected | cut -c -48 > expout
7102 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7103 # Skipping the IPv4 checksum.
7104 cat 2.expected | cut -c 53- > expout
7105 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7106
7107 reset_pcap_file hv1-vif1 hv1/vif1
7108 reset_pcap_file hv1-vif2 hv1/vif2
7109 rm -f 1.expected
7110 rm -f 2.expected
7111
7112 # Invalid type.
7113 set_dns_params vm1_invalid_type
7114 src_ip=`ip_to_hex 10 0 0 6`
7115 dst_ip=`ip_to_hex 10 0 0 1`
7116 dns_reply=0
7117 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7118
7119 # NXT_RESUMEs should be 6.
7120 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7121
7122 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7123 AT_CHECK([cat 2.packets], [0], [])
7124
7125 reset_pcap_file hv1-vif1 hv1/vif1
7126 reset_pcap_file hv1-vif2 hv1/vif2
7127 rm -f 1.expected
7128 rm -f 2.expected
7129
7130 # Incomplete DNS packet.
7131 set_dns_params vm1_incomplete
7132 src_ip=`ip_to_hex 10 0 0 6`
7133 dst_ip=`ip_to_hex 10 0 0 1`
7134 dns_reply=0
7135 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7136
7137 # NXT_RESUMEs should be 7.
7138 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7139
7140 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7141 AT_CHECK([cat 2.packets], [0], [])
7142
7143 reset_pcap_file hv1-vif1 hv1/vif1
7144 reset_pcap_file hv1-vif2 hv1/vif2
7145 rm -f 1.expected
7146 rm -f 2.expected
7147
7148 # Add one more DNS record to the ls1.
7149 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7150
7151 set_dns_params vm3
7152 src_ip=`ip_to_hex 10 0 0 4`
7153 dst_ip=`ip_to_hex 10 0 0 1`
7154 dns_reply=1
7155 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7156
7157 # NXT_RESUMEs should be 8.
7158 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7159
7160 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7161 cat 1.expected | cut -c -48 > expout
7162 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7163 # Skipping the IPv4 checksum.
7164 cat 1.expected | cut -c 53- > expout
7165 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7166
7167 reset_pcap_file hv1-vif1 hv1/vif1
7168 reset_pcap_file hv1-vif2 hv1/vif2
7169 rm -f 1.expected
7170 rm -f 2.expected
7171
7172 # Try DNS query over IPv6
7173 set_dns_params vm1
7174 src_ip=aef00000000000000000000000000004
7175 dst_ip=aef00000000000000000000000000001
7176 dns_reply=1
7177 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7178
7179 # NXT_RESUMEs should be 9.
7180 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7181
7182 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7183 # Skipping the UDP checksum.
7184 cat 1.expected | cut -c 1-120,125- > expout
7185 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
7186
7187 reset_pcap_file hv1-vif1 hv1/vif1
7188 reset_pcap_file hv1-vif2 hv1/vif2
7189 rm -f 1.expected
7190 rm -f 2.expected
7191
7192 as hv1
7193 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7194 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7195 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7196
7197 as ovn-sb
7198 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7199
7200 as ovn-nb
7201 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7202
7203 as northd
7204 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7205
7206 as main
7207 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7208 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7209 AT_CLEANUP
7210
7211 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7212 AT_SKIP_IF([test $HAVE_PYTHON = no])
7213 ovn_start
7214
7215 net_add n1
7216
7217 sim_add hv1
7218 as hv1
7219 ovs-vsctl add-br br-phys
7220 ovn_attach n1 br-phys 192.168.0.1
7221 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7222 set interface hv1-vif1 external-ids:iface-id=foo1 \
7223 options:tx_pcap=hv1/vif1-tx.pcap \
7224 options:rxq_pcap=hv1/vif1-rx.pcap \
7225 ofport-request=1
7226
7227 sim_add gw1
7228 as gw1
7229 ovs-vsctl add-br br-phys
7230 ovn_attach n1 br-phys 192.168.0.2
7231
7232 sim_add gw2
7233 as gw2
7234 ovs-vsctl add-br br-phys
7235 ovn_attach n1 br-phys 192.168.0.4
7236
7237 sim_add ext1
7238 as ext1
7239 ovs-vsctl add-br br-phys
7240 ovn_attach n1 br-phys 192.168.0.3
7241 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7242 set interface ext1-vif1 external-ids:iface-id=outside1 \
7243 options:tx_pcap=ext1/vif1-tx.pcap \
7244 options:rxq_pcap=ext1/vif1-rx.pcap \
7245 ofport-request=1
7246
7247 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7248 # packets for ARP resolution (native tunneling doesn't queue packets
7249 # for ARP resolution).
7250 OVN_POPULATE_ARP
7251
7252 ovn-nbctl create Logical_Router name=R1
7253
7254 ovn-nbctl ls-add foo
7255 ovn-nbctl ls-add alice
7256 ovn-nbctl ls-add outside
7257
7258 # Connect foo to R1
7259 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7260 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7261 type=router options:router-port=foo \
7262 -- lsp-set-addresses rp-foo router
7263
7264 # Connect alice to R1 as distributed router gateway port on gw1
7265 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7266
7267 ovn-nbctl \
7268 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7269 chassis_name=gw1 \
7270 priority=20 -- \
7271 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7272 chassis_name=gw2 \
7273 priority=10 -- \
7274 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7275
7276 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7277 type=router options:router-port=alice \
7278 -- lsp-set-addresses rp-alice router
7279
7280 # Create logical port foo1 in foo
7281 ovn-nbctl lsp-add foo foo1 \
7282 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7283
7284 # Create logical port outside1 in outside
7285 ovn-nbctl lsp-add outside outside1 \
7286 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7287
7288 # Create localnet port in alice
7289 ovn-nbctl lsp-add alice ln-alice
7290 ovn-nbctl lsp-set-addresses ln-alice unknown
7291 ovn-nbctl lsp-set-type ln-alice localnet
7292 ovn-nbctl lsp-set-options ln-alice network_name=phys
7293
7294 # Create localnet port in outside
7295 ovn-nbctl lsp-add outside ln-outside
7296 ovn-nbctl lsp-set-addresses ln-outside unknown
7297 ovn-nbctl lsp-set-type ln-outside localnet
7298 ovn-nbctl lsp-set-options ln-outside network_name=phys
7299
7300 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7301 # mapping to the external network, is the one generating packets
7302 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7303 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7304 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7305
7306 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7307
7308 # Allow some time for ovn-northd and ovn-controller to catch up.
7309 # XXX This should be more systematic.
7310 sleep 2
7311
7312 ip_to_hex() {
7313 printf "%02x%02x%02x%02x" "$@"
7314 }
7315
7316 reset_pcap_file() {
7317 local iface=$1
7318 local pcap_file=$2
7319 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7320 options:rxq_pcap=dummy-rx.pcap
7321 rm -f ${pcap_file}*.pcap
7322 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7323 options:rxq_pcap=${pcap_file}-rx.pcap
7324 }
7325
7326 test_ip_packet()
7327 {
7328 local active_gw=$1
7329 local backup_gw=$2
7330
7331 # Send ip packet between foo1 and outside1
7332 src_mac="f00000010203" # foo1 mac
7333 dst_mac="000001010203" # rp-foo mac (internal router leg)
7334 src_ip=`ip_to_hex 192 168 1 2`
7335 dst_ip=`ip_to_hex 172 16 1 3`
7336 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7337
7338 # ARP request packet to expect at outside1
7339 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7340
7341 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7342
7343 # Send ARP reply from outside1 back to the router
7344 # XXX: note, we could avoid this if we plug this port into a netns
7345 # and setup the IP address into the port, so the kernel would simply reply
7346 src_mac="000002010203"
7347 reply_mac="f00000010204"
7348 dst_ip=`ip_to_hex 172 16 1 3`
7349 src_ip=`ip_to_hex 172 16 1 1`
7350 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7351
7352 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7353
7354 OVS_WAIT_UNTIL([
7355 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7356 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7357 ])
7358
7359 # Packet to Expect at ext1 chassis, outside1 port
7360 src_mac="000002010203"
7361 dst_mac="f00000010204"
7362 src_ip=`ip_to_hex 192 168 1 2`
7363 dst_ip=`ip_to_hex 172 16 1 3`
7364 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7365 echo $expected > ext1-vif1.expected
7366
7367 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7368 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7369 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7370
7371 # Resend packet from foo1 to outside1
7372 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7373
7374 sleep 1
7375
7376 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7377 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7378 AT_CHECK([grep $expected packets | sort], [0], [expout])
7379 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7380 AT_CHECK([grep $expected packets | sort], [0], [])
7381 }
7382
7383 test_ip_packet gw1 gw2
7384
7385 ovn-nbctl --timeout=3 --wait=hv \
7386 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7387 chassis_name=gw1 \
7388 priority=10 -- \
7389 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7390 chassis_name=gw2 \
7391 priority=20 -- \
7392 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7393
7394 test_ip_packet gw2 gw1
7395
7396 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7397 AT_CLEANUP
7398
7399 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7400 AT_SKIP_IF([test $HAVE_PYTHON = no])
7401 ovn_start
7402
7403 net_add n1
7404
7405 sim_add hv1
7406 as hv1
7407 ovs-vsctl add-br br-phys
7408 ovn_attach n1 br-phys 192.168.0.1
7409 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7410 set interface hv1-vif1 external-ids:iface-id=foo1 \
7411 options:tx_pcap=hv1/vif1-tx.pcap \
7412 options:rxq_pcap=hv1/vif1-rx.pcap \
7413 ofport-request=1
7414
7415 sim_add gw1
7416 as gw1
7417 ovs-vsctl add-br br-phys
7418 ovn_attach n1 br-phys 192.168.0.2
7419
7420 sim_add gw2
7421 as gw2
7422 ovs-vsctl add-br br-phys
7423 ovn_attach n1 br-phys 192.168.0.4
7424
7425 sim_add ext1
7426 as ext1
7427 ovs-vsctl add-br br-phys
7428 ovn_attach n1 br-phys 192.168.0.3
7429 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7430 set interface ext1-vif1 external-ids:iface-id=outside1 \
7431 options:tx_pcap=ext1/vif1-tx.pcap \
7432 options:rxq_pcap=ext1/vif1-rx.pcap \
7433 ofport-request=1
7434
7435 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7436 # packets for ARP resolution (native tunneling doesn't queue packets
7437 # for ARP resolution).
7438 OVN_POPULATE_ARP
7439
7440 ovn-nbctl create Logical_Router name=R0
7441 ovn-nbctl create Logical_Router name=R1
7442
7443 ovn-nbctl ls-add foo
7444 ovn-nbctl ls-add join
7445 ovn-nbctl ls-add alice
7446 ovn-nbctl ls-add outside
7447
7448 #Connect foo to R0
7449 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7450 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7451 type=router options:router-port=R0-foo \
7452 -- lsp-set-addresses foo-R0 router
7453
7454 #Connect R0 to join
7455 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7456 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7457 type=router options:router-port=R0-join \
7458 -- lsp-set-addresses join-R0 router
7459
7460 #Connect join to R1
7461 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7462 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7463 type=router options:router-port=R1-join \
7464 -- lsp-set-addresses join-R1 router
7465
7466 #add route rules
7467 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7468 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7469
7470 # Connect alice to R1 as distributed router gateway port on gw1
7471 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7472
7473 ovn-nbctl \
7474 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7475 chassis_name=gw1 \
7476 priority=20 -- \
7477 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7478 chassis_name=gw2 \
7479 priority=10 -- \
7480 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7481
7482 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7483 type=router options:router-port=alice \
7484 -- lsp-set-addresses rp-alice router
7485
7486 # Create logical port foo1 in foo
7487 ovn-nbctl lsp-add foo foo1 \
7488 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7489
7490 # Create logical port outside1 in outside
7491 ovn-nbctl lsp-add outside outside1 \
7492 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7493
7494 # Create localnet port in alice
7495 ovn-nbctl lsp-add alice ln-alice
7496 ovn-nbctl lsp-set-addresses ln-alice unknown
7497 ovn-nbctl lsp-set-type ln-alice localnet
7498 ovn-nbctl lsp-set-options ln-alice network_name=phys
7499
7500 # Create localnet port in outside
7501 ovn-nbctl lsp-add outside ln-outside
7502 ovn-nbctl lsp-set-addresses ln-outside unknown
7503 ovn-nbctl lsp-set-type ln-outside localnet
7504 ovn-nbctl lsp-set-options ln-outside network_name=phys
7505
7506 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7507 # mapping to the external network, is the one generating packets
7508 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7509 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7510 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7511
7512 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7513
7514 # Allow some time for ovn-northd and ovn-controller to catch up.
7515 # XXX This should be more systematic.
7516 sleep 2
7517
7518 ip_to_hex() {
7519 printf "%02x%02x%02x%02x" "$@"
7520 }
7521
7522 reset_pcap_file() {
7523 local iface=$1
7524 local pcap_file=$2
7525 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7526 options:rxq_pcap=dummy-rx.pcap
7527 rm -f ${pcap_file}*.pcap
7528 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7529 options:rxq_pcap=${pcap_file}-rx.pcap
7530 }
7531
7532 test_ip_packet()
7533 {
7534 local active_gw=$1
7535 local backup_gw=$2
7536
7537 # Send ip packet between foo1 and outside1
7538 src_mac="f00000010203" # foo1 mac
7539 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7540 src_ip=`ip_to_hex 192 168 1 2`
7541 dst_ip=`ip_to_hex 172 16 1 3`
7542 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7543
7544 # ARP request packet to expect at outside1
7545 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7546
7547 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7548
7549 # Send ARP reply from outside1 back to the router
7550 # XXX: note, we could avoid this if we plug this port into a netns
7551 # and setup the IP address into the port, so the kernel would simply reply
7552 src_mac="000002010203"
7553 reply_mac="f00000010204"
7554 dst_ip=`ip_to_hex 172 16 1 3`
7555 src_ip=`ip_to_hex 172 16 1 1`
7556 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7557
7558 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7559
7560 OVS_WAIT_UNTIL([
7561 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7562 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7563 ])
7564
7565 # Packet to Expect at ext1 chassis, outside1 port
7566 src_mac="000002010203"
7567 dst_mac="f00000010204"
7568 src_ip=`ip_to_hex 192 168 1 2`
7569 dst_ip=`ip_to_hex 172 16 1 3`
7570 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7571 echo $expected > ext1-vif1.expected
7572
7573 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7574 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7575 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7576
7577 # Resend packet from foo1 to outside1
7578 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7579
7580 sleep 1
7581
7582 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7583 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7584 AT_CHECK([grep $expected packets | sort], [0], [expout])
7585 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7586 AT_CHECK([grep $expected packets | sort], [0], [])
7587 }
7588
7589 test_ip_packet gw1 gw2
7590
7591 ovn-nbctl --timeout=3 --wait=hv \
7592 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7593 chassis_name=gw1 \
7594 priority=10 -- \
7595 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7596 chassis_name=gw2 \
7597 priority=20 -- \
7598 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7599
7600 test_ip_packet gw2 gw1
7601
7602 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7603 AT_CLEANUP
7604
7605 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7606 AT_SKIP_IF([test $HAVE_PYTHON = no])
7607 ovn_start
7608
7609 # Logical network:
7610 # One LR R1 that has switches foo (192.168.1.0/24) and
7611 # alice (172.16.1.0/24) connected to it. The logical port
7612 # between R1 and alice has a "redirect-chassis" specified,
7613 # i.e. it is the distributed router gateway port.
7614 # Switch alice also has a localnet port defined.
7615 # An additional switch outside has a localnet port and the
7616 # same subnet as alice (172.16.1.0/24).
7617
7618 # Physical network:
7619 # Three hypervisors hv[123].
7620 # hv1 hosts vif foo1.
7621 # hv2 is the "redirect-chassis" that hosts the distributed
7622 # router gateway port.
7623 # hv3 hosts vif outside1.
7624 # In order to show that connectivity works only through hv2,
7625 # an initial round of tests is run without any bridge-mapping
7626 # defined for the localnet on hv2. These tests are expected
7627 # to fail.
7628 # Subsequent tests are run after defining the bridge-mapping
7629 # for the localnet on hv2. These tests are expected to succeed.
7630
7631 # Create three hypervisors and create OVS ports corresponding
7632 # to logical ports.
7633 net_add n1
7634
7635 sim_add hv1
7636 as hv1
7637 ovs-vsctl add-br br-phys
7638 ovn_attach n1 br-phys 192.168.0.1
7639 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7640 set interface hv1-vif1 external-ids:iface-id=foo1 \
7641 options:tx_pcap=hv1/vif1-tx.pcap \
7642 options:rxq_pcap=hv1/vif1-rx.pcap \
7643 ofport-request=1
7644
7645 sim_add hv2
7646 as hv2
7647 ovs-vsctl add-br br-phys
7648 ovn_attach n1 br-phys 192.168.0.2
7649
7650 sim_add hv3
7651 as hv3
7652 ovs-vsctl add-br br-phys
7653 ovn_attach n1 br-phys 192.168.0.3
7654 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7655 set interface hv3-vif1 external-ids:iface-id=outside1 \
7656 options:tx_pcap=hv3/vif1-tx.pcap \
7657 options:rxq_pcap=hv3/vif1-rx.pcap \
7658 ofport-request=1
7659
7660 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7661 # packets for ARP resolution (native tunneling doesn't queue packets
7662 # for ARP resolution).
7663 OVN_POPULATE_ARP
7664
7665 ovn-nbctl create Logical_Router name=R1
7666
7667 ovn-nbctl ls-add foo
7668 ovn-nbctl ls-add alice
7669 ovn-nbctl ls-add outside
7670
7671 # Connect foo to R1
7672 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7673 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7674 type=router options:router-port=foo \
7675 -- lsp-set-addresses rp-foo router
7676
7677 # Connect alice to R1 as distributed router gateway port on hv2
7678 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7679 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7680 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7681 type=router options:router-port=alice \
7682 -- lsp-set-addresses rp-alice router
7683
7684 # Create logical port foo1 in foo
7685 ovn-nbctl lsp-add foo foo1 \
7686 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7687
7688 # Create logical port outside1 in outside
7689 ovn-nbctl lsp-add outside outside1 \
7690 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7691
7692 # Create localnet port in alice
7693 ovn-nbctl lsp-add alice ln-alice
7694 ovn-nbctl lsp-set-addresses ln-alice unknown
7695 ovn-nbctl lsp-set-type ln-alice localnet
7696 ovn-nbctl lsp-set-options ln-alice network_name=phys
7697
7698 # Create localnet port in outside
7699 ovn-nbctl lsp-add outside ln-outside
7700 ovn-nbctl lsp-set-addresses ln-outside unknown
7701 ovn-nbctl lsp-set-type ln-outside localnet
7702 ovn-nbctl lsp-set-options ln-outside network_name=phys
7703
7704 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7705 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7706 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7707
7708
7709 # Allow some time for ovn-northd and ovn-controller to catch up.
7710 # XXX This should be more systematic.
7711 sleep 2
7712
7713 echo "---------NB dump-----"
7714 ovn-nbctl show
7715 echo "---------------------"
7716 ovn-nbctl list logical_router
7717 echo "---------------------"
7718 ovn-nbctl list logical_router_port
7719 echo "---------------------"
7720
7721 echo "---------SB dump-----"
7722 ovn-sbctl list datapath_binding
7723 echo "---------------------"
7724 ovn-sbctl list port_binding
7725 echo "---------------------"
7726 ovn-sbctl dump-flows
7727 echo "---------------------"
7728 ovn-sbctl list chassis
7729 ovn-sbctl list encap
7730 echo "------ Gateway_Chassis dump (SBDB) -------"
7731 ovn-sbctl list Gateway_Chassis
7732 echo "------ Port_Binding chassisredirect -------"
7733 ovn-sbctl find Port_Binding type=chassisredirect
7734 echo "-------------------------------------------"
7735
7736 echo "------ hv1 dump ----------"
7737 as hv1 ovs-ofctl show br-int
7738 as hv1 ovs-ofctl dump-flows br-int
7739 echo "------ hv2 dump ----------"
7740 as hv2 ovs-ofctl show br-int
7741 as hv2 ovs-ofctl dump-flows br-int
7742 echo "------ hv3 dump ----------"
7743 as hv3 ovs-ofctl show br-int
7744 as hv3 ovs-ofctl dump-flows br-int
7745 echo "--------------------------"
7746
7747
7748 # Check that redirect mapping is programmed only on hv2
7749 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7750 ])
7751 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7752 ])
7753 # Check that hv1 sends chassisredirect port traffic to hv2
7754 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7755 ])
7756 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7757 ])
7758 # Check that arp reply on distributed gateway port is only programmed on hv2
7759 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7760 ])
7761 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7762 ])
7763
7764
7765 ip_to_hex() {
7766 printf "%02x%02x%02x%02x" "$@"
7767 }
7768
7769
7770 : > hv2-vif1.expected
7771 : > hv3-vif1.expected
7772
7773 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7774 #
7775 # Causes a packet to be received on INPORT. The packet is an ARP
7776 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7777 # it should be the hardware address of the target to expect to receive in an
7778 # ARP reply; otherwise no reply is expected.
7779 #
7780 # INPORT is an logical switch port number, e.g. 11 for vif11.
7781 # SHA and REPLY_HA are each 12 hex digits.
7782 # SPA and TPA are each 8 hex digits.
7783 test_arp() {
7784 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7785 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7786 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7787
7788 if test X$reply_ha != X; then
7789 # Expect to receive the reply, if any.
7790 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7791 echo $reply >> hv${hv}-vif$inport.expected
7792 fi
7793 }
7794
7795 rtr_ip=$(ip_to_hex 172 16 1 1)
7796 foo_ip=$(ip_to_hex 192 168 1 2)
7797 outside_ip=$(ip_to_hex 172 16 1 3)
7798
7799 echo $rtr_ip
7800 echo $foo_ip
7801 echo $outside_ip
7802
7803 # ARP for router IP address from outside1, no response expected
7804 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7805
7806 # Now check the packets actually received against the ones expected.
7807 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7808
7809 # Send ip packet between foo1 and outside1
7810 src_mac="f00000010203"
7811 dst_mac="000001010203"
7812 src_ip=`ip_to_hex 192 168 1 2`
7813 dst_ip=`ip_to_hex 172 16 1 3`
7814 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7815
7816 # Now check the packets actually received against the ones expected.
7817 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7818
7819 # Now add bridge-mappings on hv2, which should make everything work
7820 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7821
7822 # Allow some time for ovn-northd and ovn-controller to catch up.
7823 # XXX This should be more systematic.
7824 sleep 2
7825
7826 # ARP for router IP address from outside1
7827 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7828
7829 # Now check the packets actually received against the ones expected.
7830 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7831
7832 # Send ip packet between foo1 and outside1
7833 src_mac="f00000010203"
7834 dst_mac="000001010203"
7835 src_ip=`ip_to_hex 192 168 1 2`
7836 dst_ip=`ip_to_hex 172 16 1 3`
7837 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7838
7839 # ARP request packet to expect at outside1
7840 src_mac="000002010203"
7841 src_ip=`ip_to_hex 172 16 1 1`
7842 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7843
7844 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7845
7846 echo $arp_request >> hv3-vif1.expected
7847 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7848
7849 # Send ARP reply from outside1 back to the router
7850 reply_mac="f00000010204"
7851 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7852
7853 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7854
7855 # Allow some time for ovn-northd and ovn-controller to catch up.
7856 # XXX This should be more systematic.
7857 sleep 1
7858
7859 # Packet to Expect at outside1
7860 src_mac="000002010203"
7861 dst_mac="f00000010204"
7862 src_ip=`ip_to_hex 192 168 1 2`
7863 dst_ip=`ip_to_hex 172 16 1 3`
7864 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7865
7866 # Resend packet from foo1 to outside1
7867 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7868
7869 echo "------ hv1 dump ----------"
7870 as hv1 ovs-ofctl show br-int
7871 as hv1 ovs-ofctl dump-flows br-int
7872 echo "------ hv2 dump ----------"
7873 as hv2 ovs-ofctl show br-int
7874 as hv2 ovs-ofctl dump-flows br-int
7875 echo "------ hv3 dump ----------"
7876 as hv3 ovs-ofctl show br-int
7877 as hv3 ovs-ofctl dump-flows br-int
7878 echo "----------------------------"
7879
7880 echo $expected >> hv3-vif1.expected
7881 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7882
7883 #Check ovn-trace over "chassisredirect" port
7884 AT_CAPTURE_FILE([trace])
7885 ovn_trace () {
7886 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7887 }
7888
7889 echo 'ip.ttl--;' > expout
7890 echo 'eth.src = 00:00:02:01:02:03;' >> expout
7891 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7892 echo 'output("ln-alice");' >> expout
7893 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])
7894
7895 # Create logical port alice1 in alice on hv1
7896 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7897 set interface hv1-vif2 external-ids:iface-id=alice1 \
7898 options:tx_pcap=hv1/vif2-tx.pcap \
7899 options:rxq_pcap=hv1/vif2-rx.pcap \
7900 ofport-request=1
7901
7902 ovn-nbctl lsp-add alice alice1 \
7903 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7904
7905 # Create logical port foo2 in foo on hv2
7906 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7907 set interface hv2-vif1 external-ids:iface-id=foo2 \
7908 options:tx_pcap=hv2/vif1-tx.pcap \
7909 options:rxq_pcap=hv2/vif1-rx.pcap \
7910 ofport-request=1
7911
7912 ovn-nbctl lsp-add foo foo2 \
7913 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7914
7915 # Allow some time for ovn-northd and ovn-controller to catch up.
7916 # XXX This should be more systematic.
7917 sleep 1
7918
7919 : > hv1-vif2.expected
7920
7921 # Send ip packet between alice1 and foo2
7922 src_mac="f00000010205"
7923 dst_mac="000002010203"
7924 src_ip=`ip_to_hex 172 16 1 4`
7925 dst_ip=`ip_to_hex 192 168 1 3`
7926 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7927
7928 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7929
7930 # Packet to Expect at foo2
7931 src_mac="000001010203"
7932 dst_mac="f00000010206"
7933 src_ip=`ip_to_hex 172 16 1 4`
7934 dst_ip=`ip_to_hex 192 168 1 3`
7935 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7936
7937 echo $expected >> hv2-vif1.expected
7938 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
7939
7940 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
7941 ])
7942
7943 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
7944
7945 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
7946 ])
7947
7948 OVN_CLEANUP([hv1],[hv2],[hv3])
7949
7950 AT_CLEANUP
7951
7952 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7953 AT_SKIP_IF([test $HAVE_PYTHON = no])
7954 ovn_start
7955 # Create logical switches
7956 ovn-nbctl ls-add ls0
7957 ovn-nbctl ls-add ls1
7958 # Create distributed router
7959 ovn-nbctl create Logical_Router name=lr0
7960 # Add distributed gateway port to distributed router
7961 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7962 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7963 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7964 type=router options:router-port=lrp0 addresses="router"
7965 # Add router port to ls1
7966 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7967 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7968 type=router options:router-port=lrp1 addresses="router"
7969 # Add logical ports for NAT rules
7970 ovn-nbctl lsp-add ls1 foo1 \
7971 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7972 ovn-nbctl lsp-add ls1 foo2 \
7973 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
7974 # Add nat-addresses option
7975 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7976 # Add NAT rules
7977 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7978 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7979 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])
7980 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])
7981
7982 net_add n1
7983 sim_add hv1
7984 as hv1
7985 ovs-vsctl add-br br-phys
7986 ovn_attach n1 br-phys 192.168.0.1
7987
7988 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7989 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])
7990
7991 sim_add hv2
7992 as hv2
7993 ovs-vsctl add-br br-phys
7994 ovn_attach n1 br-phys 192.168.0.2
7995 # Initially test with no bridge-mapping on hv2, expect to receive no packets
7996
7997 sim_add hv3
7998 as hv3
7999 ovs-vsctl add-br br-phys
8000 ovn_attach n1 br-phys 192.168.0.3
8001 # Initially test with no bridge-mapping on hv3
8002
8003 # Create a localnet port.
8004 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8005 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8006 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8007 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8008
8009 # Allow some time for ovn-northd and ovn-controller to catch up.
8010 # XXX This should be more systematic.
8011 sleep 2
8012
8013 # Expect no packets when hv2 bridge-mapping is not present
8014 : > packets
8015 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8016
8017 # Add bridge-mapping on hv2
8018 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8019
8020 # Wait for packets to be received.
8021 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8022 trim_zeros() {
8023 sed 's/\(00\)\{1,\}$//'
8024 }
8025 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8026 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8027 echo $expected > expout
8028 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8029 echo $expected >> expout
8030 AT_CHECK([sort packets], [0], [expout])
8031 sort packets | cat
8032
8033 # Temporarily remove nat-addresses option to avoid race conditions
8034 # due to GARP backoff
8035 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8036
8037 reset_pcap_file() {
8038 local iface=$1
8039 local pcap_file=$2
8040 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8041 options:rxq_pcap=dummy-rx.pcap
8042 rm -f ${pcap_file}*.pcap
8043 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8044 options:rxq_pcap=${pcap_file}-rx.pcap
8045 }
8046
8047 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8048
8049 # Add OVS ports for foo1 and foo2 on hv3
8050 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8051 set interface hv3-vif1 external-ids:iface-id=foo1 \
8052 ofport-request=1
8053 ovs-vsctl -- add-port br-int hv3-vif2 -- \
8054 set interface hv3-vif2 external-ids:iface-id=foo2 \
8055 ofport-request=2
8056
8057 # Add bridge-mapping on hv3
8058 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8059
8060 # Re-add nat-addresses option
8061 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8062
8063 # Wait for packets to be received.
8064 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8065 trim_zeros() {
8066 sed 's/\(00\)\{1,\}$//'
8067 }
8068
8069 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8070 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8071 echo $expected >> expout
8072 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8073 echo $expected >> expout
8074 AT_CHECK([sort packets], [0], [expout])
8075 sort packets | cat
8076
8077 OVN_CLEANUP([hv1],[hv2],[hv3])
8078
8079 AT_CLEANUP
8080
8081 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8082 AT_KEYWORDS([ovn-nd_ra])
8083 AT_SKIP_IF([test $HAVE_PYTHON = no])
8084 ovn_start
8085
8086 # In this test case we create 1 lswitch with 3 VIF ports attached,
8087 # and a lrouter connected to the lswitch.
8088 # We generate the Router solicitation packet and verify the Router Advertisement
8089 # reply packet from the ovn-controller.
8090
8091 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8092 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8093 # 'slaac' to allow lrp0 send RA for SLAAC mode.
8094 ovn-nbctl ls-add lsw0
8095 ovn-nbctl lr-add lr0
8096 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8097 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8098 ovn-nbctl \
8099 -- lsp-add lsw0 lsp0 \
8100 -- set Logical_Switch_Port lsp0 type=router \
8101 options:router-port=lrp0 \
8102 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8103 net_add n1
8104 sim_add hv1
8105 as hv1
8106 ovs-vsctl add-br br-phys
8107 ovn_attach n1 br-phys 192.168.0.2
8108
8109 ovn-nbctl lsp-add lsw0 lp1
8110 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8111 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"
8112
8113 ovn-nbctl lsp-add lsw0 lp2
8114 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8115 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"
8116
8117 ovn-nbctl lsp-add lsw0 lp3
8118 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8119 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"
8120
8121 # Add ACL rule for ICMPv6 on lsw0
8122 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8123 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8124 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8125 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8126
8127 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8128 set interface hv1-vif1 external-ids:iface-id=lp1 \
8129 options:tx_pcap=hv1/vif1-tx.pcap \
8130 options:rxq_pcap=hv1/vif1-rx.pcap \
8131 ofport-request=1
8132
8133 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8134 set interface hv1-vif2 external-ids:iface-id=lp2 \
8135 options:tx_pcap=hv1/vif2-tx.pcap \
8136 options:rxq_pcap=hv1/vif2-rx.pcap \
8137 ofport-request=2
8138
8139 ovs-vsctl -- add-port br-int hv1-vif3 -- \
8140 set interface hv1-vif3 external-ids:iface-id=lp3 \
8141 options:tx_pcap=hv1/vif3-tx.pcap \
8142 options:rxq_pcap=hv1/vif3-rx.pcap \
8143 ofport-request=3
8144
8145 # Allow some time for ovn-northd and ovn-controller to catch up.
8146 # XXX This should be more systematic.
8147 sleep 1
8148
8149 reset_pcap_file() {
8150 local iface=$1
8151 local pcap_file=$2
8152 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8153 options:rxq_pcap=dummy-rx.pcap
8154 rm -f ${pcap_file}*.pcap
8155 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8156 options:rxq_pcap=${pcap_file}-rx.pcap
8157 }
8158
8159 # Make sure that ovn-controller has installed the corresponding OF Flow.
8160 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"`])
8161
8162 # This shell function sends a Router Solicitation packet.
8163 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8164 test_ipv6_ra() {
8165 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8166 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8167
8168 local len=24
8169 local mtu_opt=""
8170 if test $mtu != 0; then
8171 len=`expr $len + 8`
8172 mtu_opt=05010000${mtu}
8173 fi
8174
8175 if test ${#prefix_opt} != 0; then
8176 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8177 len=`expr $len + ${#prefix_opt} / 2`
8178 fi
8179
8180 len=$(printf "%x" $len)
8181 local lrp_mac=fa163e000001
8182 local lrp_lla=fe80000000000000f8163efffe000001
8183 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8184 echo $reply >> $inport.expected
8185
8186 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8187 }
8188
8189 AT_CAPTURE_FILE([ofctl_monitor0.log])
8190 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8191 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8192
8193 # MTU is not set and the address mode is set to slaac
8194 addr_mode=00
8195 default_prefix_option_config=030440c0ffffffffffffffff00000000
8196 src_mac=fa163e000002
8197 src_lla=fe80000000000000f8163efffe000002
8198 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8199
8200 # NXT_RESUME should be 1.
8201 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8202
8203 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8204
8205 cat 1.expected | cut -c -112 > expout
8206 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8207
8208 # Skipping the ICMPv6 checksum.
8209 cat 1.expected | cut -c 117- > expout
8210 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8211
8212 rm -f *.expected
8213 reset_pcap_file hv1-vif1 hv1/vif1
8214 reset_pcap_file hv1-vif2 hv1/vif2
8215 reset_pcap_file hv1-vif3 hv1/vif3
8216
8217 # Set the MTU to 1500
8218 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8219
8220 # Make sure that ovn-controller has installed the corresponding OF Flow.
8221 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"`])
8222
8223 addr_mode=00
8224 default_prefix_option_config=030440c0ffffffffffffffff00000000
8225 src_mac=fa163e000003
8226 src_lla=fe80000000000000f8163efffe000003
8227 mtu=000005dc
8228
8229 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8230
8231 # NXT_RESUME should be 2.
8232 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8233
8234 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8235
8236 cat 2.expected | cut -c -112 > expout
8237 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8238
8239 # Skipping the ICMPv6 checksum.
8240 cat 2.expected | cut -c 117- > expout
8241 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8242
8243 rm -f *.expected
8244 reset_pcap_file hv1-vif1 hv1/vif1
8245 reset_pcap_file hv1-vif2 hv1/vif2
8246 reset_pcap_file hv1-vif3 hv1/vif3
8247
8248 # Set the address mode to dhcpv6_stateful
8249 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8250 # Make sure that ovn-controller has installed the corresponding OF Flow.
8251 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"`])
8252
8253 addr_mode=80
8254 default_prefix_option_config=""
8255 src_mac=fa163e000004
8256 src_lla=fe80000000000000f8163efffe000004
8257 mtu=000005dc
8258
8259 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8260
8261 # NXT_RESUME should be 3.
8262 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8263
8264 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8265
8266 cat 3.expected | cut -c -112 > expout
8267 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8268
8269 # Skipping the ICMPv6 checksum.
8270 cat 3.expected | cut -c 117- > expout
8271 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8272
8273 rm -f *.expected
8274 reset_pcap_file hv1-vif1 hv1/vif1
8275 reset_pcap_file hv1-vif2 hv1/vif2
8276 reset_pcap_file hv1-vif3 hv1/vif3
8277
8278 # Set the address mode to dhcpv6_stateless
8279 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8280 # Make sure that ovn-controller has installed the corresponding OF Flow.
8281 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"`])
8282
8283 addr_mode=40
8284 default_prefix_option_config=030440c0ffffffffffffffff00000000
8285 src_mac=fa163e000002
8286 src_lla=fe80000000000000f8163efffe000002
8287 mtu=000005dc
8288
8289 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8290
8291 # NXT_RESUME should be 4.
8292 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8293
8294 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8295
8296 cat 1.expected | cut -c -112 > expout
8297 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8298
8299 # Skipping the ICMPv6 checksum.
8300 cat 1.expected | cut -c 117- > expout
8301 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8302
8303 rm -f *.expected
8304 reset_pcap_file hv1-vif1 hv1/vif1
8305 reset_pcap_file hv1-vif2 hv1/vif2
8306 reset_pcap_file hv1-vif3 hv1/vif3
8307
8308 # Set the address mode to invalid.
8309 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8310 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8311 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"`])
8312
8313 addr_mode=40
8314 default_prefix_option_config=""
8315 src_mac=fa163e000002
8316 src_lla=fe80000000000000f8163efffe000002
8317 mtu=000005dc
8318
8319 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8320
8321 # NXT_RESUME should be 4 only.
8322 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8323
8324 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8325 AT_CHECK([cat 1.packets], [0], [])
8326
8327 OVN_CLEANUP([hv1])
8328 AT_CLEANUP
8329
8330 AT_SETUP([ovn -- /32 router IP address])
8331 AT_SKIP_IF([test $HAVE_PYTHON = no])
8332 ovn_start
8333
8334 # Logical network:
8335 # 2 LS 'foo' and 'alice' connected via router R1.
8336 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8337 # nexthop to push traffic to a logical port in switch 'alice'
8338
8339 ovn-nbctl lr-add R1
8340
8341 ovn-nbctl ls-add foo
8342 ovn-nbctl ls-add alice
8343
8344 # Connect foo to R1
8345 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8346 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8347 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8348
8349 # Connect alice to R1.
8350 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8351 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8352 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8353
8354 # Create logical port foo1 in foo
8355 ovn-nbctl lsp-add foo foo1 \
8356 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8357
8358 # Create logical port alice1 in alice
8359 ovn-nbctl lsp-add alice alice1 \
8360 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8361
8362 #install default route in R1 to use alice1's IP address as nexthop
8363 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8364
8365 # Create two hypervisor and create OVS ports corresponding to logical ports.
8366 net_add n1
8367
8368 sim_add hv1
8369 as hv1
8370 ovs-vsctl add-br br-phys
8371 ovn_attach n1 br-phys 192.168.0.1
8372 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8373 set interface hv1-vif1 external-ids:iface-id=foo1 \
8374 options:tx_pcap=hv1/vif1-tx.pcap \
8375 options:rxq_pcap=hv1/vif1-rx.pcap \
8376 ofport-request=1
8377
8378 sim_add hv2
8379 as hv2
8380 ovs-vsctl add-br br-phys
8381 ovn_attach n1 br-phys 192.168.0.2
8382 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8383 set interface hv2-vif1 external-ids:iface-id=alice1 \
8384 options:tx_pcap=hv2/vif1-tx.pcap \
8385 options:rxq_pcap=hv2/vif1-rx.pcap \
8386 ofport-request=1
8387
8388
8389 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8390 # packets for ARP resolution (native tunneling doesn't queue packets
8391 # for ARP resolution).
8392 OVN_POPULATE_ARP
8393
8394 # Allow some time for ovn-northd and ovn-controller to catch up.
8395 # XXX This should be more systematic.
8396 sleep 1
8397
8398 ip_to_hex() {
8399 printf "%02x%02x%02x%02x" "$@"
8400 }
8401
8402 # Send ip packets between foo1 and alice1
8403 src_mac="f00000010203"
8404 dst_mac="000000010203"
8405 src_ip=`ip_to_hex 192 168 1 2`
8406 dst_ip=`ip_to_hex 10 0 0 2`
8407 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8408
8409 # Send the first packet to trigger a ARP response and population of
8410 # mac_bindings table.
8411 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8412 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8413 ovn-nbctl --wait=hv sync
8414 # Send the second packet to reach the destination.
8415 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8416
8417 # Packet to Expect at 'alice1'
8418 src_mac="000000010204"
8419 dst_mac="f00000010204"
8420 src_ip=`ip_to_hex 192 168 1 2`
8421 dst_ip=`ip_to_hex 10 0 0 2`
8422 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8423
8424 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8425
8426 OVN_CLEANUP([hv1],[hv2])
8427
8428 AT_CLEANUP
8429
8430 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8431 AT_SKIP_IF([test $HAVE_PYTHON = no])
8432 ovn_start
8433
8434 ovn-nbctl ls-add ls1
8435
8436 # Add localport to the switch
8437 ovn-nbctl lsp-add ls1 lp01
8438 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8439 ovn-nbctl lsp-set-type lp01 localport
8440
8441 net_add n1
8442
8443 for i in 1 2; do
8444 sim_add hv$i
8445 as hv$i
8446 ovs-vsctl add-br br-phys
8447 ovn_attach n1 br-phys 192.168.0.$i
8448 ovs-vsctl add-port br-int vif01 -- \
8449 set Interface vif01 external-ids:iface-id=lp01 \
8450 options:tx_pcap=hv${i}/vif01-tx.pcap \
8451 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8452 ofport-request=${i}0
8453
8454 ovs-vsctl add-port br-int vif${i}1 -- \
8455 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8456 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8457 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8458 ofport-request=${i}1
8459
8460 ovn-nbctl lsp-add ls1 lp${i}1
8461 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8462 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8463
8464 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8465 done
8466
8467 ovn-nbctl --wait=sb sync
8468 ovn-sbctl dump-flows
8469
8470 OVN_POPULATE_ARP
8471
8472 # Given the name of a logical port, prints the name of the hypervisor
8473 # on which it is located.
8474 vif_to_hv() {
8475 echo hv${1%?}
8476 }
8477 #
8478 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8479 #
8480 # This shell function causes a packet to be received on INPORT. The packet's
8481 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8482 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8483 # logical switch port numbers, e.g. 11 for vif11.
8484 #
8485 # EOUT is the end-to-end output port, that is, where the packet will end up
8486 # after possibly bouncing through one or more localnet ports. LOUT is the
8487 # logical output port, which might be a localnet port, as seen by ovn-trace
8488 # (which doesn't know what localnet ports are connected to and therefore can't
8489 # figure out the end-to-end answer).
8490 #
8491 # DEFHV is the default hypervisor from where the packet is going to be sent
8492 # if the source port is a localport.
8493 for i in 1 2; do
8494 for j in 0 1; do
8495 : > $i$j.expected
8496 done
8497 done
8498 test_packet() {
8499 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8500 echo "$@"
8501
8502 # First try tracing the packet.
8503 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8504 if test $lout != drop; then
8505 echo "output(\"$lout\");"
8506 fi > expout
8507 AT_CAPTURE_FILE([trace])
8508 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8509
8510 # Then actually send a packet, for an end-to-end test.
8511 local packet=$(echo $dst$src | sed 's/://g')${eth}
8512 hv=`vif_to_hv $inport`
8513 # If hypervisor 0 (localport) use the defhv parameter
8514 if test $hv = hv0; then
8515 hv=$defhv
8516 fi
8517 vif=vif$inport
8518 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8519 if test $eout != drop; then
8520 echo $packet >> ${eout#lp}.expected
8521 fi
8522 }
8523
8524
8525 # lp11 and lp21 are on different hypervisors
8526 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8527 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8528
8529 # Both VIFs should be able to reach the localport on their own HV
8530 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8531 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8532
8533 # Packet sent from localport on same hv should reach the vif
8534 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8535 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8536
8537 # Packet sent from localport on different hv should be dropped
8538 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8539 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8540
8541 # Now check the packets actually received against the ones expected.
8542 for i in 1 2; do
8543 for j in 0 1; do
8544 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8545 done
8546 done
8547
8548 OVN_CLEANUP([hv1],[hv2])
8549
8550 AT_CLEANUP
8551
8552 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8553 AT_SKIP_IF([test $HAVE_PYTHON = no])
8554 ovn_start
8555
8556 net_add n1
8557
8558 # create gateways with external network connectivity
8559
8560 for i in 1 2; do
8561 sim_add gw$i
8562 as gw$i
8563 ovs-vsctl add-br br-phys
8564 ovn_attach n1 br-phys 192.168.0.$i
8565 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8566 done
8567
8568 ovn-nbctl ls-add inside
8569 ovn-nbctl ls-add outside
8570
8571 # create hypervisors with a vif port each to an internal network
8572
8573 for i in 1 2; do
8574 sim_add hv$i
8575 as hv$i
8576 ovs-vsctl add-br br-phys
8577 ovn_attach n1 br-phys 192.168.0.1$i
8578 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8579 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8580 options:tx_pcap=hv$i/vif1-tx.pcap \
8581 options:rxq_pcap=hv$i/vif1-rx.pcap \
8582 ofport-request=1
8583
8584 ovn-nbctl lsp-add inside inside$i \
8585 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8586
8587 done
8588
8589 OVN_POPULATE_ARP
8590
8591 ovn-nbctl create Logical_Router name=R1
8592
8593 # Connect inside to R1
8594 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8595 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8596 type=router options:router-port=inside \
8597 -- lsp-set-addresses rp-inside router
8598
8599 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8600 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8601
8602 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8603 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8604 --id=@gc1 create Gateway_Chassis \
8605 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8606 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8607
8608 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8609 type=router options:router-port=outside \
8610 -- lsp-set-addresses rp-outside router
8611
8612 # Create localnet port in outside
8613 ovn-nbctl lsp-add outside ln-outside
8614 ovn-nbctl lsp-set-addresses ln-outside unknown
8615 ovn-nbctl lsp-set-type ln-outside localnet
8616 ovn-nbctl lsp-set-options ln-outside network_name=phys
8617
8618 # Allow some time for ovn-northd and ovn-controller to catch up.
8619 # XXX This should be more systematic.
8620 ovn-nbctl --wait=hv --timeout=3 sync
8621
8622 echo "---------NB dump-----"
8623 ovn-nbctl show
8624 echo "---------------------"
8625 ovn-nbctl list logical_router
8626 echo "---------------------"
8627 ovn-nbctl list logical_router_port
8628 echo "---------------------"
8629
8630 echo "---------SB dump-----"
8631 ovn-sbctl list datapath_binding
8632 echo "---------------------"
8633 ovn-sbctl list port_binding
8634 echo "---------------------"
8635 ovn-sbctl dump-flows
8636 echo "---------------------"
8637 ovn-sbctl list chassis
8638 ovn-sbctl list encap
8639 echo "---------------------"
8640 echo "------ Gateway_Chassis dump (SBDB) -------"
8641 ovn-sbctl list Gateway_Chassis
8642 echo "------ Port_Binding chassisredirect -------"
8643 ovn-sbctl find Port_Binding type=chassisredirect
8644 echo "-------------------------------------------"
8645
8646 for chassis in gw1 gw2 hv1 hv2; do
8647 as $chassis
8648 echo "------ $chassis dump ----------"
8649 ovs-ofctl show br-int
8650 ovs-ofctl dump-flows br-int
8651 echo "--------------------------"
8652 done
8653 function bfd_dump() {
8654 for chassis in gw1 gw2 hv1 hv2; do
8655 as $chassis
8656 echo "------ $chassis dump (BFD)----"
8657 echo "BFD (from $chassis):"
8658 # dump BFD config and status to the other chassis
8659 for chassis2 in gw1 gw2 hv1 hv2; do
8660 if [[ "$chassis" != "$chassis2" ]]; then
8661 echo " -> $chassis2:"
8662 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8663 fi
8664 done
8665 echo "--------------------------"
8666 done
8667 }
8668
8669 bfd_dump
8670
8671 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8672 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8673 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8674 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8675
8676 echo $hv1_gw1_ofport
8677 echo $hv1_gw2_ofport
8678 echo $hv2_gw1_ofport
8679 echo $hv2_gw2_ofport
8680
8681 echo "--- hv1 ---"
8682 as hv1 ovs-ofctl dump-flows br-int table=32
8683
8684 echo "--- hv2 ---"
8685 as hv2 ovs-ofctl dump-flows br-int table=32
8686
8687 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8688 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8689
8690 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
8691 ])
8692
8693 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
8694 ])
8695
8696 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8697
8698 # make sure that flows for handling the outside router port reside on gw1
8699 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8700 ]])
8701 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8702 ]])
8703
8704 # make sure ARP responder flows for outside router port reside on gw1 too
8705 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8706 ]])
8707 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8708 ]])
8709
8710
8711
8712 # check that the chassis redirect port has been claimed by the gw1 chassis
8713 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8714 [0],[[1
8715 ]])
8716
8717
8718 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8719
8720 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8721 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8722 --id=@gc1 create Gateway_Chassis \
8723 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8724 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8725
8726
8727 # XXX: Let the change propagate down to the ovn-controllers
8728 ovn-nbctl --wait=hv --timeout=3 sync
8729
8730 # we make sure that the hypervisors noticed, and inverted the slave ports
8731 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
8732 ])
8733
8734 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
8735 ])
8736
8737 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8738 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8739 [0],[[1
8740 ]])
8741
8742 # check BFD enablement on tunnel ports from gw1 #########
8743 as gw1
8744 for chassis in gw2 hv1 hv2; do
8745 echo "checking gw1 -> $chassis"
8746 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8747 [[enable=true
8748 ]])
8749 done
8750
8751
8752 # check BFD enablement on tunnel ports from gw2 ##########
8753 as gw2
8754 for chassis in gw1 hv1 hv2; do
8755 echo "checking gw2 -> $chassis"
8756 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8757 [[enable=true
8758 ]])
8759 done
8760
8761 # check BFD enablement on tunnel ports from hv1 ###########
8762 as hv1
8763 for chassis in gw1 gw2; do
8764 echo "checking hv1 -> $chassis"
8765 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8766 [[enable=true
8767 ]])
8768 done
8769 # make sure BFD is not enabled to hv2, we don't need it
8770 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8771 [[enable=false
8772 ]])
8773
8774
8775 # check BFD enablement on tunnel ports from hv2 ##########
8776 as hv2
8777 for chassis in gw1 gw2; do
8778 echo "checking hv2 -> $chassis"
8779 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8780 [[enable=true
8781 ]])
8782 done
8783 # make sure BFD is not enabled to hv1, we don't need it
8784 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8785 [[enable=false
8786 ]])
8787
8788 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8789
8790 # make sure that flows for handling the outside router port reside on gw2 now
8791 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8792 ]])
8793 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8794 ]])
8795
8796 # disconnect GW2 from the network, GW1 should take over
8797 as gw2
8798 port=${sandbox}_br-phys
8799 as main ovs-vsctl del-port n1 $port
8800 sleep 4
8801
8802 bfd_dump
8803
8804 # make sure that flows for handling the outside router port reside on gw2 now
8805 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8806 ]])
8807 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8808 ]])
8809
8810 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8811 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8812 [0],[[1
8813 ]])
8814
8815 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8816
8817 AT_CLEANUP
8818
8819 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8820 AT_SKIP_IF([test $HAVE_PYTHON = no])
8821 ovn_start
8822 ovn-nbctl ls-add ls0
8823 ovn-nbctl ls-add ls1
8824 ovn-nbctl create Logical_Router name=lr0
8825 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8826
8827 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8828 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8829 --id=@gc1 create Gateway_Chassis \
8830 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8831 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8832
8833 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8834 type=router options:router-port=lrp0 addresses="router"
8835 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8836 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8837 type=router options:router-port=lrp1 addresses="router"
8838
8839 # Add NAT rules
8840 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8841
8842 net_add n1
8843 sim_add hv1
8844 as hv1
8845 ovs-vsctl add-br br-phys
8846 ovn_attach n1 br-phys 192.168.0.1
8847 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8848 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])
8849
8850 sim_add hv2
8851 as hv2
8852 ovs-vsctl add-br br-phys
8853 ovn_attach n1 br-phys 192.168.0.2
8854 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8855
8856 sim_add hv3
8857 as hv3
8858 ovs-vsctl add-br br-phys
8859 ovn_attach n1 br-phys 192.168.0.3
8860 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8861
8862 # Create a localnet port.
8863 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8864 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8865 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8866 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8867
8868 # wait for earlier changes to take effect
8869 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
8870
8871 reset_pcap_file() {
8872 local iface=$1
8873 local pcap_file=$2
8874 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8875 options:rxq_pcap=dummy-rx.pcap
8876 rm -f ${pcap_file}*.pcap
8877 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8878 options:rxq_pcap=${pcap_file}-rx.pcap
8879 }
8880
8881 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8882 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8883 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8884 # add nat-addresses option
8885 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8886
8887 # Wait for packets to be received through hv2.
8888 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8889 trim_zeros() {
8890 sed 's/\(00\)\{1,\}$//'
8891 }
8892
8893 only_broadcast_from_lrp1() {
8894 grep "fffffffffffff00000000001"
8895 }
8896
8897 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
8898 echo $garp > expout
8899
8900 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
8901 echo "packets on hv1-snoopvif:"
8902 cat hv1_snoop_tx
8903 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
8904 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8905 echo "packets on hv2 br-phys tx"
8906 cat hv2_br_phys_tx
8907 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
8908 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8909 echo "packets on hv3 br-phys tx"
8910 cat hv3_br_phys_tx
8911 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8912
8913
8914 # at this point, we invert the priority of the gw chassis between hv2 and hv3
8915
8916 ovn-nbctl --wait=hv \
8917 --id=@gc0 create Gateway_Chassis \
8918 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8919 --id=@gc1 create Gateway_Chassis \
8920 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8921 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8922
8923
8924 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8925 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8926 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8927
8928 # Wait for packets to be received.
8929 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8930 trim_zeros() {
8931 sed 's/\(00\)\{1,\}$//'
8932 }
8933
8934 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8935 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8936 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8937 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8938 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8939 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8940
8941 # change localnet port tag.
8942 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8943
8944 # wait for earlier changes to take effect
8945 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
8946
8947 # update nat-addresses option
8948 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
8949 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8950
8951 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8952 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8953 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8954
8955 # Wait for packets to be received.
8956 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8957 trim_zeros() {
8958 sed 's/\(00\)\{1,\}$//'
8959 }
8960
8961 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
8962 echo $garp > expout
8963
8964 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8965 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8966 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8967 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8968 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8969 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8970
8971 OVN_CLEANUP([hv1],[hv2],[hv3])
8972
8973 AT_CLEANUP
8974
8975 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8976 AT_SKIP_IF([test $HAVE_PYTHON = no])
8977 ovn_start
8978
8979 net_add n1
8980
8981 # create two gateways with external network connectivity
8982 for i in 1 2; do
8983 sim_add gw$i
8984 as gw$i
8985 ovs-vsctl add-br br-phys
8986 ovn_attach n1 br-phys 192.168.0.$i
8987 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8988 done
8989
8990 ovn-nbctl ls-add inside
8991 ovn-nbctl ls-add outside
8992
8993 # create one hypervisors with a vif port the internal network
8994 sim_add hv1
8995 as hv1
8996 ovs-vsctl add-br br-phys
8997 ovn_attach n1 br-phys 192.168.0.11
8998 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8999 set interface hv1-vif1 external-ids:iface-id=inside1 \
9000 options:tx_pcap=hv1/vif1-tx.pcap \
9001 options:rxq_pcap=hv1/vif1-rx.pcap \
9002 ofport-request=1
9003
9004 ovn-nbctl lsp-add inside inside1 \
9005 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9006
9007
9008 OVN_POPULATE_ARP
9009
9010 ovn-nbctl create Logical_Router name=R1
9011
9012 # Connect inside to R1
9013 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9014 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9015 type=router options:router-port=inside \
9016 -- lsp-set-addresses rp-inside router
9017
9018 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9019 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9020
9021 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9022 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9023 --id=@gc1 create Gateway_Chassis \
9024 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9025 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9026
9027 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9028 type=router options:router-port=outside \
9029 -- lsp-set-addresses rp-outside router
9030
9031 # Create localnet port in outside
9032 ovn-nbctl lsp-add outside ln-outside
9033 ovn-nbctl lsp-set-addresses ln-outside unknown
9034 ovn-nbctl lsp-set-type ln-outside localnet
9035 ovn-nbctl lsp-set-options ln-outside network_name=phys
9036
9037 # Allow some time for ovn-northd and ovn-controller to catch up.
9038 ovn-nbctl --wait=hv --timeout=3 sync
9039
9040 # currently when ovn-controller is restarted, the old entry is deleted
9041 # and a new one is created, which leaves the Gateway_Chassis with
9042 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
9043 # doesn't have the same effect because "name" is conserved, and the
9044 # Chassis entry is not replaced.
9045
9046 > gw1/ovn-controller.log
9047
9048 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9049 ovn-sbctl destroy Chassis $gw2_chassis
9050
9051 # Ensure ovn-controller has processed latest sbdb update
9052 # ovn-nbctl --wait=hv sync
9053
9054 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9055
9056 OVN_CLEANUP([gw1],[gw2],[hv1])
9057
9058 AT_CLEANUP
9059
9060 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9061 AT_KEYWORDS([ovn-nd_ns for unknown mac])
9062 AT_SKIP_IF([test $HAVE_PYTHON = no])
9063 ovn_start
9064
9065 ovn-nbctl ls-add sw0_ip6
9066 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9067 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9068 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9069
9070 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9071 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9072
9073 ovn-nbctl lr-add lr0_ip6
9074 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
9075 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9076 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9077 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9078 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9079 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9080
9081 ovn-nbctl ls-add public
9082 ovn-nbctl lsp-add public ln-public
9083 ovn-nbctl lsp-set-addresses ln-public unknown
9084 ovn-nbctl lsp-set-type ln-public localnet
9085 ovn-nbctl lsp-set-options ln-public network_name=phys
9086
9087 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
9088 2001:db8:1:0:200:02ff:fe01:0204/64 \
9089 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9090
9091
9092 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9093 rp-ip6_public type=router options:router-port=ip6_public \
9094 -- lsp-set-addresses rp-ip6_public router
9095
9096 net_add n1
9097 sim_add hv1
9098 as hv1
9099 ovs-vsctl add-br br-phys
9100 ovn_attach n1 br-phys 192.168.0.2
9101
9102 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9103 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9104 options:tx_pcap=hv1/vif1-tx.pcap \
9105 options:rxq_pcap=hv1/vif1-rx.pcap \
9106 ofport-request=1
9107 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9108
9109 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9110 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9111
9112 # There is only one chassis.
9113 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9114 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
9115
9116 trim_zeros() {
9117 sed 's/\(00\)\{1,\}$//'
9118 }
9119
9120 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9121 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
9122 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9123 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9124 # This function sends ipv6 packet
9125 test_ipv6() {
9126 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9127 dst_ip=20010db800010000020002fffe010205
9128
9129 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9130 packet=${packet}8000000000000000
9131 shift; shift; shift; shift
9132
9133 dst_mac=3333ff010205
9134 src_mac=000002010204
9135 mcast_node_ip=ff0200000000000000000001ff010205
9136 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9137 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9138 expected_packet=${expected_packet}0101${src_mac}
9139
9140 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9141 echo $expected_packet >> ipv6_ns.expected
9142 }
9143
9144 src_mac=506400000002
9145 dst_mac=00000000af01
9146 src_ip=aef0000000000000526400fffe000002
9147 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9148 # should be received by the ports attached to br-phys.
9149 test_ipv6 1 $src_mac $dst_mac $src_ip 2
9150
9151 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9152 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9153
9154 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9155 trim_zeros > 1.packets
9156 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9157 trim_zeros > 2.packets
9158
9159 cat ipv6_ns.expected | cut -c -112 > expout
9160 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9161 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9162
9163 # Skipping the ICMPv6 checksum
9164 cat ipv6_ns.expected | cut -c 117- > expout
9165 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9166 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9167
9168 OVN_CLEANUP([hv1])
9169
9170 AT_CLEANUP
9171
9172 AT_SETUP([ovn -- options:requested-chassis for logical port])
9173 ovn_start
9174
9175 net_add n1
9176
9177 ovn-nbctl ls-add ls0
9178 ovn-nbctl lsp-add ls0 lsp0
9179
9180 # create two hypervisors, each with one vif port
9181 sim_add hv1
9182 as hv1
9183 ovs-vsctl add-br br-phys
9184 ovn_attach n1 br-phys 192.168.0.11
9185 ovs-vsctl -- add-port br-int hv1-vif0 -- \
9186 set Interface hv1-vif0 ofport-request=1
9187
9188 sim_add hv2
9189 as hv2
9190 ovs-vsctl add-br br-phys
9191 ovn_attach n1 br-phys 192.168.0.12
9192 ovs-vsctl -- add-port br-int hv2-vif0 -- \
9193 set Interface hv2-vif0 ofport-request=1
9194
9195 # Allow only chassis hv1 to bind logical port lsp0.
9196 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9197
9198 # Allow some time for ovn-northd and ovn-controller to catch up.
9199 ovn-nbctl --wait=hv --timeout=3 sync
9200
9201 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9202 ovn-sbctl wait-until chassis hv1
9203 ovn-sbctl wait-until chassis hv2
9204 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9205 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9206
9207 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9208 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9209 as hv2
9210 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9211
9212 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9213 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9214
9215 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9216 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9217 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9218
9219 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9220 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9221 as hv1
9222 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9223
9224 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9225 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9226
9227 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9228 as hv1 ovs-ofctl dump-flows br-int
9229 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9230 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9231
9232 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9233 # the requested chassis for lsp0 is changed from hv1 to hv2.
9234 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9235
9236 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9237 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9238 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
9239
9240 # (6) Chassis hv2 should add flows and hv1 should not.
9241 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9242 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9243
9244 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9245 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9246
9247 OVN_CLEANUP([hv1],[hv2])
9248
9249 AT_CLEANUP
9250
9251 AT_SETUP([ovn -- options:requested-chassis with hostname])
9252
9253 ovn_start
9254
9255 ovn-nbctl ls-add ls0
9256 ovn-nbctl lsp-add ls0 lsp0
9257
9258 net_add n1
9259 sim_add hv1
9260 as hv1
9261 ovs-vsctl add-br br-phys
9262 ovn_attach n1 br-phys 192.168.0.11
9263 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
9264
9265 ovn-sbctl wait-until chassis hv1
9266 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9267 echo "hv1_hostname=${hv1_hostname}"
9268 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9269 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9270
9271 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9272 echo "hv1_uuid=${hv1_uuid}"
9273 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9274 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9275 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9276 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9277
9278 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9279 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9280 ovn-nbctl --wait=hv --timeout=3 sync
9281 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9282 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9283 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9284
9285 OVN_CLEANUP([hv1])
9286
9287 AT_CLEANUP
9288
9289 AT_SETUP([ovn -- IPv6 periodic RA])
9290 ovn_start
9291
9292 # This test sets up two hypervisors.
9293 # hv1 and hv2 run ovn-controllers, and
9294 # each has a VIF connected to the same
9295 # logical switch in OVN. The logical
9296 # switch is connected to a logical
9297 # router port that is configured to send
9298 # periodic router advertisements.
9299 #
9300 # The reason for having two ovn-controller
9301 # hypervisors is to ensure that the
9302 # periodic RAs being sent by each ovn-controller
9303 # are kept to their local hypervisors. If the
9304 # packets are not kept local, then each port
9305 # will receive too many RAs.
9306
9307 net_add n1
9308 sim_add hv1
9309 sim_add hv2
9310 as hv1
9311 ovs-vsctl add-br br-phys
9312 ovn_attach n1 br-phys 192.168.0.2
9313 as hv2
9314 ovs-vsctl add-br br-phys
9315 ovn_attach n1 br-phys 192.168.0.3
9316
9317 ovn-nbctl lr-add ro
9318 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
9319
9320 ovn-nbctl ls-add sw
9321 ovn-nbctl lsp-add sw sw-ro
9322 ovn-nbctl lsp-set-type sw-ro router
9323 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9324 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9325 ovn-nbctl lsp-add sw sw-p1
9326 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9327 ovn-nbctl lsp-add sw sw-p2
9328 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9329
9330 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9331 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9332 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9333 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9334
9335 for i in 1 2 ; do
9336 as hv$i
9337 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9338 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9339 options:tx_pcap=hv$i/vif1-tx.pcap \
9340 options:rxq_pcap=hv$i/vif1-rx.pcap \
9341 ofport-request=1
9342 done
9343
9344 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9345 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
9346
9347 reset_pcap_file() {
9348 local iface=$1
9349 local pcap_file=$2
9350 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9351 options:rxq_pcap=dummy-rx.pcap
9352 rm -f ${pcap_file}*.pcap
9353 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9354 options:rxq_pcap=${pcap_file}-rx.pcap
9355
9356 }
9357
9358 construct_expected_ra() {
9359 local src_mac=000000000001
9360 local dst_mac=333300000001
9361 local src_addr=fe80000000000000020000fffe000001
9362 local dst_addr=ff020000000000000000000000000001
9363
9364 local mtu=$1
9365 local ra_mo=$2
9366 local ra_prefix_la=$3
9367
9368 local slla=0101${src_mac}
9369 local mtu_opt=""
9370 if test $mtu != 0; then
9371 mtu_opt=05010000${mtu}
9372 fi
9373 shift 3
9374
9375 local prefix=""
9376 while [[ $# -gt 0 ]] ; do
9377 local size=$1
9378 local net=$2
9379 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9380 shift 2
9381 done
9382
9383 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
9384 local icmp=8600XXXX${ra}
9385
9386 local ip_len=$(expr ${#icmp} / 2)
9387 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
9388
9389 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9390 local eth=${dst_mac}${src_mac}86dd${ip}
9391 local packet=${eth}
9392 echo $packet >> expected
9393 }
9394
9395 ra_test() {
9396 construct_expected_ra $@
9397
9398 for i in hv1 hv2 ; do
9399 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9400
9401 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9402
9403 cat expected | cut -c -112 > expout
9404 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9405
9406 # Skip ICMPv6 checksum.
9407 cat expected | cut -c 117- > expout
9408 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9409
9410 rm -f packets
9411 as $i reset_pcap_file $i-vif1 $i/vif1
9412 done
9413
9414 rm -f expected
9415 }
9416
9417 # Baseline test with no MTU
9418 ra_test 0 00 c0 40 aef00000000000000000000000000000
9419
9420 # Now make sure an MTU option makes it
9421 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9422 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9423
9424 # Now test for multiple network prefixes
9425 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9426 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9427
9428 # Test a different address mode now
9429 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9430 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9431
9432 # And the other address mode
9433 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9434 ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9435
9436 OVN_CLEANUP([hv1],[hv2])
9437 AT_CLEANUP
9438
9439 AT_SETUP([ovn -- ACL reject rule test])
9440 AT_KEYWORDS([acl-reject])
9441 AT_SKIP_IF([test $HAVE_PYTHON = no])
9442 ovn_start
9443
9444 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9445 #
9446 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9447 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9448 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9449 # unreachable frame generated from ACL rule hit
9450 #
9451 # INPORT is a lport number, e.g. 11 for vif11.
9452 # HV is a hypervisor number
9453 # ETH_SRC and ETH_DST are each 12 hex digits.
9454 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9455 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9456 test_ip_packet() {
9457 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9458 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9459 shift 9
9460
9461 local ip_ttl=ff
9462 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9463
9464 local reply_icmp_ttl=ff
9465 local icmp_type_code_response=0301
9466 local icmp_data=00000000
9467 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9468 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9469 echo $reply >> vif$inport.expected
9470
9471 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9472 }
9473
9474 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9475 #
9476 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9477 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9478 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9479 test_ipv6_packet() {
9480 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9481 shift 7
9482
9483 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9484 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9485
9486 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9487 echo $reply >> vif$inport.expected
9488
9489 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9490 }
9491
9492 # 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
9493 #
9494 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9495 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9496 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9497 #
9498 # INPORT is an lport number, e.g. 11 for vif11.
9499 # HV is an hypervisor number
9500 # ETH_SRC and ETH_DST are each 12 hex digits.
9501 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9502 # TCP_SPORT and TCP_DPORT are 4 hex digits.
9503 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9504 test_tcp_syn_packet() {
9505 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9506 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9507 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9508 shift 12
9509
9510 local ip_ttl=ff
9511 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9512
9513 local tcp_rst_ttl=ff
9514 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
9515 echo $reply >> vif$inport.expected
9516
9517 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9518 }
9519
9520 # Create hypervisors hv[123].
9521 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9522 # Add all of the vifs to a single logical switch sw0.
9523
9524 net_add n1
9525 ovn-nbctl ls-add sw0
9526 for i in 1 2 3; do
9527 sim_add hv$i
9528 as hv$i
9529 ovs-vsctl add-br br-phys
9530 ovn_attach n1 br-phys 192.168.0.$i
9531
9532 for j in 1 2 3; do
9533 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9534 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9535
9536 ovs-vsctl -- add-port br-int vif$i$j -- \
9537 set interface vif$i$j \
9538 external-ids:iface-id=sw0-p$i$j \
9539 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9540 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9541 ofport-request=$i$j
9542 done
9543 done
9544
9545 OVN_POPULATE_ARP
9546 # allow some time for ovn-northd and ovn-controller to catch up.
9547 sleep 1
9548
9549 ip_to_hex() {
9550 printf "%02x%02x%02x%02x" "$@"
9551 }
9552
9553 for i in 1 2 3; do
9554 : > vif${i}1.expected
9555 done
9556
9557 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9558 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9559 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
9560 OVS_WAIT_UNTIL([test 3 = $(ovn-sbctl lflow-list | grep 'icmp4 {' | wc -l)])
9561
9562 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9563 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9564 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9565
9566 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9567
9568 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
9569 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
9570 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
9571
9572 for i in 1 2 3; do
9573 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9574 done
9575
9576 OVN_CLEANUP([hv1], [hv2], [hv3])
9577 AT_CLEANUP
9578
9579 AT_SETUP([ovn -- Port Groups])
9580 AT_KEYWORDS([ovnpg])
9581 AT_SKIP_IF([test $HAVE_PYTHON = no])
9582 ovn_start
9583
9584 # Logical network:
9585 #
9586 # Three logical switches ls1, ls2, ls3.
9587 # One logical router lr0 connected to ls[123],
9588 # with nine subnets, three per logical switch:
9589 #
9590 # lrp11 on ls1 for subnet 192.168.11.0/24
9591 # lrp12 on ls1 for subnet 192.168.12.0/24
9592 # lrp13 on ls1 for subnet 192.168.13.0/24
9593 # ...
9594 # lrp33 on ls3 for subnet 192.168.33.0/24
9595 #
9596 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9597 # digits are the subnet and the last digit distinguishes the VIF.
9598 #
9599 # This test will create two port groups and uses them in ACL.
9600
9601 get_lsp_uuid () {
9602 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9603 }
9604
9605 pg1_ports=
9606 pg2_ports=
9607 for i in 1 2 3; do
9608 ovn-nbctl ls-add ls$i
9609 for j in 1 2 3; do
9610 for k in 1 2 3; do
9611 ovn-nbctl \
9612 -- lsp-add ls$i lp$i$j$k \
9613 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9614 192.168.$i$j.$k"
9615 # logical ports lp[12]?1 belongs to port group pg1
9616 if test $i != 3 && test $k == 1; then
9617 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9618 fi
9619 # logical ports lp[23]?2 belongs to port group pg2
9620 if test $i != 1 && test $k == 2; then
9621 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9622 fi
9623 done
9624 done
9625 done
9626
9627 ovn-nbctl lr-add lr0
9628 for i in 1 2 3; do
9629 for j in 1 2 3; do
9630 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9631 ovn-nbctl \
9632 -- lsp-add ls$i lrp$i$j-attachment \
9633 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9634 options:router-port=lrp$i$j \
9635 addresses='"00:00:00:00:ff:'$i$j'"'
9636 done
9637 done
9638
9639 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9640 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9641
9642 # create ACLs on all lswitches to drop traffic from pg2 to pg1
9643 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9644 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9645 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9646
9647 # Physical network:
9648 #
9649 # Three hypervisors hv[123].
9650 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9651 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9652 # lp?3[123] all on hv3.
9653
9654 # Given the name of a logical port, prints the name of the hypervisor
9655 # on which it is located.
9656 vif_to_hv() {
9657 case $1 in dnl (
9658 ?11) echo 1 ;; dnl (
9659 ?12 | ?21 | ?22) echo 2 ;; dnl (
9660 ?13 | ?23 | ?3?) echo 3 ;;
9661 esac
9662 }
9663
9664 # Given the name of a logical port, prints the name of its logical router
9665 # port, e.g. "vif_to_lrp 123" yields 12.
9666 vif_to_lrp() {
9667 echo ${1%?}
9668 }
9669
9670 # Given the name of a logical port, prints the name of its logical
9671 # switch, e.g. "vif_to_ls 123" yields 1.
9672 vif_to_ls() {
9673 echo ${1%??}
9674 }
9675
9676 net_add n1
9677 for i in 1 2 3; do
9678 sim_add hv$i
9679 as hv$i
9680 ovs-vsctl add-br br-phys
9681 ovn_attach n1 br-phys 192.168.0.$i
9682 done
9683 for i in 1 2 3; do
9684 for j in 1 2 3; do
9685 for k in 1 2 3; do
9686 hv=`vif_to_hv $i$j$k`
9687 as hv$hv ovs-vsctl \
9688 -- add-port br-int vif$i$j$k \
9689 -- set Interface vif$i$j$k \
9690 external-ids:iface-id=lp$i$j$k \
9691 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9692 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9693 ofport-request=$i$j$k
9694 done
9695 done
9696 done
9697
9698 # Pre-populate the hypervisors' ARP tables so that we don't lose any
9699 # packets for ARP resolution (native tunneling doesn't queue packets
9700 # for ARP resolution).
9701 OVN_POPULATE_ARP
9702
9703 # Allow some time for ovn-northd and ovn-controller to catch up.
9704 # XXX This should be more systematic.
9705 sleep 1
9706
9707 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9708 #
9709 # This shell function causes a packet to be received on INPORT. The packet's
9710 # content has Ethernet destination DST and source SRC (each exactly 12 hex
9711 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9712 # more) list the VIFs on which the packet should be received. INPORT and the
9713 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9714 for i in 1 2 3; do
9715 for j in 1 2 3; do
9716 for k in 1 2 3; do
9717 : > $i$j$k.expected
9718 done
9719 done
9720 done
9721 test_ip() {
9722 # This packet has bad checksums but logical L3 routing doesn't check.
9723 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9724 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9725 shift; shift; shift; shift; shift
9726 hv=hv`vif_to_hv $inport`
9727 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9728 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9729 in_ls=`vif_to_ls $inport`
9730 in_lrp=`vif_to_lrp $inport`
9731 for outport; do
9732 out_ls=`vif_to_ls $outport`
9733 if test $in_ls = $out_ls; then
9734 # Ports on the same logical switch receive exactly the same packet.
9735 echo $packet
9736 else
9737 # Routing decrements TTL and updates source and dest MAC
9738 # (and checksum).
9739 out_lrp=`vif_to_lrp $outport`
9740 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9741 fi >> $outport.expected
9742 done
9743 }
9744
9745 as hv1 ovs-vsctl --columns=name,ofport list interface
9746 as hv1 ovn-sbctl list port_binding
9747 as hv1 ovn-sbctl list datapath_binding
9748 as hv1 ovn-sbctl list port_group
9749 as hv1 ovn-sbctl list address_set
9750 as hv1 ovn-sbctl dump-flows
9751 as hv1 ovs-ofctl dump-flows br-int
9752
9753 # Send IP packets between all pairs of source and destination ports,
9754 # packets matches ACL (pg2 to pg1) should be dropped
9755 ip_to_hex() {
9756 printf "%02x%02x%02x%02x" "$@"
9757 }
9758 for is in 1 2 3; do
9759 for js in 1 2 3; do
9760 for ks in 1 2 3; do
9761 bcast=
9762 s=$is$js$ks
9763 smac=f00000000$s
9764 sip=`ip_to_hex 192 168 $is$js $ks`
9765 for id in 1 2 3; do
9766 for jd in 1 2 3; do
9767 for kd in 1 2 3; do
9768 d=$id$jd$kd
9769 dip=`ip_to_hex 192 168 $id$jd $kd`
9770 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
9771 if test $d != $s; then unicast=$d; else unicast=; fi
9772
9773 # packets matches ACL should be dropped
9774 if test $id != 3 && test $kd == 1; then
9775 if test $is != 1 && test $ks == 2; then
9776 unicast=
9777 fi
9778 fi
9779 test_ip $s $smac $dmac $sip $dip $unicast #1
9780 done
9781 done
9782 done
9783 done
9784 done
9785 done
9786
9787 # Allow some time for packet forwarding.
9788 # XXX This can be improved.
9789 sleep 1
9790
9791 # Now check the packets actually received against the ones expected.
9792 for i in 1 2 3; do
9793 for j in 1 2 3; do
9794 for k in 1 2 3; do
9795 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9796 [$i$j$k.expected])
9797 done
9798 done
9799 done
9800
9801 # Gracefully terminate daemons
9802 OVN_CLEANUP([hv1], [hv2], [hv3])
9803 AT_CLEANUP