1 # OVN_CHECK_PACKETS([PCAP], [EXPECTED])
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.
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__ () {
15 echo "checking packets in $1 against $2:"
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
19 exp_n=`wc -l < "$exp_text"`
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
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
27 sort $exp_text > expout
30 m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
34 AT_BANNER([OVN components])
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 "
44 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45 $1 => error("`$' must be followed by a valid identifier.") 1
50 a/*/b => a error("`/*' without matching `*/'.")
52 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
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.")
61 1/0 => error("Value contains unmasked 1-bits.")
65 1/ => error("Integer constant expected.")
67 1/0x123 => error("Value and mask have incompatible formats.")
74 0XFEDCBA9876543210 => 0xfedcba9876543210
75 0xfedcba9876543210fedcba9876543210
76 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
77 0x => error("Hex digits expected following 0x.")
78 0X => error("Hex digits expected following 0X.")
81 0x1/0x0 => error("Value contains unmasked 1-bits.")
83 0x. => error("Invalid syntax in hexadecimal constant.")
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.")
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.")
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
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
103 ::ffff:c000:0280 => ::ffff:192.0.2.128
105 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
108 ff00::/ff00:: => ff00::/8
111 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
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.")
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 `--'.")
127 ^ => error("Invalid character `^' in input.")
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])
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.
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]
146 reg4 = xxreg1[96..127]
147 reg5 = xxreg1[64..95]
148 reg6 = xxreg1[32..63]
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
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]
171 ct.snat = ct_state[6]
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
180 AT_SETUP([ovn -- compsition])
181 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
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], [[
189 eth.type==0x800 => eth.type == 0x800
190 eth.type[0..15] == 0x800 => eth.type == 0x800
193 vlan.present == 1 => vlan.present
194 !(vlan.present == 0) => vlan.present
195 !(vlan.present != 1) => 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
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]
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]
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
219 !vlan.pcp => vlan.pcp == 0
220 !(vlan.pcp) => vlan.pcp == 0
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
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
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
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
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)
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
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
288 !(inport != "eth0") => inport == "eth0"
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.
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.
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.
304 123 == 123 => Syntax error at `123' expecting field name.
306 $name => Syntax error at `$name' expecting address set name.
307 @name => Syntax error at `@name' expecting port group name.
309 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
312 inport[1] == 1 => Cannot select subfield of string field inport.
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.
318 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
320 eth.type[5..1] => Invalid bit range 5 to 1.
322 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
324 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
326 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
328 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
330 123 => Syntax error at end of input expecting relational operator.
332 123 x => Syntax error at `x' expecting relational operator.
334 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
336 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
338 (1 x) => Syntax error at `x' expecting `)'.
340 !0x800 != eth.type => Missing parentheses around operand of !.
342 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
344 eth.dst == {} => Syntax error at `}' expecting constant.
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).
348 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
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 `>=').
352 eth.dst[40] x => Syntax error at `x' expecting end of input.
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.
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])
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
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'.
378 vlan.present => vlan.tci[12]
379 !vlan.present => !vlan.tci[12]
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
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)
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'.
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])
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.
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.
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.
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 == != < <= > >=.
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.
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.
435 AT_SETUP([ovn -- simplification special cases])
437 echo "$1" | ovstest test-ovn simplify-expr
439 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
441 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
443 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
444 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
446 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
447 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
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)
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)
457 AT_SETUP([ovn -- is_chassis_resident simplification])
459 echo "$1" | ovstest test-ovn simplify-expr
461 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
463 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
465 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
467 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
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 == != < <= > >=.
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.
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.
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 ==.
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.
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.
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 ==.
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.
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.
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 ==.
535 AT_SETUP([ovn -- converting expressions to flows -- string fields])
536 AT_KEYWORDS([expression])
538 echo "$1" | ovstest test-ovn expr-to-flows | sort
540 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
542 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
544 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
546 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
550 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
554 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
556 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
561 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
567 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
572 AT_SETUP([ovn -- converting expressions to flows -- address sets])
573 AT_KEYWORDS([expression])
575 echo "$1" | ovstest test-ovn expr-to-flows | sort
577 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
582 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
587 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
593 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
600 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
605 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
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
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
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
627 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
630 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
633 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
636 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
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
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
661 AT_SETUP([ovn -- converting expressions to flows -- port groups])
662 AT_KEYWORDS([expression])
664 echo "$1" | ovstest test-ovn expr-to-flows | sort
666 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
671 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
674 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
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],
687 Syntax error at `next' expecting end of input.
689 Syntax error at `drop' expecting action.
693 encodes as resubmit(,64)
697 encodes as resubmit(,19)
700 encodes as resubmit(,19)
702 encodes as resubmit(,8)
704 encodes as resubmit(,31)
707 Syntax error at `)' expecting "pipeline" or "table".
709 Syntax error at `;' expecting `)'.
711 "next" action cannot advance beyond table 23.
715 encodes as resubmit(,19)
716 next(pipeline=ingress);
718 encodes as resubmit(,19)
719 next(table=11, pipeline=ingress);
721 encodes as resubmit(,19)
722 next(pipeline=ingress, table=11);
724 encodes as resubmit(,19)
726 next(pipeline=egress);
727 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
731 encodes as resubmit(,18)
733 # Loading a constant value.
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)
739 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
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
746 encodes as set_field:0->reg14
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)
756 Cannot select subfield of string field inport.
758 Cannot select subfield of nominal field ip.proto.
760 Syntax error at `==' expecting `=' or `<->'.
762 Predicate symbol ip used where lvalue required.
764 Field ip.proto is not modifiable.
766 Syntax error at `{' expecting constant.
768 Syntax error at `{' expecting constant.
770 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
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'.
774 Predicate symbol vlan.present used where lvalue required.
776 # Moving one field into another.
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]
787 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
789 reg0[0] = vlan.present;
790 Predicate symbol vlan.present used where lvalue required.
792 Can't assign 11-bit value to 32-bit destination.
794 Can't assign integer field (reg0) to string field (inport).
796 String fields inport and big_string are incompatible for assignment.
797 ip.proto = reg0[0..7];
798 Field ip.proto is not modifiable.
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]
810 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
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.
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.
830 Syntax error at end of input expecting `--'.
834 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
838 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
840 ct_lb(192.168.1.2:80, 192.168.1.3:80);
843 ct_lb(192.168.1.2, 192.168.1.3, );
844 formats as ct_lb(192.168.1.2, 192.168.1.3);
847 ct_lb(fd0f::2, fd0f::3, );
848 formats as ct_lb(fd0f::2, fd0f::3);
853 Syntax error at `)' expecting port number.
854 ct_lb(192.168.1.2:123456);
855 Syntax error at `123456' expecting port number.
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.
863 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
868 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
871 formats as ct_commit;
872 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
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))
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))
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))
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))
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))
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))
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))
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))
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))
910 ct_commit(ct_label=18446744073709551616);
911 Decimal constants must be less than 2**64.
915 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
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))
921 ct_dnat(192.168.1.2, 192.168.1.3);
922 Syntax error at `,' expecting `)'.
924 Syntax error at `foo' expecting IPv4 address.
926 Syntax error at `foo' expecting IPv4 address.
928 Syntax error at `)' expecting IPv4 address.
932 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
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))
938 ct_snat(192.168.1.2, 192.168.1.3);
939 Syntax error at `,' expecting `)'.
941 Syntax error at `foo' expecting IPv4 address.
943 Syntax error at `foo' expecting IPv4 address.
945 Syntax error at `)' expecting IPv4 address.
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
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)
961 formats as arp { drop; };
962 encodes as controller(userdata=00.00.00.00.00.00.00.00)
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[]
973 Syntax error at `;' expecting `('.
975 Syntax error at `)' expecting field name.
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.
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
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)
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.
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)
1027 formats as nd_ns { drop; };
1028 encodes as controller(userdata=00.00.00.09.00.00.00.00)
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)
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[]
1044 Syntax error at `;' expecting `('.
1046 Syntax error at `)' expecting field name.
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.
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)
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.
1091 encodes as set_queue:0
1093 encodes as set_queue:61440
1095 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
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)
1101 reg1[0] = dns_lookup("foo");
1102 dns_lookup doesn't take any parameters
1106 Rate 0 for set_meter is not in valid.
1109 set_meter(100, 1000);
1111 set_meter(100, 1000, );
1112 Syntax error at `,' expecting `)'.
1113 set_meter(4294967295, 4294967295);
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)
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)
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)
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
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)
1153 formats as icmp4 { drop; };
1154 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
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)
1163 formats as icmp6 { drop; };
1164 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
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)
1173 formats as tcp_reset { drop; };
1174 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
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
1185 # Miscellaneous negative tests.
1187 Syntax error at `;'.
1189 Syntax error at `xyzzy' expecting action.
1191 Syntax error at `123'.
1193 Syntax error at `xyzzy' expecting action.
1195 Syntax error at end of input expecting `;'.
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])
1202 AT_BANNER([OVN end-to-end tests])
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])
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
1221 ovs-vsctl add-br br-phys
1222 ovn_attach n1 br-phys 192.168.0.$i
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
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"
1233 ip_addrs="192.168.0.$i$j"
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
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
1247 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
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
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).
1258 # Allow some time for ovn-northd and ovn-controller to catch up.
1259 # XXX This should be more systematic.
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`"])
1267 # Given the name of a logical port, prints the name of the hypervisor
1268 # on which it is located.
1273 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
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.
1286 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1287 hv=`vif_to_hv $inport`
1289 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1291 echo $packet >> $outport.expected
1295 # test_arp INPORT SHA SPA TPA [REPLY_HA]
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.
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.
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
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.
1317 if test $i$j != $inport; then
1318 echo $request >> $i$j.expected
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
1330 printf "%02x%02x%02x%02x" "$@"
1333 # Send packets between all pairs of source and destination ports:
1335 # 1. Unicast packets are delivered to exactly one logical switch port
1336 # (except that packets destined to their input ports are dropped).
1338 # 2. Broadcast and multicast are delivered to all logical switch ports
1339 # except the input port.
1341 # 3. When port security is turned on, the switch drops packets from the wrong
1344 # 4. The switch drops all packets with a VLAN tag.
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.)
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).
1354 # 7. The switch drops unicast packets that violate an ACL.
1356 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1358 # 9. OVN generates responses to ARP requests for known IPs, except for
1359 # requests from a port for the port's own IP.
1361 # 10. No response to ARP requests for unknown IPs.
1374 if test $d != $s; then unicast=$d; else unicast=; fi
1375 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1377 if test $d != $s && test $js = 1; then
1382 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
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).
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).
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
1406 test_packet $s f000000000$d f00000000055 810000091234 #4
1407 test_packet $s f000000000$d 0100000000$s $s$d #5
1409 if test $d != $s && test $jd = 1; then
1410 unknown="$unknown $d"
1412 bcast="$bcast $unicast"
1413 bacl2="$bacl2 $acl2"
1414 bacl3="$bacl3 $acl3"
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
1424 test_arp $s f000000000$s $sip $tip $reply_ha #9
1425 test_arp $s f000000000$s $sip $tip_unknown #10
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
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
1443 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1445 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
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
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"
1460 # Allow some time for ovn-northd and ovn-controller to catch up.
1461 # XXX This should be more systematic.
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
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
1472 # dump information and flows with counters
1473 ovn-sbctl dump-flows -- list multicast_group
1475 echo "------ hv1 dump ------"
1476 as hv1 ovs-vsctl show
1477 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1479 echo "------ hv2 dump ------"
1480 as hv2 ovs-vsctl show
1481 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1483 echo "------ hv3 dump ------"
1484 as hv3 ovs-vsctl show
1485 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1487 # Now check the packets actually received against the ones expected.
1490 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1494 OVN_CLEANUP([hv1],[hv2],[hv3])
1498 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1499 AT_SKIP_IF([test $HAVE_PYTHON = no])
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
1509 ovn-nbctl lsp-add lsw0 lp$i
1511 ovn-nbctl --wait=sb sync
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
1517 if test $i = 3; then
1518 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1520 ip_addrs="192.168.0.$i"
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
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
1532 ovn-nbctl --wait=sb sync
1533 on_exit 'kill `cat ovn-trace.pid`'
1534 ovn-trace --detach --pidfile --no-chdir
1536 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
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.
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"
1548 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1549 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1554 echo "output(\"lp$outport\");"
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])
1561 # test_arp INPORT SHA SPA TPA [REPLY_HA]
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.
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.
1572 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
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"
1579 if test -z "$reply_ha"; then
1583 if test $i != $inport; then
1584 reply="${reply}output(\"lp$i\");
1591 eth.src = $reply_ha;
1594 arp.sha = $reply_ha;
1597 output(\"lp$inport\");
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])
1605 # Send packets between all pairs of source and destination ports:
1607 # 1. Unicast packets are delivered to exactly one logical switch port
1608 # (except that packets destined to their input ports are dropped).
1610 # 2. Broadcast and multicast are delivered to all logical switch ports
1611 # except the input port.
1613 # 3. When port security is turned on, the switch drops packets from the wrong
1616 # 4. The switch drops all packets with a VLAN tag.
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.)
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).
1626 # 7. The switch drops unicast packets that violate an ACL.
1628 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1630 # 9. OVN generates responses to ARP requests for known IPs, except for
1631 # requests from a port for the port's own IP.
1633 # 10. No response to ARP requests for unknown IPs.
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
1646 if test $d != $s && test $s = 1; then
1651 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
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).
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
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
1672 if test $d != $s && test $d = 1; then
1673 unknown="$unknown $d"
1675 bcast="$bcast $unicast"
1676 bacl2="$bacl2 $acl2"
1677 bacl3="$bacl3 $acl3"
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
1686 if test $d = 3; then
1687 # lp3 has an additional ip 192.169.0.[123]3.
1689 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
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
1701 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1703 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
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
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
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])
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.
1731 # Each switch's VLAN tag and their logical switch ports are:
1734 # - ports: lp11, lp12, lp21, lp22
1737 # - tagged with VLAN 101
1738 # - ports: lp13, lp14, lp23, lp24
1741 # - ports: lp15, lp25
1743 # Note: a localnet port is created for each switch to connect to
1748 ovn-nbctl ls-add $ls_name
1750 if test $i -eq 2; then
1751 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1753 ovn-nbctl lsp-add $ls_name $ln_port_name
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
1762 # Prints the name of the logical switch that contains LSP.
1765 lp?[[12]]) echo ls1 ;; dnl (
1766 lp?[[34]]) echo ls2 ;; dnl (
1767 lp?5) echo ls3 ;; dnl (
1768 *) AT_FAIL_IF([:]) ;;
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
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 \
1788 ls_name=$(lsp_to_ls $lsp_name)
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
1794 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1797 ovn-nbctl --wait=sb sync
1798 ovn-sbctl dump-flows
1802 # XXX This is now the 3rd copy of these functions in this file ...
1804 # Given the name of a logical port, prints the name of the hypervisor
1805 # on which it is located.
1810 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
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.
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).
1823 for j in 1 2 3 4 5; do
1828 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
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\");"
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])
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`
1843 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1844 if test $eout != drop; then
1845 echo $packet >> ${eout#lp}.expected
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
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
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
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
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
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
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
1889 # Dump a bunch of info helpful for debugging if there's a failure.
1891 echo "------ OVN dump ------"
1895 echo "------ hv1 dump ------"
1896 as hv1 ovs-vsctl show
1897 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1899 echo "------ hv2 dump ------"
1900 as hv2 ovs-vsctl show
1901 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1903 # Now check the packets actually received against the ones expected.
1905 for j in 1 2 3 4 5; do
1906 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1910 OVN_CLEANUP([hv1],[hv2])
1914 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1916 AT_SKIP_IF([test $HAVE_PYTHON = no])
1919 # Configure the Northbound database
1920 ovn-nbctl ls-add lsw0
1922 ovn-nbctl lsp-add lsw0 lp1
1923 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1925 ovn-nbctl lsp-add lsw0 lp2
1926 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
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
1933 # lpr, lr and lrp1 are used for the ARP request handling test only.
1934 ovn-nbctl lsp-add lsw0 lpr
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"'
1942 net_add n1 # Network to connect hv1, hv2, and vtep
1943 net_add n2 # Network to connect vtep and hv3
1945 # Create hypervisor hv1 connected to n1
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
1952 # Create hypervisor hv2 connected to n1
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
1960 # Start the vtep emulator with a leg in both networks
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
1967 ovs-vsctl add-br br-phys
1968 net_attach n1 br-phys
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
1975 ovs-vsctl add-br br-vtep
1976 net_attach n2 br-vtep
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
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
1985 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1987 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1989 # It takes more time for the update to be processed by ovs-vtep.
1992 # Add hv3 on the other side of the vtep
1995 ovs-vsctl add-br br-phys
1996 net_attach n2 br-phys
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
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).
2005 # Allow some time for ovn-northd and ovn-controller to catch up.
2006 # XXX This should be more systematic.
2009 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
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.
2020 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2021 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2024 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2026 echo $packet >> $outport.expected
2030 # Send packets between all pairs of source and destination ports:
2032 # 1. Unicast packets are delivered to exactly one logical switch port
2033 # (except that packets destined to their input ports are dropped).
2035 # 2. Broadcast and multicast are delivered to all logical switch ports
2036 # except the input port.
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).
2045 if test $d != $s; then unicast=$d; else unicast=; fi
2046 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2048 # The vtep (vif3) is the only one configured for "unknown"
2049 if test $d != $s && test $d = 3; then
2050 unknown="$unknown $d"
2052 bcast="$bcast $unicast"
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
2059 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
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
2066 printf "%02x%02x%02x%02x" "$@"
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
2076 # dump information with counters
2077 echo "------ OVN dump ------"
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
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
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
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
2105 # Now check the packets actually received against the ones expected.
2107 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2110 # Gracefully terminate daemons
2111 OVN_CLEANUP([hv1],[hv2],[vtep])
2112 OVN_CLEANUP_VSWITCH([hv3])
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])
2121 # Configure the Northbound database
2122 ovn-nbctl ls-add lsw0
2124 ovn-nbctl lsp-add lsw0 lp1
2125 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2127 ovn-nbctl lsp-add lsw0 lp2
2128 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
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
2135 net_add n1 # Network to connect hv1, hv2, and gw
2136 net_add n2 # Network to connect gw and hv3
2138 # Create hypervisor hv1 connected to n1
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
2145 # Create hypervisor hv2 connected to n1
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
2152 # Create hypervisor hv_gw connected to n1 and n2
2153 # connect br-phys bridge to n1; connect hv-gw bridge to n2
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"
2162 # Add hv3 on the other side of the GW
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
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).
2175 # Allow some time for ovn-northd and ovn-controller to catch up.
2176 # XXX This should be more systematic.
2179 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
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.
2190 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2191 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2194 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2196 echo $packet >> $outport.expected
2200 # Send packets between all pairs of source and destination ports:
2202 # 1. Unicast packets are delivered to exactly one lport (except that packets
2203 # destined to their input ports are dropped).
2205 # 2. Broadcast and multicast are delivered to all lports except the input port.
2207 # 3. The lswitch delivers packets with an unknown destination to lports with
2208 # "unknown" among their MAC addresses (and port security disabled).
2213 if test $d != $s; then unicast=$d; else unicast=; fi
2214 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2216 # The vtep (vif3) is the only one configured for "unknown"
2217 if test $d != $s && test $d = 3; then
2218 unknown="$unknown $d"
2220 bcast="$bcast $unicast"
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
2228 echo "------ ovn-nbctl show ------"
2230 echo "------ ovn-sbctl show ------"
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
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
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
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
2259 # Now check the packets actually received against the ones expected.
2261 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
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])
2272 # Three logical switches ls1, ls2, ls3.
2273 # One logical router lr0 connected to ls[123],
2274 # with nine subnets, three per logical switch:
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
2280 # lrp33 on ls3 for subnet 192.168.33.0/24
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.
2285 ovn-nbctl ls-add ls$i
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
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
2300 ovn-nbctl lr-add lr0
2303 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
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'"'
2312 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2313 addresses='"00:00:00:00:ff:33 192.168.33.254"'
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.
2323 # Given the name of a logical port, prints the name of the hypervisor
2324 # on which it is located.
2327 ?11) echo 1 ;; dnl (
2328 ?12 | ?21 | ?22) echo 2 ;; dnl (
2329 ?13 | ?23 | ?3?) echo 3 ;;
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.
2339 # Given the name of a logical port, prints the name of its logical
2340 # switch, e.g. "vif_to_ls 123" yields 1.
2349 ovs-vsctl add-br br-phys
2350 ovn_attach n1 br-phys 192.168.0.$i
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
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).
2372 # Allow some time for ovn-northd and ovn-controller to catch up.
2373 # XXX This should be more systematic.
2376 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
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.
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`
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.
2406 # Routing decrements TTL and updates source and dest MAC
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
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
2420 # Send IP packets between all pairs of source and destination ports:
2422 # 1. Unicast IP packets are delivered to exactly one logical switch port
2423 # (except that packets destined to their input ports are dropped).
2425 # 2. Broadcast IP packets are delivered to all logical switch ports
2426 # except the input port.
2428 printf "%02x%02x%02x%02x" "$@"
2436 sip=`ip_to_hex 192 168 $is$js $ks`
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
2445 test_ip $s $smac $dmac $sip $dip $unicast #1
2447 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2451 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
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.
2465 sip=`ip_to_hex 192 168 $is$js $ks`
2468 if test $is$js = $id$jd; then
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
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
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
2489 echo $arp >> $id$jd2$kd.expected
2498 # test_arp INPORT SHA SPA TPA [REPLY_HA]
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.
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.
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
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`
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
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
2537 # Test router replies to ARP requests from all source ports:
2539 # 4. Router replies to query for its MAC address from port's own IP address.
2541 # 5. Router replies to query for its MAC address from any random IP address
2544 # 6. Router replies to query for its MAC address from another subnet.
2546 # 7. No reply to query for IP address other than router IP.
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
2563 # Allow some time for packet forwarding.
2564 # XXX This can be improved.
2567 # 8. Generate an ARP reply for each of the IP addresses ARPed for
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
2580 if test $is$js = $id$jd; then
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
2591 lrmac=00000000ff$id$jd
2592 lrip=`ip_to_hex 192 168 $id$jd 254`
2594 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
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
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
2613 # Allow some time for packet forwarding.
2614 # XXX This can be improved.
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.)
2628 sip=`ip_to_hex 192 168 $is$js $ks`
2631 if test $is$js = $id$jd; then
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
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
2645 # Expect the packet egress.
2646 host_mac=8000000000$o4
2649 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2656 ovn-sbctl -f csv -d bare --no-heading \
2657 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2659 # Now check the packets actually received against the ones expected.
2663 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2669 # Check the MAC bindings against those expected.
2670 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2673 # Gracefully terminate daemons
2674 OVN_CLEANUP([hv1], [hv2], [hv3])
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])
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
2695 ovs-vsctl add-br br-phys
2696 ovn_attach n1 br-phys 192.168.0.$i
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
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"
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).
2719 # Allow some time for ovn-northd and ovn-controller to catch up.
2720 # XXX This should be more systematic.
2723 # Given the name of a logical port, prints the name of the hypervisor
2724 # on which it is located.
2735 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
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.
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
2752 echo $packet >> $outport.expected
2756 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
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.
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.
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.
2779 if test $i$j != $inport; then
2780 echo $request >> $i$j.expected
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
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
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
2803 echo $packet >> $outport.expected
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
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
2818 echo $packet >> $outport.expected
2823 printf "%02x%02x%02x%02x" "$@"
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
2832 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2834 if test $i != $j; then
2835 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2841 sip=`ip_to_hex 192 168 0 12`
2842 tip=`ip_to_hex 192 168 0 13`
2844 # arp packet should be allowed since lp22 is configured with
2846 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2848 # arp packet should not be allowed since lp32 is not configured with
2850 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2852 # arp packet with sha set to f00000000021 should not be allowed
2854 test_arp 12 f00000000012 f00000000021 $sip $tip 1
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`
2862 if test $i != $j; then
2863 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
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
2874 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
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
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
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
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`
2903 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
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
2913 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
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
2919 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2922 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2923 # fe80::ea2a:eaff:fe28:0012
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
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
2935 tip=fe80000000000000ea2aeafffe2800${i}3
2936 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
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
2945 sip=ee800000000000000000000000000000
2946 tip=fe80000000000000ea2aeafffe280023
2947 test_ipv6 11 f00000000011 f00000000333 $sip $tip
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
2954 tip=ee800000000000000000000000000000
2956 sip=fe80000000000000ea2aeafffe2800${i}3
2957 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
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
2970 sip=ae80000000000000ea2aeafffe2800aa
2971 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
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"
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
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
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
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
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
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
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
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
3026 #dump information including flow counters
3028 ovn-sbctl dump-flows -- list multicast_group
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
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
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
3045 # Now check the packets actually received against the ones expected.
3048 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3052 OVN_CLEANUP([hv1],[hv2],[hv3])
3056 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3057 AT_SKIP_IF([test $HAVE_PYTHON = no])
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.
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"
3070 ls1_lp1_ip="192.168.1.2"
3071 ls2_lp1_ip="172.16.1.2"
3076 ovn-nbctl ls-add ls1
3077 ovn-nbctl ls-add ls2
3080 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
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\"
3086 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
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\"
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
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
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"
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"
3106 # Create two hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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).
3135 # Allow some time for ovn-northd and ovn-controller to catch up.
3136 # XXX This should be more systematic.
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"
3146 echo "---------NB dump-----"
3148 echo "---------------------"
3149 ovn-nbctl list logical_router
3150 echo "---------------------"
3151 ovn-nbctl list logical_router_port
3152 echo "---------------------"
3154 echo "---------SB dump-----"
3155 ovn-sbctl list datapath_binding
3156 echo "---------------------"
3157 ovn-sbctl list port_binding
3158 echo "---------------------"
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
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
3174 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3176 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3177 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3180 # Disable the ls2-lp1 port.
3181 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3183 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3184 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3187 # Generate the packet destined for ls2-lp1 and it should not be delivered.
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"
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])
3197 OVN_CLEANUP([hv1],[hv2])
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])
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.
3213 ovn-nbctl ls-add ls1
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\"
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"
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"
3228 # Create one hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
3248 # Allow some time for ovn-northd and ovn-controller to catch up.
3249 # XXX This should be more systematic.
3252 # Send ip packets between the two ports.
3254 printf "%02x%02x%02x%02x" "$@"
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
3266 echo "---------NB dump-----"
3268 echo "---------------------"
3269 ovn-nbctl list logical_router
3270 echo "---------------------"
3271 ovn-nbctl list logical_router_port
3272 echo "---------------------"
3274 echo "---------SB dump-----"
3275 ovn-sbctl list datapath_binding
3276 echo "---------------------"
3277 ovn-sbctl list logical_flow
3278 echo "---------------------"
3280 echo "------ hv1 dump ----------"
3281 as hv1 ovs-ofctl dump-flows br-int
3285 ovn-nbctl set Logical_Router R1 enabled=false
3287 # Allow some time for ovn-northd and ovn-controller to catch up.
3288 # XXX This should be more systematic.
3291 echo "---------SB dump-----"
3292 ovn-sbctl list datapath_binding
3293 echo "---------------------"
3294 ovn-sbctl list logical_flow
3295 echo "---------------------"
3297 echo "------ hv1 dump ----------"
3298 as hv1 ovs-ofctl dump-flows br-int
3300 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
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
3307 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3311 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3312 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3313 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3316 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3319 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3322 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3325 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3326 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
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])
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.
3342 ovn-nbctl ls-add ls1
3343 ovn-nbctl ls-add ls2
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\"
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\"
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"
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"
3363 # Create one hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
3383 # Allow some time for ovn-northd and ovn-controller to catch up.
3384 # XXX This should be more systematic.
3387 # Send ip packets between the two ports.
3389 printf "%02x%02x%02x%02x" "$@"
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
3401 echo "---------NB dump-----"
3403 echo "---------------------"
3404 ovn-nbctl list logical_router
3405 echo "---------------------"
3406 ovn-nbctl list logical_router_port
3407 echo "---------------------"
3409 echo "---------SB dump-----"
3410 ovn-sbctl list datapath_binding
3411 echo "---------------------"
3412 ovn-sbctl list logical_flow
3413 echo "---------------------"
3415 echo "------ hv1 dump ----------"
3416 as hv1 ovs-ofctl dump-flows br-int
3419 ovn-nbctl set Logical_Router R1 enabled=false
3421 echo "---------SB dump-----"
3422 ovn-sbctl list datapath_binding
3423 echo "---------------------"
3424 ovn-sbctl list logical_flow
3425 echo "---------------------"
3427 echo "------ hv1 dump ----------"
3428 as hv1 ovs-ofctl dump-flows br-int
3430 # Allow some time for the disabling of logical router R1 to propagate.
3431 # XXX This should be more systematic.
3434 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
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
3441 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3447 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3448 AT_SKIP_IF([test $HAVE_PYTHON = no])
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)
3455 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3460 ovn-nbctl ls-add foo
3461 ovn-nbctl ls-add alice
3462 ovn-nbctl ls-add bob
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\"
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\"
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\"
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
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
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"
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"
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"
3500 # Create two hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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 \
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).
3535 # Allow some time for ovn-northd and ovn-controller to catch up.
3536 # XXX This should be more systematic.
3540 printf "%02x%02x%02x%02x" "$@"
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
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
3559 echo "---------NB dump-----"
3561 echo "---------------------"
3562 ovn-nbctl list logical_router
3563 echo "---------------------"
3564 ovn-nbctl list logical_router_port
3565 echo "---------------------"
3567 echo "---------SB dump-----"
3568 ovn-sbctl list datapath_binding
3569 echo "---------------------"
3570 ovn-sbctl list port_binding
3571 echo "---------------------"
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
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
3585 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
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
3594 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3596 OVN_CLEANUP([hv1],[hv2])
3600 AT_SETUP([ovn -- send gratuitous arp on localnet])
3601 AT_SKIP_IF([test $HAVE_PYTHON = no])
3603 ovn-nbctl ls-add lsw0
3611 ovn_attach n1 br-phys 192.168.0.1
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])
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"])
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])
3627 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3629 # Wait for packet to be received.
3630 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3631 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3633 # Check GARP packet when restart openflow connection.
3635 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3637 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3640 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3642 # Wait for packet to be received.
3643 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3644 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3646 # Delete the localnet ports.
3647 AT_CHECK([ovs-vsctl del-port localvif1])
3648 AT_CHECK([ovn-nbctl lsp-del ln_port])
3654 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3655 AT_SKIP_IF([test $HAVE_PYTHON = no])
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)
3668 ovn-nbctl ls-add foo
3669 ovn-nbctl ls-add alice
3670 ovn-nbctl ls-add bob
3671 ovn-nbctl ls-add join
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\"
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\"
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\"
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"'
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"'
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"'
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
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
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
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"
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"
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"
3725 # Create two hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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 \
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).
3760 # Allow some time for ovn-northd and ovn-controller to catch up.
3761 # XXX This should be more systematic.
3765 printf "%02x%02x%02x%02x" "$@"
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
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
3785 echo "---------NB dump-----"
3787 echo "---------------------"
3788 ovn-nbctl list logical_router
3789 echo "---------------------"
3790 ovn-nbctl list logical_router_port
3791 echo "---------------------"
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 "---------------------"
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 "----------------------------"
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
3816 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
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
3825 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3827 OVN_CLEANUP([hv1],[hv2])
3831 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3832 AT_SKIP_IF([test $HAVE_PYTHON = no])
3835 ovn-nbctl ls-add ls1
3837 ovn-nbctl lsp-add ls1 ls1-lp1 \
3838 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3840 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
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"
3845 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
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"
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\"")"
3859 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3860 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
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\"")"
3866 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
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 \
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 \
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 \
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 \
3902 as hv1 ovs-vsctl show
3904 # This shell function sends a DHCP request packet
3905 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
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
3914 src_ip=`ip_to_hex 0 0 0 0`
3915 dst_ip=`ip_to_hex 255 255 255 255`
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
3924 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3925 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3927 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3928 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3929 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3930 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3932 request=${request}63825363
3934 request=${request}3501${dhcp_type}ff
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
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
3956 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3957 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3959 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3960 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3961 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3962 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3964 reply=${reply}63825363
3966 local dhcp_reply_type=02
3967 if test $dhcp_type = 03; then
3970 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3971 echo $reply >> $inport.expected
3974 echo $request >> $outport.expected
3977 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
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
3991 printf "%02x%02x%02x%02x" "$@"
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
3998 echo "---------NB dump-----"
4000 echo "---------------------"
4001 echo "---------SB dump-----"
4002 ovn-sbctl list datapath_binding
4003 echo "---------------------"
4004 ovn-sbctl list logical_flow
4005 echo "---------------------"
4007 echo "---------------------"
4008 ovn-sbctl dump-flows
4009 echo "---------------------"
4011 echo "------ hv1 dump ----------"
4012 as hv1 ovs-ofctl dump-flows br-int
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
4020 # NXT_RESUMEs should be 1.
4021 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
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
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
4043 # NXT_RESUMEs should be 2.
4044 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
4053 reset_pcap_file hv1-vif1 hv1/vif1
4054 reset_pcap_file hv1-vif2 hv1/vif2
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."
4063 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4065 # NXT_RESUMEs should be 3.
4066 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4068 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4069 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4071 reset_pcap_file hv1-vif1 hv1/vif1
4072 reset_pcap_file hv1-vif2 hv1/vif2
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.
4079 test_dhcp 3 f00000000003 01 0 4 0
4081 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4083 test_dhcp 4 f00000000004 01 0 3 0
4085 # NXT_RESUMEs should be 3.
4086 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4088 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4089 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
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
4097 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4099 # NXT_RESUMEs should be 4.
4100 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
4109 reset_pcap_file hv1-vif1 hv1/vif1
4110 reset_pcap_file hv1-vif2 hv1/vif2
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
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
4122 # NXT_RESUMEs should be 5.
4123 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
4132 reset_pcap_file hv1-vif1 hv1/vif1
4133 reset_pcap_file hv1-vif2 hv1/vif2
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
4143 # NXT_RESUMEs should be 5.
4144 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4146 # vif1-tx.pcap should have received the DHCPv4 request packet
4147 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4150 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4151 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4152 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4155 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4158 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4161 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4164 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4165 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4169 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4170 AT_SKIP_IF([test $HAVE_PYTHON = no])
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"
4177 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4179 ovn-nbctl lsp-add ls1 ls1-lp2 \
4180 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4182 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4184 ovn-nbctl lsp-add ls1 ls1-lp3 \
4185 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4187 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4189 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4190 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4192 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4193 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4195 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4196 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4198 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
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"
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 \
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 \
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 \
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 \
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 \
4249 sed 's/\(00\)\{1,\}$//'
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"
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}
4261 request=${request}ff020000000000000000000000010002
4262 # udp header and dhcpv6 header
4263 request=${request}02220223002affff${msg_code}010203
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
4273 if test $msg_code = 01; then
4277 if test $offer_ip = 1; then
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
4284 reply=${reply}0001000a00030001${src_mac}
4286 if test $offer_ip != 1; then
4287 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4290 reply=${reply}0002000a00030001${server_mac}
4291 echo $reply | trim_zeros >> $inport.expected
4294 echo $request | trim_zeros >> $outport.expected
4298 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
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
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
4315 echo "---------NB dump-----"
4317 echo "---------------------"
4318 echo "---------SB dump-----"
4319 ovn-sbctl list datapath_binding
4320 echo "---------------------"
4321 ovn-sbctl list logical_flow
4322 echo "---------------------"
4324 echo "---------------------"
4325 ovn-sbctl dump-flows
4326 echo "---------------------"
4328 echo "------ hv1 dump ----------"
4329 as hv1 ovs-ofctl dump-flows br-int
4331 src_mac=f00000000001
4332 src_lla=fe80000000000000f20000fffe000001
4333 offer_ip=ae700000000000000000000000000004
4334 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4336 # NXT_RESUMEs should be 1.
4337 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
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.
4354 reset_pcap_file hv1-vif1 hv1/vif1
4355 reset_pcap_file hv1-vif2 hv1/vif2
4357 src_mac=f00000000002
4358 src_lla=fe80000000000000f20000fffe000002
4359 offer_ip=ae700000000000000000000000000005
4360 # Set invalid msg_type
4362 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4364 # NXT_RESUMEs should be 2.
4365 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4367 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4369 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4370 AT_CHECK([cat 2.packets], [0], [])
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])
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.
4381 src_mac=f00000000003
4382 src_lla=fe80000000000000f20000fffe000003
4383 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4385 # NXT_RESUMEs should be 2 only.
4386 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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], [])
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])
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
4404 # NXT_RESUMEs should be 3.
4405 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
4413 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4414 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4415 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4418 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4421 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4424 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4427 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4428 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4432 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4433 AT_SKIP_IF([test $HAVE_PYTHON = no])
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.
4444 # Create two hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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).
4473 ovn-nbctl create Logical_Router name=R1
4474 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4476 ovn-nbctl ls-add foo
4477 ovn-nbctl ls-add alice
4478 ovn-nbctl ls-add join
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\"
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\"
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"'
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"'
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
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
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"
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"
4519 # Allow some time for ovn-northd and ovn-controller to catch up.
4520 # XXX This should be more systematic.
4524 printf "%02x%02x%02x%02x" "$@"
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
4534 echo "---------NB dump-----"
4536 echo "---------------------"
4537 ovn-nbctl list logical_router
4538 echo "---------------------"
4539 ovn-nbctl list logical_router_port
4540 echo "---------------------"
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 "---------------------"
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
4561 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4562 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
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 "----------------------------"
4572 echo $expected > expected
4573 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4575 # Delete the router and re-create it. Things should work as before.
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
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
4587 # Wait for ovn-controller to catch up.
4590 # Send the packet again.
4591 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
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 "----------------------------"
4601 echo $expected >> expected
4602 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4604 OVN_CLEANUP([hv1],[hv2])
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])
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.
4619 ovn-nbctl ls-add ls1
4620 ovn-nbctl ls-add ls2
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\"
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\"
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"
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"
4640 # Create one hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
4660 # Allow some time for ovn-northd and ovn-controller to catch up.
4661 # XXX This should be more systematic.
4666 printf "%02x%02x%02x%02x" "$@"
4671 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
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.
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
4693 # Use ttl to exercise section 4.2.2.9 of RFC1812
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}
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
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)
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
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
4728 echo "---------NB dump-----"
4730 echo "---------------------"
4731 ovn-nbctl list logical_router
4732 echo "---------------------"
4733 ovn-nbctl list logical_router_port
4734 echo "---------------------"
4736 echo "---------SB dump-----"
4737 ovn-sbctl list datapath_binding
4738 echo "---------------------"
4739 ovn-sbctl list logical_flow
4740 echo "---------------------"
4742 echo "------ hv1 dump ----------"
4743 as hv1 ovs-ofctl dump-flows br-int
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])
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])
4760 ovn-nbctl ls-add ls1
4761 ovn-nbctl lsp-add ls1 lp1
4762 ovn-nbctl lsp-set-addresses lp1 unknown
4766 as hv1 ovs-vsctl add-br br-phys
4767 as hv1 ovn_attach n1 br-phys 192.168.0.1
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])
4772 as hv1 ovs-vsctl del-port br-int vif1
4773 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
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])
4788 as hv1 ovs-vsctl add-br br-phys
4789 as hv1 ovn_attach n1 br-phys 192.168.0.1
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.
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} ------"
4804 echo "------ ovn-sbctl show ${stage_info} ------"
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
4811 if test $expect_datapath != 0; then
4812 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4814 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4818 test_datapath_in_of_rules 0 "before ls+port create"
4820 ovn-nbctl ls-add ls1
4821 ovn-nbctl lsp-add ls1 lp1
4822 ovn-nbctl lsp-set-addresses lp1 unknown
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])
4827 test_datapath_in_of_rules 1 "after port is bound"
4829 as hv1 ovs-vsctl del-port br-int vif1
4830 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4832 ovn-nbctl lsp-set-addresses lp1
4833 ovn-nbctl lsp-del lp1
4834 ovn-nbctl ls-del ls1
4836 # wait for earlier changes to take effect
4837 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
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"
4846 AT_SETUP([ovn -- nd_na ])
4847 AT_SKIP_IF([test $HAVE_PYTHON = no])
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.
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.
4858 # Create hypervisors and logical switch lsw0.
4859 ovn-nbctl ls-add lsw0
4863 ovs-vsctl add-br br-phys
4864 ovn_attach n1 br-phys 192.168.0.2
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"
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"
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
4883 # Allow some time for ovn-northd and ovn-controller to catch up.
4884 # XXX This should be more systematic.
4887 # Given the name of a logical port, prints the name of the hypervisor
4888 # on which it is located.
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
4902 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4903 echo $na_packet >> 1.expected
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
4911 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4918 AT_SETUP([ovn -- address sets modification/removal smoke test])
4925 ovs-vsctl add-br br-phys
4926 ovn_attach n1 br-phys 192.168.0.1
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
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])
4945 AT_SETUP([ovn -- ipam])
4946 AT_SKIP_IF([test $HAVE_PYTHON = no])
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"
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
4962 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4963 ["0a:00:00:00:00:02 192.168.1.3"
4965 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4966 ["0a:00:00:00:00:03 192.168.1.4"
4968 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4969 ["0a:00:00:00:00:04 192.168.1.5"
4971 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4972 ["0a:00:00:00:00:05 192.168.1.6"
4974 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4975 ["0a:00:00:00:00:06 192.168.1.7"
4977 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4978 ["0a:00:00:00:00:07 192.168.1.8"
4980 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4981 ["0a:00:00:00:00:08 192.168.1.9"
4983 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4984 ["0a:00:00:00:00:09 192.168.1.10"
4986 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4987 ["0a:00:00:00:00:0a 192.168.1.11"
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"
4999 for n in `seq 11 19`; do
5000 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
5002 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5003 ["0a:00:00:00:00:0c 192.168.1.3"
5005 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5006 ["0a:00:00:00:00:0d 192.168.1.4"
5008 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5009 ["0a:00:00:00:00:0e 192.168.1.5"
5011 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5012 ["0a:00:00:00:00:0f 192.168.1.6"
5014 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5015 ["0a:00:00:00:00:10 192.168.1.7"
5017 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5018 ["0a:00:00:00:00:11 192.168.1.8"
5020 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5021 ["0a:00:00:00:00:12 192.168.1.9"
5023 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5024 ["0a:00:00:00:00:13 192.168.1.10"
5026 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5027 ["0a:00:00:00:00:14 192.168.1.11"
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"
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"
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"
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"
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"
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"
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 \
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"
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"
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
5102 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5103 ["fe:dc:ba:98:76:55 192.168.1.18"
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"
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"
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"
5121 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
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"
5128 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
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"
5135 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
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"
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 \
5146 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5147 ["0a:00:00:00:00:24 192.168.1.19"
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 \
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"
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],
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 \
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"
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 \
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"
5185 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5186 "f0:00:00:00:10:12 dynamic"
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"
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 \
5197 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
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::"
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"
5210 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
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"
5218 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5221 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5224 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5228 AT_SETUP([ovn -- ipam connectivity])
5229 AT_SKIP_IF([test $HAVE_PYTHON = no])
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
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
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\"
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])
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"'])
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"'])
5264 # Create a hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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 \
5289 # Allow some time for ovn-northd and ovn-controller to catch up.
5290 # XXX This should be more systematic.
5294 printf "%02x%02x%02x%02x" "$@"
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
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
5313 echo "---------NB dump-----"
5315 echo "---------------------"
5316 ovn-nbctl list logical_router
5317 echo "---------------------"
5318 ovn-nbctl list logical_router_port
5319 echo "---------------------"
5321 echo "---------SB dump-----"
5322 ovn-sbctl list datapath_binding
5323 echo "---------------------"
5324 ovn-sbctl list port_binding
5325 echo "---------------------"
5327 echo "------ hv1 dump ----------"
5328 as hv1 ovs-ofctl dump-flows br-int
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
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])
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
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])
5356 AT_SETUP([ovn -- ovs-vswitchd restart])
5357 AT_KEYWORDS([vswitchd])
5358 AT_SKIP_IF([test $HAVE_PYTHON = no])
5361 ovn-nbctl ls-add ls1
5363 ovn-nbctl lsp-add ls1 ls1-lp1 \
5364 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5366 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
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 \
5383 as hv1 ovs-vsctl show
5385 echo "---------------------"
5386 ovn-sbctl dump-flows
5387 echo "---------------------"
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`
5393 echo "Total flows before vswitchd restart = " $total_flows
5395 # Code taken from ovs-save utility
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
5403 restart_vswitchd () {
5406 if test $restore_flows = true; then
5411 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5413 if test $restore_flows = true; then
5415 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5419 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5420 ovs-ofctl dump-flows br-int
5422 if test $restore_flows = true; then
5423 sh ./restore_flows.sh
5424 echo "Flows after restore"
5426 ovs-ofctl dump-flows br-int
5427 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5428 flow-restore-wait="true"
5432 # Save the flows, restart vswitchd and restore the flows
5433 restart_vswitchd true
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}"
5440 # Restart vswitchd without restoring
5441 restart_vswitchd false
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}"
5451 AT_SETUP([ovn -- send arp for nexthop])
5452 AT_SKIP_IF([test $HAVE_PYTHON = no])
5455 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5457 # Create logical switches
5458 ovn-nbctl ls-add ls1
5459 ovn-nbctl ls-add ls2
5462 ovn-nbctl create Logical_Router name=lr0
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"'
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"'
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
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"
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"
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 \
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 \
5503 # Allow some time for ovn-northd and ovn-controller to catch up.
5504 # XXX This should be more systematic.
5507 echo "---------NB dump-----"
5509 echo "---------------------"
5510 ovn-nbctl list logical_router
5511 echo "---------------------"
5512 ovn-nbctl list logical_router_port
5513 echo "---------------------"
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 "---------------------"
5526 echo "------Flows dump-----"
5528 ovs-ofctl dump-flows
5529 echo "---------------------"
5532 printf "%02x%02x%02x%02x" "$@"
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
5541 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5542 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5545 sed 's/\(00\)\{1,\}$//'
5548 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
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])
5561 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5562 AT_SKIP_IF([test $HAVE_PYTHON = no])
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"
5582 ovn_attach n1 br-phys 192.168.0.1
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])
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])
5594 # Wait for packet to be received.
5595 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5597 sed 's/\(00\)\{1,\}$//'
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])
5609 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5610 AT_SKIP_IF([test $HAVE_PYTHON = no])
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"
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])
5638 ovn_attach n1 br-phys 192.168.0.1
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])
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])
5650 # Wait for packet to be received.
5651 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5653 sed 's/\(00\)\{1,\}$//'
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])
5669 AT_SETUP([ovn -- delete mac bindings])
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])
5700 AT_SETUP([ovn -- conntrack zone allocation])
5701 AT_SKIP_IF([test $HAVE_PYTHON = no])
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.
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
5723 ovn-nbctl create Logical_Router name=R1
5724 ovn-nbctl ls-add foo
5725 ovn-nbctl ls-add bar
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\"
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\"
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"
5741 # Create logical port bar1, bar2 and bar3 in bar
5742 for i in `seq 1 3`; do
5744 ovn-nbctl lsp-add bar bar$i \
5745 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5748 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5754 AT_SETUP([ovn -- tag allocation])
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])
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
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
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
5775 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5776 logical_port="c1"], [0], [1
5779 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5780 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5782 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5783 logical_port="c2"], [0], [2
5785 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5786 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5788 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5789 logical_port="c3"], [0], [4
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
5796 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5797 logical_port="c4"], [0], [1
5800 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5801 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5803 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5804 logical_port="c5"], [0], [2
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
5812 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5813 logical_port="c6"], [0], [1
5816 dnl Restart northd to see that the same allocation remains.
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
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
5827 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5829 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5831 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5833 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5835 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
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
5843 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5844 logical_port="c7"], [0], [2
5846 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
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
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
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
5869 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5871 ovn-nbctl ls-add lsw0
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])
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])
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"])
5900 # Bind the localvif1 to hv1.
5902 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
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])
5907 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5909 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5911 # Now bind vif2 on hv2.
5912 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
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])
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])
5921 # Now bind vif3 on hv2.
5922 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
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])
5928 AT_CHECK([ovn-nbctl lsp-del localvif2])
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])
5934 OVN_CLEANUP([hv1],[hv2])
5939 AT_SETUP([ovn -- ACL logging])
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
5956 lp1_mac="f0:00:00:00:00:01"
5957 lp1_ip="192.168.1.2"
5959 lp2_mac="f0:00:00:00:00:02"
5960 lp2_ip="192.168.1.3"
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
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
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
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
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
5981 ovn-sbctl dump-flows
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"
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"
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"
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"
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"
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"
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"
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"
6032 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
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
6045 AT_SETUP([ovn -- DSCP marking and meter check])
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
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
6067 AT_CAPTURE_FILE([trace])
6069 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
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.
6080 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6089 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to 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])
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`
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");
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
6110 # check at L3 without dscp marking
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
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
6123 # Update the meter rate
6124 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
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
6129 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6132 # Update the DSCP marking
6133 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6136 # Update the meter rate
6137 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
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
6142 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6145 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
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
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
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
6163 # check no meter table
6164 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6166 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6172 AT_SETUP([ovn -- read-only sb db:ptcp access])
6173 AT_SKIP_IF([test $HAVE_PYTHON = no])
6176 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6178 # Add read-only remote to sb ovsdb-server
6180 [ovsdb-tool transact ovn-sb.db \
6181 ['["OVN_Southbound",
6183 "table": "SB_Global",
6185 "connections": ["set", [["named-uuid", "xyz"]]]}},
6187 "table": "Connection",
6189 "row": {"target": "ptcp:0:127.0.0.1",
6190 "read_only": true}}]']], [0], [ignore], [ignore])
6192 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6194 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
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])
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"}
6205 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
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" : ".*[ '\"
6216 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6218 # Add read-only remote to sb ovsdb-server
6220 [ovsdb-tool transact ovn-sb.db \
6221 ['["OVN_Southbound",
6223 "table": "SB_Global",
6225 "connections": ["set", [["named-uuid", "xyz"]]]}},
6227 "table": "Connection",
6229 "row": {"target": "pssl:0:127.0.0.1",
6230 "read_only": true}}]']], [0], [ignore], [ignore])
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" \
6239 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
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])
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"}
6262 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
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" : ".*[ '\"
6273 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
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 \
6283 # Populate SSL configuration entries in nb db
6285 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6286 $PKIDIR/testpki-cert.pem \
6287 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
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])
6292 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
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 \
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 \
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 \
6312 [0], [stdout], [ignore])
6314 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
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" : ".*[ '\"
6325 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
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 \
6335 # Populate SSL configuration entries in sb db
6337 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6338 $PKIDIR/testpki-cert.pem \
6339 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
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])
6344 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
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 \
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 \
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 \
6364 [0], [stdout], [ignore])
6366 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6369 AT_SETUP([ovn -- nested containers])
6373 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
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.
6380 ovn-nbctl ls-add mgmt
6381 ovn-nbctl ls-add foo
6382 ovn-nbctl ls-add bar
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\"
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\"
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\"
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"
6403 ovn-nbctl lsp-add mgmt vm2 \
6404 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
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"
6411 ovn-nbctl lsp-add foo foo2 vm2 2 \
6412 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
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"
6419 ovn-nbctl lsp-add bar bar2 vm2 1 \
6420 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
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"
6426 # Create two hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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 \
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).
6460 # Allow some time for ovn-northd and ovn-controller to catch up.
6461 # XXX This should be more systematic.
6465 printf "%02x%02x%02x%02x" "$@"
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
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])
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
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])
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
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])
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
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])
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
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])
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
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])
6559 OVN_CLEANUP([hv1],[hv2])
6563 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6564 AT_SKIP_IF([test $HAVE_PYTHON = no])
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.
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.
6579 # Create three hypervisors and create OVS ports corresponding to logical ports.
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 \
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 \
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 \
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 \
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"
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
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\"
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\"
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\"
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\"
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"'
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"'
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"'
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
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
6672 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
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"
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"
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"
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"
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).
6695 # Allow some time for ovn-northd and ovn-controller to catch up.
6696 # XXX This should be more systematic.
6700 printf "%02x%02x%02x%02x" "$@"
6703 sed 's/\(00\)\{1,\}$//'
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
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
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
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])
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])
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])
6760 for sim in hv1 hv2 hv3; do
6762 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6763 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6764 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6768 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6771 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6774 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6777 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6778 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6782 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6783 AT_SKIP_IF([test $HAVE_PYTHON = no])
6786 ovn-nbctl ls-add ls1
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"
6791 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
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"
6796 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6798 DNS1=`ovn-nbctl create DNS records={}`
6799 DNS2=`ovn-nbctl create DNS records={}`
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"
6805 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
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 \
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 \
6827 as hv1 ovs-vsctl show
6829 echo "*************************"
6831 echo "*************************"
6834 printf "%02x%02x%02x%02x" "$@"
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
6847 # set_dns_params host_name
6848 # Sets the dns_req_data and dns_resp_data
6857 query_name=03766d31036f766e036f726700
6858 # IPv4 address - 10.0.0.4
6859 expected_dns_answer=${query_name}00010001${ttl}00040a000004
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
6872 query_name=03766d33036f766e036f726700
6873 # IPv4 address - 40.0.0.4
6874 expected_dns_answer=${query_name}00010001${ttl}000428000004
6878 query_name=03766d31036f766e036f726700
6879 # IPv6 address - aef0::4
6881 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6885 query_name=03766d31036f766e036f726700
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
6896 query_name=03766d31036f766e036f726700
6897 # IPv6 address - aef0::4
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}
6911 # This shell function sends a DNS request packet
6912 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
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
6926 request=${request}${dns_query_data}
6928 if test $dns_reply != 0; then
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
6939 echo $request >> $outport.expected
6942 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
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`
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
6958 request=${request}${dns_query_data}
6960 if test $dns_reply != 0; then
6962 ip_len=`expr 8 + ${#dns_reply} / 2`
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
6971 echo $request >> $outport.expected
6974 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
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
6982 src_ip=`ip_to_hex 10 0 0 4`
6983 dst_ip=`ip_to_hex 10 0 0 1`
6985 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6987 # NXT_RESUMEs should be 1.
6988 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
6997 reset_pcap_file hv1-vif1 hv1/vif1
6998 reset_pcap_file hv1-vif2 hv1/vif2
7003 src_ip=`ip_to_hex 10 0 0 6`
7004 dst_ip=`ip_to_hex 10 0 0 1`
7006 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7008 # NXT_RESUMEs should be 2.
7009 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
7018 reset_pcap_file hv1-vif1 hv1/vif1
7019 reset_pcap_file hv1-vif2 hv1/vif2
7023 # Clear the query name options for ls1-lp2
7024 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7027 src_ip=`ip_to_hex 10 0 0 4`
7028 dst_ip=`ip_to_hex 10 0 0 1`
7030 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7032 # NXT_RESUMEs should be 3.
7033 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7035 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7036 AT_CHECK([cat 1.packets], [0], [])
7038 reset_pcap_file hv1-vif1 hv1/vif1
7039 reset_pcap_file hv1-vif2 hv1/vif2
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
7049 src_ip=`ip_to_hex 10 0 0 6`
7050 dst_ip=`ip_to_hex 10 0 0 1`
7052 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7054 # NXT_RESUMEs should be 3 only.
7055 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7057 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7058 AT_CHECK([cat 2.packets], [0], [])
7060 reset_pcap_file hv1-vif1 hv1/vif1
7061 reset_pcap_file hv1-vif2 hv1/vif2
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"
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`
7073 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7075 # NXT_RESUMEs should be 4.
7076 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
7085 reset_pcap_file hv1-vif1 hv1/vif1
7086 reset_pcap_file hv1-vif2 hv1/vif2
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`
7095 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7097 # NXT_RESUMEs should be 5.
7098 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
7107 reset_pcap_file hv1-vif1 hv1/vif1
7108 reset_pcap_file hv1-vif2 hv1/vif2
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`
7117 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7119 # NXT_RESUMEs should be 6.
7120 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7122 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7123 AT_CHECK([cat 2.packets], [0], [])
7125 reset_pcap_file hv1-vif1 hv1/vif1
7126 reset_pcap_file hv1-vif2 hv1/vif2
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`
7135 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7137 # NXT_RESUMEs should be 7.
7138 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7140 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7141 AT_CHECK([cat 2.packets], [0], [])
7143 reset_pcap_file hv1-vif1 hv1/vif1
7144 reset_pcap_file hv1-vif2 hv1/vif2
7148 # Add one more DNS record to the ls1.
7149 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7152 src_ip=`ip_to_hex 10 0 0 4`
7153 dst_ip=`ip_to_hex 10 0 0 1`
7155 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7157 # NXT_RESUMEs should be 8.
7158 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
7167 reset_pcap_file hv1-vif1 hv1/vif1
7168 reset_pcap_file hv1-vif2 hv1/vif2
7172 # Try DNS query over IPv6
7174 src_ip=aef00000000000000000000000000004
7175 dst_ip=aef00000000000000000000000000001
7177 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7179 # NXT_RESUMEs should be 9.
7180 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
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])
7187 reset_pcap_file hv1-vif1 hv1/vif1
7188 reset_pcap_file hv1-vif2 hv1/vif2
7193 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7194 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7195 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7198 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7201 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7204 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7207 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7208 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
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])
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 \
7229 ovs-vsctl add-br br-phys
7230 ovn_attach n1 br-phys 192.168.0.2
7234 ovs-vsctl add-br br-phys
7235 ovn_attach n1 br-phys 192.168.0.4
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 \
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).
7252 ovn-nbctl create Logical_Router name=R1
7254 ovn-nbctl ls-add foo
7255 ovn-nbctl ls-add alice
7256 ovn-nbctl ls-add outside
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
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
7268 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7271 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7274 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
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
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"
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"
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
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
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
7306 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7308 # Allow some time for ovn-northd and ovn-controller to catch up.
7309 # XXX This should be more systematic.
7313 printf "%02x%02x%02x%02x" "$@"
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
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
7338 # ARP request packet to expect at outside1
7339 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7341 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
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}
7352 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
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
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
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
7371 # Resend packet from foo1 to outside1
7372 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
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], [])
7383 test_ip_packet gw1 gw2
7385 ovn-nbctl --timeout=3 --wait=hv \
7386 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7389 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7392 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7394 test_ip_packet gw2 gw1
7396 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
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])
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 \
7417 ovs-vsctl add-br br-phys
7418 ovn_attach n1 br-phys 192.168.0.2
7422 ovs-vsctl add-br br-phys
7423 ovn_attach n1 br-phys 192.168.0.4
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 \
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).
7440 ovn-nbctl create Logical_Router name=R0
7441 ovn-nbctl create Logical_Router name=R1
7443 ovn-nbctl ls-add foo
7444 ovn-nbctl ls-add join
7445 ovn-nbctl ls-add alice
7446 ovn-nbctl ls-add outside
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
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
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
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
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
7474 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7477 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7480 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
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
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"
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"
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
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
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
7512 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7514 # Allow some time for ovn-northd and ovn-controller to catch up.
7515 # XXX This should be more systematic.
7519 printf "%02x%02x%02x%02x" "$@"
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
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
7544 # ARP request packet to expect at outside1
7545 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7547 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
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}
7558 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
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
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
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
7577 # Resend packet from foo1 to outside1
7578 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
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], [])
7589 test_ip_packet gw1 gw2
7591 ovn-nbctl --timeout=3 --wait=hv \
7592 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7595 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7598 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7600 test_ip_packet gw2 gw1
7602 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7605 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7606 AT_SKIP_IF([test $HAVE_PYTHON = no])
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).
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
7628 # Subsequent tests are run after defining the bridge-mapping
7629 # for the localnet on hv2. These tests are expected to succeed.
7631 # Create three hypervisors and create OVS ports corresponding
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 \
7647 ovs-vsctl add-br br-phys
7648 ovn_attach n1 br-phys 192.168.0.2
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 \
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).
7665 ovn-nbctl create Logical_Router name=R1
7667 ovn-nbctl ls-add foo
7668 ovn-nbctl ls-add alice
7669 ovn-nbctl ls-add outside
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
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
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"
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"
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
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
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
7709 # Allow some time for ovn-northd and ovn-controller to catch up.
7710 # XXX This should be more systematic.
7713 echo "---------NB dump-----"
7715 echo "---------------------"
7716 ovn-nbctl list logical_router
7717 echo "---------------------"
7718 ovn-nbctl list logical_router_port
7719 echo "---------------------"
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 "-------------------------------------------"
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 "--------------------------"
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
7751 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
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
7756 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
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
7761 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7766 printf "%02x%02x%02x%02x" "$@"
7770 : > hv2-vif1.expected
7771 : > hv3-vif1.expected
7773 # test_arp INPORT SHA SPA TPA [REPLY_HA]
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.
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.
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
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
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)
7803 # ARP for router IP address from outside1, no response expected
7804 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7806 # Now check the packets actually received against the ones expected.
7807 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
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
7816 # Now check the packets actually received against the ones expected.
7817 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
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
7822 # Allow some time for ovn-northd and ovn-controller to catch up.
7823 # XXX This should be more systematic.
7826 # ARP for router IP address from outside1
7827 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7829 # Now check the packets actually received against the ones expected.
7830 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
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
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}
7844 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7846 echo $arp_request >> hv3-vif1.expected
7847 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
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}
7853 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7855 # Allow some time for ovn-northd and ovn-controller to catch up.
7856 # XXX This should be more systematic.
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
7866 # Resend packet from foo1 to outside1
7867 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
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 "----------------------------"
7880 echo $expected >> hv3-vif1.expected
7881 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7883 #Check ovn-trace over "chassisredirect" port
7884 AT_CAPTURE_FILE([trace])
7886 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
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])
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 \
7902 ovn-nbctl lsp-add alice alice1 \
7903 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
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 \
7912 ovn-nbctl lsp-add foo foo2 \
7913 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7915 # Allow some time for ovn-northd and ovn-controller to catch up.
7916 # XXX This should be more systematic.
7919 : > hv1-vif2.expected
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
7928 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
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
7937 echo $expected >> hv2-vif1.expected
7938 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
7940 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
7943 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
7945 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
7948 OVN_CLEANUP([hv1],[hv2],[hv3])
7952 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7953 AT_SKIP_IF([test $HAVE_PYTHON = no])
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"
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])
7985 ovs-vsctl add-br br-phys
7986 ovn_attach n1 br-phys 192.168.0.1
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])
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
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
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])
8009 # Allow some time for ovn-northd and ovn-controller to catch up.
8010 # XXX This should be more systematic.
8013 # Expect no packets when hv2 bridge-mapping is not present
8015 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8017 # Add bridge-mapping on hv2
8018 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8020 # Wait for packets to be received.
8021 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8023 sed 's/\(00\)\{1,\}$//'
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])
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=""
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
8047 as hv1 reset_pcap_file snoopvif hv1/snoopvif
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 \
8053 ovs-vsctl -- add-port br-int hv3-vif2 -- \
8054 set interface hv3-vif2 external-ids:iface-id=foo2 \
8057 # Add bridge-mapping on hv3
8058 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8060 # Re-add nat-addresses option
8061 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8063 # Wait for packets to be received.
8064 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8066 sed 's/\(00\)\{1,\}$//'
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])
8077 OVN_CLEANUP([hv1],[hv2],[hv3])
8081 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8082 AT_KEYWORDS([ovn-nd_ra])
8083 AT_SKIP_IF([test $HAVE_PYTHON = no])
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.
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"
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"'
8106 ovs-vsctl add-br br-phys
8107 ovn_attach n1 br-phys 192.168.0.2
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"
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"
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"
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
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 \
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 \
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 \
8145 # Allow some time for ovn-northd and ovn-controller to catch up.
8146 # XXX This should be more systematic.
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
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"`])
8162 # This shell function sends a Router Solicitation packet.
8163 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
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}
8170 if test $mtu != 0; then
8172 mtu_opt=05010000${mtu}
8175 if test ${#prefix_opt} != 0; then
8176 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8177 len=`expr $len + ${#prefix_opt} / 2`
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
8186 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
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
8193 # MTU is not set and the address mode is set to slaac
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
8200 # NXT_RESUME should be 1.
8201 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8203 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8205 cat 1.expected | cut -c -112 > expout
8206 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8208 # Skipping the ICMPv6 checksum.
8209 cat 1.expected | cut -c 117- > expout
8210 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8213 reset_pcap_file hv1-vif1 hv1/vif1
8214 reset_pcap_file hv1-vif2 hv1/vif2
8215 reset_pcap_file hv1-vif3 hv1/vif3
8217 # Set the MTU to 1500
8218 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
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"`])
8224 default_prefix_option_config=030440c0ffffffffffffffff00000000
8225 src_mac=fa163e000003
8226 src_lla=fe80000000000000f8163efffe000003
8229 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8231 # NXT_RESUME should be 2.
8232 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8234 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8236 cat 2.expected | cut -c -112 > expout
8237 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8239 # Skipping the ICMPv6 checksum.
8240 cat 2.expected | cut -c 117- > expout
8241 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8244 reset_pcap_file hv1-vif1 hv1/vif1
8245 reset_pcap_file hv1-vif2 hv1/vif2
8246 reset_pcap_file hv1-vif3 hv1/vif3
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"`])
8254 default_prefix_option_config=""
8255 src_mac=fa163e000004
8256 src_lla=fe80000000000000f8163efffe000004
8259 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8261 # NXT_RESUME should be 3.
8262 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8264 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8266 cat 3.expected | cut -c -112 > expout
8267 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8269 # Skipping the ICMPv6 checksum.
8270 cat 3.expected | cut -c 117- > expout
8271 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8274 reset_pcap_file hv1-vif1 hv1/vif1
8275 reset_pcap_file hv1-vif2 hv1/vif2
8276 reset_pcap_file hv1-vif3 hv1/vif3
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"`])
8284 default_prefix_option_config=030440c0ffffffffffffffff00000000
8285 src_mac=fa163e000002
8286 src_lla=fe80000000000000f8163efffe000002
8289 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8291 # NXT_RESUME should be 4.
8292 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8294 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8296 cat 1.expected | cut -c -112 > expout
8297 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8299 # Skipping the ICMPv6 checksum.
8300 cat 1.expected | cut -c 117- > expout
8301 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8304 reset_pcap_file hv1-vif1 hv1/vif1
8305 reset_pcap_file hv1-vif2 hv1/vif2
8306 reset_pcap_file hv1-vif3 hv1/vif3
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"`])
8314 default_prefix_option_config=""
8315 src_mac=fa163e000002
8316 src_lla=fe80000000000000f8163efffe000002
8319 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8321 # NXT_RESUME should be 4 only.
8322 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8324 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8325 AT_CHECK([cat 1.packets], [0], [])
8330 AT_SETUP([ovn -- /32 router IP address])
8331 AT_SKIP_IF([test $HAVE_PYTHON = no])
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'
8341 ovn-nbctl ls-add foo
8342 ovn-nbctl ls-add alice
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\"
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\"
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"
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"
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
8365 # Create two hypervisor and create OVS ports corresponding to logical ports.
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 \
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 \
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).
8394 # Allow some time for ovn-northd and ovn-controller to catch up.
8395 # XXX This should be more systematic.
8399 printf "%02x%02x%02x%02x" "$@"
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
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
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
8424 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8426 OVN_CLEANUP([hv1],[hv2])
8430 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8431 AT_SKIP_IF([test $HAVE_PYTHON = no])
8434 ovn-nbctl ls-add ls1
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
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
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
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
8464 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8467 ovn-nbctl --wait=sb sync
8468 ovn-sbctl dump-flows
8472 # Given the name of a logical port, prints the name of the hypervisor
8473 # on which it is located.
8478 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
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.
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).
8491 # DEFHV is the default hypervisor from where the packet is going to be sent
8492 # if the source port is a localport.
8499 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
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\");"
8507 AT_CAPTURE_FILE([trace])
8508 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
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
8518 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8519 if test $eout != drop; then
8520 echo $packet >> ${eout#lp}.expected
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
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
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
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
8541 # Now check the packets actually received against the ones expected.
8544 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8548 OVN_CLEANUP([hv1],[hv2])
8552 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8553 AT_SKIP_IF([test $HAVE_PYTHON = no])
8558 # create gateways with external network connectivity
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
8568 ovn-nbctl ls-add inside
8569 ovn-nbctl ls-add outside
8571 # create hypervisors with a vif port each to an internal network
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 \
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"
8591 ovn-nbctl create Logical_Router name=R1
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
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
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]'
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
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
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
8622 echo "---------NB dump-----"
8624 echo "---------------------"
8625 ovn-nbctl list logical_router
8626 echo "---------------------"
8627 ovn-nbctl list logical_router_port
8628 echo "---------------------"
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 "-------------------------------------------"
8646 for chassis in gw1 gw2 hv1 hv2; do
8648 echo "------ $chassis dump ----------"
8649 ovs-ofctl show br-int
8650 ovs-ofctl dump-flows br-int
8651 echo "--------------------------"
8653 function bfd_dump() {
8654 for chassis in gw1 gw2 hv1 hv2; do
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)"
8665 echo "--------------------------"
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)
8676 echo $hv1_gw1_ofport
8677 echo $hv1_gw2_ofport
8678 echo $hv2_gw1_ofport
8679 echo $hv2_gw2_ofport
8682 as hv1 ovs-ofctl dump-flows br-int table=32
8685 as hv2 ovs-ofctl dump-flows br-int table=32
8687 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8688 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
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
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
8696 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
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
8701 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
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
8707 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
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],
8718 # at this point, we invert the priority of the gw chassis between gw1 and gw2
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]'
8727 # XXX: Let the change propagate down to the ovn-controllers
8728 ovn-nbctl --wait=hv --timeout=3 sync
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
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
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],
8742 # check BFD enablement on tunnel ports from 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],
8752 # check BFD enablement on tunnel ports from 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],
8761 # check BFD enablement on tunnel ports from 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],
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],
8775 # check BFD enablement on tunnel ports from 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],
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],
8788 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
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
8793 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8796 # disconnect GW2 from the network, GW1 should take over
8798 port=${sandbox}_br-phys
8799 as main ovs-vsctl del-port n1 $port
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
8807 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
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],
8815 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8819 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8820 AT_SKIP_IF([test $HAVE_PYTHON = no])
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
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]'
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"
8840 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
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])
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])
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])
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])
8868 # wait for earlier changes to take effect
8869 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
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
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"
8887 # Wait for packets to be received through hv2.
8888 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8890 sed 's/\(00\)\{1,\}$//'
8893 only_broadcast_from_lrp1() {
8894 grep "fffffffffffff00000000001"
8897 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
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:"
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"
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"
8911 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8914 # at this point, we invert the priority of the gw chassis between hv2 and hv3
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]'
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
8928 # Wait for packets to be received.
8929 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8931 sed 's/\(00\)\{1,\}$//'
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], [])
8941 # change localnet port tag.
8942 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8944 # wait for earlier changes to take effect
8945 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
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"
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
8955 # Wait for packets to be received.
8956 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8958 sed 's/\(00\)\{1,\}$//'
8961 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
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], [])
8971 OVN_CLEANUP([hv1],[hv2],[hv3])
8975 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8976 AT_SKIP_IF([test $HAVE_PYTHON = no])
8981 # create two gateways with external network connectivity
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
8990 ovn-nbctl ls-add inside
8991 ovn-nbctl ls-add outside
8993 # create one hypervisors with a vif port the internal network
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 \
9004 ovn-nbctl lsp-add inside inside1 \
9005 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9010 ovn-nbctl create Logical_Router name=R1
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
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
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]'
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
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
9037 # Allow some time for ovn-northd and ovn-controller to catch up.
9038 ovn-nbctl --wait=hv --timeout=3 sync
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.
9046 > gw1/ovn-controller.log
9048 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9049 ovn-sbctl destroy Chassis $gw2_chassis
9051 # Ensure ovn-controller has processed latest sbdb update
9052 # ovn-nbctl --wait=hv sync
9054 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9056 OVN_CLEANUP([gw1],[gw2],[hv1])
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])
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"
9070 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9071 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
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
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
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"
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
9099 ovs-vsctl add-br br-phys
9100 ovn_attach n1 br-phys 192.168.0.2
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 \
9107 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
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 ":"`
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`])
9117 sed 's/\(00\)\{1,\}$//'
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
9126 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9127 dst_ip=20010db800010000020002fffe010205
9129 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9130 packet=${packet}8000000000000000
9131 shift; shift; shift; shift
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}
9140 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9141 echo $expected_packet >> ipv6_ns.expected
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
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)])
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
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])
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])
9172 AT_SETUP([ovn -- options:requested-chassis for logical port])
9177 ovn-nbctl ls-add ls0
9178 ovn-nbctl lsp-add ls0 lsp0
9180 # create two hypervisors, each with one vif port
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
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
9195 # Allow only chassis hv1 to bind logical port lsp0.
9196 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9198 # Allow some time for ovn-northd and ovn-controller to catch up.
9199 ovn-nbctl --wait=hv --timeout=3 sync
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)
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"
9210 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
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], [])
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], [])
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"
9222 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
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], [])
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])
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"
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"])
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])
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], [])
9247 OVN_CLEANUP([hv1],[hv2])
9251 AT_SETUP([ovn -- options:requested-chassis with hostname])
9255 ovn-nbctl ls-add ls0
9256 ovn-nbctl lsp-add ls0 lsp0
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
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
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])
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], [])
9289 AT_SETUP([ovn -- IPv6 periodic RA])
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.
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.
9311 ovs-vsctl add-br br-phys
9312 ovn_attach n1 br-phys 192.168.0.2
9314 ovs-vsctl add-br br-phys
9315 ovn_attach n1 br-phys 192.168.0.3
9318 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
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"
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
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 \
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])
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
9358 construct_expected_ra() {
9359 local src_mac=000000000001
9360 local dst_mac=333300000001
9361 local src_addr=fe80000000000000020000fffe000001
9362 local dst_addr=ff020000000000000000000000000001
9366 local ra_prefix_la=$3
9368 local slla=0101${src_mac}
9370 if test $mtu != 0; then
9371 mtu_opt=05010000${mtu}
9376 while [[ $# -gt 0 ]] ; do
9379 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9383 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
9384 local icmp=8600XXXX${ra}
9386 local ip_len=$(expr ${#icmp} / 2)
9387 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
9389 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9390 local eth=${dst_mac}${src_mac}86dd${ip}
9392 echo $packet >> expected
9396 construct_expected_ra $@
9398 for i in hv1 hv2 ; do
9399 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9401 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9403 cat expected | cut -c -112 > expout
9404 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9406 # Skip ICMPv6 checksum.
9407 cat expected | cut -c 117- > expout
9408 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9411 as $i reset_pcap_file $i-vif1 $i/vif1
9417 # Baseline test with no MTU
9418 ra_test 0 00 c0 40 aef00000000000000000000000000000
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
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
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
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
9436 OVN_CLEANUP([hv1],[hv2])
9439 AT_SETUP([ovn -- ACL reject rule test])
9440 AT_KEYWORDS([acl-reject])
9441 AT_SKIP_IF([test $HAVE_PYTHON = no])
9444 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
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
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
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
9462 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
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
9471 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9474 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
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
9483 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9484 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
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
9489 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
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
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
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}
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
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
9517 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
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.
9525 ovn-nbctl ls-add sw0
9529 ovs-vsctl add-br br-phys
9530 ovn_attach n1 br-phys 192.168.0.$i
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"
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 \
9546 # allow some time for ovn-northd and ovn-controller to catch up.
9550 printf "%02x%02x%02x%02x" "$@"
9554 : > vif${i}1.expected
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)])
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
9566 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
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
9573 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9576 OVN_CLEANUP([hv1], [hv2], [hv3])
9579 AT_SETUP([ovn -- Port Groups])
9580 AT_KEYWORDS([ovnpg])
9581 AT_SKIP_IF([test $HAVE_PYTHON = no])
9586 # Three logical switches ls1, ls2, ls3.
9587 # One logical router lr0 connected to ls[123],
9588 # with nine subnets, three per logical switch:
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
9594 # lrp33 on ls3 for subnet 192.168.33.0/24
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.
9599 # This test will create two port groups and uses them in ACL.
9602 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9608 ovn-nbctl ls-add ls$i
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 \
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`"
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`"
9627 ovn-nbctl lr-add lr0
9630 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
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'"'
9639 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9640 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
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
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.
9654 # Given the name of a logical port, prints the name of the hypervisor
9655 # on which it is located.
9658 ?11) echo 1 ;; dnl (
9659 ?12 | ?21 | ?22) echo 2 ;; dnl (
9660 ?13 | ?23 | ?3?) echo 3 ;;
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.
9670 # Given the name of a logical port, prints the name of its logical
9671 # switch, e.g. "vif_to_ls 123" yields 1.
9680 ovs-vsctl add-br br-phys
9681 ovn_attach n1 br-phys 192.168.0.$i
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
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).
9703 # Allow some time for ovn-northd and ovn-controller to catch up.
9704 # XXX This should be more systematic.
9707 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
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.
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`
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.
9737 # Routing decrements TTL and updates source and dest MAC
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
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
9753 # Send IP packets between all pairs of source and destination ports,
9754 # packets matches ACL (pg2 to pg1) should be dropped
9756 printf "%02x%02x%02x%02x" "$@"
9764 sip=`ip_to_hex 192 168 $is$js $ks`
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
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
9779 test_ip $s $smac $dmac $sip $dip $unicast #1
9787 # Allow some time for packet forwarding.
9788 # XXX This can be improved.
9791 # Now check the packets actually received against the ones expected.
9795 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9801 # Gracefully terminate daemons
9802 OVN_CLEANUP([hv1], [hv2], [hv3])