1 # OVN_CHECK_PACKETS([PCAP], [EXPECTED])
3 # This compares packets read from PCAP, in pcap format, to those read
4 # from EXPECTED, which is a text file containing packets as hex
5 # strings, one per line. If PCAP contains fewer packets than
6 # EXPECTED, it waits up to 10 seconds for more packets to appear.
8 # The implementation is an m4 macro that is mostly implemented in
9 # terms of a shell function. This reduces the size of the generated
10 # testsuite file since the shell function is only emitted once even
11 # when this macro is invoked many times.
12 m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
15 echo "checking packets in $1 against $2:"
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
19 exp_n=`wc -l < "$exp_text"`
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
27 sort $exp_text > expout
30 m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
34 AT_BANNER([OVN components])
36 AT_SETUP([ovn -- lexer])
37 dnl For lines without =>, input and expected output are identical.
38 dnl For lines with =>, input precedes => and expected output follows =>.
39 AT_DATA([test-cases.txt], [dnl
40 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41 "abc\u0020def" => "abc def"
42 " => error("Input ends inside quoted string.")dnl "
44 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45 $1 => error("`$' must be followed by a valid identifier.") 1
50 a/*/b => a error("`/*' without matching `*/'.")
52 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
54 0 1 12345 18446744073709551615
55 18446744073709551616 => error("Decimal constants must be less than 2**64.")
56 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
57 01 => error("Decimal constants must not have leading zeros.")
61 1/0 => error("Value contains unmasked 1-bits.")
65 1/ => error("Integer constant expected.")
67 1/0x123 => error("Value and mask have incompatible formats.")
74 0XFEDCBA9876543210 => 0xfedcba9876543210
75 0xfedcba9876543210fedcba9876543210
76 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
77 0x => error("Hex digits expected following 0x.")
78 0X => error("Hex digits expected following 0X.")
81 0x1/0x0 => error("Value contains unmasked 1-bits.")
83 0x. => error("Invalid syntax in hexadecimal constant.")
85 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86 256.1.2.3 => error("Invalid numeric constant.")
88 192.168.0.0/255.255.0.0 => 192.168.0.0/16
89 192.168.0.0/255.255.255.0 => 192.168.0.0/24
90 192.168.0.0/255.255.0.255
91 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
93 192.168.0.0/255.255.255.255 => 192.168.0.0/32
94 1.2.3.4:5 => 1.2.3.4 : 5
98 ff00::1234 => ff00::1234
99 2001:db8:85a3::8a2e:370:7334
100 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
101 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
103 ::ffff:c000:0280 => ::ffff:192.0.2.128
105 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
108 ff00::/ff00:: => ff00::/8
111 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
113 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
114 01:00:00:00:00:00/01:00:00:00:00:00
115 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118 fe:x => error("Invalid numeric constant.")
119 00:01:02:03:04:x => error("Invalid numeric constant.")
121 # Test that operators are tokenized as expected, even without white space.
122 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
123 & => error("`&' is only valid as part of `&&'.")
124 | => error("`|' is only valid as part of `||'.")
125 - => error("`-' is only valid as part of `--'.")
127 ^ => error("Invalid character `^' in input.")
129 AT_CAPTURE_FILE([input.txt])
130 sed 's/ =>.*//' test-cases.txt > input.txt
131 sed 's/.* => //' test-cases.txt > expout
132 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
135 dnl The OVN expression parser needs to know what fields overlap with one
136 dnl another. This test therefore verifies that all the smaller registers
137 dnl are defined as terms of subfields of the larger ones.
139 dnl When we add or remove registers this test needs to be updated, of course.
140 AT_SETUP([ovn -- registers])
141 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142 [[reg0 = xxreg0[96..127]
143 reg1 = xxreg0[64..95]
144 reg2 = xxreg0[32..63]
146 reg4 = xxreg1[96..127]
147 reg5 = xxreg1[64..95]
148 reg6 = xxreg1[32..63]
152 xreg0 = xxreg0[64..127]
153 xreg1 = xxreg0[0..63]
154 xreg2 = xxreg1[64..127]
155 xreg3 = xxreg1[0..63]
156 xreg4 = OXM_OF_PKT_REG4
157 xxreg0 = NXM_NX_XXREG0
158 xxreg1 = NXM_NX_XXREG1
162 dnl Check that the OVN conntrack field definitions are correct.
163 AT_SETUP([ovn -- conntrack fields])
164 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
165 [[ct.dnat = ct_state[7]
171 ct.snat = ct_state[6]
173 ct_label = NXM_NX_CT_LABEL
174 ct_label.blocked = ct_label[0]
175 ct_mark = NXM_NX_CT_MARK
176 ct_state = NXM_NX_CT_STATE
180 AT_SETUP([ovn -- compsition])
181 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
184 AT_SETUP([ovn -- expression parser])
185 dnl For lines without =>, input and expected output are identical.
186 dnl For lines with =>, input precedes => and expected output follows =>.
187 AT_DATA([test-cases.txt], [[
189 eth.type==0x800 => eth.type == 0x800
190 eth.type[0..15] == 0x800 => eth.type == 0x800
193 vlan.present == 1 => vlan.present
194 !(vlan.present == 0) => vlan.present
195 !(vlan.present != 1) => vlan.present
197 vlan.present == 0 => !vlan.present
198 vlan.present != 1 => !vlan.present
199 !(vlan.present == 1) => !vlan.present
200 !(vlan.present != 0) => !vlan.present
203 eth.dst[0] == 1 => eth.dst[0]
204 eth.dst[0] != 0 => eth.dst[0]
205 !(eth.dst[0] == 0) => eth.dst[0]
206 !(eth.dst[0] != 1) => eth.dst[0]
209 eth.dst[0] == 0 => !eth.dst[0]
210 eth.dst[0] != 1 => !eth.dst[0]
211 !(eth.dst[0] == 1) => !eth.dst[0]
212 !(eth.dst[0] != 0) => !eth.dst[0]
214 vlan.tci[12..15] == 0x3
215 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216 vlan.tci[12..15] != 0x3
217 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
219 !vlan.pcp => vlan.pcp == 0
220 !(vlan.pcp) => vlan.pcp == 0
227 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
228 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
229 !(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230 !(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232 !(vlan.pcp > 0x4) => vlan.pcp <= 0x4
233 0x4 == vlan.pcp => vlan.pcp == 0x4
234 0x4 != vlan.pcp => vlan.pcp != 0x4
235 0x4 < vlan.pcp => vlan.pcp > 0x4
236 0x4 <= vlan.pcp => vlan.pcp >= 0x4
237 0x4 > vlan.pcp => vlan.pcp < 0x4
238 0x4 >= vlan.pcp => vlan.pcp <= 0x4
239 !(0x4 != vlan.pcp) => vlan.pcp == 0x4
240 !(0x4 == vlan.pcp) => vlan.pcp != 0x4
241 !(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242 !(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243 !(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244 !(0x4 < vlan.pcp) => vlan.pcp <= 0x4
246 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
247 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
248 1 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
249 1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
250 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
251 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
252 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
253 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
254 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257 !(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
265 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
268 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
271 vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273 vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
275 ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276 ip6.src == ::1 => ip6.src == 0x1
278 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280 ip6.src == ::1 => ip6.src == 0x1
288 !(inport != "eth0") => inport == "eth0"
290 ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291 inport == 1 => String field inport is not compatible with integer constant.
292 ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
294 ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295 eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296 vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
298 inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299 !(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300 eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301 !(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
302 inport = "eth0" => Syntax error at `=' expecting relational operator.
304 123 == 123 => Syntax error at `123' expecting field name.
306 $name => Syntax error at `$name' expecting address set name.
308 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
309 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311 inport[1] == 1 => Cannot select subfield of string field inport.
313 eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
314 eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
315 eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319 eth.type[5..1] => Invalid bit range 5 to 1.
321 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329 123 => Syntax error at end of input expecting relational operator.
331 123 x => Syntax error at `x' expecting relational operator.
333 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337 (1 x) => Syntax error at `x' expecting `)'.
339 !0x800 != eth.type => Missing parentheses around operand of !.
341 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343 eth.dst == {} => Syntax error at `}' expecting constant.
345 eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
347 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
349 1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
351 eth.dst[40] x => Syntax error at `x' expecting end of input.
353 ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
354 eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
356 sed 's/ =>.*//' test-cases.txt > input.txt
357 sed 's/.* => //' test-cases.txt > expout
358 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
361 AT_SETUP([ovn -- expression annotation])
362 dnl Input precedes =>, expected output follows =>.
363 AT_DATA([test-cases.txt], [[
364 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
365 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
366 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
367 ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
368 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
370 ip => eth.type == 0x800 || eth.type == 0x86dd
371 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
372 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
373 ip > 0 => Only == and != operators may be used with nominal field ip.
374 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
375 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
377 vlan.present => vlan.tci[12]
378 !vlan.present => !vlan.tci[12]
380 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
381 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
382 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
384 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
385 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
386 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
388 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
389 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
390 mutual_recurse_1 != 0 => Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_1'.
391 mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
393 sed 's/ =>.*//' test-cases.txt > input.txt
394 sed 's/.* => //' test-cases.txt > expout
395 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
398 AT_SETUP([ovn -- 1-term expression conversion])
399 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
400 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
404 AT_SETUP([ovn -- 2-term expression conversion])
405 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
406 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
410 AT_SETUP([ovn -- 3-term expression conversion])
411 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
412 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
416 AT_SETUP([ovn -- 3-term numeric expression simplification])
417 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
418 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
422 AT_SETUP([ovn -- 4-term string expression simplification])
423 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
424 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
428 AT_SETUP([ovn -- 3-term mixed expression simplification])
429 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
430 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
434 AT_SETUP([ovn -- simplification special cases])
436 echo "$1" | ovstest test-ovn simplify-expr
438 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
440 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
442 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
443 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
445 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
446 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
448 AT_CHECK([simplify 'tcp.dst > 0'], [0],
449 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
451 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
452 [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
456 AT_SETUP([ovn -- is_chassis_resident simplification])
458 echo "$1" | ovstest test-ovn simplify-expr
460 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
462 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
464 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
466 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
470 AT_SETUP([ovn -- 4-term numeric expression normalization])
471 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
472 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
476 AT_SETUP([ovn -- 4-term string expression normalization])
477 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
478 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
482 AT_SETUP([ovn -- 4-term mixed expression normalization])
483 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
484 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
488 AT_SETUP([ovn -- 5-term numeric expression normalization])
489 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
490 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
494 AT_SETUP([ovn -- 5-term string expression normalization])
495 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
500 AT_SETUP([ovn -- 5-term mixed expression normalization])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
506 AT_SETUP([ovn -- 4-term numeric expressions to flows])
507 AT_KEYWORDS([expression])
508 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
509 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
513 AT_SETUP([ovn -- 4-term string expressions to flows])
514 AT_KEYWORDS([expression])
515 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
516 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
520 AT_SETUP([ovn -- 4-term mixed expressions to flows])
521 AT_KEYWORDS([expression])
522 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
523 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
527 AT_SETUP([ovn -- 3-term numeric expressions to flows])
528 AT_KEYWORDS([expression])
529 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
530 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
534 AT_SETUP([ovn -- converting expressions to flows -- string fields])
535 AT_KEYWORDS([expression])
537 echo "$1" | ovstest test-ovn expr-to-flows | sort
539 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
541 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
543 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
545 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
549 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
553 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
555 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
560 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
566 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
571 AT_SETUP([ovn -- converting expressions to flows -- address sets])
572 AT_KEYWORDS([expression])
574 echo "$1" | ovstest test-ovn expr-to-flows | sort
576 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
581 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
586 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
592 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
604 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
610 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, 00:00:00:00:00:02, 00:00:00:00:00:03}'], [0], [dnl
611 dl_src=00:00:00:00:00:01
612 dl_src=00:00:00:00:00:02
613 dl_src=00:00:00:00:00:03
615 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
616 dl_src=00:00:00:00:00:01
617 dl_src=00:00:00:00:00:02
618 dl_src=00:00:00:00:00:03
620 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
621 dl_src=00:00:00:00:00:01
622 dl_src=00:00:00:00:00:02
623 dl_src=00:00:00:00:00:03
624 dl_src=ba:be:be:ef:de:ad
626 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
629 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
632 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
635 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
638 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
639 ip,nw_src=0.0.0.0/1.0.0.0
640 ip,nw_src=128.0.0.0/1
641 ip,nw_src=16.0.0.0/16.0.0.0
642 ip,nw_src=2.0.0.0/2.0.0.0
643 ip,nw_src=32.0.0.0/32.0.0.0
644 ip,nw_src=4.0.0.0/4.0.0.0
645 ip,nw_src=64.0.0.0/64.0.0.0
646 ip,nw_src=8.0.0.0/8.0.0.0
648 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
649 ip,nw_src=0.0.0.0/1.0.0.0
650 ip,nw_src=128.0.0.0/1
651 ip,nw_src=16.0.0.0/16.0.0.0
652 ip,nw_src=2.0.0.0/2.0.0.0
653 ip,nw_src=32.0.0.0/32.0.0.0
654 ip,nw_src=4.0.0.0/4.0.0.0
655 ip,nw_src=64.0.0.0/64.0.0.0
656 ip,nw_src=8.0.0.0/8.0.0.0
660 AT_SETUP([ovn -- action parsing])
661 dnl Unindented text is input (a set of OVN logical actions).
662 dnl Indented text is expected output.
663 AT_DATA([test-cases.txt],
668 Syntax error at `next' expecting end of input.
670 Syntax error at `drop' expecting action.
674 encodes as resubmit(,64)
678 encodes as resubmit(,19)
681 encodes as resubmit(,19)
683 encodes as resubmit(,8)
685 encodes as resubmit(,31)
688 Syntax error at `)' expecting "pipeline" or "table".
690 Syntax error at `;' expecting `)'.
692 "next" action cannot advance beyond table 23.
696 encodes as resubmit(,19)
697 next(pipeline=ingress);
699 encodes as resubmit(,19)
700 next(table=11, pipeline=ingress);
702 encodes as resubmit(,19)
703 next(pipeline=ingress, table=11);
705 encodes as resubmit(,19)
707 next(pipeline=egress);
708 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
712 encodes as resubmit(,18)
714 # Loading a constant value.
716 formats as tcp.dst = 80;
717 encodes as set_field:80->tcp_dst
718 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
720 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
722 encodes as set_field:0x4000/0xe000->vlan_tci
723 has prereqs vlan.tci[12]
724 vlan.tci[13..15] = 2;
725 encodes as set_field:0x4000/0xe000->vlan_tci
727 encodes as set_field:0->reg14
729 formats as ip.ttl = 4;
730 encodes as set_field:4->nw_ttl
731 has prereqs eth.type == 0x800 || eth.type == 0x86dd
732 outport="eth0"; next; outport="LOCAL"; next;
733 formats as outport = "eth0"; next; outport = "LOCAL"; next;
734 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
737 Cannot select subfield of string field inport.
739 Cannot select subfield of nominal field ip.proto.
741 Syntax error at `==' expecting `=' or `<->'.
743 Predicate symbol ip used where lvalue required.
745 Field ip.proto is not modifiable.
747 Syntax error at `{' expecting constant.
749 Syntax error at `{' expecting constant.
751 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
753 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'.
755 Predicate symbol vlan.present used where lvalue required.
757 # Moving one field into another.
759 formats as reg0 = reg1;
760 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
761 vlan.pcp = reg0[0..2];
762 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
763 has prereqs vlan.tci[12]
764 reg0[10] = vlan.pcp[1];
765 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
766 has prereqs vlan.tci[12]
768 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
770 reg0[0] = vlan.present;
771 Predicate symbol vlan.present used where lvalue required.
773 Can't assign 11-bit value to 32-bit destination.
775 Can't assign integer field (reg0) to string field (inport).
777 String fields inport and big_string are incompatible for assignment.
778 ip.proto = reg0[0..7];
779 Field ip.proto is not modifiable.
783 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]
784 vlan.pcp <-> reg0[0..2];
785 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]
786 has prereqs vlan.tci[12]
787 reg0[10] <-> vlan.pcp[1];
788 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
789 has prereqs vlan.tci[12]
791 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
793 reg0[0] <-> vlan.present;
794 Predicate symbol vlan.present used where lvalue required.
795 reg0 <-> reg1[0..10];
796 Can't exchange 32-bit field with 11-bit field.
798 Can't exchange string field (inport) with integer field (reg0).
799 inport <-> big_string;
800 String fields inport and big_string are incompatible for exchange.
801 ip.proto <-> reg0[0..7];
802 Field ip.proto is not modifiable.
803 reg0[0..7] <-> ip.proto;
804 Field ip.proto is not modifiable.
811 Syntax error at end of input expecting `--'.
815 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
819 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
821 ct_lb(192.168.1.2:80, 192.168.1.3:80);
824 ct_lb(192.168.1.2, 192.168.1.3, );
825 formats as ct_lb(192.168.1.2, 192.168.1.3);
828 ct_lb(fd0f::2, fd0f::3, );
829 formats as ct_lb(fd0f::2, fd0f::3);
834 Syntax error at `)' expecting port number.
835 ct_lb(192.168.1.2:123456);
836 Syntax error at `123456' expecting port number.
838 Syntax error at `foo' expecting IP address.
839 ct_lb([192.168.1.2]);
840 Syntax error at `192.168.1.2' expecting IPv6 address.
844 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
849 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
852 formats as ct_commit;
853 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
855 ct_commit(ct_mark=1);
856 formats as ct_commit(ct_mark=0x1);
857 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
859 ct_commit(ct_mark=1/1);
860 formats as ct_commit(ct_mark=0x1/0x1);
861 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
863 ct_commit(ct_label=1);
864 formats as ct_commit(ct_label=0x1);
865 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
867 ct_commit(ct_label=1/1);
868 formats as ct_commit(ct_label=0x1/0x1);
869 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
871 ct_commit(ct_mark=1, ct_label=2);
872 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
873 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
876 ct_commit(ct_label=0x01020304050607080910111213141516);
877 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
878 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
880 ct_commit(ct_label=0x181716151413121110090807060504030201);
881 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
882 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
884 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
885 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
887 ct_commit(ct_label=18446744073709551615);
888 formats as ct_commit(ct_label=0xffffffffffffffff);
889 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
891 ct_commit(ct_label=18446744073709551616);
892 Decimal constants must be less than 2**64.
896 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
898 ct_dnat(192.168.1.2);
899 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
902 ct_dnat(192.168.1.2, 192.168.1.3);
903 Syntax error at `,' expecting `)'.
905 Syntax error at `foo' expecting IPv4 address.
907 Syntax error at `foo' expecting IPv4 address.
909 Syntax error at `)' expecting IPv4 address.
913 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
915 ct_snat(192.168.1.2);
916 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
919 ct_snat(192.168.1.2, 192.168.1.3);
920 Syntax error at `,' expecting `)'.
922 Syntax error at `foo' expecting IPv4 address.
924 Syntax error at `foo' expecting IPv4 address.
926 Syntax error at `)' expecting IPv4 address.
933 clone { ip4.dst = 255.255.255.255; output; }; next;
934 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
935 has prereqs eth.type == 0x800
938 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
939 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
942 formats as arp { drop; };
943 encodes as controller(userdata=00.00.00.00.00.00.00.00)
947 get_arp(outport, ip4.dst);
948 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[]
949 has prereqs eth.type == 0x800
950 get_arp(inport, reg0);
951 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[]
954 Syntax error at `;' expecting `('.
956 Syntax error at `)' expecting field name.
958 Syntax error at `)' expecting `,'.
959 get_arp(inport ip4.dst);
960 Syntax error at `ip4.dst' expecting `,'.
961 get_arp(inport, ip4.dst;
962 Syntax error at `;' expecting `)'.
963 get_arp(inport, eth.dst);
964 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
965 get_arp(inport, outport);
966 Cannot use string field outport where numeric field is required.
967 get_arp(reg0, ip4.dst);
968 Cannot use numeric field reg0 where string field is required.
971 put_arp(inport, arp.spa, arp.sha);
972 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[]
973 has prereqs eth.type == 0x806 && eth.type == 0x806
976 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
977 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)
978 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");
979 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");
980 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)
981 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);
982 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);
983 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)
985 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
986 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
987 reg1[0] = put_dhcp_opts();
988 put_dhcp_opts requires offerip to be specified.
989 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
990 Syntax error at `x' expecting DHCPv4 option name.
991 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
992 put_dhcp_opts requires offerip to be specified.
993 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
994 Syntax error at `"hi"'.
995 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
996 Syntax error at `xyzzy' expecting DHCPv4 option name.
997 reg1[0] = put_dhcp_opts(offerip="xyzzy");
998 DHCPv4 option offerip requires numeric value.
999 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1000 DHCPv4 option domain requires string value.
1003 nd_ns { nd.target = xxreg0; output; };
1004 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1008 formats as nd_ns { drop; };
1009 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1013 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; };
1014 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1015 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)
1019 get_nd(outport, ip6.dst);
1020 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[]
1021 has prereqs eth.type == 0x86dd
1022 get_nd(inport, xxreg0);
1023 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[]
1025 Syntax error at `;' expecting `('.
1027 Syntax error at `)' expecting field name.
1029 Syntax error at `)' expecting `,'.
1030 get_nd(inport ip6.dst);
1031 Syntax error at `ip6.dst' expecting `,'.
1032 get_nd(inport, ip6.dst;
1033 Syntax error at `;' expecting `)'.
1034 get_nd(inport, eth.dst);
1035 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1036 get_nd(inport, outport);
1037 Cannot use string field outport where numeric field is required.
1038 get_nd(xxreg0, ip6.dst);
1039 Cannot use numeric field xxreg0 where string field is required.
1042 put_nd(inport, nd.target, nd.sll);
1043 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[]
1044 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)
1047 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1048 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)
1049 reg1[0] = put_dhcpv6_opts();
1050 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1051 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1052 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1053 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)
1054 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1055 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1056 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)
1057 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1058 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)
1059 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1060 Syntax error at `x' expecting DHCPv6 option name.
1061 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1062 Syntax error at `"hi"'.
1063 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1064 Syntax error at `xyzzy' expecting DHCPv6 option name.
1065 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1066 DHCPv6 option ia_addr requires numeric value.
1067 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1068 DHCPv6 option domain_search requires string value.
1072 encodes as set_queue:0
1074 encodes as set_queue:61440
1076 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1079 reg1[0] = dns_lookup();
1080 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1082 reg1[0] = dns_lookup("foo");
1083 dns_lookup doesn't take any parameters
1087 Rate 0 for set_meter is not in valid.
1090 set_meter(100, 1000);
1092 set_meter(100, 1000, );
1093 Syntax error at `,' expecting `)'.
1094 set_meter(4294967295, 4294967295);
1098 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1099 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1101 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1102 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1104 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1105 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1107 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1108 slla option not present
1109 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1110 prefix option can't be set when address mode is dhcpv6_stateful.
1111 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1112 prefix option can't be set when address mode is dhcpv6_stateful.
1113 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1114 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1115 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1116 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1117 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1118 Syntax error at `dhcpv6_stateless' expecting constant.
1119 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1120 Invalid value for "prefix" option
1121 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1122 Invalid value for "addr_mode" option
1123 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1124 IPv6 ND RA option mtu requires numeric value.
1125 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1126 Invalid value for "mtu" option
1129 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1130 encodes as controller(userdata=00.00.00.0a.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1134 formats as icmp4 { drop; };
1135 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1138 # Contradictionary prerequisites (allowed but not useful):
1139 ip4.src = ip6.src[0..31];
1140 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1141 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1142 ip4.src <-> ip6.src[0..31];
1143 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[]
1144 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1146 # Miscellaneous negative tests.
1148 Syntax error at `;'.
1150 Syntax error at `xyzzy' expecting action.
1152 Syntax error at `123'.
1154 Syntax error at `xyzzy' expecting action.
1156 Syntax error at end of input expecting `;'.
1158 sed '/^[[ ]]/d' test-cases.txt > input.txt
1159 cp test-cases.txt expout
1160 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1163 AT_BANNER([OVN end-to-end tests])
1165 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1166 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1167 AT_KEYWORDS([ovnarp])
1168 AT_SKIP_IF([test $HAVE_PYTHON = no])
1171 # Create hypervisors hv[123].
1172 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1173 # Add all of the vifs to a single logical switch lsw0.
1174 # Turn on port security on all the vifs except vif[123]1.
1175 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1176 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1177 ovn-nbctl ls-add lsw0
1182 ovs-vsctl add-br br-phys
1183 ovn_attach n1 br-phys 192.168.0.$i
1186 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
1187 ovn-nbctl lsp-add lsw0 lp$i$j
1188 if test $j = 1; then
1189 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1191 if test $j = 3; then
1192 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1194 ip_addrs="192.168.0.$i$j"
1196 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1197 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1201 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1202 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1203 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1204 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\"
1205 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1207 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1208 # packets for ARP resolution (native tunneling doesn't queue packets
1209 # for ARP resolution).
1212 # Allow some time for ovn-northd and ovn-controller to catch up.
1213 # XXX This should be more systematic.
1216 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1217 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1218 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1219 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1221 # Given the name of a logical port, prints the name of the hypervisor
1222 # on which it is located.
1227 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1229 # This shell function causes a packet to be received on INPORT. The packet's
1230 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1231 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1232 # more) list the VIFs on which the packet should be received. INPORT and the
1233 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1240 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1241 hv=`vif_to_hv $inport`
1243 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1245 echo $packet >> $outport.expected
1249 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1251 # Causes a packet to be received on INPORT. The packet is an ARP
1252 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1253 # it should be the hardware address of the target to expect to receive in an
1254 # ARP reply; otherwise no reply is expected.
1256 # INPORT is an logical switch port number, e.g. 11 for vif11.
1257 # SHA and REPLY_HA are each 12 hex digits.
1258 # SPA and TPA are each 8 hex digits.
1260 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1261 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1262 hv=`vif_to_hv $inport`
1263 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1265 if test X$reply_ha = X; then
1266 # Expect to receive the broadcast ARP on the other logical switch ports
1267 # if no reply is expected.
1271 if test $i$j != $inport; then
1272 echo $request >> $i$j.expected
1277 # Expect to receive the reply, if any.
1278 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1279 echo $reply >> $inport.expected
1284 printf "%02x%02x%02x%02x" "$@"
1287 # Send packets between all pairs of source and destination ports:
1289 # 1. Unicast packets are delivered to exactly one logical switch port
1290 # (except that packets destined to their input ports are dropped).
1292 # 2. Broadcast and multicast are delivered to all logical switch ports
1293 # except the input port.
1295 # 3. When port security is turned on, the switch drops packets from the wrong
1298 # 4. The switch drops all packets with a VLAN tag.
1300 # 5. The switch drops all packets with a multicast source address. (This only
1301 # affects behavior when port security is turned off, since otherwise port
1302 # security would drop the packet anyway.)
1304 # 6. The switch delivers packets with an unknown destination to logical
1305 # switch ports with "unknown" among their MAC addresses (and port
1306 # security disabled).
1308 # 7. The switch drops unicast packets that violate an ACL.
1310 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1312 # 9. OVN generates responses to ARP requests for known IPs, except for
1313 # requests from a port for the port's own IP.
1315 # 10. No response to ARP requests for unknown IPs.
1328 if test $d != $s; then unicast=$d; else unicast=; fi
1329 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1331 if test $d != $s && test $js = 1; then
1336 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1338 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1339 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1340 if test $d = $s || (test $js = 1 && test $d = 33); then
1341 # Source of 11, 21, or 31 and dest of 33 should be dropped
1342 # due to the 4th ACL that uses address_set(set1).
1347 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1348 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1349 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1350 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1352 test_packet $s f000000000$d f00000000055 810000091234 #4
1353 test_packet $s f000000000$d 0100000000$s $s$d #5
1355 if test $d != $s && test $jd = 1; then
1356 unknown="$unknown $d"
1358 bcast="$bcast $unicast"
1359 bacl2="$bacl2 $acl2"
1360 bacl3="$bacl3 $acl3"
1362 sip=`ip_to_hex 192 168 0 $is$js`
1363 tip=`ip_to_hex 192 168 0 $id$jd`
1364 tip_unknown=`ip_to_hex 11 11 11 11`
1365 if test $d != $s; then
1366 reply_ha=f000000000$d
1370 test_arp $s f000000000$s $sip $tip $reply_ha #9
1371 test_arp $s f000000000$s $sip $tip_unknown #10
1373 if test $jd = 3; then
1374 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1375 tip=`ip_to_hex 192 169 0 $id$jd`
1376 test_arp $s f000000000$s $sip $tip $reply_ha #9
1381 # Broadcast and multicast.
1382 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1383 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1384 if test $js = 1; then
1385 bcast_impersonate=$bcast
1389 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1391 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1393 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1394 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1395 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1396 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1397 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1398 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1402 # set address for lp13 with invalid characters.
1403 # lp13 should be configured with only 192.168.0.13.
1404 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1406 # Allow some time for ovn-northd and ovn-controller to catch up.
1407 # XXX This should be more systematic.
1410 sip=`ip_to_hex 192 168 0 11`
1411 tip=`ip_to_hex 192 168 0 13`
1412 test_arp 11 f00000000011 $sip $tip f00000000013
1414 tip=`ip_to_hex 192 169 0 13`
1415 #arp request for 192.169.0.13 should be flooded
1416 test_arp 11 f00000000011 $sip $tip
1418 # dump information and flows with counters
1419 ovn-sbctl dump-flows -- list multicast_group
1421 echo "------ hv1 dump ------"
1422 as hv1 ovs-vsctl show
1423 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1425 echo "------ hv2 dump ------"
1426 as hv2 ovs-vsctl show
1427 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1429 echo "------ hv3 dump ------"
1430 as hv3 ovs-vsctl show
1431 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1433 # Now check the packets actually received against the ones expected.
1436 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1440 OVN_CLEANUP([hv1],[hv2],[hv3])
1444 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1445 AT_SKIP_IF([test $HAVE_PYTHON = no])
1448 # Create a logical switch and some logical ports.
1449 # Turn on port security on all lports except ls1.
1450 # Make ls1 a destination for unknown MACs.
1451 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1452 ovn-nbctl ls-add lsw0
1453 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1455 ovn-nbctl lsp-add lsw0 lp$i
1457 ovn-nbctl --wait=sb sync
1459 ovn-sbctl lsp-bind lp$i hv0
1460 if test $i = 1; then
1461 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1463 if test $i = 3; then
1464 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1466 ip_addrs="192.168.0.$i"
1468 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1469 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1472 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1473 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1474 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1475 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1476 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1478 ovn-nbctl --wait=sb sync
1479 on_exit 'kill `cat ovn-trace.pid`'
1480 ovn-trace --detach --pidfile --no-chdir
1482 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1484 # This shell function causes a packet to be received on INPORT. The packet's
1485 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1486 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1487 # more) list the VIFs on which the packet should be received. INPORT and the
1488 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1490 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1491 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1494 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1495 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1500 echo "output(\"lp$outport\");"
1503 AT_CAPTURE_FILE([trace])
1504 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1507 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1509 # Causes a packet to be received on INPORT. The packet is an ARP
1510 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1511 # it should be the hardware address of the target to expect to receive in an
1512 # ARP reply; otherwise no reply is expected.
1514 # INPORT is an logical switch port number, e.g. 11 for vif11.
1515 # SHA and REPLY_HA are each 12 hex digits.
1516 # SPA and TPA are each 8 hex digits.
1518 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1520 local request="inport == \"lp$inport\"
1521 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1522 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1523 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1525 if test -z "$reply_ha"; then
1529 if test $i != $inport; then
1530 reply="${reply}output(\"lp$i\");
1537 eth.src = $reply_ha;
1540 arp.sha = $reply_ha;
1543 output(\"lp$inport\");
1547 AT_CAPTURE_FILE([trace])
1548 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1551 # Send packets between all pairs of source and destination ports:
1553 # 1. Unicast packets are delivered to exactly one logical switch port
1554 # (except that packets destined to their input ports are dropped).
1556 # 2. Broadcast and multicast are delivered to all logical switch ports
1557 # except the input port.
1559 # 3. When port security is turned on, the switch drops packets from the wrong
1562 # 4. The switch drops all packets with a VLAN tag.
1564 # 5. The switch drops all packets with a multicast source address. (This only
1565 # affects behavior when port security is turned off, since otherwise port
1566 # security would drop the packet anyway.)
1568 # 6. The switch delivers packets with an unknown destination to logical
1569 # switch ports with "unknown" among their MAC addresses (and port
1570 # security disabled).
1572 # 7. The switch drops unicast packets that violate an ACL.
1574 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1576 # 9. OVN generates responses to ARP requests for known IPs, except for
1577 # requests from a port for the port's own IP.
1579 # 10. No response to ARP requests for unknown IPs.
1589 if test $d != $s; then unicast=$d; else unicast=; fi
1590 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1592 if test $d != $s && test $s = 1; then
1597 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1599 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1600 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1601 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1602 # Source of 1 or 2 and dest of 3 should be dropped
1603 # due to the 4th ACL that uses address_set(set1).
1610 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1611 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1612 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1613 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1615 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1616 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1618 if test $d != $s && test $d = 1; then
1619 unknown="$unknown $d"
1621 bcast="$bcast $unicast"
1622 bacl2="$bacl2 $acl2"
1623 bacl3="$bacl3 $acl3"
1627 tip_unknown=11.11.11.11
1628 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1629 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1630 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1632 if test $d = 3; then
1633 # lp3 has an additional ip 192.169.0.[123]3.
1635 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1639 # Broadcast and multicast.
1640 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1641 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1642 if test $s = 1; then
1643 bcast_impersonate=$bcast
1647 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1649 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1652 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1653 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1654 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1657 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1658 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1659 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1664 # 2 hypervisors, 4 logical ports per HV
1665 # 2 locally attached networks (one flat, one vlan tagged over same device)
1666 # 2 ports per HV on each network
1667 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1668 AT_SKIP_IF([test $HAVE_PYTHON = no])
1671 # In this test cases we create 3 switches, all connected to same
1672 # physical network (through br-phys on each HV). Each switch has
1673 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1674 # of VIF port name indicates the hypervisor it is bound to, e.g.
1675 # lp23 means VIF 3 on hv2.
1677 # Each switch's VLAN tag and their logical switch ports are:
1680 # - ports: lp11, lp12, lp21, lp22
1683 # - tagged with VLAN 101
1684 # - ports: lp13, lp14, lp23, lp24
1687 # - ports: lp15, lp25
1689 # Note: a localnet port is created for each switch to connect to
1694 ovn-nbctl ls-add $ls_name
1696 if test $i -eq 2; then
1697 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1699 ovn-nbctl lsp-add $ls_name $ln_port_name
1701 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1702 ovn-nbctl lsp-set-type $ln_port_name localnet
1703 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1708 # Prints the name of the logical switch that contains LSP.
1711 lp?[[12]]) echo ls1 ;; dnl (
1712 lp?[[34]]) echo ls2 ;; dnl (
1713 lp?5) echo ls3 ;; dnl (
1714 *) AT_FAIL_IF([:]) ;;
1722 ovs-vsctl add-br br-phys
1723 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1724 ovn_attach n1 br-phys 192.168.0.$i
1726 for j in 1 2 3 4 5; do
1727 ovs-vsctl add-port br-int vif$i$j -- \
1728 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1729 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1730 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1734 ls_name=$(lsp_to_ls $lsp_name)
1736 ovn-nbctl lsp-add $ls_name $lsp_name
1737 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1738 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1740 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1743 ovn-nbctl --wait=sb sync
1744 ovn-sbctl dump-flows
1748 # XXX This is now the 3rd copy of these functions in this file ...
1750 # Given the name of a logical port, prints the name of the hypervisor
1751 # on which it is located.
1756 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1758 # This shell function causes a packet to be received on INPORT. The packet's
1759 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1760 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1761 # logical switch port numbers, e.g. 11 for vif11.
1763 # EOUT is the end-to-end output port, that is, where the packet will end up
1764 # after possibly bouncing through one or more localnet ports. LOUT is the
1765 # logical output port, which might be a localnet port, as seen by ovn-trace
1766 # (which doesn't know what localnet ports are connected to and therefore can't
1767 # figure out the end-to-end answer).
1769 for j in 1 2 3 4 5; do
1774 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1777 # First try tracing the packet.
1778 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1779 if test $lout != drop; then
1780 echo "output(\"$lout\");"
1782 AT_CAPTURE_FILE([trace])
1783 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1785 # Then actually send a packet, for an end-to-end test.
1786 local packet=$(echo $dst$src | sed 's/://g')${eth}
1787 hv=`vif_to_hv $inport`
1789 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1790 if test $eout != drop; then
1791 echo $packet >> ${eout#lp}.expected
1795 # lp11 and lp21 are on the same network (phys, untagged)
1796 # and on different hypervisors
1797 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1798 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1800 # lp11 and lp12 are on the same network (phys, untagged)
1801 # and on the same hypervisor
1802 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1803 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1805 # lp13 and lp23 are on the same network (phys, VLAN 101)
1806 # and on different hypervisors
1807 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1808 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1810 # lp13 and lp14 are on the same network (phys, VLAN 101)
1811 # and on the same hypervisor
1812 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1813 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1815 # lp11 and lp15 are on the same network (phys, untagged),
1816 # same hypervisor, and on different switches
1817 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1818 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1820 # lp11 and lp25 are on the same network (phys, untagged),
1821 # different hypervisors, and on different switches
1822 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1823 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1825 # Ports that should not be able to communicate
1826 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1827 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1828 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1829 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1830 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1831 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1832 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1833 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1835 # Dump a bunch of info helpful for debugging if there's a failure.
1837 echo "------ OVN dump ------"
1841 echo "------ hv1 dump ------"
1842 as hv1 ovs-vsctl show
1843 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1845 echo "------ hv2 dump ------"
1846 as hv2 ovs-vsctl show
1847 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1849 # Now check the packets actually received against the ones expected.
1851 for j in 1 2 3 4 5; do
1852 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1856 OVN_CLEANUP([hv1],[hv2])
1860 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1862 AT_SKIP_IF([test $HAVE_PYTHON = no])
1865 # Configure the Northbound database
1866 ovn-nbctl ls-add lsw0
1868 ovn-nbctl lsp-add lsw0 lp1
1869 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1871 ovn-nbctl lsp-add lsw0 lp2
1872 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1874 ovn-nbctl lsp-add lsw0 lp-vtep
1875 ovn-nbctl lsp-set-type lp-vtep vtep
1876 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1877 ovn-nbctl lsp-set-addresses lp-vtep unknown
1879 # lpr, lr and lrp1 are used for the ARP request handling test only.
1880 ovn-nbctl lsp-add lsw0 lpr
1882 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1883 ovn-nbctl set Logical_Switch_Port lpr type=router \
1884 options:router-port=lrp1 \
1885 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1888 net_add n1 # Network to connect hv1, hv2, and vtep
1889 net_add n2 # Network to connect vtep and hv3
1891 # Create hypervisor hv1 connected to n1
1894 ovs-vsctl add-br br-phys
1895 ovn_attach n1 br-phys 192.168.0.1
1896 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
1898 # Create hypervisor hv2 connected to n1
1901 ovs-vsctl add-br br-phys
1902 ovn_attach n1 br-phys 192.168.0.2
1903 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
1906 # Start the vtep emulator with a leg in both networks
1910 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1911 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1913 ovs-vsctl add-br br-phys
1914 net_attach n1 br-phys
1916 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1917 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1918 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1919 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1921 ovs-vsctl add-br br-vtep
1922 net_attach n2 br-vtep
1924 vtep-ctl add-ps br-vtep
1925 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1926 vtep-ctl add-ls lsw0
1928 start_daemon ovs-vtep br-vtep
1929 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1931 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1933 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1935 # It takes more time for the update to be processed by ovs-vtep.
1938 # Add hv3 on the other side of the vtep
1941 ovs-vsctl add-br br-phys
1942 net_attach n2 br-phys
1944 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
1946 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1947 # packets for ARP resolution (native tunneling doesn't queue packets
1948 # for ARP resolution).
1951 # Allow some time for ovn-northd and ovn-controller to catch up.
1952 # XXX This should be more systematic.
1955 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1957 # This shell function causes a packet to be received on INPORT. The packet's
1958 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1959 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1960 # more) list the VIFs on which the packet should be received. INPORT and the
1961 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
1966 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1967 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1970 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1972 echo $packet >> $outport.expected
1976 # Send packets between all pairs of source and destination ports:
1978 # 1. Unicast packets are delivered to exactly one logical switch port
1979 # (except that packets destined to their input ports are dropped).
1981 # 2. Broadcast and multicast are delivered to all logical switch ports
1982 # except the input port.
1984 # 3. The switch delivers packets with an unknown destination to logical
1985 # switch ports with "unknown" among their MAC addresses (and port
1986 # security disabled).
1991 if test $d != $s; then unicast=$d; else unicast=; fi
1992 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1994 # The vtep (vif3) is the only one configured for "unknown"
1995 if test $d != $s && test $d = 3; then
1996 unknown="$unknown $d"
1998 bcast="$bcast $unicast"
2001 # Broadcast and multicast.
2002 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2003 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2005 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2008 # ARP request should not be responded to by logical switch router
2009 # type arp responder on HV1 and HV2 and should reach directly to
2012 printf "%02x%02x%02x%02x" "$@"
2015 spa=`ip_to_hex 192 168 1 2`
2016 tpa=`ip_to_hex 192 168 1 1`
2017 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2018 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2019 echo $request >> 1.expected
2020 echo $request >> 2.expected
2022 # dump information with counters
2023 echo "------ OVN dump ------"
2027 echo "---------SB dump-----"
2028 ovn-sbctl list datapath_binding
2029 echo "---------------------"
2030 ovn-sbctl list port_binding
2031 echo "---------------------"
2032 ovn-sbctl dump-flows
2034 echo "------ hv1 dump ------"
2035 as hv1 ovs-vsctl show
2036 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2037 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2039 echo "------ hv2 dump ------"
2040 as hv2 ovs-vsctl show
2041 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2042 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2044 echo "------ hv3 dump ------"
2045 as hv3 ovs-vsctl show
2046 # note: hv3 has no logical port bind, thus it should not have br-int
2047 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2048 [ovs-ofctl: br-int is not a bridge or a socket
2051 # Now check the packets actually received against the ones expected.
2053 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2056 # Gracefully terminate daemons
2057 OVN_CLEANUP([hv1],[hv2],[vtep])
2058 OVN_CLEANUP_VSWITCH([hv3])
2062 # Similar test to "hardware GW"
2063 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2064 AT_SKIP_IF([test $HAVE_PYTHON = no])
2067 # Configure the Northbound database
2068 ovn-nbctl ls-add lsw0
2070 ovn-nbctl lsp-add lsw0 lp1
2071 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2073 ovn-nbctl lsp-add lsw0 lp2
2074 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2076 ovn-nbctl lsp-add lsw0 lp-gw
2077 ovn-nbctl lsp-set-type lp-gw l2gateway
2078 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2079 ovn-nbctl lsp-set-addresses lp-gw unknown
2081 net_add n1 # Network to connect hv1, hv2, and gw
2082 net_add n2 # Network to connect gw and hv3
2084 # Create hypervisor hv1 connected to n1
2087 ovs-vsctl add-br br-phys
2088 ovn_attach n1 br-phys 192.168.0.1
2089 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
2091 # Create hypervisor hv2 connected to n1
2094 ovs-vsctl add-br br-phys
2095 ovn_attach n1 br-phys 192.168.0.2
2096 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
2098 # Create hypervisor hv_gw connected to n1 and n2
2099 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2102 ovs-vsctl add-br br-phys
2103 ovn_attach n1 br-phys 192.168.0.3
2104 ovs-vsctl add-br br-phys2
2105 net_attach n2 br-phys2
2106 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2108 # Add hv3 on the other side of the GW
2111 ovs-vsctl add-br br-phys
2112 net_attach n2 br-phys
2113 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
2116 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2117 # packets for ARP resolution (native tunneling doesn't queue packets
2118 # for ARP resolution).
2121 # Allow some time for ovn-northd and ovn-controller to catch up.
2122 # XXX This should be more systematic.
2125 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2127 # This shell function causes a packet to be received on INPORT. The packet's
2128 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2129 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2130 # more) list the VIFs on which the packet should be received. INPORT and the
2131 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2136 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2137 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2140 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2142 echo $packet >> $outport.expected
2146 # Send packets between all pairs of source and destination ports:
2148 # 1. Unicast packets are delivered to exactly one lport (except that packets
2149 # destined to their input ports are dropped).
2151 # 2. Broadcast and multicast are delivered to all lports except the input port.
2153 # 3. The lswitch delivers packets with an unknown destination to lports with
2154 # "unknown" among their MAC addresses (and port security disabled).
2159 if test $d != $s; then unicast=$d; else unicast=; fi
2160 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2162 # The vtep (vif3) is the only one configured for "unknown"
2163 if test $d != $s && test $d = 3; then
2164 unknown="$unknown $d"
2166 bcast="$bcast $unicast"
2169 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2170 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2171 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2174 echo "------ ovn-nbctl show ------"
2176 echo "------ ovn-sbctl show ------"
2179 echo "------ hv1 ------"
2180 as hv1 ovs-vsctl show
2181 echo "------ hv1 br-int ------"
2182 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2183 echo "------ hv1 br-phys ------"
2184 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2186 echo "------ hv2 ------"
2187 as hv2 ovs-vsctl show
2188 echo "------ hv2 br-int ------"
2189 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2190 echo "------ hv2 br-phys ------"
2191 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2193 echo "------ hv_gw ------"
2194 as hv_gw ovs-vsctl show
2195 echo "------ hv_gw br-phys ------"
2196 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2197 echo "------ hv_gw br-phys2 ------"
2198 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2200 echo "------ hv3 ------"
2201 as hv3 ovs-vsctl show
2202 echo "------ hv3 br-phys ------"
2203 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2205 # Now check the packets actually received against the ones expected.
2207 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2211 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2212 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2213 AT_SKIP_IF([test $HAVE_PYTHON = no])
2218 # Three logical switches ls1, ls2, ls3.
2219 # One logical router lr0 connected to ls[123],
2220 # with nine subnets, three per logical switch:
2222 # lrp11 on ls1 for subnet 192.168.11.0/24
2223 # lrp12 on ls1 for subnet 192.168.12.0/24
2224 # lrp13 on ls1 for subnet 192.168.13.0/24
2226 # lrp33 on ls3 for subnet 192.168.33.0/24
2228 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2229 # digits are the subnet and the last digit distinguishes the VIF.
2231 ovn-nbctl ls-add ls$i
2234 # Add "unknown" to MAC addresses for lp?11, so packets for
2235 # MAC-IP bindings discovered via ARP later have somewhere to go.
2236 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2239 -- lsp-add ls$i lp$i$j$k \
2240 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2241 192.168.$i$j.$k" $unknown
2246 ovn-nbctl lr-add lr0
2249 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2251 -- lsp-add ls$i lrp$i$j-attachment \
2252 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2253 options:router-port=lrp$i$j \
2254 addresses='"00:00:00:00:ff:'$i$j'"'
2258 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2259 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2263 # Three hypervisors hv[123].
2264 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2265 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2266 # lp?3[123] all on hv3.
2269 # Given the name of a logical port, prints the name of the hypervisor
2270 # on which it is located.
2273 ?11) echo 1 ;; dnl (
2274 ?12 | ?21 | ?22) echo 2 ;; dnl (
2275 ?13 | ?23 | ?3?) echo 3 ;;
2279 # Given the name of a logical port, prints the name of its logical router
2280 # port, e.g. "vif_to_lrp 123" yields 12.
2285 # Given the name of a logical port, prints the name of its logical
2286 # switch, e.g. "vif_to_ls 123" yields 1.
2295 ovs-vsctl add-br br-phys
2296 ovn_attach n1 br-phys 192.168.0.$i
2301 hv=`vif_to_hv $i$j$k`
2302 as hv$hv ovs-vsctl \
2303 -- add-port br-int vif$i$j$k \
2304 -- set Interface vif$i$j$k \
2305 external-ids:iface-id=lp$i$j$k \
2306 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2307 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2308 ofport-request=$i$j$k
2313 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2314 # packets for ARP resolution (native tunneling doesn't queue packets
2315 # for ARP resolution).
2318 # Allow some time for ovn-northd and ovn-controller to catch up.
2319 # XXX This should be more systematic.
2322 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2324 # This shell function causes a packet to be received on INPORT. The packet's
2325 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2326 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2327 # more) list the VIFs on which the packet should be received. INPORT and the
2328 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2337 # This packet has bad checksums but logical L3 routing doesn't check.
2338 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2339 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2340 shift; shift; shift; shift; shift
2341 hv=hv`vif_to_hv $inport`
2342 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2343 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2344 in_ls=`vif_to_ls $inport`
2345 in_lrp=`vif_to_lrp $inport`
2347 out_ls=`vif_to_ls $outport`
2348 if test $in_ls = $out_ls; then
2349 # Ports on the same logical switch receive exactly the same packet.
2352 # Routing decrements TTL and updates source and dest MAC
2354 out_lrp=`vif_to_lrp $outport`
2355 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2356 fi >> $outport.expected
2360 as hv1 ovs-vsctl --columns=name,ofport list interface
2361 as hv1 ovn-sbctl list port_binding
2362 as hv1 ovn-sbctl list datapath_binding
2363 as hv1 ovn-sbctl dump-flows
2364 as hv1 ovs-ofctl dump-flows br-int
2366 # Send IP packets between all pairs of source and destination ports:
2368 # 1. Unicast IP packets are delivered to exactly one logical switch port
2369 # (except that packets destined to their input ports are dropped).
2371 # 2. Broadcast IP packets are delivered to all logical switch ports
2372 # except the input port.
2374 printf "%02x%02x%02x%02x" "$@"
2382 sip=`ip_to_hex 192 168 $is$js $ks`
2387 dip=`ip_to_hex 192 168 $id$jd $kd`
2388 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2389 if test $d != $s; then unicast=$d; else unicast=; fi
2391 test_ip $s $smac $dmac $sip $dip $unicast #1
2393 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2397 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2402 # 3. Send an IP packet from every logical port to every other subnet,
2403 # to an IP address that does not have a static IP-MAC binding.
2404 # This should generate a broadcast ARP request for the destination
2405 # IP address in the destination subnet.
2411 sip=`ip_to_hex 192 168 $is$js $ks`
2414 if test $is$js = $id$jd; then
2419 dmac=00000000ff$is$js
2420 # Calculate a 4th octet for the destination that is
2421 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2422 # that have static MAC bindings, and fits in the range
2424 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2425 dip=`ip_to_hex 192 168 $id$jd $o4`
2426 test_ip $s $smac $dmac $sip $dip
2428 # Every LP on the destination subnet's lswitch should
2429 # receive the ARP request.
2430 lrmac=00000000ff$id$jd
2431 lrip=`ip_to_hex 192 168 $id$jd 254`
2432 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2433 for jd2 in 1 2 3; do
2435 echo $arp >> $id$jd2$kd.expected
2444 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2446 # Causes a packet to be received on INPORT. The packet is an ARP
2447 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2448 # it should be the hardware address of the target to expect to receive in an
2449 # ARP reply; otherwise no reply is expected.
2451 # INPORT is an logical switch port number, e.g. 11 for vif11.
2452 # SHA and REPLY_HA are each 12 hex digits.
2453 # SPA and TPA are each 8 hex digits.
2455 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2456 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2457 hv=hv`vif_to_hv $inport`
2458 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2459 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2461 # Expect to receive the broadcast ARP on the other logical switch ports if
2462 # IP address is not configured to the switch patch port.
2463 local i=`vif_to_ls $inport`
2467 # 192.168.33.254 is configured to the switch patch port for lrp33,
2468 # so no ARP flooding expected for it.
2469 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2470 echo $request >> $i$j$k.expected
2475 # Expect to receive the reply, if any.
2476 if test X$reply_ha != X; then
2477 lrp=`vif_to_lrp $inport`
2478 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2479 echo $reply >> $inport.expected
2483 # Test router replies to ARP requests from all source ports:
2485 # 4. Router replies to query for its MAC address from port's own IP address.
2487 # 5. Router replies to query for its MAC address from any random IP address
2490 # 6. Router replies to query for its MAC address from another subnet.
2492 # 7. No reply to query for IP address other than router IP.
2496 smac=f00000000$i$j$k # Source MAC
2497 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2498 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2499 rmac=00000000ff$i$j # Router MAC
2500 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2501 test_arp $i$j$k $smac $sip $rip $rmac #4
2502 test_arp $i$j$k $smac $otherip $rip $rmac #5
2503 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2504 test_arp $i$j$k $smac $sip $otherip #7
2509 # Allow some time for packet forwarding.
2510 # XXX This can be improved.
2513 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2516 # Here, the $s is the VIF that originated the ARP request and $d is
2517 # the VIF that sends the ARP reply, which is somewhat backward but
2518 # it means that $s and $d are the same as #3.
2519 : > mac_bindings.expected
2526 if test $is$js = $id$jd; then
2533 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2534 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2535 host_mac=8000000000$o4
2537 lrmac=00000000ff$id$jd
2538 lrip=`ip_to_hex 192 168 $id$jd 254`
2540 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2546 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2547 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2548 #as $hv ovs-ofctl dump-flows br-int table=19
2550 host_ip_pretty=192.168.$id$jd.$o4
2551 host_mac_pretty=80:00:00:00:00:$o4
2552 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2559 # Allow some time for packet forwarding.
2560 # XXX This can be improved.
2563 # 9. Send an IP packet from every logical port to every other subnet. These
2564 # are the same packets already sent as #3, but now the destinations' IP-MAC
2565 # bindings have been discovered via ARP, so instead of provoking an ARP
2566 # request, these packets now get routed to their destinations (which don't
2567 # have static MAC bindings, so they go to the port we've designated as
2568 # accepting "unknown" MACs.)
2574 sip=`ip_to_hex 192 168 $is$js $ks`
2577 if test $is$js = $id$jd; then
2582 dmac=00000000ff$is$js
2583 # Calculate a 4th octet for the destination that is
2584 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2585 # that have static MAC bindings, and fits in the range
2587 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2588 dip=`ip_to_hex 192 168 $id$jd $o4`
2589 test_ip $s $smac $dmac $sip $dip
2591 # Expect the packet egress.
2592 host_mac=8000000000$o4
2595 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2602 ovn-sbctl -f csv -d bare --no-heading \
2603 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2605 # Now check the packets actually received against the ones expected.
2609 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2615 # Check the MAC bindings against those expected.
2616 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2619 # Gracefully terminate daemons
2620 OVN_CLEANUP([hv1], [hv2], [hv3])
2624 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2625 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2626 AT_SKIP_IF([test $HAVE_PYTHON = no])
2629 # Create hypervisors hv[123].
2630 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2631 # Add all of the vifs to a single logical switch lsw0.
2632 # Turn off port security on vifs vif[123]1
2633 # Turn on l2 port security on vifs vif[123]2
2634 # Turn of l2 and l3 port security on vifs vif[123]3
2635 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2636 ovn-nbctl ls-add lsw0
2641 ovs-vsctl add-br br-phys
2642 ovn_attach n1 br-phys 192.168.0.$i
2645 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
2646 ovn-nbctl lsp-add lsw0 lp$i$j
2647 if test $j = 1; then
2648 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2649 elif test $j = 2; then
2650 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2651 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2653 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2654 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2655 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2660 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2661 # packets for ARP resolution (native tunneling doesn't queue packets
2662 # for ARP resolution).
2665 # Allow some time for ovn-northd and ovn-controller to catch up.
2666 # XXX This should be more systematic.
2669 # Given the name of a logical port, prints the name of the hypervisor
2670 # on which it is located.
2681 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2683 # This shell function causes an ip packet to be received on INPORT.
2684 # The packet's content has Ethernet destination DST and source SRC
2685 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2686 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2687 # be received. INPORT and the OUTPORTs are specified as logical switch
2688 # port numbers, e.g. 11 for vif11.
2690 # This packet has bad checksums but logical L3 routing doesn't check.
2691 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2692 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2693 shift; shift; shift; shift; shift
2694 hv=`vif_to_hv $inport`
2695 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2696 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2698 echo $packet >> $outport.expected
2702 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2704 # Causes a packet to be received on INPORT. The packet is an ARP
2705 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2706 # it should be the hardware address of the target to expect to receive in an
2707 # ARP reply; otherwise no reply is expected.
2709 # INPORT is an logical switch port number, e.g. 11 for vif11.
2710 # SHA and REPLY_HA are each 12 hex digits.
2711 # SPA and TPA are each 8 hex digits.
2713 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2714 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2715 hv=`vif_to_hv $inport`
2716 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2717 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2718 if test $drop != 1; then
2719 if test X$reply_ha = X; then
2720 # Expect to receive the broadcast ARP on the other logical switch ports
2721 # if no reply is expected.
2725 if test $i$j != $inport; then
2726 echo $request >> $i$j.expected
2731 # Expect to receive the reply, if any.
2732 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2733 echo $reply >> $inport.expected
2738 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2739 # This function is similar to test_ip() except that it sends
2742 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2743 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2744 shift; shift; shift; shift; shift
2745 hv=`vif_to_hv $inport`
2746 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2747 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2749 echo $packet >> $outport.expected
2753 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2754 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2755 # of the test packet
2757 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2758 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2759 shift; shift; shift; shift; shift; shift
2760 hv=`vif_to_hv $inport`
2761 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2762 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2764 echo $packet >> $outport.expected
2769 printf "%02x%02x%02x%02x" "$@"
2773 sip=`ip_to_hex 192 168 0 12`
2774 tip=`ip_to_hex 192 168 0 13`
2775 # the arp packet should be allowed even if lp[123]1 is
2776 # not configured with mac f00000000023 and ip 192.168.0.12
2778 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2780 if test $i != $j; then
2781 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2787 sip=`ip_to_hex 192 168 0 12`
2788 tip=`ip_to_hex 192 168 0 13`
2790 # arp packet should be allowed since lp22 is configured with
2792 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2794 # arp packet should not be allowed since lp32 is not configured with
2796 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2798 # arp packet with sha set to f00000000021 should not be allowed
2800 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2802 # ip packets should be allowed and received since lp[123]2 do not
2803 # have l3 port security
2804 sip=`ip_to_hex 192 168 0 55`
2805 tip=`ip_to_hex 192 168 0 66`
2808 if test $i != $j; then
2809 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2814 # ipv6 packets should be received by lp[123]2
2815 # lp[123]1 can send ipv6 traffic as there is no port security
2816 sip=fe800000000000000000000000000000
2817 tip=ff020000000000000000000000000000
2820 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2824 # l2 and l3 port security
2825 sip=`ip_to_hex 192 168 0 13`
2826 tip=`ip_to_hex 192 168 0 22`
2827 # arp packet should be allowed since lp13 is configured with
2828 # f00000000013 and 192.168.0.13
2829 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2831 # the arp packet should be dropped because lp23 is not configured
2832 # with mac f00000000022
2833 sip=`ip_to_hex 192 168 0 13`
2834 tip=`ip_to_hex 192 168 0 22`
2835 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2837 # the arp packet should be dropped because lp33 is not configured
2838 # with ip 192.168.0.55
2839 spa=`ip_to_hex 192 168 0 55`
2840 tpa=`ip_to_hex 192 168 0 22`
2841 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2843 # ip packets should not be received by lp[123]3 since
2844 # l3 port security is enabled
2845 sip=`ip_to_hex 192 168 0 55`
2846 tip=`ip_to_hex 192 168 0 66`
2849 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2853 # ipv6 packets should be dropped for lp[123]3 since
2854 # it is configured with only ipv4 address
2855 sip=fe800000000000000000000000000000
2856 tip=ff020000000000000000000000000000
2859 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2862 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2863 # lp[123]1 can send ipv6 traffic as there is no port security
2865 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2868 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2869 # fe80::ea2a:eaff:fe28:0012
2871 # ipv4 packet should be dropped for lp13 with mac f0000000113
2872 sip=`ip_to_hex 192 168 0 13`
2873 tip=`ip_to_hex 192 168 0 23`
2874 test_ip 13 f00000000113 f00000000023 $sip $tip
2876 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2877 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2878 # lp11 can send ipv6 traffic as there is no port security
2879 sip=ee800000000000000000000000000000
2881 tip=fe80000000000000ea2aeafffe2800${i}3
2882 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2886 # ipv6 packet should not be received by lp33 with mac f0000000333
2887 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2888 # configured with fe80::ea2a:eaff:fe28:0033
2889 # lp11 can send ipv6 traffic as there is no port security
2891 sip=ee800000000000000000000000000000
2892 tip=fe80000000000000ea2aeafffe280023
2893 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2895 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2896 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2897 # and should be dropped for any other ip6.src
2898 # lp21 can receive ipv6 traffic as there is no port security
2900 tip=ee800000000000000000000000000000
2902 sip=fe80000000000000ea2aeafffe2800${i}3
2903 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2905 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2906 sip=00000000000000000000000000000000
2907 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2908 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2909 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2910 # Traffic to non-multicast traffic should be dropped
2911 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2912 # Traffic of other ICMPv6 types should be dropped
2913 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2916 sip=ae80000000000000ea2aeafffe2800aa
2917 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2920 # configure lsp13 to send and received IPv4 packets with an address range
2921 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"
2925 sip=`ip_to_hex 10 0 0 13`
2926 tip=`ip_to_hex 192 168 0 22`
2927 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2928 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2930 sip=`ip_to_hex 10 0 0 14`
2931 tip=`ip_to_hex 192 168 0 23`
2932 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2933 # with dst ip 192.168.0.23 should be allowed
2934 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2936 sip=`ip_to_hex 192 168 0 33`
2937 tip=`ip_to_hex 10 0 0 15`
2938 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2939 # with dst ip 10.0.0.15 should be received by lsp13
2940 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2942 sip=`ip_to_hex 192 168 0 33`
2943 tip=`ip_to_hex 20 0 0 4`
2944 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2945 # with dst ip 20.0.0.4 should be received by lsp13
2946 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2948 sip=`ip_to_hex 192 168 0 33`
2949 tip=`ip_to_hex 20 0 0 5`
2950 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2951 # with dst ip 20.0.0.5 should not be received by lsp13
2952 test_ip 33 f00000000033 f00000000013 $sip $tip
2954 sip=`ip_to_hex 192 168 0 33`
2955 tip=`ip_to_hex 20 0 0 255`
2956 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2957 # with dst ip 20.0.0.255 should be received by lsp13
2958 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2960 sip=`ip_to_hex 192 168 0 33`
2961 tip=`ip_to_hex 192 168 0 255`
2962 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2963 # with dst ip 192.168.0.255 should not be received by lsp13
2964 test_ip 33 f00000000033 f00000000013 $sip $tip
2966 sip=`ip_to_hex 192 168 0 33`
2967 tip=`ip_to_hex 224 0 0 4`
2968 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2969 # with dst ip 224.0.0.4 should be received by lsp13
2970 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2972 #dump information including flow counters
2974 ovn-sbctl dump-flows -- list multicast_group
2976 echo "------ hv1 dump ------"
2977 as hv1 ovs-vsctl show
2978 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2979 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2981 echo "------ hv2 dump ------"
2982 as hv2 ovs-vsctl show
2983 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2984 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2986 echo "------ hv3 dump ------"
2987 as hv3 ovs-vsctl show
2988 as hv3 ovs-ofctl -O OpenFlow13 show br-int
2989 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2991 # Now check the packets actually received against the ones expected.
2994 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2998 OVN_CLEANUP([hv1],[hv2],[hv3])
3002 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3003 AT_SKIP_IF([test $HAVE_PYTHON = no])
3007 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3008 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3009 # R2 has ls2 (172.16.1.0/24) connected to it.
3011 ls1_lp1_mac="f0:00:00:01:02:03"
3012 rp_ls1_mac="00:00:00:01:02:03"
3013 rp_ls2_mac="00:00:00:01:02:04"
3014 ls2_lp1_mac="f0:00:00:01:02:04"
3016 ls1_lp1_ip="192.168.1.2"
3017 ls2_lp1_ip="172.16.1.2"
3022 ovn-nbctl ls-add ls1
3023 ovn-nbctl ls-add ls2
3026 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3028 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3029 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3032 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3034 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3035 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3038 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3039 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3041 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3042 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3044 # Create logical port ls1-lp1 in ls1
3045 ovn-nbctl lsp-add ls1 ls1-lp1 \
3046 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3048 # Create logical port ls2-lp1 in ls2
3049 ovn-nbctl lsp-add ls2 ls2-lp1 \
3050 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3052 # Create two hypervisor and create OVS ports corresponding to logical ports.
3057 ovs-vsctl add-br br-phys
3058 ovn_attach n1 br-phys 192.168.0.1
3059 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3060 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3061 options:tx_pcap=hv1/vif1-tx.pcap \
3062 options:rxq_pcap=hv1/vif1-rx.pcap \
3067 ovs-vsctl add-br br-phys
3068 ovn_attach n1 br-phys 192.168.0.2
3069 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3070 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3071 options:tx_pcap=hv2/vif1-tx.pcap \
3072 options:rxq_pcap=hv2/vif1-rx.pcap \
3076 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3077 # packets for ARP resolution (native tunneling doesn't queue packets
3078 # for ARP resolution).
3081 # Allow some time for ovn-northd and ovn-controller to catch up.
3082 # XXX This should be more systematic.
3086 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3087 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3088 udp && udp.src==53 && udp.dst==4369"
3089 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3092 echo "---------NB dump-----"
3094 echo "---------------------"
3095 ovn-nbctl list logical_router
3096 echo "---------------------"
3097 ovn-nbctl list logical_router_port
3098 echo "---------------------"
3100 echo "---------SB dump-----"
3101 ovn-sbctl list datapath_binding
3102 echo "---------------------"
3103 ovn-sbctl list port_binding
3104 echo "---------------------"
3106 echo "------ hv1 dump ----------"
3107 as hv1 ovs-ofctl show br-int
3108 as hv1 ovs-ofctl dump-flows br-int
3109 echo "------ hv2 dump ----------"
3110 as hv2 ovs-ofctl show br-int
3111 as hv2 ovs-ofctl dump-flows br-int
3114 # The TTL should be decremented by 2.
3115 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3116 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3117 udp && udp.src==53 && udp.dst==4369"
3118 echo $packet | ovstest test-ovn expr-to-packets > expected
3120 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3122 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3123 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3126 # Disable the ls2-lp1 port.
3127 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3129 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3130 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3133 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3135 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3136 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3137 udp && udp.src==53 && udp.dst==4369"
3139 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3140 # The 2nd packet sent shound not be received.
3141 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3143 OVN_CLEANUP([hv1],[hv2])
3148 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3149 AT_KEYWORDS([router-admin-state])
3150 AT_SKIP_IF([test $HAVE_PYTHON = no])
3154 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3155 # and 172.16.1.0/24) connected to it.
3159 ovn-nbctl ls-add ls1
3162 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3163 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3164 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3166 # Create logical port ls1-lp1 in ls1
3167 ovn-nbctl lsp-add ls1 ls1-lp1 \
3168 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3170 # Create logical port ls1-lp2 in ls1
3171 ovn-nbctl lsp-add ls1 ls1-lp2 \
3172 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3174 # Create one hypervisor and create OVS ports corresponding to logical ports.
3179 ovs-vsctl add-br br-phys
3180 ovn_attach n1 br-phys 192.168.0.1
3181 ovs-vsctl -- add-port br-int vif1 -- \
3182 set interface vif1 external-ids:iface-id=ls1-lp1 \
3183 options:tx_pcap=hv1/vif1-tx.pcap \
3184 options:rxq_pcap=hv1/vif1-rx.pcap \
3187 ovs-vsctl -- add-port br-int vif2 -- \
3188 set interface vif2 external-ids:iface-id=ls1-lp2 \
3189 options:tx_pcap=hv1/vif2-tx.pcap \
3190 options:rxq_pcap=hv1/vif2-rx.pcap \
3194 # Allow some time for ovn-northd and ovn-controller to catch up.
3195 # XXX This should be more systematic.
3198 # Send ip packets between the two ports.
3200 printf "%02x%02x%02x%02x" "$@"
3204 src_mac="f00000010203"
3205 dst_mac="000000010203"
3206 src_ip=`ip_to_hex 192 168 1 2`
3207 dst_ip=`ip_to_hex 172 16 1 2`
3208 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3209 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3212 echo "---------NB dump-----"
3214 echo "---------------------"
3215 ovn-nbctl list logical_router
3216 echo "---------------------"
3217 ovn-nbctl list logical_router_port
3218 echo "---------------------"
3220 echo "---------SB dump-----"
3221 ovn-sbctl list datapath_binding
3222 echo "---------------------"
3223 ovn-sbctl list logical_flow
3224 echo "---------------------"
3226 echo "------ hv1 dump ----------"
3227 as hv1 ovs-ofctl dump-flows br-int
3231 ovn-nbctl set Logical_Router R1 enabled=false
3233 # Allow some time for ovn-northd and ovn-controller to catch up.
3234 # XXX This should be more systematic.
3237 echo "---------SB dump-----"
3238 ovn-sbctl list datapath_binding
3239 echo "---------------------"
3240 ovn-sbctl list logical_flow
3241 echo "---------------------"
3243 echo "------ hv1 dump ----------"
3244 as hv1 ovs-ofctl dump-flows br-int
3246 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3249 expect_src_mac="000000010203"
3250 expect_dst_mac="f00000010204"
3251 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3253 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3257 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3258 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3259 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3262 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3265 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3268 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3271 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3272 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3277 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3278 AT_KEYWORDS([router-admin-state])
3279 AT_SKIP_IF([test $HAVE_PYTHON = no])
3283 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3284 # and has switch ls2 (172.16.1.0/24) connected to it.
3288 ovn-nbctl ls-add ls1
3289 ovn-nbctl ls-add ls2
3292 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3293 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3294 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3297 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3298 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3299 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3301 # Create logical port ls1-lp1 in ls1
3302 ovn-nbctl lsp-add ls1 ls1-lp1 \
3303 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3305 # Create logical port ls2-lp1 in ls2
3306 ovn-nbctl lsp-add ls2 ls2-lp1 \
3307 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3309 # Create one hypervisor and create OVS ports corresponding to logical ports.
3314 ovs-vsctl add-br br-phys
3315 ovn_attach n1 br-phys 192.168.0.1
3316 ovs-vsctl -- add-port br-int vif1 -- \
3317 set interface vif1 external-ids:iface-id=ls1-lp1 \
3318 options:tx_pcap=hv1/vif1-tx.pcap \
3319 options:rxq_pcap=hv1/vif1-rx.pcap \
3322 ovs-vsctl -- add-port br-int vif2 -- \
3323 set interface vif2 external-ids:iface-id=ls2-lp1 \
3324 options:tx_pcap=hv1/vif2-tx.pcap \
3325 options:rxq_pcap=hv1/vif2-rx.pcap \
3329 # Allow some time for ovn-northd and ovn-controller to catch up.
3330 # XXX This should be more systematic.
3333 # Send ip packets between the two ports.
3335 printf "%02x%02x%02x%02x" "$@"
3339 src_mac="f00000010203"
3340 dst_mac="000000010203"
3341 src_ip=`ip_to_hex 192 168 1 2`
3342 dst_ip=`ip_to_hex 172 16 1 2`
3343 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3344 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3347 echo "---------NB dump-----"
3349 echo "---------------------"
3350 ovn-nbctl list logical_router
3351 echo "---------------------"
3352 ovn-nbctl list logical_router_port
3353 echo "---------------------"
3355 echo "---------SB dump-----"
3356 ovn-sbctl list datapath_binding
3357 echo "---------------------"
3358 ovn-sbctl list logical_flow
3359 echo "---------------------"
3361 echo "------ hv1 dump ----------"
3362 as hv1 ovs-ofctl dump-flows br-int
3365 ovn-nbctl set Logical_Router R1 enabled=false
3367 echo "---------SB dump-----"
3368 ovn-sbctl list datapath_binding
3369 echo "---------------------"
3370 ovn-sbctl list logical_flow
3371 echo "---------------------"
3373 echo "------ hv1 dump ----------"
3374 as hv1 ovs-ofctl dump-flows br-int
3376 # Allow some time for the disabling of logical router R1 to propagate.
3377 # XXX This should be more systematic.
3380 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3383 expect_src_mac="000000010204"
3384 expect_dst_mac="f00000010204"
3385 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3387 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3393 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3394 AT_SKIP_IF([test $HAVE_PYTHON = no])
3398 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3399 # network. R1 has switchess foo (192.168.1.0/24)
3401 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3406 ovn-nbctl ls-add foo
3407 ovn-nbctl ls-add alice
3408 ovn-nbctl ls-add bob
3411 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3412 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3413 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3415 # Connect alice to R2
3416 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3417 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3418 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3421 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3422 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3423 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3426 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3427 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3429 #install static routes
3430 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3431 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3432 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3434 # Create logical port foo1 in foo
3435 ovn-nbctl lsp-add foo foo1 \
3436 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3438 # Create logical port alice1 in alice
3439 ovn-nbctl lsp-add alice alice1 \
3440 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3442 # Create logical port bob1 in bob
3443 ovn-nbctl lsp-add bob bob1 \
3444 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3446 # Create two hypervisor and create OVS ports corresponding to logical ports.
3451 ovs-vsctl add-br br-phys
3452 ovn_attach n1 br-phys 192.168.0.1
3453 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3454 set interface hv1-vif1 external-ids:iface-id=foo1 \
3455 options:tx_pcap=hv1/vif1-tx.pcap \
3456 options:rxq_pcap=hv1/vif1-rx.pcap \
3459 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3460 set interface hv1-vif2 external-ids:iface-id=alice1 \
3461 options:tx_pcap=hv1/vif2-tx.pcap \
3462 options:rxq_pcap=hv1/vif2-rx.pcap \
3467 ovs-vsctl add-br br-phys
3468 ovn_attach n1 br-phys 192.168.0.2
3469 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3470 set interface hv2-vif1 external-ids:iface-id=bob1 \
3471 options:tx_pcap=hv2/vif1-tx.pcap \
3472 options:rxq_pcap=hv2/vif1-rx.pcap \
3476 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3477 # packets for ARP resolution (native tunneling doesn't queue packets
3478 # for ARP resolution).
3481 # Allow some time for ovn-northd and ovn-controller to catch up.
3482 # XXX This should be more systematic.
3486 printf "%02x%02x%02x%02x" "$@"
3489 # Send ip packets between foo1 and alice1
3490 src_mac="f00000010203"
3491 dst_mac="000000010203"
3492 src_ip=`ip_to_hex 192 168 1 2`
3493 dst_ip=`ip_to_hex 172 16 1 2`
3494 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3495 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3497 # Send ip packets between foo1 and bob1
3498 src_mac="f00000010203"
3499 dst_mac="000000010203"
3500 src_ip=`ip_to_hex 192 168 1 2`
3501 dst_ip=`ip_to_hex 172 16 2 2`
3502 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3503 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3505 echo "---------NB dump-----"
3507 echo "---------------------"
3508 ovn-nbctl list logical_router
3509 echo "---------------------"
3510 ovn-nbctl list logical_router_port
3511 echo "---------------------"
3513 echo "---------SB dump-----"
3514 ovn-sbctl list datapath_binding
3515 echo "---------------------"
3516 ovn-sbctl list port_binding
3517 echo "---------------------"
3519 echo "------ hv1 dump ----------"
3520 as hv1 ovs-ofctl dump-flows br-int
3521 echo "------ hv2 dump ----------"
3522 as hv2 ovs-ofctl dump-flows br-int
3524 # Packet to Expect at bob1
3525 src_mac="000000010205"
3526 dst_mac="f00000010205"
3527 src_ip=`ip_to_hex 192 168 1 2`
3528 dst_ip=`ip_to_hex 172 16 2 2`
3529 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3531 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3533 # Packet to Expect at alice1
3534 src_mac="000000010204"
3535 dst_mac="f00000010204"
3536 src_ip=`ip_to_hex 192 168 1 2`
3537 dst_ip=`ip_to_hex 172 16 1 2`
3538 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3540 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3542 OVN_CLEANUP([hv1],[hv2])
3546 AT_SETUP([ovn -- send gratuitous arp on localnet])
3547 AT_SKIP_IF([test $HAVE_PYTHON = no])
3549 ovn-nbctl ls-add lsw0
3557 ovn_attach n1 br-phys 192.168.0.1
3559 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3560 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])
3563 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3564 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3565 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3567 # Create a localnet port.
3568 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3569 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3570 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3571 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3573 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3575 # Wait for packet to be received.
3576 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3577 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3579 # Check GARP packet when restart openflow connection.
3581 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3583 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3586 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3588 # Wait for packet to be received.
3589 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3590 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3592 # Delete the localnet ports.
3593 AT_CHECK([ovs-vsctl del-port localvif1])
3594 AT_CHECK([ovn-nbctl lsp-del ln_port])
3600 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3601 AT_SKIP_IF([test $HAVE_PYTHON = no])
3605 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3606 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3607 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3614 ovn-nbctl ls-add foo
3615 ovn-nbctl ls-add alice
3616 ovn-nbctl ls-add bob
3617 ovn-nbctl ls-add join
3620 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3621 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3622 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3624 # Connect alice to R2
3625 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3626 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3627 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3630 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3631 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3632 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3634 # Connect R1 to join
3635 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3636 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3637 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3639 # Connect R2 to join
3640 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3641 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3642 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3644 # Connect R3 to join
3645 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3646 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3647 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3649 #install static routes
3650 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3651 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3653 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3654 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3656 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3657 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3659 # Create logical port foo1 in foo
3660 ovn-nbctl lsp-add foo foo1 \
3661 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3663 # Create logical port alice1 in alice
3664 ovn-nbctl lsp-add alice alice1 \
3665 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3667 # Create logical port bob1 in bob
3668 ovn-nbctl lsp-add bob bob1 \
3669 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3671 # Create two hypervisor and create OVS ports corresponding to logical ports.
3676 ovs-vsctl add-br br-phys
3677 ovn_attach n1 br-phys 192.168.0.1
3678 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3679 set interface hv1-vif1 external-ids:iface-id=foo1 \
3680 options:tx_pcap=hv1/vif1-tx.pcap \
3681 options:rxq_pcap=hv1/vif1-rx.pcap \
3684 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3685 set interface hv1-vif2 external-ids:iface-id=alice1 \
3686 options:tx_pcap=hv1/vif2-tx.pcap \
3687 options:rxq_pcap=hv1/vif2-rx.pcap \
3692 ovs-vsctl add-br br-phys
3693 ovn_attach n1 br-phys 192.168.0.2
3694 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3695 set interface hv2-vif1 external-ids:iface-id=bob1 \
3696 options:tx_pcap=hv2/vif1-tx.pcap \
3697 options:rxq_pcap=hv2/vif1-rx.pcap \
3701 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3702 # packets for ARP resolution (native tunneling doesn't queue packets
3703 # for ARP resolution).
3706 # Allow some time for ovn-northd and ovn-controller to catch up.
3707 # XXX This should be more systematic.
3711 printf "%02x%02x%02x%02x" "$@"
3714 # Send ip packets between foo1 and alice1
3715 src_mac="f00000010203"
3716 dst_mac="000001010203"
3717 src_ip=`ip_to_hex 192 168 1 2`
3718 dst_ip=`ip_to_hex 172 16 1 2`
3719 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3720 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3721 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3723 # Send ip packets between foo1 and bob1
3724 src_mac="f00000010203"
3725 dst_mac="000001010203"
3726 src_ip=`ip_to_hex 192 168 1 2`
3727 dst_ip=`ip_to_hex 10 32 1 2`
3728 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3729 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3731 echo "---------NB dump-----"
3733 echo "---------------------"
3734 ovn-nbctl list logical_router
3735 echo "---------------------"
3736 ovn-nbctl list logical_router_port
3737 echo "---------------------"
3739 echo "---------SB dump-----"
3740 ovn-sbctl list datapath_binding
3741 echo "---------------------"
3742 ovn-sbctl list port_binding
3743 echo "---------------------"
3744 ovn-sbctl dump-flows
3745 echo "---------------------"
3747 echo "------ hv1 dump ----------"
3748 as hv1 ovs-ofctl show br-int
3749 as hv1 ovs-ofctl dump-flows br-int
3750 echo "------ hv2 dump ----------"
3751 as hv2 ovs-ofctl show br-int
3752 as hv2 ovs-ofctl dump-flows br-int
3753 echo "----------------------------"
3755 # Packet to Expect at bob1
3756 src_mac="000003010203"
3757 dst_mac="f00000010205"
3758 src_ip=`ip_to_hex 192 168 1 2`
3759 dst_ip=`ip_to_hex 10 32 1 2`
3760 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3762 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3764 # Packet to Expect at alice1
3765 src_mac="000002010203"
3766 dst_mac="f00000010204"
3767 src_ip=`ip_to_hex 192 168 1 2`
3768 dst_ip=`ip_to_hex 172 16 1 2`
3769 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3771 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3773 OVN_CLEANUP([hv1],[hv2])
3777 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3778 AT_SKIP_IF([test $HAVE_PYTHON = no])
3781 ovn-nbctl ls-add ls1
3783 ovn-nbctl lsp-add ls1 ls1-lp1 \
3784 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3786 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3788 ovn-nbctl lsp-add ls1 ls1-lp2 \
3789 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3791 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3793 ovn-nbctl ls-add ls2
3794 ovn-nbctl lsp-add ls2 ls2-lp1 \
3795 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3796 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3797 ovn-nbctl lsp-add ls2 ls2-lp2 \
3798 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3799 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3801 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3802 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3803 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3805 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3806 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3808 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3809 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3810 \"lease_time\"=\"3600\"")"
3812 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3818 ovs-vsctl add-br br-phys
3819 ovn_attach n1 br-phys 192.168.0.1
3820 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3821 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3822 options:tx_pcap=hv1/vif1-tx.pcap \
3823 options:rxq_pcap=hv1/vif1-rx.pcap \
3826 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3827 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3828 options:tx_pcap=hv1/vif2-tx.pcap \
3829 options:rxq_pcap=hv1/vif2-rx.pcap \
3832 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3833 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3834 options:tx_pcap=hv1/vif3-tx.pcap \
3835 options:rxq_pcap=hv1/vif3-rx.pcap \
3838 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3839 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3840 options:tx_pcap=hv1/vif4-tx.pcap \
3841 options:rxq_pcap=hv1/vif4-rx.pcap \
3848 as hv1 ovs-vsctl show
3850 # This shell function sends a DHCP request packet
3851 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3853 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3854 shift; shift; shift; shift; shift;
3855 if test $use_ip != 0; then
3860 src_ip=`ip_to_hex 0 0 0 0`
3861 dst_ip=`ip_to_hex 255 255 255 255`
3863 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
3864 # udp header and dhcp header
3865 request=${request}0044004300fc0000
3866 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3867 # client hardware padding
3868 request=${request}00000000000000000000
3870 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3871 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3873 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3874 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3875 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3876 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3878 request=${request}63825363
3880 request=${request}3501${dhcp_type}ff
3882 if test $offer_ip != 0; then
3883 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
3884 # total IP length will be the IP length of the request packet
3885 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3886 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3887 udp_len=`expr $ip_len - 20`
3888 ip_len=$(printf "%x" $ip_len)
3889 udp_len=$(printf "%x" $udp_len)
3890 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3891 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3892 # udp header and dhcp header.
3893 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3894 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3896 reply=${reply}${offer_ip}
3897 # next server ip address, relay agent ip address, client mac address
3898 reply=${reply}0000000000000000${src_mac}
3899 # client hardware padding
3900 reply=${reply}00000000000000000000
3902 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3903 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3905 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3906 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3907 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3908 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3910 reply=${reply}63825363
3912 local dhcp_reply_type=02
3913 if test $dhcp_type = 03; then
3916 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3917 echo $reply >> $inport.expected
3920 echo $request >> $outport.expected
3923 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3929 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3930 options:rxq_pcap=dummy-rx.pcap
3931 rm -f ${pcap_file}*.pcap
3932 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3933 options:rxq_pcap=${pcap_file}-rx.pcap
3937 printf "%02x%02x%02x%02x" "$@"
3940 AT_CAPTURE_FILE([ofctl_monitor0.log])
3941 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3942 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3944 echo "---------NB dump-----"
3946 echo "---------------------"
3947 echo "---------SB dump-----"
3948 ovn-sbctl list datapath_binding
3949 echo "---------------------"
3950 ovn-sbctl list logical_flow
3951 echo "---------------------"
3953 echo "---------------------"
3954 ovn-sbctl dump-flows
3955 echo "---------------------"
3957 echo "------ hv1 dump ----------"
3958 as hv1 ovs-ofctl dump-flows br-int
3960 # Send DHCPDISCOVER.
3961 offer_ip=`ip_to_hex 10 0 0 4`
3962 server_ip=`ip_to_hex 10 0 0 1`
3963 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3964 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3966 # NXT_RESUMEs should be 1.
3967 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3969 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3970 cat 1.expected | cut -c -48 > expout
3971 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3972 # Skipping the IPv4 checksum.
3973 cat 1.expected | cut -c 53- > expout
3974 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3976 # ovs-ofctl also resumes the packets and this causes other ports to receive
3977 # the DHCP request packet. So reset the pcap files so that its easier to test.
3978 reset_pcap_file hv1-vif1 hv1/vif1
3979 reset_pcap_file hv1-vif2 hv1/vif2
3984 offer_ip=`ip_to_hex 10 0 0 6`
3985 server_ip=`ip_to_hex 10 0 0 1`
3986 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3987 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3989 # NXT_RESUMEs should be 2.
3990 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3992 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3993 cat 2.expected | cut -c -48 > expout
3994 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3995 # Skipping the IPv4 checksum.
3996 cat 2.expected | cut -c 53- > expout
3997 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3999 reset_pcap_file hv1-vif1 hv1/vif1
4000 reset_pcap_file hv1-vif2 hv1/vif2
4004 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4005 # but should be resumed without the reply.
4006 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4007 # one from ovn-controller and the other from "ovs-ofctl resume."
4009 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4011 # NXT_RESUMEs should be 3.
4012 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4014 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4015 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4017 reset_pcap_file hv1-vif1 hv1/vif1
4018 reset_pcap_file hv1-vif2 hv1/vif2
4022 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4023 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4025 test_dhcp 3 f00000000003 01 0 4 0
4027 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4029 test_dhcp 4 f00000000004 01 0 3 0
4031 # NXT_RESUMEs should be 3.
4032 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4034 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4035 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4037 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4038 offer_ip=`ip_to_hex 10 0 0 6`
4039 server_ip=`ip_to_hex 10 0 0 1`
4040 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4043 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4045 # NXT_RESUMEs should be 4.
4046 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4048 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4049 cat 2.expected | cut -c -48 > expout
4050 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4051 # Skipping the IPv4 checksum.
4052 cat 2.expected | cut -c 53- > expout
4053 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4055 reset_pcap_file hv1-vif1 hv1/vif1
4056 reset_pcap_file hv1-vif2 hv1/vif2
4060 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4061 offer_ip=`ip_to_hex 10 0 0 6`
4062 server_ip=`ip_to_hex 10 0 0 1`
4063 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4065 dst_ip=`ip_to_hex 255 255 255 255`
4066 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4068 # NXT_RESUMEs should be 5.
4069 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4071 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4072 cat 2.expected | cut -c -48 > expout
4073 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4074 # Skipping the IPv4 checksum.
4075 cat 2.expected | cut -c 53- > expout
4076 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4078 reset_pcap_file hv1-vif1 hv1/vif1
4079 reset_pcap_file hv1-vif2 hv1/vif2
4083 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4084 # The packet should not be received by ovn-controller.
4085 src_ip=`ip_to_hex 10 0 0 6`
4086 dst_ip=`ip_to_hex 10 0 0 4`
4087 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4089 # NXT_RESUMEs should be 5.
4090 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4092 # vif1-tx.pcap should have received the DHCPv4 request packet
4093 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4096 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4097 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4098 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4101 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4104 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4107 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4110 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4111 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4115 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4116 AT_SKIP_IF([test $HAVE_PYTHON = no])
4119 ovn-nbctl ls-add ls1
4120 ovn-nbctl lsp-add ls1 ls1-lp1 \
4121 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4123 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4125 ovn-nbctl lsp-add ls1 ls1-lp2 \
4126 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4128 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4130 ovn-nbctl lsp-add ls1 ls1-lp3 \
4131 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4133 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4135 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4136 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4138 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4139 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4141 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4142 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4144 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4146 ovn-nbctl ls-add ls2
4147 ovn-nbctl lsp-add ls2 ls2-lp1 \
4148 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4149 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4150 ovn-nbctl lsp-add ls2 ls2-lp2 \
4151 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4152 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4158 ovs-vsctl add-br br-phys
4159 ovn_attach n1 br-phys 192.168.0.1
4160 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4161 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4162 options:tx_pcap=hv1/vif1-tx.pcap \
4163 options:rxq_pcap=hv1/vif1-rx.pcap \
4166 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4167 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4168 options:tx_pcap=hv1/vif2-tx.pcap \
4169 options:rxq_pcap=hv1/vif2-rx.pcap \
4172 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4173 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4174 options:tx_pcap=hv1/vif3-tx.pcap \
4175 options:rxq_pcap=hv1/vif3-rx.pcap \
4178 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4179 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4180 options:tx_pcap=hv1/vif4-tx.pcap \
4181 options:rxq_pcap=hv1/vif4-rx.pcap \
4184 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4185 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4186 options:tx_pcap=hv1/vif5-tx.pcap \
4187 options:rxq_pcap=hv1/vif5-rx.pcap \
4195 sed 's/\(00\)\{1,\}$//'
4198 # This shell function sends a DHCPv6 request packet
4199 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4200 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4201 # packet should be received twice (one from ovn-controller and the other
4202 # from the "ovs-ofctl monitor br-int resume"
4204 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4205 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4207 request=${request}ff020000000000000000000000010002
4208 # udp header and dhcpv6 header
4209 request=${request}02220223002affff${msg_code}010203
4211 request=${request}0001000a00030001${src_mac}
4212 # IA-NA (Identity Association for Non Temporary Address)
4213 request=${request}0003000c0102030400000e1000001518
4214 shift; shift; shift; shift; shift;
4215 if test $offer_ip != 0; then
4216 local server_mac=000000100001
4217 local server_lla=fe80000000000000020000fffe100001
4219 if test $msg_code = 01; then
4223 if test $offer_ip = 1; then
4226 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4227 # udp header and dhcpv6 header
4228 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4230 reply=${reply}0001000a00030001${src_mac}
4232 if test $offer_ip != 1; then
4233 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4236 reply=${reply}0002000a00030001${server_mac}
4237 echo $reply | trim_zeros >> $inport.expected
4240 echo $request | trim_zeros >> $outport.expected
4244 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4250 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4251 options:rxq_pcap=dummy-rx.pcap
4252 rm -f ${pcap_file}*.pcap
4253 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4254 options:rxq_pcap=${pcap_file}-rx.pcap
4257 AT_CAPTURE_FILE([ofctl_monitor0.log])
4258 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4259 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4261 echo "---------NB dump-----"
4263 echo "---------------------"
4264 echo "---------SB dump-----"
4265 ovn-sbctl list datapath_binding
4266 echo "---------------------"
4267 ovn-sbctl list logical_flow
4268 echo "---------------------"
4270 echo "---------------------"
4271 ovn-sbctl dump-flows
4272 echo "---------------------"
4274 echo "------ hv1 dump ----------"
4275 as hv1 ovs-ofctl dump-flows br-int
4277 src_mac=f00000000001
4278 src_lla=fe80000000000000f20000fffe000001
4279 offer_ip=ae700000000000000000000000000004
4280 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4282 # NXT_RESUMEs should be 1.
4283 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4285 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4286 # cat 1.expected | trim_zeros > expout
4287 cat 1.expected | cut -c -120 > expout
4288 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4289 # Skipping the UDP checksum
4290 cat 1.expected | cut -c 125- > expout
4291 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4295 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4296 # without any modifications and the packet should be received by ls1-lp1.
4297 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4298 # resume and the other from ovs-ofctl monitor resume.
4300 reset_pcap_file hv1-vif1 hv1/vif1
4301 reset_pcap_file hv1-vif2 hv1/vif2
4303 src_mac=f00000000002
4304 src_lla=fe80000000000000f20000fffe000002
4305 offer_ip=ae700000000000000000000000000005
4306 # Set invalid msg_type
4308 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4310 # NXT_RESUMEs should be 2.
4311 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4313 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4315 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4316 AT_CHECK([cat 2.packets], [0], [])
4318 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4319 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4320 cat 1.expected > expout
4321 AT_CHECK([cat 1.packets], [0], [expout])
4323 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4324 # There should be no DHCPv6 reply from ovn-controller and the request packet
4325 # should be received by ls2-lp2.
4327 src_mac=f00000000003
4328 src_lla=fe80000000000000f20000fffe000003
4329 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4331 # NXT_RESUMEs should be 2 only.
4332 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4334 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4335 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4336 AT_CHECK([cat 3.packets], [0], [])
4338 # vif4-tx.pcap should have received the DHCPv6 request packet
4339 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4340 cat 4.expected > expout
4341 AT_CHECK([cat 4.packets], [0], [expout])
4343 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4344 # The DHCPv6 reply should doesn't contian offer_ip.
4345 src_mac=f00000000022
4346 src_lla=fe80000000000000f20000fffe000022
4347 reset_pcap_file hv1-vif5 hv1/vif5
4348 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4350 # NXT_RESUMEs should be 3.
4351 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4353 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4354 # Skipping the UDP checksum
4355 cat 5.expected | cut -c 1-120,125- > expout
4356 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4359 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4360 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4361 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4364 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4367 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4370 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4373 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4374 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4378 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4379 AT_SKIP_IF([test $HAVE_PYTHON = no])
4383 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4384 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4385 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4386 # R2 is a gateway router.
4390 # Create two hypervisor and create OVS ports corresponding to logical ports.
4395 ovs-vsctl add-br br-phys
4396 ovn_attach n1 br-phys 192.168.0.1
4397 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4398 set interface hv1-vif1 external-ids:iface-id=foo1 \
4399 options:tx_pcap=hv1/vif1-tx.pcap \
4400 options:rxq_pcap=hv1/vif1-rx.pcap \
4406 ovs-vsctl add-br br-phys
4407 ovn_attach n1 br-phys 192.168.0.2
4408 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4409 set interface hv2-vif1 external-ids:iface-id=alice1 \
4410 options:tx_pcap=hv2/vif1-tx.pcap \
4411 options:rxq_pcap=hv2/vif1-rx.pcap \
4414 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4415 # packets for ARP resolution (native tunneling doesn't queue packets
4416 # for ARP resolution).
4419 ovn-nbctl create Logical_Router name=R1
4420 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4422 ovn-nbctl ls-add foo
4423 ovn-nbctl ls-add alice
4424 ovn-nbctl ls-add join
4427 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4428 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4429 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4431 # Connect alice to R2
4432 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4433 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4434 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4436 # Connect R1 to join
4437 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4438 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4439 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4441 # Connect R2 to join
4442 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4443 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4444 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4447 #install static routes
4448 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4449 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4450 R1 static_routes @lrt
4452 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4453 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4454 R2 static_routes @lrt
4456 # Create logical port foo1 in foo
4457 ovn-nbctl lsp-add foo foo1 \
4458 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4460 # Create logical port alice1 in alice
4461 ovn-nbctl lsp-add alice alice1 \
4462 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4465 # Allow some time for ovn-northd and ovn-controller to catch up.
4466 # XXX This should be more systematic.
4470 printf "%02x%02x%02x%02x" "$@"
4473 # Send ip packets between foo1 and alice1
4474 src_mac="f00000010203"
4475 dst_mac="000001010203"
4476 src_ip=`ip_to_hex 192 168 1 2`
4477 dst_ip=`ip_to_hex 172 16 1 2`
4478 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4480 echo "---------NB dump-----"
4482 echo "---------------------"
4483 ovn-nbctl list logical_router
4484 echo "---------------------"
4485 ovn-nbctl list logical_router_port
4486 echo "---------------------"
4488 echo "---------SB dump-----"
4489 ovn-sbctl list datapath_binding
4490 echo "---------------------"
4491 ovn-sbctl list port_binding
4492 echo "---------------------"
4493 ovn-sbctl dump-flows
4494 echo "---------------------"
4495 ovn-sbctl list chassis
4496 ovn-sbctl list encap
4497 echo "---------------------"
4499 # Packet to Expect at alice1
4500 src_mac="000002010203"
4501 dst_mac="f00000010204"
4502 src_ip=`ip_to_hex 192 168 1 2`
4503 dst_ip=`ip_to_hex 172 16 1 2`
4504 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4507 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4508 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4510 echo "------ hv1 dump after packet 1 ----------"
4511 as hv1 ovs-ofctl show br-int
4512 as hv1 ovs-ofctl dump-flows br-int
4513 echo "------ hv2 dump after packet 1 ----------"
4514 as hv2 ovs-ofctl show br-int
4515 as hv2 ovs-ofctl dump-flows br-int
4516 echo "----------------------------"
4518 echo $expected > expected
4519 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4521 # Delete the router and re-create it. Things should work as before.
4523 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4524 # Connect alice to R2
4525 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4526 # Connect R2 to join
4527 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4529 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4530 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4531 R2 static_routes @lrt
4533 # Wait for ovn-controller to catch up.
4536 # Send the packet again.
4537 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4539 echo "------ hv1 dump after packet 2 ----------"
4540 as hv1 ovs-ofctl show br-int
4541 as hv1 ovs-ofctl dump-flows br-int
4542 echo "------ hv2 dump after packet 2 ----------"
4543 as hv2 ovs-ofctl show br-int
4544 as hv2 ovs-ofctl dump-flows br-int
4545 echo "----------------------------"
4547 echo $expected >> expected
4548 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4550 OVN_CLEANUP([hv1],[hv2])
4554 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4555 AT_KEYWORDS([router-icmp-reply])
4556 AT_SKIP_IF([test $HAVE_PYTHON = no])
4560 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4561 # and has switch ls2 (172.16.1.0/24) connected to it.
4565 ovn-nbctl ls-add ls1
4566 ovn-nbctl ls-add ls2
4569 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4570 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4571 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4574 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4575 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4576 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4578 # Create logical port ls1-lp1 in ls1
4579 ovn-nbctl lsp-add ls1 ls1-lp1 \
4580 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4582 # Create logical port ls2-lp1 in ls2
4583 ovn-nbctl lsp-add ls2 ls2-lp1 \
4584 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4586 # Create one hypervisor and create OVS ports corresponding to logical ports.
4591 ovs-vsctl add-br br-phys
4592 ovn_attach n1 br-phys 192.168.0.1
4593 ovs-vsctl -- add-port br-int vif1 -- \
4594 set interface vif1 external-ids:iface-id=ls1-lp1 \
4595 options:tx_pcap=hv1/vif1-tx.pcap \
4596 options:rxq_pcap=hv1/vif1-rx.pcap \
4599 ovs-vsctl -- add-port br-int vif2 -- \
4600 set interface vif2 external-ids:iface-id=ls2-lp1 \
4601 options:tx_pcap=hv1/vif2-tx.pcap \
4602 options:rxq_pcap=hv1/vif2-rx.pcap \
4606 # Allow some time for ovn-northd and ovn-controller to catch up.
4607 # XXX This should be more systematic.
4612 printf "%02x%02x%02x%02x" "$@"
4617 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4619 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4620 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4621 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4622 # provided, then it should be the ip and icmp checksums of the packet
4623 # responded; otherwise, no reply is expected.
4624 # In the absence of an ip checksum calculation helpers, this relies
4625 # on the caller to provide the checksums for the ip and icmp headers.
4626 # XXX This should be more systematic.
4628 # INPORT is an lport number, e.g. 11 for vif11.
4629 # ETH_SRC and ETH_DST are each 12 hex digits.
4630 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4631 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4632 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4633 test_ipv4_icmp_request() {
4634 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4635 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4636 shift; shift; shift; shift; shift; shift; shift
4639 # Use ttl to exercise section 4.2.2.9 of RFC1812
4643 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4644 local icmp_type_code_request=0800
4645 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4646 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4648 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4649 if test X$exp_icmp_chksum != X; then
4650 # Expect to receive the reply, if any. In same port where packet was sent.
4651 # Note: src and dst fields are expected to be reversed.
4652 local icmp_type_code_response=0000
4653 local reply_icmp_ttl=fe
4654 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4655 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4656 echo $reply >> vif$inport.expected
4660 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4661 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4662 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4663 l1_ip=$(ip_to_hex 192 168 1 2)
4664 l2_ip=$(ip_to_hex 172 16 1 2)
4666 # Ping router ip address that is on same subnet as the logical port
4667 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4668 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4670 # Ping router ip address that is on the other side of the logical ports
4671 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4672 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4674 echo "---------NB dump-----"
4676 echo "---------------------"
4677 ovn-nbctl list logical_router
4678 echo "---------------------"
4679 ovn-nbctl list logical_router_port
4680 echo "---------------------"
4682 echo "---------SB dump-----"
4683 ovn-sbctl list datapath_binding
4684 echo "---------------------"
4685 ovn-sbctl list logical_flow
4686 echo "---------------------"
4688 echo "------ hv1 dump ----------"
4689 as hv1 ovs-ofctl dump-flows br-int
4691 # Now check the packets actually received against the ones expected.
4692 for inport in 1 2; do
4693 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4700 # 1 hypervisor, 1 port
4701 # make sure that the port state is properly set to up and back down
4702 # when created and deleted.
4703 AT_SETUP([ovn -- port state up and down])
4706 ovn-nbctl ls-add ls1
4707 ovn-nbctl lsp-add ls1 lp1
4708 ovn-nbctl lsp-set-addresses lp1 unknown
4712 as hv1 ovs-vsctl add-br br-phys
4713 as hv1 ovn_attach n1 br-phys 192.168.0.1
4715 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4716 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4718 as hv1 ovs-vsctl del-port br-int vif1
4719 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4725 # 1 hypervisor, 1 port
4726 # make sure that the OF rules created to support a datapath are added/cleared
4727 # when logical switch is created and removed.
4728 AT_SETUP([ovn -- datapath rules added/removed])
4729 AT_KEYWORDS([cleanup])
4734 as hv1 ovs-vsctl add-br br-phys
4735 as hv1 ovn_attach n1 br-phys 192.168.0.1
4737 # This shell function checks if OF rules in br-int have clauses
4738 # related to OVN datapaths. The caller determines if it should find
4739 # a match in the output, or not.
4741 # EXPECT_DATAPATH param determines whether flows that refer to
4742 # datapath to should be present or not. 0 means
4743 # they should not be.
4744 # STAGE_INFO param is a simple string to help identify the stage
4745 # in the test when this function was invoked.
4746 test_datapath_in_of_rules() {
4747 local expect_datapath=$1 stage_info=$2
4748 echo "------ ovn-nbctl show ${stage_info} ------"
4750 echo "------ ovn-sbctl show ${stage_info} ------"
4752 echo "------ OF rules ${stage_info} ------"
4753 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4754 # if there is a datapath mentioned in the output, check for the
4755 # magic keyword that represents one, based on the exit status of
4757 if test $expect_datapath != 0; then
4758 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4760 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4764 test_datapath_in_of_rules 0 "before ls+port create"
4766 ovn-nbctl ls-add ls1
4767 ovn-nbctl lsp-add ls1 lp1
4768 ovn-nbctl lsp-set-addresses lp1 unknown
4770 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4771 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4773 test_datapath_in_of_rules 1 "after port is bound"
4775 as hv1 ovs-vsctl del-port br-int vif1
4776 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4778 ovn-nbctl lsp-set-addresses lp1
4779 ovn-nbctl lsp-del lp1
4780 ovn-nbctl ls-del ls1
4782 # wait for earlier changes to take effect
4783 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4785 # ensure OF rules are no longer present. There used to be a bug here.
4786 test_datapath_in_of_rules 0 "after lport+ls removal"
4792 AT_SETUP([ovn -- nd_na ])
4793 AT_SKIP_IF([test $HAVE_PYTHON = no])
4796 #TODO: since patch port for IPv6 logical router port is not ready not,
4797 # so we are not going to test vifs on different lswitches cases. Try
4798 # to update for that once relevant stuff implemented.
4800 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4801 # with. NS packet we test, from one VIF for another VIF, will be replied
4802 # by local ovn-controller, but not by target VIF.
4804 # Create hypervisors and logical switch lsw0.
4805 ovn-nbctl ls-add lsw0
4809 ovs-vsctl add-br br-phys
4810 ovn_attach n1 br-phys 192.168.0.2
4812 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4813 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
4814 ovn-nbctl lsp-add lsw0 lp1
4815 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4816 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"
4818 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4819 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
4820 ovn-nbctl lsp-add lsw0 lp2
4821 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4822 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"
4824 # Add ACL rule for ICMPv6 on lsw0
4825 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4826 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4827 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4829 # Allow some time for ovn-northd and ovn-controller to catch up.
4830 # XXX This should be more systematic.
4833 # Given the name of a logical port, prints the name of the hypervisor
4834 # on which it is located.
4842 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4843 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4844 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4845 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4846 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4848 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4849 echo $na_packet >> 1.expected
4851 echo "------ hv1 dump ------"
4852 as hv1 ovs-vsctl show
4853 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4854 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4857 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4864 AT_SETUP([ovn -- address sets modification/removal smoke test])
4871 ovs-vsctl add-br br-phys
4872 ovn_attach n1 br-phys 192.168.0.1
4874 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4875 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4876 ovn-nbctl destroy Address_Set $row
4880 # A bug previously existed in the address set support code
4881 # that caused ovn-controller to crash after an address set
4882 # was updated and then removed. This test case ensures
4883 # that ovn-controller is at least still running after
4884 # creating, updating, and deleting an address set.
4885 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4891 AT_SETUP([ovn -- ipam])
4892 AT_SKIP_IF([test $HAVE_PYTHON = no])
4895 # Add a port to a switch that does not have a subnet set, then set the
4896 # subnet which should result in an address being allocated for the port.
4897 ovn-nbctl ls-add sw0
4898 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4899 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4900 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4901 ["0a:00:00:00:00:01 192.168.1.2"
4904 # Add 9 more ports to sw0, addresses should all be unique.
4905 for n in `seq 1 9`; do
4906 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4908 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4909 ["0a:00:00:00:00:02 192.168.1.3"
4911 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4912 ["0a:00:00:00:00:03 192.168.1.4"
4914 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4915 ["0a:00:00:00:00:04 192.168.1.5"
4917 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4918 ["0a:00:00:00:00:05 192.168.1.6"
4920 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4921 ["0a:00:00:00:00:06 192.168.1.7"
4923 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4924 ["0a:00:00:00:00:07 192.168.1.8"
4926 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4927 ["0a:00:00:00:00:08 192.168.1.9"
4929 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4930 ["0a:00:00:00:00:09 192.168.1.10"
4932 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4933 ["0a:00:00:00:00:0a 192.168.1.11"
4936 # Trying similar tests with a second switch. MAC addresses should be unique
4937 # across both switches but IP's only need to be unique within the same switch.
4938 ovn-nbctl ls-add sw1
4939 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4940 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4941 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4942 ["0a:00:00:00:00:0b 192.168.1.2"
4945 for n in `seq 11 19`; do
4946 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4948 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4949 ["0a:00:00:00:00:0c 192.168.1.3"
4951 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4952 ["0a:00:00:00:00:0d 192.168.1.4"
4954 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4955 ["0a:00:00:00:00:0e 192.168.1.5"
4957 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4958 ["0a:00:00:00:00:0f 192.168.1.6"
4960 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4961 ["0a:00:00:00:00:10 192.168.1.7"
4963 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4964 ["0a:00:00:00:00:11 192.168.1.8"
4966 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4967 ["0a:00:00:00:00:12 192.168.1.9"
4969 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4970 ["0a:00:00:00:00:13 192.168.1.10"
4972 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4973 ["0a:00:00:00:00:14 192.168.1.11"
4976 # Change a port's address to test for multiple ip's for a single address entry
4977 # and addresses set by the user.
4978 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4979 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4980 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4981 ["0a:00:00:00:00:16 192.168.1.13"
4984 # Test for logical router port address management.
4985 ovn-nbctl create Logical_Router name=R1
4986 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4987 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4988 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4989 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4990 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4991 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4992 ["0a:00:00:00:00:18 192.168.1.15"
4995 # Test for address reuse after logical port is deleted.
4996 ovn-nbctl lsp-del p0
4997 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4998 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4999 ["0a:00:00:00:00:19 192.168.1.2"
5002 # Test for multiple addresses to one logical port.
5003 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5004 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
5005 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
5006 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5007 ["0a:00:00:00:00:1c 192.168.1.16"
5010 # Test for exhausting subnet address space.
5011 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
5012 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
5013 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5014 ["0a:00:00:00:00:1d 172.16.1.2"
5017 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
5018 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
5019 ["0a:00:00:00:00:1e"
5022 # Test that address management does not add duplicate MAC for lsp/lrp peers.
5023 ovn-nbctl create Logical_Router name=R2
5024 ovn-nbctl ls-add sw3
5025 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
5027 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5028 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5029 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5030 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
5031 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
5032 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5033 ["0a:00:00:00:00:20 192.168.1.17"
5036 # Test static MAC address with dynamically allocated IP
5037 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5038 "fe:dc:ba:98:76:54 dynamic"
5039 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5040 ["fe:dc:ba:98:76:54 192.168.1.18"
5043 # Update the static MAC address with dynamically allocated IP and check
5044 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5045 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5046 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5048 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5049 ["fe:dc:ba:98:76:55 192.168.1.18"
5052 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5053 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5054 ["fe:dc:ba:98:76:55 192.168.1.18"
5057 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5058 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5059 ["fe:dc:ba:98:76:56 192.168.1.18"
5063 # Test the exclude_ips from the IPAM list
5064 ovn-nbctl --wait=sb set logical_switch sw0 \
5065 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5067 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5069 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5070 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5071 ["0a:00:00:00:00:21 192.168.1.20"
5074 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5076 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5077 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5078 ["0a:00:00:00:00:22 192.168.1.22"
5081 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5083 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5084 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5085 ["0a:00:00:00:00:23 192.168.1.51"
5088 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5089 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5090 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5092 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5093 ["0a:00:00:00:00:24 192.168.1.19"
5096 # Set invalid data in exclude_ips list. It should be ignored.
5097 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5098 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5100 # 192.168.1.21 should be assigned as that's the next free one.
5101 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5102 ["0a:00:00:00:00:25 192.168.1.21"
5105 # Clear the dynamic addresses assignment request.
5106 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5107 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5112 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5113 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5116 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5117 # - aef0::800:ff:fe00:26 (EUI64)
5118 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5119 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5122 ovn-nbctl --wait=sb ls-add sw4
5123 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5124 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5127 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5128 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5131 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5132 "f0:00:00:00:10:12 dynamic"
5134 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5135 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5138 # Clear the other_config for sw4. No dynamic ip should be assigned.
5139 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5140 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5143 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5147 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5148 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5149 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5151 # Now p40 should be assigned with dynamic addresses.
5152 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5153 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5156 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5158 # p41 should not have IPv4 address (as the pool is exhausted).
5159 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5160 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5164 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5167 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5170 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5174 AT_SETUP([ovn -- ipam connectivity])
5175 AT_SKIP_IF([test $HAVE_PYTHON = no])
5180 # Test for a ping using dynamically allocated addresses.
5181 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5182 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5185 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5186 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5187 options:router-port=foo \
5188 -- lsp-set-addresses rp-foo router
5190 # Connect alice to R1
5191 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5192 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5193 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5195 # Create logical port foo1 in foo
5196 ovn-nbctl --wait=sb lsp-add foo foo1 \
5197 -- lsp-set-addresses foo1 "dynamic"
5198 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])
5200 # Create logical port alice1 in alice
5201 ovn-nbctl --wait=sb lsp-add alice alice1 \
5202 -- lsp-set-addresses alice1 "dynamic"
5203 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5205 # Create logical port foo2 in foo
5206 ovn-nbctl --wait=sb lsp-add foo foo2 \
5207 -- lsp-set-addresses foo2 "dynamic"
5208 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5210 # Create a hypervisor and create OVS ports corresponding to logical ports.
5215 ovs-vsctl add-br br-phys
5216 ovn_attach n1 br-phys 192.168.0.1
5217 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5218 set interface hv1-vif1 external-ids:iface-id=foo1 \
5219 options:tx_pcap=hv1/vif1-tx.pcap \
5220 options:rxq_pcap=hv1/vif1-rx.pcap \
5223 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5224 set interface hv1-vif2 external-ids:iface-id=foo2 \
5225 options:tx_pcap=hv1/vif2-tx.pcap \
5226 options:rxq_pcap=hv1/vif2-rx.pcap \
5229 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5230 set interface hv1-vif3 external-ids:iface-id=alice1 \
5231 options:tx_pcap=hv1/vif3-tx.pcap \
5232 options:rxq_pcap=hv1/vif3-rx.pcap \
5235 # Allow some time for ovn-northd and ovn-controller to catch up.
5236 # XXX This should be more systematic.
5240 printf "%02x%02x%02x%02x" "$@"
5243 # Send ip packets between foo1 and foo2
5244 src_mac="0a0000000001"
5245 dst_mac="0a0000000003"
5246 src_ip=`ip_to_hex 192 168 1 2`
5247 dst_ip=`ip_to_hex 192 168 1 3`
5248 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5249 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5251 # Send ip packets between foo1 and alice1
5252 src_mac="0a0000000001"
5253 dst_mac="000000010203"
5254 src_ip=`ip_to_hex 192 168 1 2`
5255 dst_ip=`ip_to_hex 192 168 2 2`
5256 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5257 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5259 echo "---------NB dump-----"
5261 echo "---------------------"
5262 ovn-nbctl list logical_router
5263 echo "---------------------"
5264 ovn-nbctl list logical_router_port
5265 echo "---------------------"
5267 echo "---------SB dump-----"
5268 ovn-sbctl list datapath_binding
5269 echo "---------------------"
5270 ovn-sbctl list port_binding
5271 echo "---------------------"
5273 echo "------ hv1 dump ----------"
5274 as hv1 ovs-ofctl dump-flows br-int
5276 # Packet to Expect at foo2
5277 src_mac="0a0000000001"
5278 dst_mac="0a0000000003"
5279 src_ip=`ip_to_hex 192 168 1 2`
5280 dst_ip=`ip_to_hex 192 168 1 3`
5281 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5283 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5284 echo $expected > expout
5285 AT_CHECK([cat received1.packets], [0], [expout])
5287 # Packet to Expect at alice1
5288 src_mac="000000010204"
5289 dst_mac="0a0000000002"
5290 src_ip=`ip_to_hex 192 168 1 2`
5291 dst_ip=`ip_to_hex 192 168 2 2`
5292 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5294 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5295 echo $expected > expout
5296 AT_CHECK([cat received2.packets], [0], [expout])
5302 AT_SETUP([ovn -- ovs-vswitchd restart])
5303 AT_KEYWORDS([vswitchd])
5304 AT_SKIP_IF([test $HAVE_PYTHON = no])
5307 ovn-nbctl ls-add ls1
5309 ovn-nbctl lsp-add ls1 ls1-lp1 \
5310 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5312 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5318 ovs-vsctl add-br br-phys
5319 ovn_attach n1 br-phys 192.168.0.1
5320 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5321 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5322 options:tx_pcap=hv1/vif1-tx.pcap \
5323 options:rxq_pcap=hv1/vif1-rx.pcap \
5329 as hv1 ovs-vsctl show
5331 echo "---------------------"
5332 ovn-sbctl dump-flows
5333 echo "---------------------"
5335 echo "------ hv1 dump ----------"
5336 as hv1 ovs-ofctl dump-flows br-int
5337 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5339 echo "Total flows before vswitchd restart = " $total_flows
5341 # Code taken from ovs-save utility
5343 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5344 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5345 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5346 echo "EOF" >> restore_flows.sh
5349 restart_vswitchd () {
5352 if test $restore_flows = true; then
5357 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5359 if test $restore_flows = true; then
5361 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5365 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5366 ovs-ofctl dump-flows br-int
5368 if test $restore_flows = true; then
5369 sh ./restore_flows.sh
5370 echo "Flows after restore"
5372 ovs-ofctl dump-flows br-int
5373 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5374 flow-restore-wait="true"
5378 # Save the flows, restart vswitchd and restore the flows
5379 restart_vswitchd true
5381 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5382 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5383 test "${total_flows}" = "${total_flows_after_restart}"
5386 # Restart vswitchd without restoring
5387 restart_vswitchd false
5389 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5390 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5391 test "${total_flows}" = "${total_flows_after_restart}"
5397 AT_SETUP([ovn -- send arp for nexthop])
5398 AT_SKIP_IF([test $HAVE_PYTHON = no])
5401 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5403 # Create logical switches
5404 ovn-nbctl ls-add ls1
5405 ovn-nbctl ls-add ls2
5408 ovn-nbctl create Logical_Router name=lr0
5410 # Add router ls1p1 port to gateway router
5411 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5412 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5413 type=router options:router-port=lrp-ls1lp1 \
5414 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5416 # Add router ls2p2 port to gateway router
5417 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5418 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5419 type=router options:router-port=lrp-ls2lp1 \
5420 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5422 # Set default gateway (nexthop) to 192.168.1.254
5423 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5425 # Create logical port ls1lp2 in ls1
5426 ovn-nbctl lsp-add ls1 ls1lp2 \
5427 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5429 # Create logical port ls2lp2 in ls2
5430 ovn-nbctl lsp-add ls2 ls2lp2 \
5431 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5436 ovs-vsctl add-br br-phys
5437 ovn_attach n1 br-phys 192.168.0.1
5438 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5439 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5440 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5441 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5443 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5444 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5445 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5446 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5449 # Allow some time for ovn-northd and ovn-controller to catch up.
5450 # XXX This should be more systematic.
5453 echo "---------NB dump-----"
5455 echo "---------------------"
5456 ovn-nbctl list logical_router
5457 echo "---------------------"
5458 ovn-nbctl list logical_router_port
5459 echo "---------------------"
5461 echo "---------SB dump-----"
5462 ovn-sbctl list datapath_binding
5463 echo "---------------------"
5464 ovn-sbctl list port_binding
5465 echo "---------------------"
5466 ovn-sbctl dump-flows
5467 echo "---------------------"
5468 ovn-sbctl list chassis
5469 ovn-sbctl list encap
5470 echo "---------------------"
5472 echo "------Flows dump-----"
5474 ovs-ofctl dump-flows
5475 echo "---------------------"
5478 printf "%02x%02x%02x%02x" "$@"
5481 src_mac="f00000000003"
5482 dst_mac="f00000000001"
5483 src_ip=`ip_to_hex 192 168 0 2`
5484 dst_ip=`ip_to_hex 8 8 8 8`
5485 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5487 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5488 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5491 sed 's/\(00\)\{1,\}$//'
5494 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5497 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5498 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5499 echo $expected > expout
5500 AT_CHECK([cat packets], [0], [expout])
5507 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5508 AT_SKIP_IF([test $HAVE_PYTHON = no])
5510 # Create logical switch
5511 ovn-nbctl ls-add ls0
5512 # Create gateway router
5513 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5514 # Add router port to gateway router
5515 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5516 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5517 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5518 # Add nat-address option
5519 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5528 ovn_attach n1 br-phys 192.168.0.1
5530 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5531 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])
5533 # Create a localnet port.
5534 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5535 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5536 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5537 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5540 # Wait for packet to be received.
5541 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5543 sed 's/\(00\)\{1,\}$//'
5545 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5546 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5547 echo $expected > expout
5548 AT_CHECK([sort packets], [0], [expout])
5555 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5556 AT_SKIP_IF([test $HAVE_PYTHON = no])
5558 # Create logical switch
5559 ovn-nbctl ls-add ls0
5560 # Create gateway router
5561 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5562 # Add router port to gateway router
5563 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5564 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5565 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5566 # Add nat-address option
5567 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5569 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5570 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5571 # Add load balancers
5572 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5573 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5574 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5575 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5584 ovn_attach n1 br-phys 192.168.0.1
5586 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5587 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])
5589 # Create a localnet port.
5590 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5591 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5592 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5593 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5596 # Wait for packet to be received.
5597 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5599 sed 's/\(00\)\{1,\}$//'
5601 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5602 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5603 echo $expected > expout
5604 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5605 echo $expected >> expout
5606 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5607 echo $expected >> expout
5608 AT_CHECK([sort packets], [0], [expout])
5615 AT_SETUP([ovn -- delete mac bindings])
5620 ovs-vsctl -- add-br br-phys
5621 ovn_attach n1 br-phys 192.168.0.1
5622 # Create logical switch ls0
5623 ovn-nbctl ls-add ls0
5624 # Create ports lp0, lp1 in ls0
5625 ovn-nbctl lsp-add ls0 lp0
5626 ovn-nbctl lsp-add ls0 lp1
5627 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5628 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5629 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5630 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5631 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5632 ovn-sbctl find MAC_Binding
5633 # Delete port lp0 and check that its MAC_Binding is deleted.
5634 ovn-nbctl lsp-del lp0
5635 ovn-sbctl find MAC_Binding
5636 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5637 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5638 ovn-nbctl ls-del ls0
5639 ovn-sbctl find MAC_Binding
5640 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5646 AT_SETUP([ovn -- conntrack zone allocation])
5647 AT_SKIP_IF([test $HAVE_PYTHON = no])
5651 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5652 # connected to a router R1.
5653 # foo has foo1 to act as a client.
5654 # bar has bar1, bar2, bar3 to act as servers.
5660 ovs-vsctl add-br br-phys
5661 ovn_attach n1 br-phys 192.168.0.1
5662 for i in foo1 bar1 bar2 bar3; do
5663 ovs-vsctl -- add-port br-int $i -- \
5664 set interface $i external-ids:iface-id=$i \
5665 options:tx_pcap=hv1/$i-tx.pcap \
5666 options:rxq_pcap=hv1/$i-rx.pcap
5669 ovn-nbctl create Logical_Router name=R1
5670 ovn-nbctl ls-add foo
5671 ovn-nbctl ls-add bar
5674 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5675 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5676 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5679 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5680 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5681 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5683 # Create logical port foo1 in foo
5684 ovn-nbctl lsp-add foo foo1 \
5685 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5687 # Create logical port bar1, bar2 and bar3 in bar
5688 for i in `seq 1 3`; do
5690 ovn-nbctl lsp-add bar bar$i \
5691 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5694 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5700 AT_SETUP([ovn -- tag allocation])
5703 AT_CHECK([ovn-nbctl ls-add ls0])
5704 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5705 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5706 AT_CHECK([ovn-nbctl ls-add ls1])
5708 dnl When a tag is provided, no allocation is done
5709 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5710 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5712 dnl The same 'tag' gets created in southbound database.
5713 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5714 logical_port="c0"], [0], [3
5717 dnl Allocate tags and see it getting created in both NB and SB
5718 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5719 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5721 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5722 logical_port="c1"], [0], [1
5725 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5726 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5728 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5729 logical_port="c2"], [0], [2
5731 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5732 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5734 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5735 logical_port="c3"], [0], [4
5738 dnl A different parent.
5739 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5740 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5742 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5743 logical_port="c4"], [0], [1
5746 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5747 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5749 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5750 logical_port="c5"], [0], [2
5753 dnl Delete a logical port and create a new one.
5754 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5755 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5756 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5758 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5759 logical_port="c6"], [0], [1
5762 dnl Restart northd to see that the same allocation remains.
5764 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5765 start_daemon ovn-northd \
5766 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5767 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5769 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5770 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5771 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5773 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5775 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5777 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5779 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5781 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5784 dnl Create a switch port with a tag that has already been allocated.
5785 dnl It should go through fine with a duplicate tag.
5786 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5787 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5789 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5790 logical_port="c7"], [0], [2
5792 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5795 AT_CHECK([ovn-nbctl ls-add ls2])
5796 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5797 dnl gets copied to 'tag'
5798 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5799 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5801 dnl The same 'tag' gets created in southbound database.
5802 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5803 logical_port="local0"], [0], [25
5805 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5806 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5807 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5808 dnl change the tag_request.
5809 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5810 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5815 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5817 ovn-nbctl ls-add lsw0
5822 ovs-vsctl add-br br-phys
5823 ovn_attach n1 br-phys 192.168.0.$i
5824 ovs-vsctl add-br br-eth0
5825 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5828 # Create a localnet port.
5829 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5830 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5831 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5832 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5836 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5837 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5838 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5839 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5840 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5841 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5842 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5843 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5844 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5846 # Bind the localvif1 to hv1.
5848 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5850 # On hv1, check that there are no flows outputting bcast to tunnel
5851 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5853 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5855 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5857 # Now bind vif2 on hv2.
5858 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5860 # At this point, the broadcast flow on vif2 should be deleted.
5861 # because, there is now a localnet vif bound (table=32 programming logic)
5862 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5864 # Verify that the local net patch port exists on hv2.
5865 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5867 # Now bind vif3 on hv2.
5868 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5870 # Verify that the local net patch port still exists on hv2
5871 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5874 AT_CHECK([ovn-nbctl lsp-del localvif2])
5876 # Verify that the local net patch port still exists on hv2,
5877 # because, localvif3 is still bound.
5878 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5880 OVN_CLEANUP([hv1],[hv2])
5885 AT_SETUP([ovn -- ACL logging])
5893 ovs-vsctl add-br br-phys
5894 ovn_attach n1 br-phys 192.168.0.1
5895 for i in lp1 lp2; do
5896 ovs-vsctl -- add-port br-int $i -- \
5897 set interface $i external-ids:iface-id=$i \
5898 options:tx_pcap=hv/$i-tx.pcap \
5899 options:rxq_pcap=hv/$i-rx.pcap
5902 lp1_mac="f0:00:00:00:00:01"
5903 lp1_ip="192.168.1.2"
5905 lp2_mac="f0:00:00:00:00:02"
5906 lp2_ip="192.168.1.3"
5908 ovn-nbctl ls-add lsw0
5909 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5910 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5911 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5912 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5913 ovn-nbctl --wait=sb sync
5915 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5916 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5918 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5919 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5921 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5922 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5924 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5925 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5927 ovn-sbctl dump-flows
5930 # Send packet that should be dropped without logging.
5931 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5932 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5933 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5934 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5936 # Send packet that should be dropped with logging.
5937 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5938 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5939 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5940 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5942 # Send packet that should be allowed without logging.
5943 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5944 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5945 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
5946 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5948 # Send packet that should be allowed with logging.
5949 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5950 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5951 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
5952 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5954 # Send packet that should allow related flows without logging.
5955 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5956 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5957 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
5958 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5960 # Send packet that should allow related flows with logging.
5961 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5962 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5963 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
5964 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5966 # Send packet that should be rejected without logging.
5967 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5968 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5969 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
5970 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5972 # Send packet that should be rejected with logging.
5973 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5974 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5975 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
5976 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5978 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
5980 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
5981 name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
5982 name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
5983 name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
5984 name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
5991 AT_SETUP([ovn -- DSCP marking and meter check])
5995 ovn-nbctl ls-add lsw0
5996 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5997 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5998 ovn-nbctl --wait=sb lsp-add lsw0 lp3
5999 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6000 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
6001 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
6002 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6003 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6004 ovn-nbctl --wait=sb sync
6008 ovs-vsctl add-br br-phys
6009 ovn_attach n1 br-phys 192.168.0.1
6010 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
6011 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
6013 AT_CAPTURE_FILE([trace])
6015 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6018 # Extracts nw_tos from the final flow from ofproto/trace output and prints
6019 # it on stdout. Prints "none" if no nw_tos was included.
6020 get_final_nw_tos() {
6021 if flow=$(grep '^Final flow:' stdout); then :; else
6022 # The output didn't have a final flow.
6026 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6035 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6037 # First check with ovn-trace for logical flows.
6038 echo "checking for tos $1"
6039 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6040 echo 'output("lp2");') > expout
6041 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])
6043 # Then re-check with ofproto/trace for a physical packet.
6044 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])
6045 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6050 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");
6052 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])
6053 AT_CHECK([get_final_nw_tos], [0], [none
6056 # check at L3 without dscp marking
6059 # Mark DSCP with a valid value
6060 qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"\ &&\ is_chassis_resident(\"lp1\")" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
6061 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6065 # check at hv without qos meter
6066 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6069 # Update the meter rate
6070 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6072 # check at hv with a qos meter table
6073 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6075 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6078 # Update the DSCP marking
6079 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6082 # Update the meter rate
6083 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6085 # check at hv with a qos meter table
6086 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6088 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6091 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6094 # Disable DSCP marking
6095 ovn-nbctl --wait=hv qos-del lsw0
6096 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6100 # check at hv without qos meter
6101 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6104 # check meter with chassis not resident
6105 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6106 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6109 # check no meter table
6110 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6112 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6118 AT_SETUP([ovn -- read-only sb db:ptcp access])
6119 AT_SKIP_IF([test $HAVE_PYTHON = no])
6122 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6124 # Add read-only remote to sb ovsdb-server
6126 [ovsdb-tool transact ovn-sb.db \
6127 ['["OVN_Southbound",
6129 "table": "SB_Global",
6131 "connections": ["set", [["named-uuid", "xyz"]]]}},
6133 "table": "Connection",
6135 "row": {"target": "ptcp:0:127.0.0.1",
6136 "read_only": true}}]']], [0], [ignore], [ignore])
6138 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6140 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6142 # read-only accesses should succeed
6143 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6144 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6146 # write access should fail
6147 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6148 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6151 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6154 AT_SETUP([ovn -- read-only sb db:pssl access])
6155 AT_SKIP_IF([test $HAVE_PYTHON = no])
6156 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6157 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6158 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6162 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6164 # Add read-only remote to sb ovsdb-server
6166 [ovsdb-tool transact ovn-sb.db \
6167 ['["OVN_Southbound",
6169 "table": "SB_Global",
6171 "connections": ["set", [["named-uuid", "xyz"]]]}},
6173 "table": "Connection",
6175 "row": {"target": "pssl:0:127.0.0.1",
6176 "read_only": true}}]']], [0], [ignore], [ignore])
6178 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6179 --remote=db:OVN_Southbound,SB_Global,connections \
6180 --private-key="$PKIDIR/testpki-privkey2.pem" \
6181 --certificate="$PKIDIR/testpki-cert2.pem" \
6182 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6185 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6187 # read-only accesses should succeed
6188 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6189 --private-key=$PKIDIR/testpki-privkey.pem \
6190 --certificate=$PKIDIR/testpki-cert.pem \
6191 --ca-cert=$PKIDIR/testpki-cacert.pem \
6192 list SB_Global], [0], [stdout], [ignore])
6193 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6194 --private-key=$PKIDIR/testpki-privkey.pem \
6195 --certificate=$PKIDIR/testpki-cert.pem \
6196 --ca-cert=$PKIDIR/testpki-cacert.pem \
6197 list Connection], [0], [stdout], [ignore])
6199 # write access should fail
6200 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6201 --private-key=$PKIDIR/testpki-privkey.pem \
6202 --certificate=$PKIDIR/testpki-cert.pem \
6203 --ca-cert=$PKIDIR/testpki-cacert.pem \
6204 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6205 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6208 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6211 AT_SETUP([ovn -- nb connection/ssl commands])
6212 AT_SKIP_IF([test $HAVE_PYTHON = no])
6213 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6214 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6215 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6219 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6221 # Start nb db server using db connection/ssl entries (unpopulated initially)
6222 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6223 --remote=db:OVN_Northbound,NB_Global,connections \
6224 --private-key=db:OVN_Northbound,SSL,private_key \
6225 --certificate=db:OVN_Northbound,SSL,certificate \
6226 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6229 # Populate SSL configuration entries in nb db
6231 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6232 $PKIDIR/testpki-cert.pem \
6233 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6235 # Populate a passive SSL connection in nb db
6236 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6238 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6240 # Verify SSL connetivity to nb db server
6241 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6242 --private-key=$PKIDIR/testpki-privkey.pem \
6243 --certificate=$PKIDIR/testpki-cert.pem \
6244 --ca-cert=$PKIDIR/testpki-cacert.pem \
6246 [0], [stdout], [ignore])
6247 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6248 --private-key=$PKIDIR/testpki-privkey.pem \
6249 --certificate=$PKIDIR/testpki-cert.pem \
6250 --ca-cert=$PKIDIR/testpki-cacert.pem \
6252 [0], [stdout], [ignore])
6253 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6254 --private-key=$PKIDIR/testpki-privkey.pem \
6255 --certificate=$PKIDIR/testpki-cert.pem \
6256 --ca-cert=$PKIDIR/testpki-cacert.pem \
6258 [0], [stdout], [ignore])
6260 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6263 AT_SETUP([ovn -- sb connection/ssl commands])
6264 AT_SKIP_IF([test $HAVE_PYTHON = no])
6265 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6266 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6267 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6271 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6273 # Start sb db server using db connection/ssl entries (unpopulated initially)
6274 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6275 --remote=db:OVN_Southbound,SB_Global,connections \
6276 --private-key=db:OVN_Southbound,SSL,private_key \
6277 --certificate=db:OVN_Southbound,SSL,certificate \
6278 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6281 # Populate SSL configuration entries in sb db
6283 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6284 $PKIDIR/testpki-cert.pem \
6285 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6287 # Populate a passive SSL connection in sb db
6288 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6290 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6292 # Verify SSL connetivity to sb db server
6293 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6294 --private-key=$PKIDIR/testpki-privkey.pem \
6295 --certificate=$PKIDIR/testpki-cert.pem \
6296 --ca-cert=$PKIDIR/testpki-cacert.pem \
6298 [0], [stdout], [ignore])
6299 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6300 --private-key=$PKIDIR/testpki-privkey.pem \
6301 --certificate=$PKIDIR/testpki-cert.pem \
6302 --ca-cert=$PKIDIR/testpki-cacert.pem \
6304 [0], [stdout], [ignore])
6305 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6306 --private-key=$PKIDIR/testpki-privkey.pem \
6307 --certificate=$PKIDIR/testpki-cert.pem \
6308 --ca-cert=$PKIDIR/testpki-cacert.pem \
6310 [0], [stdout], [ignore])
6312 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6315 AT_SETUP([ovn -- nested containers])
6319 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6322 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6323 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6326 ovn-nbctl ls-add mgmt
6327 ovn-nbctl ls-add foo
6328 ovn-nbctl ls-add bar
6330 # Connect mgmt to R1
6331 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6332 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6333 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6336 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6337 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6338 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6341 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6342 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6343 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6345 # "mgmt" has VM1 and VM2 connected
6346 ovn-nbctl lsp-add mgmt vm1 \
6347 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6349 ovn-nbctl lsp-add mgmt vm2 \
6350 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6352 # "foo1" and "foo2" are containers belonging to switch "foo"
6353 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6354 ovn-nbctl lsp-add foo foo1 vm1 1 \
6355 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6357 ovn-nbctl lsp-add foo foo2 vm2 2 \
6358 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6360 # "bar1" and "bar2" are containers belonging to switch "bar"
6361 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6362 ovn-nbctl lsp-add bar bar1 vm1 2 \
6363 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6365 ovn-nbctl lsp-add bar bar2 vm2 1 \
6366 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6368 # bar3 is a standalone VM belonging to switch "bar"
6369 ovn-nbctl lsp-add bar bar3 \
6370 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6372 # Create two hypervisor and create OVS ports corresponding to logical ports.
6377 ovs-vsctl add-br br-phys
6378 ovn_attach n1 br-phys 192.168.0.1
6379 ovs-vsctl -- add-port br-int vm1 -- \
6380 set interface vm1 external-ids:iface-id=vm1 \
6381 options:tx_pcap=hv1/vm1-tx.pcap \
6382 options:rxq_pcap=hv1/vm1-rx.pcap \
6385 ovs-vsctl -- add-port br-int bar3 -- \
6386 set interface bar3 external-ids:iface-id=bar3 \
6387 options:tx_pcap=hv1/bar3-tx.pcap \
6388 options:rxq_pcap=hv1/bar3-rx.pcap \
6393 ovs-vsctl add-br br-phys
6394 ovn_attach n1 br-phys 192.168.0.2
6395 ovs-vsctl -- add-port br-int vm2 -- \
6396 set interface vm2 external-ids:iface-id=vm2 \
6397 options:tx_pcap=hv2/vm2-tx.pcap \
6398 options:rxq_pcap=hv2/vm2-rx.pcap \
6401 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6402 # packets for ARP resolution (native tunneling doesn't queue packets
6403 # for ARP resolution).
6406 # Allow some time for ovn-northd and ovn-controller to catch up.
6407 # XXX This should be more systematic.
6411 printf "%02x%02x%02x%02x" "$@"
6414 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6415 # different VLAN tags).
6416 src_mac="f00000010205"
6417 dst_mac="f00000010206"
6418 src_ip=`ip_to_hex 192 168 1 2`
6419 dst_ip=`ip_to_hex 192 168 1 3`
6420 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6421 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6423 # expected packet at foo2
6424 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6425 echo $packet > expected
6426 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6428 # Send ip packets between foo1 and bar2 (different switch, different HV)
6429 src_mac="f00000010205"
6430 dst_mac="000000010203"
6431 src_ip=`ip_to_hex 192 168 1 2`
6432 dst_ip=`ip_to_hex 192 168 2 3`
6433 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6434 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6436 # expected packet at bar2
6437 src_mac="000000010204"
6438 dst_mac="f00000010208"
6439 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6440 echo $packet >> expected
6441 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6443 # Send ip packets between foo1 and bar1
6444 # (different switch, loopback to same vm but different tag)
6445 src_mac="f00000010205"
6446 dst_mac="000000010203"
6447 src_ip=`ip_to_hex 192 168 1 2`
6448 dst_ip=`ip_to_hex 192 168 2 2`
6449 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6450 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6452 # expected packet at bar1
6453 src_mac="000000010204"
6454 dst_mac="f00000010207"
6455 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6456 echo $packet > expected1
6457 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6459 # Send ip packets between bar1 and bar3
6460 # (same switch. But one is container and another is a standalone VM)
6461 src_mac="f00000010207"
6462 dst_mac="f00000010209"
6463 src_ip=`ip_to_hex 192 168 2 2`
6464 dst_ip=`ip_to_hex 192 168 2 3`
6465 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6466 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6468 # expected packet at bar3
6469 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6470 echo $packet > expected
6471 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6473 # Send ip packets between foo1 and vm1.
6474 (different switch, container to the VM hosting it.)
6475 src_mac="f00000010205"
6476 dst_mac="000000010203"
6477 src_ip=`ip_to_hex 192 168 1 2`
6478 dst_ip=`ip_to_hex 172 16 1 2`
6479 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6480 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6482 # expected packet at vm1
6483 src_mac="000000010202"
6484 dst_mac="f00000010203"
6485 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6486 echo $packet >> expected1
6487 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6489 # Send packets from vm1 to bar1.
6490 (different switch, A hosting VM to a container inside it)
6491 src_mac="f00000010203"
6492 dst_mac="000000010202"
6493 src_ip=`ip_to_hex 172 16 1 2`
6494 dst_ip=`ip_to_hex 192 168 2 2`
6495 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6496 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6498 # expected packet at vm1
6499 src_mac="000000010204"
6500 dst_mac="f00000010207"
6501 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6502 echo $packet >> expected1
6503 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6505 OVN_CLEANUP([hv1],[hv2])
6509 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6510 AT_SKIP_IF([test $HAVE_PYTHON = no])
6514 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6515 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6516 # (192.168.2.0/24) connected to it.
6518 # R2 and R3 are gateway routers.
6519 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6520 # connected to it. Note how both alice and bob have the same subnet behind it.
6521 # We are trying to simulate external network via those 2 switches. In real
6522 # world the switch ports of these switches will have addresses set as "unknown"
6523 # to make them learning switches. Or those switches will be "localnet" ones.
6525 # Create three hypervisors and create OVS ports corresponding to logical ports.
6530 ovs-vsctl add-br br-phys
6531 ovn_attach n1 br-phys 192.168.0.1
6532 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6533 set interface hv1-vif1 external-ids:iface-id=foo1 \
6534 options:tx_pcap=hv1/vif1-tx.pcap \
6535 options:rxq_pcap=hv1/vif1-rx.pcap \
6538 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6539 set interface hv1-vif2 external-ids:iface-id=bar1 \
6540 options:tx_pcap=hv1/vif2-tx.pcap \
6541 options:rxq_pcap=hv1/vif2-rx.pcap \
6546 ovs-vsctl add-br br-phys
6547 ovn_attach n1 br-phys 192.168.0.2
6548 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6549 set interface hv2-vif1 external-ids:iface-id=alice1 \
6550 options:tx_pcap=hv2/vif1-tx.pcap \
6551 options:rxq_pcap=hv2/vif1-rx.pcap \
6556 ovs-vsctl add-br br-phys
6557 ovn_attach n1 br-phys 192.168.0.3
6558 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6559 set interface hv3-vif1 external-ids:iface-id=bob1 \
6560 options:tx_pcap=hv3/vif1-tx.pcap \
6561 options:rxq_pcap=hv3/vif1-rx.pcap \
6565 ovn-nbctl create Logical_Router name=R1
6566 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6567 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6569 ovn-nbctl ls-add foo
6570 ovn-nbctl ls-add bar
6571 ovn-nbctl ls-add alice
6572 ovn-nbctl ls-add bob
6573 ovn-nbctl ls-add join
6576 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6577 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6578 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6581 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6582 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6583 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6585 # Connect alice to R2
6586 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6587 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6588 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6591 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6592 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6593 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6595 # Connect R1 to join
6596 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6597 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6598 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6600 # Connect R2 to join
6601 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6602 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6603 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6605 # Connect R3 to join
6606 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6607 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6608 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6610 # Install static routes with source ip address as the policy for routing.
6611 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6612 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6613 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6615 # Install static routes with destination ip address as the policy for routing.
6616 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6618 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6620 # Create logical port foo1 in foo
6621 ovn-nbctl lsp-add foo foo1 \
6622 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6624 # Create logical port bar1 in bar
6625 ovn-nbctl lsp-add bar bar1 \
6626 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6628 # Create logical port alice1 in alice
6629 ovn-nbctl lsp-add alice alice1 \
6630 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6632 # Create logical port bob1 in bob
6633 ovn-nbctl lsp-add bob bob1 \
6634 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6636 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6637 # packets for ARP resolution (native tunneling doesn't queue packets
6638 # for ARP resolution).
6641 # Allow some time for ovn-northd and ovn-controller to catch up.
6642 # XXX This should be more systematic.
6646 printf "%02x%02x%02x%02x" "$@"
6649 sed 's/\(00\)\{1,\}$//'
6652 # Send ip packets between foo1 and bar1
6653 # (East-west traffic should flow normally)
6654 src_mac="f00000010203"
6655 dst_mac="000001010203"
6656 src_ip=`ip_to_hex 192 168 1 2`
6657 dst_ip=`ip_to_hex 192 168 2 2`
6658 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6659 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6661 # Send ip packets between foo1 and alice1
6662 src_mac="f00000010203"
6663 dst_mac="000001010203"
6664 src_ip=`ip_to_hex 192 168 1 2`
6665 dst_ip=`ip_to_hex 172 16 1 3`
6666 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6667 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6668 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6670 # Send ip packets between bar1 and bob1
6671 src_mac="f00000010204"
6672 dst_mac="000001010204"
6673 src_ip=`ip_to_hex 192 168 2 2`
6674 dst_ip=`ip_to_hex 172 16 1 4`
6675 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6676 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6677 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6679 # Packet to expect at bar1
6680 src_mac="000001010204"
6681 dst_mac="f00000010204"
6682 src_ip=`ip_to_hex 192 168 1 2`
6683 dst_ip=`ip_to_hex 192 168 2 2`
6684 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6685 echo $expected > expected
6686 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6688 # Packet to Expect at alice1
6689 src_mac="000002010203"
6690 dst_mac="f00000010205"
6691 src_ip=`ip_to_hex 192 168 1 2`
6692 dst_ip=`ip_to_hex 172 16 1 3`
6693 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6694 echo $expected > expected
6695 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6697 # Packet to Expect at bob1
6698 src_mac="000003010203"
6699 dst_mac="f00000010206"
6700 src_ip=`ip_to_hex 192 168 2 2`
6701 dst_ip=`ip_to_hex 172 16 1 4`
6702 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6703 echo $expected > expected
6704 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6706 for sim in hv1 hv2 hv3; do
6708 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6709 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6710 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6714 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6717 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6720 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6723 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6724 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6728 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6729 AT_SKIP_IF([test $HAVE_PYTHON = no])
6732 ovn-nbctl ls-add ls1
6734 ovn-nbctl lsp-add ls1 ls1-lp1 \
6735 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6737 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6739 ovn-nbctl lsp-add ls1 ls1-lp2 \
6740 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6742 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6744 DNS1=`ovn-nbctl create DNS records={}`
6745 DNS2=`ovn-nbctl create DNS records={}`
6747 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6748 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6749 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6751 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6757 ovs-vsctl add-br br-phys
6758 ovn_attach n1 br-phys 192.168.0.1
6759 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6760 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6761 options:tx_pcap=hv1/vif1-tx.pcap \
6762 options:rxq_pcap=hv1/vif1-rx.pcap \
6765 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6766 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6767 options:tx_pcap=hv1/vif2-tx.pcap \
6768 options:rxq_pcap=hv1/vif2-rx.pcap \
6773 as hv1 ovs-vsctl show
6775 echo "*************************"
6777 echo "*************************"
6780 printf "%02x%02x%02x%02x" "$@"
6786 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6787 options:rxq_pcap=dummy-rx.pcap
6788 rm -f ${pcap_file}*.pcap
6789 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6790 options:rxq_pcap=${pcap_file}-rx.pcap
6793 # set_dns_params host_name
6794 # Sets the dns_req_data and dns_resp_data
6803 query_name=03766d31036f766e036f726700
6804 # IPv4 address - 10.0.0.4
6805 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6809 query_name=03766d32036f766e036f726700
6810 # IPv4 address - 10.0.0.6
6811 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6812 # IPv4 address - 20.0.0.4
6813 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6818 query_name=03766d33036f766e036f726700
6819 # IPv4 address - 40.0.0.4
6820 expected_dns_answer=${query_name}00010001${ttl}000428000004
6824 query_name=03766d31036f766e036f726700
6825 # IPv6 address - aef0::4
6827 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6831 query_name=03766d31036f766e036f726700
6834 # IPv4 address - 10.0.0.4
6835 # IPv6 address - aef0::4
6836 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6837 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6838 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6842 query_name=03766d31036f766e036f726700
6843 # IPv6 address - aef0::4
6851 local dns_req_header=010201200001000000000000
6852 local dns_resp_header=010281200001${an_count}00000000
6853 dns_req_data=${dns_req_header}${query_name}${type}0001
6854 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6857 # This shell function sends a DNS request packet
6858 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6860 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6861 local dns_query_data=$7
6862 shift; shift; shift; shift; shift; shift; shift;
6863 # Packet size => IPv4 header (20) + UDP header (8) +
6864 # DNS data (header + query)
6865 ip_len=`expr 28 + ${#dns_query_data} / 2`
6866 udp_len=`expr $ip_len - 20`
6867 ip_len=$(printf "%x" $ip_len)
6868 udp_len=$(printf "%x" $udp_len)
6869 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6870 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6872 request=${request}${dns_query_data}
6874 if test $dns_reply != 0; then
6876 ip_len=`expr 28 + ${#dns_reply} / 2`
6877 udp_len=`expr $ip_len - 20`
6878 ip_len=$(printf "%x" $ip_len)
6879 udp_len=$(printf "%x" $udp_len)
6880 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6881 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6882 echo $reply >> $inport.expected
6885 echo $request >> $outport.expected
6888 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6892 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6893 local dns_query_data=$7
6894 shift; shift; shift; shift; shift; shift; shift;
6895 # Packet size => UDP header (8) +
6896 # DNS data (header + query)
6897 ip_len=`expr 8 + ${#dns_query_data} / 2`
6899 ip_len=$(printf "%x" $ip_len)
6900 udp_len=$(printf "%x" $udp_len)
6901 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
6902 request=${request}9234003500${udp_len}0000
6904 request=${request}${dns_query_data}
6906 if test $dns_reply != 0; then
6908 ip_len=`expr 8 + ${#dns_reply} / 2`
6910 ip_len=$(printf "%x" $ip_len)
6911 udp_len=$(printf "%x" $udp_len)
6912 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
6913 reply=${reply}0035923400${udp_len}0000${dns_reply}
6914 echo $reply >> $inport.expected
6917 echo $request >> $outport.expected
6920 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6923 AT_CAPTURE_FILE([ofctl_monitor0.log])
6924 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6925 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6928 src_ip=`ip_to_hex 10 0 0 4`
6929 dst_ip=`ip_to_hex 10 0 0 1`
6931 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6933 # NXT_RESUMEs should be 1.
6934 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6936 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6937 cat 1.expected | cut -c -48 > expout
6938 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6939 # Skipping the IPv4 checksum.
6940 cat 1.expected | cut -c 53- > expout
6941 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6943 reset_pcap_file hv1-vif1 hv1/vif1
6944 reset_pcap_file hv1-vif2 hv1/vif2
6949 src_ip=`ip_to_hex 10 0 0 6`
6950 dst_ip=`ip_to_hex 10 0 0 1`
6952 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6954 # NXT_RESUMEs should be 2.
6955 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6957 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6958 cat 2.expected | cut -c -48 > expout
6959 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6960 # Skipping the IPv4 checksum.
6961 cat 2.expected | cut -c 53- > expout
6962 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6964 reset_pcap_file hv1-vif1 hv1/vif1
6965 reset_pcap_file hv1-vif2 hv1/vif2
6969 # Clear the query name options for ls1-lp2
6970 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
6973 src_ip=`ip_to_hex 10 0 0 4`
6974 dst_ip=`ip_to_hex 10 0 0 1`
6976 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
6978 # NXT_RESUMEs should be 3.
6979 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6981 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6982 AT_CHECK([cat 1.packets], [0], [])
6984 reset_pcap_file hv1-vif1 hv1/vif1
6985 reset_pcap_file hv1-vif2 hv1/vif2
6989 # Clear the query name for ls1-lp1
6990 # Since ls1 has no query names configued,
6991 # ovn-northd should not add the DNS flows.
6992 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
6995 src_ip=`ip_to_hex 10 0 0 6`
6996 dst_ip=`ip_to_hex 10 0 0 1`
6998 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7000 # NXT_RESUMEs should be 3 only.
7001 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7003 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7004 AT_CHECK([cat 2.packets], [0], [])
7006 reset_pcap_file hv1-vif1 hv1/vif1
7007 reset_pcap_file hv1-vif2 hv1/vif2
7011 # Test IPv6 (AAAA records) using IPv4 packet.
7012 # Add back the DNS options for ls1-lp1.
7013 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7015 set_dns_params vm1_ipv6_only
7016 src_ip=`ip_to_hex 10 0 0 6`
7017 dst_ip=`ip_to_hex 10 0 0 1`
7019 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7021 # NXT_RESUMEs should be 4.
7022 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7024 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7025 cat 2.expected | cut -c -48 > expout
7026 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7027 # Skipping the IPv4 checksum.
7028 cat 2.expected | cut -c 53- > expout
7029 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7031 reset_pcap_file hv1-vif1 hv1/vif1
7032 reset_pcap_file hv1-vif2 hv1/vif2
7036 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7037 set_dns_params vm1_ipv4_v6
7038 src_ip=`ip_to_hex 10 0 0 6`
7039 dst_ip=`ip_to_hex 10 0 0 1`
7041 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7043 # NXT_RESUMEs should be 5.
7044 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7046 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7047 cat 2.expected | cut -c -48 > expout
7048 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7049 # Skipping the IPv4 checksum.
7050 cat 2.expected | cut -c 53- > expout
7051 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7053 reset_pcap_file hv1-vif1 hv1/vif1
7054 reset_pcap_file hv1-vif2 hv1/vif2
7059 set_dns_params vm1_invalid_type
7060 src_ip=`ip_to_hex 10 0 0 6`
7061 dst_ip=`ip_to_hex 10 0 0 1`
7063 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7065 # NXT_RESUMEs should be 6.
7066 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7068 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7069 AT_CHECK([cat 2.packets], [0], [])
7071 reset_pcap_file hv1-vif1 hv1/vif1
7072 reset_pcap_file hv1-vif2 hv1/vif2
7076 # Incomplete DNS packet.
7077 set_dns_params vm1_incomplete
7078 src_ip=`ip_to_hex 10 0 0 6`
7079 dst_ip=`ip_to_hex 10 0 0 1`
7081 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7083 # NXT_RESUMEs should be 7.
7084 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7086 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7087 AT_CHECK([cat 2.packets], [0], [])
7089 reset_pcap_file hv1-vif1 hv1/vif1
7090 reset_pcap_file hv1-vif2 hv1/vif2
7094 # Add one more DNS record to the ls1.
7095 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7098 src_ip=`ip_to_hex 10 0 0 4`
7099 dst_ip=`ip_to_hex 10 0 0 1`
7101 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7103 # NXT_RESUMEs should be 8.
7104 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7106 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7107 cat 1.expected | cut -c -48 > expout
7108 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7109 # Skipping the IPv4 checksum.
7110 cat 1.expected | cut -c 53- > expout
7111 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7113 reset_pcap_file hv1-vif1 hv1/vif1
7114 reset_pcap_file hv1-vif2 hv1/vif2
7118 # Try DNS query over IPv6
7120 src_ip=aef00000000000000000000000000004
7121 dst_ip=aef00000000000000000000000000001
7123 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7125 # NXT_RESUMEs should be 9.
7126 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7128 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7129 # Skipping the UDP checksum.
7130 cat 1.expected | cut -c 1-120,125- > expout
7131 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
7133 reset_pcap_file hv1-vif1 hv1/vif1
7134 reset_pcap_file hv1-vif2 hv1/vif2
7139 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7140 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7141 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7144 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7147 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7150 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7153 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7154 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7157 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7158 AT_SKIP_IF([test $HAVE_PYTHON = no])
7165 ovs-vsctl add-br br-phys
7166 ovn_attach n1 br-phys 192.168.0.1
7167 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7168 set interface hv1-vif1 external-ids:iface-id=foo1 \
7169 options:tx_pcap=hv1/vif1-tx.pcap \
7170 options:rxq_pcap=hv1/vif1-rx.pcap \
7175 ovs-vsctl add-br br-phys
7176 ovn_attach n1 br-phys 192.168.0.2
7180 ovs-vsctl add-br br-phys
7181 ovn_attach n1 br-phys 192.168.0.4
7185 ovs-vsctl add-br br-phys
7186 ovn_attach n1 br-phys 192.168.0.3
7187 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7188 set interface ext1-vif1 external-ids:iface-id=outside1 \
7189 options:tx_pcap=ext1/vif1-tx.pcap \
7190 options:rxq_pcap=ext1/vif1-rx.pcap \
7193 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7194 # packets for ARP resolution (native tunneling doesn't queue packets
7195 # for ARP resolution).
7198 ovn-nbctl create Logical_Router name=R1
7200 ovn-nbctl ls-add foo
7201 ovn-nbctl ls-add alice
7202 ovn-nbctl ls-add outside
7205 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7206 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7207 type=router options:router-port=foo \
7208 -- lsp-set-addresses rp-foo router
7210 # Connect alice to R1 as distributed router gateway port on gw1
7211 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7214 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7217 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7220 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7222 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7223 type=router options:router-port=alice \
7224 -- lsp-set-addresses rp-alice router
7226 # Create logical port foo1 in foo
7227 ovn-nbctl lsp-add foo foo1 \
7228 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7230 # Create logical port outside1 in outside
7231 ovn-nbctl lsp-add outside outside1 \
7232 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7234 # Create localnet port in alice
7235 ovn-nbctl lsp-add alice ln-alice
7236 ovn-nbctl lsp-set-addresses ln-alice unknown
7237 ovn-nbctl lsp-set-type ln-alice localnet
7238 ovn-nbctl lsp-set-options ln-alice network_name=phys
7240 # Create localnet port in outside
7241 ovn-nbctl lsp-add outside ln-outside
7242 ovn-nbctl lsp-set-addresses ln-outside unknown
7243 ovn-nbctl lsp-set-type ln-outside localnet
7244 ovn-nbctl lsp-set-options ln-outside network_name=phys
7246 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7247 # mapping to the external network, is the one generating packets
7248 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7249 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7250 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7252 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7254 # Allow some time for ovn-northd and ovn-controller to catch up.
7255 # XXX This should be more systematic.
7259 printf "%02x%02x%02x%02x" "$@"
7265 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7266 options:rxq_pcap=dummy-rx.pcap
7267 rm -f ${pcap_file}*.pcap
7268 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7269 options:rxq_pcap=${pcap_file}-rx.pcap
7277 # Send ip packet between foo1 and outside1
7278 src_mac="f00000010203" # foo1 mac
7279 dst_mac="000001010203" # rp-foo mac (internal router leg)
7280 src_ip=`ip_to_hex 192 168 1 2`
7281 dst_ip=`ip_to_hex 172 16 1 3`
7282 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7284 # ARP request packet to expect at outside1
7285 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7287 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7289 # Send ARP reply from outside1 back to the router
7290 # XXX: note, we could avoid this if we plug this port into a netns
7291 # and setup the IP address into the port, so the kernel would simply reply
7292 src_mac="000002010203"
7293 reply_mac="f00000010204"
7294 dst_ip=`ip_to_hex 172 16 1 3`
7295 src_ip=`ip_to_hex 172 16 1 1`
7296 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7298 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7300 # Packet to Expect at ext1 chassis, outside1 port
7301 src_mac="000002010203"
7302 dst_mac="f00000010204"
7303 src_ip=`ip_to_hex 192 168 1 2`
7304 dst_ip=`ip_to_hex 172 16 1 3`
7305 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7306 echo $expected > ext1-vif1.expected
7308 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7309 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7310 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7312 # Resend packet from foo1 to outside1
7313 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7317 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7318 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7319 AT_CHECK([grep $expected packets | sort], [0], [expout])
7320 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7321 AT_CHECK([grep $expected packets | sort], [0], [])
7324 test_ip_packet gw1 gw2
7326 ovn-nbctl --timeout=3 --wait=hv \
7327 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7330 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7333 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7335 test_ip_packet gw2 gw1
7337 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7340 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7341 AT_SKIP_IF([test $HAVE_PYTHON = no])
7348 ovs-vsctl add-br br-phys
7349 ovn_attach n1 br-phys 192.168.0.1
7350 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7351 set interface hv1-vif1 external-ids:iface-id=foo1 \
7352 options:tx_pcap=hv1/vif1-tx.pcap \
7353 options:rxq_pcap=hv1/vif1-rx.pcap \
7358 ovs-vsctl add-br br-phys
7359 ovn_attach n1 br-phys 192.168.0.2
7363 ovs-vsctl add-br br-phys
7364 ovn_attach n1 br-phys 192.168.0.4
7368 ovs-vsctl add-br br-phys
7369 ovn_attach n1 br-phys 192.168.0.3
7370 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7371 set interface ext1-vif1 external-ids:iface-id=outside1 \
7372 options:tx_pcap=ext1/vif1-tx.pcap \
7373 options:rxq_pcap=ext1/vif1-rx.pcap \
7376 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7377 # packets for ARP resolution (native tunneling doesn't queue packets
7378 # for ARP resolution).
7381 ovn-nbctl create Logical_Router name=R0
7382 ovn-nbctl create Logical_Router name=R1
7384 ovn-nbctl ls-add foo
7385 ovn-nbctl ls-add join
7386 ovn-nbctl ls-add alice
7387 ovn-nbctl ls-add outside
7390 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7391 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7392 type=router options:router-port=R0-foo \
7393 -- lsp-set-addresses foo-R0 router
7396 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7397 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7398 type=router options:router-port=R0-join \
7399 -- lsp-set-addresses join-R0 router
7402 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7403 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7404 type=router options:router-port=R1-join \
7405 -- lsp-set-addresses join-R1 router
7408 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7409 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7411 # Connect alice to R1 as distributed router gateway port on gw1
7412 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7415 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7418 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7421 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7423 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7424 type=router options:router-port=alice \
7425 -- lsp-set-addresses rp-alice router
7427 # Create logical port foo1 in foo
7428 ovn-nbctl lsp-add foo foo1 \
7429 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7431 # Create logical port outside1 in outside
7432 ovn-nbctl lsp-add outside outside1 \
7433 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7435 # Create localnet port in alice
7436 ovn-nbctl lsp-add alice ln-alice
7437 ovn-nbctl lsp-set-addresses ln-alice unknown
7438 ovn-nbctl lsp-set-type ln-alice localnet
7439 ovn-nbctl lsp-set-options ln-alice network_name=phys
7441 # Create localnet port in outside
7442 ovn-nbctl lsp-add outside ln-outside
7443 ovn-nbctl lsp-set-addresses ln-outside unknown
7444 ovn-nbctl lsp-set-type ln-outside localnet
7445 ovn-nbctl lsp-set-options ln-outside network_name=phys
7447 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7448 # mapping to the external network, is the one generating packets
7449 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7450 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7451 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7453 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7455 # Allow some time for ovn-northd and ovn-controller to catch up.
7456 # XXX This should be more systematic.
7460 printf "%02x%02x%02x%02x" "$@"
7466 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7467 options:rxq_pcap=dummy-rx.pcap
7468 rm -f ${pcap_file}*.pcap
7469 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7470 options:rxq_pcap=${pcap_file}-rx.pcap
7478 # Send ip packet between foo1 and outside1
7479 src_mac="f00000010203" # foo1 mac
7480 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7481 src_ip=`ip_to_hex 192 168 1 2`
7482 dst_ip=`ip_to_hex 172 16 1 3`
7483 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7485 # ARP request packet to expect at outside1
7486 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7488 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7490 # Send ARP reply from outside1 back to the router
7491 # XXX: note, we could avoid this if we plug this port into a netns
7492 # and setup the IP address into the port, so the kernel would simply reply
7493 src_mac="000002010203"
7494 reply_mac="f00000010204"
7495 dst_ip=`ip_to_hex 172 16 1 3`
7496 src_ip=`ip_to_hex 172 16 1 1`
7497 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7499 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7501 # Packet to Expect at ext1 chassis, outside1 port
7502 src_mac="000002010203"
7503 dst_mac="f00000010204"
7504 src_ip=`ip_to_hex 192 168 1 2`
7505 dst_ip=`ip_to_hex 172 16 1 3`
7506 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7507 echo $expected > ext1-vif1.expected
7509 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7510 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7511 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7513 # Resend packet from foo1 to outside1
7514 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7518 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7519 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7520 AT_CHECK([grep $expected packets | sort], [0], [expout])
7521 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7522 AT_CHECK([grep $expected packets | sort], [0], [])
7525 test_ip_packet gw1 gw2
7527 ovn-nbctl --timeout=3 --wait=hv \
7528 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7531 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7534 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7536 test_ip_packet gw2 gw1
7538 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7541 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7542 AT_SKIP_IF([test $HAVE_PYTHON = no])
7546 # One LR R1 that has switches foo (192.168.1.0/24) and
7547 # alice (172.16.1.0/24) connected to it. The logical port
7548 # between R1 and alice has a "redirect-chassis" specified,
7549 # i.e. it is the distributed router gateway port.
7550 # Switch alice also has a localnet port defined.
7551 # An additional switch outside has a localnet port and the
7552 # same subnet as alice (172.16.1.0/24).
7555 # Three hypervisors hv[123].
7556 # hv1 hosts vif foo1.
7557 # hv2 is the "redirect-chassis" that hosts the distributed
7558 # router gateway port.
7559 # hv3 hosts vif outside1.
7560 # In order to show that connectivity works only through hv2,
7561 # an initial round of tests is run without any bridge-mapping
7562 # defined for the localnet on hv2. These tests are expected
7564 # Subsequent tests are run after defining the bridge-mapping
7565 # for the localnet on hv2. These tests are expected to succeed.
7567 # Create three hypervisors and create OVS ports corresponding
7573 ovs-vsctl add-br br-phys
7574 ovn_attach n1 br-phys 192.168.0.1
7575 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7576 set interface hv1-vif1 external-ids:iface-id=foo1 \
7577 options:tx_pcap=hv1/vif1-tx.pcap \
7578 options:rxq_pcap=hv1/vif1-rx.pcap \
7583 ovs-vsctl add-br br-phys
7584 ovn_attach n1 br-phys 192.168.0.2
7588 ovs-vsctl add-br br-phys
7589 ovn_attach n1 br-phys 192.168.0.3
7590 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7591 set interface hv3-vif1 external-ids:iface-id=outside1 \
7592 options:tx_pcap=hv3/vif1-tx.pcap \
7593 options:rxq_pcap=hv3/vif1-rx.pcap \
7596 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7597 # packets for ARP resolution (native tunneling doesn't queue packets
7598 # for ARP resolution).
7601 ovn-nbctl create Logical_Router name=R1
7603 ovn-nbctl ls-add foo
7604 ovn-nbctl ls-add alice
7605 ovn-nbctl ls-add outside
7608 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7609 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7610 type=router options:router-port=foo \
7611 -- lsp-set-addresses rp-foo router
7613 # Connect alice to R1 as distributed router gateway port on hv2
7614 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7615 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7616 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7617 type=router options:router-port=alice \
7618 -- lsp-set-addresses rp-alice router
7620 # Create logical port foo1 in foo
7621 ovn-nbctl lsp-add foo foo1 \
7622 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7624 # Create logical port outside1 in outside
7625 ovn-nbctl lsp-add outside outside1 \
7626 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7628 # Create localnet port in alice
7629 ovn-nbctl lsp-add alice ln-alice
7630 ovn-nbctl lsp-set-addresses ln-alice unknown
7631 ovn-nbctl lsp-set-type ln-alice localnet
7632 ovn-nbctl lsp-set-options ln-alice network_name=phys
7634 # Create localnet port in outside
7635 ovn-nbctl lsp-add outside ln-outside
7636 ovn-nbctl lsp-set-addresses ln-outside unknown
7637 ovn-nbctl lsp-set-type ln-outside localnet
7638 ovn-nbctl lsp-set-options ln-outside network_name=phys
7640 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7641 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7642 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7645 # Allow some time for ovn-northd and ovn-controller to catch up.
7646 # XXX This should be more systematic.
7649 echo "---------NB dump-----"
7651 echo "---------------------"
7652 ovn-nbctl list logical_router
7653 echo "---------------------"
7654 ovn-nbctl list logical_router_port
7655 echo "---------------------"
7657 echo "---------SB dump-----"
7658 ovn-sbctl list datapath_binding
7659 echo "---------------------"
7660 ovn-sbctl list port_binding
7661 echo "---------------------"
7662 ovn-sbctl dump-flows
7663 echo "---------------------"
7664 ovn-sbctl list chassis
7665 ovn-sbctl list encap
7666 echo "------ Gateway_Chassis dump (SBDB) -------"
7667 ovn-sbctl list Gateway_Chassis
7668 echo "------ Port_Binding chassisredirect -------"
7669 ovn-sbctl find Port_Binding type=chassisredirect
7670 echo "-------------------------------------------"
7672 echo "------ hv1 dump ----------"
7673 as hv1 ovs-ofctl show br-int
7674 as hv1 ovs-ofctl dump-flows br-int
7675 echo "------ hv2 dump ----------"
7676 as hv2 ovs-ofctl show br-int
7677 as hv2 ovs-ofctl dump-flows br-int
7678 echo "------ hv3 dump ----------"
7679 as hv3 ovs-ofctl show br-int
7680 as hv3 ovs-ofctl dump-flows br-int
7681 echo "--------------------------"
7684 # Check that redirect mapping is programmed only on hv2
7685 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7687 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7689 # Check that hv1 sends chassisredirect port traffic to hv2
7690 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7692 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7694 # Check that arp reply on distributed gateway port is only programmed on hv2
7695 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7697 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7702 printf "%02x%02x%02x%02x" "$@"
7706 : > hv2-vif1.expected
7707 : > hv3-vif1.expected
7709 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7711 # Causes a packet to be received on INPORT. The packet is an ARP
7712 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7713 # it should be the hardware address of the target to expect to receive in an
7714 # ARP reply; otherwise no reply is expected.
7716 # INPORT is an logical switch port number, e.g. 11 for vif11.
7717 # SHA and REPLY_HA are each 12 hex digits.
7718 # SPA and TPA are each 8 hex digits.
7720 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7721 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7722 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7724 if test X$reply_ha != X; then
7725 # Expect to receive the reply, if any.
7726 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7727 echo $reply >> hv${hv}-vif$inport.expected
7731 rtr_ip=$(ip_to_hex 172 16 1 1)
7732 foo_ip=$(ip_to_hex 192 168 1 2)
7733 outside_ip=$(ip_to_hex 172 16 1 3)
7739 # ARP for router IP address from outside1, no response expected
7740 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7742 # Now check the packets actually received against the ones expected.
7743 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7745 # Send ip packet between foo1 and outside1
7746 src_mac="f00000010203"
7747 dst_mac="000001010203"
7748 src_ip=`ip_to_hex 192 168 1 2`
7749 dst_ip=`ip_to_hex 172 16 1 3`
7750 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7752 # Now check the packets actually received against the ones expected.
7753 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7755 # Now add bridge-mappings on hv2, which should make everything work
7756 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7758 # Allow some time for ovn-northd and ovn-controller to catch up.
7759 # XXX This should be more systematic.
7762 # ARP for router IP address from outside1
7763 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7765 # Now check the packets actually received against the ones expected.
7766 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7768 # Send ip packet between foo1 and outside1
7769 src_mac="f00000010203"
7770 dst_mac="000001010203"
7771 src_ip=`ip_to_hex 192 168 1 2`
7772 dst_ip=`ip_to_hex 172 16 1 3`
7773 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7775 # ARP request packet to expect at outside1
7776 src_mac="000002010203"
7777 src_ip=`ip_to_hex 172 16 1 1`
7778 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7780 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7782 echo $arp_request >> hv3-vif1.expected
7783 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7785 # Send ARP reply from outside1 back to the router
7786 reply_mac="f00000010204"
7787 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7789 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7791 # Allow some time for ovn-northd and ovn-controller to catch up.
7792 # XXX This should be more systematic.
7795 # Packet to Expect at outside1
7796 src_mac="000002010203"
7797 dst_mac="f00000010204"
7798 src_ip=`ip_to_hex 192 168 1 2`
7799 dst_ip=`ip_to_hex 172 16 1 3`
7800 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7802 # Resend packet from foo1 to outside1
7803 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7805 echo "------ hv1 dump ----------"
7806 as hv1 ovs-ofctl show br-int
7807 as hv1 ovs-ofctl dump-flows br-int
7808 echo "------ hv2 dump ----------"
7809 as hv2 ovs-ofctl show br-int
7810 as hv2 ovs-ofctl dump-flows br-int
7811 echo "------ hv3 dump ----------"
7812 as hv3 ovs-ofctl show br-int
7813 as hv3 ovs-ofctl dump-flows br-int
7814 echo "----------------------------"
7816 echo $expected >> hv3-vif1.expected
7817 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7819 #Check ovn-trace over "chassisredirect" port
7820 AT_CAPTURE_FILE([trace])
7822 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7825 echo 'ip.ttl--;' > expout
7826 echo 'eth.src = 00:00:02:01:02:03;' >> expout
7827 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7828 echo 'output("ln-alice");' >> expout
7829 AT_CHECK_UNQUOTED([ovn_trace foo 'inport == "foo1" && eth.src == f0:00:00:01:02:03 && eth.dst == 00:00:01:01:02:03 && ip4.src == 192.168.1.2 && ip4.dst == 172.16.1.3 && ip.ttl == 0xff'], [0], [expout])
7831 # Create logical port alice1 in alice on hv1
7832 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7833 set interface hv1-vif2 external-ids:iface-id=alice1 \
7834 options:tx_pcap=hv1/vif2-tx.pcap \
7835 options:rxq_pcap=hv1/vif2-rx.pcap \
7838 ovn-nbctl lsp-add alice alice1 \
7839 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7841 # Create logical port foo2 in foo on hv2
7842 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7843 set interface hv2-vif1 external-ids:iface-id=foo2 \
7844 options:tx_pcap=hv2/vif1-tx.pcap \
7845 options:rxq_pcap=hv2/vif1-rx.pcap \
7848 ovn-nbctl lsp-add foo foo2 \
7849 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7851 # Allow some time for ovn-northd and ovn-controller to catch up.
7852 # XXX This should be more systematic.
7855 : > hv1-vif2.expected
7857 # Send ip packet between alice1 and foo2
7858 src_mac="f00000010205"
7859 dst_mac="000002010203"
7860 src_ip=`ip_to_hex 172 16 1 4`
7861 dst_ip=`ip_to_hex 192 168 1 3`
7862 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7864 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7866 # Packet to Expect at foo2
7867 src_mac="000001010203"
7868 dst_mac="f00000010206"
7869 src_ip=`ip_to_hex 172 16 1 4`
7870 dst_ip=`ip_to_hex 192 168 1 3`
7871 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7873 echo $expected >> hv2-vif1.expected
7874 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
7876 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
7879 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
7881 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
7884 OVN_CLEANUP([hv1],[hv2],[hv3])
7888 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7889 AT_SKIP_IF([test $HAVE_PYTHON = no])
7891 # Create logical switches
7892 ovn-nbctl ls-add ls0
7893 ovn-nbctl ls-add ls1
7894 # Create distributed router
7895 ovn-nbctl create Logical_Router name=lr0
7896 # Add distributed gateway port to distributed router
7897 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7898 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7899 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7900 type=router options:router-port=lrp0 addresses="router"
7901 # Add router port to ls1
7902 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7903 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7904 type=router options:router-port=lrp1 addresses="router"
7905 # Add logical ports for NAT rules
7906 ovn-nbctl lsp-add ls1 foo1 \
7907 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7908 ovn-nbctl lsp-add ls1 foo2 \
7909 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
7910 # Add nat-addresses option
7911 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7913 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7914 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7915 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.3 10.0.0.3 foo1 f0:00:00:00:00:03])
7916 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.4 10.0.0.4 foo2 f0:00:00:00:00:04])
7921 ovs-vsctl add-br br-phys
7922 ovn_attach n1 br-phys 192.168.0.1
7924 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7925 AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
7929 ovs-vsctl add-br br-phys
7930 ovn_attach n1 br-phys 192.168.0.2
7931 # Initially test with no bridge-mapping on hv2, expect to receive no packets
7935 ovs-vsctl add-br br-phys
7936 ovn_attach n1 br-phys 192.168.0.3
7937 # Initially test with no bridge-mapping on hv3
7939 # Create a localnet port.
7940 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
7941 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7942 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7943 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7945 # Allow some time for ovn-northd and ovn-controller to catch up.
7946 # XXX This should be more systematic.
7949 # Expect no packets when hv2 bridge-mapping is not present
7951 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
7953 # Add bridge-mapping on hv2
7954 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7956 # Wait for packets to be received.
7957 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
7959 sed 's/\(00\)\{1,\}$//'
7961 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7962 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
7963 echo $expected > expout
7964 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
7965 echo $expected >> expout
7966 AT_CHECK([sort packets], [0], [expout])
7969 # Temporarily remove nat-addresses option to avoid race conditions
7970 # due to GARP backoff
7971 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
7976 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7977 options:rxq_pcap=dummy-rx.pcap
7978 rm -f ${pcap_file}*.pcap
7979 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7980 options:rxq_pcap=${pcap_file}-rx.pcap
7983 as hv1 reset_pcap_file snoopvif hv1/snoopvif
7985 # Add OVS ports for foo1 and foo2 on hv3
7986 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7987 set interface hv3-vif1 external-ids:iface-id=foo1 \
7989 ovs-vsctl -- add-port br-int hv3-vif2 -- \
7990 set interface hv3-vif2 external-ids:iface-id=foo2 \
7993 # Add bridge-mapping on hv3
7994 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7996 # Re-add nat-addresses option
7997 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7999 # Wait for packets to be received.
8000 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8002 sed 's/\(00\)\{1,\}$//'
8005 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8006 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8007 echo $expected >> expout
8008 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8009 echo $expected >> expout
8010 AT_CHECK([sort packets], [0], [expout])
8013 OVN_CLEANUP([hv1],[hv2],[hv3])
8017 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8018 AT_KEYWORDS([ovn-nd_ra])
8019 AT_SKIP_IF([test $HAVE_PYTHON = no])
8022 # In this test case we create 1 lswitch with 3 VIF ports attached,
8023 # and a lrouter connected to the lswitch.
8024 # We generate the Router solicitation packet and verify the Router Advertisement
8025 # reply packet from the ovn-controller.
8027 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8028 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8029 # 'slaac' to allow lrp0 send RA for SLAAC mode.
8030 ovn-nbctl ls-add lsw0
8031 ovn-nbctl lr-add lr0
8032 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8033 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8035 -- lsp-add lsw0 lsp0 \
8036 -- set Logical_Switch_Port lsp0 type=router \
8037 options:router-port=lrp0 \
8038 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8042 ovs-vsctl add-br br-phys
8043 ovn_attach n1 br-phys 192.168.0.2
8045 ovn-nbctl lsp-add lsw0 lp1
8046 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8047 ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8049 ovn-nbctl lsp-add lsw0 lp2
8050 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8051 ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8053 ovn-nbctl lsp-add lsw0 lp3
8054 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8055 ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8057 # Add ACL rule for ICMPv6 on lsw0
8058 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8059 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8060 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8061 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8063 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8064 set interface hv1-vif1 external-ids:iface-id=lp1 \
8065 options:tx_pcap=hv1/vif1-tx.pcap \
8066 options:rxq_pcap=hv1/vif1-rx.pcap \
8069 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8070 set interface hv1-vif2 external-ids:iface-id=lp2 \
8071 options:tx_pcap=hv1/vif2-tx.pcap \
8072 options:rxq_pcap=hv1/vif2-rx.pcap \
8075 ovs-vsctl -- add-port br-int hv1-vif3 -- \
8076 set interface hv1-vif3 external-ids:iface-id=lp3 \
8077 options:tx_pcap=hv1/vif3-tx.pcap \
8078 options:rxq_pcap=hv1/vif3-rx.pcap \
8081 # Allow some time for ovn-northd and ovn-controller to catch up.
8082 # XXX This should be more systematic.
8088 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8089 options:rxq_pcap=dummy-rx.pcap
8090 rm -f ${pcap_file}*.pcap
8091 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8092 options:rxq_pcap=${pcap_file}-rx.pcap
8095 # Make sure that ovn-controller has installed the corresponding OF Flow.
8096 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8098 # This shell function sends a Router Solicitation packet.
8099 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8101 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8102 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8106 if test $mtu != 0; then
8108 mtu_opt=05010000${mtu}
8111 if test ${#prefix_opt} != 0; then
8112 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8113 len=`expr $len + ${#prefix_opt} / 2`
8116 len=$(printf "%x" $len)
8117 local lrp_mac=fa163e000001
8118 local lrp_lla=fe80000000000000f8163efffe000001
8119 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8120 echo $reply >> $inport.expected
8122 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8125 AT_CAPTURE_FILE([ofctl_monitor0.log])
8126 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8127 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8129 # MTU is not set and the address mode is set to slaac
8131 default_prefix_option_config=030440c0ffffffffffffffff00000000
8132 src_mac=fa163e000002
8133 src_lla=fe80000000000000f8163efffe000002
8134 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8136 # NXT_RESUME should be 1.
8137 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8139 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8141 cat 1.expected | cut -c -112 > expout
8142 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8144 # Skipping the ICMPv6 checksum.
8145 cat 1.expected | cut -c 117- > expout
8146 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8149 reset_pcap_file hv1-vif1 hv1/vif1
8150 reset_pcap_file hv1-vif2 hv1/vif2
8151 reset_pcap_file hv1-vif3 hv1/vif3
8153 # Set the MTU to 1500
8154 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8156 # Make sure that ovn-controller has installed the corresponding OF Flow.
8157 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8160 default_prefix_option_config=030440c0ffffffffffffffff00000000
8161 src_mac=fa163e000003
8162 src_lla=fe80000000000000f8163efffe000003
8165 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8167 # NXT_RESUME should be 2.
8168 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8170 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8172 cat 2.expected | cut -c -112 > expout
8173 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8175 # Skipping the ICMPv6 checksum.
8176 cat 2.expected | cut -c 117- > expout
8177 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8180 reset_pcap_file hv1-vif1 hv1/vif1
8181 reset_pcap_file hv1-vif2 hv1/vif2
8182 reset_pcap_file hv1-vif3 hv1/vif3
8184 # Set the address mode to dhcpv6_stateful
8185 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8186 # Make sure that ovn-controller has installed the corresponding OF Flow.
8187 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8190 default_prefix_option_config=""
8191 src_mac=fa163e000004
8192 src_lla=fe80000000000000f8163efffe000004
8195 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8197 # NXT_RESUME should be 3.
8198 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8200 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8202 cat 3.expected | cut -c -112 > expout
8203 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8205 # Skipping the ICMPv6 checksum.
8206 cat 3.expected | cut -c 117- > expout
8207 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8210 reset_pcap_file hv1-vif1 hv1/vif1
8211 reset_pcap_file hv1-vif2 hv1/vif2
8212 reset_pcap_file hv1-vif3 hv1/vif3
8214 # Set the address mode to dhcpv6_stateless
8215 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8216 # Make sure that ovn-controller has installed the corresponding OF Flow.
8217 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8220 default_prefix_option_config=030440c0ffffffffffffffff00000000
8221 src_mac=fa163e000002
8222 src_lla=fe80000000000000f8163efffe000002
8225 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8227 # NXT_RESUME should be 4.
8228 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8230 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8232 cat 1.expected | cut -c -112 > expout
8233 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8235 # Skipping the ICMPv6 checksum.
8236 cat 1.expected | cut -c 117- > expout
8237 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8240 reset_pcap_file hv1-vif1 hv1/vif1
8241 reset_pcap_file hv1-vif2 hv1/vif2
8242 reset_pcap_file hv1-vif3 hv1/vif3
8244 # Set the address mode to invalid.
8245 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8246 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8247 OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8250 default_prefix_option_config=""
8251 src_mac=fa163e000002
8252 src_lla=fe80000000000000f8163efffe000002
8255 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8257 # NXT_RESUME should be 4 only.
8258 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8260 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8261 AT_CHECK([cat 1.packets], [0], [])
8266 AT_SETUP([ovn -- /32 router IP address])
8267 AT_SKIP_IF([test $HAVE_PYTHON = no])
8271 # 2 LS 'foo' and 'alice' connected via router R1.
8272 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8273 # nexthop to push traffic to a logical port in switch 'alice'
8277 ovn-nbctl ls-add foo
8278 ovn-nbctl ls-add alice
8281 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8282 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8283 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8285 # Connect alice to R1.
8286 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8287 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8288 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8290 # Create logical port foo1 in foo
8291 ovn-nbctl lsp-add foo foo1 \
8292 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8294 # Create logical port alice1 in alice
8295 ovn-nbctl lsp-add alice alice1 \
8296 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8298 #install default route in R1 to use alice1's IP address as nexthop
8299 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8301 # Create two hypervisor and create OVS ports corresponding to logical ports.
8306 ovs-vsctl add-br br-phys
8307 ovn_attach n1 br-phys 192.168.0.1
8308 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8309 set interface hv1-vif1 external-ids:iface-id=foo1 \
8310 options:tx_pcap=hv1/vif1-tx.pcap \
8311 options:rxq_pcap=hv1/vif1-rx.pcap \
8316 ovs-vsctl add-br br-phys
8317 ovn_attach n1 br-phys 192.168.0.2
8318 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8319 set interface hv2-vif1 external-ids:iface-id=alice1 \
8320 options:tx_pcap=hv2/vif1-tx.pcap \
8321 options:rxq_pcap=hv2/vif1-rx.pcap \
8325 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8326 # packets for ARP resolution (native tunneling doesn't queue packets
8327 # for ARP resolution).
8330 # Allow some time for ovn-northd and ovn-controller to catch up.
8331 # XXX This should be more systematic.
8335 printf "%02x%02x%02x%02x" "$@"
8338 # Send ip packets between foo1 and alice1
8339 src_mac="f00000010203"
8340 dst_mac="000000010203"
8341 src_ip=`ip_to_hex 192 168 1 2`
8342 dst_ip=`ip_to_hex 10 0 0 2`
8343 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8345 # Send the first packet to trigger a ARP response and population of
8346 # mac_bindings table.
8347 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8348 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8350 # Send the second packet to reach the destination.
8351 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8353 # Packet to Expect at 'alice1'
8354 src_mac="000000010204"
8355 dst_mac="f00000010204"
8356 src_ip=`ip_to_hex 192 168 1 2`
8357 dst_ip=`ip_to_hex 10 0 0 2`
8358 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8360 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8362 OVN_CLEANUP([hv1],[hv2])
8366 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8367 AT_SKIP_IF([test $HAVE_PYTHON = no])
8370 ovn-nbctl ls-add ls1
8372 # Add localport to the switch
8373 ovn-nbctl lsp-add ls1 lp01
8374 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8375 ovn-nbctl lsp-set-type lp01 localport
8382 ovs-vsctl add-br br-phys
8383 ovn_attach n1 br-phys 192.168.0.$i
8384 ovs-vsctl add-port br-int vif01 -- \
8385 set Interface vif01 external-ids:iface-id=lp01 \
8386 options:tx_pcap=hv${i}/vif01-tx.pcap \
8387 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8388 ofport-request=${i}0
8390 ovs-vsctl add-port br-int vif${i}1 -- \
8391 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8392 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8393 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8394 ofport-request=${i}1
8396 ovn-nbctl lsp-add ls1 lp${i}1
8397 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8398 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8400 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8403 ovn-nbctl --wait=sb sync
8404 ovn-sbctl dump-flows
8408 # Given the name of a logical port, prints the name of the hypervisor
8409 # on which it is located.
8414 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8416 # This shell function causes a packet to be received on INPORT. The packet's
8417 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8418 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8419 # logical switch port numbers, e.g. 11 for vif11.
8421 # EOUT is the end-to-end output port, that is, where the packet will end up
8422 # after possibly bouncing through one or more localnet ports. LOUT is the
8423 # logical output port, which might be a localnet port, as seen by ovn-trace
8424 # (which doesn't know what localnet ports are connected to and therefore can't
8425 # figure out the end-to-end answer).
8427 # DEFHV is the default hypervisor from where the packet is going to be sent
8428 # if the source port is a localport.
8435 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8438 # First try tracing the packet.
8439 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8440 if test $lout != drop; then
8441 echo "output(\"$lout\");"
8443 AT_CAPTURE_FILE([trace])
8444 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8446 # Then actually send a packet, for an end-to-end test.
8447 local packet=$(echo $dst$src | sed 's/://g')${eth}
8448 hv=`vif_to_hv $inport`
8449 # If hypervisor 0 (localport) use the defhv parameter
8450 if test $hv = hv0; then
8454 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8455 if test $eout != drop; then
8456 echo $packet >> ${eout#lp}.expected
8461 # lp11 and lp21 are on different hypervisors
8462 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8463 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8465 # Both VIFs should be able to reach the localport on their own HV
8466 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8467 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8469 # Packet sent from localport on same hv should reach the vif
8470 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8471 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8473 # Packet sent from localport on different hv should be dropped
8474 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8475 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8477 # Now check the packets actually received against the ones expected.
8480 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8484 OVN_CLEANUP([hv1],[hv2])
8488 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8489 AT_SKIP_IF([test $HAVE_PYTHON = no])
8494 # create gateways with external network connectivity
8499 ovs-vsctl add-br br-phys
8500 ovn_attach n1 br-phys 192.168.0.$i
8501 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8504 ovn-nbctl ls-add inside
8505 ovn-nbctl ls-add outside
8507 # create hypervisors with a vif port each to an internal network
8512 ovs-vsctl add-br br-phys
8513 ovn_attach n1 br-phys 192.168.0.1$i
8514 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8515 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8516 options:tx_pcap=hv$i/vif1-tx.pcap \
8517 options:rxq_pcap=hv$i/vif1-rx.pcap \
8520 ovn-nbctl lsp-add inside inside$i \
8521 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8527 ovn-nbctl create Logical_Router name=R1
8529 # Connect inside to R1
8530 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8531 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8532 type=router options:router-port=inside \
8533 -- lsp-set-addresses rp-inside router
8535 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8536 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8538 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8539 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8540 --id=@gc1 create Gateway_Chassis \
8541 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8542 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8544 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8545 type=router options:router-port=outside \
8546 -- lsp-set-addresses rp-outside router
8548 # Create localnet port in outside
8549 ovn-nbctl lsp-add outside ln-outside
8550 ovn-nbctl lsp-set-addresses ln-outside unknown
8551 ovn-nbctl lsp-set-type ln-outside localnet
8552 ovn-nbctl lsp-set-options ln-outside network_name=phys
8554 # Allow some time for ovn-northd and ovn-controller to catch up.
8555 # XXX This should be more systematic.
8556 ovn-nbctl --wait=hv --timeout=3 sync
8558 echo "---------NB dump-----"
8560 echo "---------------------"
8561 ovn-nbctl list logical_router
8562 echo "---------------------"
8563 ovn-nbctl list logical_router_port
8564 echo "---------------------"
8566 echo "---------SB dump-----"
8567 ovn-sbctl list datapath_binding
8568 echo "---------------------"
8569 ovn-sbctl list port_binding
8570 echo "---------------------"
8571 ovn-sbctl dump-flows
8572 echo "---------------------"
8573 ovn-sbctl list chassis
8574 ovn-sbctl list encap
8575 echo "---------------------"
8576 echo "------ Gateway_Chassis dump (SBDB) -------"
8577 ovn-sbctl list Gateway_Chassis
8578 echo "------ Port_Binding chassisredirect -------"
8579 ovn-sbctl find Port_Binding type=chassisredirect
8580 echo "-------------------------------------------"
8582 for chassis in gw1 gw2 hv1 hv2; do
8584 echo "------ $chassis dump ----------"
8585 ovs-ofctl show br-int
8586 ovs-ofctl dump-flows br-int
8587 echo "--------------------------"
8589 function bfd_dump() {
8590 for chassis in gw1 gw2 hv1 hv2; do
8592 echo "------ $chassis dump (BFD)----"
8593 echo "BFD (from $chassis):"
8594 # dump BFD config and status to the other chassis
8595 for chassis2 in gw1 gw2 hv1 hv2; do
8596 if [[ "$chassis" != "$chassis2" ]]; then
8597 echo " -> $chassis2:"
8598 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8601 echo "--------------------------"
8607 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8608 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8609 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8610 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8612 echo $hv1_gw1_ofport
8613 echo $hv1_gw2_ofport
8614 echo $hv2_gw1_ofport
8615 echo $hv2_gw2_ofport
8618 as hv1 ovs-ofctl dump-flows br-int table=32
8621 as hv2 ovs-ofctl dump-flows br-int table=32
8623 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8624 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8626 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
8629 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
8632 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8634 # make sure that flows for handling the outside router port reside on gw1
8635 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8637 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8640 # make sure ARP responder flows for outside router port reside on gw1 too
8641 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8643 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8648 # check that the chassis redirect port has been claimed by the gw1 chassis
8649 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8654 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8656 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8657 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8658 --id=@gc1 create Gateway_Chassis \
8659 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8660 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8663 # XXX: Let the change propagate down to the ovn-controllers
8664 ovn-nbctl --wait=hv --timeout=3 sync
8666 # we make sure that the hypervisors noticed, and inverted the slave ports
8667 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
8670 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
8673 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8674 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8678 # check BFD enablement on tunnel ports from gw1 #########
8680 for chassis in gw2 hv1 hv2; do
8681 echo "checking gw1 -> $chassis"
8682 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8688 # check BFD enablement on tunnel ports from gw2 ##########
8690 for chassis in gw1 hv1 hv2; do
8691 echo "checking gw2 -> $chassis"
8692 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8697 # check BFD enablement on tunnel ports from hv1 ###########
8699 for chassis in gw1 gw2; do
8700 echo "checking hv1 -> $chassis"
8701 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8705 # make sure BFD is not enabled to hv2, we don't need it
8706 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8711 # check BFD enablement on tunnel ports from hv2 ##########
8713 for chassis in gw1 gw2; do
8714 echo "checking hv2 -> $chassis"
8715 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8719 # make sure BFD is not enabled to hv1, we don't need it
8720 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8724 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8726 # make sure that flows for handling the outside router port reside on gw2 now
8727 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8729 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8732 # disconnect GW2 from the network, GW1 should take over
8734 port=${sandbox}_br-phys
8735 as main ovs-vsctl del-port n1 $port
8740 # make sure that flows for handling the outside router port reside on gw2 now
8741 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8743 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8746 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8747 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8751 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8755 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8756 AT_SKIP_IF([test $HAVE_PYTHON = no])
8758 ovn-nbctl ls-add ls0
8759 ovn-nbctl ls-add ls1
8760 ovn-nbctl create Logical_Router name=lr0
8761 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8763 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8764 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8765 --id=@gc1 create Gateway_Chassis \
8766 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8767 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8769 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8770 type=router options:router-port=lrp0 addresses="router"
8771 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8772 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8773 type=router options:router-port=lrp1 addresses="router"
8776 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8781 ovs-vsctl add-br br-phys
8782 ovn_attach n1 br-phys 192.168.0.1
8783 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8784 AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
8788 ovs-vsctl add-br br-phys
8789 ovn_attach n1 br-phys 192.168.0.2
8790 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8794 ovs-vsctl add-br br-phys
8795 ovn_attach n1 br-phys 192.168.0.3
8796 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8798 # Create a localnet port.
8799 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8800 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8801 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8802 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8804 # wait for earlier changes to take effect
8805 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8810 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8811 options:rxq_pcap=dummy-rx.pcap
8812 rm -f ${pcap_file}*.pcap
8813 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8814 options:rxq_pcap=${pcap_file}-rx.pcap
8817 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8818 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8819 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8820 # add nat-addresses option
8821 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8823 # Wait for packets to be received through hv2.
8824 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8826 sed 's/\(00\)\{1,\}$//'
8829 only_broadcast_from_lrp1() {
8830 grep "fffffffffffff00000000001"
8833 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
8836 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
8837 echo "packets on hv1-snoopvif:"
8839 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
8840 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8841 echo "packets on hv2 br-phys tx"
8843 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
8844 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8845 echo "packets on hv3 br-phys tx"
8847 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8850 # at this point, we invert the priority of the gw chassis between hv2 and hv3
8852 ovn-nbctl --wait=hv \
8853 --id=@gc0 create Gateway_Chassis \
8854 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8855 --id=@gc1 create Gateway_Chassis \
8856 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8857 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8860 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8861 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8862 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8864 # Wait for packets to be received.
8865 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8867 sed 's/\(00\)\{1,\}$//'
8870 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8871 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8872 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8873 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8874 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8875 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8877 # change localnet port tag.
8878 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8880 # wait for earlier changes to take effect
8881 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8883 # update nat-addresses option
8884 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0
8885 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8887 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8888 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8889 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8891 # Wait for packets to be received.
8892 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8894 sed 's/\(00\)\{1,\}$//'
8897 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
8900 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8901 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8902 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8903 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8904 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8905 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8907 OVN_CLEANUP([hv1],[hv2],[hv3])
8911 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8912 AT_SKIP_IF([test $HAVE_PYTHON = no])
8917 # create two gateways with external network connectivity
8921 ovs-vsctl add-br br-phys
8922 ovn_attach n1 br-phys 192.168.0.$i
8923 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8926 ovn-nbctl ls-add inside
8927 ovn-nbctl ls-add outside
8929 # create one hypervisors with a vif port the internal network
8932 ovs-vsctl add-br br-phys
8933 ovn_attach n1 br-phys 192.168.0.11
8934 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8935 set interface hv1-vif1 external-ids:iface-id=inside1 \
8936 options:tx_pcap=hv1/vif1-tx.pcap \
8937 options:rxq_pcap=hv1/vif1-rx.pcap \
8940 ovn-nbctl lsp-add inside inside1 \
8941 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
8946 ovn-nbctl create Logical_Router name=R1
8948 # Connect inside to R1
8949 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8950 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8951 type=router options:router-port=inside \
8952 -- lsp-set-addresses rp-inside router
8954 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8955 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8957 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8958 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8959 --id=@gc1 create Gateway_Chassis \
8960 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8961 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8963 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8964 type=router options:router-port=outside \
8965 -- lsp-set-addresses rp-outside router
8967 # Create localnet port in outside
8968 ovn-nbctl lsp-add outside ln-outside
8969 ovn-nbctl lsp-set-addresses ln-outside unknown
8970 ovn-nbctl lsp-set-type ln-outside localnet
8971 ovn-nbctl lsp-set-options ln-outside network_name=phys
8973 # Allow some time for ovn-northd and ovn-controller to catch up.
8974 ovn-nbctl --wait=hv --timeout=3 sync
8976 # currently when ovn-controller is restarted, the old entry is deleted
8977 # and a new one is created, which leaves the Gateway_Chassis with
8978 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
8979 # doesn't have the same effect because "name" is conserved, and the
8980 # Chassis entry is not replaced.
8982 > gw1/ovn-controller.log
8984 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8985 ovn-sbctl destroy Chassis $gw2_chassis
8987 # Ensure ovn-controller has processed latest sbdb update
8988 # ovn-nbctl --wait=hv sync
8990 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
8992 OVN_CLEANUP([gw1],[gw2],[hv1])
8996 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
8997 AT_KEYWORDS([ovn-nd_ns for unknown mac])
8998 AT_SKIP_IF([test $HAVE_PYTHON = no])
9001 ovn-nbctl ls-add sw0_ip6
9002 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9003 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9004 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9006 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9007 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9009 ovn-nbctl lr-add lr0_ip6
9010 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
9011 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9012 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9013 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9014 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9015 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9017 ovn-nbctl ls-add public
9018 ovn-nbctl lsp-add public ln-public
9019 ovn-nbctl lsp-set-addresses ln-public unknown
9020 ovn-nbctl lsp-set-type ln-public localnet
9021 ovn-nbctl lsp-set-options ln-public network_name=phys
9023 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
9024 2001:db8:1:0:200:02ff:fe01:0204/64 \
9025 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9028 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9029 rp-ip6_public type=router options:router-port=ip6_public \
9030 -- lsp-set-addresses rp-ip6_public router
9035 ovs-vsctl add-br br-phys
9036 ovn_attach n1 br-phys 192.168.0.2
9038 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9039 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9040 options:tx_pcap=hv1/vif1-tx.pcap \
9041 options:rxq_pcap=hv1/vif1-rx.pcap \
9043 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9045 # Allow some time for ovn-northd and ovn-controller to catch up.
9046 # XXX This should be more systematic.
9050 sed 's/\(00\)\{1,\}$//'
9053 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9054 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
9055 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9056 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9057 # This function sends ipv6 packet
9059 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9060 dst_ip=20010db800010000020002fffe010205
9062 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9063 packet=${packet}8000000000000000
9064 shift; shift; shift; shift
9066 dst_mac=3333ff010205
9067 src_mac=000002010204
9068 mcast_node_ip=ff0200000000000000000001ff010205
9069 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9070 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9071 expected_packet=${expected_packet}0101${src_mac}
9073 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9074 echo $expected_packet >> ipv6_ns.expected
9077 src_mac=506400000002
9078 dst_mac=00000000af01
9079 src_ip=aef0000000000000526400fffe000002
9080 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9081 # should be received by the ports attached to br-phys.
9082 test_ipv6 1 $src_mac $dst_mac $src_ip 2
9084 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9085 trim_zeros > 1.packets
9086 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9087 trim_zeros > 2.packets
9089 cat ipv6_ns.expected | cut -c -112 > expout
9090 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9091 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9093 # Skipping the ICMPv6 checksum
9094 cat ipv6_ns.expected | cut -c 117- > expout
9095 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9096 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9102 AT_SETUP([ovn -- options:requested-chassis for logical port])
9107 ovn-nbctl ls-add ls0
9108 ovn-nbctl lsp-add ls0 lsp0
9110 # create two hypervisors, each with one vif port
9113 ovs-vsctl add-br br-phys
9114 ovn_attach n1 br-phys 192.168.0.11
9115 ovs-vsctl -- add-port br-int hv1-vif0
9119 ovs-vsctl add-br br-phys
9120 ovn_attach n1 br-phys 192.168.0.12
9121 ovs-vsctl -- add-port br-int hv2-vif0
9123 # Allow only chassis hv1 to bind logical port lsp0.
9124 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9126 # Allow some time for ovn-northd and ovn-controller to catch up.
9127 ovn-nbctl --wait=hv --timeout=3 sync
9129 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9130 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9131 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9133 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9134 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9136 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9138 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9139 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9141 # (2) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9142 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9144 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9146 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9147 AT_CHECK([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv1_uuid"], [0], [])
9149 # (3) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9150 # the requested chassis for lsp0 is changed from hv1 to hv2.
9151 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9153 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9154 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9155 OVS_WAIT_UNTIL([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv2_uuid"])
9157 OVN_CLEANUP([hv1],[hv2])
9161 AT_SETUP([ovn -- options:requested-chassis with hostname])
9165 ovn-nbctl ls-add ls0
9166 ovn-nbctl lsp-add ls0 lsp0
9171 ovs-vsctl add-br br-phys
9172 ovn_attach n1 br-phys 192.168.0.11
9173 ovs-vsctl -- add-port br-int hv1-vif0
9175 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9176 echo "hv1_hostname=${hv1_hostname}"
9177 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9178 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9180 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9181 echo "hv1_uuid=${hv1_uuid}"
9182 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9183 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9185 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9186 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9187 ovn-nbctl --wait=hv --timeout=3 sync
9188 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9194 AT_SETUP([ovn -- IPv6 periodic RA])
9197 # This test sets up two hypervisors.
9198 # hv1 and hv2 run ovn-controllers, and
9199 # each has a VIF connected to the same
9200 # logical switch in OVN. The logical
9201 # switch is connected to a logical
9202 # router port that is configured to send
9203 # periodic router advertisements.
9205 # The reason for having two ovn-controller
9206 # hypervisors is to ensure that the
9207 # periodic RAs being sent by each ovn-controller
9208 # are kept to their local hypervisors. If the
9209 # packets are not kept local, then each port
9210 # will receive too many RAs.
9216 ovs-vsctl add-br br-phys
9217 ovn_attach n1 br-phys 192.168.0.2
9219 ovs-vsctl add-br br-phys
9220 ovn_attach n1 br-phys 192.168.0.3
9223 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0::1/64
9226 ovn-nbctl lsp-add sw sw-ro
9227 ovn-nbctl lsp-set-type sw-ro router
9228 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9229 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9230 ovn-nbctl lsp-add sw sw-p1
9231 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9232 ovn-nbctl lsp-add sw sw-p2
9233 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9235 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9236 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9237 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9238 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9240 for i in hv1 hv2 ; do
9242 ovs-vsctl -- add-port br-int $i-vif1 -- \
9243 set interface $i-vif1 external-ids:iface-id=sw-p1 \
9244 options:tx_pcap=$i/vif1-tx.pcap \
9245 options:rxq_pcap=$i/vif1-rx.pcap \
9249 # Allow time for ovn-northd and ovn-controller to catch up
9255 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9256 options:rxq_pcap=dummy-rx.pcap
9257 rm -f ${pcap_file}*.pcap
9258 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9259 options:rxq_pcap=${pcap_file}-rx.pcap
9263 construct_expected_ra() {
9264 local src_mac=000000000001
9265 local dst_mac=333300000001
9266 local src_addr=fe80000000000000020000fffe000001
9267 local dst_addr=ff020000000000000000000000000001
9271 local ra_prefix_la=$3
9273 local slla=0101${src_mac}
9275 if test $mtu != 0; then
9276 mtu_opt=05010000${mtu}
9281 while [[ $# -gt 0 ]] ; do
9284 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9288 local ra=ff${ra_mo}00000000000000000000${slla}${mtu_opt}${prefix}
9289 local icmp=8600XXXX${ra}
9291 local ip_len=$(expr ${#icmp} / 2)
9292 ip_len=$(printf "%0.4x" ${ip_len})
9294 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9295 local eth=${dst_mac}${src_mac}86dd${ip}
9297 echo $packet >> expected
9301 construct_expected_ra $@
9303 for i in hv1 hv2 ; do
9304 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9306 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9308 cat expected | cut -c -112 > expout
9309 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9311 # Skip ICMPv6 checksum.
9312 cat expected | cut -c 117- > expout
9313 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9316 as $i reset_pcap_file $i-vif1 $i/vif1
9322 # Baseline test with no MTU
9323 ra_test 0 00 c0 40 aef00000000000000000000000000000
9325 # Now make sure an MTU option makes it
9326 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9327 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9329 # Now test for multiple network prefixes
9330 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9331 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9333 # Test a different address mode now
9334 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9335 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9337 # And the other address mode
9338 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9339 ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9341 OVN_CLEANUP([hv1],[hv2])