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.
308 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
309 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311 inport[1] == 1 => Cannot select subfield of string field inport.
313 eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
314 eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
315 eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319 eth.type[5..1] => Invalid bit range 5 to 1.
321 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329 123 => Syntax error at end of input expecting relational operator.
331 123 x => Syntax error at `x' expecting relational operator.
333 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337 (1 x) => Syntax error at `x' expecting `)'.
339 !0x800 != eth.type => Missing parentheses around operand of !.
341 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343 eth.dst == {} => Syntax error at `}' expecting constant.
345 eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
347 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
349 1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
351 eth.dst[40] x => Syntax error at `x' expecting end of input.
353 ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
354 eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
356 sed 's/ =>.*//' test-cases.txt > input.txt
357 sed 's/.* => //' test-cases.txt > expout
358 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
361 AT_SETUP([ovn -- expression annotation])
362 dnl Input precedes =>, expected output follows =>.
363 AT_DATA([test-cases.txt], [[
364 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
365 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
366 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
367 ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
368 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
370 ip => eth.type == 0x800 || eth.type == 0x86dd
371 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
372 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
373 ip > 0 => Only == and != operators may be used with nominal field ip.
374 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
375 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
377 vlan.present => vlan.tci[12]
378 !vlan.present => !vlan.tci[12]
380 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
381 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
382 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
384 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
385 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
386 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
388 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
389 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
390 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'.
391 mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
393 sed 's/ =>.*//' test-cases.txt > input.txt
394 sed 's/.* => //' test-cases.txt > expout
395 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
398 AT_SETUP([ovn -- 1-term expression conversion])
399 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
400 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
404 AT_SETUP([ovn -- 2-term expression conversion])
405 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
406 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
410 AT_SETUP([ovn -- 3-term expression conversion])
411 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
412 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
416 AT_SETUP([ovn -- 3-term numeric expression simplification])
417 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
418 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
422 AT_SETUP([ovn -- 4-term string expression simplification])
423 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
424 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
428 AT_SETUP([ovn -- 3-term mixed expression simplification])
429 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
430 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
434 AT_SETUP([ovn -- simplification special cases])
436 echo "$1" | ovstest test-ovn simplify-expr
438 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
440 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
442 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
443 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
445 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
446 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
448 AT_CHECK([simplify 'tcp.dst > 0'], [0],
449 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
451 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
452 [[(!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)
456 AT_SETUP([ovn -- is_chassis_resident simplification])
458 echo "$1" | ovstest test-ovn simplify-expr
460 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
462 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
464 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
466 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
470 AT_SETUP([ovn -- 4-term numeric expression normalization])
471 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
472 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
476 AT_SETUP([ovn -- 4-term string expression normalization])
477 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
478 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
482 AT_SETUP([ovn -- 4-term mixed expression normalization])
483 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
484 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
488 AT_SETUP([ovn -- 5-term numeric expression normalization])
489 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
490 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
494 AT_SETUP([ovn -- 5-term string expression normalization])
495 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
500 AT_SETUP([ovn -- 5-term mixed expression normalization])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
506 AT_SETUP([ovn -- 4-term numeric expressions to flows])
507 AT_KEYWORDS([expression])
508 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
509 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
513 AT_SETUP([ovn -- 4-term string expressions to flows])
514 AT_KEYWORDS([expression])
515 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
516 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
520 AT_SETUP([ovn -- 4-term mixed expressions to flows])
521 AT_KEYWORDS([expression])
522 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
523 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
527 AT_SETUP([ovn -- 3-term numeric expressions to flows])
528 AT_KEYWORDS([expression])
529 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
530 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
534 AT_SETUP([ovn -- converting expressions to flows -- string fields])
535 AT_KEYWORDS([expression])
537 echo "$1" | ovstest test-ovn expr-to-flows | sort
539 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
541 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
543 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
545 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
549 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
553 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
555 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
560 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
566 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
571 AT_SETUP([ovn -- converting expressions to flows -- address sets])
572 AT_KEYWORDS([expression])
574 echo "$1" | ovstest test-ovn expr-to-flows | sort
576 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
581 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
586 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
592 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
604 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
610 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
611 dl_src=00:00:00:00:00:01
612 dl_src=00:00:00:00:00:02
613 dl_src=00:00:00:00:00:03
615 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
616 dl_src=00:00:00:00:00:01
617 dl_src=00:00:00:00:00:02
618 dl_src=00:00:00:00:00:03
620 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
621 dl_src=00:00:00:00:00:01
622 dl_src=00:00:00:00:00:02
623 dl_src=00:00:00:00:00:03
624 dl_src=ba:be:be:ef:de:ad
628 AT_SETUP([ovn -- action parsing])
629 dnl Unindented text is input (a set of OVN logical actions).
630 dnl Indented text is expected output.
631 AT_DATA([test-cases.txt],
636 Syntax error at `next' expecting end of input.
638 Syntax error at `drop' expecting action.
642 encodes as resubmit(,64)
646 encodes as resubmit(,27)
649 encodes as resubmit(,27)
651 encodes as resubmit(,16)
653 encodes as resubmit(,31)
656 Syntax error at `)' expecting "pipeline" or "table".
658 Syntax error at `;' expecting `)'.
660 "next" action cannot advance beyond table 15.
664 encodes as resubmit(,27)
665 next(pipeline=ingress);
667 encodes as resubmit(,27)
668 next(table=11, pipeline=ingress);
670 encodes as resubmit(,27)
671 next(pipeline=ingress, table=11);
673 encodes as resubmit(,27)
675 next(pipeline=egress);
676 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
680 encodes as resubmit(,26)
682 # Loading a constant value.
684 formats as tcp.dst = 80;
685 encodes as set_field:80->tcp_dst
686 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
688 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
690 encodes as set_field:0x4000/0xe000->vlan_tci
691 has prereqs vlan.tci[12]
692 vlan.tci[13..15] = 2;
693 encodes as set_field:0x4000/0xe000->vlan_tci
695 encodes as set_field:0->reg14
697 formats as ip.ttl = 4;
698 encodes as set_field:4->nw_ttl
699 has prereqs eth.type == 0x800 || eth.type == 0x86dd
700 outport="eth0"; next; outport="LOCAL"; next;
701 formats as outport = "eth0"; next; outport = "LOCAL"; next;
702 encodes as set_field:0x5->reg15,resubmit(,27),set_field:0xfffe->reg15,resubmit(,27)
705 Cannot select subfield of string field inport.
707 Cannot select subfield of nominal field ip.proto.
709 Syntax error at `==' expecting `=' or `<->'.
711 Predicate symbol ip used where lvalue required.
713 Field ip.proto is not modifiable.
715 Syntax error at `{' expecting constant.
717 Syntax error at `{' expecting constant.
719 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
721 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'.
723 Predicate symbol vlan.present used where lvalue required.
725 # Moving one field into another.
727 formats as reg0 = reg1;
728 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
729 vlan.pcp = reg0[0..2];
730 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
731 has prereqs vlan.tci[12]
732 reg0[10] = vlan.pcp[1];
733 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
734 has prereqs vlan.tci[12]
736 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
738 reg0[0] = vlan.present;
739 Predicate symbol vlan.present used where lvalue required.
741 Can't assign 11-bit value to 32-bit destination.
743 Can't assign integer field (reg0) to string field (inport).
745 String fields inport and big_string are incompatible for assignment.
746 ip.proto = reg0[0..7];
747 Field ip.proto is not modifiable.
751 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]
752 vlan.pcp <-> reg0[0..2];
753 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]
754 has prereqs vlan.tci[12]
755 reg0[10] <-> vlan.pcp[1];
756 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
757 has prereqs vlan.tci[12]
759 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
761 reg0[0] <-> vlan.present;
762 Predicate symbol vlan.present used where lvalue required.
763 reg0 <-> reg1[0..10];
764 Can't exchange 32-bit field with 11-bit field.
766 Can't exchange string field (inport) with integer field (reg0).
767 inport <-> big_string;
768 String fields inport and big_string are incompatible for exchange.
769 ip.proto <-> reg0[0..7];
770 Field ip.proto is not modifiable.
771 reg0[0..7] <-> ip.proto;
772 Field ip.proto is not modifiable.
779 Syntax error at end of input expecting `--'.
783 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
787 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
789 ct_lb(192.168.1.2:80, 192.168.1.3:80);
792 ct_lb(192.168.1.2, 192.168.1.3, );
793 formats as ct_lb(192.168.1.2, 192.168.1.3);
798 Syntax error at `)' expecting port number.
799 ct_lb(192.168.1.2:123456);
800 Syntax error at `123456' expecting port number.
802 Syntax error at `foo' expecting IPv4 address.
806 encodes as ct(table=27,zone=NXM_NX_REG13[0..15])
811 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
814 formats as ct_commit;
815 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
817 ct_commit(ct_mark=1);
818 formats as ct_commit(ct_mark=0x1);
819 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
821 ct_commit(ct_mark=1/1);
822 formats as ct_commit(ct_mark=0x1/0x1);
823 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
825 ct_commit(ct_label=1);
826 formats as ct_commit(ct_label=0x1);
827 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
829 ct_commit(ct_label=1/1);
830 formats as ct_commit(ct_label=0x1/0x1);
831 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
833 ct_commit(ct_mark=1, ct_label=2);
834 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
835 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
838 ct_commit(ct_label=0x01020304050607080910111213141516);
839 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
840 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
842 ct_commit(ct_label=0x181716151413121110090807060504030201);
843 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
844 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
846 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
847 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
849 ct_commit(ct_label=18446744073709551615);
850 formats as ct_commit(ct_label=0xffffffffffffffff);
851 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
853 ct_commit(ct_label=18446744073709551616);
854 Decimal constants must be less than 2**64.
858 encodes as ct(table=27,zone=NXM_NX_REG11[0..15],nat)
860 ct_dnat(192.168.1.2);
861 encodes as ct(commit,table=27,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
864 ct_dnat(192.168.1.2, 192.168.1.3);
865 Syntax error at `,' expecting `)'.
867 Syntax error at `foo' expecting IPv4 address.
869 Syntax error at `foo' expecting IPv4 address.
871 Syntax error at `)' expecting IPv4 address.
875 encodes as ct(table=27,zone=NXM_NX_REG12[0..15],nat)
877 ct_snat(192.168.1.2);
878 encodes as ct(commit,table=27,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
881 ct_snat(192.168.1.2, 192.168.1.3);
882 Syntax error at `,' expecting `)'.
884 Syntax error at `foo' expecting IPv4 address.
886 Syntax error at `foo' expecting IPv4 address.
888 Syntax error at `)' expecting IPv4 address.
895 clone { ip4.dst = 255.255.255.255; output; }; next;
896 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,27)
897 has prereqs eth.type == 0x800
900 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
901 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)
904 formats as arp { drop; };
905 encodes as controller(userdata=00.00.00.00.00.00.00.00)
909 get_arp(outport, ip4.dst);
910 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[]
911 has prereqs eth.type == 0x800
912 get_arp(inport, reg0);
913 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[]
916 Syntax error at `;' expecting `('.
918 Syntax error at `)' expecting field name.
920 Syntax error at `)' expecting `,'.
921 get_arp(inport ip4.dst);
922 Syntax error at `ip4.dst' expecting `,'.
923 get_arp(inport, ip4.dst;
924 Syntax error at `;' expecting `)'.
925 get_arp(inport, eth.dst);
926 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
927 get_arp(inport, outport);
928 Cannot use string field outport where numeric field is required.
929 get_arp(reg0, ip4.dst);
930 Cannot use numeric field reg0 where string field is required.
933 put_arp(inport, arp.spa, arp.sha);
934 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[]
935 has prereqs eth.type == 0x806 && eth.type == 0x806
938 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
939 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)
940 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");
941 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");
942 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)
943 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);
944 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);
945 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)
947 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
948 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
949 reg1[0] = put_dhcp_opts();
950 put_dhcp_opts requires offerip to be specified.
951 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
952 Syntax error at `x' expecting DHCPv4 option name.
953 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
954 put_dhcp_opts requires offerip to be specified.
955 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
956 Syntax error at `"hi"'.
957 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
958 Syntax error at `xyzzy' expecting DHCPv4 option name.
959 reg1[0] = put_dhcp_opts(offerip="xyzzy");
960 DHCPv4 option offerip requires numeric value.
961 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
962 DHCPv4 option domain requires string value.
965 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; };
966 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
967 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)
971 get_nd(outport, ip6.dst);
972 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[]
973 has prereqs eth.type == 0x86dd
974 get_nd(inport, xxreg0);
975 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[]
977 Syntax error at `;' expecting `('.
979 Syntax error at `)' expecting field name.
981 Syntax error at `)' expecting `,'.
982 get_nd(inport ip6.dst);
983 Syntax error at `ip6.dst' expecting `,'.
984 get_nd(inport, ip6.dst;
985 Syntax error at `;' expecting `)'.
986 get_nd(inport, eth.dst);
987 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
988 get_nd(inport, outport);
989 Cannot use string field outport where numeric field is required.
990 get_nd(xxreg0, ip6.dst);
991 Cannot use numeric field xxreg0 where string field is required.
994 put_nd(inport, nd.target, nd.sll);
995 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[]
996 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)
999 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1000 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)
1001 reg1[0] = put_dhcpv6_opts();
1002 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1003 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1004 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1005 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)
1006 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1007 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1008 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)
1009 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1010 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)
1011 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1012 Syntax error at `x' expecting DHCPv6 option name.
1013 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1014 Syntax error at `"hi"'.
1015 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1016 Syntax error at `xyzzy' expecting DHCPv6 option name.
1017 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1018 DHCPv6 option ia_addr requires numeric value.
1019 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1020 DHCPv6 option domain_search requires string value.
1024 encodes as set_queue:0
1026 encodes as set_queue:61440
1028 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1030 # Contradictionary prerequisites (allowed but not useful):
1031 ip4.src = ip6.src[0..31];
1032 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1033 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1034 ip4.src <-> ip6.src[0..31];
1035 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[]
1036 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1038 # Miscellaneous negative tests.
1040 Syntax error at `;'.
1042 Syntax error at `xyzzy' expecting action.
1044 Syntax error at `123'.
1046 Syntax error at `xyzzy' expecting action.
1048 Syntax error at end of input expecting `;'.
1050 sed '/^[[ ]]/d' test-cases.txt > input.txt
1051 cp test-cases.txt expout
1052 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1055 AT_BANNER([OVN end-to-end tests])
1057 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1058 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1059 AT_KEYWORDS([ovnarp])
1060 AT_SKIP_IF([test $HAVE_PYTHON = no])
1063 # Create hypervisors hv[123].
1064 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1065 # Add all of the vifs to a single logical switch lsw0.
1066 # Turn on port security on all the vifs except vif[123]1.
1067 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1068 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1069 ovn-nbctl ls-add lsw0
1074 ovs-vsctl add-br br-phys
1075 ovn_attach n1 br-phys 192.168.0.$i
1078 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
1079 ovn-nbctl lsp-add lsw0 lp$i$j
1080 if test $j = 1; then
1081 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1083 if test $j = 3; then
1084 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1086 ip_addrs="192.168.0.$i$j"
1088 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1089 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1093 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1094 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1095 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1096 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\"
1097 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1099 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1100 # packets for ARP resolution (native tunneling doesn't queue packets
1101 # for ARP resolution).
1104 # Allow some time for ovn-northd and ovn-controller to catch up.
1105 # XXX This should be more systematic.
1108 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1109 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1110 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1111 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1113 # Given the name of a logical port, prints the name of the hypervisor
1114 # on which it is located.
1119 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1121 # This shell function causes a packet to be received on INPORT. The packet's
1122 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1123 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1124 # more) list the VIFs on which the packet should be received. INPORT and the
1125 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1132 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1133 hv=`vif_to_hv $inport`
1135 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1137 echo $packet >> $outport.expected
1141 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1143 # Causes a packet to be received on INPORT. The packet is an ARP
1144 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1145 # it should be the hardware address of the target to expect to receive in an
1146 # ARP reply; otherwise no reply is expected.
1148 # INPORT is an logical switch port number, e.g. 11 for vif11.
1149 # SHA and REPLY_HA are each 12 hex digits.
1150 # SPA and TPA are each 8 hex digits.
1152 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1153 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1154 hv=`vif_to_hv $inport`
1155 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1157 if test X$reply_ha = X; then
1158 # Expect to receive the broadcast ARP on the other logical switch ports
1159 # if no reply is expected.
1163 if test $i$j != $inport; then
1164 echo $request >> $i$j.expected
1169 # Expect to receive the reply, if any.
1170 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1171 echo $reply >> $inport.expected
1176 printf "%02x%02x%02x%02x" "$@"
1179 # Send packets between all pairs of source and destination ports:
1181 # 1. Unicast packets are delivered to exactly one logical switch port
1182 # (except that packets destined to their input ports are dropped).
1184 # 2. Broadcast and multicast are delivered to all logical switch ports
1185 # except the input port.
1187 # 3. When port security is turned on, the switch drops packets from the wrong
1190 # 4. The switch drops all packets with a VLAN tag.
1192 # 5. The switch drops all packets with a multicast source address. (This only
1193 # affects behavior when port security is turned off, since otherwise port
1194 # security would drop the packet anyway.)
1196 # 6. The switch delivers packets with an unknown destination to logical
1197 # switch ports with "unknown" among their MAC addresses (and port
1198 # security disabled).
1200 # 7. The switch drops unicast packets that violate an ACL.
1202 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1204 # 9. OVN generates responses to ARP requests for known IPs, except for
1205 # requests from a port for the port's own IP.
1207 # 10. No response to ARP requests for unknown IPs.
1220 if test $d != $s; then unicast=$d; else unicast=; fi
1221 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1223 if test $d != $s && test $js = 1; then
1228 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1230 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1231 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1232 if test $d = $s || (test $js = 1 && test $d = 33); then
1233 # Source of 11, 21, or 31 and dest of 33 should be dropped
1234 # due to the 4th ACL that uses address_set(set1).
1239 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1240 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1241 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1242 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1244 test_packet $s f000000000$d f00000000055 810000091234 #4
1245 test_packet $s f000000000$d 0100000000$s $s$d #5
1247 if test $d != $s && test $jd = 1; then
1248 unknown="$unknown $d"
1250 bcast="$bcast $unicast"
1251 bacl2="$bacl2 $acl2"
1252 bacl3="$bacl3 $acl3"
1254 sip=`ip_to_hex 192 168 0 $i$j`
1255 tip=`ip_to_hex 192 168 0 $id$jd`
1256 tip_unknown=`ip_to_hex 11 11 11 11`
1257 if test $d != $s; then
1258 reply_ha=f000000000$d
1262 test_arp $s f000000000$s $sip $tip $reply_ha #9
1263 test_arp $s f000000000$s $sip $tip_unknown #10
1265 if test $jd = 3; then
1266 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1267 tip=`ip_to_hex 192 169 0 $id$jd`
1268 test_arp $s f000000000$s $sip $tip $reply_ha #9
1273 # Broadcast and multicast.
1274 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1275 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1276 if test $js = 1; then
1277 bcast_impersonate=$bcast
1281 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1283 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1285 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1286 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1287 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1288 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1289 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1290 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1294 # set address for lp13 with invalid characters.
1295 # lp13 should be configured with only 192.168.0.13.
1296 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1298 # Allow some time for ovn-northd and ovn-controller to catch up.
1299 # XXX This should be more systematic.
1302 sip=`ip_to_hex 192 168 0 11`
1303 tip=`ip_to_hex 192 168 0 13`
1304 test_arp 11 f00000000011 $sip $tip f00000000013
1306 tip=`ip_to_hex 192 169 0 13`
1307 #arp request for 192.169.0.13 should be flooded
1308 test_arp 11 f00000000011 $sip $tip
1310 # dump information and flows with counters
1311 ovn-sbctl dump-flows -- list multicast_group
1313 echo "------ hv1 dump ------"
1314 as hv1 ovs-vsctl show
1315 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1317 echo "------ hv2 dump ------"
1318 as hv2 ovs-vsctl show
1319 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1321 echo "------ hv3 dump ------"
1322 as hv3 ovs-vsctl show
1323 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1325 # Now check the packets actually received against the ones expected.
1328 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1332 OVN_CLEANUP([hv1],[hv2],[hv3])
1336 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1337 AT_SKIP_IF([test $HAVE_PYTHON = no])
1340 # Create a logical switch and some logical ports.
1341 # Turn on port security on all lports except ls1.
1342 # Make ls1 a destination for unknown MACs.
1343 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1344 ovn-nbctl ls-add lsw0
1345 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1347 ovn-nbctl lsp-add lsw0 lp$i
1349 ovn-nbctl --wait=sb sync
1351 ovn-sbctl lsp-bind lp$i hv0
1352 if test $i = 1; then
1353 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1355 if test $i = 3; then
1356 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1358 ip_addrs="192.168.0.$i"
1360 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1361 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
1364 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1365 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1366 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1367 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1368 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1370 ovn-nbctl --wait=sb sync
1371 on_exit 'kill `cat ovn-trace.pid`'
1372 ovn-trace --detach --pidfile --no-chdir
1374 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1376 # This shell function causes a packet to be received on INPORT. The packet's
1377 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1378 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1379 # more) list the VIFs on which the packet should be received. INPORT and the
1380 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1382 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1383 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1386 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1387 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1392 echo "output(\"lp$outport\");"
1395 AT_CAPTURE_FILE([trace])
1396 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1399 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1401 # Causes a packet to be received on INPORT. The packet is an ARP
1402 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1403 # it should be the hardware address of the target to expect to receive in an
1404 # ARP reply; otherwise no reply is expected.
1406 # INPORT is an logical switch port number, e.g. 11 for vif11.
1407 # SHA and REPLY_HA are each 12 hex digits.
1408 # SPA and TPA are each 8 hex digits.
1410 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1412 local request="inport == \"lp$inport\"
1413 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1414 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1415 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1417 if test -z "$reply_ha"; then
1421 if test $i != $inport; then
1422 reply="${reply}output(\"lp$i\");
1429 eth.src = $reply_ha;
1432 arp.sha = $reply_ha;
1435 output(\"lp$inport\");
1439 AT_CAPTURE_FILE([trace])
1440 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1443 # Send packets between all pairs of source and destination ports:
1445 # 1. Unicast packets are delivered to exactly one logical switch port
1446 # (except that packets destined to their input ports are dropped).
1448 # 2. Broadcast and multicast are delivered to all logical switch ports
1449 # except the input port.
1451 # 3. When port security is turned on, the switch drops packets from the wrong
1454 # 4. The switch drops all packets with a VLAN tag.
1456 # 5. The switch drops all packets with a multicast source address. (This only
1457 # affects behavior when port security is turned off, since otherwise port
1458 # security would drop the packet anyway.)
1460 # 6. The switch delivers packets with an unknown destination to logical
1461 # switch ports with "unknown" among their MAC addresses (and port
1462 # security disabled).
1464 # 7. The switch drops unicast packets that violate an ACL.
1466 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1468 # 9. OVN generates responses to ARP requests for known IPs, except for
1469 # requests from a port for the port's own IP.
1471 # 10. No response to ARP requests for unknown IPs.
1481 if test $d != $s; then unicast=$d; else unicast=; fi
1482 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1484 if test $d != $s && test $s = 1; then
1489 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1491 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1492 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1493 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1494 # Source of 1 or 2 and dest of 3 should be dropped
1495 # due to the 4th ACL that uses address_set(set1).
1502 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1503 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1504 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1505 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1507 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1508 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1510 if test $d != $s && test $d = 1; then
1511 unknown="$unknown $d"
1513 bcast="$bcast $unicast"
1514 bacl2="$bacl2 $acl2"
1515 bacl3="$bacl3 $acl3"
1519 tip_unknown=11.11.11.11
1520 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1521 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1522 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1524 if test $d = 3; then
1525 # lp3 has an additional ip 192.169.0.[123]3.
1527 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1531 # Broadcast and multicast.
1532 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1533 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1534 if test $s = 1; then
1535 bcast_impersonate=$bcast
1539 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1541 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1544 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1545 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1546 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1549 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1550 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1551 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1556 # 2 hypervisors, 4 logical ports per HV
1557 # 2 locally attached networks (one flat, one vlan tagged over same device)
1558 # 2 ports per HV on each network
1559 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1560 AT_SKIP_IF([test $HAVE_PYTHON = no])
1563 # In this test cases we create 3 switches, all connected to same
1564 # physical network (through br-phys on each HV). Each switch has
1565 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1566 # of VIF port name indicates the hypervisor it is bound to, e.g.
1567 # lp23 means VIF 3 on hv2.
1569 # Each switch's VLAN tag and their logical switch ports are:
1572 # - ports: lp11, lp12, lp21, lp22
1575 # - tagged with VLAN 101
1576 # - ports: lp13, lp14, lp23, lp24
1579 # - ports: lp15, lp25
1581 # Note: a localnet port is created for each switch to connect to
1586 ovn-nbctl ls-add $ls_name
1588 if test $i -eq 2; then
1589 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1591 ovn-nbctl lsp-add $ls_name $ln_port_name
1593 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1594 ovn-nbctl lsp-set-type $ln_port_name localnet
1595 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1600 # Prints the name of the logical switch that contains LSP.
1603 lp?[[12]]) echo ls1 ;; dnl (
1604 lp?[[34]]) echo ls2 ;; dnl (
1605 lp?5) echo ls3 ;; dnl (
1606 *) AT_FAIL_IF([:]) ;;
1614 ovs-vsctl add-br br-phys
1615 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1616 ovn_attach n1 br-phys 192.168.0.$i
1618 for j in 1 2 3 4 5; do
1619 ovs-vsctl add-port br-int vif$i$j -- \
1620 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1621 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1622 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1626 ls_name=$(lsp_to_ls $lsp_name)
1628 ovn-nbctl lsp-add $ls_name $lsp_name
1629 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1630 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1632 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1635 ovn-nbctl --wait=sb sync
1636 ovn-sbctl dump-flows
1640 # XXX This is now the 3rd copy of these functions in this file ...
1642 # Given the name of a logical port, prints the name of the hypervisor
1643 # on which it is located.
1648 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1650 # This shell function causes a packet to be received on INPORT. The packet's
1651 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1652 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1653 # logical switch port numbers, e.g. 11 for vif11.
1655 # EOUT is the end-to-end output port, that is, where the packet will end up
1656 # after possibly bouncing through one or more localnet ports. LOUT is the
1657 # logical output port, which might be a localnet port, as seen by ovn-trace
1658 # (which doesn't know what localnet ports are connected to and therefore can't
1659 # figure out the end-to-end answer).
1661 for j in 1 2 3 4 5; do
1666 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1669 # First try tracing the packet.
1670 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1671 if test $lout != drop; then
1672 echo "output(\"$lout\");"
1674 AT_CAPTURE_FILE([trace])
1675 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1677 # Then actually send a packet, for an end-to-end test.
1678 local packet=$(echo $dst$src | sed 's/://g')${eth}
1679 hv=`vif_to_hv $inport`
1681 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1682 if test $eout != drop; then
1683 echo $packet >> ${eout#lp}.expected
1687 # lp11 and lp21 are on the same network (phys, untagged)
1688 # and on different hypervisors
1689 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1690 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1692 # lp11 and lp12 are on the same network (phys, untagged)
1693 # and on the same hypervisor
1694 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1695 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1697 # lp13 and lp23 are on the same network (phys, VLAN 101)
1698 # and on different hypervisors
1699 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1700 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1702 # lp13 and lp14 are on the same network (phys, VLAN 101)
1703 # and on the same hypervisor
1704 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1705 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1707 # lp11 and lp15 are on the same network (phys, untagged),
1708 # same hypervisor, and on different switches
1709 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1710 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1712 # lp11 and lp25 are on the same network (phys, untagged),
1713 # different hypervisors, and on different switches
1714 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1715 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1717 # Ports that should not be able to communicate
1718 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1719 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1720 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1721 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1722 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1723 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1724 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1725 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1727 # Dump a bunch of info helpful for debugging if there's a failure.
1729 echo "------ OVN dump ------"
1733 echo "------ hv1 dump ------"
1734 as hv1 ovs-vsctl show
1735 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1737 echo "------ hv2 dump ------"
1738 as hv2 ovs-vsctl show
1739 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1741 # Now check the packets actually received against the ones expected.
1743 for j in 1 2 3 4 5; do
1744 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1748 OVN_CLEANUP([hv1],[hv2])
1752 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1754 AT_SKIP_IF([test $HAVE_PYTHON = no])
1757 # Configure the Northbound database
1758 ovn-nbctl ls-add lsw0
1760 ovn-nbctl lsp-add lsw0 lp1
1761 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1763 ovn-nbctl lsp-add lsw0 lp2
1764 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1766 ovn-nbctl lsp-add lsw0 lp-vtep
1767 ovn-nbctl lsp-set-type lp-vtep vtep
1768 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1769 ovn-nbctl lsp-set-addresses lp-vtep unknown
1771 # lpr, lr and lrp1 are used for the ARP request handling test only.
1772 ovn-nbctl lsp-add lsw0 lpr
1774 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1775 ovn-nbctl set Logical_Switch_Port lpr type=router \
1776 options:router-port=lrp1 \
1777 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1780 net_add n1 # Network to connect hv1, hv2, and vtep
1781 net_add n2 # Network to connect vtep and hv3
1783 # Create hypervisor hv1 connected to n1
1786 ovs-vsctl add-br br-phys
1787 ovn_attach n1 br-phys 192.168.0.1
1788 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
1790 # Create hypervisor hv2 connected to n1
1793 ovs-vsctl add-br br-phys
1794 ovn_attach n1 br-phys 192.168.0.2
1795 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
1798 # Start the vtep emulator with a leg in both networks
1802 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1803 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1805 ovs-vsctl add-br br-phys
1806 net_attach n1 br-phys
1808 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1809 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1810 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1811 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1813 ovs-vsctl add-br br-vtep
1814 net_attach n2 br-vtep
1816 vtep-ctl add-ps br-vtep
1817 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1818 vtep-ctl add-ls lsw0
1820 start_daemon ovs-vtep br-vtep
1821 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1823 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1825 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1827 # It takes more time for the update to be processed by ovs-vtep.
1830 # Add hv3 on the other side of the vtep
1833 ovs-vsctl add-br br-phys
1834 net_attach n2 br-phys
1836 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
1838 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1839 # packets for ARP resolution (native tunneling doesn't queue packets
1840 # for ARP resolution).
1843 # Allow some time for ovn-northd and ovn-controller to catch up.
1844 # XXX This should be more systematic.
1847 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1849 # This shell function causes a packet to be received on INPORT. The packet's
1850 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1851 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1852 # more) list the VIFs on which the packet should be received. INPORT and the
1853 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
1858 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1859 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1862 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1864 echo $packet >> $outport.expected
1868 # Send packets between all pairs of source and destination ports:
1870 # 1. Unicast packets are delivered to exactly one logical switch port
1871 # (except that packets destined to their input ports are dropped).
1873 # 2. Broadcast and multicast are delivered to all logical switch ports
1874 # except the input port.
1876 # 3. The switch delivers packets with an unknown destination to logical
1877 # switch ports with "unknown" among their MAC addresses (and port
1878 # security disabled).
1883 if test $d != $s; then unicast=$d; else unicast=; fi
1884 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1886 # The vtep (vif3) is the only one configured for "unknown"
1887 if test $d != $s && test $d = 3; then
1888 unknown="$unknown $d"
1890 bcast="$bcast $unicast"
1893 # Broadcast and multicast.
1894 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1895 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
1897 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1900 # ARP request should not be responded to by logical switch router
1901 # type arp responder on HV1 and HV2 and should reach directly to
1904 printf "%02x%02x%02x%02x" "$@"
1907 spa=`ip_to_hex 192 168 1 2`
1908 tpa=`ip_to_hex 192 168 1 1`
1909 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1910 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1911 echo $request >> 1.expected
1912 echo $request >> 2.expected
1914 # dump information with counters
1915 echo "------ OVN dump ------"
1919 echo "---------SB dump-----"
1920 ovn-sbctl list datapath_binding
1921 echo "---------------------"
1922 ovn-sbctl list port_binding
1923 echo "---------------------"
1924 ovn-sbctl dump-flows
1926 echo "------ hv1 dump ------"
1927 as hv1 ovs-vsctl show
1928 as hv1 ovs-ofctl -O OpenFlow13 show br-int
1929 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1931 echo "------ hv2 dump ------"
1932 as hv2 ovs-vsctl show
1933 as hv2 ovs-ofctl -O OpenFlow13 show br-int
1934 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1936 echo "------ hv3 dump ------"
1937 as hv3 ovs-vsctl show
1938 # note: hv3 has no logical port bind, thus it should not have br-int
1939 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1940 [ovs-ofctl: br-int is not a bridge or a socket
1943 # Now check the packets actually received against the ones expected.
1945 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
1948 # Gracefully terminate daemons
1949 OVN_CLEANUP([hv1],[hv2],[vtep])
1950 OVN_CLEANUP_VSWITCH([hv3])
1954 # Similar test to "hardware GW"
1955 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1956 AT_SKIP_IF([test $HAVE_PYTHON = no])
1959 # Configure the Northbound database
1960 ovn-nbctl ls-add lsw0
1962 ovn-nbctl lsp-add lsw0 lp1
1963 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1965 ovn-nbctl lsp-add lsw0 lp2
1966 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1968 ovn-nbctl lsp-add lsw0 lp-gw
1969 ovn-nbctl lsp-set-type lp-gw l2gateway
1970 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
1971 ovn-nbctl lsp-set-addresses lp-gw unknown
1973 net_add n1 # Network to connect hv1, hv2, and gw
1974 net_add n2 # Network to connect gw and hv3
1976 # Create hypervisor hv1 connected to n1
1979 ovs-vsctl add-br br-phys
1980 ovn_attach n1 br-phys 192.168.0.1
1981 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
1983 # Create hypervisor hv2 connected to n1
1986 ovs-vsctl add-br br-phys
1987 ovn_attach n1 br-phys 192.168.0.2
1988 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
1990 # Create hypervisor hv_gw connected to n1 and n2
1991 # connect br-phys bridge to n1; connect hv-gw bridge to n2
1994 ovs-vsctl add-br br-phys
1995 ovn_attach n1 br-phys 192.168.0.3
1996 ovs-vsctl add-br br-phys2
1997 net_attach n2 br-phys2
1998 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2000 # Add hv3 on the other side of the GW
2003 ovs-vsctl add-br br-phys
2004 net_attach n2 br-phys
2005 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
2008 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2009 # packets for ARP resolution (native tunneling doesn't queue packets
2010 # for ARP resolution).
2013 # Allow some time for ovn-northd and ovn-controller to catch up.
2014 # XXX This should be more systematic.
2017 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2019 # This shell function causes a packet to be received on INPORT. The packet's
2020 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2021 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2022 # more) list the VIFs on which the packet should be received. INPORT and the
2023 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2028 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2029 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2032 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2034 echo $packet >> $outport.expected
2038 # Send packets between all pairs of source and destination ports:
2040 # 1. Unicast packets are delivered to exactly one lport (except that packets
2041 # destined to their input ports are dropped).
2043 # 2. Broadcast and multicast are delivered to all lports except the input port.
2045 # 3. The lswitch delivers packets with an unknown destination to lports with
2046 # "unknown" among their MAC addresses (and port security disabled).
2051 if test $d != $s; then unicast=$d; else unicast=; fi
2052 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2054 # The vtep (vif3) is the only one configured for "unknown"
2055 if test $d != $s && test $d = 3; then
2056 unknown="$unknown $d"
2058 bcast="$bcast $unicast"
2061 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2062 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2063 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2066 echo "------ ovn-nbctl show ------"
2068 echo "------ ovn-sbctl show ------"
2071 echo "------ hv1 ------"
2072 as hv1 ovs-vsctl show
2073 echo "------ hv1 br-int ------"
2074 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2075 echo "------ hv1 br-phys ------"
2076 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2078 echo "------ hv2 ------"
2079 as hv2 ovs-vsctl show
2080 echo "------ hv2 br-int ------"
2081 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2082 echo "------ hv2 br-phys ------"
2083 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2085 echo "------ hv_gw ------"
2086 as hv_gw ovs-vsctl show
2087 echo "------ hv_gw br-phys ------"
2088 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2089 echo "------ hv_gw br-phys2 ------"
2090 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2092 echo "------ hv3 ------"
2093 as hv3 ovs-vsctl show
2094 echo "------ hv3 br-phys ------"
2095 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2097 # Now check the packets actually received against the ones expected.
2099 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2103 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2104 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2105 AT_SKIP_IF([test $HAVE_PYTHON = no])
2110 # Three logical switches ls1, ls2, ls3.
2111 # One logical router lr0 connected to ls[123],
2112 # with nine subnets, three per logical switch:
2114 # lrp11 on ls1 for subnet 192.168.11.0/24
2115 # lrp12 on ls1 for subnet 192.168.12.0/24
2116 # lrp13 on ls1 for subnet 192.168.13.0/24
2118 # lrp33 on ls3 for subnet 192.168.33.0/24
2120 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2121 # digits are the subnet and the last digit distinguishes the VIF.
2123 ovn-nbctl ls-add ls$i
2126 # Add "unknown" to MAC addresses for lp?11, so packets for
2127 # MAC-IP bindings discovered via ARP later have somewhere to go.
2128 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2131 -- lsp-add ls$i lp$i$j$k \
2132 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2133 192.168.$i$j.$k" $unknown
2138 ovn-nbctl lr-add lr0
2141 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2143 -- lsp-add ls$i lrp$i$j-attachment \
2144 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2145 options:router-port=lrp$i$j \
2146 addresses='"00:00:00:00:ff:'$i$j'"'
2150 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2151 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2155 # Three hypervisors hv[123].
2156 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2157 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2158 # lp?3[123] all on hv3.
2161 # Given the name of a logical port, prints the name of the hypervisor
2162 # on which it is located.
2165 ?11) echo 1 ;; dnl (
2166 ?12 | ?21 | ?22) echo 2 ;; dnl (
2167 ?13 | ?23 | ?3?) echo 3 ;;
2171 # Given the name of a logical port, prints the name of its logical router
2172 # port, e.g. "vif_to_lrp 123" yields 12.
2177 # Given the name of a logical port, prints the name of its logical
2178 # switch, e.g. "vif_to_ls 123" yields 1.
2187 ovs-vsctl add-br br-phys
2188 ovn_attach n1 br-phys 192.168.0.$i
2193 hv=`vif_to_hv $i$j$k`
2194 as hv$hv ovs-vsctl \
2195 -- add-port br-int vif$i$j$k \
2196 -- set Interface vif$i$j$k \
2197 external-ids:iface-id=lp$i$j$k \
2198 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2199 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2200 ofport-request=$i$j$k
2205 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2206 # packets for ARP resolution (native tunneling doesn't queue packets
2207 # for ARP resolution).
2210 # Allow some time for ovn-northd and ovn-controller to catch up.
2211 # XXX This should be more systematic.
2214 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2216 # This shell function causes a packet to be received on INPORT. The packet's
2217 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2218 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2219 # more) list the VIFs on which the packet should be received. INPORT and the
2220 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2229 # This packet has bad checksums but logical L3 routing doesn't check.
2230 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2231 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2232 shift; shift; shift; shift; shift
2233 hv=hv`vif_to_hv $inport`
2234 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2235 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2236 in_ls=`vif_to_ls $inport`
2237 in_lrp=`vif_to_lrp $inport`
2239 out_ls=`vif_to_ls $outport`
2240 if test $in_ls = $out_ls; then
2241 # Ports on the same logical switch receive exactly the same packet.
2244 # Routing decrements TTL and updates source and dest MAC
2246 out_lrp=`vif_to_lrp $outport`
2247 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2248 fi >> $outport.expected
2252 as hv1 ovs-vsctl --columns=name,ofport list interface
2253 as hv1 ovn-sbctl list port_binding
2254 as hv1 ovn-sbctl list datapath_binding
2255 as hv1 ovn-sbctl dump-flows
2256 as hv1 ovs-ofctl dump-flows br-int
2258 # Send IP packets between all pairs of source and destination ports:
2260 # 1. Unicast IP packets are delivered to exactly one logical switch port
2261 # (except that packets destined to their input ports are dropped).
2263 # 2. Broadcast IP packets are delivered to all logical switch ports
2264 # except the input port.
2266 printf "%02x%02x%02x%02x" "$@"
2274 sip=`ip_to_hex 192 168 $is$js $ks`
2279 dip=`ip_to_hex 192 168 $id$jd $kd`
2280 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2281 if test $d != $s; then unicast=$d; else unicast=; fi
2283 test_ip $s $smac $dmac $sip $dip $unicast #1
2285 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2289 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2294 # 3. Send an IP packet from every logical port to every other subnet,
2295 # to an IP address that does not have a static IP-MAC binding.
2296 # This should generate a broadcast ARP request for the destination
2297 # IP address in the destination subnet.
2303 sip=`ip_to_hex 192 168 $is$js $ks`
2306 if test $is$js = $id$jd; then
2311 dmac=00000000ff$is$js
2312 # Calculate a 4th octet for the destination that is
2313 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2314 # that have static MAC bindings, and fits in the range
2316 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2317 dip=`ip_to_hex 192 168 $id$jd $o4`
2318 test_ip $s $smac $dmac $sip $dip
2320 # Every LP on the destination subnet's lswitch should
2321 # receive the ARP request.
2322 lrmac=00000000ff$id$jd
2323 lrip=`ip_to_hex 192 168 $id$jd 254`
2324 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2325 for jd2 in 1 2 3; do
2327 echo $arp >> $id$jd2$kd.expected
2336 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2338 # Causes a packet to be received on INPORT. The packet is an ARP
2339 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2340 # it should be the hardware address of the target to expect to receive in an
2341 # ARP reply; otherwise no reply is expected.
2343 # INPORT is an logical switch port number, e.g. 11 for vif11.
2344 # SHA and REPLY_HA are each 12 hex digits.
2345 # SPA and TPA are each 8 hex digits.
2347 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2348 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2349 hv=hv`vif_to_hv $inport`
2350 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2351 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2353 # Expect to receive the broadcast ARP on the other logical switch ports if
2354 # IP address is not configured to the switch patch port.
2355 local i=`vif_to_ls $inport`
2359 # 192.168.33.254 is configured to the switch patch port for lrp33,
2360 # so no ARP flooding expected for it.
2361 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2362 echo $request >> $i$j$k.expected
2367 # Expect to receive the reply, if any.
2368 if test X$reply_ha != X; then
2369 lrp=`vif_to_lrp $inport`
2370 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2371 echo $reply >> $inport.expected
2375 # Test router replies to ARP requests from all source ports:
2377 # 4. Router replies to query for its MAC address from port's own IP address.
2379 # 5. Router replies to query for its MAC address from any random IP address
2382 # 6. Router replies to query for its MAC address from another subnet.
2384 # 7. No reply to query for IP address other than router IP.
2388 smac=f00000000$i$j$k # Source MAC
2389 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2390 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2391 rmac=00000000ff$i$j # Router MAC
2392 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2393 test_arp $i$j$k $smac $sip $rip $rmac #4
2394 test_arp $i$j$k $smac $otherip $rip $rmac #5
2395 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2396 test_arp $i$j$k $smac $sip $otherip #7
2401 # Allow some time for packet forwarding.
2402 # XXX This can be improved.
2405 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2408 # Here, the $s is the VIF that originated the ARP request and $d is
2409 # the VIF that sends the ARP reply, which is somewhat backward but
2410 # it means that $s and $d are the same as #3.
2411 : > mac_bindings.expected
2418 if test $is$js = $id$jd; then
2425 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2426 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2427 host_mac=8000000000$o4
2429 lrmac=00000000ff$id$jd
2430 lrip=`ip_to_hex 192 168 $id$jd 254`
2432 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2438 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2439 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2440 #as $hv ovs-ofctl dump-flows br-int table=19
2442 host_ip_pretty=192.168.$id$jd.$o4
2443 host_mac_pretty=80:00:00:00:00:$o4
2444 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2451 # Allow some time for packet forwarding.
2452 # XXX This can be improved.
2455 # 9. Send an IP packet from every logical port to every other subnet. These
2456 # are the same packets already sent as #3, but now the destinations' IP-MAC
2457 # bindings have been discovered via ARP, so instead of provoking an ARP
2458 # request, these packets now get routed to their destinations (which don't
2459 # have static MAC bindings, so they go to the port we've designated as
2460 # accepting "unknown" MACs.)
2466 sip=`ip_to_hex 192 168 $is$js $ks`
2469 if test $is$js = $id$jd; then
2474 dmac=00000000ff$is$js
2475 # Calculate a 4th octet for the destination that is
2476 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2477 # that have static MAC bindings, and fits in the range
2479 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2480 dip=`ip_to_hex 192 168 $id$jd $o4`
2481 test_ip $s $smac $dmac $sip $dip
2483 # Expect the packet egress.
2484 host_mac=8000000000$o4
2487 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2494 ovn-sbctl -f csv -d bare --no-heading \
2495 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2497 # Now check the packets actually received against the ones expected.
2501 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2507 # Check the MAC bindings against those expected.
2508 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2511 # Gracefully terminate daemons
2512 OVN_CLEANUP([hv1], [hv2], [hv3])
2516 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2517 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2518 AT_SKIP_IF([test $HAVE_PYTHON = no])
2521 # Create hypervisors hv[123].
2522 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2523 # Add all of the vifs to a single logical switch lsw0.
2524 # Turn off port security on vifs vif[123]1
2525 # Turn on l2 port security on vifs vif[123]2
2526 # Turn of l2 and l3 port security on vifs vif[123]3
2527 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2528 ovn-nbctl ls-add lsw0
2533 ovs-vsctl add-br br-phys
2534 ovn_attach n1 br-phys 192.168.0.$i
2537 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
2538 ovn-nbctl lsp-add lsw0 lp$i$j
2539 if test $j = 1; then
2540 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2541 elif test $j = 2; then
2542 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2543 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2545 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2546 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2547 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2552 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2553 # packets for ARP resolution (native tunneling doesn't queue packets
2554 # for ARP resolution).
2557 # Allow some time for ovn-northd and ovn-controller to catch up.
2558 # XXX This should be more systematic.
2561 # Given the name of a logical port, prints the name of the hypervisor
2562 # on which it is located.
2573 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2575 # This shell function causes an ip packet to be received on INPORT.
2576 # The packet's content has Ethernet destination DST and source SRC
2577 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2578 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2579 # be received. INPORT and the OUTPORTs are specified as logical switch
2580 # port numbers, e.g. 11 for vif11.
2582 # This packet has bad checksums but logical L3 routing doesn't check.
2583 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2584 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2585 shift; shift; shift; shift; shift
2586 hv=`vif_to_hv $inport`
2587 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2588 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2590 echo $packet >> $outport.expected
2594 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2596 # Causes a packet to be received on INPORT. The packet is an ARP
2597 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2598 # it should be the hardware address of the target to expect to receive in an
2599 # ARP reply; otherwise no reply is expected.
2601 # INPORT is an logical switch port number, e.g. 11 for vif11.
2602 # SHA and REPLY_HA are each 12 hex digits.
2603 # SPA and TPA are each 8 hex digits.
2605 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2606 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2607 hv=`vif_to_hv $inport`
2608 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2609 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2610 if test $drop != 1; then
2611 if test X$reply_ha = X; then
2612 # Expect to receive the broadcast ARP on the other logical switch ports
2613 # if no reply is expected.
2617 if test $i$j != $inport; then
2618 echo $request >> $i$j.expected
2623 # Expect to receive the reply, if any.
2624 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2625 echo $reply >> $inport.expected
2630 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2631 # This function is similar to test_ip() except that it sends
2634 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2635 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2636 shift; shift; shift; shift; shift
2637 hv=`vif_to_hv $inport`
2638 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2639 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2641 echo $packet >> $outport.expected
2645 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2646 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2647 # of the test packet
2649 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2650 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2651 shift; shift; shift; shift; shift; shift
2652 hv=`vif_to_hv $inport`
2653 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2654 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2656 echo $packet >> $outport.expected
2661 printf "%02x%02x%02x%02x" "$@"
2665 sip=`ip_to_hex 192 168 0 12`
2666 tip=`ip_to_hex 192 168 0 13`
2667 # the arp packet should be allowed even if lp[123]1 is
2668 # not configured with mac f00000000023 and ip 192.168.0.12
2670 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2672 if test $i != $j; then
2673 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2679 sip=`ip_to_hex 192 168 0 12`
2680 tip=`ip_to_hex 192 168 0 13`
2682 # arp packet should be allowed since lp22 is configured with
2684 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2686 # arp packet should not be allowed since lp32 is not configured with
2688 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2690 # arp packet with sha set to f00000000021 should not be allowed
2692 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2694 # ip packets should be allowed and received since lp[123]2 do not
2695 # have l3 port security
2696 sip=`ip_to_hex 192 168 0 55`
2697 tip=`ip_to_hex 192 168 0 66`
2700 if test $i != $j; then
2701 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2706 # ipv6 packets should be received by lp[123]2
2707 # lp[123]1 can send ipv6 traffic as there is no port security
2708 sip=fe800000000000000000000000000000
2709 tip=ff020000000000000000000000000000
2712 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2716 # l2 and l3 port security
2717 sip=`ip_to_hex 192 168 0 13`
2718 tip=`ip_to_hex 192 168 0 22`
2719 # arp packet should be allowed since lp13 is configured with
2720 # f00000000013 and 192.168.0.13
2721 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2723 # the arp packet should be dropped because lp23 is not configured
2724 # with mac f00000000022
2725 sip=`ip_to_hex 192 168 0 13`
2726 tip=`ip_to_hex 192 168 0 22`
2727 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2729 # the arp packet should be dropped because lp33 is not configured
2730 # with ip 192.168.0.55
2731 spa=`ip_to_hex 192 168 0 55`
2732 tpa=`ip_to_hex 192 168 0 22`
2733 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2735 # ip packets should not be received by lp[123]3 since
2736 # l3 port security is enabled
2737 sip=`ip_to_hex 192 168 0 55`
2738 tip=`ip_to_hex 192 168 0 66`
2741 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2745 # ipv6 packets should be dropped for lp[123]3 since
2746 # it is configured with only ipv4 address
2747 sip=fe800000000000000000000000000000
2748 tip=ff020000000000000000000000000000
2751 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2754 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2755 # lp[123]1 can send ipv6 traffic as there is no port security
2757 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2760 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2761 # fe80::ea2a:eaff:fe28:0012
2763 # ipv4 packet should be dropped for lp13 with mac f0000000113
2764 sip=`ip_to_hex 192 168 0 13`
2765 tip=`ip_to_hex 192 168 0 23`
2766 test_ip 13 f00000000113 f00000000023 $sip $tip
2768 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2769 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2770 # lp11 can send ipv6 traffic as there is no port security
2771 sip=ee800000000000000000000000000000
2773 tip=fe80000000000000ea2aeafffe2800${i}3
2774 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2778 # ipv6 packet should not be received by lp33 with mac f0000000333
2779 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2780 # configured with fe80::ea2a:eaff:fe28:0033
2781 # lp11 can send ipv6 traffic as there is no port security
2783 sip=ee800000000000000000000000000000
2784 tip=fe80000000000000ea2aeafffe280023
2785 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2787 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2788 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2789 # and should be dropped for any other ip6.src
2790 # lp21 can receive ipv6 traffic as there is no port security
2792 tip=ee800000000000000000000000000000
2794 sip=fe80000000000000ea2aeafffe2800${i}3
2795 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2797 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2798 sip=00000000000000000000000000000000
2799 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2800 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2801 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2802 # Traffic to non-multicast traffic should be dropped
2803 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2804 # Traffic of other ICMPv6 types should be dropped
2805 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2808 sip=ae80000000000000ea2aeafffe2800aa
2809 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2812 # configure lsp13 to send and received IPv4 packets with an address range
2813 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"
2817 sip=`ip_to_hex 10 0 0 13`
2818 tip=`ip_to_hex 192 168 0 22`
2819 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2820 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2822 sip=`ip_to_hex 10 0 0 14`
2823 tip=`ip_to_hex 192 168 0 23`
2824 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2825 # with dst ip 192.168.0.23 should be allowed
2826 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2828 sip=`ip_to_hex 192 168 0 33`
2829 tip=`ip_to_hex 10 0 0 15`
2830 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2831 # with dst ip 10.0.0.15 should be received by lsp13
2832 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2834 sip=`ip_to_hex 192 168 0 33`
2835 tip=`ip_to_hex 20 0 0 4`
2836 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2837 # with dst ip 20.0.0.4 should be received by lsp13
2838 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2840 sip=`ip_to_hex 192 168 0 33`
2841 tip=`ip_to_hex 20 0 0 5`
2842 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2843 # with dst ip 20.0.0.5 should not be received by lsp13
2844 test_ip 33 f00000000033 f00000000013 $sip $tip
2846 sip=`ip_to_hex 192 168 0 33`
2847 tip=`ip_to_hex 20 0 0 255`
2848 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2849 # with dst ip 20.0.0.255 should be received by lsp13
2850 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2852 sip=`ip_to_hex 192 168 0 33`
2853 tip=`ip_to_hex 192 168 0 255`
2854 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2855 # with dst ip 192.168.0.255 should not be received by lsp13
2856 test_ip 33 f00000000033 f00000000013 $sip $tip
2858 sip=`ip_to_hex 192 168 0 33`
2859 tip=`ip_to_hex 224 0 0 4`
2860 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2861 # with dst ip 224.0.0.4 should be received by lsp13
2862 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2864 #dump information including flow counters
2866 ovn-sbctl dump-flows -- list multicast_group
2868 echo "------ hv1 dump ------"
2869 as hv1 ovs-vsctl show
2870 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2871 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2873 echo "------ hv2 dump ------"
2874 as hv2 ovs-vsctl show
2875 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2876 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2878 echo "------ hv3 dump ------"
2879 as hv3 ovs-vsctl show
2880 as hv3 ovs-ofctl -O OpenFlow13 show br-int
2881 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2883 # Now check the packets actually received against the ones expected.
2886 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2890 OVN_CLEANUP([hv1],[hv2],[hv3])
2894 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2895 AT_SKIP_IF([test $HAVE_PYTHON = no])
2899 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2900 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2901 # R2 has ls2 (172.16.1.0/24) connected to it.
2903 ls1_lp1_mac="f0:00:00:01:02:03"
2904 rp_ls1_mac="00:00:00:01:02:03"
2905 rp_ls2_mac="00:00:00:01:02:04"
2906 ls2_lp1_mac="f0:00:00:01:02:04"
2908 ls1_lp1_ip="192.168.1.2"
2909 ls2_lp1_ip="172.16.1.2"
2914 ovn-nbctl ls-add ls1
2915 ovn-nbctl ls-add ls2
2918 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
2920 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2921 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
2924 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
2926 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
2927 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
2930 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
2931 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
2933 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
2934 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
2936 # Create logical port ls1-lp1 in ls1
2937 ovn-nbctl lsp-add ls1 ls1-lp1 \
2938 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
2940 # Create logical port ls2-lp1 in ls2
2941 ovn-nbctl lsp-add ls2 ls2-lp1 \
2942 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
2944 # Create two hypervisor and create OVS ports corresponding to logical ports.
2949 ovs-vsctl add-br br-phys
2950 ovn_attach n1 br-phys 192.168.0.1
2951 ovs-vsctl -- add-port br-int hv1-vif1 -- \
2952 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2953 options:tx_pcap=hv1/vif1-tx.pcap \
2954 options:rxq_pcap=hv1/vif1-rx.pcap \
2959 ovs-vsctl add-br br-phys
2960 ovn_attach n1 br-phys 192.168.0.2
2961 ovs-vsctl -- add-port br-int hv2-vif1 -- \
2962 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
2963 options:tx_pcap=hv2/vif1-tx.pcap \
2964 options:rxq_pcap=hv2/vif1-rx.pcap \
2968 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2969 # packets for ARP resolution (native tunneling doesn't queue packets
2970 # for ARP resolution).
2973 # Allow some time for ovn-northd and ovn-controller to catch up.
2974 # XXX This should be more systematic.
2978 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
2979 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
2980 udp && udp.src==53 && udp.dst==4369"
2981 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
2984 echo "---------NB dump-----"
2986 echo "---------------------"
2987 ovn-nbctl list logical_router
2988 echo "---------------------"
2989 ovn-nbctl list logical_router_port
2990 echo "---------------------"
2992 echo "---------SB dump-----"
2993 ovn-sbctl list datapath_binding
2994 echo "---------------------"
2995 ovn-sbctl list port_binding
2996 echo "---------------------"
2998 echo "------ hv1 dump ----------"
2999 as hv1 ovs-ofctl show br-int
3000 as hv1 ovs-ofctl dump-flows br-int
3001 echo "------ hv2 dump ----------"
3002 as hv2 ovs-ofctl show br-int
3003 as hv2 ovs-ofctl dump-flows br-int
3006 # The TTL should be decremented by 2.
3007 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3008 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3009 udp && udp.src==53 && udp.dst==4369"
3010 echo $packet | ovstest test-ovn expr-to-packets > expected
3012 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3014 OVN_CLEANUP([hv1],[hv2])
3019 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3020 AT_KEYWORDS([router-admin-state])
3021 AT_SKIP_IF([test $HAVE_PYTHON = no])
3025 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3026 # and 172.16.1.0/24) connected to it.
3030 ovn-nbctl ls-add ls1
3033 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3034 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3035 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3037 # Create logical port ls1-lp1 in ls1
3038 ovn-nbctl lsp-add ls1 ls1-lp1 \
3039 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3041 # Create logical port ls1-lp2 in ls1
3042 ovn-nbctl lsp-add ls1 ls1-lp2 \
3043 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3045 # Create one hypervisor and create OVS ports corresponding to logical ports.
3050 ovs-vsctl add-br br-phys
3051 ovn_attach n1 br-phys 192.168.0.1
3052 ovs-vsctl -- add-port br-int vif1 -- \
3053 set interface vif1 external-ids:iface-id=ls1-lp1 \
3054 options:tx_pcap=hv1/vif1-tx.pcap \
3055 options:rxq_pcap=hv1/vif1-rx.pcap \
3058 ovs-vsctl -- add-port br-int vif2 -- \
3059 set interface vif2 external-ids:iface-id=ls1-lp2 \
3060 options:tx_pcap=hv1/vif2-tx.pcap \
3061 options:rxq_pcap=hv1/vif2-rx.pcap \
3065 # Allow some time for ovn-northd and ovn-controller to catch up.
3066 # XXX This should be more systematic.
3069 # Send ip packets between the two ports.
3071 printf "%02x%02x%02x%02x" "$@"
3075 src_mac="f00000010203"
3076 dst_mac="000000010203"
3077 src_ip=`ip_to_hex 192 168 1 2`
3078 dst_ip=`ip_to_hex 172 16 1 2`
3079 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3080 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3083 echo "---------NB dump-----"
3085 echo "---------------------"
3086 ovn-nbctl list logical_router
3087 echo "---------------------"
3088 ovn-nbctl list logical_router_port
3089 echo "---------------------"
3091 echo "---------SB dump-----"
3092 ovn-sbctl list datapath_binding
3093 echo "---------------------"
3094 ovn-sbctl list logical_flow
3095 echo "---------------------"
3097 echo "------ hv1 dump ----------"
3098 as hv1 ovs-ofctl dump-flows br-int
3102 ovn-nbctl set Logical_Router R1 enabled=false
3104 # Allow some time for ovn-northd and ovn-controller to catch up.
3105 # XXX This should be more systematic.
3108 echo "---------SB dump-----"
3109 ovn-sbctl list datapath_binding
3110 echo "---------------------"
3111 ovn-sbctl list logical_flow
3112 echo "---------------------"
3114 echo "------ hv1 dump ----------"
3115 as hv1 ovs-ofctl dump-flows br-int
3117 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3120 expect_src_mac="000000010203"
3121 expect_dst_mac="f00000010204"
3122 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3124 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3128 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3129 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3130 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3133 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3136 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3139 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3142 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3143 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3148 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3149 AT_KEYWORDS([router-admin-state])
3150 AT_SKIP_IF([test $HAVE_PYTHON = no])
3154 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3155 # and has switch ls2 (172.16.1.0/24) connected to it.
3159 ovn-nbctl ls-add ls1
3160 ovn-nbctl ls-add ls2
3163 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3164 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3165 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3168 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3169 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3170 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3172 # Create logical port ls1-lp1 in ls1
3173 ovn-nbctl lsp-add ls1 ls1-lp1 \
3174 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3176 # Create logical port ls2-lp1 in ls2
3177 ovn-nbctl lsp-add ls2 ls2-lp1 \
3178 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3180 # Create one hypervisor and create OVS ports corresponding to logical ports.
3185 ovs-vsctl add-br br-phys
3186 ovn_attach n1 br-phys 192.168.0.1
3187 ovs-vsctl -- add-port br-int vif1 -- \
3188 set interface vif1 external-ids:iface-id=ls1-lp1 \
3189 options:tx_pcap=hv1/vif1-tx.pcap \
3190 options:rxq_pcap=hv1/vif1-rx.pcap \
3193 ovs-vsctl -- add-port br-int vif2 -- \
3194 set interface vif2 external-ids:iface-id=ls2-lp1 \
3195 options:tx_pcap=hv1/vif2-tx.pcap \
3196 options:rxq_pcap=hv1/vif2-rx.pcap \
3200 # Allow some time for ovn-northd and ovn-controller to catch up.
3201 # XXX This should be more systematic.
3204 # Send ip packets between the two ports.
3206 printf "%02x%02x%02x%02x" "$@"
3210 src_mac="f00000010203"
3211 dst_mac="000000010203"
3212 src_ip=`ip_to_hex 192 168 1 2`
3213 dst_ip=`ip_to_hex 172 16 1 2`
3214 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3215 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3218 echo "---------NB dump-----"
3220 echo "---------------------"
3221 ovn-nbctl list logical_router
3222 echo "---------------------"
3223 ovn-nbctl list logical_router_port
3224 echo "---------------------"
3226 echo "---------SB dump-----"
3227 ovn-sbctl list datapath_binding
3228 echo "---------------------"
3229 ovn-sbctl list logical_flow
3230 echo "---------------------"
3232 echo "------ hv1 dump ----------"
3233 as hv1 ovs-ofctl dump-flows br-int
3236 ovn-nbctl set Logical_Router R1 enabled=false
3238 echo "---------SB dump-----"
3239 ovn-sbctl list datapath_binding
3240 echo "---------------------"
3241 ovn-sbctl list logical_flow
3242 echo "---------------------"
3244 echo "------ hv1 dump ----------"
3245 as hv1 ovs-ofctl dump-flows br-int
3247 # Allow some time for the disabling of logical router R1 to propagate.
3248 # XXX This should be more systematic.
3251 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3254 expect_src_mac="000000010204"
3255 expect_dst_mac="f00000010204"
3256 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3258 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3264 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3265 AT_SKIP_IF([test $HAVE_PYTHON = no])
3269 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3270 # network. R1 has switchess foo (192.168.1.0/24)
3272 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3277 ovn-nbctl ls-add foo
3278 ovn-nbctl ls-add alice
3279 ovn-nbctl ls-add bob
3282 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3283 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3284 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3286 # Connect alice to R2
3287 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3288 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3289 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3292 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3293 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3294 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3297 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3298 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3300 #install static routes
3301 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3302 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3303 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3305 # Create logical port foo1 in foo
3306 ovn-nbctl lsp-add foo foo1 \
3307 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3309 # Create logical port alice1 in alice
3310 ovn-nbctl lsp-add alice alice1 \
3311 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3313 # Create logical port bob1 in bob
3314 ovn-nbctl lsp-add bob bob1 \
3315 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3317 # Create two hypervisor and create OVS ports corresponding to logical ports.
3322 ovs-vsctl add-br br-phys
3323 ovn_attach n1 br-phys 192.168.0.1
3324 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3325 set interface hv1-vif1 external-ids:iface-id=foo1 \
3326 options:tx_pcap=hv1/vif1-tx.pcap \
3327 options:rxq_pcap=hv1/vif1-rx.pcap \
3330 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3331 set interface hv1-vif2 external-ids:iface-id=alice1 \
3332 options:tx_pcap=hv1/vif2-tx.pcap \
3333 options:rxq_pcap=hv1/vif2-rx.pcap \
3338 ovs-vsctl add-br br-phys
3339 ovn_attach n1 br-phys 192.168.0.2
3340 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3341 set interface hv2-vif1 external-ids:iface-id=bob1 \
3342 options:tx_pcap=hv2/vif1-tx.pcap \
3343 options:rxq_pcap=hv2/vif1-rx.pcap \
3347 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3348 # packets for ARP resolution (native tunneling doesn't queue packets
3349 # for ARP resolution).
3352 # Allow some time for ovn-northd and ovn-controller to catch up.
3353 # XXX This should be more systematic.
3357 printf "%02x%02x%02x%02x" "$@"
3360 # Send ip packets between foo1 and alice1
3361 src_mac="f00000010203"
3362 dst_mac="000000010203"
3363 src_ip=`ip_to_hex 192 168 1 2`
3364 dst_ip=`ip_to_hex 172 16 1 2`
3365 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3366 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3368 # Send ip packets between foo1 and bob1
3369 src_mac="f00000010203"
3370 dst_mac="000000010203"
3371 src_ip=`ip_to_hex 192 168 1 2`
3372 dst_ip=`ip_to_hex 172 16 2 2`
3373 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3374 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3376 echo "---------NB dump-----"
3378 echo "---------------------"
3379 ovn-nbctl list logical_router
3380 echo "---------------------"
3381 ovn-nbctl list logical_router_port
3382 echo "---------------------"
3384 echo "---------SB dump-----"
3385 ovn-sbctl list datapath_binding
3386 echo "---------------------"
3387 ovn-sbctl list port_binding
3388 echo "---------------------"
3390 echo "------ hv1 dump ----------"
3391 as hv1 ovs-ofctl dump-flows br-int
3392 echo "------ hv2 dump ----------"
3393 as hv2 ovs-ofctl dump-flows br-int
3395 # Packet to Expect at bob1
3396 src_mac="000000010205"
3397 dst_mac="f00000010205"
3398 src_ip=`ip_to_hex 192 168 1 2`
3399 dst_ip=`ip_to_hex 172 16 2 2`
3400 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3402 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3404 # Packet to Expect at alice1
3405 src_mac="000000010204"
3406 dst_mac="f00000010204"
3407 src_ip=`ip_to_hex 192 168 1 2`
3408 dst_ip=`ip_to_hex 172 16 1 2`
3409 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3411 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3413 OVN_CLEANUP([hv1],[hv2])
3417 AT_SETUP([ovn -- send gratuitous arp on localnet])
3418 AT_SKIP_IF([test $HAVE_PYTHON = no])
3420 ovn-nbctl ls-add lsw0
3428 ovn_attach n1 br-phys 192.168.0.1
3430 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3431 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])
3434 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3435 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3436 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3438 # Create a localnet port.
3439 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3440 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3441 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3442 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3444 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3446 # Wait for packet to be received.
3447 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3448 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3450 # Delete the localnet ports.
3451 AT_CHECK([ovs-vsctl del-port localvif1])
3452 AT_CHECK([ovn-nbctl lsp-del ln_port])
3458 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3459 AT_SKIP_IF([test $HAVE_PYTHON = no])
3463 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3464 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3465 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3472 ovn-nbctl ls-add foo
3473 ovn-nbctl ls-add alice
3474 ovn-nbctl ls-add bob
3475 ovn-nbctl ls-add join
3478 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3479 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3480 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3482 # Connect alice to R2
3483 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3484 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3485 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3488 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3489 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3490 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3492 # Connect R1 to join
3493 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3494 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3495 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3497 # Connect R2 to join
3498 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3499 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3500 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3502 # Connect R3 to join
3503 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3504 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3505 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3507 #install static routes
3508 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3509 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3511 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3512 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3514 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3515 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3517 # Create logical port foo1 in foo
3518 ovn-nbctl lsp-add foo foo1 \
3519 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3521 # Create logical port alice1 in alice
3522 ovn-nbctl lsp-add alice alice1 \
3523 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3525 # Create logical port bob1 in bob
3526 ovn-nbctl lsp-add bob bob1 \
3527 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3529 # Create two hypervisor and create OVS ports corresponding to logical ports.
3534 ovs-vsctl add-br br-phys
3535 ovn_attach n1 br-phys 192.168.0.1
3536 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3537 set interface hv1-vif1 external-ids:iface-id=foo1 \
3538 options:tx_pcap=hv1/vif1-tx.pcap \
3539 options:rxq_pcap=hv1/vif1-rx.pcap \
3542 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3543 set interface hv1-vif2 external-ids:iface-id=alice1 \
3544 options:tx_pcap=hv1/vif2-tx.pcap \
3545 options:rxq_pcap=hv1/vif2-rx.pcap \
3550 ovs-vsctl add-br br-phys
3551 ovn_attach n1 br-phys 192.168.0.2
3552 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3553 set interface hv2-vif1 external-ids:iface-id=bob1 \
3554 options:tx_pcap=hv2/vif1-tx.pcap \
3555 options:rxq_pcap=hv2/vif1-rx.pcap \
3559 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3560 # packets for ARP resolution (native tunneling doesn't queue packets
3561 # for ARP resolution).
3564 # Allow some time for ovn-northd and ovn-controller to catch up.
3565 # XXX This should be more systematic.
3569 printf "%02x%02x%02x%02x" "$@"
3572 # Send ip packets between foo1 and alice1
3573 src_mac="f00000010203"
3574 dst_mac="000001010203"
3575 src_ip=`ip_to_hex 192 168 1 2`
3576 dst_ip=`ip_to_hex 172 16 1 2`
3577 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3578 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3579 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3581 # Send ip packets between foo1 and bob1
3582 src_mac="f00000010203"
3583 dst_mac="000001010203"
3584 src_ip=`ip_to_hex 192 168 1 2`
3585 dst_ip=`ip_to_hex 10 32 1 2`
3586 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3587 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3589 echo "---------NB dump-----"
3591 echo "---------------------"
3592 ovn-nbctl list logical_router
3593 echo "---------------------"
3594 ovn-nbctl list logical_router_port
3595 echo "---------------------"
3597 echo "---------SB dump-----"
3598 ovn-sbctl list datapath_binding
3599 echo "---------------------"
3600 ovn-sbctl list port_binding
3601 echo "---------------------"
3602 ovn-sbctl dump-flows
3603 echo "---------------------"
3605 echo "------ hv1 dump ----------"
3606 as hv1 ovs-ofctl show br-int
3607 as hv1 ovs-ofctl dump-flows br-int
3608 echo "------ hv2 dump ----------"
3609 as hv2 ovs-ofctl show br-int
3610 as hv2 ovs-ofctl dump-flows br-int
3611 echo "----------------------------"
3613 # Packet to Expect at bob1
3614 src_mac="000003010203"
3615 dst_mac="f00000010205"
3616 src_ip=`ip_to_hex 192 168 1 2`
3617 dst_ip=`ip_to_hex 10 32 1 2`
3618 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3620 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3622 # Packet to Expect at alice1
3623 src_mac="000002010203"
3624 dst_mac="f00000010204"
3625 src_ip=`ip_to_hex 192 168 1 2`
3626 dst_ip=`ip_to_hex 172 16 1 2`
3627 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3629 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3631 OVN_CLEANUP([hv1],[hv2])
3635 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3636 AT_SKIP_IF([test $HAVE_PYTHON = no])
3639 ovn-nbctl ls-add ls1
3641 ovn-nbctl lsp-add ls1 ls1-lp1 \
3642 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3644 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3646 ovn-nbctl lsp-add ls1 ls1-lp2 \
3647 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3649 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3651 ovn-nbctl ls-add ls2
3652 ovn-nbctl lsp-add ls2 ls2-lp1 \
3653 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3654 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3655 ovn-nbctl lsp-add ls2 ls2-lp2 \
3656 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3657 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3659 ovn-nbctl -- --id=@d1 create DHCP_Options cidr=10.0.0.0/24 \
3660 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3661 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"" \
3662 -- add Logical_Switch_Port ls1-lp1 dhcpv4_options @d1 \
3663 -- add Logical_Switch_Port ls1-lp2 dhcpv4_options @d1
3665 ovn-nbctl -- --id=@d2 create DHCP_Options cidr=30.0.0.0/24 \
3666 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3667 \"lease_time\"=\"3600\"" -- add Logical_Switch_Port ls2-lp2 dhcpv4_options @d2
3673 ovs-vsctl add-br br-phys
3674 ovn_attach n1 br-phys 192.168.0.1
3675 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3676 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3677 options:tx_pcap=hv1/vif1-tx.pcap \
3678 options:rxq_pcap=hv1/vif1-rx.pcap \
3681 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3682 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3683 options:tx_pcap=hv1/vif2-tx.pcap \
3684 options:rxq_pcap=hv1/vif2-rx.pcap \
3687 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3688 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3689 options:tx_pcap=hv1/vif3-tx.pcap \
3690 options:rxq_pcap=hv1/vif3-rx.pcap \
3693 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3694 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3695 options:tx_pcap=hv1/vif4-tx.pcap \
3696 options:rxq_pcap=hv1/vif4-rx.pcap \
3703 as hv1 ovs-vsctl show
3705 # This shell function sends a DHCP request packet
3706 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3708 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3709 shift; shift; shift; shift; shift;
3710 if test $use_ip != 0; then
3715 src_ip=`ip_to_hex 0 0 0 0`
3716 dst_ip=`ip_to_hex 255 255 255 255`
3718 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
3719 # udp header and dhcp header
3720 request=${request}0044004300fc0000
3721 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3722 # client hardware padding
3723 request=${request}00000000000000000000
3725 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3726 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3728 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3729 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3730 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3731 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3733 request=${request}63825363
3735 request=${request}3501${dhcp_type}ff
3737 if test $offer_ip != 0; then
3738 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
3739 # total IP length will be the IP length of the request packet
3740 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3741 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3742 udp_len=`expr $ip_len - 20`
3743 ip_len=$(printf "%x" $ip_len)
3744 udp_len=$(printf "%x" $udp_len)
3745 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3746 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3747 # udp header and dhcp header.
3748 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3749 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3751 reply=${reply}${offer_ip}
3752 # next server ip address, relay agent ip address, client mac address
3753 reply=${reply}0000000000000000${src_mac}
3754 # client hardware padding
3755 reply=${reply}00000000000000000000
3757 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3758 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3760 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3761 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3762 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3763 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3765 reply=${reply}63825363
3767 local dhcp_reply_type=02
3768 if test $dhcp_type = 03; then
3771 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3772 echo $reply >> $inport.expected
3775 echo $request >> $outport.expected
3778 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3784 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3785 options:rxq_pcap=dummy-rx.pcap
3786 rm -f ${pcap_file}*.pcap
3787 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3788 options:rxq_pcap=${pcap_file}-rx.pcap
3792 printf "%02x%02x%02x%02x" "$@"
3795 AT_CAPTURE_FILE([ofctl_monitor0.log])
3796 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3797 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3799 echo "---------NB dump-----"
3801 echo "---------------------"
3802 echo "---------SB dump-----"
3803 ovn-sbctl list datapath_binding
3804 echo "---------------------"
3805 ovn-sbctl list logical_flow
3806 echo "---------------------"
3808 echo "---------------------"
3809 ovn-sbctl dump-flows
3810 echo "---------------------"
3812 echo "------ hv1 dump ----------"
3813 as hv1 ovs-ofctl dump-flows br-int
3815 # Send DHCPDISCOVER.
3816 offer_ip=`ip_to_hex 10 0 0 4`
3817 server_ip=`ip_to_hex 10 0 0 1`
3818 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3819 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3821 # NXT_RESUMEs should be 1.
3822 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3824 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3825 cat 1.expected | cut -c -48 > expout
3826 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3827 # Skipping the IPv4 checksum.
3828 cat 1.expected | cut -c 53- > expout
3829 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3831 # ovs-ofctl also resumes the packets and this causes other ports to receive
3832 # the DHCP request packet. So reset the pcap files so that its easier to test.
3833 reset_pcap_file hv1-vif1 hv1/vif1
3834 reset_pcap_file hv1-vif2 hv1/vif2
3839 offer_ip=`ip_to_hex 10 0 0 6`
3840 server_ip=`ip_to_hex 10 0 0 1`
3841 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3842 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3844 # NXT_RESUMEs should be 2.
3845 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3847 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3848 cat 2.expected | cut -c -48 > expout
3849 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3850 # Skipping the IPv4 checksum.
3851 cat 2.expected | cut -c 53- > expout
3852 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3854 reset_pcap_file hv1-vif1 hv1/vif1
3855 reset_pcap_file hv1-vif2 hv1/vif2
3859 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3860 # but should be resumed without the reply.
3861 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3862 # one from ovn-controller and the other from "ovs-ofctl resume."
3864 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
3866 # NXT_RESUMEs should be 3.
3867 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3869 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
3870 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3872 reset_pcap_file hv1-vif1 hv1/vif1
3873 reset_pcap_file hv1-vif2 hv1/vif2
3877 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3878 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3880 test_dhcp 3 f00000000003 01 0 4 0
3882 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3884 test_dhcp 4 f00000000004 01 0 3 0
3886 # NXT_RESUMEs should be 3.
3887 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3889 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3890 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
3892 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
3893 offer_ip=`ip_to_hex 10 0 0 6`
3894 server_ip=`ip_to_hex 10 0 0 1`
3895 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3898 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
3900 # NXT_RESUMEs should be 4.
3901 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3903 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3904 cat 2.expected | cut -c -48 > expout
3905 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3906 # Skipping the IPv4 checksum.
3907 cat 2.expected | cut -c 53- > expout
3908 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3910 reset_pcap_file hv1-vif1 hv1/vif1
3911 reset_pcap_file hv1-vif2 hv1/vif2
3915 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
3916 offer_ip=`ip_to_hex 10 0 0 6`
3917 server_ip=`ip_to_hex 10 0 0 1`
3918 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3920 dst_ip=`ip_to_hex 255 255 255 255`
3921 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
3923 # NXT_RESUMEs should be 5.
3924 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3926 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3927 cat 2.expected | cut -c -48 > expout
3928 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3929 # Skipping the IPv4 checksum.
3930 cat 2.expected | cut -c 53- > expout
3931 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3933 reset_pcap_file hv1-vif1 hv1/vif1
3934 reset_pcap_file hv1-vif2 hv1/vif2
3938 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
3939 # The packet should not be received by ovn-controller.
3940 src_ip=`ip_to_hex 10 0 0 6`
3941 dst_ip=`ip_to_hex 10 0 0 4`
3942 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
3944 # NXT_RESUMEs should be 5.
3945 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3947 # vif1-tx.pcap should have received the DHCPv4 request packet
3948 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3951 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3952 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3953 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3956 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3959 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3962 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3965 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3966 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3970 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
3971 AT_SKIP_IF([test $HAVE_PYTHON = no])
3974 ovn-nbctl ls-add ls1
3975 ovn-nbctl lsp-add ls1 ls1-lp1 \
3976 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3978 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3980 ovn-nbctl lsp-add ls1 ls1-lp2 \
3981 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3983 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3985 ovn-nbctl lsp-add ls1 ls1-lp3 \
3986 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3988 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3990 ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
3991 options="\"server_id\"=\"00:00:00:10:00:01\"" \
3992 -- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
3993 -- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
3995 ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
3996 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
3997 -- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
3999 ovn-nbctl ls-add ls2
4000 ovn-nbctl lsp-add ls2 ls2-lp1 \
4001 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4002 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4003 ovn-nbctl lsp-add ls2 ls2-lp2 \
4004 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4005 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4011 ovs-vsctl add-br br-phys
4012 ovn_attach n1 br-phys 192.168.0.1
4013 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4014 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4015 options:tx_pcap=hv1/vif1-tx.pcap \
4016 options:rxq_pcap=hv1/vif1-rx.pcap \
4019 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4020 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4021 options:tx_pcap=hv1/vif2-tx.pcap \
4022 options:rxq_pcap=hv1/vif2-rx.pcap \
4025 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4026 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4027 options:tx_pcap=hv1/vif3-tx.pcap \
4028 options:rxq_pcap=hv1/vif3-rx.pcap \
4031 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4032 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4033 options:tx_pcap=hv1/vif4-tx.pcap \
4034 options:rxq_pcap=hv1/vif4-rx.pcap \
4037 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4038 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4039 options:tx_pcap=hv1/vif5-tx.pcap \
4040 options:rxq_pcap=hv1/vif5-rx.pcap \
4048 sed 's/\(00\)\{1,\}$//'
4051 # This shell function sends a DHCPv6 request packet
4052 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4053 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4054 # packet should be received twice (one from ovn-controller and the other
4055 # from the "ovs-ofctl monitor br-int resume"
4057 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4058 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4060 request=${request}ff020000000000000000000000010002
4061 # udp header and dhcpv6 header
4062 request=${request}02220223002affff${msg_code}010203
4064 request=${request}0001000a00030001${src_mac}
4065 # IA-NA (Identity Association for Non Temporary Address)
4066 request=${request}0003000c0102030400000e1000001518
4067 shift; shift; shift; shift; shift;
4068 if test $offer_ip != 0; then
4069 local server_mac=000000100001
4070 local server_lla=fe80000000000000020000fffe100001
4072 if test $msg_code = 01; then
4076 if test $offer_ip = 1; then
4079 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4080 # udp header and dhcpv6 header
4081 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4083 reply=${reply}0001000a00030001${src_mac}
4085 if test $offer_ip != 1; then
4086 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4089 reply=${reply}0002000a00030001${server_mac}
4090 echo $reply | trim_zeros >> $inport.expected
4093 echo $request | trim_zeros >> $outport.expected
4097 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4103 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4104 options:rxq_pcap=dummy-rx.pcap
4105 rm -f ${pcap_file}*.pcap
4106 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4107 options:rxq_pcap=${pcap_file}-rx.pcap
4110 AT_CAPTURE_FILE([ofctl_monitor0.log])
4111 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4112 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4114 echo "---------NB dump-----"
4116 echo "---------------------"
4117 echo "---------SB dump-----"
4118 ovn-sbctl list datapath_binding
4119 echo "---------------------"
4120 ovn-sbctl list logical_flow
4121 echo "---------------------"
4123 echo "---------------------"
4124 ovn-sbctl dump-flows
4125 echo "---------------------"
4127 echo "------ hv1 dump ----------"
4128 as hv1 ovs-ofctl dump-flows br-int
4130 src_mac=f00000000001
4131 src_lla=fe80000000000000f20000fffe000001
4132 offer_ip=ae700000000000000000000000000004
4133 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4135 # NXT_RESUMEs should be 1.
4136 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4138 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4139 # cat 1.expected | trim_zeros > expout
4140 cat 1.expected | cut -c -120 > expout
4141 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4142 # Skipping the UDP checksum
4143 cat 1.expected | cut -c 125- > expout
4144 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4148 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4149 # without any modifications and the packet should be received by ls1-lp1.
4150 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4151 # resume and the other from ovs-ofctl monitor resume.
4153 reset_pcap_file hv1-vif1 hv1/vif1
4154 reset_pcap_file hv1-vif2 hv1/vif2
4156 src_mac=f00000000002
4157 src_lla=fe80000000000000f20000fffe000002
4158 offer_ip=ae700000000000000000000000000005
4159 # Set invalid msg_type
4161 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4163 # NXT_RESUMEs should be 2.
4164 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4166 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4168 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4169 AT_CHECK([cat 2.packets], [0], [])
4171 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4172 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4173 cat 1.expected > expout
4174 AT_CHECK([cat 1.packets], [0], [expout])
4176 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4177 # There should be no DHCPv6 reply from ovn-controller and the request packet
4178 # should be received by ls2-lp2.
4180 src_mac=f00000000003
4181 src_lla=fe80000000000000f20000fffe000003
4182 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4184 # NXT_RESUMEs should be 2 only.
4185 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4187 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4188 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4189 AT_CHECK([cat 3.packets], [0], [])
4191 # vif4-tx.pcap should have received the DHCPv6 request packet
4192 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4193 cat 4.expected > expout
4194 AT_CHECK([cat 4.packets], [0], [expout])
4196 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4197 # The DHCPv6 reply should doesn't contian offer_ip.
4198 src_mac=f00000000022
4199 src_lla=fe80000000000000f20000fffe000022
4200 reset_pcap_file hv1-vif5 hv1/vif5
4201 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4203 # NXT_RESUMEs should be 3.
4204 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4206 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4207 # Skipping the UDP checksum
4208 cat 5.expected | cut -c 1-120,125- > expout
4209 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4212 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4213 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4214 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4217 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4220 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4223 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4226 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4227 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4231 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4232 AT_SKIP_IF([test $HAVE_PYTHON = no])
4236 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4237 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4238 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4239 # R2 is a gateway router.
4243 # Create two hypervisor and create OVS ports corresponding to logical ports.
4248 ovs-vsctl add-br br-phys
4249 ovn_attach n1 br-phys 192.168.0.1
4250 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4251 set interface hv1-vif1 external-ids:iface-id=foo1 \
4252 options:tx_pcap=hv1/vif1-tx.pcap \
4253 options:rxq_pcap=hv1/vif1-rx.pcap \
4259 ovs-vsctl add-br br-phys
4260 ovn_attach n1 br-phys 192.168.0.2
4261 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4262 set interface hv2-vif1 external-ids:iface-id=alice1 \
4263 options:tx_pcap=hv2/vif1-tx.pcap \
4264 options:rxq_pcap=hv2/vif1-rx.pcap \
4267 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4268 # packets for ARP resolution (native tunneling doesn't queue packets
4269 # for ARP resolution).
4272 ovn-nbctl create Logical_Router name=R1
4273 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4275 ovn-nbctl ls-add foo
4276 ovn-nbctl ls-add alice
4277 ovn-nbctl ls-add join
4280 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4281 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4282 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4284 # Connect alice to R2
4285 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4286 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4287 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4289 # Connect R1 to join
4290 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4291 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4292 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4294 # Connect R2 to join
4295 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4296 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4297 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4300 #install static routes
4301 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4302 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4303 R1 static_routes @lrt
4305 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4306 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4307 R2 static_routes @lrt
4309 # Create logical port foo1 in foo
4310 ovn-nbctl lsp-add foo foo1 \
4311 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4313 # Create logical port alice1 in alice
4314 ovn-nbctl lsp-add alice alice1 \
4315 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4318 # Allow some time for ovn-northd and ovn-controller to catch up.
4319 # XXX This should be more systematic.
4323 printf "%02x%02x%02x%02x" "$@"
4326 # Send ip packets between foo1 and alice1
4327 src_mac="f00000010203"
4328 dst_mac="000001010203"
4329 src_ip=`ip_to_hex 192 168 1 2`
4330 dst_ip=`ip_to_hex 172 16 1 2`
4331 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4333 echo "---------NB dump-----"
4335 echo "---------------------"
4336 ovn-nbctl list logical_router
4337 echo "---------------------"
4338 ovn-nbctl list logical_router_port
4339 echo "---------------------"
4341 echo "---------SB dump-----"
4342 ovn-sbctl list datapath_binding
4343 echo "---------------------"
4344 ovn-sbctl list port_binding
4345 echo "---------------------"
4346 ovn-sbctl dump-flows
4347 echo "---------------------"
4348 ovn-sbctl list chassis
4349 ovn-sbctl list encap
4350 echo "---------------------"
4352 # Packet to Expect at alice1
4353 src_mac="000002010203"
4354 dst_mac="f00000010204"
4355 src_ip=`ip_to_hex 192 168 1 2`
4356 dst_ip=`ip_to_hex 172 16 1 2`
4357 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4360 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4361 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4363 echo "------ hv1 dump after packet 1 ----------"
4364 as hv1 ovs-ofctl show br-int
4365 as hv1 ovs-ofctl dump-flows br-int
4366 echo "------ hv2 dump after packet 1 ----------"
4367 as hv2 ovs-ofctl show br-int
4368 as hv2 ovs-ofctl dump-flows br-int
4369 echo "----------------------------"
4371 echo $expected > expected
4372 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4374 # Delete the router and re-create it. Things should work as before.
4376 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4377 # Connect alice to R2
4378 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4379 # Connect R2 to join
4380 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4382 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4383 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4384 R2 static_routes @lrt
4386 # Wait for ovn-controller to catch up.
4389 # Send the packet again.
4390 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4392 echo "------ hv1 dump after packet 2 ----------"
4393 as hv1 ovs-ofctl show br-int
4394 as hv1 ovs-ofctl dump-flows br-int
4395 echo "------ hv2 dump after packet 2 ----------"
4396 as hv2 ovs-ofctl show br-int
4397 as hv2 ovs-ofctl dump-flows br-int
4398 echo "----------------------------"
4400 echo $expected >> expected
4401 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4403 OVN_CLEANUP([hv1],[hv2])
4407 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4408 AT_KEYWORDS([router-icmp-reply])
4409 AT_SKIP_IF([test $HAVE_PYTHON = no])
4413 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4414 # and has switch ls2 (172.16.1.0/24) connected to it.
4418 ovn-nbctl ls-add ls1
4419 ovn-nbctl ls-add ls2
4422 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4423 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4424 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4427 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4428 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4429 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4431 # Create logical port ls1-lp1 in ls1
4432 ovn-nbctl lsp-add ls1 ls1-lp1 \
4433 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4435 # Create logical port ls2-lp1 in ls2
4436 ovn-nbctl lsp-add ls2 ls2-lp1 \
4437 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4439 # Create one hypervisor and create OVS ports corresponding to logical ports.
4444 ovs-vsctl add-br br-phys
4445 ovn_attach n1 br-phys 192.168.0.1
4446 ovs-vsctl -- add-port br-int vif1 -- \
4447 set interface vif1 external-ids:iface-id=ls1-lp1 \
4448 options:tx_pcap=hv1/vif1-tx.pcap \
4449 options:rxq_pcap=hv1/vif1-rx.pcap \
4452 ovs-vsctl -- add-port br-int vif2 -- \
4453 set interface vif2 external-ids:iface-id=ls2-lp1 \
4454 options:tx_pcap=hv1/vif2-tx.pcap \
4455 options:rxq_pcap=hv1/vif2-rx.pcap \
4459 # Allow some time for ovn-northd and ovn-controller to catch up.
4460 # XXX This should be more systematic.
4465 printf "%02x%02x%02x%02x" "$@"
4470 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4472 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4473 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4474 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4475 # provided, then it should be the ip and icmp checksums of the packet
4476 # responded; otherwise, no reply is expected.
4477 # In the absence of an ip checksum calculation helpers, this relies
4478 # on the caller to provide the checksums for the ip and icmp headers.
4479 # XXX This should be more systematic.
4481 # INPORT is an lport number, e.g. 11 for vif11.
4482 # ETH_SRC and ETH_DST are each 12 hex digits.
4483 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4484 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4485 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4486 test_ipv4_icmp_request() {
4487 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4488 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4489 shift; shift; shift; shift; shift; shift; shift
4492 # Use ttl to exercise section 4.2.2.9 of RFC1812
4496 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4497 local icmp_type_code_request=0800
4498 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4499 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4501 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4502 if test X$exp_icmp_chksum != X; then
4503 # Expect to receive the reply, if any. In same port where packet was sent.
4504 # Note: src and dst fields are expected to be reversed.
4505 local icmp_type_code_response=0000
4506 local reply_icmp_ttl=fe
4507 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4508 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4509 echo $reply >> vif$inport.expected
4513 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4514 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4515 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4516 l1_ip=$(ip_to_hex 192 168 1 2)
4517 l2_ip=$(ip_to_hex 172 16 1 2)
4519 # Ping router ip address that is on same subnet as the logical port
4520 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4521 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4523 # Ping router ip address that is on the other side of the logical ports
4524 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4525 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4527 echo "---------NB dump-----"
4529 echo "---------------------"
4530 ovn-nbctl list logical_router
4531 echo "---------------------"
4532 ovn-nbctl list logical_router_port
4533 echo "---------------------"
4535 echo "---------SB dump-----"
4536 ovn-sbctl list datapath_binding
4537 echo "---------------------"
4538 ovn-sbctl list logical_flow
4539 echo "---------------------"
4541 echo "------ hv1 dump ----------"
4542 as hv1 ovs-ofctl dump-flows br-int
4544 # Now check the packets actually received against the ones expected.
4545 for inport in 1 2; do
4546 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4553 # 1 hypervisor, 1 port
4554 # make sure that the port state is properly set to up and back down
4555 # when created and deleted.
4556 AT_SETUP([ovn -- port state up and down])
4559 ovn-nbctl ls-add ls1
4560 ovn-nbctl lsp-add ls1 lp1
4561 ovn-nbctl lsp-set-addresses lp1 unknown
4565 as hv1 ovs-vsctl add-br br-phys
4566 as hv1 ovn_attach n1 br-phys 192.168.0.1
4568 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4569 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4571 as hv1 ovs-vsctl del-port br-int vif1
4572 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4578 # 1 hypervisor, 1 port
4579 # make sure that the OF rules created to support a datapath are added/cleared
4580 # when logical switch is created and removed.
4581 AT_SETUP([ovn -- datapath rules added/removed])
4582 AT_KEYWORDS([cleanup])
4587 as hv1 ovs-vsctl add-br br-phys
4588 as hv1 ovn_attach n1 br-phys 192.168.0.1
4590 # This shell function checks if OF rules in br-int have clauses
4591 # related to OVN datapaths. The caller determines if it should find
4592 # a match in the output, or not.
4594 # EXPECT_DATAPATH param determines whether flows that refer to
4595 # datapath to should be present or not. 0 means
4596 # they should not be.
4597 # STAGE_INFO param is a simple string to help identify the stage
4598 # in the test when this function was invoked.
4599 test_datapath_in_of_rules() {
4600 local expect_datapath=$1 stage_info=$2
4601 echo "------ ovn-nbctl show ${stage_info} ------"
4603 echo "------ ovn-sbctl show ${stage_info} ------"
4605 echo "------ OF rules ${stage_info} ------"
4606 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4607 # if there is a datapath mentioned in the output, check for the
4608 # magic keyword that represents one, based on the exit status of
4610 if test $expect_datapath != 0; then
4611 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4613 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4617 test_datapath_in_of_rules 0 "before ls+port create"
4619 ovn-nbctl ls-add ls1
4620 ovn-nbctl lsp-add ls1 lp1
4621 ovn-nbctl lsp-set-addresses lp1 unknown
4623 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4624 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4626 test_datapath_in_of_rules 1 "after port is bound"
4628 as hv1 ovs-vsctl del-port br-int vif1
4629 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4631 ovn-nbctl lsp-set-addresses lp1
4632 ovn-nbctl lsp-del lp1
4633 ovn-nbctl ls-del ls1
4635 # wait for earlier changes to take effect
4636 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4638 # ensure OF rules are no longer present. There used to be a bug here.
4639 test_datapath_in_of_rules 0 "after lport+ls removal"
4645 AT_SETUP([ovn -- nd_na ])
4646 AT_SKIP_IF([test $HAVE_PYTHON = no])
4649 #TODO: since patch port for IPv6 logical router port is not ready not,
4650 # so we are not going to test vifs on different lswitches cases. Try
4651 # to update for that once relevant stuff implemented.
4653 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4654 # with. NS packet we test, from one VIF for another VIF, will be replied
4655 # by local ovn-controller, but not by target VIF.
4657 # Create hypervisors and logical switch lsw0.
4658 ovn-nbctl ls-add lsw0
4662 ovs-vsctl add-br br-phys
4663 ovn_attach n1 br-phys 192.168.0.2
4665 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4666 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
4667 ovn-nbctl lsp-add lsw0 lp1
4668 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4669 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"
4671 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4672 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
4673 ovn-nbctl lsp-add lsw0 lp2
4674 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4675 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"
4677 # Add ACL rule for ICMPv6 on lsw0
4678 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4679 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4680 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4682 # Allow some time for ovn-northd and ovn-controller to catch up.
4683 # XXX This should be more systematic.
4686 # Given the name of a logical port, prints the name of the hypervisor
4687 # on which it is located.
4695 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4696 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4697 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4698 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4699 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4701 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4702 echo $na_packet >> 1.expected
4704 echo "------ hv1 dump ------"
4705 as hv1 ovs-vsctl show
4706 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4707 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4710 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4717 AT_SETUP([ovn -- address sets modification/removal smoke test])
4724 ovs-vsctl add-br br-phys
4725 ovn_attach n1 br-phys 192.168.0.1
4727 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4728 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4729 ovn-nbctl destroy Address_Set $row
4733 # A bug previously existed in the address set support code
4734 # that caused ovn-controller to crash after an address set
4735 # was updated and then removed. This test case ensures
4736 # that ovn-controller is at least still running after
4737 # creating, updating, and deleting an address set.
4738 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4744 AT_SETUP([ovn -- ipam])
4745 AT_SKIP_IF([test $HAVE_PYTHON = no])
4748 # Add a port to a switch that does not have a subnet set, then set the
4749 # subnet which should result in an address being allocated for the port.
4750 ovn-nbctl ls-add sw0
4751 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4752 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4753 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4754 ["0a:00:00:00:00:01 192.168.1.2"
4757 # Add 9 more ports to sw0, addresses should all be unique.
4758 for n in `seq 1 9`; do
4759 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4761 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4762 ["0a:00:00:00:00:02 192.168.1.3"
4764 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4765 ["0a:00:00:00:00:03 192.168.1.4"
4767 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4768 ["0a:00:00:00:00:04 192.168.1.5"
4770 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4771 ["0a:00:00:00:00:05 192.168.1.6"
4773 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4774 ["0a:00:00:00:00:06 192.168.1.7"
4776 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4777 ["0a:00:00:00:00:07 192.168.1.8"
4779 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4780 ["0a:00:00:00:00:08 192.168.1.9"
4782 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4783 ["0a:00:00:00:00:09 192.168.1.10"
4785 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4786 ["0a:00:00:00:00:0a 192.168.1.11"
4789 # Trying similar tests with a second switch. MAC addresses should be unique
4790 # across both switches but IP's only need to be unique within the same switch.
4791 ovn-nbctl ls-add sw1
4792 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4793 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4794 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4795 ["0a:00:00:00:00:0b 192.168.1.2"
4798 for n in `seq 11 19`; do
4799 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4801 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4802 ["0a:00:00:00:00:0c 192.168.1.3"
4804 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4805 ["0a:00:00:00:00:0d 192.168.1.4"
4807 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4808 ["0a:00:00:00:00:0e 192.168.1.5"
4810 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4811 ["0a:00:00:00:00:0f 192.168.1.6"
4813 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4814 ["0a:00:00:00:00:10 192.168.1.7"
4816 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4817 ["0a:00:00:00:00:11 192.168.1.8"
4819 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4820 ["0a:00:00:00:00:12 192.168.1.9"
4822 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4823 ["0a:00:00:00:00:13 192.168.1.10"
4825 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4826 ["0a:00:00:00:00:14 192.168.1.11"
4829 # Change a port's address to test for multiple ip's for a single address entry
4830 # and addresses set by the user.
4831 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4832 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4833 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4834 ["0a:00:00:00:00:16 192.168.1.13"
4837 # Test for logical router port address management.
4838 ovn-nbctl create Logical_Router name=R1
4839 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4840 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4841 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4842 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4843 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4844 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4845 ["0a:00:00:00:00:18 192.168.1.15"
4848 # Test for address reuse after logical port is deleted.
4849 ovn-nbctl lsp-del p0
4850 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4851 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4852 ["0a:00:00:00:00:19 192.168.1.2"
4855 # Test for multiple addresses to one logical port.
4856 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4857 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
4858 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
4859 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4860 ["0a:00:00:00:00:1c 192.168.1.16"
4863 # Test for exhausting subnet address space.
4864 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
4865 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
4866 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4867 ["0a:00:00:00:00:1d 172.16.1.2"
4870 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
4871 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4875 # Test that address management does not add duplicate MAC for lsp/lrp peers.
4876 ovn-nbctl create Logical_Router name=R2
4877 ovn-nbctl ls-add sw3
4878 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4880 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4881 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4882 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4883 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
4884 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
4885 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4886 ["0a:00:00:00:00:20 192.168.1.17"
4889 # Test static MAC address with dynamically allocated IP
4890 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
4891 "fe:dc:ba:98:76:54 dynamic"
4892 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4893 ["fe:dc:ba:98:76:54 192.168.1.18"
4897 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4900 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4903 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4907 AT_SETUP([ovn -- ipam connectivity])
4908 AT_SKIP_IF([test $HAVE_PYTHON = no])
4913 # Test for a ping using dynamically allocated addresses.
4914 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
4915 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
4918 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4919 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4920 options:router-port=foo \
4921 -- lsp-set-addresses rp-foo router
4923 # Connect alice to R1
4924 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
4925 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
4926 options:router-port=alice addresses=\"00:00:00:01:02:04\"
4928 # Create logical port foo1 in foo
4929 ovn-nbctl --wait=sb lsp-add foo foo1 \
4930 -- lsp-set-addresses foo1 "dynamic"
4931 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])
4933 # Create logical port alice1 in alice
4934 ovn-nbctl --wait=sb lsp-add alice alice1 \
4935 -- lsp-set-addresses alice1 "dynamic"
4936 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
4938 # Create logical port foo2 in foo
4939 ovn-nbctl --wait=sb lsp-add foo foo2 \
4940 -- lsp-set-addresses foo2 "dynamic"
4941 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
4943 # Create a hypervisor and create OVS ports corresponding to logical ports.
4948 ovs-vsctl add-br br-phys
4949 ovn_attach n1 br-phys 192.168.0.1
4950 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4951 set interface hv1-vif1 external-ids:iface-id=foo1 \
4952 options:tx_pcap=hv1/vif1-tx.pcap \
4953 options:rxq_pcap=hv1/vif1-rx.pcap \
4956 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4957 set interface hv1-vif2 external-ids:iface-id=foo2 \
4958 options:tx_pcap=hv1/vif2-tx.pcap \
4959 options:rxq_pcap=hv1/vif2-rx.pcap \
4962 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4963 set interface hv1-vif3 external-ids:iface-id=alice1 \
4964 options:tx_pcap=hv1/vif3-tx.pcap \
4965 options:rxq_pcap=hv1/vif3-rx.pcap \
4968 # Allow some time for ovn-northd and ovn-controller to catch up.
4969 # XXX This should be more systematic.
4973 printf "%02x%02x%02x%02x" "$@"
4976 # Send ip packets between foo1 and foo2
4977 src_mac="0a0000000001"
4978 dst_mac="0a0000000003"
4979 src_ip=`ip_to_hex 192 168 1 2`
4980 dst_ip=`ip_to_hex 192 168 1 3`
4981 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4982 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4984 # Send ip packets between foo1 and alice1
4985 src_mac="0a0000000001"
4986 dst_mac="000000010203"
4987 src_ip=`ip_to_hex 192 168 1 2`
4988 dst_ip=`ip_to_hex 192 168 2 2`
4989 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4990 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4992 echo "---------NB dump-----"
4994 echo "---------------------"
4995 ovn-nbctl list logical_router
4996 echo "---------------------"
4997 ovn-nbctl list logical_router_port
4998 echo "---------------------"
5000 echo "---------SB dump-----"
5001 ovn-sbctl list datapath_binding
5002 echo "---------------------"
5003 ovn-sbctl list port_binding
5004 echo "---------------------"
5006 echo "------ hv1 dump ----------"
5007 as hv1 ovs-ofctl dump-flows br-int
5009 # Packet to Expect at foo2
5010 src_mac="0a0000000001"
5011 dst_mac="0a0000000003"
5012 src_ip=`ip_to_hex 192 168 1 2`
5013 dst_ip=`ip_to_hex 192 168 1 3`
5014 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5016 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5017 echo $expected > expout
5018 AT_CHECK([cat received1.packets], [0], [expout])
5020 # Packet to Expect at alice1
5021 src_mac="000000010204"
5022 dst_mac="0a0000000002"
5023 src_ip=`ip_to_hex 192 168 1 2`
5024 dst_ip=`ip_to_hex 192 168 2 2`
5025 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5027 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5028 echo $expected > expout
5029 AT_CHECK([cat received2.packets], [0], [expout])
5035 AT_SETUP([ovn -- ovs-vswitchd restart])
5036 AT_KEYWORDS([vswitchd])
5037 AT_SKIP_IF([test $HAVE_PYTHON = no])
5040 ovn-nbctl ls-add ls1
5042 ovn-nbctl lsp-add ls1 ls1-lp1 \
5043 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5045 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5051 ovs-vsctl add-br br-phys
5052 ovn_attach n1 br-phys 192.168.0.1
5053 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5054 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5055 options:tx_pcap=hv1/vif1-tx.pcap \
5056 options:rxq_pcap=hv1/vif1-rx.pcap \
5062 as hv1 ovs-vsctl show
5064 echo "---------------------"
5065 ovn-sbctl dump-flows
5066 echo "---------------------"
5068 echo "------ hv1 dump ----------"
5069 as hv1 ovs-ofctl dump-flows br-int
5070 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5072 echo "Total flows before vswitchd restart = " $total_flows
5074 # Code taken from ovs-save utility
5076 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5077 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5078 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5079 echo "EOF" >> restore_flows.sh
5082 restart_vswitchd () {
5085 if test $restore_flows = true; then
5090 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5092 if test $restore_flows = true; then
5094 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5098 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5099 ovs-ofctl dump-flows br-int
5101 if test $restore_flows = true; then
5102 sh ./restore_flows.sh
5103 echo "Flows after restore"
5105 ovs-ofctl dump-flows br-int
5106 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5107 flow-restore-wait="true"
5111 # Save the flows, restart vswitchd and restore the flows
5112 restart_vswitchd true
5114 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5115 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5116 test "${total_flows}" = "${total_flows_after_restart}"
5119 # Restart vswitchd without restoring
5120 restart_vswitchd false
5122 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5123 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5124 test "${total_flows}" = "${total_flows_after_restart}"
5130 AT_SETUP([ovn -- send arp for nexthop])
5131 AT_SKIP_IF([test $HAVE_PYTHON = no])
5134 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5136 # Create logical switches
5137 ovn-nbctl ls-add ls1
5138 ovn-nbctl ls-add ls2
5141 ovn-nbctl create Logical_Router name=lr0
5143 # Add router ls1p1 port to gateway router
5144 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5145 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5146 type=router options:router-port=lrp-ls1lp1 \
5147 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5149 # Add router ls2p2 port to gateway router
5150 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5151 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5152 type=router options:router-port=lrp-ls2lp1 \
5153 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5155 # Set default gateway (nexthop) to 192.168.1.254
5156 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5158 # Create logical port ls1lp2 in ls1
5159 ovn-nbctl lsp-add ls1 ls1lp2 \
5160 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5162 # Create logical port ls2lp2 in ls2
5163 ovn-nbctl lsp-add ls2 ls2lp2 \
5164 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5169 ovs-vsctl add-br br-phys
5170 ovn_attach n1 br-phys 192.168.0.1
5171 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5172 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5173 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5174 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5176 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5177 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5178 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5179 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5182 # Allow some time for ovn-northd and ovn-controller to catch up.
5183 # XXX This should be more systematic.
5186 echo "---------NB dump-----"
5188 echo "---------------------"
5189 ovn-nbctl list logical_router
5190 echo "---------------------"
5191 ovn-nbctl list logical_router_port
5192 echo "---------------------"
5194 echo "---------SB dump-----"
5195 ovn-sbctl list datapath_binding
5196 echo "---------------------"
5197 ovn-sbctl list port_binding
5198 echo "---------------------"
5199 ovn-sbctl dump-flows
5200 echo "---------------------"
5201 ovn-sbctl list chassis
5202 ovn-sbctl list encap
5203 echo "---------------------"
5205 echo "------Flows dump-----"
5207 ovs-ofctl dump-flows
5208 echo "---------------------"
5211 printf "%02x%02x%02x%02x" "$@"
5214 src_mac="f00000000003"
5215 dst_mac="f00000000001"
5216 src_ip=`ip_to_hex 192 168 0 2`
5217 dst_ip=`ip_to_hex 8 8 8 8`
5218 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5220 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5221 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5224 sed 's/\(00\)\{1,\}$//'
5227 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5230 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5231 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5232 echo $expected > expout
5233 AT_CHECK([cat packets], [0], [expout])
5240 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5241 AT_SKIP_IF([test $HAVE_PYTHON = no])
5243 # Create logical switch
5244 ovn-nbctl ls-add ls0
5245 # Create gateway router
5246 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5247 # Add router port to gateway router
5248 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5249 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5250 type=router options:router-port=lrp0-rp addresses='"f0:00:00:00:00:01"'
5251 # Add nat-address option
5252 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5261 ovn_attach n1 br-phys 192.168.0.1
5263 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5264 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])
5266 # Create a localnet port.
5267 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5268 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5269 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5270 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5273 # Wait for packet to be received.
5274 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5276 sed 's/\(00\)\{1,\}$//'
5278 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5279 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5280 echo $expected > expout
5281 AT_CHECK([sort packets], [0], [expout])
5288 AT_SETUP([ovn -- delete mac bindings])
5293 ovs-vsctl -- add-br br-phys
5294 ovn_attach n1 br-phys 192.168.0.1
5295 # Create logical switch ls0
5296 ovn-nbctl ls-add ls0
5297 # Create ports lp0, lp1 in ls0
5298 ovn-nbctl lsp-add ls0 lp0
5299 ovn-nbctl lsp-add ls0 lp1
5300 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5301 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5302 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5303 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5304 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5305 ovn-sbctl find MAC_Binding
5306 # Delete port lp0 and check that its MAC_Binding is deleted.
5307 ovn-nbctl lsp-del lp0
5308 ovn-sbctl find MAC_Binding
5309 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5310 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5311 ovn-nbctl ls-del ls0
5312 ovn-sbctl find MAC_Binding
5313 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5319 AT_SETUP([ovn -- conntrack zone allocation])
5320 AT_SKIP_IF([test $HAVE_PYTHON = no])
5324 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5325 # connected to a router R1.
5326 # foo has foo1 to act as a client.
5327 # bar has bar1, bar2, bar3 to act as servers.
5333 ovs-vsctl add-br br-phys
5334 ovn_attach n1 br-phys 192.168.0.1
5335 for i in foo1 bar1 bar2 bar3; do
5336 ovs-vsctl -- add-port br-int $i -- \
5337 set interface $i external-ids:iface-id=$i \
5338 options:tx_pcap=hv1/$i-tx.pcap \
5339 options:rxq_pcap=hv1/$i-rx.pcap
5342 ovn-nbctl create Logical_Router name=R1
5343 ovn-nbctl ls-add foo
5344 ovn-nbctl ls-add bar
5347 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5348 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5349 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5352 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5353 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5354 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5356 # Create logical port foo1 in foo
5357 ovn-nbctl lsp-add foo foo1 \
5358 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5360 # Create logical port bar1, bar2 and bar3 in bar
5361 for i in `seq 1 3`; do
5363 ovn-nbctl lsp-add bar bar$i \
5364 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5367 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5373 AT_SETUP([ovn -- tag allocation])
5376 AT_CHECK([ovn-nbctl ls-add ls0])
5377 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5378 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5379 AT_CHECK([ovn-nbctl ls-add ls1])
5381 dnl When a tag is provided, no allocation is done
5382 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5383 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5385 dnl The same 'tag' gets created in southbound database.
5386 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5387 logical_port="c0"], [0], [3
5390 dnl Allocate tags and see it getting created in both NB and SB
5391 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5392 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5394 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5395 logical_port="c1"], [0], [1
5398 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5399 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5401 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5402 logical_port="c2"], [0], [2
5404 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5405 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5407 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5408 logical_port="c3"], [0], [4
5411 dnl A different parent.
5412 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5413 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5415 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5416 logical_port="c4"], [0], [1
5419 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5420 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5422 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5423 logical_port="c5"], [0], [2
5426 dnl Delete a logical port and create a new one.
5427 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5428 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5429 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5431 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5432 logical_port="c6"], [0], [1
5435 dnl Restart northd to see that the same allocation remains.
5437 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5438 start_daemon ovn-northd \
5439 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5440 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5442 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5443 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5444 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5446 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5448 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5450 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5452 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5454 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5457 dnl Create a switch port with a tag that has already been allocated.
5458 dnl It should go through fine with a duplicate tag.
5459 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5460 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5462 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5463 logical_port="c7"], [0], [2
5465 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5468 AT_CHECK([ovn-nbctl ls-add ls2])
5469 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5470 dnl gets copied to 'tag'
5471 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5472 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5474 dnl The same 'tag' gets created in southbound database.
5475 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5476 logical_port="local0"], [0], [25
5478 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5479 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5480 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5481 dnl change the tag_request.
5482 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5483 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5488 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5490 ovn-nbctl ls-add lsw0
5495 ovs-vsctl add-br br-phys
5496 ovn_attach n1 br-phys 192.168.0.$i
5497 ovs-vsctl add-br br-eth0
5498 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5501 # Create a localnet port.
5502 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5503 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5504 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5505 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5509 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5510 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5511 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5512 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5513 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5514 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5515 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5516 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5517 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5519 # Bind the localvif1 to hv1.
5521 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5523 # On hv1, check that there are no flows outputting bcast to tunnel
5524 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5526 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5528 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5530 # Now bind vif2 on hv2.
5531 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5533 # At this point, the broadcast flow on vif2 should be deleted.
5534 # because, there is now a localnet vif bound (table=32 programming logic)
5535 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5537 # Verify that the local net patch port exists on hv2.
5538 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5540 # Now bind vif3 on hv2.
5541 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5543 # Verify that the local net patch port still exists on hv2
5544 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5547 AT_CHECK([ovn-nbctl lsp-del localvif2])
5549 # Verify that the local net patch port still exists on hv2,
5550 # because, localvif3 is still bound.
5551 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5553 OVN_CLEANUP([hv1],[hv2])
5557 AT_SETUP([ovn -- DSCP marking check])
5561 ovn-nbctl ls-add lsw0
5562 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5563 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5564 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5565 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5566 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5567 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5568 ovn-nbctl --wait=sb sync
5572 ovs-vsctl add-br br-phys
5573 ovn_attach n1 br-phys 192.168.0.1
5574 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
5575 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
5577 AT_CAPTURE_FILE([trace])
5579 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5582 # Extracts nw_tos from the final flow from ofproto/trace output and prints
5583 # it on stdout. Prints "none" if no nw_tos was included.
5584 get_final_nw_tos() {
5585 if flow=$(grep '^Final flow:' stdout); then :; else
5586 # The output didn't have a final flow.
5590 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5599 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5601 # First check with ovn-trace for logical flows.
5602 echo "checking for tos $1"
5603 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
5604 echo 'output("lp2");') > expout
5605 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])
5607 # Then re-check with ofproto/trace for a physical packet.
5608 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])
5609 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
5614 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");
5616 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])
5617 AT_CHECK([get_final_nw_tos], [0], [none
5620 # check at L3 without dscp marking
5623 # Mark DSCP with a valid value
5624 qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
5627 # Update the DSCP marking
5628 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
5631 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
5634 # Disable DSCP marking
5635 ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
5641 AT_SETUP([ovn -- read-only sb db:ptcp access])
5642 AT_SKIP_IF([test $HAVE_PYTHON = no])
5645 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5647 # Add read-only remote to sb ovsdb-server
5649 [ovsdb-tool transact ovn-sb.db \
5650 ['["OVN_Southbound",
5652 "table": "SB_Global",
5654 "connections": ["set", [["named-uuid", "xyz"]]]}},
5656 "table": "Connection",
5658 "row": {"target": "ptcp:0:127.0.0.1",
5659 "read_only": true}}]']], [0], [ignore], [ignore])
5661 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
5663 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5665 # read-only accesses should succeed
5666 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
5667 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
5669 # write access should fail
5670 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5671 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5674 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5677 AT_SETUP([ovn -- read-only sb db:pssl access])
5678 AT_SKIP_IF([test $HAVE_PYTHON = no])
5679 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5680 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5681 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5685 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5687 # Add read-only remote to sb ovsdb-server
5689 [ovsdb-tool transact ovn-sb.db \
5690 ['["OVN_Southbound",
5692 "table": "SB_Global",
5694 "connections": ["set", [["named-uuid", "xyz"]]]}},
5696 "table": "Connection",
5698 "row": {"target": "pssl:0:127.0.0.1",
5699 "read_only": true}}]']], [0], [ignore], [ignore])
5701 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
5702 --remote=db:OVN_Southbound,SB_Global,connections \
5703 --private-key="$PKIDIR/testpki-privkey2.pem" \
5704 --certificate="$PKIDIR/testpki-cert2.pem" \
5705 --ca-cert="$PKIDIR/testpki-cacert.pem" \
5708 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5710 # read-only accesses should succeed
5711 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5712 --private-key=$PKIDIR/testpki-privkey.pem \
5713 --certificate=$PKIDIR/testpki-cert.pem \
5714 --ca-cert=$PKIDIR/testpki-cacert.pem \
5715 list SB_Global], [0], [stdout], [ignore])
5716 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5717 --private-key=$PKIDIR/testpki-privkey.pem \
5718 --certificate=$PKIDIR/testpki-cert.pem \
5719 --ca-cert=$PKIDIR/testpki-cacert.pem \
5720 list Connection], [0], [stdout], [ignore])
5722 # write access should fail
5723 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5724 --private-key=$PKIDIR/testpki-privkey.pem \
5725 --certificate=$PKIDIR/testpki-cert.pem \
5726 --ca-cert=$PKIDIR/testpki-cacert.pem \
5727 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5728 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5731 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5734 AT_SETUP([ovn -- nb connection/ssl commands])
5735 AT_SKIP_IF([test $HAVE_PYTHON = no])
5736 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5737 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5738 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5742 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
5744 # Start nb db server using db connection/ssl entries (unpopulated initially)
5745 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
5746 --remote=db:OVN_Northbound,NB_Global,connections \
5747 --private-key=db:OVN_Northbound,SSL,private_key \
5748 --certificate=db:OVN_Northbound,SSL,certificate \
5749 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
5752 # Populate SSL configuration entries in nb db
5754 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
5755 $PKIDIR/testpki-cert.pem \
5756 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
5758 # Populate a passive SSL connection in nb db
5759 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
5761 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5763 # Verify SSL connetivity to nb db server
5764 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5765 --private-key=$PKIDIR/testpki-privkey.pem \
5766 --certificate=$PKIDIR/testpki-cert.pem \
5767 --ca-cert=$PKIDIR/testpki-cacert.pem \
5769 [0], [stdout], [ignore])
5770 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5771 --private-key=$PKIDIR/testpki-privkey.pem \
5772 --certificate=$PKIDIR/testpki-cert.pem \
5773 --ca-cert=$PKIDIR/testpki-cacert.pem \
5775 [0], [stdout], [ignore])
5776 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5777 --private-key=$PKIDIR/testpki-privkey.pem \
5778 --certificate=$PKIDIR/testpki-cert.pem \
5779 --ca-cert=$PKIDIR/testpki-cacert.pem \
5781 [0], [stdout], [ignore])
5783 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5786 AT_SETUP([ovn -- sb connection/ssl commands])
5787 AT_SKIP_IF([test $HAVE_PYTHON = no])
5788 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5789 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5790 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5794 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5796 # Start sb db server using db connection/ssl entries (unpopulated initially)
5797 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
5798 --remote=db:OVN_Southbound,SB_Global,connections \
5799 --private-key=db:OVN_Southbound,SSL,private_key \
5800 --certificate=db:OVN_Southbound,SSL,certificate \
5801 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
5804 # Populate SSL configuration entries in sb db
5806 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
5807 $PKIDIR/testpki-cert.pem \
5808 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
5810 # Populate a passive SSL connection in sb db
5811 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
5813 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5815 # Verify SSL connetivity to sb db server
5816 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5817 --private-key=$PKIDIR/testpki-privkey.pem \
5818 --certificate=$PKIDIR/testpki-cert.pem \
5819 --ca-cert=$PKIDIR/testpki-cacert.pem \
5821 [0], [stdout], [ignore])
5822 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5823 --private-key=$PKIDIR/testpki-privkey.pem \
5824 --certificate=$PKIDIR/testpki-cert.pem \
5825 --ca-cert=$PKIDIR/testpki-cacert.pem \
5827 [0], [stdout], [ignore])
5828 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5829 --private-key=$PKIDIR/testpki-privkey.pem \
5830 --certificate=$PKIDIR/testpki-cert.pem \
5831 --ca-cert=$PKIDIR/testpki-cacert.pem \
5833 [0], [stdout], [ignore])
5835 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5838 AT_SETUP([ovn -- nested containers])
5842 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
5845 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
5846 # and "bar" (192.168.2.0/24). They are all connected to router R1.
5849 ovn-nbctl ls-add mgmt
5850 ovn-nbctl ls-add foo
5851 ovn-nbctl ls-add bar
5853 # Connect mgmt to R1
5854 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
5855 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
5856 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
5859 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5860 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5861 options:router-port=foo addresses=\"00:00:00:01:02:03\"
5864 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
5865 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
5866 options:router-port=bar addresses=\"00:00:00:01:02:04\"
5868 # "mgmt" has VM1 and VM2 connected
5869 ovn-nbctl lsp-add mgmt vm1 \
5870 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
5872 ovn-nbctl lsp-add mgmt vm2 \
5873 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
5875 # "foo1" and "foo2" are containers belonging to switch "foo"
5876 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
5877 ovn-nbctl lsp-add foo foo1 vm1 1 \
5878 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
5880 ovn-nbctl lsp-add foo foo2 vm2 2 \
5881 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
5883 # "bar1" and "bar2" are containers belonging to switch "bar"
5884 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
5885 ovn-nbctl lsp-add bar bar1 vm1 2 \
5886 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
5888 ovn-nbctl lsp-add bar bar2 vm2 1 \
5889 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
5891 # bar3 is a standalone VM belonging to switch "bar"
5892 ovn-nbctl lsp-add bar bar3 \
5893 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
5895 # Create two hypervisor and create OVS ports corresponding to logical ports.
5900 ovs-vsctl add-br br-phys
5901 ovn_attach n1 br-phys 192.168.0.1
5902 ovs-vsctl -- add-port br-int vm1 -- \
5903 set interface vm1 external-ids:iface-id=vm1 \
5904 options:tx_pcap=hv1/vm1-tx.pcap \
5905 options:rxq_pcap=hv1/vm1-rx.pcap \
5908 ovs-vsctl -- add-port br-int bar3 -- \
5909 set interface bar3 external-ids:iface-id=bar3 \
5910 options:tx_pcap=hv1/bar3-tx.pcap \
5911 options:rxq_pcap=hv1/bar3-rx.pcap \
5916 ovs-vsctl add-br br-phys
5917 ovn_attach n1 br-phys 192.168.0.2
5918 ovs-vsctl -- add-port br-int vm2 -- \
5919 set interface vm2 external-ids:iface-id=vm2 \
5920 options:tx_pcap=hv2/vm2-tx.pcap \
5921 options:rxq_pcap=hv2/vm2-rx.pcap \
5924 # Pre-populate the hypervisors' ARP tables so that we don't lose any
5925 # packets for ARP resolution (native tunneling doesn't queue packets
5926 # for ARP resolution).
5929 # Allow some time for ovn-northd and ovn-controller to catch up.
5930 # XXX This should be more systematic.
5934 printf "%02x%02x%02x%02x" "$@"
5937 # Send ip packets between foo1 and foo2 (same switch, different HVs and
5938 # different VLAN tags).
5939 src_mac="f00000010205"
5940 dst_mac="f00000010206"
5941 src_ip=`ip_to_hex 192 168 1 2`
5942 dst_ip=`ip_to_hex 192 168 1 3`
5943 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5944 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5946 # expected packet at foo2
5947 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5948 echo $packet > expected
5949 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
5951 # Send ip packets between foo1 and bar2 (different switch, different HV)
5952 src_mac="f00000010205"
5953 dst_mac="000000010203"
5954 src_ip=`ip_to_hex 192 168 1 2`
5955 dst_ip=`ip_to_hex 192 168 2 3`
5956 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5957 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5959 # expected packet at bar2
5960 src_mac="000000010204"
5961 dst_mac="f00000010208"
5962 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5963 echo $packet >> expected
5964 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
5966 # Send ip packets between foo1 and bar1
5967 # (different switch, loopback to same vm but different tag)
5968 src_mac="f00000010205"
5969 dst_mac="000000010203"
5970 src_ip=`ip_to_hex 192 168 1 2`
5971 dst_ip=`ip_to_hex 192 168 2 2`
5972 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5973 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5975 # expected packet at bar1
5976 src_mac="000000010204"
5977 dst_mac="f00000010207"
5978 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5979 echo $packet > expected1
5980 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5982 # Send ip packets between bar1 and bar3
5983 # (same switch. But one is container and another is a standalone VM)
5984 src_mac="f00000010207"
5985 dst_mac="f00000010209"
5986 src_ip=`ip_to_hex 192 168 2 2`
5987 dst_ip=`ip_to_hex 192 168 2 3`
5988 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5989 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5991 # expected packet at bar3
5992 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5993 echo $packet > expected
5994 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
5996 # Send ip packets between foo1 and vm1.
5997 (different switch, container to the VM hosting it.)
5998 src_mac="f00000010205"
5999 dst_mac="000000010203"
6000 src_ip=`ip_to_hex 192 168 1 2`
6001 dst_ip=`ip_to_hex 172 16 1 2`
6002 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6003 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6005 # expected packet at vm1
6006 src_mac="000000010202"
6007 dst_mac="f00000010203"
6008 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6009 echo $packet >> expected1
6010 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6012 # Send packets from vm1 to bar1.
6013 (different switch, A hosting VM to a container inside it)
6014 src_mac="f00000010203"
6015 dst_mac="000000010202"
6016 src_ip=`ip_to_hex 172 16 1 2`
6017 dst_ip=`ip_to_hex 192 168 2 2`
6018 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6019 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6021 # expected packet at vm1
6022 src_mac="000000010204"
6023 dst_mac="f00000010207"
6024 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6025 echo $packet >> expected1
6026 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6028 OVN_CLEANUP([hv1],[hv2])
6032 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6033 AT_SKIP_IF([test $HAVE_PYTHON = no])
6037 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6038 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6039 # (192.168.2.0/24) connected to it.
6041 # R2 and R3 are gateway routers.
6042 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6043 # connected to it. Note how both alice and bob have the same subnet behind it.
6044 # We are trying to simulate external network via those 2 switches. In real
6045 # world the switch ports of these switches will have addresses set as "unknown"
6046 # to make them learning switches. Or those switches will be "localnet" ones.
6048 # Create three hypervisors and create OVS ports corresponding to logical ports.
6053 ovs-vsctl add-br br-phys
6054 ovn_attach n1 br-phys 192.168.0.1
6055 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6056 set interface hv1-vif1 external-ids:iface-id=foo1 \
6057 options:tx_pcap=hv1/vif1-tx.pcap \
6058 options:rxq_pcap=hv1/vif1-rx.pcap \
6061 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6062 set interface hv1-vif2 external-ids:iface-id=bar1 \
6063 options:tx_pcap=hv1/vif2-tx.pcap \
6064 options:rxq_pcap=hv1/vif2-rx.pcap \
6069 ovs-vsctl add-br br-phys
6070 ovn_attach n1 br-phys 192.168.0.2
6071 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6072 set interface hv2-vif1 external-ids:iface-id=alice1 \
6073 options:tx_pcap=hv2/vif1-tx.pcap \
6074 options:rxq_pcap=hv2/vif1-rx.pcap \
6079 ovs-vsctl add-br br-phys
6080 ovn_attach n1 br-phys 192.168.0.3
6081 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6082 set interface hv3-vif1 external-ids:iface-id=bob1 \
6083 options:tx_pcap=hv3/vif1-tx.pcap \
6084 options:rxq_pcap=hv3/vif1-rx.pcap \
6088 ovn-nbctl create Logical_Router name=R1
6089 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6090 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6092 ovn-nbctl ls-add foo
6093 ovn-nbctl ls-add bar
6094 ovn-nbctl ls-add alice
6095 ovn-nbctl ls-add bob
6096 ovn-nbctl ls-add join
6099 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6100 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6101 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6104 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6105 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6106 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6108 # Connect alice to R2
6109 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6110 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6111 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6114 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6115 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6116 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6118 # Connect R1 to join
6119 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6120 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6121 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6123 # Connect R2 to join
6124 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6125 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6126 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6128 # Connect R3 to join
6129 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6130 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6131 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6133 # Install static routes with source ip address as the policy for routing.
6134 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6135 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6136 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6138 # Install static routes with destination ip address as the policy for routing.
6139 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6141 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6143 # Create logical port foo1 in foo
6144 ovn-nbctl lsp-add foo foo1 \
6145 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6147 # Create logical port bar1 in bar
6148 ovn-nbctl lsp-add bar bar1 \
6149 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6151 # Create logical port alice1 in alice
6152 ovn-nbctl lsp-add alice alice1 \
6153 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6155 # Create logical port bob1 in bob
6156 ovn-nbctl lsp-add bob bob1 \
6157 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6159 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6160 # packets for ARP resolution (native tunneling doesn't queue packets
6161 # for ARP resolution).
6164 # Allow some time for ovn-northd and ovn-controller to catch up.
6165 # XXX This should be more systematic.
6169 printf "%02x%02x%02x%02x" "$@"
6172 sed 's/\(00\)\{1,\}$//'
6175 # Send ip packets between foo1 and bar1
6176 # (East-west traffic should flow normally)
6177 src_mac="f00000010203"
6178 dst_mac="000001010203"
6179 src_ip=`ip_to_hex 192 168 1 2`
6180 dst_ip=`ip_to_hex 192 168 2 2`
6181 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6182 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6184 # Send ip packets between foo1 and alice1
6185 src_mac="f00000010203"
6186 dst_mac="000001010203"
6187 src_ip=`ip_to_hex 192 168 1 2`
6188 dst_ip=`ip_to_hex 172 16 1 3`
6189 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6190 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6191 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6193 # Send ip packets between bar1 and bob1
6194 src_mac="f00000010204"
6195 dst_mac="000001010204"
6196 src_ip=`ip_to_hex 192 168 2 2`
6197 dst_ip=`ip_to_hex 172 16 1 4`
6198 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6199 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6200 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6202 # Packet to expect at bar1
6203 src_mac="000001010204"
6204 dst_mac="f00000010204"
6205 src_ip=`ip_to_hex 192 168 1 2`
6206 dst_ip=`ip_to_hex 192 168 2 2`
6207 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6208 echo $expected > expected
6209 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6211 # Packet to Expect at alice1
6212 src_mac="000002010203"
6213 dst_mac="f00000010205"
6214 src_ip=`ip_to_hex 192 168 1 2`
6215 dst_ip=`ip_to_hex 172 16 1 3`
6216 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6217 echo $expected > expected
6218 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6220 # Packet to Expect at bob1
6221 src_mac="000003010203"
6222 dst_mac="f00000010206"
6223 src_ip=`ip_to_hex 192 168 2 2`
6224 dst_ip=`ip_to_hex 172 16 1 4`
6225 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6226 echo $expected > expected
6227 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6229 for sim in hv1 hv2 hv3; do
6231 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6232 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6233 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6237 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6240 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6243 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6246 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6247 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6251 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
6252 AT_SKIP_IF([test $HAVE_PYTHON = no])
6256 # One LR R1 that has switches foo (192.168.1.0/24) and
6257 # alice (172.16.1.0/24) connected to it. The logical port
6258 # between R1 and alice has a "redirect-chassis" specified,
6259 # i.e. it is the distributed router gateway port.
6260 # Switch alice also has a localnet port defined.
6261 # An additional switch outside has a localnet port and the
6262 # same subnet as alice (172.16.1.0/24).
6265 # Three hypervisors hv[123].
6266 # hv1 hosts vif foo1.
6267 # hv2 is the "redirect-chassis" that hosts the distributed
6268 # router gateway port.
6269 # hv3 hosts vif outside1.
6270 # In order to show that connectivity works only through hv2,
6271 # an initial round of tests is run without any bridge-mapping
6272 # defined for the localnet on hv2. These tests are expected
6274 # Subsequent tests are run after defining the bridge-mapping
6275 # for the localnet on hv2. These tests are expected to succeed.
6277 # Create three hypervisors and create OVS ports corresponding
6283 ovs-vsctl add-br br-phys
6284 ovn_attach n1 br-phys 192.168.0.1
6285 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6286 set interface hv1-vif1 external-ids:iface-id=foo1 \
6287 options:tx_pcap=hv1/vif1-tx.pcap \
6288 options:rxq_pcap=hv1/vif1-rx.pcap \
6293 ovs-vsctl add-br br-phys
6294 ovn_attach n1 br-phys 192.168.0.2
6298 ovs-vsctl add-br br-phys
6299 ovn_attach n1 br-phys 192.168.0.3
6300 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6301 set interface hv3-vif1 external-ids:iface-id=outside1 \
6302 options:tx_pcap=hv3/vif1-tx.pcap \
6303 options:rxq_pcap=hv3/vif1-rx.pcap \
6306 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6307 # packets for ARP resolution (native tunneling doesn't queue packets
6308 # for ARP resolution).
6311 ovn-nbctl create Logical_Router name=R1
6313 ovn-nbctl ls-add foo
6314 ovn-nbctl ls-add alice
6315 ovn-nbctl ls-add outside
6318 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6319 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6320 type=router options:router-port=foo \
6321 -- lsp-set-addresses rp-foo router
6323 # Connect alice to R1 as distributed router gateway port on hv2
6324 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
6325 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
6326 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6327 type=router options:router-port=alice \
6328 -- lsp-set-addresses rp-alice router
6330 # Create logical port foo1 in foo
6331 ovn-nbctl lsp-add foo foo1 \
6332 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6334 # Create logical port outside1 in outside
6335 ovn-nbctl lsp-add outside outside1 \
6336 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
6338 # Create localnet port in alice
6339 ovn-nbctl lsp-add alice ln-alice
6340 ovn-nbctl lsp-set-addresses ln-alice unknown
6341 ovn-nbctl lsp-set-type ln-alice localnet
6342 ovn-nbctl lsp-set-options ln-alice network_name=phys
6344 # Create localnet port in outside
6345 ovn-nbctl lsp-add outside ln-outside
6346 ovn-nbctl lsp-set-addresses ln-outside unknown
6347 ovn-nbctl lsp-set-type ln-outside localnet
6348 ovn-nbctl lsp-set-options ln-outside network_name=phys
6350 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
6351 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
6352 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
6355 # Allow some time for ovn-northd and ovn-controller to catch up.
6356 # XXX This should be more systematic.
6359 echo "---------NB dump-----"
6361 echo "---------------------"
6362 ovn-nbctl list logical_router
6363 echo "---------------------"
6364 ovn-nbctl list logical_router_port
6365 echo "---------------------"
6367 echo "---------SB dump-----"
6368 ovn-sbctl list datapath_binding
6369 echo "---------------------"
6370 ovn-sbctl list port_binding
6371 echo "---------------------"
6372 ovn-sbctl dump-flows
6373 echo "---------------------"
6374 ovn-sbctl list chassis
6375 ovn-sbctl list encap
6376 echo "---------------------"
6378 echo "------ hv1 dump ----------"
6379 as hv1 ovs-ofctl show br-int
6380 as hv1 ovs-ofctl dump-flows br-int
6381 echo "------ hv2 dump ----------"
6382 as hv2 ovs-ofctl show br-int
6383 as hv2 ovs-ofctl dump-flows br-int
6384 echo "------ hv3 dump ----------"
6385 as hv3 ovs-ofctl show br-int
6386 as hv3 ovs-ofctl dump-flows br-int
6387 echo "--------------------------"
6389 # Check that redirect mapping is programmed only on hv2
6390 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
6392 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
6394 # Check that hv1 sends chassisredirect port traffic to hv2
6395 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
6397 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
6399 # Check that arp reply on distributed gateway port is only programmed on hv2
6400 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
6402 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
6407 printf "%02x%02x%02x%02x" "$@"
6411 : > hv2-vif1.expected
6412 : > hv3-vif1.expected
6414 # test_arp INPORT SHA SPA TPA [REPLY_HA]
6416 # Causes a packet to be received on INPORT. The packet is an ARP
6417 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
6418 # it should be the hardware address of the target to expect to receive in an
6419 # ARP reply; otherwise no reply is expected.
6421 # INPORT is an logical switch port number, e.g. 11 for vif11.
6422 # SHA and REPLY_HA are each 12 hex digits.
6423 # SPA and TPA are each 8 hex digits.
6425 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
6426 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
6427 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
6429 if test X$reply_ha != X; then
6430 # Expect to receive the reply, if any.
6431 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
6432 echo $reply >> hv${hv}-vif$inport.expected
6436 rtr_ip=$(ip_to_hex 172 16 1 1)
6437 foo_ip=$(ip_to_hex 192 168 1 2)
6438 outside_ip=$(ip_to_hex 172 16 1 3)
6444 # ARP for router IP address from outside1, no response expected
6445 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
6447 # Now check the packets actually received against the ones expected.
6448 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
6450 # Send ip packet between foo1 and outside1
6451 src_mac="f00000010203"
6452 dst_mac="000001010203"
6453 src_ip=`ip_to_hex 192 168 1 2`
6454 dst_ip=`ip_to_hex 172 16 1 3`
6455 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6457 # Now check the packets actually received against the ones expected.
6458 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
6460 # Now add bridge-mappings on hv2, which should make everything work
6461 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
6463 # Allow some time for ovn-northd and ovn-controller to catch up.
6464 # XXX This should be more systematic.
6467 # ARP for router IP address from outside1
6468 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
6470 # Now check the packets actually received against the ones expected.
6471 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
6473 # Send ip packet between foo1 and outside1
6474 src_mac="f00000010203"
6475 dst_mac="000001010203"
6476 src_ip=`ip_to_hex 192 168 1 2`
6477 dst_ip=`ip_to_hex 172 16 1 3`
6478 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6480 # ARP request packet to expect at outside1
6481 src_mac="000002010203"
6482 src_ip=`ip_to_hex 172 16 1 1`
6483 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
6485 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6487 echo $arp_request >> hv3-vif1.expected
6488 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
6490 # Send ARP reply from outside1 back to the router
6491 reply_mac="f00000010204"
6492 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
6494 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
6496 # Allow some time for ovn-northd and ovn-controller to catch up.
6497 # XXX This should be more systematic.
6500 # Packet to Expect at outside1
6501 src_mac="000002010203"
6502 dst_mac="f00000010204"
6503 src_ip=`ip_to_hex 192 168 1 2`
6504 dst_ip=`ip_to_hex 172 16 1 3`
6505 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6507 # Resend packet from foo1 to outside1
6508 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6510 echo "------ hv1 dump ----------"
6511 as hv1 ovs-ofctl show br-int
6512 as hv1 ovs-ofctl dump-flows br-int
6513 echo "------ hv2 dump ----------"
6514 as hv2 ovs-ofctl show br-int
6515 as hv2 ovs-ofctl dump-flows br-int
6516 echo "------ hv3 dump ----------"
6517 as hv3 ovs-ofctl show br-int
6518 as hv3 ovs-ofctl dump-flows br-int
6519 echo "----------------------------"
6521 echo $expected >> hv3-vif1.expected
6522 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
6524 #Check ovn-trace over "chassisredirect" port
6525 AT_CAPTURE_FILE([trace])
6527 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6530 echo 'ip.ttl--;' > expout
6531 echo 'eth.src = 00:00:02:01:02:03;' >> expout
6532 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
6533 echo 'output("ln-alice");' >> expout
6534 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])
6536 # Create logical port alice1 in alice on hv1
6537 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6538 set interface hv1-vif2 external-ids:iface-id=alice1 \
6539 options:tx_pcap=hv1/vif2-tx.pcap \
6540 options:rxq_pcap=hv1/vif2-rx.pcap \
6543 ovn-nbctl lsp-add alice alice1 \
6544 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
6546 # Create logical port foo2 in foo on hv2
6547 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6548 set interface hv2-vif1 external-ids:iface-id=foo2 \
6549 options:tx_pcap=hv2/vif1-tx.pcap \
6550 options:rxq_pcap=hv2/vif1-rx.pcap \
6553 ovn-nbctl lsp-add foo foo2 \
6554 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6556 # Allow some time for ovn-northd and ovn-controller to catch up.
6557 # XXX This should be more systematic.
6560 : > hv1-vif2.expected
6562 # Send ip packet between alice1 and foo2
6563 src_mac="f00000010205"
6564 dst_mac="000002010203"
6565 src_ip=`ip_to_hex 172 16 1 4`
6566 dst_ip=`ip_to_hex 192 168 1 3`
6567 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6569 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6571 # Packet to Expect at foo2
6572 src_mac="000001010203"
6573 dst_mac="f00000010206"
6574 src_ip=`ip_to_hex 172 16 1 4`
6575 dst_ip=`ip_to_hex 192 168 1 3`
6576 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6578 echo $expected >> hv2-vif1.expected
6579 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
6581 OVN_CLEANUP([hv1],[hv2],[hv3])