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 -- 4-term numeric expression normalization])
457 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
458 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
462 AT_SETUP([ovn -- 4-term string expression normalization])
463 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
464 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
468 AT_SETUP([ovn -- 4-term mixed expression normalization])
469 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
470 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
474 AT_SETUP([ovn -- 5-term numeric expression normalization])
475 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
476 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
480 AT_SETUP([ovn -- 5-term string expression normalization])
481 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
482 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
486 AT_SETUP([ovn -- 5-term mixed expression normalization])
487 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
488 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
492 AT_SETUP([ovn -- 4-term numeric expressions to flows])
493 AT_KEYWORDS([expression])
494 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
495 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
499 AT_SETUP([ovn -- 4-term string expressions to flows])
500 AT_KEYWORDS([expression])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
502 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
506 AT_SETUP([ovn -- 4-term mixed expressions to flows])
507 AT_KEYWORDS([expression])
508 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
509 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
513 AT_SETUP([ovn -- 3-term numeric expressions to flows])
514 AT_KEYWORDS([expression])
515 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
516 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
520 AT_SETUP([ovn -- converting expressions to flows -- string fields])
521 AT_KEYWORDS([expression])
523 echo "$1" | ovstest test-ovn expr-to-flows | sort
525 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
527 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
529 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
531 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
535 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
539 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
541 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
546 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
552 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
557 AT_SETUP([ovn -- converting expressions to flows -- address sets])
558 AT_KEYWORDS([expression])
560 echo "$1" | ovstest test-ovn expr-to-flows | sort
562 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
567 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
572 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
578 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
585 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
590 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
596 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
597 dl_src=00:00:00:00:00:01
598 dl_src=00:00:00:00:00:02
599 dl_src=00:00:00:00:00:03
601 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
602 dl_src=00:00:00:00:00:01
603 dl_src=00:00:00:00:00:02
604 dl_src=00:00:00:00:00:03
606 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
607 dl_src=00:00:00:00:00:01
608 dl_src=00:00:00:00:00:02
609 dl_src=00:00:00:00:00:03
610 dl_src=ba:be:be:ef:de:ad
614 AT_SETUP([ovn -- action parsing])
615 dnl Unindented text is input (a set of OVN logical actions).
616 dnl Indented text is expected output.
617 AT_DATA([test-cases.txt],
622 Syntax error at `next' expecting end of input.
624 Syntax error at `drop' expecting action.
628 encodes as resubmit(,64)
633 encodes as resubmit(,27)
635 encodes as resubmit(,27)
637 encodes as resubmit(,16)
639 encodes as resubmit(,31)
642 Syntax error at `)' expecting small integer.
644 Syntax error at `;' expecting `)'.
646 "next" argument must be in range 0 to 15.
648 # Loading a constant value.
650 formats as tcp.dst = 80;
651 encodes as set_field:80->tcp_dst
652 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
654 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
656 encodes as set_field:0x4000/0xe000->vlan_tci
657 has prereqs vlan.tci[12]
658 vlan.tci[13..15] = 2;
659 encodes as set_field:0x4000/0xe000->vlan_tci
661 encodes as set_field:0->reg14
663 formats as ip.ttl = 4;
664 encodes as set_field:4->nw_ttl
665 has prereqs eth.type == 0x800 || eth.type == 0x86dd
666 outport="eth0"; next; outport="LOCAL"; next;
667 formats as outport = "eth0"; next(11); outport = "LOCAL"; next(11);
668 encodes as set_field:0x5->reg15,resubmit(,27),set_field:0xfffe->reg15,resubmit(,27)
671 Cannot select subfield of string field inport.
673 Cannot select subfield of nominal field ip.proto.
675 Syntax error at `==' expecting `=' or `<->'.
677 Predicate symbol ip used where lvalue required.
679 Field ip.proto is not modifiable.
681 Syntax error at `{' expecting constant.
683 Syntax error at `{' expecting constant.
685 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
687 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'.
689 Predicate symbol vlan.present used where lvalue required.
691 # Moving one field into another.
693 formats as reg0 = reg1;
694 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
695 vlan.pcp = reg0[0..2];
696 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
697 has prereqs vlan.tci[12]
698 reg0[10] = vlan.pcp[1];
699 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
700 has prereqs vlan.tci[12]
702 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
704 reg0[0] = vlan.present;
705 Predicate symbol vlan.present used where lvalue required.
707 Can't assign 11-bit value to 32-bit destination.
709 Can't assign integer field (reg0) to string field (inport).
711 String fields inport and big_string are incompatible for assignment.
712 ip.proto = reg0[0..7];
713 Field ip.proto is not modifiable.
717 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]
718 vlan.pcp <-> reg0[0..2];
719 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]
720 has prereqs vlan.tci[12]
721 reg0[10] <-> vlan.pcp[1];
722 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
723 has prereqs vlan.tci[12]
725 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
727 reg0[0] <-> vlan.present;
728 Predicate symbol vlan.present used where lvalue required.
729 reg0 <-> reg1[0..10];
730 Can't exchange 32-bit field with 11-bit field.
732 Can't exchange string field (inport) with integer field (reg0).
733 inport <-> big_string;
734 String fields inport and big_string are incompatible for exchange.
735 ip.proto <-> reg0[0..7];
736 Field ip.proto is not modifiable.
737 reg0[0..7] <-> ip.proto;
738 Field ip.proto is not modifiable.
745 Syntax error at end of input expecting `--'.
749 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
753 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
755 ct_lb(192.168.1.2:80, 192.168.1.3:80);
758 ct_lb(192.168.1.2, 192.168.1.3, );
759 formats as ct_lb(192.168.1.2, 192.168.1.3);
764 Syntax error at `)' expecting port number.
765 ct_lb(192.168.1.2:123456);
766 Syntax error at `123456' expecting port number.
768 Syntax error at `foo' expecting IPv4 address.
772 encodes as ct(table=27,zone=NXM_NX_REG13[0..15])
777 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
780 formats as ct_commit;
781 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
783 ct_commit(ct_mark=1);
784 formats as ct_commit(ct_mark=0x1);
785 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
787 ct_commit(ct_mark=1/1);
788 formats as ct_commit(ct_mark=0x1/0x1);
789 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
791 ct_commit(ct_label=1);
792 formats as ct_commit(ct_label=0x1);
793 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
795 ct_commit(ct_label=1/1);
796 formats as ct_commit(ct_label=0x1/0x1);
797 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
799 ct_commit(ct_mark=1, ct_label=2);
800 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
801 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
804 ct_commit(ct_label=0x01020304050607080910111213141516);
805 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
806 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
808 ct_commit(ct_label=0x181716151413121110090807060504030201);
809 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
810 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
812 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
813 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
815 ct_commit(ct_label=18446744073709551615);
816 formats as ct_commit(ct_label=0xffffffffffffffff);
817 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
819 ct_commit(ct_label=18446744073709551616);
820 Decimal constants must be less than 2**64.
824 encodes as ct(table=27,zone=NXM_NX_REG11[0..15],nat)
826 ct_dnat(192.168.1.2);
827 encodes as ct(commit,table=27,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
830 ct_dnat(192.168.1.2, 192.168.1.3);
831 Syntax error at `,' expecting `)'.
833 Syntax error at `foo' expecting IPv4 address.
835 Syntax error at `foo' expecting IPv4 address.
837 Syntax error at `)' expecting IPv4 address.
841 encodes as ct(zone=NXM_NX_REG12[0..15],nat)
843 ct_snat(192.168.1.2);
844 encodes as ct(commit,table=27,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
847 ct_snat(192.168.1.2, 192.168.1.3);
848 Syntax error at `,' expecting `)'.
850 Syntax error at `foo' expecting IPv4 address.
852 Syntax error at `foo' expecting IPv4 address.
854 Syntax error at `)' expecting IPv4 address.
857 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; };
858 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)
862 get_arp(outport, ip4.dst);
863 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[]
864 has prereqs eth.type == 0x800
865 get_arp(inport, reg0);
866 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[]
869 Syntax error at `;' expecting `('.
871 Syntax error at `)' expecting field name.
873 Syntax error at `)' expecting `,'.
874 get_arp(inport ip4.dst);
875 Syntax error at `ip4.dst' expecting `,'.
876 get_arp(inport, ip4.dst;
877 Syntax error at `;' expecting `)'.
878 get_arp(inport, eth.dst);
879 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
880 get_arp(inport, outport);
881 Cannot use string field outport where numeric field is required.
882 get_arp(reg0, ip4.dst);
883 Cannot use numeric field reg0 where string field is required.
886 put_arp(inport, arp.spa, arp.sha);
887 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[]
888 has prereqs eth.type == 0x806 && eth.type == 0x806
891 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
892 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)
893 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");
894 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");
895 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)
896 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);
897 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);
898 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)
900 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
901 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
902 reg1[0] = put_dhcp_opts();
903 put_dhcp_opts requires offerip to be specified.
904 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
905 Syntax error at `x' expecting DHCPv4 option name.
906 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
907 put_dhcp_opts requires offerip to be specified.
908 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
909 Syntax error at `"hi"'.
910 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
911 Syntax error at `xyzzy' expecting DHCPv4 option name.
912 reg1[0] = put_dhcp_opts(offerip="xyzzy");
913 DHCPv4 option offerip requires numeric value.
914 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
915 DHCPv4 option domain requires string value.
918 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; };
919 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
920 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)
924 get_nd(outport, ip6.dst);
925 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[]
926 has prereqs eth.type == 0x86dd
927 get_nd(inport, xxreg0);
928 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[]
930 Syntax error at `;' expecting `('.
932 Syntax error at `)' expecting field name.
934 Syntax error at `)' expecting `,'.
935 get_nd(inport ip6.dst);
936 Syntax error at `ip6.dst' expecting `,'.
937 get_nd(inport, ip6.dst;
938 Syntax error at `;' expecting `)'.
939 get_nd(inport, eth.dst);
940 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
941 get_nd(inport, outport);
942 Cannot use string field outport where numeric field is required.
943 get_nd(xxreg0, ip6.dst);
944 Cannot use numeric field xxreg0 where string field is required.
947 put_nd(inport, nd.target, nd.sll);
948 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[]
949 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)
952 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
953 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)
954 reg1[0] = put_dhcpv6_opts();
955 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
956 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
957 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
958 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)
959 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
960 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
961 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)
962 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
963 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)
964 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
965 Syntax error at `x' expecting DHCPv6 option name.
966 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
967 Syntax error at `"hi"'.
968 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
969 Syntax error at `xyzzy' expecting DHCPv6 option name.
970 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
971 DHCPv6 option ia_addr requires numeric value.
972 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
973 DHCPv6 option domain_search requires string value.
977 encodes as set_queue:0
979 encodes as set_queue:61440
981 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
983 # Contradictionary prerequisites (allowed but not useful):
984 ip4.src = ip6.src[0..31];
985 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
986 has prereqs eth.type == 0x800 && eth.type == 0x86dd
987 ip4.src <-> ip6.src[0..31];
988 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[]
989 has prereqs eth.type == 0x800 && eth.type == 0x86dd
991 # Miscellaneous negative tests.
995 Syntax error at `xyzzy' expecting action.
997 Syntax error at `123'.
999 Syntax error at `xyzzy' expecting action.
1001 Syntax error at end of input expecting `;'.
1003 sed '/^[[ ]]/d' test-cases.txt > input.txt
1004 cp test-cases.txt expout
1005 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1008 AT_BANNER([OVN end-to-end tests])
1010 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1011 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1012 AT_KEYWORDS([ovnarp])
1013 AT_SKIP_IF([test $HAVE_PYTHON = no])
1016 # Create hypervisors hv[123].
1017 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1018 # Add all of the vifs to a single logical switch lsw0.
1019 # Turn on port security on all the vifs except vif[123]1.
1020 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1021 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1022 ovn-nbctl ls-add lsw0
1027 ovs-vsctl add-br br-phys
1028 ovn_attach n1 br-phys 192.168.0.$i
1031 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
1032 ovn-nbctl lsp-add lsw0 lp$i$j
1033 if test $j = 1; then
1034 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1036 if test $j = 3; then
1037 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1039 ip_addrs="192.168.0.$i$j"
1041 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1042 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1046 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1047 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1048 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1049 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\"
1050 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1052 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1053 # packets for ARP resolution (native tunneling doesn't queue packets
1054 # for ARP resolution).
1057 # Allow some time for ovn-northd and ovn-controller to catch up.
1058 # XXX This should be more systematic.
1061 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1062 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1063 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1064 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1066 # Given the name of a logical port, prints the name of the hypervisor
1067 # on which it is located.
1072 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1074 # This shell function causes a packet to be received on INPORT. The packet's
1075 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1076 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1077 # more) list the VIFs on which the packet should be received. INPORT and the
1078 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1085 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1086 hv=`vif_to_hv $inport`
1088 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1090 echo $packet >> $outport.expected
1094 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1096 # Causes a packet to be received on INPORT. The packet is an ARP
1097 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1098 # it should be the hardware address of the target to expect to receive in an
1099 # ARP reply; otherwise no reply is expected.
1101 # INPORT is an logical switch port number, e.g. 11 for vif11.
1102 # SHA and REPLY_HA are each 12 hex digits.
1103 # SPA and TPA are each 8 hex digits.
1105 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1106 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1107 hv=`vif_to_hv $inport`
1108 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1110 if test X$reply_ha = X; then
1111 # Expect to receive the broadcast ARP on the other logical switch ports
1112 # if no reply is expected.
1116 if test $i$j != $inport; then
1117 echo $request >> $i$j.expected
1122 # Expect to receive the reply, if any.
1123 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1124 echo $reply >> $inport.expected
1129 printf "%02x%02x%02x%02x" "$@"
1132 # Send packets between all pairs of source and destination ports:
1134 # 1. Unicast packets are delivered to exactly one logical switch port
1135 # (except that packets destined to their input ports are dropped).
1137 # 2. Broadcast and multicast are delivered to all logical switch ports
1138 # except the input port.
1140 # 3. When port security is turned on, the switch drops packets from the wrong
1143 # 4. The switch drops all packets with a VLAN tag.
1145 # 5. The switch drops all packets with a multicast source address. (This only
1146 # affects behavior when port security is turned off, since otherwise port
1147 # security would drop the packet anyway.)
1149 # 6. The switch delivers packets with an unknown destination to logical
1150 # switch ports with "unknown" among their MAC addresses (and port
1151 # security disabled).
1153 # 7. The switch drops unicast packets that violate an ACL.
1155 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1157 # 9. OVN generates responses to ARP requests for known IPs, except for
1158 # requests from a port for the port's own IP.
1160 # 10. No response to ARP requests for unknown IPs.
1173 if test $d != $s; then unicast=$d; else unicast=; fi
1174 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1176 if test $d != $s && test $js = 1; then
1181 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1183 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1184 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1185 if test $d = $s || (test $js = 1 && test $d = 33); then
1186 # Source of 11, 21, or 31 and dest of 33 should be dropped
1187 # due to the 4th ACL that uses address_set(set1).
1192 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1193 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1194 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1195 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1197 test_packet $s f000000000$d f00000000055 810000091234 #4
1198 test_packet $s f000000000$d 0100000000$s $s$d #5
1200 if test $d != $s && test $jd = 1; then
1201 unknown="$unknown $d"
1203 bcast="$bcast $unicast"
1204 bacl2="$bacl2 $acl2"
1205 bacl3="$bacl3 $acl3"
1207 sip=`ip_to_hex 192 168 0 $i$j`
1208 tip=`ip_to_hex 192 168 0 $id$jd`
1209 tip_unknown=`ip_to_hex 11 11 11 11`
1210 if test $d != $s; then
1211 reply_ha=f000000000$d
1215 test_arp $s f000000000$s $sip $tip $reply_ha #9
1216 test_arp $s f000000000$s $sip $tip_unknown #10
1218 if test $jd = 3; then
1219 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1220 tip=`ip_to_hex 192 169 0 $id$jd`
1221 test_arp $s f000000000$s $sip $tip $reply_ha #9
1226 # Broadcast and multicast.
1227 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1228 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1229 if test $js = 1; then
1230 bcast_impersonate=$bcast
1234 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1236 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1238 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1239 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1240 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1241 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1242 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1243 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1247 # set address for lp13 with invalid characters.
1248 # lp13 should be configured with only 192.168.0.13.
1249 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1251 # Allow some time for ovn-northd and ovn-controller to catch up.
1252 # XXX This should be more systematic.
1255 sip=`ip_to_hex 192 168 0 11`
1256 tip=`ip_to_hex 192 168 0 13`
1257 test_arp 11 f00000000011 $sip $tip f00000000013
1259 tip=`ip_to_hex 192 169 0 13`
1260 #arp request for 192.169.0.13 should be flooded
1261 test_arp 11 f00000000011 $sip $tip
1263 # dump information and flows with counters
1264 ovn-sbctl dump-flows -- list multicast_group
1266 echo "------ hv1 dump ------"
1267 as hv1 ovs-vsctl show
1268 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1270 echo "------ hv2 dump ------"
1271 as hv2 ovs-vsctl show
1272 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1274 echo "------ hv3 dump ------"
1275 as hv3 ovs-vsctl show
1276 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1278 # Now check the packets actually received against the ones expected.
1281 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1285 OVN_CLEANUP([hv1],[hv2],[hv3])
1289 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1290 AT_SKIP_IF([test $HAVE_PYTHON = no])
1293 # Create a logical switch and some logical ports.
1294 # Turn on port security on all lports except ls1.
1295 # Make ls1 a destination for unknown MACs.
1296 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1297 ovn-nbctl ls-add lsw0
1298 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1300 ovn-nbctl lsp-add lsw0 lp$i
1302 ovn-nbctl --wait=sb sync
1304 ovn-sbctl lsp-bind lp$i hv0
1305 if test $i = 1; then
1306 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1308 if test $i = 3; then
1309 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1311 ip_addrs="192.168.0.$i"
1313 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1314 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
1317 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1318 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1319 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1320 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1321 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1323 ovn-nbctl --wait=sb sync
1324 on_exit 'kill `cat ovn-trace.pid`'
1325 ovn-trace --detach --pidfile --no-chdir
1327 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1329 # This shell function causes a packet to be received on INPORT. The packet's
1330 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1331 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1332 # more) list the VIFs on which the packet should be received. INPORT and the
1333 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1335 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1336 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1339 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1340 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1345 echo "output(\"lp$outport\");"
1348 AT_CAPTURE_FILE([trace])
1349 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1352 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1354 # Causes a packet to be received on INPORT. The packet is an ARP
1355 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1356 # it should be the hardware address of the target to expect to receive in an
1357 # ARP reply; otherwise no reply is expected.
1359 # INPORT is an logical switch port number, e.g. 11 for vif11.
1360 # SHA and REPLY_HA are each 12 hex digits.
1361 # SPA and TPA are each 8 hex digits.
1363 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1365 local request="inport == \"lp$inport\"
1366 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1367 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1368 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1370 if test -z "$reply_ha"; then
1374 if test $i != $inport; then
1375 reply="${reply}output(\"lp$i\");
1382 eth.src = $reply_ha;
1385 arp.sha = $reply_ha;
1388 output(\"lp$inport\");
1392 AT_CAPTURE_FILE([trace])
1393 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1396 # Send packets between all pairs of source and destination ports:
1398 # 1. Unicast packets are delivered to exactly one logical switch port
1399 # (except that packets destined to their input ports are dropped).
1401 # 2. Broadcast and multicast are delivered to all logical switch ports
1402 # except the input port.
1404 # 3. When port security is turned on, the switch drops packets from the wrong
1407 # 4. The switch drops all packets with a VLAN tag.
1409 # 5. The switch drops all packets with a multicast source address. (This only
1410 # affects behavior when port security is turned off, since otherwise port
1411 # security would drop the packet anyway.)
1413 # 6. The switch delivers packets with an unknown destination to logical
1414 # switch ports with "unknown" among their MAC addresses (and port
1415 # security disabled).
1417 # 7. The switch drops unicast packets that violate an ACL.
1419 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1421 # 9. OVN generates responses to ARP requests for known IPs, except for
1422 # requests from a port for the port's own IP.
1424 # 10. No response to ARP requests for unknown IPs.
1434 if test $d != $s; then unicast=$d; else unicast=; fi
1435 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1437 if test $d != $s && test $s = 1; then
1442 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1444 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1445 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1446 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1447 # Source of 1 or 2 and dest of 3 should be dropped
1448 # due to the 4th ACL that uses address_set(set1).
1455 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1456 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1457 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1458 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1460 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1461 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1463 if test $d != $s && test $d = 1; then
1464 unknown="$unknown $d"
1466 bcast="$bcast $unicast"
1467 bacl2="$bacl2 $acl2"
1468 bacl3="$bacl3 $acl3"
1472 tip_unknown=11.11.11.11
1473 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1474 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1475 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1477 if test $d = 3; then
1478 # lp3 has an additional ip 192.169.0.[123]3.
1480 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1484 # Broadcast and multicast.
1485 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1486 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1487 if test $s = 1; then
1488 bcast_impersonate=$bcast
1492 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1494 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1497 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1498 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1499 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1502 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1503 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1504 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1509 # 2 hypervisors, 4 logical ports per HV
1510 # 2 locally attached networks (one flat, one vlan tagged over same device)
1511 # 2 ports per HV on each network
1512 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1513 AT_SKIP_IF([test $HAVE_PYTHON = no])
1516 # In this test cases we create 3 switches, all connected to same
1517 # physical network (through br-phys on each HV). Each switch has
1518 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1519 # of VIF port name indicates the hypervisor it is bound to, e.g.
1520 # lp23 means VIF 3 on hv2.
1522 # Each switch's VLAN tag and their logical switch ports are:
1525 # - ports: lp11, lp12, lp21, lp22
1528 # - tagged with VLAN 101
1529 # - ports: lp13, lp14, lp23, lp24
1532 # - ports: lp15, lp25
1534 # Note: a localnet port is created for each switch to connect to
1539 ovn-nbctl ls-add $ls_name
1541 if test $i -eq 2; then
1542 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1544 ovn-nbctl lsp-add $ls_name $ln_port_name
1546 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1547 ovn-nbctl lsp-set-type $ln_port_name localnet
1548 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1553 # Prints the name of the logical switch that contains LSP.
1556 lp?[[12]]) echo ls1 ;; dnl (
1557 lp?[[34]]) echo ls2 ;; dnl (
1558 lp?5) echo ls3 ;; dnl (
1559 *) AT_FAIL_IF([:]) ;;
1567 ovs-vsctl add-br br-phys
1568 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1569 ovn_attach n1 br-phys 192.168.0.$i
1571 for j in 1 2 3 4 5; do
1572 ovs-vsctl add-port br-int vif$i$j -- \
1573 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1574 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1575 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1579 ls_name=$(lsp_to_ls $lsp_name)
1581 ovn-nbctl lsp-add $ls_name $lsp_name
1582 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1583 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1585 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1588 ovn-nbctl --wait=sb sync
1589 ovn-sbctl dump-flows
1593 # XXX This is now the 3rd copy of these functions in this file ...
1595 # Given the name of a logical port, prints the name of the hypervisor
1596 # on which it is located.
1601 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1603 # This shell function causes a packet to be received on INPORT. The packet's
1604 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1605 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1606 # logical switch port numbers, e.g. 11 for vif11.
1608 # EOUT is the end-to-end output port, that is, where the packet will end up
1609 # after possibly bouncing through one or more localnet ports. LOUT is the
1610 # logical output port, which might be a localnet port, as seen by ovn-trace
1611 # (which doesn't know what localnet ports are connected to and therefore can't
1612 # figure out the end-to-end answer).
1614 for j in 1 2 3 4 5; do
1619 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1622 # First try tracing the packet.
1623 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1624 if test $lout != drop; then
1625 echo "output(\"$lout\");"
1627 AT_CAPTURE_FILE([trace])
1628 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1630 # Then actually send a packet, for an end-to-end test.
1631 local packet=$(echo $dst$src | sed 's/://g')${eth}
1632 hv=`vif_to_hv $inport`
1634 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1635 if test $eout != drop; then
1636 echo $packet >> ${eout#lp}.expected
1640 # lp11 and lp21 are on the same network (phys, untagged)
1641 # and on different hypervisors
1642 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1643 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1645 # lp11 and lp12 are on the same network (phys, untagged)
1646 # and on the same hypervisor
1647 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1648 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1650 # lp13 and lp23 are on the same network (phys, VLAN 101)
1651 # and on different hypervisors
1652 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1653 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1655 # lp13 and lp14 are on the same network (phys, VLAN 101)
1656 # and on the same hypervisor
1657 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1658 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1660 # lp11 and lp15 are on the same network (phys, untagged),
1661 # same hypervisor, and on different switches
1662 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1663 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1665 # lp11 and lp25 are on the same network (phys, untagged),
1666 # different hypervisors, and on different switches
1667 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1668 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1670 # Ports that should not be able to communicate
1671 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1672 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1673 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1674 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1675 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1676 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1677 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1678 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1680 # Dump a bunch of info helpful for debugging if there's a failure.
1682 echo "------ OVN dump ------"
1686 echo "------ hv1 dump ------"
1687 as hv1 ovs-vsctl show
1688 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1690 echo "------ hv2 dump ------"
1691 as hv2 ovs-vsctl show
1692 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1694 # Now check the packets actually received against the ones expected.
1696 for j in 1 2 3 4 5; do
1697 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1701 OVN_CLEANUP([hv1],[hv2])
1705 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1707 AT_SKIP_IF([test $HAVE_PYTHON = no])
1710 # Configure the Northbound database
1711 ovn-nbctl ls-add lsw0
1713 ovn-nbctl lsp-add lsw0 lp1
1714 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1716 ovn-nbctl lsp-add lsw0 lp2
1717 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1719 ovn-nbctl lsp-add lsw0 lp-vtep
1720 ovn-nbctl lsp-set-type lp-vtep vtep
1721 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1722 ovn-nbctl lsp-set-addresses lp-vtep unknown
1724 # lpr, lr and lrp1 are used for the ARP request handling test only.
1725 ovn-nbctl lsp-add lsw0 lpr
1727 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1728 ovn-nbctl set Logical_Switch_Port lpr type=router \
1729 options:router-port=lrp1 \
1730 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1733 net_add n1 # Network to connect hv1, hv2, and vtep
1734 net_add n2 # Network to connect vtep and hv3
1736 # Create hypervisor hv1 connected to n1
1739 ovs-vsctl add-br br-phys
1740 ovn_attach n1 br-phys 192.168.0.1
1741 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
1743 # Create hypervisor hv2 connected to n1
1746 ovs-vsctl add-br br-phys
1747 ovn_attach n1 br-phys 192.168.0.2
1748 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
1751 # Start the vtep emulator with a leg in both networks
1755 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1756 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1758 ovs-vsctl add-br br-phys
1759 net_attach n1 br-phys
1761 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1762 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1763 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1764 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1766 ovs-vsctl add-br br-vtep
1767 net_attach n2 br-vtep
1769 vtep-ctl add-ps br-vtep
1770 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1771 vtep-ctl add-ls lsw0
1773 start_daemon ovs-vtep br-vtep
1774 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1776 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1778 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1780 # It takes more time for the update to be processed by ovs-vtep.
1783 # Add hv3 on the other side of the vtep
1786 ovs-vsctl add-br br-phys
1787 net_attach n2 br-phys
1789 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
1791 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1792 # packets for ARP resolution (native tunneling doesn't queue packets
1793 # for ARP resolution).
1796 # Allow some time for ovn-northd and ovn-controller to catch up.
1797 # XXX This should be more systematic.
1800 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1802 # This shell function causes a packet to be received on INPORT. The packet's
1803 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1804 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1805 # more) list the VIFs on which the packet should be received. INPORT and the
1806 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
1811 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1812 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1815 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1817 echo $packet >> $outport.expected
1821 # Send packets between all pairs of source and destination ports:
1823 # 1. Unicast packets are delivered to exactly one logical switch port
1824 # (except that packets destined to their input ports are dropped).
1826 # 2. Broadcast and multicast are delivered to all logical switch ports
1827 # except the input port.
1829 # 3. The switch delivers packets with an unknown destination to logical
1830 # switch ports with "unknown" among their MAC addresses (and port
1831 # security disabled).
1836 if test $d != $s; then unicast=$d; else unicast=; fi
1837 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1839 # The vtep (vif3) is the only one configured for "unknown"
1840 if test $d != $s && test $d = 3; then
1841 unknown="$unknown $d"
1843 bcast="$bcast $unicast"
1846 # Broadcast and multicast.
1847 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1848 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
1850 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1853 # ARP request should not be responded to by logical switch router
1854 # type arp responder on HV1 and HV2 and should reach directly to
1857 printf "%02x%02x%02x%02x" "$@"
1860 spa=`ip_to_hex 192 168 1 2`
1861 tpa=`ip_to_hex 192 168 1 1`
1862 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1863 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1864 echo $request >> 1.expected
1865 echo $request >> 2.expected
1867 # dump information with counters
1868 echo "------ OVN dump ------"
1872 echo "---------SB dump-----"
1873 ovn-sbctl list datapath_binding
1874 echo "---------------------"
1875 ovn-sbctl list port_binding
1876 echo "---------------------"
1877 ovn-sbctl dump-flows
1879 echo "------ hv1 dump ------"
1880 as hv1 ovs-vsctl show
1881 as hv1 ovs-ofctl -O OpenFlow13 show br-int
1882 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1884 echo "------ hv2 dump ------"
1885 as hv2 ovs-vsctl show
1886 as hv2 ovs-ofctl -O OpenFlow13 show br-int
1887 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1889 echo "------ hv3 dump ------"
1890 as hv3 ovs-vsctl show
1891 # note: hv3 has no logical port bind, thus it should not have br-int
1892 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1893 [ovs-ofctl: br-int is not a bridge or a socket
1896 # Now check the packets actually received against the ones expected.
1898 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
1901 # Gracefully terminate daemons
1902 OVN_CLEANUP([hv1],[hv2],[vtep])
1903 OVN_CLEANUP_VSWITCH([hv3])
1907 # Similar test to "hardware GW"
1908 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1909 AT_SKIP_IF([test $HAVE_PYTHON = no])
1912 # Configure the Northbound database
1913 ovn-nbctl ls-add lsw0
1915 ovn-nbctl lsp-add lsw0 lp1
1916 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1918 ovn-nbctl lsp-add lsw0 lp2
1919 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1921 ovn-nbctl lsp-add lsw0 lp-gw
1922 ovn-nbctl lsp-set-type lp-gw l2gateway
1923 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
1924 ovn-nbctl lsp-set-addresses lp-gw unknown
1926 net_add n1 # Network to connect hv1, hv2, and gw
1927 net_add n2 # Network to connect gw and hv3
1929 # Create hypervisor hv1 connected to n1
1932 ovs-vsctl add-br br-phys
1933 ovn_attach n1 br-phys 192.168.0.1
1934 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
1936 # Create hypervisor hv2 connected to n1
1939 ovs-vsctl add-br br-phys
1940 ovn_attach n1 br-phys 192.168.0.2
1941 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
1943 # Create hypervisor hv_gw connected to n1 and n2
1944 # connect br-phys bridge to n1; connect hv-gw bridge to n2
1947 ovs-vsctl add-br br-phys
1948 ovn_attach n1 br-phys 192.168.0.3
1949 ovs-vsctl add-br br-phys2
1950 net_attach n2 br-phys2
1951 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
1953 # Add hv3 on the other side of the GW
1956 ovs-vsctl add-br br-phys
1957 net_attach n2 br-phys
1958 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
1961 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1962 # packets for ARP resolution (native tunneling doesn't queue packets
1963 # for ARP resolution).
1966 # Allow some time for ovn-northd and ovn-controller to catch up.
1967 # XXX This should be more systematic.
1970 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1972 # This shell function causes a packet to be received on INPORT. The packet's
1973 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1974 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1975 # more) list the VIFs on which the packet should be received. INPORT and the
1976 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
1981 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1982 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1985 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1987 echo $packet >> $outport.expected
1991 # Send packets between all pairs of source and destination ports:
1993 # 1. Unicast packets are delivered to exactly one lport (except that packets
1994 # destined to their input ports are dropped).
1996 # 2. Broadcast and multicast are delivered to all lports except the input port.
1998 # 3. The lswitch delivers packets with an unknown destination to lports with
1999 # "unknown" among their MAC addresses (and port security disabled).
2004 if test $d != $s; then unicast=$d; else unicast=; fi
2005 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2007 # The vtep (vif3) is the only one configured for "unknown"
2008 if test $d != $s && test $d = 3; then
2009 unknown="$unknown $d"
2011 bcast="$bcast $unicast"
2014 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2015 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2016 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2019 echo "------ ovn-nbctl show ------"
2021 echo "------ ovn-sbctl show ------"
2024 echo "------ hv1 ------"
2025 as hv1 ovs-vsctl show
2026 echo "------ hv1 br-int ------"
2027 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2028 echo "------ hv1 br-phys ------"
2029 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2031 echo "------ hv2 ------"
2032 as hv2 ovs-vsctl show
2033 echo "------ hv2 br-int ------"
2034 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2035 echo "------ hv2 br-phys ------"
2036 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2038 echo "------ hv_gw ------"
2039 as hv_gw ovs-vsctl show
2040 echo "------ hv_gw br-phys ------"
2041 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2042 echo "------ hv_gw br-phys2 ------"
2043 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2045 echo "------ hv3 ------"
2046 as hv3 ovs-vsctl show
2047 echo "------ hv3 br-phys ------"
2048 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2050 # Now check the packets actually received against the ones expected.
2052 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2056 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2057 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2058 AT_SKIP_IF([test $HAVE_PYTHON = no])
2063 # Three logical switches ls1, ls2, ls3.
2064 # One logical router lr0 connected to ls[123],
2065 # with nine subnets, three per logical switch:
2067 # lrp11 on ls1 for subnet 192.168.11.0/24
2068 # lrp12 on ls1 for subnet 192.168.12.0/24
2069 # lrp13 on ls1 for subnet 192.168.13.0/24
2071 # lrp33 on ls3 for subnet 192.168.33.0/24
2073 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2074 # digits are the subnet and the last digit distinguishes the VIF.
2076 ovn-nbctl ls-add ls$i
2079 # Add "unknown" to MAC addresses for lp?11, so packets for
2080 # MAC-IP bindings discovered via ARP later have somewhere to go.
2081 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2084 -- lsp-add ls$i lp$i$j$k \
2085 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2086 192.168.$i$j.$k" $unknown
2091 ovn-nbctl lr-add lr0
2094 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2096 -- lsp-add ls$i lrp$i$j-attachment \
2097 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2098 options:router-port=lrp$i$j \
2099 addresses='"00:00:00:00:ff:'$i$j'"'
2103 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2104 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2108 # Three hypervisors hv[123].
2109 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2110 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2111 # lp?3[123] all on hv3.
2114 # Given the name of a logical port, prints the name of the hypervisor
2115 # on which it is located.
2118 ?11) echo 1 ;; dnl (
2119 ?12 | ?21 | ?22) echo 2 ;; dnl (
2120 ?13 | ?23 | ?3?) echo 3 ;;
2124 # Given the name of a logical port, prints the name of its logical router
2125 # port, e.g. "vif_to_lrp 123" yields 12.
2130 # Given the name of a logical port, prints the name of its logical
2131 # switch, e.g. "vif_to_ls 123" yields 1.
2140 ovs-vsctl add-br br-phys
2141 ovn_attach n1 br-phys 192.168.0.$i
2146 hv=`vif_to_hv $i$j$k`
2147 as hv$hv ovs-vsctl \
2148 -- add-port br-int vif$i$j$k \
2149 -- set Interface vif$i$j$k \
2150 external-ids:iface-id=lp$i$j$k \
2151 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2152 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2153 ofport-request=$i$j$k
2158 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2159 # packets for ARP resolution (native tunneling doesn't queue packets
2160 # for ARP resolution).
2163 # Allow some time for ovn-northd and ovn-controller to catch up.
2164 # XXX This should be more systematic.
2167 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2169 # This shell function causes a packet to be received on INPORT. The packet's
2170 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2171 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2172 # more) list the VIFs on which the packet should be received. INPORT and the
2173 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2182 # This packet has bad checksums but logical L3 routing doesn't check.
2183 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2184 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2185 shift; shift; shift; shift; shift
2186 hv=hv`vif_to_hv $inport`
2187 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2188 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2189 in_ls=`vif_to_ls $inport`
2190 in_lrp=`vif_to_lrp $inport`
2192 out_ls=`vif_to_ls $outport`
2193 if test $in_ls = $out_ls; then
2194 # Ports on the same logical switch receive exactly the same packet.
2197 # Routing decrements TTL and updates source and dest MAC
2199 out_lrp=`vif_to_lrp $outport`
2200 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2201 fi >> $outport.expected
2205 as hv1 ovs-vsctl --columns=name,ofport list interface
2206 as hv1 ovn-sbctl list port_binding
2207 as hv1 ovn-sbctl list datapath_binding
2208 as hv1 ovn-sbctl dump-flows
2209 as hv1 ovs-ofctl dump-flows br-int
2211 # Send IP packets between all pairs of source and destination ports:
2213 # 1. Unicast IP packets are delivered to exactly one logical switch port
2214 # (except that packets destined to their input ports are dropped).
2216 # 2. Broadcast IP packets are delivered to all logical switch ports
2217 # except the input port.
2219 printf "%02x%02x%02x%02x" "$@"
2227 sip=`ip_to_hex 192 168 $is$js $ks`
2232 dip=`ip_to_hex 192 168 $id$jd $kd`
2233 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2234 if test $d != $s; then unicast=$d; else unicast=; fi
2236 test_ip $s $smac $dmac $sip $dip $unicast #1
2238 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2242 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2247 # 3. Send an IP packet from every logical port to every other subnet,
2248 # to an IP address that does not have a static IP-MAC binding.
2249 # This should generate a broadcast ARP request for the destination
2250 # IP address in the destination subnet.
2256 sip=`ip_to_hex 192 168 $is$js $ks`
2259 if test $is$js = $id$jd; then
2264 dmac=00000000ff$is$js
2265 # Calculate a 4th octet for the destination that is
2266 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2267 # that have static MAC bindings, and fits in the range
2269 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2270 dip=`ip_to_hex 192 168 $id$jd $o4`
2271 test_ip $s $smac $dmac $sip $dip
2273 # Every LP on the destination subnet's lswitch should
2274 # receive the ARP request.
2275 lrmac=00000000ff$id$jd
2276 lrip=`ip_to_hex 192 168 $id$jd 254`
2277 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2278 for jd2 in 1 2 3; do
2280 echo $arp >> $id$jd2$kd.expected
2289 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2291 # Causes a packet to be received on INPORT. The packet is an ARP
2292 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2293 # it should be the hardware address of the target to expect to receive in an
2294 # ARP reply; otherwise no reply is expected.
2296 # INPORT is an logical switch port number, e.g. 11 for vif11.
2297 # SHA and REPLY_HA are each 12 hex digits.
2298 # SPA and TPA are each 8 hex digits.
2300 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2301 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2302 hv=hv`vif_to_hv $inport`
2303 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2304 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2306 # Expect to receive the broadcast ARP on the other logical switch ports if
2307 # IP address is not configured to the switch patch port.
2308 local i=`vif_to_ls $inport`
2312 # 192.168.33.254 is configured to the switch patch port for lrp33,
2313 # so no ARP flooding expected for it.
2314 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2315 echo $request >> $i$j$k.expected
2320 # Expect to receive the reply, if any.
2321 if test X$reply_ha != X; then
2322 lrp=`vif_to_lrp $inport`
2323 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2324 echo $reply >> $inport.expected
2328 # Test router replies to ARP requests from all source ports:
2330 # 4. Router replies to query for its MAC address from port's own IP address.
2332 # 5. Router replies to query for its MAC address from any random IP address
2335 # 6. Router replies to query for its MAC address from another subnet.
2337 # 7. No reply to query for IP address other than router IP.
2341 smac=f00000000$i$j$k # Source MAC
2342 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2343 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2344 rmac=00000000ff$i$j # Router MAC
2345 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2346 test_arp $i$j$k $smac $sip $rip $rmac #4
2347 test_arp $i$j$k $smac $otherip $rip $rmac #5
2348 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2349 test_arp $i$j$k $smac $sip $otherip #7
2354 # Allow some time for packet forwarding.
2355 # XXX This can be improved.
2358 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2361 # Here, the $s is the VIF that originated the ARP request and $d is
2362 # the VIF that sends the ARP reply, which is somewhat backward but
2363 # it means that $s and $d are the same as #3.
2364 : > mac_bindings.expected
2371 if test $is$js = $id$jd; then
2378 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2379 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2380 host_mac=8000000000$o4
2382 lrmac=00000000ff$id$jd
2383 lrip=`ip_to_hex 192 168 $id$jd 254`
2385 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2391 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2392 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2393 #as $hv ovs-ofctl dump-flows br-int table=19
2395 host_ip_pretty=192.168.$id$jd.$o4
2396 host_mac_pretty=80:00:00:00:00:$o4
2397 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2404 # Allow some time for packet forwarding.
2405 # XXX This can be improved.
2408 # 9. Send an IP packet from every logical port to every other subnet. These
2409 # are the same packets already sent as #3, but now the destinations' IP-MAC
2410 # bindings have been discovered via ARP, so instead of provoking an ARP
2411 # request, these packets now get routed to their destinations (which don't
2412 # have static MAC bindings, so they go to the port we've designated as
2413 # accepting "unknown" MACs.)
2419 sip=`ip_to_hex 192 168 $is$js $ks`
2422 if test $is$js = $id$jd; then
2427 dmac=00000000ff$is$js
2428 # Calculate a 4th octet for the destination that is
2429 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2430 # that have static MAC bindings, and fits in the range
2432 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2433 dip=`ip_to_hex 192 168 $id$jd $o4`
2434 test_ip $s $smac $dmac $sip $dip
2436 # Expect the packet egress.
2437 host_mac=8000000000$o4
2440 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2447 ovn-sbctl -f csv -d bare --no-heading \
2448 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2450 # Now check the packets actually received against the ones expected.
2454 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2460 # Check the MAC bindings against those expected.
2461 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2464 # Gracefully terminate daemons
2465 OVN_CLEANUP([hv1], [hv2], [hv3])
2469 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2470 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2471 AT_SKIP_IF([test $HAVE_PYTHON = no])
2474 # Create hypervisors hv[123].
2475 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2476 # Add all of the vifs to a single logical switch lsw0.
2477 # Turn off port security on vifs vif[123]1
2478 # Turn on l2 port security on vifs vif[123]2
2479 # Turn of l2 and l3 port security on vifs vif[123]3
2480 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2481 ovn-nbctl ls-add lsw0
2486 ovs-vsctl add-br br-phys
2487 ovn_attach n1 br-phys 192.168.0.$i
2490 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
2491 ovn-nbctl lsp-add lsw0 lp$i$j
2492 if test $j = 1; then
2493 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2494 elif test $j = 2; then
2495 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2496 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2498 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2499 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2500 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2505 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2506 # packets for ARP resolution (native tunneling doesn't queue packets
2507 # for ARP resolution).
2510 # Allow some time for ovn-northd and ovn-controller to catch up.
2511 # XXX This should be more systematic.
2514 # Given the name of a logical port, prints the name of the hypervisor
2515 # on which it is located.
2526 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2528 # This shell function causes an ip packet to be received on INPORT.
2529 # The packet's content has Ethernet destination DST and source SRC
2530 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2531 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2532 # be received. INPORT and the OUTPORTs are specified as logical switch
2533 # port numbers, e.g. 11 for vif11.
2535 # This packet has bad checksums but logical L3 routing doesn't check.
2536 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2537 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2538 shift; shift; shift; shift; shift
2539 hv=`vif_to_hv $inport`
2540 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2541 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2543 echo $packet >> $outport.expected
2547 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2549 # Causes a packet to be received on INPORT. The packet is an ARP
2550 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2551 # it should be the hardware address of the target to expect to receive in an
2552 # ARP reply; otherwise no reply is expected.
2554 # INPORT is an logical switch port number, e.g. 11 for vif11.
2555 # SHA and REPLY_HA are each 12 hex digits.
2556 # SPA and TPA are each 8 hex digits.
2558 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2559 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2560 hv=`vif_to_hv $inport`
2561 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2562 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2563 if test $drop != 1; then
2564 if test X$reply_ha = X; then
2565 # Expect to receive the broadcast ARP on the other logical switch ports
2566 # if no reply is expected.
2570 if test $i$j != $inport; then
2571 echo $request >> $i$j.expected
2576 # Expect to receive the reply, if any.
2577 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2578 echo $reply >> $inport.expected
2583 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2584 # This function is similar to test_ip() except that it sends
2587 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2588 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2589 shift; shift; shift; shift; shift
2590 hv=`vif_to_hv $inport`
2591 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2592 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2594 echo $packet >> $outport.expected
2598 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2599 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2600 # of the test packet
2602 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2603 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2604 shift; shift; shift; shift; shift; shift
2605 hv=`vif_to_hv $inport`
2606 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2607 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2609 echo $packet >> $outport.expected
2614 printf "%02x%02x%02x%02x" "$@"
2618 sip=`ip_to_hex 192 168 0 12`
2619 tip=`ip_to_hex 192 168 0 13`
2620 # the arp packet should be allowed even if lp[123]1 is
2621 # not configured with mac f00000000023 and ip 192.168.0.12
2623 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2625 if test $i != $j; then
2626 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2632 sip=`ip_to_hex 192 168 0 12`
2633 tip=`ip_to_hex 192 168 0 13`
2635 # arp packet should be allowed since lp22 is configured with
2637 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2639 # arp packet should not be allowed since lp32 is not configured with
2641 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2643 # arp packet with sha set to f00000000021 should not be allowed
2645 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2647 # ip packets should be allowed and received since lp[123]2 do not
2648 # have l3 port security
2649 sip=`ip_to_hex 192 168 0 55`
2650 tip=`ip_to_hex 192 168 0 66`
2653 if test $i != $j; then
2654 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2659 # ipv6 packets should be received by lp[123]2
2660 # lp[123]1 can send ipv6 traffic as there is no port security
2661 sip=fe800000000000000000000000000000
2662 tip=ff020000000000000000000000000000
2665 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2669 # l2 and l3 port security
2670 sip=`ip_to_hex 192 168 0 13`
2671 tip=`ip_to_hex 192 168 0 22`
2672 # arp packet should be allowed since lp13 is configured with
2673 # f00000000013 and 192.168.0.13
2674 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2676 # the arp packet should be dropped because lp23 is not configured
2677 # with mac f00000000022
2678 sip=`ip_to_hex 192 168 0 13`
2679 tip=`ip_to_hex 192 168 0 22`
2680 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2682 # the arp packet should be dropped because lp33 is not configured
2683 # with ip 192.168.0.55
2684 spa=`ip_to_hex 192 168 0 55`
2685 tpa=`ip_to_hex 192 168 0 22`
2686 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2688 # ip packets should not be received by lp[123]3 since
2689 # l3 port security is enabled
2690 sip=`ip_to_hex 192 168 0 55`
2691 tip=`ip_to_hex 192 168 0 66`
2694 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2698 # ipv6 packets should be dropped for lp[123]3 since
2699 # it is configured with only ipv4 address
2700 sip=fe800000000000000000000000000000
2701 tip=ff020000000000000000000000000000
2704 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2707 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2708 # lp[123]1 can send ipv6 traffic as there is no port security
2710 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2713 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2714 # fe80::ea2a:eaff:fe28:0012
2716 # ipv4 packet should be dropped for lp13 with mac f0000000113
2717 sip=`ip_to_hex 192 168 0 13`
2718 tip=`ip_to_hex 192 168 0 23`
2719 test_ip 13 f00000000113 f00000000023 $sip $tip
2721 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2722 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2723 # lp11 can send ipv6 traffic as there is no port security
2724 sip=ee800000000000000000000000000000
2726 tip=fe80000000000000ea2aeafffe2800${i}3
2727 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2731 # ipv6 packet should not be received by lp33 with mac f0000000333
2732 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2733 # configured with fe80::ea2a:eaff:fe28:0033
2734 # lp11 can send ipv6 traffic as there is no port security
2736 sip=ee800000000000000000000000000000
2737 tip=fe80000000000000ea2aeafffe280023
2738 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2740 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2741 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2742 # and should be dropped for any other ip6.src
2743 # lp21 can receive ipv6 traffic as there is no port security
2745 tip=ee800000000000000000000000000000
2747 sip=fe80000000000000ea2aeafffe2800${i}3
2748 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2750 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2751 sip=00000000000000000000000000000000
2752 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2753 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2754 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2755 # Traffic to non-multicast traffic should be dropped
2756 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2757 # Traffic of other ICMPv6 types should be dropped
2758 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2761 sip=ae80000000000000ea2aeafffe2800aa
2762 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2765 # configure lsp13 to send and received IPv4 packets with an address range
2766 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"
2770 sip=`ip_to_hex 10 0 0 13`
2771 tip=`ip_to_hex 192 168 0 22`
2772 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2773 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2775 sip=`ip_to_hex 10 0 0 14`
2776 tip=`ip_to_hex 192 168 0 23`
2777 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2778 # with dst ip 192.168.0.23 should be allowed
2779 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2781 sip=`ip_to_hex 192 168 0 33`
2782 tip=`ip_to_hex 10 0 0 15`
2783 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2784 # with dst ip 10.0.0.15 should be received by lsp13
2785 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2787 sip=`ip_to_hex 192 168 0 33`
2788 tip=`ip_to_hex 20 0 0 4`
2789 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2790 # with dst ip 20.0.0.4 should be received by lsp13
2791 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2793 sip=`ip_to_hex 192 168 0 33`
2794 tip=`ip_to_hex 20 0 0 5`
2795 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2796 # with dst ip 20.0.0.5 should not be received by lsp13
2797 test_ip 33 f00000000033 f00000000013 $sip $tip
2799 sip=`ip_to_hex 192 168 0 33`
2800 tip=`ip_to_hex 20 0 0 255`
2801 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2802 # with dst ip 20.0.0.255 should be received by lsp13
2803 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2805 sip=`ip_to_hex 192 168 0 33`
2806 tip=`ip_to_hex 192 168 0 255`
2807 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2808 # with dst ip 192.168.0.255 should not be received by lsp13
2809 test_ip 33 f00000000033 f00000000013 $sip $tip
2811 sip=`ip_to_hex 192 168 0 33`
2812 tip=`ip_to_hex 224 0 0 4`
2813 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2814 # with dst ip 224.0.0.4 should be received by lsp13
2815 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2817 #dump information including flow counters
2819 ovn-sbctl dump-flows -- list multicast_group
2821 echo "------ hv1 dump ------"
2822 as hv1 ovs-vsctl show
2823 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2824 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2826 echo "------ hv2 dump ------"
2827 as hv2 ovs-vsctl show
2828 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2829 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2831 echo "------ hv3 dump ------"
2832 as hv3 ovs-vsctl show
2833 as hv3 ovs-ofctl -O OpenFlow13 show br-int
2834 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2836 # Now check the packets actually received against the ones expected.
2839 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2843 OVN_CLEANUP([hv1],[hv2],[hv3])
2847 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2848 AT_SKIP_IF([test $HAVE_PYTHON = no])
2852 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2853 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2854 # R2 has ls2 (172.16.1.0/24) connected to it.
2856 ls1_lp1_mac="f0:00:00:01:02:03"
2857 rp_ls1_mac="00:00:00:01:02:03"
2858 rp_ls2_mac="00:00:00:01:02:04"
2859 ls2_lp1_mac="f0:00:00:01:02:04"
2861 ls1_lp1_ip="192.168.1.2"
2862 ls2_lp1_ip="172.16.1.2"
2867 ovn-nbctl ls-add ls1
2868 ovn-nbctl ls-add ls2
2871 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
2873 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2874 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
2877 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
2879 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
2880 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
2883 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
2884 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
2886 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
2887 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
2889 # Create logical port ls1-lp1 in ls1
2890 ovn-nbctl lsp-add ls1 ls1-lp1 \
2891 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
2893 # Create logical port ls2-lp1 in ls2
2894 ovn-nbctl lsp-add ls2 ls2-lp1 \
2895 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
2897 # Create two hypervisor and create OVS ports corresponding to logical ports.
2902 ovs-vsctl add-br br-phys
2903 ovn_attach n1 br-phys 192.168.0.1
2904 ovs-vsctl -- add-port br-int hv1-vif1 -- \
2905 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2906 options:tx_pcap=hv1/vif1-tx.pcap \
2907 options:rxq_pcap=hv1/vif1-rx.pcap \
2912 ovs-vsctl add-br br-phys
2913 ovn_attach n1 br-phys 192.168.0.2
2914 ovs-vsctl -- add-port br-int hv2-vif1 -- \
2915 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
2916 options:tx_pcap=hv2/vif1-tx.pcap \
2917 options:rxq_pcap=hv2/vif1-rx.pcap \
2921 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2922 # packets for ARP resolution (native tunneling doesn't queue packets
2923 # for ARP resolution).
2926 # Allow some time for ovn-northd and ovn-controller to catch up.
2927 # XXX This should be more systematic.
2931 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
2932 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
2933 udp && udp.src==53 && udp.dst==4369"
2934 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
2937 echo "---------NB dump-----"
2939 echo "---------------------"
2940 ovn-nbctl list logical_router
2941 echo "---------------------"
2942 ovn-nbctl list logical_router_port
2943 echo "---------------------"
2945 echo "---------SB dump-----"
2946 ovn-sbctl list datapath_binding
2947 echo "---------------------"
2948 ovn-sbctl list port_binding
2949 echo "---------------------"
2951 echo "------ hv1 dump ----------"
2952 as hv1 ovs-ofctl show br-int
2953 as hv1 ovs-ofctl dump-flows br-int
2954 echo "------ hv2 dump ----------"
2955 as hv2 ovs-ofctl show br-int
2956 as hv2 ovs-ofctl dump-flows br-int
2959 # The TTL should be decremented by 2.
2960 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
2961 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
2962 udp && udp.src==53 && udp.dst==4369"
2963 echo $packet | ovstest test-ovn expr-to-packets > expected
2965 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
2967 OVN_CLEANUP([hv1],[hv2])
2972 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
2973 AT_KEYWORDS([router-admin-state])
2974 AT_SKIP_IF([test $HAVE_PYTHON = no])
2978 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
2979 # and 172.16.1.0/24) connected to it.
2983 ovn-nbctl ls-add ls1
2986 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
2987 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2988 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
2990 # Create logical port ls1-lp1 in ls1
2991 ovn-nbctl lsp-add ls1 ls1-lp1 \
2992 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
2994 # Create logical port ls1-lp2 in ls1
2995 ovn-nbctl lsp-add ls1 ls1-lp2 \
2996 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
2998 # Create one hypervisor and create OVS ports corresponding to logical ports.
3003 ovs-vsctl add-br br-phys
3004 ovn_attach n1 br-phys 192.168.0.1
3005 ovs-vsctl -- add-port br-int vif1 -- \
3006 set interface vif1 external-ids:iface-id=ls1-lp1 \
3007 options:tx_pcap=hv1/vif1-tx.pcap \
3008 options:rxq_pcap=hv1/vif1-rx.pcap \
3011 ovs-vsctl -- add-port br-int vif2 -- \
3012 set interface vif2 external-ids:iface-id=ls1-lp2 \
3013 options:tx_pcap=hv1/vif2-tx.pcap \
3014 options:rxq_pcap=hv1/vif2-rx.pcap \
3018 # Allow some time for ovn-northd and ovn-controller to catch up.
3019 # XXX This should be more systematic.
3022 # Send ip packets between the two ports.
3024 printf "%02x%02x%02x%02x" "$@"
3028 src_mac="f00000010203"
3029 dst_mac="000000010203"
3030 src_ip=`ip_to_hex 192 168 1 2`
3031 dst_ip=`ip_to_hex 172 16 1 2`
3032 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3033 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3036 echo "---------NB dump-----"
3038 echo "---------------------"
3039 ovn-nbctl list logical_router
3040 echo "---------------------"
3041 ovn-nbctl list logical_router_port
3042 echo "---------------------"
3044 echo "---------SB dump-----"
3045 ovn-sbctl list datapath_binding
3046 echo "---------------------"
3047 ovn-sbctl list logical_flow
3048 echo "---------------------"
3050 echo "------ hv1 dump ----------"
3051 as hv1 ovs-ofctl dump-flows br-int
3055 ovn-nbctl set Logical_Router R1 enabled=false
3057 # Allow some time for ovn-northd and ovn-controller to catch up.
3058 # XXX This should be more systematic.
3061 echo "---------SB dump-----"
3062 ovn-sbctl list datapath_binding
3063 echo "---------------------"
3064 ovn-sbctl list logical_flow
3065 echo "---------------------"
3067 echo "------ hv1 dump ----------"
3068 as hv1 ovs-ofctl dump-flows br-int
3070 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3073 expect_src_mac="000000010203"
3074 expect_dst_mac="f00000010204"
3075 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3077 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3081 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3082 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3083 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3086 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3089 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3092 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3095 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3096 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3101 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3102 AT_KEYWORDS([router-admin-state])
3103 AT_SKIP_IF([test $HAVE_PYTHON = no])
3107 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3108 # and has switch ls2 (172.16.1.0/24) connected to it.
3112 ovn-nbctl ls-add ls1
3113 ovn-nbctl ls-add ls2
3116 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3117 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3118 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3121 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3122 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3123 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3125 # Create logical port ls1-lp1 in ls1
3126 ovn-nbctl lsp-add ls1 ls1-lp1 \
3127 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3129 # Create logical port ls2-lp1 in ls2
3130 ovn-nbctl lsp-add ls2 ls2-lp1 \
3131 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3133 # Create one hypervisor and create OVS ports corresponding to logical ports.
3138 ovs-vsctl add-br br-phys
3139 ovn_attach n1 br-phys 192.168.0.1
3140 ovs-vsctl -- add-port br-int vif1 -- \
3141 set interface vif1 external-ids:iface-id=ls1-lp1 \
3142 options:tx_pcap=hv1/vif1-tx.pcap \
3143 options:rxq_pcap=hv1/vif1-rx.pcap \
3146 ovs-vsctl -- add-port br-int vif2 -- \
3147 set interface vif2 external-ids:iface-id=ls2-lp1 \
3148 options:tx_pcap=hv1/vif2-tx.pcap \
3149 options:rxq_pcap=hv1/vif2-rx.pcap \
3153 # Allow some time for ovn-northd and ovn-controller to catch up.
3154 # XXX This should be more systematic.
3157 # Send ip packets between the two ports.
3159 printf "%02x%02x%02x%02x" "$@"
3163 src_mac="f00000010203"
3164 dst_mac="000000010203"
3165 src_ip=`ip_to_hex 192 168 1 2`
3166 dst_ip=`ip_to_hex 172 16 1 2`
3167 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3168 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3171 echo "---------NB dump-----"
3173 echo "---------------------"
3174 ovn-nbctl list logical_router
3175 echo "---------------------"
3176 ovn-nbctl list logical_router_port
3177 echo "---------------------"
3179 echo "---------SB dump-----"
3180 ovn-sbctl list datapath_binding
3181 echo "---------------------"
3182 ovn-sbctl list logical_flow
3183 echo "---------------------"
3185 echo "------ hv1 dump ----------"
3186 as hv1 ovs-ofctl dump-flows br-int
3189 ovn-nbctl set Logical_Router R1 enabled=false
3191 echo "---------SB dump-----"
3192 ovn-sbctl list datapath_binding
3193 echo "---------------------"
3194 ovn-sbctl list logical_flow
3195 echo "---------------------"
3197 echo "------ hv1 dump ----------"
3198 as hv1 ovs-ofctl dump-flows br-int
3200 # Allow some time for the disabling of logical router R1 to propagate.
3201 # XXX This should be more systematic.
3204 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3207 expect_src_mac="000000010204"
3208 expect_dst_mac="f00000010204"
3209 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3211 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3217 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3218 AT_SKIP_IF([test $HAVE_PYTHON = no])
3222 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3223 # network. R1 has switchess foo (192.168.1.0/24)
3225 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3230 ovn-nbctl ls-add foo
3231 ovn-nbctl ls-add alice
3232 ovn-nbctl ls-add bob
3235 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3236 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3237 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3239 # Connect alice to R2
3240 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3241 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3242 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3245 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3246 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3247 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3250 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3251 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3253 #install static routes
3254 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3255 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3256 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3258 # Create logical port foo1 in foo
3259 ovn-nbctl lsp-add foo foo1 \
3260 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3262 # Create logical port alice1 in alice
3263 ovn-nbctl lsp-add alice alice1 \
3264 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3266 # Create logical port bob1 in bob
3267 ovn-nbctl lsp-add bob bob1 \
3268 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3270 # Create two hypervisor and create OVS ports corresponding to logical ports.
3275 ovs-vsctl add-br br-phys
3276 ovn_attach n1 br-phys 192.168.0.1
3277 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3278 set interface hv1-vif1 external-ids:iface-id=foo1 \
3279 options:tx_pcap=hv1/vif1-tx.pcap \
3280 options:rxq_pcap=hv1/vif1-rx.pcap \
3283 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3284 set interface hv1-vif2 external-ids:iface-id=alice1 \
3285 options:tx_pcap=hv1/vif2-tx.pcap \
3286 options:rxq_pcap=hv1/vif2-rx.pcap \
3291 ovs-vsctl add-br br-phys
3292 ovn_attach n1 br-phys 192.168.0.2
3293 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3294 set interface hv2-vif1 external-ids:iface-id=bob1 \
3295 options:tx_pcap=hv2/vif1-tx.pcap \
3296 options:rxq_pcap=hv2/vif1-rx.pcap \
3300 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3301 # packets for ARP resolution (native tunneling doesn't queue packets
3302 # for ARP resolution).
3305 # Allow some time for ovn-northd and ovn-controller to catch up.
3306 # XXX This should be more systematic.
3310 printf "%02x%02x%02x%02x" "$@"
3313 # Send ip packets between foo1 and alice1
3314 src_mac="f00000010203"
3315 dst_mac="000000010203"
3316 src_ip=`ip_to_hex 192 168 1 2`
3317 dst_ip=`ip_to_hex 172 16 1 2`
3318 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3319 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3321 # Send ip packets between foo1 and bob1
3322 src_mac="f00000010203"
3323 dst_mac="000000010203"
3324 src_ip=`ip_to_hex 192 168 1 2`
3325 dst_ip=`ip_to_hex 172 16 2 2`
3326 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3327 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3329 echo "---------NB dump-----"
3331 echo "---------------------"
3332 ovn-nbctl list logical_router
3333 echo "---------------------"
3334 ovn-nbctl list logical_router_port
3335 echo "---------------------"
3337 echo "---------SB dump-----"
3338 ovn-sbctl list datapath_binding
3339 echo "---------------------"
3340 ovn-sbctl list port_binding
3341 echo "---------------------"
3343 echo "------ hv1 dump ----------"
3344 as hv1 ovs-ofctl dump-flows br-int
3345 echo "------ hv2 dump ----------"
3346 as hv2 ovs-ofctl dump-flows br-int
3348 # Packet to Expect at bob1
3349 src_mac="000000010205"
3350 dst_mac="f00000010205"
3351 src_ip=`ip_to_hex 192 168 1 2`
3352 dst_ip=`ip_to_hex 172 16 2 2`
3353 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3355 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3357 # Packet to Expect at alice1
3358 src_mac="000000010204"
3359 dst_mac="f00000010204"
3360 src_ip=`ip_to_hex 192 168 1 2`
3361 dst_ip=`ip_to_hex 172 16 1 2`
3362 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3364 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3366 OVN_CLEANUP([hv1],[hv2])
3370 AT_SETUP([ovn -- send gratuitous arp on localnet])
3371 AT_SKIP_IF([test $HAVE_PYTHON = no])
3373 ovn-nbctl ls-add lsw0
3381 ovn_attach n1 br-phys 192.168.0.1
3383 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3384 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])
3387 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3388 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3389 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3391 # Create a localnet port.
3392 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3393 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3394 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3395 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3397 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3399 # Wait for packet to be received.
3400 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3401 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3403 # Delete the localnet ports.
3404 AT_CHECK([ovs-vsctl del-port localvif1])
3405 AT_CHECK([ovn-nbctl lsp-del ln_port])
3411 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3412 AT_SKIP_IF([test $HAVE_PYTHON = no])
3416 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3417 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3418 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3425 ovn-nbctl ls-add foo
3426 ovn-nbctl ls-add alice
3427 ovn-nbctl ls-add bob
3428 ovn-nbctl ls-add join
3431 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3432 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3433 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3435 # Connect alice to R2
3436 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3437 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3438 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3441 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3442 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3443 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3445 # Connect R1 to join
3446 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3447 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3448 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3450 # Connect R2 to join
3451 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3452 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3453 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3455 # Connect R3 to join
3456 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3457 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3458 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3460 #install static routes
3461 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3462 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3464 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3465 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3467 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3468 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3470 # Create logical port foo1 in foo
3471 ovn-nbctl lsp-add foo foo1 \
3472 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3474 # Create logical port alice1 in alice
3475 ovn-nbctl lsp-add alice alice1 \
3476 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3478 # Create logical port bob1 in bob
3479 ovn-nbctl lsp-add bob bob1 \
3480 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3482 # Create two hypervisor and create OVS ports corresponding to logical ports.
3487 ovs-vsctl add-br br-phys
3488 ovn_attach n1 br-phys 192.168.0.1
3489 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3490 set interface hv1-vif1 external-ids:iface-id=foo1 \
3491 options:tx_pcap=hv1/vif1-tx.pcap \
3492 options:rxq_pcap=hv1/vif1-rx.pcap \
3495 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3496 set interface hv1-vif2 external-ids:iface-id=alice1 \
3497 options:tx_pcap=hv1/vif2-tx.pcap \
3498 options:rxq_pcap=hv1/vif2-rx.pcap \
3503 ovs-vsctl add-br br-phys
3504 ovn_attach n1 br-phys 192.168.0.2
3505 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3506 set interface hv2-vif1 external-ids:iface-id=bob1 \
3507 options:tx_pcap=hv2/vif1-tx.pcap \
3508 options:rxq_pcap=hv2/vif1-rx.pcap \
3512 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3513 # packets for ARP resolution (native tunneling doesn't queue packets
3514 # for ARP resolution).
3517 # Allow some time for ovn-northd and ovn-controller to catch up.
3518 # XXX This should be more systematic.
3522 printf "%02x%02x%02x%02x" "$@"
3525 # Send ip packets between foo1 and alice1
3526 src_mac="f00000010203"
3527 dst_mac="000001010203"
3528 src_ip=`ip_to_hex 192 168 1 2`
3529 dst_ip=`ip_to_hex 172 16 1 2`
3530 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3531 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3532 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3534 # Send ip packets between foo1 and bob1
3535 src_mac="f00000010203"
3536 dst_mac="000001010203"
3537 src_ip=`ip_to_hex 192 168 1 2`
3538 dst_ip=`ip_to_hex 10 32 1 2`
3539 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3540 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3542 echo "---------NB dump-----"
3544 echo "---------------------"
3545 ovn-nbctl list logical_router
3546 echo "---------------------"
3547 ovn-nbctl list logical_router_port
3548 echo "---------------------"
3550 echo "---------SB dump-----"
3551 ovn-sbctl list datapath_binding
3552 echo "---------------------"
3553 ovn-sbctl list port_binding
3554 echo "---------------------"
3555 ovn-sbctl dump-flows
3556 echo "---------------------"
3558 echo "------ hv1 dump ----------"
3559 as hv1 ovs-ofctl show br-int
3560 as hv1 ovs-ofctl dump-flows br-int
3561 echo "------ hv2 dump ----------"
3562 as hv2 ovs-ofctl show br-int
3563 as hv2 ovs-ofctl dump-flows br-int
3564 echo "----------------------------"
3566 # Packet to Expect at bob1
3567 src_mac="000003010203"
3568 dst_mac="f00000010205"
3569 src_ip=`ip_to_hex 192 168 1 2`
3570 dst_ip=`ip_to_hex 10 32 1 2`
3571 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3573 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3575 # Packet to Expect at alice1
3576 src_mac="000002010203"
3577 dst_mac="f00000010204"
3578 src_ip=`ip_to_hex 192 168 1 2`
3579 dst_ip=`ip_to_hex 172 16 1 2`
3580 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3582 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3584 OVN_CLEANUP([hv1],[hv2])
3588 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3589 AT_SKIP_IF([test $HAVE_PYTHON = no])
3592 ovn-nbctl ls-add ls1
3594 ovn-nbctl lsp-add ls1 ls1-lp1 \
3595 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3597 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3599 ovn-nbctl lsp-add ls1 ls1-lp2 \
3600 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3602 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3604 ovn-nbctl ls-add ls2
3605 ovn-nbctl lsp-add ls2 ls2-lp1 \
3606 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3607 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3608 ovn-nbctl lsp-add ls2 ls2-lp2 \
3609 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3610 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3612 ovn-nbctl -- --id=@d1 create DHCP_Options cidr=10.0.0.0/24 \
3613 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3614 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"" \
3615 -- add Logical_Switch_Port ls1-lp1 dhcpv4_options @d1 \
3616 -- add Logical_Switch_Port ls1-lp2 dhcpv4_options @d1
3618 ovn-nbctl -- --id=@d2 create DHCP_Options cidr=30.0.0.0/24 \
3619 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3620 \"lease_time\"=\"3600\"" -- add Logical_Switch_Port ls2-lp2 dhcpv4_options @d2
3626 ovs-vsctl add-br br-phys
3627 ovn_attach n1 br-phys 192.168.0.1
3628 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3629 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3630 options:tx_pcap=hv1/vif1-tx.pcap \
3631 options:rxq_pcap=hv1/vif1-rx.pcap \
3634 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3635 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3636 options:tx_pcap=hv1/vif2-tx.pcap \
3637 options:rxq_pcap=hv1/vif2-rx.pcap \
3640 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3641 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3642 options:tx_pcap=hv1/vif3-tx.pcap \
3643 options:rxq_pcap=hv1/vif3-rx.pcap \
3646 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3647 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3648 options:tx_pcap=hv1/vif4-tx.pcap \
3649 options:rxq_pcap=hv1/vif4-rx.pcap \
3656 as hv1 ovs-vsctl show
3658 # This shell function sends a DHCP request packet
3659 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3661 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4
3662 local request=ffffffffffff${src_mac}080045100110000000008011000000000000ffffffff
3663 # udp header and dhcp header
3664 request=${request}0044004300fc0000
3665 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3666 # client hardware padding
3667 request=${request}00000000000000000000
3669 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3670 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3672 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3673 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3674 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3675 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3677 request=${request}63825363
3679 request=${request}3501${dhcp_type}ff
3681 if test $offer_ip != 0; then
3682 local srv_mac=$5 srv_ip=$6 expected_dhcp_opts=$7
3683 # total IP length will be the IP length of the request packet
3684 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3685 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3686 udp_len=`expr $ip_len - 20`
3687 ip_len=$(printf "%x" $ip_len)
3688 udp_len=$(printf "%x" $udp_len)
3689 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3690 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3691 # udp header and dhcp header.
3692 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3693 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3695 reply=${reply}${offer_ip}
3696 # next server ip address, relay agent ip address, client mac address
3697 reply=${reply}0000000000000000${src_mac}
3698 # client hardware padding
3699 reply=${reply}00000000000000000000
3701 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3702 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3704 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3705 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3706 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3707 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3709 reply=${reply}63825363
3711 local dhcp_reply_type=02
3712 if test $dhcp_type = 03; then
3715 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3716 echo $reply >> $inport.expected
3718 shift; shift; shift; shift;
3720 echo $request >> $outport.expected
3723 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3729 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3730 options:rxq_pcap=dummy-rx.pcap
3731 rm -f ${pcap_file}*.pcap
3732 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3733 options:rxq_pcap=${pcap_file}-rx.pcap
3737 printf "%02x%02x%02x%02x" "$@"
3740 AT_CAPTURE_FILE([ofctl_monitor0.log])
3741 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3742 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3744 echo "---------NB dump-----"
3746 echo "---------------------"
3747 echo "---------SB dump-----"
3748 ovn-sbctl list datapath_binding
3749 echo "---------------------"
3750 ovn-sbctl list logical_flow
3751 echo "---------------------"
3753 echo "---------------------"
3754 ovn-sbctl dump-flows
3755 echo "---------------------"
3757 echo "------ hv1 dump ----------"
3758 as hv1 ovs-ofctl dump-flows br-int
3760 # Send DHCPDISCOVER.
3761 offer_ip=`ip_to_hex 10 0 0 4`
3762 server_ip=`ip_to_hex 10 0 0 1`
3763 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3764 test_dhcp 1 f00000000001 01 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3766 # NXT_RESUMEs should be 1.
3767 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3770 cat 1.expected | cut -c -48 > expout
3771 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3772 # Skipping the IPv4 checksum.
3773 cat 1.expected | cut -c 53- > expout
3774 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3776 # ovs-ofctl also resumes the packets and this causes other ports to receive
3777 # the DHCP request packet. So reset the pcap files so that its easier to test.
3778 reset_pcap_file hv1-vif1 hv1/vif1
3779 reset_pcap_file hv1-vif2 hv1/vif2
3784 offer_ip=`ip_to_hex 10 0 0 6`
3785 server_ip=`ip_to_hex 10 0 0 1`
3786 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3787 test_dhcp 2 f00000000002 03 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3789 # NXT_RESUMEs should be 2.
3790 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3792 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3793 cat 2.expected | cut -c -48 > expout
3794 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3795 # Skipping the IPv4 checksum.
3796 cat 2.expected | cut -c 53- > expout
3797 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3799 reset_pcap_file hv1-vif1 hv1/vif1
3800 reset_pcap_file hv1-vif2 hv1/vif2
3804 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3805 # but should be resumed without the reply.
3806 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3807 # one from ovn-controller and the other from "ovs-ofctl resume."
3809 test_dhcp 2 f00000000002 08 $offer_ip 1 1
3811 # NXT_RESUMEs should be 3.
3812 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3814 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
3815 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3817 reset_pcap_file hv1-vif1 hv1/vif1
3818 reset_pcap_file hv1-vif2 hv1/vif2
3822 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3823 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3825 test_dhcp 3 f00000000003 01 0 4
3827 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3829 test_dhcp 4 f00000000004 01 0 3
3831 # NXT_RESUMEs should be 3.
3832 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3834 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3835 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
3838 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3839 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3840 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3843 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3846 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3849 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3852 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3853 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3857 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
3858 AT_SKIP_IF([test $HAVE_PYTHON = no])
3861 ovn-nbctl ls-add ls1
3862 ovn-nbctl lsp-add ls1 ls1-lp1 \
3863 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3865 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3867 ovn-nbctl lsp-add ls1 ls1-lp2 \
3868 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3870 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3872 ovn-nbctl lsp-add ls1 ls1-lp3 \
3873 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3875 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3877 ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
3878 options="\"server_id\"=\"00:00:00:10:00:01\"" \
3879 -- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
3880 -- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
3882 ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
3883 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
3884 -- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
3886 ovn-nbctl ls-add ls2
3887 ovn-nbctl lsp-add ls2 ls2-lp1 \
3888 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
3889 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
3890 ovn-nbctl lsp-add ls2 ls2-lp2 \
3891 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
3892 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
3898 ovs-vsctl add-br br-phys
3899 ovn_attach n1 br-phys 192.168.0.1
3900 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3901 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3902 options:tx_pcap=hv1/vif1-tx.pcap \
3903 options:rxq_pcap=hv1/vif1-rx.pcap \
3906 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3907 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3908 options:tx_pcap=hv1/vif2-tx.pcap \
3909 options:rxq_pcap=hv1/vif2-rx.pcap \
3912 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3913 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3914 options:tx_pcap=hv1/vif3-tx.pcap \
3915 options:rxq_pcap=hv1/vif3-rx.pcap \
3918 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3919 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3920 options:tx_pcap=hv1/vif4-tx.pcap \
3921 options:rxq_pcap=hv1/vif4-rx.pcap \
3924 ovs-vsctl -- add-port br-int hv1-vif5 -- \
3925 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
3926 options:tx_pcap=hv1/vif5-tx.pcap \
3927 options:rxq_pcap=hv1/vif5-rx.pcap \
3935 sed 's/\(00\)\{1,\}$//'
3938 # This shell function sends a DHCPv6 request packet
3939 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
3940 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
3941 # packet should be received twice (one from ovn-controller and the other
3942 # from the "ovs-ofctl monitor br-int resume"
3944 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
3945 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
3947 request=${request}ff020000000000000000000000010002
3948 # udp header and dhcpv6 header
3949 request=${request}02220223002affff${msg_code}010203
3951 request=${request}0001000a00030001${src_mac}
3952 # IA-NA (Identity Association for Non Temporary Address)
3953 request=${request}0003000c0102030400000e1000001518
3954 shift; shift; shift; shift; shift;
3955 if test $offer_ip != 0; then
3956 local server_mac=000000100001
3957 local server_lla=fe80000000000000020000fffe100001
3959 if test $msg_code = 01; then
3963 if test $offer_ip = 1; then
3966 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
3967 # udp header and dhcpv6 header
3968 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
3970 reply=${reply}0001000a00030001${src_mac}
3972 if test $offer_ip != 1; then
3973 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
3976 reply=${reply}0002000a00030001${server_mac}
3977 echo $reply | trim_zeros >> $inport.expected
3980 echo $request | trim_zeros >> $outport.expected
3984 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3990 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3991 options:rxq_pcap=dummy-rx.pcap
3992 rm -f ${pcap_file}*.pcap
3993 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3994 options:rxq_pcap=${pcap_file}-rx.pcap
3997 AT_CAPTURE_FILE([ofctl_monitor0.log])
3998 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3999 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4001 echo "---------NB dump-----"
4003 echo "---------------------"
4004 echo "---------SB dump-----"
4005 ovn-sbctl list datapath_binding
4006 echo "---------------------"
4007 ovn-sbctl list logical_flow
4008 echo "---------------------"
4010 echo "---------------------"
4011 ovn-sbctl dump-flows
4012 echo "---------------------"
4014 echo "------ hv1 dump ----------"
4015 as hv1 ovs-ofctl dump-flows br-int
4017 src_mac=f00000000001
4018 src_lla=fe80000000000000f20000fffe000001
4019 offer_ip=ae700000000000000000000000000004
4020 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4022 # NXT_RESUMEs should be 1.
4023 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4025 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4026 # cat 1.expected | trim_zeros > expout
4027 cat 1.expected | cut -c -120 > expout
4028 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4029 # Skipping the UDP checksum
4030 cat 1.expected | cut -c 125- > expout
4031 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4035 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4036 # without any modifications and the packet should be received by ls1-lp1.
4037 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4038 # resume and the other from ovs-ofctl monitor resume.
4040 reset_pcap_file hv1-vif1 hv1/vif1
4041 reset_pcap_file hv1-vif2 hv1/vif2
4043 src_mac=f00000000002
4044 src_lla=fe80000000000000f20000fffe000002
4045 offer_ip=ae700000000000000000000000000005
4046 # Set invalid msg_type
4048 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4050 # NXT_RESUMEs should be 2.
4051 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4053 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4055 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4056 AT_CHECK([cat 2.packets], [0], [])
4058 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4059 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4060 cat 1.expected > expout
4061 AT_CHECK([cat 1.packets], [0], [expout])
4063 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4064 # There should be no DHCPv6 reply from ovn-controller and the request packet
4065 # should be received by ls2-lp2.
4067 src_mac=f00000000003
4068 src_lla=fe80000000000000f20000fffe000003
4069 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4071 # NXT_RESUMEs should be 2 only.
4072 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4074 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4075 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4076 AT_CHECK([cat 3.packets], [0], [])
4078 # vif4-tx.pcap should have received the DHCPv6 request packet
4079 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4080 cat 4.expected > expout
4081 AT_CHECK([cat 4.packets], [0], [expout])
4083 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4084 # The DHCPv6 reply should doesn't contian offer_ip.
4085 src_mac=f00000000022
4086 src_lla=fe80000000000000f20000fffe000022
4087 reset_pcap_file hv1-vif5 hv1/vif5
4088 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4090 # NXT_RESUMEs should be 3.
4091 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4093 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4094 # Skipping the UDP checksum
4095 cat 5.expected | cut -c 1-120,125- > expout
4096 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4099 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4100 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4101 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4104 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4107 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4110 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4113 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4114 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4118 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4119 AT_SKIP_IF([test $HAVE_PYTHON = no])
4123 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4124 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4125 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4126 # R2 is a gateway router.
4130 # Create two hypervisor and create OVS ports corresponding to logical ports.
4135 ovs-vsctl add-br br-phys
4136 ovn_attach n1 br-phys 192.168.0.1
4137 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4138 set interface hv1-vif1 external-ids:iface-id=foo1 \
4139 options:tx_pcap=hv1/vif1-tx.pcap \
4140 options:rxq_pcap=hv1/vif1-rx.pcap \
4146 ovs-vsctl add-br br-phys
4147 ovn_attach n1 br-phys 192.168.0.2
4148 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4149 set interface hv2-vif1 external-ids:iface-id=alice1 \
4150 options:tx_pcap=hv2/vif1-tx.pcap \
4151 options:rxq_pcap=hv2/vif1-rx.pcap \
4154 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4155 # packets for ARP resolution (native tunneling doesn't queue packets
4156 # for ARP resolution).
4159 ovn-nbctl create Logical_Router name=R1
4160 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4162 ovn-nbctl ls-add foo
4163 ovn-nbctl ls-add alice
4164 ovn-nbctl ls-add join
4167 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4168 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4169 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4171 # Connect alice to R2
4172 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4173 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4174 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4176 # Connect R1 to join
4177 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4178 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4179 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4181 # Connect R2 to join
4182 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4183 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4184 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4187 #install static routes
4188 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4189 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4190 R1 static_routes @lrt
4192 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4193 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4194 R2 static_routes @lrt
4196 # Create logical port foo1 in foo
4197 ovn-nbctl lsp-add foo foo1 \
4198 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4200 # Create logical port alice1 in alice
4201 ovn-nbctl lsp-add alice alice1 \
4202 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4205 # Allow some time for ovn-northd and ovn-controller to catch up.
4206 # XXX This should be more systematic.
4210 printf "%02x%02x%02x%02x" "$@"
4213 # Send ip packets between foo1 and alice1
4214 src_mac="f00000010203"
4215 dst_mac="000001010203"
4216 src_ip=`ip_to_hex 192 168 1 2`
4217 dst_ip=`ip_to_hex 172 16 1 2`
4218 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4220 echo "---------NB dump-----"
4222 echo "---------------------"
4223 ovn-nbctl list logical_router
4224 echo "---------------------"
4225 ovn-nbctl list logical_router_port
4226 echo "---------------------"
4228 echo "---------SB dump-----"
4229 ovn-sbctl list datapath_binding
4230 echo "---------------------"
4231 ovn-sbctl list port_binding
4232 echo "---------------------"
4233 ovn-sbctl dump-flows
4234 echo "---------------------"
4235 ovn-sbctl list chassis
4236 ovn-sbctl list encap
4237 echo "---------------------"
4239 # Packet to Expect at alice1
4240 src_mac="000002010203"
4241 dst_mac="f00000010204"
4242 src_ip=`ip_to_hex 192 168 1 2`
4243 dst_ip=`ip_to_hex 172 16 1 2`
4244 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4247 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4248 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4250 echo "------ hv1 dump after packet 1 ----------"
4251 as hv1 ovs-ofctl show br-int
4252 as hv1 ovs-ofctl dump-flows br-int
4253 echo "------ hv2 dump after packet 1 ----------"
4254 as hv2 ovs-ofctl show br-int
4255 as hv2 ovs-ofctl dump-flows br-int
4256 echo "----------------------------"
4258 echo $expected > expected
4259 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4261 # Delete the router and re-create it. Things should work as before.
4263 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4264 # Connect alice to R2
4265 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4266 # Connect R2 to join
4267 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4269 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4270 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4271 R2 static_routes @lrt
4273 # Wait for ovn-controller to catch up.
4276 # Send the packet again.
4277 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4279 echo "------ hv1 dump after packet 2 ----------"
4280 as hv1 ovs-ofctl show br-int
4281 as hv1 ovs-ofctl dump-flows br-int
4282 echo "------ hv2 dump after packet 2 ----------"
4283 as hv2 ovs-ofctl show br-int
4284 as hv2 ovs-ofctl dump-flows br-int
4285 echo "----------------------------"
4287 echo $expected >> expected
4288 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4290 OVN_CLEANUP([hv1],[hv2])
4294 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4295 AT_KEYWORDS([router-icmp-reply])
4296 AT_SKIP_IF([test $HAVE_PYTHON = no])
4300 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4301 # and has switch ls2 (172.16.1.0/24) connected to it.
4305 ovn-nbctl ls-add ls1
4306 ovn-nbctl ls-add ls2
4309 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4310 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4311 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4314 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4315 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4316 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4318 # Create logical port ls1-lp1 in ls1
4319 ovn-nbctl lsp-add ls1 ls1-lp1 \
4320 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4322 # Create logical port ls2-lp1 in ls2
4323 ovn-nbctl lsp-add ls2 ls2-lp1 \
4324 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4326 # Create one hypervisor and create OVS ports corresponding to logical ports.
4331 ovs-vsctl add-br br-phys
4332 ovn_attach n1 br-phys 192.168.0.1
4333 ovs-vsctl -- add-port br-int vif1 -- \
4334 set interface vif1 external-ids:iface-id=ls1-lp1 \
4335 options:tx_pcap=hv1/vif1-tx.pcap \
4336 options:rxq_pcap=hv1/vif1-rx.pcap \
4339 ovs-vsctl -- add-port br-int vif2 -- \
4340 set interface vif2 external-ids:iface-id=ls2-lp1 \
4341 options:tx_pcap=hv1/vif2-tx.pcap \
4342 options:rxq_pcap=hv1/vif2-rx.pcap \
4346 # Allow some time for ovn-northd and ovn-controller to catch up.
4347 # XXX This should be more systematic.
4352 printf "%02x%02x%02x%02x" "$@"
4357 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4359 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4360 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4361 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4362 # provided, then it should be the ip and icmp checksums of the packet
4363 # responded; otherwise, no reply is expected.
4364 # In the absence of an ip checksum calculation helpers, this relies
4365 # on the caller to provide the checksums for the ip and icmp headers.
4366 # XXX This should be more systematic.
4368 # INPORT is an lport number, e.g. 11 for vif11.
4369 # ETH_SRC and ETH_DST are each 12 hex digits.
4370 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4371 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4372 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4373 test_ipv4_icmp_request() {
4374 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4375 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4376 shift; shift; shift; shift; shift; shift; shift
4379 # Use ttl to exercise section 4.2.2.9 of RFC1812
4383 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4384 local icmp_type_code_request=0800
4385 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4386 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4388 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4389 if test X$exp_icmp_chksum != X; then
4390 # Expect to receive the reply, if any. In same port where packet was sent.
4391 # Note: src and dst fields are expected to be reversed.
4392 local icmp_type_code_response=0000
4393 local reply_icmp_ttl=fe
4394 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4395 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4396 echo $reply >> vif$inport.expected
4400 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4401 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4402 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4403 l1_ip=$(ip_to_hex 192 168 1 2)
4404 l2_ip=$(ip_to_hex 172 16 1 2)
4406 # Ping router ip address that is on same subnet as the logical port
4407 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4408 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4410 # Ping router ip address that is on the other side of the logical ports
4411 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4412 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4414 echo "---------NB dump-----"
4416 echo "---------------------"
4417 ovn-nbctl list logical_router
4418 echo "---------------------"
4419 ovn-nbctl list logical_router_port
4420 echo "---------------------"
4422 echo "---------SB dump-----"
4423 ovn-sbctl list datapath_binding
4424 echo "---------------------"
4425 ovn-sbctl list logical_flow
4426 echo "---------------------"
4428 echo "------ hv1 dump ----------"
4429 as hv1 ovs-ofctl dump-flows br-int
4431 # Now check the packets actually received against the ones expected.
4432 for inport in 1 2; do
4433 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4440 # 1 hypervisor, 1 port
4441 # make sure that the port state is properly set to up and back down
4442 # when created and deleted.
4443 AT_SETUP([ovn -- port state up and down])
4446 ovn-nbctl ls-add ls1
4447 ovn-nbctl lsp-add ls1 lp1
4448 ovn-nbctl lsp-set-addresses lp1 unknown
4452 as hv1 ovs-vsctl add-br br-phys
4453 as hv1 ovn_attach n1 br-phys 192.168.0.1
4455 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4456 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4458 as hv1 ovs-vsctl del-port br-int vif1
4459 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4465 # 1 hypervisor, 1 port
4466 # make sure that the OF rules created to support a datapath are added/cleared
4467 # when logical switch is created and removed.
4468 AT_SETUP([ovn -- datapath rules added/removed])
4469 AT_KEYWORDS([cleanup])
4474 as hv1 ovs-vsctl add-br br-phys
4475 as hv1 ovn_attach n1 br-phys 192.168.0.1
4477 # This shell function checks if OF rules in br-int have clauses
4478 # related to OVN datapaths. The caller determines if it should find
4479 # a match in the output, or not.
4481 # EXPECT_DATAPATH param determines whether flows that refer to
4482 # datapath to should be present or not. 0 means
4483 # they should not be.
4484 # STAGE_INFO param is a simple string to help identify the stage
4485 # in the test when this function was invoked.
4486 test_datapath_in_of_rules() {
4487 local expect_datapath=$1 stage_info=$2
4488 echo "------ ovn-nbctl show ${stage_info} ------"
4490 echo "------ ovn-sbctl show ${stage_info} ------"
4492 echo "------ OF rules ${stage_info} ------"
4493 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4494 # if there is a datapath mentioned in the output, check for the
4495 # magic keyword that represents one, based on the exit status of
4497 if test $expect_datapath != 0; then
4498 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4500 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4504 test_datapath_in_of_rules 0 "before ls+port create"
4506 ovn-nbctl ls-add ls1
4507 ovn-nbctl lsp-add ls1 lp1
4508 ovn-nbctl lsp-set-addresses lp1 unknown
4510 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4511 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4513 test_datapath_in_of_rules 1 "after port is bound"
4515 as hv1 ovs-vsctl del-port br-int vif1
4516 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4518 ovn-nbctl lsp-set-addresses lp1
4519 ovn-nbctl lsp-del lp1
4520 ovn-nbctl ls-del ls1
4522 # wait for earlier changes to take effect
4523 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4525 # ensure OF rules are no longer present. There used to be a bug here.
4526 test_datapath_in_of_rules 0 "after lport+ls removal"
4532 AT_SETUP([ovn -- nd_na ])
4533 AT_SKIP_IF([test $HAVE_PYTHON = no])
4536 #TODO: since patch port for IPv6 logical router port is not ready not,
4537 # so we are not going to test vifs on different lswitches cases. Try
4538 # to update for that once relevant stuff implemented.
4540 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4541 # with. NS packet we test, from one VIF for another VIF, will be replied
4542 # by local ovn-controller, but not by target VIF.
4544 # Create hypervisors and logical switch lsw0.
4545 ovn-nbctl ls-add lsw0
4549 ovs-vsctl add-br br-phys
4550 ovn_attach n1 br-phys 192.168.0.2
4552 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4553 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
4554 ovn-nbctl lsp-add lsw0 lp1
4555 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4556 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"
4558 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4559 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
4560 ovn-nbctl lsp-add lsw0 lp2
4561 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4562 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"
4564 # Add ACL rule for ICMPv6 on lsw0
4565 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4566 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4567 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4569 # Allow some time for ovn-northd and ovn-controller to catch up.
4570 # XXX This should be more systematic.
4573 # Given the name of a logical port, prints the name of the hypervisor
4574 # on which it is located.
4582 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4583 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4584 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4585 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4586 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4588 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4589 echo $na_packet >> 1.expected
4591 echo "------ hv1 dump ------"
4592 as hv1 ovs-vsctl show
4593 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4594 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4597 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4604 AT_SETUP([ovn -- address sets modification/removal smoke test])
4611 ovs-vsctl add-br br-phys
4612 ovn_attach n1 br-phys 192.168.0.1
4614 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4615 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4616 ovn-nbctl destroy Address_Set $row
4620 # A bug previously existed in the address set support code
4621 # that caused ovn-controller to crash after an address set
4622 # was updated and then removed. This test case ensures
4623 # that ovn-controller is at least still running after
4624 # creating, updating, and deleting an address set.
4625 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4631 AT_SETUP([ovn -- ipam])
4632 AT_SKIP_IF([test $HAVE_PYTHON = no])
4635 # Add a port to a switch that does not have a subnet set, then set the
4636 # subnet which should result in an address being allocated for the port.
4637 ovn-nbctl ls-add sw0
4638 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4639 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4640 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4641 ["0a:00:00:00:00:01 192.168.1.2"
4644 # Add 9 more ports to sw0, addresses should all be unique.
4645 for n in `seq 1 9`; do
4646 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4648 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4649 ["0a:00:00:00:00:02 192.168.1.3"
4651 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4652 ["0a:00:00:00:00:03 192.168.1.4"
4654 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4655 ["0a:00:00:00:00:04 192.168.1.5"
4657 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4658 ["0a:00:00:00:00:05 192.168.1.6"
4660 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4661 ["0a:00:00:00:00:06 192.168.1.7"
4663 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4664 ["0a:00:00:00:00:07 192.168.1.8"
4666 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4667 ["0a:00:00:00:00:08 192.168.1.9"
4669 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4670 ["0a:00:00:00:00:09 192.168.1.10"
4672 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4673 ["0a:00:00:00:00:0a 192.168.1.11"
4676 # Trying similar tests with a second switch. MAC addresses should be unique
4677 # across both switches but IP's only need to be unique within the same switch.
4678 ovn-nbctl ls-add sw1
4679 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4680 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4681 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4682 ["0a:00:00:00:00:0b 192.168.1.2"
4685 for n in `seq 11 19`; do
4686 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4688 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4689 ["0a:00:00:00:00:0c 192.168.1.3"
4691 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4692 ["0a:00:00:00:00:0d 192.168.1.4"
4694 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4695 ["0a:00:00:00:00:0e 192.168.1.5"
4697 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4698 ["0a:00:00:00:00:0f 192.168.1.6"
4700 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4701 ["0a:00:00:00:00:10 192.168.1.7"
4703 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4704 ["0a:00:00:00:00:11 192.168.1.8"
4706 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4707 ["0a:00:00:00:00:12 192.168.1.9"
4709 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4710 ["0a:00:00:00:00:13 192.168.1.10"
4712 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4713 ["0a:00:00:00:00:14 192.168.1.11"
4716 # Change a port's address to test for multiple ip's for a single address entry
4717 # and addresses set by the user.
4718 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4719 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4720 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4721 ["0a:00:00:00:00:16 192.168.1.13"
4724 # Test for logical router port address management.
4725 ovn-nbctl create Logical_Router name=R1
4726 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4727 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4728 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4729 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4730 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4731 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4732 ["0a:00:00:00:00:18 192.168.1.15"
4735 # Test for address reuse after logical port is deleted.
4736 ovn-nbctl lsp-del p0
4737 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4738 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4739 ["0a:00:00:00:00:19 192.168.1.2"
4742 # Test for multiple addresses to one logical port.
4743 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4744 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
4745 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
4746 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4747 ["0a:00:00:00:00:1c 192.168.1.16"
4750 # Test for exhausting subnet address space.
4751 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
4752 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
4753 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4754 ["0a:00:00:00:00:1d 172.16.1.2"
4757 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
4758 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4762 # Test that address management does not add duplicate MAC for lsp/lrp peers.
4763 ovn-nbctl create Logical_Router name=R2
4764 ovn-nbctl ls-add sw3
4765 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4767 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4768 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4769 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4770 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
4771 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
4772 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4773 ["0a:00:00:00:00:20 192.168.1.17"
4776 # Test static MAC address with dynamically allocated IP
4777 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
4778 "fe:dc:ba:98:76:54 dynamic"
4779 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4780 ["fe:dc:ba:98:76:54 192.168.1.18"
4784 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4787 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4790 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4794 AT_SETUP([ovn -- ipam connectivity])
4795 AT_SKIP_IF([test $HAVE_PYTHON = no])
4800 # Test for a ping using dynamically allocated addresses.
4801 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
4802 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
4805 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4806 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4807 options:router-port=foo \
4808 -- lsp-set-addresses rp-foo router
4810 # Connect alice to R1
4811 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
4812 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
4813 options:router-port=alice addresses=\"00:00:00:01:02:04\"
4815 # Create logical port foo1 in foo
4816 ovn-nbctl --wait=sb lsp-add foo foo1 \
4817 -- lsp-set-addresses foo1 "dynamic"
4818 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])
4820 # Create logical port alice1 in alice
4821 ovn-nbctl --wait=sb lsp-add alice alice1 \
4822 -- lsp-set-addresses alice1 "dynamic"
4823 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
4825 # Create logical port foo2 in foo
4826 ovn-nbctl --wait=sb lsp-add foo foo2 \
4827 -- lsp-set-addresses foo2 "dynamic"
4828 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
4830 # Create a hypervisor and create OVS ports corresponding to logical ports.
4835 ovs-vsctl add-br br-phys
4836 ovn_attach n1 br-phys 192.168.0.1
4837 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4838 set interface hv1-vif1 external-ids:iface-id=foo1 \
4839 options:tx_pcap=hv1/vif1-tx.pcap \
4840 options:rxq_pcap=hv1/vif1-rx.pcap \
4843 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4844 set interface hv1-vif2 external-ids:iface-id=foo2 \
4845 options:tx_pcap=hv1/vif2-tx.pcap \
4846 options:rxq_pcap=hv1/vif2-rx.pcap \
4849 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4850 set interface hv1-vif3 external-ids:iface-id=alice1 \
4851 options:tx_pcap=hv1/vif3-tx.pcap \
4852 options:rxq_pcap=hv1/vif3-rx.pcap \
4855 # Allow some time for ovn-northd and ovn-controller to catch up.
4856 # XXX This should be more systematic.
4860 printf "%02x%02x%02x%02x" "$@"
4863 # Send ip packets between foo1 and foo2
4864 src_mac="0a0000000001"
4865 dst_mac="0a0000000003"
4866 src_ip=`ip_to_hex 192 168 1 2`
4867 dst_ip=`ip_to_hex 192 168 1 3`
4868 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4869 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4871 # Send ip packets between foo1 and alice1
4872 src_mac="0a0000000001"
4873 dst_mac="000000010203"
4874 src_ip=`ip_to_hex 192 168 1 2`
4875 dst_ip=`ip_to_hex 192 168 2 2`
4876 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4877 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4879 echo "---------NB dump-----"
4881 echo "---------------------"
4882 ovn-nbctl list logical_router
4883 echo "---------------------"
4884 ovn-nbctl list logical_router_port
4885 echo "---------------------"
4887 echo "---------SB dump-----"
4888 ovn-sbctl list datapath_binding
4889 echo "---------------------"
4890 ovn-sbctl list port_binding
4891 echo "---------------------"
4893 echo "------ hv1 dump ----------"
4894 as hv1 ovs-ofctl dump-flows br-int
4896 # Packet to Expect at foo2
4897 src_mac="0a0000000001"
4898 dst_mac="0a0000000003"
4899 src_ip=`ip_to_hex 192 168 1 2`
4900 dst_ip=`ip_to_hex 192 168 1 3`
4901 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4903 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
4904 echo $expected > expout
4905 AT_CHECK([cat received1.packets], [0], [expout])
4907 # Packet to Expect at alice1
4908 src_mac="000000010204"
4909 dst_mac="0a0000000002"
4910 src_ip=`ip_to_hex 192 168 1 2`
4911 dst_ip=`ip_to_hex 192 168 2 2`
4912 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
4914 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
4915 echo $expected > expout
4916 AT_CHECK([cat received2.packets], [0], [expout])
4922 AT_SETUP([ovn -- ovs-vswitchd restart])
4923 AT_KEYWORDS([vswitchd])
4924 AT_SKIP_IF([test $HAVE_PYTHON = no])
4927 ovn-nbctl ls-add ls1
4929 ovn-nbctl lsp-add ls1 ls1-lp1 \
4930 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4932 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4938 ovs-vsctl add-br br-phys
4939 ovn_attach n1 br-phys 192.168.0.1
4940 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4941 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4942 options:tx_pcap=hv1/vif1-tx.pcap \
4943 options:rxq_pcap=hv1/vif1-rx.pcap \
4949 as hv1 ovs-vsctl show
4951 echo "---------------------"
4952 ovn-sbctl dump-flows
4953 echo "---------------------"
4955 echo "------ hv1 dump ----------"
4956 as hv1 ovs-ofctl dump-flows br-int
4957 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4959 echo "Total flows before vswitchd restart = " $total_flows
4961 # Code taken from ovs-save utility
4963 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
4964 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
4965 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
4966 echo "EOF" >> restore_flows.sh
4969 restart_vswitchd () {
4972 if test $restore_flows = true; then
4977 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4979 if test $restore_flows = true; then
4981 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
4985 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4986 ovs-ofctl dump-flows br-int
4988 if test $restore_flows = true; then
4989 sh ./restore_flows.sh
4990 echo "Flows after restore"
4992 ovs-ofctl dump-flows br-int
4993 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
4994 flow-restore-wait="true"
4998 # Save the flows, restart vswitchd and restore the flows
4999 restart_vswitchd true
5001 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5002 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5003 test "${total_flows}" = "${total_flows_after_restart}"
5006 # Restart vswitchd without restoring
5007 restart_vswitchd false
5009 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5010 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5011 test "${total_flows}" = "${total_flows_after_restart}"
5017 AT_SETUP([ovn -- send arp for nexthop])
5018 AT_SKIP_IF([test $HAVE_PYTHON = no])
5021 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5023 # Create logical switches
5024 ovn-nbctl ls-add ls1
5025 ovn-nbctl ls-add ls2
5028 ovn-nbctl create Logical_Router name=lr0
5030 # Add router ls1p1 port to gateway router
5031 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5032 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5033 type=router options:router-port=lrp-ls1lp1 \
5034 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5036 # Add router ls2p2 port to gateway router
5037 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5038 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5039 type=router options:router-port=lrp-ls2lp1 \
5040 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5042 # Set default gateway (nexthop) to 192.168.1.254
5043 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5045 # Create logical port ls1lp2 in ls1
5046 ovn-nbctl lsp-add ls1 ls1lp2 \
5047 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5049 # Create logical port ls2lp2 in ls2
5050 ovn-nbctl lsp-add ls2 ls2lp2 \
5051 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5056 ovs-vsctl add-br br-phys
5057 ovn_attach n1 br-phys 192.168.0.1
5058 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5059 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5060 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5061 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5063 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5064 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5065 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5066 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5069 # Allow some time for ovn-northd and ovn-controller to catch up.
5070 # XXX This should be more systematic.
5073 echo "---------NB dump-----"
5075 echo "---------------------"
5076 ovn-nbctl list logical_router
5077 echo "---------------------"
5078 ovn-nbctl list logical_router_port
5079 echo "---------------------"
5081 echo "---------SB dump-----"
5082 ovn-sbctl list datapath_binding
5083 echo "---------------------"
5084 ovn-sbctl list port_binding
5085 echo "---------------------"
5086 ovn-sbctl dump-flows
5087 echo "---------------------"
5088 ovn-sbctl list chassis
5089 ovn-sbctl list encap
5090 echo "---------------------"
5092 echo "------Flows dump-----"
5094 ovs-ofctl dump-flows
5095 echo "---------------------"
5098 printf "%02x%02x%02x%02x" "$@"
5101 src_mac="f00000000003"
5102 dst_mac="f00000000001"
5103 src_ip=`ip_to_hex 192 168 0 2`
5104 dst_ip=`ip_to_hex 8 8 8 8`
5105 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5107 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5108 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5111 sed 's/\(00\)\{1,\}$//'
5114 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5117 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5118 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5119 echo $expected > expout
5120 AT_CHECK([cat packets], [0], [expout])
5127 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5128 AT_SKIP_IF([test $HAVE_PYTHON = no])
5130 # Create logical switch
5131 ovn-nbctl ls-add ls0
5132 # Create gateway router
5133 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5134 # Add router port to gateway router
5135 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5136 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5137 type=router options:router-port=lrp0-rp addresses='"f0:00:00:00:00:01"'
5138 # Add nat-address option
5139 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5148 ovn_attach n1 br-phys 192.168.0.1
5150 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5151 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])
5153 # Create a localnet port.
5154 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5155 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5156 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5157 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5160 # Wait for packet to be received.
5161 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5163 sed 's/\(00\)\{1,\}$//'
5165 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5166 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5167 echo $expected > expout
5168 AT_CHECK([sort packets], [0], [expout])
5175 AT_SETUP([ovn -- delete mac bindings])
5180 ovs-vsctl -- add-br br-phys
5181 ovn_attach n1 br-phys 192.168.0.1
5182 # Create logical switch ls0
5183 ovn-nbctl ls-add ls0
5184 # Create ports lp0, lp1 in ls0
5185 ovn-nbctl lsp-add ls0 lp0
5186 ovn-nbctl lsp-add ls0 lp1
5187 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5188 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5189 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5190 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5191 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5192 ovn-sbctl find MAC_Binding
5193 # Delete port lp0 and check that its MAC_Binding is deleted.
5194 ovn-nbctl lsp-del lp0
5195 ovn-sbctl find MAC_Binding
5196 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5197 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5198 ovn-nbctl ls-del ls0
5199 ovn-sbctl find MAC_Binding
5200 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5206 AT_SETUP([ovn -- conntrack zone allocation])
5207 AT_SKIP_IF([test $HAVE_PYTHON = no])
5211 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5212 # connected to a router R1.
5213 # foo has foo1 to act as a client.
5214 # bar has bar1, bar2, bar3 to act as servers.
5220 ovs-vsctl add-br br-phys
5221 ovn_attach n1 br-phys 192.168.0.1
5222 for i in foo1 bar1 bar2 bar3; do
5223 ovs-vsctl -- add-port br-int $i -- \
5224 set interface $i external-ids:iface-id=$i \
5225 options:tx_pcap=hv1/$i-tx.pcap \
5226 options:rxq_pcap=hv1/$i-rx.pcap
5229 ovn-nbctl create Logical_Router name=R1
5230 ovn-nbctl ls-add foo
5231 ovn-nbctl ls-add bar
5234 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5235 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5236 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5239 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5240 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5241 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5243 # Create logical port foo1 in foo
5244 ovn-nbctl lsp-add foo foo1 \
5245 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5247 # Create logical port bar1, bar2 and bar3 in bar
5248 for i in `seq 1 3`; do
5250 ovn-nbctl lsp-add bar bar$i \
5251 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5254 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5260 AT_SETUP([ovn -- tag allocation])
5263 AT_CHECK([ovn-nbctl ls-add ls0])
5264 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5265 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5266 AT_CHECK([ovn-nbctl ls-add ls1])
5268 dnl When a tag is provided, no allocation is done
5269 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5270 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5272 dnl The same 'tag' gets created in southbound database.
5273 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5274 logical_port="c0"], [0], [3
5277 dnl Allocate tags and see it getting created in both NB and SB
5278 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5279 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5281 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5282 logical_port="c1"], [0], [1
5285 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5286 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5288 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5289 logical_port="c2"], [0], [2
5291 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5292 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5294 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5295 logical_port="c3"], [0], [4
5298 dnl A different parent.
5299 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5300 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5302 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5303 logical_port="c4"], [0], [1
5306 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5307 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5309 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5310 logical_port="c5"], [0], [2
5313 dnl Delete a logical port and create a new one.
5314 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5315 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5316 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5318 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5319 logical_port="c6"], [0], [1
5322 dnl Restart northd to see that the same allocation remains.
5324 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5325 start_daemon ovn-northd \
5326 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5327 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5329 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5330 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5331 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5333 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5335 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5337 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5339 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5341 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5344 dnl Create a switch port with a tag that has already been allocated.
5345 dnl It should go through fine with a duplicate tag.
5346 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5347 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5349 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5350 logical_port="c7"], [0], [2
5352 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5355 AT_CHECK([ovn-nbctl ls-add ls2])
5356 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5357 dnl gets copied to 'tag'
5358 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5359 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5361 dnl The same 'tag' gets created in southbound database.
5362 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5363 logical_port="local0"], [0], [25
5365 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5366 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5367 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5368 dnl change the tag_request.
5369 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5370 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5375 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5377 ovn-nbctl ls-add lsw0
5382 ovs-vsctl add-br br-phys
5383 ovn_attach n1 br-phys 192.168.0.$i
5384 ovs-vsctl add-br br-eth0
5385 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5388 # Create a localnet port.
5389 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5390 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5391 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5392 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5396 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5397 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5398 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5399 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5400 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5401 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5402 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5403 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5404 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5406 # Bind the localvif1 to hv1.
5408 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5410 # On hv1, check that there are no flows outputting bcast to tunnel
5411 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5413 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5415 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5417 # Now bind vif2 on hv2.
5418 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5420 # At this point, the broadcast flow on vif2 should be deleted.
5421 # because, there is now a localnet vif bound (table=32 programming logic)
5422 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5424 # Verify that the local net patch port exists on hv2.
5425 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5427 # Now bind vif3 on hv2.
5428 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5430 # Verify that the local net patch port still exists on hv2
5431 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5434 AT_CHECK([ovn-nbctl lsp-del localvif2])
5436 # Verify that the local net patch port still exists on hv2,
5437 # because, localvif3 is still bound.
5438 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5440 OVN_CLEANUP([hv1],[hv2])
5444 AT_SETUP([ovn -- DSCP marking check])
5448 ovn-nbctl ls-add lsw0
5449 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5450 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5451 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5452 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5453 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5454 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5455 ovn-nbctl --wait=sb sync
5459 ovs-vsctl add-br br-phys
5460 ovn_attach n1 br-phys 192.168.0.1
5461 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
5462 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
5464 AT_CAPTURE_FILE([trace])
5466 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5469 # Extracts nw_tos from the final flow from ofproto/trace output and prints
5470 # it on stdout. Prints "none" if no nw_tos was included.
5471 get_final_nw_tos() {
5472 if flow=$(grep '^Final flow:' stdout); then :; else
5473 # The output didn't have a final flow.
5477 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5486 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5488 # First check with ovn-trace for logical flows.
5489 echo "checking for tos $1"
5490 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
5491 echo 'output("lp2");') > expout
5492 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])
5494 # Then re-check with ofproto/trace for a physical packet.
5495 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])
5496 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
5501 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");
5503 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])
5504 AT_CHECK([get_final_nw_tos], [0], [none
5507 # check at L3 without dscp marking
5510 # Mark DSCP with a valid value
5511 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)
5514 # Update the DSCP marking
5515 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
5518 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
5521 # Disable DSCP marking
5522 ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
5528 AT_SETUP([ovn -- read-only sb db:ptcp access])
5529 AT_SKIP_IF([test $HAVE_PYTHON = no])
5532 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5534 # Add read-only remote to sb ovsdb-server
5536 [ovsdb-tool transact ovn-sb.db \
5537 ['["OVN_Southbound",
5539 "table": "SB_Global",
5541 "connections": ["set", [["named-uuid", "xyz"]]]}},
5543 "table": "Connection",
5545 "row": {"target": "ptcp:0:127.0.0.1",
5546 "read_only": true}}]']], [0], [ignore], [ignore])
5548 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
5550 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5552 # read-only accesses should succeed
5553 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
5554 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
5556 # write access should fail
5557 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5558 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5561 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5564 AT_SETUP([ovn -- read-only sb db:pssl access])
5565 AT_SKIP_IF([test $HAVE_PYTHON = no])
5566 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5567 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5568 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5572 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5574 # Add read-only remote to sb ovsdb-server
5576 [ovsdb-tool transact ovn-sb.db \
5577 ['["OVN_Southbound",
5579 "table": "SB_Global",
5581 "connections": ["set", [["named-uuid", "xyz"]]]}},
5583 "table": "Connection",
5585 "row": {"target": "pssl:0:127.0.0.1",
5586 "read_only": true}}]']], [0], [ignore], [ignore])
5588 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
5589 --remote=db:OVN_Southbound,SB_Global,connections \
5590 --private-key="$PKIDIR/testpki-privkey2.pem" \
5591 --certificate="$PKIDIR/testpki-cert2.pem" \
5592 --ca-cert="$PKIDIR/testpki-cacert.pem" \
5595 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5597 # read-only accesses should succeed
5598 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5599 --private-key=$PKIDIR/testpki-privkey.pem \
5600 --certificate=$PKIDIR/testpki-cert.pem \
5601 --ca-cert=$PKIDIR/testpki-cacert.pem \
5602 list SB_Global], [0], [stdout], [ignore])
5603 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5604 --private-key=$PKIDIR/testpki-privkey.pem \
5605 --certificate=$PKIDIR/testpki-cert.pem \
5606 --ca-cert=$PKIDIR/testpki-cacert.pem \
5607 list Connection], [0], [stdout], [ignore])
5609 # write access should fail
5610 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5611 --private-key=$PKIDIR/testpki-privkey.pem \
5612 --certificate=$PKIDIR/testpki-cert.pem \
5613 --ca-cert=$PKIDIR/testpki-cacert.pem \
5614 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
5615 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
5618 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5621 AT_SETUP([ovn -- nb connection/ssl commands])
5622 AT_SKIP_IF([test $HAVE_PYTHON = no])
5623 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5624 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5625 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5629 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
5631 # Start nb db server using db connection/ssl entries (unpopulated initially)
5632 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
5633 --remote=db:OVN_Northbound,NB_Global,connections \
5634 --private-key=db:OVN_Northbound,SSL,private_key \
5635 --certificate=db:OVN_Northbound,SSL,certificate \
5636 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
5639 # Populate SSL configuration entries in nb db
5641 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
5642 $PKIDIR/testpki-cert.pem \
5643 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
5645 # Populate a passive SSL connection in nb db
5646 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
5648 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5650 # Verify SSL connetivity to nb db server
5651 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5652 --private-key=$PKIDIR/testpki-privkey.pem \
5653 --certificate=$PKIDIR/testpki-cert.pem \
5654 --ca-cert=$PKIDIR/testpki-cacert.pem \
5656 [0], [stdout], [ignore])
5657 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5658 --private-key=$PKIDIR/testpki-privkey.pem \
5659 --certificate=$PKIDIR/testpki-cert.pem \
5660 --ca-cert=$PKIDIR/testpki-cacert.pem \
5662 [0], [stdout], [ignore])
5663 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
5664 --private-key=$PKIDIR/testpki-privkey.pem \
5665 --certificate=$PKIDIR/testpki-cert.pem \
5666 --ca-cert=$PKIDIR/testpki-cacert.pem \
5668 [0], [stdout], [ignore])
5670 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5673 AT_SETUP([ovn -- sb connection/ssl commands])
5674 AT_SKIP_IF([test $HAVE_PYTHON = no])
5675 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
5676 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
5677 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
5681 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5683 # Start sb db server using db connection/ssl entries (unpopulated initially)
5684 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
5685 --remote=db:OVN_Southbound,SB_Global,connections \
5686 --private-key=db:OVN_Southbound,SSL,private_key \
5687 --certificate=db:OVN_Southbound,SSL,certificate \
5688 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
5691 # Populate SSL configuration entries in sb db
5693 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
5694 $PKIDIR/testpki-cert.pem \
5695 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
5697 # Populate a passive SSL connection in sb db
5698 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
5700 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5702 # Verify SSL connetivity to sb db server
5703 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5704 --private-key=$PKIDIR/testpki-privkey.pem \
5705 --certificate=$PKIDIR/testpki-cert.pem \
5706 --ca-cert=$PKIDIR/testpki-cacert.pem \
5708 [0], [stdout], [ignore])
5709 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5710 --private-key=$PKIDIR/testpki-privkey.pem \
5711 --certificate=$PKIDIR/testpki-cert.pem \
5712 --ca-cert=$PKIDIR/testpki-cacert.pem \
5714 [0], [stdout], [ignore])
5715 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
5716 --private-key=$PKIDIR/testpki-privkey.pem \
5717 --certificate=$PKIDIR/testpki-cert.pem \
5718 --ca-cert=$PKIDIR/testpki-cacert.pem \
5720 [0], [stdout], [ignore])
5722 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5725 AT_SETUP([ovn -- nested containers])
5729 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
5732 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
5733 # and "bar" (192.168.2.0/24). They are all connected to router R1.
5736 ovn-nbctl ls-add mgmt
5737 ovn-nbctl ls-add foo
5738 ovn-nbctl ls-add bar
5740 # Connect mgmt to R1
5741 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
5742 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
5743 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
5746 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5747 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5748 options:router-port=foo addresses=\"00:00:00:01:02:03\"
5751 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
5752 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
5753 options:router-port=bar addresses=\"00:00:00:01:02:04\"
5755 # "mgmt" has VM1 and VM2 connected
5756 ovn-nbctl lsp-add mgmt vm1 \
5757 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
5759 ovn-nbctl lsp-add mgmt vm2 \
5760 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
5762 # "foo1" and "foo2" are containers belonging to switch "foo"
5763 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
5764 ovn-nbctl lsp-add foo foo1 vm1 1 \
5765 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
5767 ovn-nbctl lsp-add foo foo2 vm2 2 \
5768 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
5770 # "bar1" and "bar2" are containers belonging to switch "bar"
5771 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
5772 ovn-nbctl lsp-add bar bar1 vm1 2 \
5773 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
5775 ovn-nbctl lsp-add bar bar2 vm2 1 \
5776 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
5778 # bar3 is a standalone VM belonging to switch "bar"
5779 ovn-nbctl lsp-add bar bar3 \
5780 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
5782 # Create two hypervisor and create OVS ports corresponding to logical ports.
5787 ovs-vsctl add-br br-phys
5788 ovn_attach n1 br-phys 192.168.0.1
5789 ovs-vsctl -- add-port br-int vm1 -- \
5790 set interface vm1 external-ids:iface-id=vm1 \
5791 options:tx_pcap=hv1/vm1-tx.pcap \
5792 options:rxq_pcap=hv1/vm1-rx.pcap \
5795 ovs-vsctl -- add-port br-int bar3 -- \
5796 set interface bar3 external-ids:iface-id=bar3 \
5797 options:tx_pcap=hv1/bar3-tx.pcap \
5798 options:rxq_pcap=hv1/bar3-rx.pcap \
5803 ovs-vsctl add-br br-phys
5804 ovn_attach n1 br-phys 192.168.0.2
5805 ovs-vsctl -- add-port br-int vm2 -- \
5806 set interface vm2 external-ids:iface-id=vm2 \
5807 options:tx_pcap=hv2/vm2-tx.pcap \
5808 options:rxq_pcap=hv2/vm2-rx.pcap \
5811 # Pre-populate the hypervisors' ARP tables so that we don't lose any
5812 # packets for ARP resolution (native tunneling doesn't queue packets
5813 # for ARP resolution).
5816 # Allow some time for ovn-northd and ovn-controller to catch up.
5817 # XXX This should be more systematic.
5821 printf "%02x%02x%02x%02x" "$@"
5824 # Send ip packets between foo1 and foo2 (same switch, different HVs and
5825 # different VLAN tags).
5826 src_mac="f00000010205"
5827 dst_mac="f00000010206"
5828 src_ip=`ip_to_hex 192 168 1 2`
5829 dst_ip=`ip_to_hex 192 168 1 3`
5830 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5831 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5833 # expected packet at foo2
5834 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5835 echo $packet > expected
5836 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
5838 # Send ip packets between foo1 and bar2 (different switch, different HV)
5839 src_mac="f00000010205"
5840 dst_mac="000000010203"
5841 src_ip=`ip_to_hex 192 168 1 2`
5842 dst_ip=`ip_to_hex 192 168 2 3`
5843 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5844 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5846 # expected packet at bar2
5847 src_mac="000000010204"
5848 dst_mac="f00000010208"
5849 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5850 echo $packet >> expected
5851 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
5853 # Send ip packets between foo1 and bar1
5854 # (different switch, loopback to same vm but different tag)
5855 src_mac="f00000010205"
5856 dst_mac="000000010203"
5857 src_ip=`ip_to_hex 192 168 1 2`
5858 dst_ip=`ip_to_hex 192 168 2 2`
5859 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5860 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5862 # expected packet at bar1
5863 src_mac="000000010204"
5864 dst_mac="f00000010207"
5865 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5866 echo $packet > expected1
5867 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5869 # Send ip packets between bar1 and bar3
5870 # (same switch. But one is container and another is a standalone VM)
5871 src_mac="f00000010207"
5872 dst_mac="f00000010209"
5873 src_ip=`ip_to_hex 192 168 2 2`
5874 dst_ip=`ip_to_hex 192 168 2 3`
5875 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5876 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5878 # expected packet at bar3
5879 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5880 echo $packet > expected
5881 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
5883 # Send ip packets between foo1 and vm1.
5884 (different switch, container to the VM hosting it.)
5885 src_mac="f00000010205"
5886 dst_mac="000000010203"
5887 src_ip=`ip_to_hex 192 168 1 2`
5888 dst_ip=`ip_to_hex 172 16 1 2`
5889 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5890 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5892 # expected packet at vm1
5893 src_mac="000000010202"
5894 dst_mac="f00000010203"
5895 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5896 echo $packet >> expected1
5897 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5899 # Send packets from vm1 to bar1.
5900 (different switch, A hosting VM to a container inside it)
5901 src_mac="f00000010203"
5902 dst_mac="000000010202"
5903 src_ip=`ip_to_hex 172 16 1 2`
5904 dst_ip=`ip_to_hex 192 168 2 2`
5905 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5906 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
5908 # expected packet at vm1
5909 src_mac="000000010204"
5910 dst_mac="f00000010207"
5911 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5912 echo $packet >> expected1
5913 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
5915 OVN_CLEANUP([hv1],[hv2])
5919 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
5920 AT_SKIP_IF([test $HAVE_PYTHON = no])
5924 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
5925 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
5926 # (192.168.2.0/24) connected to it.
5928 # R2 and R3 are gateway routers.
5929 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
5930 # connected to it. Note how both alice and bob have the same subnet behind it.
5931 # We are trying to simulate external network via those 2 switches. In real
5932 # world the switch ports of these switches will have addresses set as "unknown"
5933 # to make them learning switches. Or those switches will be "localnet" ones.
5935 # Create three hypervisors and create OVS ports corresponding to logical ports.
5940 ovs-vsctl add-br br-phys
5941 ovn_attach n1 br-phys 192.168.0.1
5942 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5943 set interface hv1-vif1 external-ids:iface-id=foo1 \
5944 options:tx_pcap=hv1/vif1-tx.pcap \
5945 options:rxq_pcap=hv1/vif1-rx.pcap \
5948 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5949 set interface hv1-vif2 external-ids:iface-id=bar1 \
5950 options:tx_pcap=hv1/vif2-tx.pcap \
5951 options:rxq_pcap=hv1/vif2-rx.pcap \
5956 ovs-vsctl add-br br-phys
5957 ovn_attach n1 br-phys 192.168.0.2
5958 ovs-vsctl -- add-port br-int hv2-vif1 -- \
5959 set interface hv2-vif1 external-ids:iface-id=alice1 \
5960 options:tx_pcap=hv2/vif1-tx.pcap \
5961 options:rxq_pcap=hv2/vif1-rx.pcap \
5966 ovs-vsctl add-br br-phys
5967 ovn_attach n1 br-phys 192.168.0.3
5968 ovs-vsctl -- add-port br-int hv3-vif1 -- \
5969 set interface hv3-vif1 external-ids:iface-id=bob1 \
5970 options:tx_pcap=hv3/vif1-tx.pcap \
5971 options:rxq_pcap=hv3/vif1-rx.pcap \
5975 ovn-nbctl create Logical_Router name=R1
5976 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5977 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
5979 ovn-nbctl ls-add foo
5980 ovn-nbctl ls-add bar
5981 ovn-nbctl ls-add alice
5982 ovn-nbctl ls-add bob
5983 ovn-nbctl ls-add join
5986 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5987 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5988 options:router-port=foo addresses=\"00:00:01:01:02:03\"
5991 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
5992 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
5993 options:router-port=bar addresses=\"00:00:01:01:02:04\"
5995 # Connect alice to R2
5996 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5997 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
5998 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6001 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6002 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6003 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6005 # Connect R1 to join
6006 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6007 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6008 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6010 # Connect R2 to join
6011 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6012 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6013 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6015 # Connect R3 to join
6016 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6017 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6018 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6020 # Install static routes with source ip address as the policy for routing.
6021 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6022 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6023 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6025 # Install static routes with destination ip address as the policy for routing.
6026 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6028 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6030 # Create logical port foo1 in foo
6031 ovn-nbctl lsp-add foo foo1 \
6032 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6034 # Create logical port bar1 in bar
6035 ovn-nbctl lsp-add bar bar1 \
6036 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6038 # Create logical port alice1 in alice
6039 ovn-nbctl lsp-add alice alice1 \
6040 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6042 # Create logical port bob1 in bob
6043 ovn-nbctl lsp-add bob bob1 \
6044 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6046 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6047 # packets for ARP resolution (native tunneling doesn't queue packets
6048 # for ARP resolution).
6051 # Allow some time for ovn-northd and ovn-controller to catch up.
6052 # XXX This should be more systematic.
6056 printf "%02x%02x%02x%02x" "$@"
6059 sed 's/\(00\)\{1,\}$//'
6062 # Send ip packets between foo1 and bar1
6063 # (East-west traffic should flow normally)
6064 src_mac="f00000010203"
6065 dst_mac="000001010203"
6066 src_ip=`ip_to_hex 192 168 1 2`
6067 dst_ip=`ip_to_hex 192 168 2 2`
6068 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6069 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6071 # Send ip packets between foo1 and alice1
6072 src_mac="f00000010203"
6073 dst_mac="000001010203"
6074 src_ip=`ip_to_hex 192 168 1 2`
6075 dst_ip=`ip_to_hex 172 16 1 3`
6076 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6077 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6078 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6080 # Send ip packets between bar1 and bob1
6081 src_mac="f00000010204"
6082 dst_mac="000001010204"
6083 src_ip=`ip_to_hex 192 168 2 2`
6084 dst_ip=`ip_to_hex 172 16 1 4`
6085 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6086 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6087 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6089 # Packet to expect at bar1
6090 src_mac="000001010204"
6091 dst_mac="f00000010204"
6092 src_ip=`ip_to_hex 192 168 1 2`
6093 dst_ip=`ip_to_hex 192 168 2 2`
6094 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6095 echo $expected > expected
6096 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6098 # Packet to Expect at alice1
6099 src_mac="000002010203"
6100 dst_mac="f00000010205"
6101 src_ip=`ip_to_hex 192 168 1 2`
6102 dst_ip=`ip_to_hex 172 16 1 3`
6103 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6104 echo $expected > expected
6105 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6107 # Packet to Expect at bob1
6108 src_mac="000003010203"
6109 dst_mac="f00000010206"
6110 src_ip=`ip_to_hex 192 168 2 2`
6111 dst_ip=`ip_to_hex 172 16 1 4`
6112 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6113 echo $expected > expected
6114 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6116 for sim in hv1 hv2 hv3; do
6118 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6119 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6120 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6124 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6127 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6130 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6133 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6134 OVS_APP_EXIT_AND_WAIT([ovsdb-server])