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 -- composition])
181 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
184 AT_SETUP([ovn -- expression parser])
185 dnl For lines without =>, input and expected output are identical.
186 dnl For lines with =>, input precedes => and expected output follows =>.
187 AT_DATA([test-cases.txt], [[
189 eth.type==0x800 => eth.type == 0x800
190 eth.type[0..15] == 0x800 => eth.type == 0x800
193 vlan.present == 1 => vlan.present
194 !(vlan.present == 0) => vlan.present
195 !(vlan.present != 1) => vlan.present
197 vlan.present == 0 => !vlan.present
198 vlan.present != 1 => !vlan.present
199 !(vlan.present == 1) => !vlan.present
200 !(vlan.present != 0) => !vlan.present
203 eth.dst[0] == 1 => eth.dst[0]
204 eth.dst[0] != 0 => eth.dst[0]
205 !(eth.dst[0] == 0) => eth.dst[0]
206 !(eth.dst[0] != 1) => eth.dst[0]
209 eth.dst[0] == 0 => !eth.dst[0]
210 eth.dst[0] != 1 => !eth.dst[0]
211 !(eth.dst[0] == 1) => !eth.dst[0]
212 !(eth.dst[0] != 0) => !eth.dst[0]
214 vlan.tci[12..15] == 0x3
215 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216 vlan.tci[12..15] != 0x3
217 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
219 !vlan.pcp => vlan.pcp == 0
220 !(vlan.pcp) => vlan.pcp == 0
227 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
228 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
229 !(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230 !(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232 !(vlan.pcp > 0x4) => vlan.pcp <= 0x4
233 0x4 == vlan.pcp => vlan.pcp == 0x4
234 0x4 != vlan.pcp => vlan.pcp != 0x4
235 0x4 < vlan.pcp => vlan.pcp > 0x4
236 0x4 <= vlan.pcp => vlan.pcp >= 0x4
237 0x4 > vlan.pcp => vlan.pcp < 0x4
238 0x4 >= vlan.pcp => vlan.pcp <= 0x4
239 !(0x4 != vlan.pcp) => vlan.pcp == 0x4
240 !(0x4 == vlan.pcp) => vlan.pcp != 0x4
241 !(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242 !(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243 !(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244 !(0x4 < vlan.pcp) => vlan.pcp <= 0x4
246 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
247 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
248 1 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
249 1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
250 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
251 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
252 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
253 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
254 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257 !(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
265 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
268 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
271 vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273 vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
275 ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276 ip6.src == ::1 => ip6.src == 0x1
278 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280 ip6.src == ::1 => ip6.src == 0x1
288 !(inport != "eth0") => inport == "eth0"
290 ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291 inport == 1 => String field inport is not compatible with integer constant.
292 ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
294 ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295 eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296 vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
298 inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299 !(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300 eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301 !(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
302 inport = "eth0" => Syntax error at `=' expecting relational operator.
304 123 == 123 => Syntax error at `123' expecting field name.
306 $name => Syntax error at `$name' expecting address set name.
307 @name => Syntax error at `@name' expecting port group name.
309 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
312 inport[1] == 1 => Cannot select subfield of string field inport.
314 eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315 eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316 eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
318 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
320 eth.type[5..1] => Invalid bit range 5 to 1.
322 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
324 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
326 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
328 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
330 123 => Syntax error at end of input expecting relational operator.
332 123 x => Syntax error at `x' expecting relational operator.
334 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
336 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
338 (1 x) => Syntax error at `x' expecting `)'.
340 !0x800 != eth.type => Missing parentheses around operand of !.
342 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
344 eth.dst == {} => Syntax error at `}' expecting constant.
346 eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
348 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
350 1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
352 eth.dst[40] x => Syntax error at `x' expecting end of input.
354 ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355 eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
357 sed 's/ =>.*//' test-cases.txt > input.txt
358 sed 's/.* => //' test-cases.txt > expout
359 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
362 AT_SETUP([ovn -- expression annotation])
363 dnl Input precedes =>, expected output follows =>.
364 dnl Empty lines and lines starting with # are ignored.
365 AT_DATA([test-cases.txt], [[
366 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
367 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
368 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
369 ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
370 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
372 # Nested expressions over a single symbol should be annotated with symbol's
373 # prerequisites only once, at the top level.
374 tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
376 ip => eth.type == 0x800 || eth.type == 0x86dd
377 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
378 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
379 ip > 0 => Only == and != operators may be used with nominal field ip.
380 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
381 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
383 vlan.present => vlan.tci[12]
384 !vlan.present => !vlan.tci[12]
386 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
387 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
388 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
390 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
391 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
392 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
394 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
395 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
396 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'.
397 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'.
399 sed 's/ =>.*//' test-cases.txt > input.txt
400 sed 's/.* => //' test-cases.txt > expout
401 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
404 AT_SETUP([ovn -- 1-term expression conversion])
405 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
406 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
410 AT_SETUP([ovn -- 2-term expression conversion])
411 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
412 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
416 AT_SETUP([ovn -- 3-term expression conversion])
417 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
418 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
422 AT_SETUP([ovn -- 3-term numeric expression simplification])
423 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
424 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
428 AT_SETUP([ovn -- 4-term string expression simplification])
429 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
430 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
434 AT_SETUP([ovn -- 3-term mixed expression simplification])
435 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
436 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
440 AT_SETUP([ovn -- simplification special cases])
442 echo "$1" | ovstest test-ovn simplify-expr
444 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
446 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
448 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
449 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
451 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
452 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
454 AT_CHECK([simplify 'tcp.dst > 0'], [0],
455 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
457 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
458 [[(!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)
462 AT_SETUP([ovn -- is_chassis_resident simplification])
464 echo "$1" | ovstest test-ovn simplify-expr
466 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
468 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
470 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
472 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
476 AT_SETUP([ovn -- 4-term numeric expression normalization])
477 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
478 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
482 AT_SETUP([ovn -- 4-term string expression normalization])
483 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
484 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
488 AT_SETUP([ovn -- 4-term mixed expression normalization])
489 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
490 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
494 AT_SETUP([ovn -- 5-term numeric expression normalization])
495 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
500 AT_SETUP([ovn -- 5-term string expression normalization])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
506 AT_SETUP([ovn -- 5-term mixed expression normalization])
507 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
508 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
512 AT_SETUP([ovn -- 4-term numeric expressions to flows])
513 AT_KEYWORDS([expression])
514 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
515 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
519 AT_SETUP([ovn -- 4-term string expressions to flows])
520 AT_KEYWORDS([expression])
521 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
522 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
526 AT_SETUP([ovn -- 4-term mixed expressions to flows])
527 AT_KEYWORDS([expression])
528 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
529 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
533 AT_SETUP([ovn -- 3-term numeric expressions to flows])
534 AT_KEYWORDS([expression])
535 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
536 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
540 AT_SETUP([ovn -- converting expressions to flows -- string fields])
541 AT_KEYWORDS([expression])
543 echo "$1" | ovstest test-ovn expr-to-flows | sort
545 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
547 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
549 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
551 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
555 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
559 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
561 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
566 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
572 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
577 AT_SETUP([ovn -- converting expressions to flows -- address sets])
578 AT_KEYWORDS([expression])
580 echo "$1" | ovstest test-ovn expr-to-flows | sort
582 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
587 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
592 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
598 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
605 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
610 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
616 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
617 dl_src=00:00:00:00:00:01
618 dl_src=00:00:00:00:00:02
619 dl_src=00:00:00:00:00:03
621 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
622 dl_src=00:00:00:00:00:01
623 dl_src=00:00:00:00:00:02
624 dl_src=00:00:00:00:00:03
626 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
627 dl_src=00:00:00:00:00:01
628 dl_src=00:00:00:00:00:02
629 dl_src=00:00:00:00:00:03
630 dl_src=ba:be:be:ef:de:ad
632 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
635 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
638 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
641 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
644 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
645 ip,nw_src=0.0.0.0/1.0.0.0
646 ip,nw_src=128.0.0.0/1
647 ip,nw_src=16.0.0.0/16.0.0.0
648 ip,nw_src=2.0.0.0/2.0.0.0
649 ip,nw_src=32.0.0.0/32.0.0.0
650 ip,nw_src=4.0.0.0/4.0.0.0
651 ip,nw_src=64.0.0.0/64.0.0.0
652 ip,nw_src=8.0.0.0/8.0.0.0
654 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
655 ip,nw_src=0.0.0.0/1.0.0.0
656 ip,nw_src=128.0.0.0/1
657 ip,nw_src=16.0.0.0/16.0.0.0
658 ip,nw_src=2.0.0.0/2.0.0.0
659 ip,nw_src=32.0.0.0/32.0.0.0
660 ip,nw_src=4.0.0.0/4.0.0.0
661 ip,nw_src=64.0.0.0/64.0.0.0
662 ip,nw_src=8.0.0.0/8.0.0.0
666 AT_SETUP([ovn -- converting expressions to flows -- port groups])
667 AT_KEYWORDS([expression])
669 echo "$1" | ovstest test-ovn expr-to-flows | sort
671 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
676 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
679 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
684 AT_SETUP([ovn -- converting expressions to flows -- conjunction])
685 AT_KEYWORDS([conjunction])
687 echo "$1" | ovstest test-ovn expr-to-flows | sort
690 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
691 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
692 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
694 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
695 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
696 ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
697 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
698 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
699 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
702 lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
703 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
704 ct_state=+est+trk,ct_label=0x1/0x1,ip
705 ct_state=+est+trk,ct_label=0x1/0x1,ipv6
707 ct_state=-est+trk,ipv6
710 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
711 ip4.dst == {20.0.0.1, 20.0.0.2}"
712 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
714 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
715 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
716 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
717 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
718 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
721 lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
722 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
723 tcp.dst >= 1000 && tcp.dst <= 1010"
725 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
727 tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
728 tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
729 tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
730 tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
731 tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
732 tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
733 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
734 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
735 tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
736 tcp,tp_dst=1000: conjunction(1, 2/3)
737 tcp,tp_dst=1001: conjunction(1, 2/3)
738 tcp,tp_dst=1010: conjunction(1, 2/3)
741 lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
742 ((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
743 tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
744 || ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
746 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
748 ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
749 ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
750 ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
751 ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
752 ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
753 ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
754 tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
755 tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
756 tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
757 tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
758 tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
759 tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
760 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
761 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
762 tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
763 tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
764 tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
765 tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
766 tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
767 tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
768 tcp,tp_dst=1000: conjunction(1, 2/4)
769 tcp,tp_dst=1001: conjunction(1, 2/4)
770 tcp,tp_dst=2000: conjunction(1, 2/4)
771 tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
772 tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
773 tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
774 tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
775 tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
776 tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
777 tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
778 tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
779 tcp,tp_src=1000: conjunction(1, 3/4)
780 tcp,tp_src=1001: conjunction(1, 3/4)
781 tcp,tp_src=2000: conjunction(1, 3/4)
785 AT_SETUP([ovn -- action parsing])
786 dnl Unindented text is input (a set of OVN logical actions).
787 dnl Indented text is expected output.
788 AT_DATA([test-cases.txt],
793 Syntax error at `next' expecting end of input.
795 Syntax error at `drop' expecting action.
799 encodes as resubmit(,64)
803 encodes as resubmit(,19)
806 encodes as resubmit(,19)
808 encodes as resubmit(,8)
810 encodes as resubmit(,31)
813 Syntax error at `)' expecting "pipeline" or "table".
815 Syntax error at `;' expecting `)'.
817 "next" action cannot advance beyond table 23.
821 encodes as resubmit(,19)
822 next(pipeline=ingress);
824 encodes as resubmit(,19)
825 next(table=11, pipeline=ingress);
827 encodes as resubmit(,19)
828 next(pipeline=ingress, table=11);
830 encodes as resubmit(,19)
832 next(pipeline=egress);
833 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
837 encodes as resubmit(,18)
839 # Loading a constant value.
841 formats as tcp.dst = 80;
842 encodes as set_field:80->tcp_dst
843 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
845 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
847 encodes as set_field:0x4000/0xe000->vlan_tci
848 has prereqs vlan.tci[12]
849 vlan.tci[13..15] = 2;
850 encodes as set_field:0x4000/0xe000->vlan_tci
852 encodes as set_field:0->reg14
854 formats as ip.ttl = 4;
855 encodes as set_field:4->nw_ttl
856 has prereqs eth.type == 0x800 || eth.type == 0x86dd
857 outport="eth0"; next; outport="LOCAL"; next;
858 formats as outport = "eth0"; next; outport = "LOCAL"; next;
859 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
862 Cannot select subfield of string field inport.
864 Cannot select subfield of nominal field ip.proto.
866 Syntax error at `==' expecting `=' or `<->'.
868 Predicate symbol ip used where lvalue required.
870 Field ip.proto is not modifiable.
872 Syntax error at `{' expecting constant.
874 Syntax error at `{' expecting constant.
876 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
878 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'.
880 Predicate symbol vlan.present used where lvalue required.
882 # Moving one field into another.
884 formats as reg0 = reg1;
885 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
886 vlan.pcp = reg0[0..2];
887 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
888 has prereqs vlan.tci[12]
889 reg0[10] = vlan.pcp[1];
890 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
891 has prereqs vlan.tci[12]
893 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
895 reg0[0] = vlan.present;
896 Predicate symbol vlan.present used where lvalue required.
898 Can't assign 11-bit value to 32-bit destination.
900 Can't assign integer field (reg0) to string field (inport).
902 String fields inport and big_string are incompatible for assignment.
903 ip.proto = reg0[0..7];
904 Field ip.proto is not modifiable.
908 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]
909 vlan.pcp <-> reg0[0..2];
910 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]
911 has prereqs vlan.tci[12]
912 reg0[10] <-> vlan.pcp[1];
913 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
914 has prereqs vlan.tci[12]
916 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
918 reg0[0] <-> vlan.present;
919 Predicate symbol vlan.present used where lvalue required.
920 reg0 <-> reg1[0..10];
921 Can't exchange 32-bit field with 11-bit field.
923 Can't exchange string field (inport) with integer field (reg0).
924 inport <-> big_string;
925 String fields inport and big_string are incompatible for exchange.
926 ip.proto <-> reg0[0..7];
927 Field ip.proto is not modifiable.
928 reg0[0..7] <-> ip.proto;
929 Field ip.proto is not modifiable.
936 Syntax error at end of input expecting `--'.
940 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
946 ct_lb(192.168.1.2:80, 192.168.1.3:80);
949 ct_lb(192.168.1.2, 192.168.1.3, );
950 formats as ct_lb(192.168.1.2, 192.168.1.3);
953 ct_lb(fd0f::2, fd0f::3, );
954 formats as ct_lb(fd0f::2, fd0f::3);
959 Syntax error at `)' expecting port number.
960 ct_lb(192.168.1.2:123456);
961 Syntax error at `123456' expecting port number.
963 Syntax error at `foo' expecting IP address.
964 ct_lb([192.168.1.2]);
965 Syntax error at `192.168.1.2' expecting IPv6 address.
969 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
974 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
977 formats as ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
980 ct_commit(ct_mark=1);
981 formats as ct_commit(ct_mark=0x1);
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
984 ct_commit(ct_mark=1/1);
985 formats as ct_commit(ct_mark=0x1/0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
988 ct_commit(ct_label=1);
989 formats as ct_commit(ct_label=0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
992 ct_commit(ct_label=1/1);
993 formats as ct_commit(ct_label=0x1/0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
996 ct_commit(ct_mark=1, ct_label=2);
997 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
1001 ct_commit(ct_label=0x01020304050607080910111213141516);
1002 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1003 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1005 ct_commit(ct_label=0x181716151413121110090807060504030201);
1006 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1009 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1010 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1012 ct_commit(ct_label=18446744073709551615);
1013 formats as ct_commit(ct_label=0xffffffffffffffff);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1016 ct_commit(ct_label=18446744073709551616);
1017 Decimal constants must be less than 2**64.
1021 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
1023 ct_dnat(192.168.1.2);
1024 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
1027 ct_dnat(192.168.1.2, 192.168.1.3);
1028 Syntax error at `,' expecting `)'.
1030 Syntax error at `foo' expecting IPv4 address.
1032 Syntax error at `foo' expecting IPv4 address.
1034 Syntax error at `)' expecting IPv4 address.
1038 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
1040 ct_snat(192.168.1.2);
1041 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
1044 ct_snat(192.168.1.2, 192.168.1.3);
1045 Syntax error at `,' expecting `)'.
1047 Syntax error at `foo' expecting IPv4 address.
1049 Syntax error at `foo' expecting IPv4 address.
1051 Syntax error at `)' expecting IPv4 address.
1058 clone { ip4.dst = 255.255.255.255; output; }; next;
1059 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
1060 has prereqs eth.type == 0x800
1063 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1064 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)
1067 formats as arp { drop; };
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1072 get_arp(outport, ip4.dst);
1073 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[]
1074 has prereqs eth.type == 0x800
1075 get_arp(inport, reg0);
1076 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[]
1079 Syntax error at `;' expecting `('.
1081 Syntax error at `)' expecting field name.
1083 Syntax error at `)' expecting `,'.
1084 get_arp(inport ip4.dst);
1085 Syntax error at `ip4.dst' expecting `,'.
1086 get_arp(inport, ip4.dst;
1087 Syntax error at `;' expecting `)'.
1088 get_arp(inport, eth.dst);
1089 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1090 get_arp(inport, outport);
1091 Cannot use string field outport where numeric field is required.
1092 get_arp(reg0, ip4.dst);
1093 Cannot use numeric field reg0 where string field is required.
1096 put_arp(inport, arp.spa, arp.sha);
1097 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[]
1098 has prereqs eth.type == 0x806 && eth.type == 0x806
1101 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1102 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)
1103 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");
1104 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");
1105 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)
1106 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);
1107 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);
1108 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)
1110 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1111 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1112 reg1[0] = put_dhcp_opts();
1113 put_dhcp_opts requires offerip to be specified.
1114 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1115 Syntax error at `x' expecting DHCPv4 option name.
1116 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1117 put_dhcp_opts requires offerip to be specified.
1118 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1119 Syntax error at `"hi"'.
1120 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1121 Syntax error at `xyzzy' expecting DHCPv4 option name.
1122 reg1[0] = put_dhcp_opts(offerip="xyzzy");
1123 DHCPv4 option offerip requires numeric value.
1124 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1125 DHCPv4 option domain requires string value.
1128 nd_ns { nd.target = xxreg0; output; };
1129 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)
1133 formats as nd_ns { drop; };
1134 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1138 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; };
1139 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1140 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)
1143 nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1144 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1145 encodes as controller(userdata=00.00.00.0c.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)
1149 get_nd(outport, ip6.dst);
1150 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[]
1151 has prereqs eth.type == 0x86dd
1152 get_nd(inport, xxreg0);
1153 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[]
1155 Syntax error at `;' expecting `('.
1157 Syntax error at `)' expecting field name.
1159 Syntax error at `)' expecting `,'.
1160 get_nd(inport ip6.dst);
1161 Syntax error at `ip6.dst' expecting `,'.
1162 get_nd(inport, ip6.dst;
1163 Syntax error at `;' expecting `)'.
1164 get_nd(inport, eth.dst);
1165 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1166 get_nd(inport, outport);
1167 Cannot use string field outport where numeric field is required.
1168 get_nd(xxreg0, ip6.dst);
1169 Cannot use numeric field xxreg0 where string field is required.
1172 put_nd(inport, nd.target, nd.sll);
1173 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[]
1174 has prereqs (icmp6.type == 0x87 || 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)
1177 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1178 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)
1179 reg1[0] = put_dhcpv6_opts();
1180 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1181 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1182 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1183 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)
1184 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1185 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1186 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)
1187 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1188 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)
1189 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1190 Syntax error at `x' expecting DHCPv6 option name.
1191 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1192 Syntax error at `"hi"'.
1193 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1194 Syntax error at `xyzzy' expecting DHCPv6 option name.
1195 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1196 DHCPv6 option ia_addr requires numeric value.
1197 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1198 DHCPv6 option domain_search requires string value.
1202 encodes as set_queue:0
1204 encodes as set_queue:61440
1206 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1209 reg1[0] = dns_lookup();
1210 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1212 reg1[0] = dns_lookup("foo");
1213 dns_lookup doesn't take any parameters
1217 Rate 0 for set_meter is not in valid.
1220 set_meter(100, 1000);
1222 set_meter(100, 1000, );
1223 Syntax error at `,' expecting `)'.
1224 set_meter(4294967295, 4294967295);
1228 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1229 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)
1231 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1232 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)
1234 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1235 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)
1237 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1238 slla option not present
1239 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);
1240 prefix option can't be set when address mode is dhcpv6_stateful.
1241 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);
1242 prefix option can't be set when address mode is dhcpv6_stateful.
1243 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1244 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1245 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1246 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1247 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1248 Syntax error at `dhcpv6_stateless' expecting constant.
1249 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1250 Invalid value for "prefix" option
1251 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1252 Invalid value for "addr_mode" option
1253 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1254 IPv6 ND RA option mtu requires numeric value.
1255 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1256 Invalid value for "mtu" option
1259 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1260 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)
1264 formats as icmp4 { drop; };
1265 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1269 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1270 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)
1274 formats as icmp6 { drop; };
1275 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1279 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1280 encodes as controller(userdata=00.00.00.0b.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1284 formats as tcp_reset { drop; };
1285 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1288 # Contradictionary prerequisites (allowed but not useful):
1289 ip4.src = ip6.src[0..31];
1290 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1291 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1292 ip4.src <-> ip6.src[0..31];
1293 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[]
1294 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1296 # Miscellaneous negative tests.
1298 Syntax error at `;'.
1300 Syntax error at `xyzzy' expecting action.
1302 Syntax error at `123'.
1304 Syntax error at `xyzzy' expecting action.
1306 Syntax error at end of input expecting `;'.
1308 sed '/^[[ ]]/d' test-cases.txt > input.txt
1309 cp test-cases.txt expout
1310 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1313 AT_BANNER([OVN end-to-end tests])
1315 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1316 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1317 AT_KEYWORDS([ovnarp])
1318 AT_SKIP_IF([test $HAVE_PYTHON = no])
1321 # Create hypervisors hv[123].
1322 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1323 # Add all of the vifs to a single logical switch lsw0.
1324 # Turn on port security on all the vifs except vif[123]1.
1325 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1326 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1327 ovn-nbctl ls-add lsw0
1332 ovs-vsctl add-br br-phys
1333 ovn_attach n1 br-phys 192.168.0.$i
1336 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
1337 ovn-nbctl lsp-add lsw0 lp$i$j
1338 if test $j = 1; then
1339 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1341 if test $j = 3; then
1342 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1344 ip_addrs="192.168.0.$i$j"
1346 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1347 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1351 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1352 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1353 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1354 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\"
1355 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1358 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1361 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1362 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1364 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1365 # packets for ARP resolution (native tunneling doesn't queue packets
1366 # for ARP resolution).
1369 # Allow some time for ovn-northd and ovn-controller to catch up.
1370 # XXX This should be more systematic.
1373 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1374 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1375 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1376 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1378 # Given the name of a logical port, prints the name of the hypervisor
1379 # on which it is located.
1384 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1386 # This shell function causes a packet to be received on INPORT. The packet's
1387 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1388 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1389 # more) list the VIFs on which the packet should be received. INPORT and the
1390 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1397 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1398 hv=`vif_to_hv $inport`
1400 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1402 echo $packet >> $outport.expected
1406 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1408 # Causes a packet to be received on INPORT. The packet is an ARP
1409 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1410 # it should be the hardware address of the target to expect to receive in an
1411 # ARP reply; otherwise no reply is expected.
1413 # INPORT is an logical switch port number, e.g. 11 for vif11.
1414 # SHA and REPLY_HA are each 12 hex digits.
1415 # SPA and TPA are each 8 hex digits.
1417 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1418 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1419 hv=`vif_to_hv $inport`
1420 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1422 if test X$reply_ha = X; then
1423 # Expect to receive the broadcast ARP on the other logical switch ports
1424 # if no reply is expected.
1428 if test $i$j != $inport; then
1429 echo $request >> $i$j.expected
1434 # Expect to receive the reply, if any.
1435 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1436 echo $reply >> $inport.expected
1441 printf "%02x%02x%02x%02x" "$@"
1444 # Send packets between all pairs of source and destination ports:
1446 # 1. Unicast packets are delivered to exactly one logical switch port
1447 # (except that packets destined to their input ports are dropped).
1449 # 2. Broadcast and multicast are delivered to all logical switch ports
1450 # except the input port.
1452 # 3. When port security is turned on, the switch drops packets from the wrong
1455 # 4. The switch drops all packets with a VLAN tag.
1457 # 5. The switch drops all packets with a multicast source address. (This only
1458 # affects behavior when port security is turned off, since otherwise port
1459 # security would drop the packet anyway.)
1461 # 6. The switch delivers packets with an unknown destination to logical
1462 # switch ports with "unknown" among their MAC addresses (and port
1463 # security disabled).
1465 # 7. The switch drops unicast packets that violate an ACL.
1467 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1469 # 9. OVN generates responses to ARP requests for known IPs, except for
1470 # requests from a port for the port's own IP.
1472 # 10. No response to ARP requests for unknown IPs.
1485 if test $d != $s; then unicast=$d; else unicast=; fi
1486 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1488 if test $d != $s && test $js = 1; then
1493 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1495 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1496 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1497 if test $d = $s || (test $js = 1 && test $d = 33); then
1498 # Source of 11, 21, or 31 and dest of 33 should be dropped
1499 # due to the 4th ACL that uses address_set(set1).
1504 if test $d = $s || test $d = 22 || test $d = 33; then
1505 # dest of 22 and 33 should be dropped
1506 # due to the 5th ACL that uses port_group(pg1).
1511 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1512 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1513 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1514 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1515 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1517 test_packet $s f000000000$d f00000000055 810000091234 #4
1518 test_packet $s f000000000$d 0100000000$s $s$d #5
1520 if test $d != $s && test $jd = 1; then
1521 unknown="$unknown $d"
1523 bcast="$bcast $unicast"
1524 bacl2="$bacl2 $acl2"
1525 bacl3="$bacl3 $acl3"
1527 sip=`ip_to_hex 192 168 0 $is$js`
1528 tip=`ip_to_hex 192 168 0 $id$jd`
1529 tip_unknown=`ip_to_hex 11 11 11 11`
1530 if test $d != $s; then
1531 reply_ha=f000000000$d
1535 test_arp $s f000000000$s $sip $tip $reply_ha #9
1536 test_arp $s f000000000$s $sip $tip_unknown #10
1538 if test $jd = 3; then
1539 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1540 tip=`ip_to_hex 192 169 0 $id$jd`
1541 test_arp $s f000000000$s $sip $tip $reply_ha #9
1546 # Broadcast and multicast.
1547 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1548 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1549 if test $js = 1; then
1550 bcast_impersonate=$bcast
1554 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1556 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1558 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1559 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1560 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1561 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1562 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1563 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1567 # set address for lp13 with invalid characters.
1568 # lp13 should be configured with only 192.168.0.13.
1569 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1571 # Allow some time for ovn-northd and ovn-controller to catch up.
1572 # XXX This should be more systematic.
1575 sip=`ip_to_hex 192 168 0 11`
1576 tip=`ip_to_hex 192 168 0 13`
1577 test_arp 11 f00000000011 $sip $tip f00000000013
1579 tip=`ip_to_hex 192 169 0 13`
1580 #arp request for 192.169.0.13 should be flooded
1581 test_arp 11 f00000000011 $sip $tip
1583 # dump information and flows with counters
1584 ovn-sbctl dump-flows -- list multicast_group
1586 echo "------ hv1 dump ------"
1587 as hv1 ovs-vsctl show
1588 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1590 echo "------ hv2 dump ------"
1591 as hv2 ovs-vsctl show
1592 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1594 echo "------ hv3 dump ------"
1595 as hv3 ovs-vsctl show
1596 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1598 # Now check the packets actually received against the ones expected.
1601 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1605 OVN_CLEANUP([hv1],[hv2],[hv3])
1609 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1610 AT_SKIP_IF([test $HAVE_PYTHON = no])
1613 # Create a logical switch and some logical ports.
1614 # Turn on port security on all lports except ls1.
1615 # Make ls1 a destination for unknown MACs.
1616 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1617 ovn-nbctl ls-add lsw0
1618 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1620 ovn-nbctl lsp-add lsw0 lp$i
1622 ovn-nbctl --wait=sb sync
1624 ovn-sbctl lsp-bind lp$i hv0
1625 if test $i = 1; then
1626 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1628 if test $i = 3; then
1629 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1631 ip_addrs="192.168.0.$i"
1633 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1634 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1637 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1638 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1639 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1640 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1641 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1643 ovn-nbctl --wait=sb sync
1644 on_exit 'kill `cat ovn-trace.pid`'
1645 ovn-trace --detach --pidfile --no-chdir
1647 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1649 # This shell function causes a packet to be received on INPORT. The packet's
1650 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1651 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1652 # more) list the VIFs on which the packet should be received. INPORT and the
1653 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1655 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1656 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1659 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1660 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1665 echo "output(\"lp$outport\");"
1668 AT_CAPTURE_FILE([trace])
1669 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1672 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1674 # Causes a packet to be received on INPORT. The packet is an ARP
1675 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1676 # it should be the hardware address of the target to expect to receive in an
1677 # ARP reply; otherwise no reply is expected.
1679 # INPORT is an logical switch port number, e.g. 11 for vif11.
1680 # SHA and REPLY_HA are each 12 hex digits.
1681 # SPA and TPA are each 8 hex digits.
1683 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1685 local request="inport == \"lp$inport\"
1686 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1687 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1688 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1690 if test -z "$reply_ha"; then
1694 if test $i != $inport; then
1695 reply="${reply}output(\"lp$i\");
1702 eth.src = $reply_ha;
1705 arp.sha = $reply_ha;
1708 output(\"lp$inport\");
1712 AT_CAPTURE_FILE([trace])
1713 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1716 # Send packets between all pairs of source and destination ports:
1718 # 1. Unicast packets are delivered to exactly one logical switch port
1719 # (except that packets destined to their input ports are dropped).
1721 # 2. Broadcast and multicast are delivered to all logical switch ports
1722 # except the input port.
1724 # 3. When port security is turned on, the switch drops packets from the wrong
1727 # 4. The switch drops all packets with a VLAN tag.
1729 # 5. The switch drops all packets with a multicast source address. (This only
1730 # affects behavior when port security is turned off, since otherwise port
1731 # security would drop the packet anyway.)
1733 # 6. The switch delivers packets with an unknown destination to logical
1734 # switch ports with "unknown" among their MAC addresses (and port
1735 # security disabled).
1737 # 7. The switch drops unicast packets that violate an ACL.
1739 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1741 # 9. OVN generates responses to ARP requests for known IPs, except for
1742 # requests from a port for the port's own IP.
1744 # 10. No response to ARP requests for unknown IPs.
1754 if test $d != $s; then unicast=$d; else unicast=; fi
1755 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1757 if test $d != $s && test $s = 1; then
1762 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1764 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1765 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1766 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1767 # Source of 1 or 2 and dest of 3 should be dropped
1768 # due to the 4th ACL that uses address_set(set1).
1775 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1776 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1777 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1780 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1781 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1783 if test $d != $s && test $d = 1; then
1784 unknown="$unknown $d"
1786 bcast="$bcast $unicast"
1787 bacl2="$bacl2 $acl2"
1788 bacl3="$bacl3 $acl3"
1792 tip_unknown=11.11.11.11
1793 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1794 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1795 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1797 if test $d = 3; then
1798 # lp3 has an additional ip 192.169.0.[123]3.
1800 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1804 # Broadcast and multicast.
1805 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1806 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1807 if test $s = 1; then
1808 bcast_impersonate=$bcast
1812 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1814 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1817 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1818 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1819 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1822 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1823 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1824 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1829 # 2 hypervisors, 4 logical ports per HV
1830 # 2 locally attached networks (one flat, one vlan tagged over same device)
1831 # 2 ports per HV on each network
1832 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1833 AT_SKIP_IF([test $HAVE_PYTHON = no])
1836 # In this test cases we create 3 switches, all connected to same
1837 # physical network (through br-phys on each HV). Each switch has
1838 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1839 # of VIF port name indicates the hypervisor it is bound to, e.g.
1840 # lp23 means VIF 3 on hv2.
1842 # Each switch's VLAN tag and their logical switch ports are:
1845 # - ports: lp11, lp12, lp21, lp22
1848 # - tagged with VLAN 101
1849 # - ports: lp13, lp14, lp23, lp24
1852 # - ports: lp15, lp25
1854 # Note: a localnet port is created for each switch to connect to
1859 ovn-nbctl ls-add $ls_name
1861 if test $i -eq 2; then
1862 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1864 ovn-nbctl lsp-add $ls_name $ln_port_name
1866 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1867 ovn-nbctl lsp-set-type $ln_port_name localnet
1868 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1873 # Prints the name of the logical switch that contains LSP.
1876 lp?[[12]]) echo ls1 ;; dnl (
1877 lp?[[34]]) echo ls2 ;; dnl (
1878 lp?5) echo ls3 ;; dnl (
1879 *) AT_FAIL_IF([:]) ;;
1887 ovs-vsctl add-br br-phys
1888 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1889 ovn_attach n1 br-phys 192.168.0.$i
1891 for j in 1 2 3 4 5; do
1892 ovs-vsctl add-port br-int vif$i$j -- \
1893 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1894 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1895 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1899 ls_name=$(lsp_to_ls $lsp_name)
1901 ovn-nbctl lsp-add $ls_name $lsp_name
1902 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1903 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1905 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1908 ovn-nbctl --wait=sb sync
1909 ovn-sbctl dump-flows
1913 # XXX This is now the 3rd copy of these functions in this file ...
1915 # Given the name of a logical port, prints the name of the hypervisor
1916 # on which it is located.
1921 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1923 # This shell function causes a packet to be received on INPORT. The packet's
1924 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1925 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1926 # logical switch port numbers, e.g. 11 for vif11.
1928 # EOUT is the end-to-end output port, that is, where the packet will end up
1929 # after possibly bouncing through one or more localnet ports. LOUT is the
1930 # logical output port, which might be a localnet port, as seen by ovn-trace
1931 # (which doesn't know what localnet ports are connected to and therefore can't
1932 # figure out the end-to-end answer).
1934 for j in 1 2 3 4 5; do
1939 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1942 # First try tracing the packet.
1943 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1944 if test $lout != drop; then
1945 echo "output(\"$lout\");"
1947 AT_CAPTURE_FILE([trace])
1948 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1950 # Then actually send a packet, for an end-to-end test.
1951 local packet=$(echo $dst$src | sed 's/://g')${eth}
1952 hv=`vif_to_hv $inport`
1954 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1955 if test $eout != drop; then
1956 echo $packet >> ${eout#lp}.expected
1960 # lp11 and lp21 are on the same network (phys, untagged)
1961 # and on different hypervisors
1962 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1963 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1965 # lp11 and lp12 are on the same network (phys, untagged)
1966 # and on the same hypervisor
1967 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1968 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1970 # lp13 and lp23 are on the same network (phys, VLAN 101)
1971 # and on different hypervisors
1972 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1973 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1975 # lp13 and lp14 are on the same network (phys, VLAN 101)
1976 # and on the same hypervisor
1977 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1978 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1980 # lp11 and lp15 are on the same network (phys, untagged),
1981 # same hypervisor, and on different switches
1982 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1983 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1985 # lp11 and lp25 are on the same network (phys, untagged),
1986 # different hypervisors, and on different switches
1987 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1988 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1990 # Ports that should not be able to communicate
1991 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1992 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1993 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1994 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1995 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1996 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1997 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1998 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
2000 # Dump a bunch of info helpful for debugging if there's a failure.
2002 echo "------ OVN dump ------"
2006 echo "------ hv1 dump ------"
2007 as hv1 ovs-vsctl show
2008 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2010 echo "------ hv2 dump ------"
2011 as hv2 ovs-vsctl show
2012 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2014 # Now check the packets actually received against the ones expected.
2016 for j in 1 2 3 4 5; do
2017 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2021 OVN_CLEANUP([hv1],[hv2])
2025 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2027 AT_SKIP_IF([test $HAVE_PYTHON = no])
2030 # Configure the Northbound database
2031 ovn-nbctl ls-add lsw0
2033 ovn-nbctl lsp-add lsw0 lp1
2034 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2036 ovn-nbctl lsp-add lsw0 lp2
2037 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2039 ovn-nbctl lsp-add lsw0 lp-vtep
2040 ovn-nbctl lsp-set-type lp-vtep vtep
2041 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2042 ovn-nbctl lsp-set-addresses lp-vtep unknown
2044 # lpr, lr and lrp1 are used for the ARP request handling test only.
2045 ovn-nbctl lsp-add lsw0 lpr
2047 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2048 ovn-nbctl set Logical_Switch_Port lpr type=router \
2049 options:router-port=lrp1 \
2050 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2053 net_add n1 # Network to connect hv1, hv2, and vtep
2054 net_add n2 # Network to connect vtep and hv3
2056 # Create hypervisor hv1 connected to n1
2059 ovs-vsctl add-br br-phys
2060 ovn_attach n1 br-phys 192.168.0.1
2061 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
2063 # Create hypervisor hv2 connected to n1
2066 ovs-vsctl add-br br-phys
2067 ovn_attach n1 br-phys 192.168.0.2
2068 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
2071 # Start the vtep emulator with a leg in both networks
2075 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2076 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2078 ovs-vsctl add-br br-phys
2079 net_attach n1 br-phys
2081 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2082 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2083 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2084 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2086 ovs-vsctl add-br br-vtep
2087 net_attach n2 br-vtep
2089 vtep-ctl add-ps br-vtep
2090 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2091 vtep-ctl add-ls lsw0
2093 start_daemon ovs-vtep br-vtep
2094 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2096 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2098 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2100 # It takes more time for the update to be processed by ovs-vtep.
2103 # Add hv3 on the other side of the vtep
2106 ovs-vsctl add-br br-phys
2107 net_attach n2 br-phys
2109 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
2111 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2112 # packets for ARP resolution (native tunneling doesn't queue packets
2113 # for ARP resolution).
2116 # Allow some time for ovn-northd and ovn-controller to catch up.
2117 # XXX This should be more systematic.
2120 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2122 # This shell function causes a packet to be received on INPORT. The packet's
2123 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2124 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2125 # more) list the VIFs on which the packet should be received. INPORT and the
2126 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2131 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2132 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2135 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2137 echo $packet >> $outport.expected
2141 # Send packets between all pairs of source and destination ports:
2143 # 1. Unicast packets are delivered to exactly one logical switch port
2144 # (except that packets destined to their input ports are dropped).
2146 # 2. Broadcast and multicast are delivered to all logical switch ports
2147 # except the input port.
2149 # 3. The switch delivers packets with an unknown destination to logical
2150 # switch ports with "unknown" among their MAC addresses (and port
2151 # security disabled).
2156 if test $d != $s; then unicast=$d; else unicast=; fi
2157 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2159 # The vtep (vif3) is the only one configured for "unknown"
2160 if test $d != $s && test $d = 3; then
2161 unknown="$unknown $d"
2163 bcast="$bcast $unicast"
2166 # Broadcast and multicast.
2167 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2168 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2170 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2173 # ARP request should not be responded to by logical switch router
2174 # type arp responder on HV1 and HV2 and should reach directly to
2177 printf "%02x%02x%02x%02x" "$@"
2180 spa=`ip_to_hex 192 168 1 2`
2181 tpa=`ip_to_hex 192 168 1 1`
2182 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2183 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2184 echo $request >> 1.expected
2185 echo $request >> 2.expected
2187 # dump information with counters
2188 echo "------ OVN dump ------"
2192 echo "---------SB dump-----"
2193 ovn-sbctl list datapath_binding
2194 echo "---------------------"
2195 ovn-sbctl list port_binding
2196 echo "---------------------"
2197 ovn-sbctl dump-flows
2199 echo "------ hv1 dump ------"
2200 as hv1 ovs-vsctl show
2201 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2202 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2204 echo "------ hv2 dump ------"
2205 as hv2 ovs-vsctl show
2206 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2207 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2209 echo "------ hv3 dump ------"
2210 as hv3 ovs-vsctl show
2211 # note: hv3 has no logical port bind, thus it should not have br-int
2212 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2213 [ovs-ofctl: br-int is not a bridge or a socket
2216 # Now check the packets actually received against the ones expected.
2218 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2221 # Gracefully terminate daemons
2222 OVN_CLEANUP([hv1],[hv2],[vtep])
2223 OVN_CLEANUP_VSWITCH([hv3])
2227 # Similar test to "hardware GW"
2228 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2229 AT_SKIP_IF([test $HAVE_PYTHON = no])
2232 # Configure the Northbound database
2233 ovn-nbctl ls-add lsw0
2235 ovn-nbctl lsp-add lsw0 lp1
2236 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2238 ovn-nbctl lsp-add lsw0 lp2
2239 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2241 ovn-nbctl lsp-add lsw0 lp-gw
2242 ovn-nbctl lsp-set-type lp-gw l2gateway
2243 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2244 ovn-nbctl lsp-set-addresses lp-gw unknown
2246 net_add n1 # Network to connect hv1, hv2, and gw
2247 net_add n2 # Network to connect gw and hv3
2249 # Create hypervisor hv1 connected to n1
2252 ovs-vsctl add-br br-phys
2253 ovn_attach n1 br-phys 192.168.0.1
2254 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
2256 # Create hypervisor hv2 connected to n1
2259 ovs-vsctl add-br br-phys
2260 ovn_attach n1 br-phys 192.168.0.2
2261 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
2263 # Create hypervisor hv_gw connected to n1 and n2
2264 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2267 ovs-vsctl add-br br-phys
2268 ovn_attach n1 br-phys 192.168.0.3
2269 ovs-vsctl add-br br-phys2
2270 net_attach n2 br-phys2
2271 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2273 # Add hv3 on the other side of the GW
2276 ovs-vsctl add-br br-phys
2277 net_attach n2 br-phys
2278 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
2281 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2282 # packets for ARP resolution (native tunneling doesn't queue packets
2283 # for ARP resolution).
2286 # Allow some time for ovn-northd and ovn-controller to catch up.
2287 # XXX This should be more systematic.
2290 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2292 # This shell function causes a packet to be received on INPORT. The packet's
2293 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2294 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2295 # more) list the VIFs on which the packet should be received. INPORT and the
2296 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2301 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2302 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2305 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2307 echo $packet >> $outport.expected
2311 # Send packets between all pairs of source and destination ports:
2313 # 1. Unicast packets are delivered to exactly one lport (except that packets
2314 # destined to their input ports are dropped).
2316 # 2. Broadcast and multicast are delivered to all lports except the input port.
2318 # 3. The lswitch delivers packets with an unknown destination to lports with
2319 # "unknown" among their MAC addresses (and port security disabled).
2324 if test $d != $s; then unicast=$d; else unicast=; fi
2325 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2327 # The vtep (vif3) is the only one configured for "unknown"
2328 if test $d != $s && test $d = 3; then
2329 unknown="$unknown $d"
2331 bcast="$bcast $unicast"
2334 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2335 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2336 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2339 echo "------ ovn-nbctl show ------"
2341 echo "------ ovn-sbctl show ------"
2344 echo "------ hv1 ------"
2345 as hv1 ovs-vsctl show
2346 echo "------ hv1 br-int ------"
2347 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2348 echo "------ hv1 br-phys ------"
2349 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2351 echo "------ hv2 ------"
2352 as hv2 ovs-vsctl show
2353 echo "------ hv2 br-int ------"
2354 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2355 echo "------ hv2 br-phys ------"
2356 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2358 echo "------ hv_gw ------"
2359 as hv_gw ovs-vsctl show
2360 echo "------ hv_gw br-phys ------"
2361 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2362 echo "------ hv_gw br-phys2 ------"
2363 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2365 echo "------ hv3 ------"
2366 as hv3 ovs-vsctl show
2367 echo "------ hv3 br-phys ------"
2368 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2370 # Now check the packets actually received against the ones expected.
2372 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2376 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2377 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2378 AT_SKIP_IF([test $HAVE_PYTHON = no])
2383 # Three logical switches ls1, ls2, ls3.
2384 # One logical router lr0 connected to ls[123],
2385 # with nine subnets, three per logical switch:
2387 # lrp11 on ls1 for subnet 192.168.11.0/24
2388 # lrp12 on ls1 for subnet 192.168.12.0/24
2389 # lrp13 on ls1 for subnet 192.168.13.0/24
2391 # lrp33 on ls3 for subnet 192.168.33.0/24
2393 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2394 # digits are the subnet and the last digit distinguishes the VIF.
2396 ovn-nbctl ls-add ls$i
2399 # Add "unknown" to MAC addresses for lp?11, so packets for
2400 # MAC-IP bindings discovered via ARP later have somewhere to go.
2401 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2404 -- lsp-add ls$i lp$i$j$k \
2405 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2406 192.168.$i$j.$k" $unknown
2411 ovn-nbctl lr-add lr0
2414 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2416 -- lsp-add ls$i lrp$i$j-attachment \
2417 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2418 options:router-port=lrp$i$j \
2419 addresses='"00:00:00:00:ff:'$i$j'"'
2423 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2424 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2428 # Three hypervisors hv[123].
2429 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2430 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2431 # lp?3[123] all on hv3.
2434 # Given the name of a logical port, prints the name of the hypervisor
2435 # on which it is located.
2438 ?11) echo 1 ;; dnl (
2439 ?12 | ?21 | ?22) echo 2 ;; dnl (
2440 ?13 | ?23 | ?3?) echo 3 ;;
2444 # Given the name of a logical port, prints the name of its logical router
2445 # port, e.g. "vif_to_lrp 123" yields 12.
2450 # Given the name of a logical port, prints the name of its logical
2451 # switch, e.g. "vif_to_ls 123" yields 1.
2460 ovs-vsctl add-br br-phys
2461 ovn_attach n1 br-phys 192.168.0.$i
2466 hv=`vif_to_hv $i$j$k`
2467 as hv$hv ovs-vsctl \
2468 -- add-port br-int vif$i$j$k \
2469 -- set Interface vif$i$j$k \
2470 external-ids:iface-id=lp$i$j$k \
2471 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2472 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2473 ofport-request=$i$j$k
2478 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2479 # packets for ARP resolution (native tunneling doesn't queue packets
2480 # for ARP resolution).
2483 # Allow some time for ovn-northd and ovn-controller to catch up.
2484 # XXX This should be more systematic.
2487 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2489 # This shell function causes a packet to be received on INPORT. The packet's
2490 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2491 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2492 # more) list the VIFs on which the packet should be received. INPORT and the
2493 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2502 # This packet has bad checksums but logical L3 routing doesn't check.
2503 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2504 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2505 shift; shift; shift; shift; shift
2506 hv=hv`vif_to_hv $inport`
2507 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2508 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2509 in_ls=`vif_to_ls $inport`
2510 in_lrp=`vif_to_lrp $inport`
2512 out_ls=`vif_to_ls $outport`
2513 if test $in_ls = $out_ls; then
2514 # Ports on the same logical switch receive exactly the same packet.
2517 # Routing decrements TTL and updates source and dest MAC
2519 out_lrp=`vif_to_lrp $outport`
2520 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2521 fi >> $outport.expected
2525 as hv1 ovs-vsctl --columns=name,ofport list interface
2526 as hv1 ovn-sbctl list port_binding
2527 as hv1 ovn-sbctl list datapath_binding
2528 as hv1 ovn-sbctl dump-flows
2529 as hv1 ovs-ofctl dump-flows br-int
2531 # Send IP packets between all pairs of source and destination ports:
2533 # 1. Unicast IP packets are delivered to exactly one logical switch port
2534 # (except that packets destined to their input ports are dropped).
2536 # 2. Broadcast IP packets are delivered to all logical switch ports
2537 # except the input port.
2539 printf "%02x%02x%02x%02x" "$@"
2547 sip=`ip_to_hex 192 168 $is$js $ks`
2552 dip=`ip_to_hex 192 168 $id$jd $kd`
2553 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2554 if test $d != $s; then unicast=$d; else unicast=; fi
2556 test_ip $s $smac $dmac $sip $dip $unicast #1
2558 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2562 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2567 # 3. Send an IP packet from every logical port to every other subnet,
2568 # to an IP address that does not have a static IP-MAC binding.
2569 # This should generate a broadcast ARP request for the destination
2570 # IP address in the destination subnet.
2576 sip=`ip_to_hex 192 168 $is$js $ks`
2579 if test $is$js = $id$jd; then
2584 dmac=00000000ff$is$js
2585 # Calculate a 4th octet for the destination that is
2586 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2587 # that have static MAC bindings, and fits in the range
2589 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2590 dip=`ip_to_hex 192 168 $id$jd $o4`
2591 test_ip $s $smac $dmac $sip $dip
2593 # Every LP on the destination subnet's lswitch should
2594 # receive the ARP request.
2595 lrmac=00000000ff$id$jd
2596 lrip=`ip_to_hex 192 168 $id$jd 254`
2597 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2598 for jd2 in 1 2 3; do
2600 echo $arp >> $id$jd2$kd.expected
2609 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2611 # Causes a packet to be received on INPORT. The packet is an ARP
2612 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2613 # it should be the hardware address of the target to expect to receive in an
2614 # ARP reply; otherwise no reply is expected.
2616 # INPORT is an logical switch port number, e.g. 11 for vif11.
2617 # SHA and REPLY_HA are each 12 hex digits.
2618 # SPA and TPA are each 8 hex digits.
2620 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2621 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2622 hv=hv`vif_to_hv $inport`
2623 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2624 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2626 # Expect to receive the broadcast ARP on the other logical switch ports if
2627 # IP address is not configured to the switch patch port.
2628 local i=`vif_to_ls $inport`
2632 # 192.168.33.254 is configured to the switch patch port for lrp33,
2633 # so no ARP flooding expected for it.
2634 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2635 echo $request >> $i$j$k.expected
2640 # Expect to receive the reply, if any.
2641 if test X$reply_ha != X; then
2642 lrp=`vif_to_lrp $inport`
2643 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2644 echo $reply >> $inport.expected
2648 # Test router replies to ARP requests from all source ports:
2650 # 4. Router replies to query for its MAC address from port's own IP address.
2652 # 5. Router replies to query for its MAC address from any random IP address
2655 # 6. Router replies to query for its MAC address from another subnet.
2657 # 7. No reply to query for IP address other than router IP.
2661 smac=f00000000$i$j$k # Source MAC
2662 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2663 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2664 rmac=00000000ff$i$j # Router MAC
2665 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2666 test_arp $i$j$k $smac $sip $rip $rmac #4
2667 test_arp $i$j$k $smac $otherip $rip $rmac #5
2668 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2669 test_arp $i$j$k $smac $sip $otherip #7
2674 # Allow some time for packet forwarding.
2675 # XXX This can be improved.
2678 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2681 # Here, the $s is the VIF that originated the ARP request and $d is
2682 # the VIF that sends the ARP reply, which is somewhat backward but
2683 # it means that $s and $d are the same as #3.
2684 : > mac_bindings.expected
2691 if test $is$js = $id$jd; then
2698 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2699 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2700 host_mac=8000000000$o4
2702 lrmac=00000000ff$id$jd
2703 lrip=`ip_to_hex 192 168 $id$jd 254`
2705 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2711 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2712 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2713 #as $hv ovs-ofctl dump-flows br-int table=19
2715 host_ip_pretty=192.168.$id$jd.$o4
2716 host_mac_pretty=80:00:00:00:00:$o4
2717 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2724 # Allow some time for packet forwarding.
2725 # XXX This can be improved.
2728 # 9. Send an IP packet from every logical port to every other subnet. These
2729 # are the same packets already sent as #3, but now the destinations' IP-MAC
2730 # bindings have been discovered via ARP, so instead of provoking an ARP
2731 # request, these packets now get routed to their destinations (which don't
2732 # have static MAC bindings, so they go to the port we've designated as
2733 # accepting "unknown" MACs.)
2739 sip=`ip_to_hex 192 168 $is$js $ks`
2742 if test $is$js = $id$jd; then
2747 dmac=00000000ff$is$js
2748 # Calculate a 4th octet for the destination that is
2749 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2750 # that have static MAC bindings, and fits in the range
2752 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2753 dip=`ip_to_hex 192 168 $id$jd $o4`
2754 test_ip $s $smac $dmac $sip $dip
2756 # Expect the packet egress.
2757 host_mac=8000000000$o4
2760 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2767 ovn-sbctl -f csv -d bare --no-heading \
2768 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2770 # Now check the packets actually received against the ones expected.
2774 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2780 # Check the MAC bindings against those expected.
2781 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2784 # Gracefully terminate daemons
2785 OVN_CLEANUP([hv1], [hv2], [hv3])
2789 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2790 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2791 AT_SKIP_IF([test $HAVE_PYTHON = no])
2794 # Create hypervisors hv[123].
2795 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2796 # Add all of the vifs to a single logical switch lsw0.
2797 # Turn off port security on vifs vif[123]1
2798 # Turn on l2 port security on vifs vif[123]2
2799 # Turn of l2 and l3 port security on vifs vif[123]3
2800 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2801 ovn-nbctl ls-add lsw0
2806 ovs-vsctl add-br br-phys
2807 ovn_attach n1 br-phys 192.168.0.$i
2810 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
2811 ovn-nbctl lsp-add lsw0 lp$i$j
2812 if test $j = 1; then
2813 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2814 elif test $j = 2; then
2815 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2816 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2818 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2819 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2820 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2825 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2826 # packets for ARP resolution (native tunneling doesn't queue packets
2827 # for ARP resolution).
2830 # Allow some time for ovn-northd and ovn-controller to catch up.
2831 # XXX This should be more systematic.
2834 # Given the name of a logical port, prints the name of the hypervisor
2835 # on which it is located.
2846 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2848 # This shell function causes an ip packet to be received on INPORT.
2849 # The packet's content has Ethernet destination DST and source SRC
2850 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2851 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2852 # be received. INPORT and the OUTPORTs are specified as logical switch
2853 # port numbers, e.g. 11 for vif11.
2855 # This packet has bad checksums but logical L3 routing doesn't check.
2856 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2857 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2858 shift; shift; shift; shift; shift
2859 hv=`vif_to_hv $inport`
2860 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2861 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2863 echo $packet >> $outport.expected
2867 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2869 # Causes a packet to be received on INPORT. The packet is an ARP
2870 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2871 # it should be the hardware address of the target to expect to receive in an
2872 # ARP reply; otherwise no reply is expected.
2874 # INPORT is an logical switch port number, e.g. 11 for vif11.
2875 # SHA and REPLY_HA are each 12 hex digits.
2876 # SPA and TPA are each 8 hex digits.
2878 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2879 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2880 hv=`vif_to_hv $inport`
2881 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2882 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2883 if test $drop != 1; then
2884 if test X$reply_ha = X; then
2885 # Expect to receive the broadcast ARP on the other logical switch ports
2886 # if no reply is expected.
2890 if test $i$j != $inport; then
2891 echo $request >> $i$j.expected
2896 # Expect to receive the reply, if any.
2897 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2898 echo $reply >> $inport.expected
2903 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2904 # This function is similar to test_ip() except that it sends
2907 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2908 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2909 shift; shift; shift; shift; shift
2910 hv=`vif_to_hv $inport`
2911 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2912 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2914 echo $packet >> $outport.expected
2918 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2919 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2920 # of the test packet
2922 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2923 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2924 shift; shift; shift; shift; shift; shift
2925 hv=`vif_to_hv $inport`
2926 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2927 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2929 echo $packet >> $outport.expected
2934 printf "%02x%02x%02x%02x" "$@"
2938 sip=`ip_to_hex 192 168 0 12`
2939 tip=`ip_to_hex 192 168 0 13`
2940 # the arp packet should be allowed even if lp[123]1 is
2941 # not configured with mac f00000000023 and ip 192.168.0.12
2943 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2945 if test $i != $j; then
2946 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2952 sip=`ip_to_hex 192 168 0 12`
2953 tip=`ip_to_hex 192 168 0 13`
2955 # arp packet should be allowed since lp22 is configured with
2957 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2959 # arp packet should not be allowed since lp32 is not configured with
2961 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2963 # arp packet with sha set to f00000000021 should not be allowed
2965 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2967 # ip packets should be allowed and received since lp[123]2 do not
2968 # have l3 port security
2969 sip=`ip_to_hex 192 168 0 55`
2970 tip=`ip_to_hex 192 168 0 66`
2973 if test $i != $j; then
2974 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2979 # ipv6 packets should be received by lp[123]2
2980 # lp[123]1 can send ipv6 traffic as there is no port security
2981 sip=fe800000000000000000000000000000
2982 tip=ff020000000000000000000000000000
2985 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2989 # l2 and l3 port security
2990 sip=`ip_to_hex 192 168 0 13`
2991 tip=`ip_to_hex 192 168 0 22`
2992 # arp packet should be allowed since lp13 is configured with
2993 # f00000000013 and 192.168.0.13
2994 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2996 # the arp packet should be dropped because lp23 is not configured
2997 # with mac f00000000022
2998 sip=`ip_to_hex 192 168 0 13`
2999 tip=`ip_to_hex 192 168 0 22`
3000 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3002 # the arp packet should be dropped because lp33 is not configured
3003 # with ip 192.168.0.55
3004 spa=`ip_to_hex 192 168 0 55`
3005 tpa=`ip_to_hex 192 168 0 22`
3006 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3008 # ip packets should not be received by lp[123]3 since
3009 # l3 port security is enabled
3010 sip=`ip_to_hex 192 168 0 55`
3011 tip=`ip_to_hex 192 168 0 66`
3014 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3018 # ipv6 packets should be dropped for lp[123]3 since
3019 # it is configured with only ipv4 address
3020 sip=fe800000000000000000000000000000
3021 tip=ff020000000000000000000000000000
3024 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3027 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3028 # lp[123]1 can send ipv6 traffic as there is no port security
3030 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3033 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3034 # fe80::ea2a:eaff:fe28:0012
3036 # ipv4 packet should be dropped for lp13 with mac f0000000113
3037 sip=`ip_to_hex 192 168 0 13`
3038 tip=`ip_to_hex 192 168 0 23`
3039 test_ip 13 f00000000113 f00000000023 $sip $tip
3041 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3042 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3043 # lp11 can send ipv6 traffic as there is no port security
3044 sip=ee800000000000000000000000000000
3046 tip=fe80000000000000ea2aeafffe2800${i}3
3047 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3051 # ipv6 packet should not be received by lp33 with mac f0000000333
3052 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3053 # configured with fe80::ea2a:eaff:fe28:0033
3054 # lp11 can send ipv6 traffic as there is no port security
3056 sip=ee800000000000000000000000000000
3057 tip=fe80000000000000ea2aeafffe280023
3058 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3060 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3061 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3062 # and should be dropped for any other ip6.src
3063 # lp21 can receive ipv6 traffic as there is no port security
3065 tip=ee800000000000000000000000000000
3067 sip=fe80000000000000ea2aeafffe2800${i}3
3068 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3070 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3071 sip=00000000000000000000000000000000
3072 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3073 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3074 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3075 # Traffic to non-multicast traffic should be dropped
3076 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3077 # Traffic of other ICMPv6 types should be dropped
3078 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3081 sip=ae80000000000000ea2aeafffe2800aa
3082 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3085 # configure lsp13 to send and received IPv4 packets with an address range
3086 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"
3090 sip=`ip_to_hex 10 0 0 13`
3091 tip=`ip_to_hex 192 168 0 22`
3092 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3093 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3095 sip=`ip_to_hex 10 0 0 14`
3096 tip=`ip_to_hex 192 168 0 23`
3097 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3098 # with dst ip 192.168.0.23 should be allowed
3099 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3101 sip=`ip_to_hex 192 168 0 33`
3102 tip=`ip_to_hex 10 0 0 15`
3103 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3104 # with dst ip 10.0.0.15 should be received by lsp13
3105 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3107 sip=`ip_to_hex 192 168 0 33`
3108 tip=`ip_to_hex 20 0 0 4`
3109 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3110 # with dst ip 20.0.0.4 should be received by lsp13
3111 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3113 sip=`ip_to_hex 192 168 0 33`
3114 tip=`ip_to_hex 20 0 0 5`
3115 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3116 # with dst ip 20.0.0.5 should not be received by lsp13
3117 test_ip 33 f00000000033 f00000000013 $sip $tip
3119 sip=`ip_to_hex 192 168 0 33`
3120 tip=`ip_to_hex 20 0 0 255`
3121 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3122 # with dst ip 20.0.0.255 should be received by lsp13
3123 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3125 sip=`ip_to_hex 192 168 0 33`
3126 tip=`ip_to_hex 192 168 0 255`
3127 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3128 # with dst ip 192.168.0.255 should not be received by lsp13
3129 test_ip 33 f00000000033 f00000000013 $sip $tip
3131 sip=`ip_to_hex 192 168 0 33`
3132 tip=`ip_to_hex 224 0 0 4`
3133 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3134 # with dst ip 224.0.0.4 should be received by lsp13
3135 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3137 #dump information including flow counters
3139 ovn-sbctl dump-flows -- list multicast_group
3141 echo "------ hv1 dump ------"
3142 as hv1 ovs-vsctl show
3143 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3144 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3146 echo "------ hv2 dump ------"
3147 as hv2 ovs-vsctl show
3148 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3149 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3151 echo "------ hv3 dump ------"
3152 as hv3 ovs-vsctl show
3153 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3154 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3156 # Now check the packets actually received against the ones expected.
3159 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3163 OVN_CLEANUP([hv1],[hv2],[hv3])
3167 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3168 AT_SKIP_IF([test $HAVE_PYTHON = no])
3172 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3173 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3174 # R2 has ls2 (172.16.1.0/24) connected to it.
3176 ls1_lp1_mac="f0:00:00:01:02:03"
3177 rp_ls1_mac="00:00:00:01:02:03"
3178 rp_ls2_mac="00:00:00:01:02:04"
3179 ls2_lp1_mac="f0:00:00:01:02:04"
3181 ls1_lp1_ip="192.168.1.2"
3182 ls2_lp1_ip="172.16.1.2"
3187 ovn-nbctl ls-add ls1
3188 ovn-nbctl ls-add ls2
3191 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3193 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3194 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3197 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3199 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3200 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3203 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3204 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3206 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3207 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3209 # Create logical port ls1-lp1 in ls1
3210 ovn-nbctl lsp-add ls1 ls1-lp1 \
3211 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3213 # Create logical port ls2-lp1 in ls2
3214 ovn-nbctl lsp-add ls2 ls2-lp1 \
3215 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3217 # Create two hypervisor and create OVS ports corresponding to logical ports.
3222 ovs-vsctl add-br br-phys
3223 ovn_attach n1 br-phys 192.168.0.1
3224 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3225 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3226 options:tx_pcap=hv1/vif1-tx.pcap \
3227 options:rxq_pcap=hv1/vif1-rx.pcap \
3232 ovs-vsctl add-br br-phys
3233 ovn_attach n1 br-phys 192.168.0.2
3234 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3235 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3236 options:tx_pcap=hv2/vif1-tx.pcap \
3237 options:rxq_pcap=hv2/vif1-rx.pcap \
3241 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3242 # packets for ARP resolution (native tunneling doesn't queue packets
3243 # for ARP resolution).
3246 # Allow some time for ovn-northd and ovn-controller to catch up.
3247 # XXX This should be more systematic.
3251 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3252 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3253 udp && udp.src==53 && udp.dst==4369"
3254 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3257 echo "---------NB dump-----"
3259 echo "---------------------"
3260 ovn-nbctl list logical_router
3261 echo "---------------------"
3262 ovn-nbctl list logical_router_port
3263 echo "---------------------"
3265 echo "---------SB dump-----"
3266 ovn-sbctl list datapath_binding
3267 echo "---------------------"
3268 ovn-sbctl list port_binding
3269 echo "---------------------"
3271 echo "------ hv1 dump ----------"
3272 as hv1 ovs-ofctl show br-int
3273 as hv1 ovs-ofctl dump-flows br-int
3274 echo "------ hv2 dump ----------"
3275 as hv2 ovs-ofctl show br-int
3276 as hv2 ovs-ofctl dump-flows br-int
3279 # The TTL should be decremented by 2.
3280 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3281 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3282 udp && udp.src==53 && udp.dst==4369"
3283 echo $packet | ovstest test-ovn expr-to-packets > expected
3285 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3287 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3288 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3291 # Disable the ls2-lp1 port.
3292 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3294 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3295 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3298 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3300 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3301 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3302 udp && udp.src==53 && udp.dst==4369"
3304 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3305 # The 2nd packet sent shound not be received.
3306 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3308 OVN_CLEANUP([hv1],[hv2])
3313 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3314 AT_KEYWORDS([router-admin-state])
3315 AT_SKIP_IF([test $HAVE_PYTHON = no])
3319 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3320 # and 172.16.1.0/24) connected to it.
3324 ovn-nbctl ls-add ls1
3327 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3328 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3329 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3331 # Create logical port ls1-lp1 in ls1
3332 ovn-nbctl lsp-add ls1 ls1-lp1 \
3333 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3335 # Create logical port ls1-lp2 in ls1
3336 ovn-nbctl lsp-add ls1 ls1-lp2 \
3337 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3339 # Create one hypervisor and create OVS ports corresponding to logical ports.
3344 ovs-vsctl add-br br-phys
3345 ovn_attach n1 br-phys 192.168.0.1
3346 ovs-vsctl -- add-port br-int vif1 -- \
3347 set interface vif1 external-ids:iface-id=ls1-lp1 \
3348 options:tx_pcap=hv1/vif1-tx.pcap \
3349 options:rxq_pcap=hv1/vif1-rx.pcap \
3352 ovs-vsctl -- add-port br-int vif2 -- \
3353 set interface vif2 external-ids:iface-id=ls1-lp2 \
3354 options:tx_pcap=hv1/vif2-tx.pcap \
3355 options:rxq_pcap=hv1/vif2-rx.pcap \
3359 # Allow some time for ovn-northd and ovn-controller to catch up.
3360 # XXX This should be more systematic.
3363 # Send ip packets between the two ports.
3365 printf "%02x%02x%02x%02x" "$@"
3369 src_mac="f00000010203"
3370 dst_mac="000000010203"
3371 src_ip=`ip_to_hex 192 168 1 2`
3372 dst_ip=`ip_to_hex 172 16 1 2`
3373 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3374 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3377 echo "---------NB dump-----"
3379 echo "---------------------"
3380 ovn-nbctl list logical_router
3381 echo "---------------------"
3382 ovn-nbctl list logical_router_port
3383 echo "---------------------"
3385 echo "---------SB dump-----"
3386 ovn-sbctl list datapath_binding
3387 echo "---------------------"
3388 ovn-sbctl list logical_flow
3389 echo "---------------------"
3391 echo "------ hv1 dump ----------"
3392 as hv1 ovs-ofctl dump-flows br-int
3396 ovn-nbctl set Logical_Router R1 enabled=false
3398 # Allow some time for ovn-northd and ovn-controller to catch up.
3399 # XXX This should be more systematic.
3402 echo "---------SB dump-----"
3403 ovn-sbctl list datapath_binding
3404 echo "---------------------"
3405 ovn-sbctl list logical_flow
3406 echo "---------------------"
3408 echo "------ hv1 dump ----------"
3409 as hv1 ovs-ofctl dump-flows br-int
3411 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3414 expect_src_mac="000000010203"
3415 expect_dst_mac="f00000010204"
3416 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3418 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3422 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3423 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3424 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3427 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3430 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3433 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3436 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3437 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3442 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3443 AT_KEYWORDS([router-admin-state])
3444 AT_SKIP_IF([test $HAVE_PYTHON = no])
3448 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3449 # and has switch ls2 (172.16.1.0/24) connected to it.
3453 ovn-nbctl ls-add ls1
3454 ovn-nbctl ls-add ls2
3457 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3458 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3459 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3462 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3463 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3464 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3466 # Create logical port ls1-lp1 in ls1
3467 ovn-nbctl lsp-add ls1 ls1-lp1 \
3468 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3470 # Create logical port ls2-lp1 in ls2
3471 ovn-nbctl lsp-add ls2 ls2-lp1 \
3472 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3474 # Create one hypervisor and create OVS ports corresponding to logical ports.
3479 ovs-vsctl add-br br-phys
3480 ovn_attach n1 br-phys 192.168.0.1
3481 ovs-vsctl -- add-port br-int vif1 -- \
3482 set interface vif1 external-ids:iface-id=ls1-lp1 \
3483 options:tx_pcap=hv1/vif1-tx.pcap \
3484 options:rxq_pcap=hv1/vif1-rx.pcap \
3487 ovs-vsctl -- add-port br-int vif2 -- \
3488 set interface vif2 external-ids:iface-id=ls2-lp1 \
3489 options:tx_pcap=hv1/vif2-tx.pcap \
3490 options:rxq_pcap=hv1/vif2-rx.pcap \
3494 # Allow some time for ovn-northd and ovn-controller to catch up.
3495 # XXX This should be more systematic.
3498 # Send ip packets between the two ports.
3500 printf "%02x%02x%02x%02x" "$@"
3504 src_mac="f00000010203"
3505 dst_mac="000000010203"
3506 src_ip=`ip_to_hex 192 168 1 2`
3507 dst_ip=`ip_to_hex 172 16 1 2`
3508 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3509 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3512 echo "---------NB dump-----"
3514 echo "---------------------"
3515 ovn-nbctl list logical_router
3516 echo "---------------------"
3517 ovn-nbctl list logical_router_port
3518 echo "---------------------"
3520 echo "---------SB dump-----"
3521 ovn-sbctl list datapath_binding
3522 echo "---------------------"
3523 ovn-sbctl list logical_flow
3524 echo "---------------------"
3526 echo "------ hv1 dump ----------"
3527 as hv1 ovs-ofctl dump-flows br-int
3530 ovn-nbctl set Logical_Router R1 enabled=false
3532 echo "---------SB dump-----"
3533 ovn-sbctl list datapath_binding
3534 echo "---------------------"
3535 ovn-sbctl list logical_flow
3536 echo "---------------------"
3538 echo "------ hv1 dump ----------"
3539 as hv1 ovs-ofctl dump-flows br-int
3541 # Allow some time for the disabling of logical router R1 to propagate.
3542 # XXX This should be more systematic.
3545 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3548 expect_src_mac="000000010204"
3549 expect_dst_mac="f00000010204"
3550 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3552 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3558 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3559 AT_SKIP_IF([test $HAVE_PYTHON = no])
3563 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3564 # network. R1 has switchess foo (192.168.1.0/24)
3566 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3571 ovn-nbctl ls-add foo
3572 ovn-nbctl ls-add alice
3573 ovn-nbctl ls-add bob
3576 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3577 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3578 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3580 # Connect alice to R2
3581 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3582 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3583 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3586 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3587 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3588 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3591 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3592 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3594 #install static routes
3595 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3596 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3597 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3599 # Create logical port foo1 in foo
3600 ovn-nbctl lsp-add foo foo1 \
3601 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3603 # Create logical port alice1 in alice
3604 ovn-nbctl lsp-add alice alice1 \
3605 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3607 # Create logical port bob1 in bob
3608 ovn-nbctl lsp-add bob bob1 \
3609 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3611 # Create two hypervisor and create OVS ports corresponding to logical ports.
3616 ovs-vsctl add-br br-phys
3617 ovn_attach n1 br-phys 192.168.0.1
3618 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3619 set interface hv1-vif1 external-ids:iface-id=foo1 \
3620 options:tx_pcap=hv1/vif1-tx.pcap \
3621 options:rxq_pcap=hv1/vif1-rx.pcap \
3624 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3625 set interface hv1-vif2 external-ids:iface-id=alice1 \
3626 options:tx_pcap=hv1/vif2-tx.pcap \
3627 options:rxq_pcap=hv1/vif2-rx.pcap \
3632 ovs-vsctl add-br br-phys
3633 ovn_attach n1 br-phys 192.168.0.2
3634 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3635 set interface hv2-vif1 external-ids:iface-id=bob1 \
3636 options:tx_pcap=hv2/vif1-tx.pcap \
3637 options:rxq_pcap=hv2/vif1-rx.pcap \
3641 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3642 # packets for ARP resolution (native tunneling doesn't queue packets
3643 # for ARP resolution).
3646 # Allow some time for ovn-northd and ovn-controller to catch up.
3647 # XXX This should be more systematic.
3651 printf "%02x%02x%02x%02x" "$@"
3654 # Send ip packets between foo1 and alice1
3655 src_mac="f00000010203"
3656 dst_mac="000000010203"
3657 src_ip=`ip_to_hex 192 168 1 2`
3658 dst_ip=`ip_to_hex 172 16 1 2`
3659 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3660 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3662 # Send ip packets between foo1 and bob1
3663 src_mac="f00000010203"
3664 dst_mac="000000010203"
3665 src_ip=`ip_to_hex 192 168 1 2`
3666 dst_ip=`ip_to_hex 172 16 2 2`
3667 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3668 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3670 echo "---------NB dump-----"
3672 echo "---------------------"
3673 ovn-nbctl list logical_router
3674 echo "---------------------"
3675 ovn-nbctl list logical_router_port
3676 echo "---------------------"
3678 echo "---------SB dump-----"
3679 ovn-sbctl list datapath_binding
3680 echo "---------------------"
3681 ovn-sbctl list port_binding
3682 echo "---------------------"
3684 echo "------ hv1 dump ----------"
3685 as hv1 ovs-ofctl dump-flows br-int
3686 echo "------ hv2 dump ----------"
3687 as hv2 ovs-ofctl dump-flows br-int
3689 # Packet to Expect at bob1
3690 src_mac="000000010205"
3691 dst_mac="f00000010205"
3692 src_ip=`ip_to_hex 192 168 1 2`
3693 dst_ip=`ip_to_hex 172 16 2 2`
3694 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3696 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3698 # Packet to Expect at alice1
3699 src_mac="000000010204"
3700 dst_mac="f00000010204"
3701 src_ip=`ip_to_hex 192 168 1 2`
3702 dst_ip=`ip_to_hex 172 16 1 2`
3703 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3705 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3707 OVN_CLEANUP([hv1],[hv2])
3711 AT_SETUP([ovn -- send gratuitous arp on localnet])
3712 AT_SKIP_IF([test $HAVE_PYTHON = no])
3714 ovn-nbctl ls-add lsw0
3722 ovn_attach n1 br-phys 192.168.0.1
3724 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3725 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])
3728 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3729 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3730 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3732 # Create a localnet port.
3733 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3734 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3735 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3736 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3738 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3740 # Wait for packet to be received.
3741 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3742 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3744 # Check GARP packet when restart openflow connection.
3746 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3748 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3751 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3753 # Wait for packet to be received.
3754 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3755 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3757 # Delete the localnet ports.
3758 AT_CHECK([ovs-vsctl del-port localvif1])
3759 AT_CHECK([ovn-nbctl lsp-del ln_port])
3765 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3766 AT_SKIP_IF([test $HAVE_PYTHON = no])
3770 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3771 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3772 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3779 ovn-nbctl ls-add foo
3780 ovn-nbctl ls-add alice
3781 ovn-nbctl ls-add bob
3782 ovn-nbctl ls-add join
3785 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3786 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3787 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3789 # Connect alice to R2
3790 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3791 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3792 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3795 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3796 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3797 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3799 # Connect R1 to join
3800 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3801 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3802 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3804 # Connect R2 to join
3805 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3806 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3807 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3809 # Connect R3 to join
3810 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3811 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3812 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3814 #install static routes
3815 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3816 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3818 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3819 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3821 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3822 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3824 # Create logical port foo1 in foo
3825 ovn-nbctl lsp-add foo foo1 \
3826 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3828 # Create logical port alice1 in alice
3829 ovn-nbctl lsp-add alice alice1 \
3830 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3832 # Create logical port bob1 in bob
3833 ovn-nbctl lsp-add bob bob1 \
3834 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3836 # Create two hypervisor and create OVS ports corresponding to logical ports.
3841 ovs-vsctl add-br br-phys
3842 ovn_attach n1 br-phys 192.168.0.1
3843 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3844 set interface hv1-vif1 external-ids:iface-id=foo1 \
3845 options:tx_pcap=hv1/vif1-tx.pcap \
3846 options:rxq_pcap=hv1/vif1-rx.pcap \
3849 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3850 set interface hv1-vif2 external-ids:iface-id=alice1 \
3851 options:tx_pcap=hv1/vif2-tx.pcap \
3852 options:rxq_pcap=hv1/vif2-rx.pcap \
3857 ovs-vsctl add-br br-phys
3858 ovn_attach n1 br-phys 192.168.0.2
3859 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3860 set interface hv2-vif1 external-ids:iface-id=bob1 \
3861 options:tx_pcap=hv2/vif1-tx.pcap \
3862 options:rxq_pcap=hv2/vif1-rx.pcap \
3866 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3867 # packets for ARP resolution (native tunneling doesn't queue packets
3868 # for ARP resolution).
3871 # Allow some time for ovn-northd and ovn-controller to catch up.
3872 # XXX This should be more systematic.
3876 printf "%02x%02x%02x%02x" "$@"
3879 # Send ip packets between foo1 and alice1
3880 src_mac="f00000010203"
3881 dst_mac="000001010203"
3882 src_ip=`ip_to_hex 192 168 1 2`
3883 dst_ip=`ip_to_hex 172 16 1 2`
3884 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3885 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3886 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3888 # Send ip packets between foo1 and bob1
3889 src_mac="f00000010203"
3890 dst_mac="000001010203"
3891 src_ip=`ip_to_hex 192 168 1 2`
3892 dst_ip=`ip_to_hex 10 32 1 2`
3893 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3894 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3896 echo "---------NB dump-----"
3898 echo "---------------------"
3899 ovn-nbctl list logical_router
3900 echo "---------------------"
3901 ovn-nbctl list logical_router_port
3902 echo "---------------------"
3904 echo "---------SB dump-----"
3905 ovn-sbctl list datapath_binding
3906 echo "---------------------"
3907 ovn-sbctl list port_binding
3908 echo "---------------------"
3909 ovn-sbctl dump-flows
3910 echo "---------------------"
3912 echo "------ hv1 dump ----------"
3913 as hv1 ovs-ofctl show br-int
3914 as hv1 ovs-ofctl dump-flows br-int
3915 echo "------ hv2 dump ----------"
3916 as hv2 ovs-ofctl show br-int
3917 as hv2 ovs-ofctl dump-flows br-int
3918 echo "----------------------------"
3920 # Packet to Expect at bob1
3921 src_mac="000003010203"
3922 dst_mac="f00000010205"
3923 src_ip=`ip_to_hex 192 168 1 2`
3924 dst_ip=`ip_to_hex 10 32 1 2`
3925 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3927 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3929 # Packet to Expect at alice1
3930 src_mac="000002010203"
3931 dst_mac="f00000010204"
3932 src_ip=`ip_to_hex 192 168 1 2`
3933 dst_ip=`ip_to_hex 172 16 1 2`
3934 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3936 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3938 OVN_CLEANUP([hv1],[hv2])
3942 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3943 AT_SKIP_IF([test $HAVE_PYTHON = no])
3946 ovn-nbctl ls-add ls1
3948 ovn-nbctl lsp-add ls1 ls1-lp1 \
3949 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3951 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3953 ovn-nbctl lsp-add ls1 ls1-lp2 \
3954 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3956 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3958 ovn-nbctl ls-add ls2
3959 ovn-nbctl lsp-add ls2 ls2-lp1 \
3960 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3961 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3962 ovn-nbctl lsp-add ls2 ls2-lp2 \
3963 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3964 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3966 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3967 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3968 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3970 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3971 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3973 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3974 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3975 \"lease_time\"=\"3600\"")"
3977 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3983 ovs-vsctl add-br br-phys
3984 ovn_attach n1 br-phys 192.168.0.1
3985 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3986 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3987 options:tx_pcap=hv1/vif1-tx.pcap \
3988 options:rxq_pcap=hv1/vif1-rx.pcap \
3991 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3992 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3993 options:tx_pcap=hv1/vif2-tx.pcap \
3994 options:rxq_pcap=hv1/vif2-rx.pcap \
3997 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3998 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3999 options:tx_pcap=hv1/vif3-tx.pcap \
4000 options:rxq_pcap=hv1/vif3-rx.pcap \
4003 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4004 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4005 options:tx_pcap=hv1/vif4-tx.pcap \
4006 options:rxq_pcap=hv1/vif4-rx.pcap \
4013 as hv1 ovs-vsctl show
4015 # This shell function sends a DHCP request packet
4016 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4018 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4019 shift; shift; shift; shift; shift;
4020 if test $use_ip != 0; then
4025 src_ip=`ip_to_hex 0 0 0 0`
4026 dst_ip=`ip_to_hex 255 255 255 255`
4028 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
4029 # udp header and dhcp header
4030 request=${request}0044004300fc0000
4031 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
4032 # client hardware padding
4033 request=${request}00000000000000000000
4035 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4036 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4038 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4039 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4040 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4041 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4043 request=${request}63825363
4045 request=${request}3501${dhcp_type}ff
4047 if test $offer_ip != 0; then
4048 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
4049 # total IP length will be the IP length of the request packet
4050 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4051 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4052 udp_len=`expr $ip_len - 20`
4053 ip_len=$(printf "%x" $ip_len)
4054 udp_len=$(printf "%x" $udp_len)
4055 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4056 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4057 # udp header and dhcp header.
4058 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4059 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
4061 reply=${reply}${offer_ip}
4062 # next server ip address, relay agent ip address, client mac address
4063 reply=${reply}0000000000000000${src_mac}
4064 # client hardware padding
4065 reply=${reply}00000000000000000000
4067 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4068 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4070 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4071 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4072 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4073 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4075 reply=${reply}63825363
4077 local dhcp_reply_type=02
4078 if test $dhcp_type = 03; then
4081 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4082 echo $reply >> $inport.expected
4085 echo $request >> $outport.expected
4088 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4094 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4095 options:rxq_pcap=dummy-rx.pcap
4096 rm -f ${pcap_file}*.pcap
4097 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4098 options:rxq_pcap=${pcap_file}-rx.pcap
4102 printf "%02x%02x%02x%02x" "$@"
4105 AT_CAPTURE_FILE([ofctl_monitor0.log])
4106 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4107 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4109 echo "---------NB dump-----"
4111 echo "---------------------"
4112 echo "---------SB dump-----"
4113 ovn-sbctl list datapath_binding
4114 echo "---------------------"
4115 ovn-sbctl list logical_flow
4116 echo "---------------------"
4118 echo "---------------------"
4119 ovn-sbctl dump-flows
4120 echo "---------------------"
4122 echo "------ hv1 dump ----------"
4123 as hv1 ovs-ofctl dump-flows br-int
4125 # Send DHCPDISCOVER.
4126 offer_ip=`ip_to_hex 10 0 0 4`
4127 server_ip=`ip_to_hex 10 0 0 1`
4128 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4129 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4131 # NXT_RESUMEs should be 1.
4132 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4134 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4135 cat 1.expected | cut -c -48 > expout
4136 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4137 # Skipping the IPv4 checksum.
4138 cat 1.expected | cut -c 53- > expout
4139 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4141 # ovs-ofctl also resumes the packets and this causes other ports to receive
4142 # the DHCP request packet. So reset the pcap files so that its easier to test.
4143 reset_pcap_file hv1-vif1 hv1/vif1
4144 reset_pcap_file hv1-vif2 hv1/vif2
4149 offer_ip=`ip_to_hex 10 0 0 6`
4150 server_ip=`ip_to_hex 10 0 0 1`
4151 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4152 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4154 # NXT_RESUMEs should be 2.
4155 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4157 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4158 cat 2.expected | cut -c -48 > expout
4159 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4160 # Skipping the IPv4 checksum.
4161 cat 2.expected | cut -c 53- > expout
4162 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4164 reset_pcap_file hv1-vif1 hv1/vif1
4165 reset_pcap_file hv1-vif2 hv1/vif2
4169 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4170 # but should be resumed without the reply.
4171 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4172 # one from ovn-controller and the other from "ovs-ofctl resume."
4174 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4176 # NXT_RESUMEs should be 3.
4177 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4179 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4180 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4182 reset_pcap_file hv1-vif1 hv1/vif1
4183 reset_pcap_file hv1-vif2 hv1/vif2
4187 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4188 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4190 test_dhcp 3 f00000000003 01 0 4 0
4192 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4194 test_dhcp 4 f00000000004 01 0 3 0
4196 # NXT_RESUMEs should be 3.
4197 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4199 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4200 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4202 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4203 offer_ip=`ip_to_hex 10 0 0 6`
4204 server_ip=`ip_to_hex 10 0 0 1`
4205 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4208 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4210 # NXT_RESUMEs should be 4.
4211 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4213 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4214 cat 2.expected | cut -c -48 > expout
4215 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4216 # Skipping the IPv4 checksum.
4217 cat 2.expected | cut -c 53- > expout
4218 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4220 reset_pcap_file hv1-vif1 hv1/vif1
4221 reset_pcap_file hv1-vif2 hv1/vif2
4225 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4226 offer_ip=`ip_to_hex 10 0 0 6`
4227 server_ip=`ip_to_hex 10 0 0 1`
4228 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4230 dst_ip=`ip_to_hex 255 255 255 255`
4231 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4233 # NXT_RESUMEs should be 5.
4234 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4236 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4237 cat 2.expected | cut -c -48 > expout
4238 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4239 # Skipping the IPv4 checksum.
4240 cat 2.expected | cut -c 53- > expout
4241 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4243 reset_pcap_file hv1-vif1 hv1/vif1
4244 reset_pcap_file hv1-vif2 hv1/vif2
4248 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4249 # The packet should not be received by ovn-controller.
4250 src_ip=`ip_to_hex 10 0 0 6`
4251 dst_ip=`ip_to_hex 10 0 0 4`
4252 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4254 # NXT_RESUMEs should be 5.
4255 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4257 # vif1-tx.pcap should have received the DHCPv4 request packet
4258 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4261 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4262 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4263 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4266 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4269 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4272 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4275 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4276 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4280 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4281 AT_SKIP_IF([test $HAVE_PYTHON = no])
4284 ovn-nbctl ls-add ls1
4285 ovn-nbctl lsp-add ls1 ls1-lp1 \
4286 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4288 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4290 ovn-nbctl lsp-add ls1 ls1-lp2 \
4291 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4293 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4295 ovn-nbctl lsp-add ls1 ls1-lp3 \
4296 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4298 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4300 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4301 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4303 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4304 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4306 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4307 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4309 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4311 ovn-nbctl ls-add ls2
4312 ovn-nbctl lsp-add ls2 ls2-lp1 \
4313 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4314 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4315 ovn-nbctl lsp-add ls2 ls2-lp2 \
4316 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4317 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4323 ovs-vsctl add-br br-phys
4324 ovn_attach n1 br-phys 192.168.0.1
4325 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4326 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4327 options:tx_pcap=hv1/vif1-tx.pcap \
4328 options:rxq_pcap=hv1/vif1-rx.pcap \
4331 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4332 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4333 options:tx_pcap=hv1/vif2-tx.pcap \
4334 options:rxq_pcap=hv1/vif2-rx.pcap \
4337 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4338 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4339 options:tx_pcap=hv1/vif3-tx.pcap \
4340 options:rxq_pcap=hv1/vif3-rx.pcap \
4343 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4344 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4345 options:tx_pcap=hv1/vif4-tx.pcap \
4346 options:rxq_pcap=hv1/vif4-rx.pcap \
4349 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4350 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4351 options:tx_pcap=hv1/vif5-tx.pcap \
4352 options:rxq_pcap=hv1/vif5-rx.pcap \
4360 sed 's/\(00\)\{1,\}$//'
4363 # This shell function sends a DHCPv6 request packet
4364 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4365 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4366 # packet should be received twice (one from ovn-controller and the other
4367 # from the "ovs-ofctl monitor br-int resume"
4369 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4370 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4372 request=${request}ff020000000000000000000000010002
4373 # udp header and dhcpv6 header
4374 request=${request}02220223002affff${msg_code}010203
4376 request=${request}0001000a00030001${src_mac}
4377 # IA-NA (Identity Association for Non Temporary Address)
4378 request=${request}0003000c0102030400000e1000001518
4379 shift; shift; shift; shift; shift;
4380 if test $offer_ip != 0; then
4381 local server_mac=000000100001
4382 local server_lla=fe80000000000000020000fffe100001
4384 if test $msg_code = 01; then
4388 if test $offer_ip = 1; then
4391 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4392 # udp header and dhcpv6 header
4393 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4395 reply=${reply}0001000a00030001${src_mac}
4397 if test $offer_ip != 1; then
4398 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4401 reply=${reply}0002000a00030001${server_mac}
4402 echo $reply | trim_zeros >> $inport.expected
4405 echo $request | trim_zeros >> $outport.expected
4409 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4415 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4416 options:rxq_pcap=dummy-rx.pcap
4417 rm -f ${pcap_file}*.pcap
4418 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4419 options:rxq_pcap=${pcap_file}-rx.pcap
4422 AT_CAPTURE_FILE([ofctl_monitor0.log])
4423 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4424 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4426 echo "---------NB dump-----"
4428 echo "---------------------"
4429 echo "---------SB dump-----"
4430 ovn-sbctl list datapath_binding
4431 echo "---------------------"
4432 ovn-sbctl list logical_flow
4433 echo "---------------------"
4435 echo "---------------------"
4436 ovn-sbctl dump-flows
4437 echo "---------------------"
4439 echo "------ hv1 dump ----------"
4440 as hv1 ovs-ofctl dump-flows br-int
4442 src_mac=f00000000001
4443 src_lla=fe80000000000000f20000fffe000001
4444 offer_ip=ae700000000000000000000000000004
4445 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4447 # NXT_RESUMEs should be 1.
4448 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4450 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4451 # cat 1.expected | trim_zeros > expout
4452 cat 1.expected | cut -c -120 > expout
4453 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4454 # Skipping the UDP checksum
4455 cat 1.expected | cut -c 125- > expout
4456 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4460 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4461 # without any modifications and the packet should be received by ls1-lp1.
4462 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4463 # resume and the other from ovs-ofctl monitor resume.
4465 reset_pcap_file hv1-vif1 hv1/vif1
4466 reset_pcap_file hv1-vif2 hv1/vif2
4468 src_mac=f00000000002
4469 src_lla=fe80000000000000f20000fffe000002
4470 offer_ip=ae700000000000000000000000000005
4471 # Set invalid msg_type
4473 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4475 # NXT_RESUMEs should be 2.
4476 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4478 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4480 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4481 AT_CHECK([cat 2.packets], [0], [])
4483 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4484 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4485 cat 1.expected > expout
4486 AT_CHECK([cat 1.packets], [0], [expout])
4488 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4489 # There should be no DHCPv6 reply from ovn-controller and the request packet
4490 # should be received by ls2-lp2.
4492 src_mac=f00000000003
4493 src_lla=fe80000000000000f20000fffe000003
4494 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4496 # NXT_RESUMEs should be 2 only.
4497 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4499 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4500 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4501 AT_CHECK([cat 3.packets], [0], [])
4503 # vif4-tx.pcap should have received the DHCPv6 request packet
4504 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4505 cat 4.expected > expout
4506 AT_CHECK([cat 4.packets], [0], [expout])
4508 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4509 # The DHCPv6 reply should doesn't contian offer_ip.
4510 src_mac=f00000000022
4511 src_lla=fe80000000000000f20000fffe000022
4512 reset_pcap_file hv1-vif5 hv1/vif5
4513 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4515 # NXT_RESUMEs should be 3.
4516 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4518 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4519 # Skipping the UDP checksum
4520 cat 5.expected | cut -c 1-120,125- > expout
4521 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4524 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4525 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4526 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4529 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4532 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4535 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4538 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4539 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4543 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4544 AT_SKIP_IF([test $HAVE_PYTHON = no])
4548 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4549 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4550 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4551 # R2 is a gateway router.
4555 # Create two hypervisor and create OVS ports corresponding to logical ports.
4560 ovs-vsctl add-br br-phys
4561 ovn_attach n1 br-phys 192.168.0.1
4562 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4563 set interface hv1-vif1 external-ids:iface-id=foo1 \
4564 options:tx_pcap=hv1/vif1-tx.pcap \
4565 options:rxq_pcap=hv1/vif1-rx.pcap \
4571 ovs-vsctl add-br br-phys
4572 ovn_attach n1 br-phys 192.168.0.2
4573 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4574 set interface hv2-vif1 external-ids:iface-id=alice1 \
4575 options:tx_pcap=hv2/vif1-tx.pcap \
4576 options:rxq_pcap=hv2/vif1-rx.pcap \
4579 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4580 # packets for ARP resolution (native tunneling doesn't queue packets
4581 # for ARP resolution).
4584 ovn-nbctl create Logical_Router name=R1
4585 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4587 ovn-nbctl ls-add foo
4588 ovn-nbctl ls-add alice
4589 ovn-nbctl ls-add join
4592 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4593 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4594 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4596 # Connect alice to R2
4597 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4598 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4599 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4601 # Connect R1 to join
4602 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4603 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4604 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4606 # Connect R2 to join
4607 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4608 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4609 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4612 #install static routes
4613 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4614 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4615 R1 static_routes @lrt
4617 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4618 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4619 R2 static_routes @lrt
4621 # Create logical port foo1 in foo
4622 ovn-nbctl lsp-add foo foo1 \
4623 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4625 # Create logical port alice1 in alice
4626 ovn-nbctl lsp-add alice alice1 \
4627 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4630 # Allow some time for ovn-northd and ovn-controller to catch up.
4631 # XXX This should be more systematic.
4635 printf "%02x%02x%02x%02x" "$@"
4638 # Send ip packets between foo1 and alice1
4639 src_mac="f00000010203"
4640 dst_mac="000001010203"
4641 src_ip=`ip_to_hex 192 168 1 2`
4642 dst_ip=`ip_to_hex 172 16 1 2`
4643 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4645 echo "---------NB dump-----"
4647 echo "---------------------"
4648 ovn-nbctl list logical_router
4649 echo "---------------------"
4650 ovn-nbctl list logical_router_port
4651 echo "---------------------"
4653 echo "---------SB dump-----"
4654 ovn-sbctl list datapath_binding
4655 echo "---------------------"
4656 ovn-sbctl list port_binding
4657 echo "---------------------"
4658 ovn-sbctl dump-flows
4659 echo "---------------------"
4660 ovn-sbctl list chassis
4661 ovn-sbctl list encap
4662 echo "---------------------"
4664 # Packet to Expect at alice1
4665 src_mac="000002010203"
4666 dst_mac="f00000010204"
4667 src_ip=`ip_to_hex 192 168 1 2`
4668 dst_ip=`ip_to_hex 172 16 1 2`
4669 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4672 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4673 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4675 echo "------ hv1 dump after packet 1 ----------"
4676 as hv1 ovs-ofctl show br-int
4677 as hv1 ovs-ofctl dump-flows br-int
4678 echo "------ hv2 dump after packet 1 ----------"
4679 as hv2 ovs-ofctl show br-int
4680 as hv2 ovs-ofctl dump-flows br-int
4681 echo "----------------------------"
4683 echo $expected > expected
4684 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4686 # Delete the router and re-create it. Things should work as before.
4688 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4689 # Connect alice to R2
4690 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4691 # Connect R2 to join
4692 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4694 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4695 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4696 R2 static_routes @lrt
4698 # Wait for ovn-controller to catch up.
4701 # Send the packet again.
4702 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4704 echo "------ hv1 dump after packet 2 ----------"
4705 as hv1 ovs-ofctl show br-int
4706 as hv1 ovs-ofctl dump-flows br-int
4707 echo "------ hv2 dump after packet 2 ----------"
4708 as hv2 ovs-ofctl show br-int
4709 as hv2 ovs-ofctl dump-flows br-int
4710 echo "----------------------------"
4712 echo $expected >> expected
4713 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4715 OVN_CLEANUP([hv1],[hv2])
4719 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4720 AT_KEYWORDS([router-icmp-reply])
4721 AT_SKIP_IF([test $HAVE_PYTHON = no])
4725 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4726 # and has switch ls2 (172.16.1.0/24) connected to it.
4730 ovn-nbctl ls-add ls1
4731 ovn-nbctl ls-add ls2
4734 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4735 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4736 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4739 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4740 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4741 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4743 # Create logical port ls1-lp1 in ls1
4744 ovn-nbctl lsp-add ls1 ls1-lp1 \
4745 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4747 # Create logical port ls2-lp1 in ls2
4748 ovn-nbctl lsp-add ls2 ls2-lp1 \
4749 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4751 # Create one hypervisor and create OVS ports corresponding to logical ports.
4756 ovs-vsctl add-br br-phys
4757 ovn_attach n1 br-phys 192.168.0.1
4758 ovs-vsctl -- add-port br-int vif1 -- \
4759 set interface vif1 external-ids:iface-id=ls1-lp1 \
4760 options:tx_pcap=hv1/vif1-tx.pcap \
4761 options:rxq_pcap=hv1/vif1-rx.pcap \
4764 ovs-vsctl -- add-port br-int vif2 -- \
4765 set interface vif2 external-ids:iface-id=ls2-lp1 \
4766 options:tx_pcap=hv1/vif2-tx.pcap \
4767 options:rxq_pcap=hv1/vif2-rx.pcap \
4771 # Allow some time for ovn-northd and ovn-controller to catch up.
4772 # XXX This should be more systematic.
4777 printf "%02x%02x%02x%02x" "$@"
4782 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4784 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4785 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4786 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4787 # provided, then it should be the ip and icmp checksums of the packet
4788 # responded; otherwise, no reply is expected.
4789 # In the absence of an ip checksum calculation helpers, this relies
4790 # on the caller to provide the checksums for the ip and icmp headers.
4791 # XXX This should be more systematic.
4793 # INPORT is an lport number, e.g. 11 for vif11.
4794 # ETH_SRC and ETH_DST are each 12 hex digits.
4795 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4796 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4797 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4798 test_ipv4_icmp_request() {
4799 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4800 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4801 shift; shift; shift; shift; shift; shift; shift
4804 # Use ttl to exercise section 4.2.2.9 of RFC1812
4808 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4809 local icmp_type_code_request=0800
4810 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4811 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4813 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4814 if test X$exp_icmp_chksum != X; then
4815 # Expect to receive the reply, if any. In same port where packet was sent.
4816 # Note: src and dst fields are expected to be reversed.
4817 local icmp_type_code_response=0000
4818 local reply_icmp_ttl=fe
4819 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4820 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4821 echo $reply >> vif$inport.expected
4825 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4826 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4827 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4828 l1_ip=$(ip_to_hex 192 168 1 2)
4829 l2_ip=$(ip_to_hex 172 16 1 2)
4831 # Ping router ip address that is on same subnet as the logical port
4832 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4833 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4835 # Ping router ip address that is on the other side of the logical ports
4836 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4837 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4839 echo "---------NB dump-----"
4841 echo "---------------------"
4842 ovn-nbctl list logical_router
4843 echo "---------------------"
4844 ovn-nbctl list logical_router_port
4845 echo "---------------------"
4847 echo "---------SB dump-----"
4848 ovn-sbctl list datapath_binding
4849 echo "---------------------"
4850 ovn-sbctl list logical_flow
4851 echo "---------------------"
4853 echo "------ hv1 dump ----------"
4854 as hv1 ovs-ofctl dump-flows br-int
4856 # Now check the packets actually received against the ones expected.
4857 for inport in 1 2; do
4858 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4865 # 1 hypervisor, 1 port
4866 # make sure that the port state is properly set to up and back down
4867 # when created and deleted.
4868 AT_SETUP([ovn -- port state up and down])
4871 ovn-nbctl ls-add ls1
4872 ovn-nbctl lsp-add ls1 lp1
4873 ovn-nbctl lsp-set-addresses lp1 unknown
4877 as hv1 ovs-vsctl add-br br-phys
4878 as hv1 ovn_attach n1 br-phys 192.168.0.1
4880 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4881 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4883 as hv1 ovs-vsctl del-port br-int vif1
4884 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4890 # 1 hypervisor, 1 port
4891 # make sure that the OF rules created to support a datapath are added/cleared
4892 # when logical switch is created and removed.
4893 AT_SETUP([ovn -- datapath rules added/removed])
4894 AT_KEYWORDS([cleanup])
4899 as hv1 ovs-vsctl add-br br-phys
4900 as hv1 ovn_attach n1 br-phys 192.168.0.1
4902 # This shell function checks if OF rules in br-int have clauses
4903 # related to OVN datapaths. The caller determines if it should find
4904 # a match in the output, or not.
4906 # EXPECT_DATAPATH param determines whether flows that refer to
4907 # datapath to should be present or not. 0 means
4908 # they should not be.
4909 # STAGE_INFO param is a simple string to help identify the stage
4910 # in the test when this function was invoked.
4911 test_datapath_in_of_rules() {
4912 local expect_datapath=$1 stage_info=$2
4913 echo "------ ovn-nbctl show ${stage_info} ------"
4915 echo "------ ovn-sbctl show ${stage_info} ------"
4917 echo "------ OF rules ${stage_info} ------"
4918 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4919 # if there is a datapath mentioned in the output, check for the
4920 # magic keyword that represents one, based on the exit status of
4922 if test $expect_datapath != 0; then
4923 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4925 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4929 test_datapath_in_of_rules 0 "before ls+port create"
4931 ovn-nbctl ls-add ls1
4932 ovn-nbctl lsp-add ls1 lp1
4933 ovn-nbctl lsp-set-addresses lp1 unknown
4935 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4936 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4938 test_datapath_in_of_rules 1 "after port is bound"
4940 as hv1 ovs-vsctl del-port br-int vif1
4941 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4943 ovn-nbctl lsp-set-addresses lp1
4944 ovn-nbctl lsp-del lp1
4945 ovn-nbctl ls-del ls1
4947 # wait for earlier changes to take effect
4948 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4950 # ensure OF rules are no longer present. There used to be a bug here.
4951 test_datapath_in_of_rules 0 "after lport+ls removal"
4957 AT_SETUP([ovn -- nd_na ])
4958 AT_SKIP_IF([test $HAVE_PYTHON = no])
4961 #TODO: since patch port for IPv6 logical router port is not ready not,
4962 # so we are not going to test vifs on different lswitches cases. Try
4963 # to update for that once relevant stuff implemented.
4965 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4966 # with. NS packet we test, from one VIF for another VIF, will be replied
4967 # by local ovn-controller, but not by target VIF.
4969 # Create hypervisors and logical switch lsw0.
4970 ovn-nbctl ls-add lsw0
4974 ovs-vsctl add-br br-phys
4975 ovn_attach n1 br-phys 192.168.0.2
4977 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4978 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
4979 ovn-nbctl lsp-add lsw0 lp1
4980 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4981 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"
4983 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4984 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
4985 ovn-nbctl lsp-add lsw0 lp2
4986 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4987 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"
4989 # Add ACL rule for ICMPv6 on lsw0
4990 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4991 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4992 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4994 # Allow some time for ovn-northd and ovn-controller to catch up.
4995 # XXX This should be more systematic.
4998 # Given the name of a logical port, prints the name of the hypervisor
4999 # on which it is located.
5007 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5008 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5009 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5010 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5011 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5013 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5014 echo $na_packet >> 1.expected
5016 echo "------ hv1 dump ------"
5017 as hv1 ovs-vsctl show
5018 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5019 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5022 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5029 AT_SETUP([ovn -- address sets modification/removal smoke test])
5036 ovs-vsctl add-br br-phys
5037 ovn_attach n1 br-phys 192.168.0.1
5039 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5040 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5041 ovn-nbctl destroy Address_Set $row
5045 # A bug previously existed in the address set support code
5046 # that caused ovn-controller to crash after an address set
5047 # was updated and then removed. This test case ensures
5048 # that ovn-controller is at least still running after
5049 # creating, updating, and deleting an address set.
5050 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5056 AT_SETUP([ovn -- ipam])
5057 AT_SKIP_IF([test $HAVE_PYTHON = no])
5060 # Add a port to a switch that does not have a subnet set, then set the
5061 # subnet which should result in an address being allocated for the port.
5062 ovn-nbctl ls-add sw0
5063 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5064 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5065 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5066 ["0a:00:00:00:00:01 192.168.1.2"
5069 # Add 9 more ports to sw0, addresses should all be unique.
5070 for n in `seq 1 9`; do
5071 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5073 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5074 ["0a:00:00:00:00:02 192.168.1.3"
5076 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5077 ["0a:00:00:00:00:03 192.168.1.4"
5079 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5080 ["0a:00:00:00:00:04 192.168.1.5"
5082 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5083 ["0a:00:00:00:00:05 192.168.1.6"
5085 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5086 ["0a:00:00:00:00:06 192.168.1.7"
5088 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5089 ["0a:00:00:00:00:07 192.168.1.8"
5091 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5092 ["0a:00:00:00:00:08 192.168.1.9"
5094 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5095 ["0a:00:00:00:00:09 192.168.1.10"
5097 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5098 ["0a:00:00:00:00:0a 192.168.1.11"
5101 # Trying similar tests with a second switch. MAC addresses should be unique
5102 # across both switches but IP's only need to be unique within the same switch.
5103 ovn-nbctl ls-add sw1
5104 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
5105 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
5106 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5107 ["0a:00:00:00:00:0b 192.168.1.2"
5110 for n in `seq 11 19`; do
5111 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
5113 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5114 ["0a:00:00:00:00:0c 192.168.1.3"
5116 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5117 ["0a:00:00:00:00:0d 192.168.1.4"
5119 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5120 ["0a:00:00:00:00:0e 192.168.1.5"
5122 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5123 ["0a:00:00:00:00:0f 192.168.1.6"
5125 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5126 ["0a:00:00:00:00:10 192.168.1.7"
5128 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5129 ["0a:00:00:00:00:11 192.168.1.8"
5131 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5132 ["0a:00:00:00:00:12 192.168.1.9"
5134 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5135 ["0a:00:00:00:00:13 192.168.1.10"
5137 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5138 ["0a:00:00:00:00:14 192.168.1.11"
5141 # Change a port's address to test for multiple ip's for a single address entry
5142 # and addresses set by the user.
5143 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
5144 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
5145 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5146 ["0a:00:00:00:00:16 192.168.1.13"
5149 # Test for logical router port address management.
5150 ovn-nbctl create Logical_Router name=R1
5151 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5152 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5153 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5154 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
5155 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
5156 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5157 ["0a:00:00:00:00:18 192.168.1.15"
5160 # Test for address reuse after logical port is deleted.
5161 ovn-nbctl lsp-del p0
5162 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
5163 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5164 ["0a:00:00:00:00:19 192.168.1.2"
5167 # Test for multiple addresses to one logical port.
5168 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5169 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
5170 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
5171 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5172 ["0a:00:00:00:00:1c 192.168.1.16"
5175 # Test for exhausting subnet address space.
5176 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
5177 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
5178 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5179 ["0a:00:00:00:00:1d 172.16.1.2"
5182 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
5183 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
5184 ["0a:00:00:00:00:1e"
5187 # Test that address management does not add duplicate MAC for lsp/lrp peers.
5188 ovn-nbctl create Logical_Router name=R2
5189 ovn-nbctl ls-add sw3
5190 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
5192 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5193 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5194 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5195 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
5196 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
5197 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5198 ["0a:00:00:00:00:20 192.168.1.17"
5201 # Test static MAC address with dynamically allocated IP
5202 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5203 "fe:dc:ba:98:76:54 dynamic"
5204 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5205 ["fe:dc:ba:98:76:54 192.168.1.18"
5208 # Update the static MAC address with dynamically allocated IP and check
5209 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5210 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5211 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5213 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5214 ["fe:dc:ba:98:76:55 192.168.1.18"
5217 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5218 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5219 ["fe:dc:ba:98:76:55 192.168.1.18"
5222 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5223 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5224 ["fe:dc:ba:98:76:56 192.168.1.18"
5228 # Test the exclude_ips from the IPAM list
5229 ovn-nbctl --wait=sb set logical_switch sw0 \
5230 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5232 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5234 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5235 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5236 ["0a:00:00:00:00:21 192.168.1.20"
5239 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5241 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5242 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5243 ["0a:00:00:00:00:22 192.168.1.22"
5246 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5248 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5249 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5250 ["0a:00:00:00:00:23 192.168.1.51"
5253 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5254 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5255 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5257 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5258 ["0a:00:00:00:00:24 192.168.1.19"
5261 # Set invalid data in exclude_ips list. It should be ignored.
5262 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5263 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5265 # 192.168.1.21 should be assigned as that's the next free one.
5266 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5267 ["0a:00:00:00:00:25 192.168.1.21"
5270 # Clear the dynamic addresses assignment request.
5271 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5272 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5277 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5278 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5281 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5282 # - aef0::800:ff:fe00:26 (EUI64)
5283 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5284 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5287 ovn-nbctl --wait=sb ls-add sw4
5288 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5289 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5292 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5293 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5296 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5297 "f0:00:00:00:10:12 dynamic"
5299 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5300 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5303 # Clear the other_config for sw4. No dynamic ip should be assigned.
5304 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5305 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5308 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5312 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5313 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5314 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5316 # Now p40 should be assigned with dynamic addresses.
5317 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5318 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5321 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5323 # p41 should not have IPv4 address (as the pool is exhausted).
5324 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5325 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5329 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5332 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5335 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5339 AT_SETUP([ovn -- ipam connectivity])
5340 AT_SKIP_IF([test $HAVE_PYTHON = no])
5345 # Test for a ping using dynamically allocated addresses.
5346 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5347 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5350 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5351 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5352 options:router-port=foo \
5353 -- lsp-set-addresses rp-foo router
5355 # Connect alice to R1
5356 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5357 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5358 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5360 # Create logical port foo1 in foo
5361 ovn-nbctl --wait=sb lsp-add foo foo1 \
5362 -- lsp-set-addresses foo1 "dynamic"
5363 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])
5365 # Create logical port alice1 in alice
5366 ovn-nbctl --wait=sb lsp-add alice alice1 \
5367 -- lsp-set-addresses alice1 "dynamic"
5368 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5370 # Create logical port foo2 in foo
5371 ovn-nbctl --wait=sb lsp-add foo foo2 \
5372 -- lsp-set-addresses foo2 "dynamic"
5373 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5375 # Create a hypervisor and create OVS ports corresponding to logical ports.
5380 ovs-vsctl add-br br-phys
5381 ovn_attach n1 br-phys 192.168.0.1
5382 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5383 set interface hv1-vif1 external-ids:iface-id=foo1 \
5384 options:tx_pcap=hv1/vif1-tx.pcap \
5385 options:rxq_pcap=hv1/vif1-rx.pcap \
5388 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5389 set interface hv1-vif2 external-ids:iface-id=foo2 \
5390 options:tx_pcap=hv1/vif2-tx.pcap \
5391 options:rxq_pcap=hv1/vif2-rx.pcap \
5394 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5395 set interface hv1-vif3 external-ids:iface-id=alice1 \
5396 options:tx_pcap=hv1/vif3-tx.pcap \
5397 options:rxq_pcap=hv1/vif3-rx.pcap \
5400 # Allow some time for ovn-northd and ovn-controller to catch up.
5401 # XXX This should be more systematic.
5405 printf "%02x%02x%02x%02x" "$@"
5408 # Send ip packets between foo1 and foo2
5409 src_mac="0a0000000001"
5410 dst_mac="0a0000000003"
5411 src_ip=`ip_to_hex 192 168 1 2`
5412 dst_ip=`ip_to_hex 192 168 1 3`
5413 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5414 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5416 # Send ip packets between foo1 and alice1
5417 src_mac="0a0000000001"
5418 dst_mac="000000010203"
5419 src_ip=`ip_to_hex 192 168 1 2`
5420 dst_ip=`ip_to_hex 192 168 2 2`
5421 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5422 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5424 echo "---------NB dump-----"
5426 echo "---------------------"
5427 ovn-nbctl list logical_router
5428 echo "---------------------"
5429 ovn-nbctl list logical_router_port
5430 echo "---------------------"
5432 echo "---------SB dump-----"
5433 ovn-sbctl list datapath_binding
5434 echo "---------------------"
5435 ovn-sbctl list port_binding
5436 echo "---------------------"
5438 echo "------ hv1 dump ----------"
5439 as hv1 ovs-ofctl dump-flows br-int
5441 # Packet to Expect at foo2
5442 src_mac="0a0000000001"
5443 dst_mac="0a0000000003"
5444 src_ip=`ip_to_hex 192 168 1 2`
5445 dst_ip=`ip_to_hex 192 168 1 3`
5446 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5448 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5449 echo $expected > expout
5450 AT_CHECK([cat received1.packets], [0], [expout])
5452 # Packet to Expect at alice1
5453 src_mac="000000010204"
5454 dst_mac="0a0000000002"
5455 src_ip=`ip_to_hex 192 168 1 2`
5456 dst_ip=`ip_to_hex 192 168 2 2`
5457 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5459 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5460 echo $expected > expout
5461 AT_CHECK([cat received2.packets], [0], [expout])
5467 AT_SETUP([ovn -- ovs-vswitchd restart])
5468 AT_KEYWORDS([vswitchd])
5469 AT_SKIP_IF([test $HAVE_PYTHON = no])
5472 ovn-nbctl ls-add ls1
5474 ovn-nbctl lsp-add ls1 ls1-lp1 \
5475 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5477 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5483 ovs-vsctl add-br br-phys
5484 ovn_attach n1 br-phys 192.168.0.1
5485 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5486 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5487 options:tx_pcap=hv1/vif1-tx.pcap \
5488 options:rxq_pcap=hv1/vif1-rx.pcap \
5494 as hv1 ovs-vsctl show
5496 echo "---------------------"
5497 ovn-sbctl dump-flows
5498 echo "---------------------"
5500 echo "------ hv1 dump ----------"
5501 as hv1 ovs-ofctl dump-flows br-int
5502 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5504 echo "Total flows before vswitchd restart = " $total_flows
5506 # Code taken from ovs-save utility
5508 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5509 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5510 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5511 echo "EOF" >> restore_flows.sh
5514 restart_vswitchd () {
5517 if test $restore_flows = true; then
5522 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5524 if test $restore_flows = true; then
5526 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5530 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5531 ovs-ofctl dump-flows br-int
5533 if test $restore_flows = true; then
5534 sh ./restore_flows.sh
5535 echo "Flows after restore"
5537 ovs-ofctl dump-flows br-int
5538 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5539 flow-restore-wait="true"
5543 # Save the flows, restart vswitchd and restore the flows
5544 restart_vswitchd true
5546 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5547 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5548 test "${total_flows}" = "${total_flows_after_restart}"
5551 # Restart vswitchd without restoring
5552 restart_vswitchd false
5554 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5555 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5556 test "${total_flows}" = "${total_flows_after_restart}"
5562 AT_SETUP([ovn -- send arp for nexthop])
5563 AT_SKIP_IF([test $HAVE_PYTHON = no])
5566 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5568 # Create logical switches
5569 ovn-nbctl ls-add ls1
5570 ovn-nbctl ls-add ls2
5573 ovn-nbctl create Logical_Router name=lr0
5575 # Add router ls1p1 port to gateway router
5576 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5577 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5578 type=router options:router-port=lrp-ls1lp1 \
5579 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5581 # Add router ls2p2 port to gateway router
5582 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5583 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5584 type=router options:router-port=lrp-ls2lp1 \
5585 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5587 # Set default gateway (nexthop) to 192.168.1.254
5588 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5590 # Create logical port ls1lp2 in ls1
5591 ovn-nbctl lsp-add ls1 ls1lp2 \
5592 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5594 # Create logical port ls2lp2 in ls2
5595 ovn-nbctl lsp-add ls2 ls2lp2 \
5596 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5601 ovs-vsctl add-br br-phys
5602 ovn_attach n1 br-phys 192.168.0.1
5603 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5604 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5605 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5606 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5608 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5609 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5610 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5611 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5614 # Allow some time for ovn-northd and ovn-controller to catch up.
5615 # XXX This should be more systematic.
5618 echo "---------NB dump-----"
5620 echo "---------------------"
5621 ovn-nbctl list logical_router
5622 echo "---------------------"
5623 ovn-nbctl list logical_router_port
5624 echo "---------------------"
5626 echo "---------SB dump-----"
5627 ovn-sbctl list datapath_binding
5628 echo "---------------------"
5629 ovn-sbctl list port_binding
5630 echo "---------------------"
5631 ovn-sbctl dump-flows
5632 echo "---------------------"
5633 ovn-sbctl list chassis
5634 ovn-sbctl list encap
5635 echo "---------------------"
5637 echo "------Flows dump-----"
5639 ovs-ofctl dump-flows
5640 echo "---------------------"
5643 printf "%02x%02x%02x%02x" "$@"
5646 src_mac="f00000000003"
5647 dst_mac="f00000000001"
5648 src_ip=`ip_to_hex 192 168 0 2`
5649 dst_ip=`ip_to_hex 8 8 8 8`
5650 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5652 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5653 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5656 sed 's/\(00\)\{1,\}$//'
5659 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5662 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5663 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5664 echo $expected > expout
5665 AT_CHECK([cat packets], [0], [expout])
5672 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5673 AT_SKIP_IF([test $HAVE_PYTHON = no])
5675 # Create logical switch
5676 ovn-nbctl ls-add ls0
5677 # Create gateway router
5678 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5679 # Add router port to gateway router
5680 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5681 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5682 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5683 # Add nat-address option
5684 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5693 ovn_attach n1 br-phys 192.168.0.1
5695 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5696 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])
5698 # Create a localnet port.
5699 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5700 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5701 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5702 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5705 # Wait for packet to be received.
5706 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5708 sed 's/\(00\)\{1,\}$//'
5710 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5711 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5712 echo $expected > expout
5713 AT_CHECK([sort packets], [0], [expout])
5720 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5721 AT_SKIP_IF([test $HAVE_PYTHON = no])
5723 # Create logical switch
5724 ovn-nbctl ls-add ls0
5725 # Create gateway router
5726 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5727 # Add router port to gateway router
5728 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5729 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5730 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5731 # Add nat-address option
5732 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5734 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5735 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5736 # Add load balancers
5737 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5738 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5739 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5740 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5749 ovn_attach n1 br-phys 192.168.0.1
5751 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5752 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])
5754 # Create a localnet port.
5755 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5756 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5757 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5758 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5761 # Wait for packet to be received.
5762 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5764 sed 's/\(00\)\{1,\}$//'
5766 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5767 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5768 echo $expected > expout
5769 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5770 echo $expected >> expout
5771 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5772 echo $expected >> expout
5773 AT_CHECK([sort packets], [0], [expout])
5780 AT_SETUP([ovn -- delete mac bindings])
5785 ovs-vsctl -- add-br br-phys
5786 ovn_attach n1 br-phys 192.168.0.1
5787 # Create logical switch ls0
5788 ovn-nbctl ls-add ls0
5789 # Create ports lp0, lp1 in ls0
5790 ovn-nbctl lsp-add ls0 lp0
5791 ovn-nbctl lsp-add ls0 lp1
5792 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5793 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5794 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5795 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5796 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5797 ovn-sbctl find MAC_Binding
5798 # Delete port lp0 and check that its MAC_Binding is deleted.
5799 ovn-nbctl lsp-del lp0
5800 ovn-sbctl find MAC_Binding
5801 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5802 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5803 ovn-nbctl ls-del ls0
5804 ovn-sbctl find MAC_Binding
5805 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5811 AT_SETUP([ovn -- conntrack zone allocation])
5812 AT_SKIP_IF([test $HAVE_PYTHON = no])
5816 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5817 # connected to a router R1.
5818 # foo has foo1 to act as a client.
5819 # bar has bar1, bar2, bar3 to act as servers.
5825 ovs-vsctl add-br br-phys
5826 ovn_attach n1 br-phys 192.168.0.1
5827 for i in foo1 bar1 bar2 bar3; do
5828 ovs-vsctl -- add-port br-int $i -- \
5829 set interface $i external-ids:iface-id=$i \
5830 options:tx_pcap=hv1/$i-tx.pcap \
5831 options:rxq_pcap=hv1/$i-rx.pcap
5834 ovn-nbctl create Logical_Router name=R1
5835 ovn-nbctl ls-add foo
5836 ovn-nbctl ls-add bar
5839 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5840 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5841 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5844 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5845 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5846 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5848 # Create logical port foo1 in foo
5849 ovn-nbctl lsp-add foo foo1 \
5850 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5852 # Create logical port bar1, bar2 and bar3 in bar
5853 for i in `seq 1 3`; do
5855 ovn-nbctl lsp-add bar bar$i \
5856 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5859 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5865 AT_SETUP([ovn -- tag allocation])
5868 AT_CHECK([ovn-nbctl ls-add ls0])
5869 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5870 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5871 AT_CHECK([ovn-nbctl ls-add ls1])
5873 dnl When a tag is provided, no allocation is done
5874 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5875 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5877 dnl The same 'tag' gets created in southbound database.
5878 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5879 logical_port="c0"], [0], [3
5882 dnl Allocate tags and see it getting created in both NB and SB
5883 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5884 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5886 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5887 logical_port="c1"], [0], [1
5890 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5891 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5893 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5894 logical_port="c2"], [0], [2
5896 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5897 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5899 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5900 logical_port="c3"], [0], [4
5903 dnl A different parent.
5904 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5905 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5907 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5908 logical_port="c4"], [0], [1
5911 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5912 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5914 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5915 logical_port="c5"], [0], [2
5918 dnl Delete a logical port and create a new one.
5919 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5920 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5921 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5923 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5924 logical_port="c6"], [0], [1
5927 dnl Restart northd to see that the same allocation remains.
5929 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5930 start_daemon ovn-northd \
5931 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5932 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5934 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5935 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5936 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5938 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5940 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5942 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5944 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5946 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5949 dnl Create a switch port with a tag that has already been allocated.
5950 dnl It should go through fine with a duplicate tag.
5951 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5952 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5954 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5955 logical_port="c7"], [0], [2
5957 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5960 AT_CHECK([ovn-nbctl ls-add ls2])
5961 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5962 dnl gets copied to 'tag'
5963 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5964 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5966 dnl The same 'tag' gets created in southbound database.
5967 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5968 logical_port="local0"], [0], [25
5970 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5971 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5972 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5973 dnl change the tag_request.
5974 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5975 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5980 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5982 ovn-nbctl ls-add lsw0
5987 ovs-vsctl add-br br-phys
5988 ovn_attach n1 br-phys 192.168.0.$i
5989 ovs-vsctl add-br br-eth0
5990 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5993 # Create a localnet port.
5994 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5995 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5996 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5997 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6001 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6002 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6003 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6004 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6005 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
6006 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6007 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6008 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6009 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6011 # Bind the localvif1 to hv1.
6013 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6015 # On hv1, check that there are no flows outputting bcast to tunnel
6016 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6018 # On hv2, check that no flow outputs bcast to tunnel to hv1.
6020 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6022 # Now bind vif2 on hv2.
6023 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6025 # At this point, the broadcast flow on vif2 should be deleted.
6026 # because, there is now a localnet vif bound (table=32 programming logic)
6027 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6029 # Verify that the local net patch port exists on hv2.
6030 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6032 # Now bind vif3 on hv2.
6033 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6035 # Verify that the local net patch port still exists on hv2
6036 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6039 AT_CHECK([ovn-nbctl lsp-del localvif2])
6041 # Verify that the local net patch port still exists on hv2,
6042 # because, localvif3 is still bound.
6043 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6045 OVN_CLEANUP([hv1],[hv2])
6050 AT_SETUP([ovn -- ACL logging])
6058 ovs-vsctl add-br br-phys
6059 ovn_attach n1 br-phys 192.168.0.1
6060 for i in lp1 lp2; do
6061 ovs-vsctl -- add-port br-int $i -- \
6062 set interface $i external-ids:iface-id=$i \
6063 options:tx_pcap=hv/$i-tx.pcap \
6064 options:rxq_pcap=hv/$i-rx.pcap
6067 lp1_mac="f0:00:00:00:00:01"
6068 lp1_ip="192.168.1.2"
6070 lp2_mac="f0:00:00:00:00:02"
6071 lp2_ip="192.168.1.3"
6073 ovn-nbctl ls-add lsw0
6074 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6075 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6076 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6077 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6078 ovn-nbctl --wait=sb sync
6080 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6081 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6083 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6084 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6086 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6087 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6089 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6090 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6092 ovn-sbctl dump-flows
6095 # Send packet that should be dropped without logging.
6096 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6097 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6098 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6099 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6101 # Send packet that should be dropped with logging.
6102 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6103 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6104 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6105 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6107 # Send packet that should be allowed without logging.
6108 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6109 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6110 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6111 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6113 # Send packet that should be allowed with logging.
6114 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6115 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6116 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6117 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6119 # Send packet that should allow related flows without logging.
6120 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6121 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6122 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6123 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6125 # Send packet that should allow related flows with logging.
6126 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6127 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6128 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6129 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6131 # Send packet that should be rejected without logging.
6132 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6133 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6134 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6135 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6137 # Send packet that should be rejected with logging.
6138 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6139 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6140 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6141 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6143 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6145 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6146 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
6147 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
6148 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
6149 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
6156 AT_SETUP([ovn -- DSCP marking and meter check])
6160 ovn-nbctl ls-add lsw0
6161 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6162 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6163 ovn-nbctl --wait=sb lsp-add lsw0 lp3
6164 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6165 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
6166 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
6167 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6168 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6169 ovn-nbctl --wait=sb sync
6173 ovs-vsctl add-br br-phys
6174 ovn_attach n1 br-phys 192.168.0.1
6175 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
6176 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
6178 AT_CAPTURE_FILE([trace])
6180 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6183 # Extracts nw_tos from the final flow from ofproto/trace output and prints
6184 # it on stdout. Prints "none" if no nw_tos was included.
6185 get_final_nw_tos() {
6186 if flow=$(grep '^Final flow:' stdout); then :; else
6187 # The output didn't have a final flow.
6191 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6200 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6202 # First check with ovn-trace for logical flows.
6203 echo "checking for tos $1"
6204 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6205 echo 'output("lp2");') > expout
6206 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])
6208 # Then re-check with ofproto/trace for a physical packet.
6209 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])
6210 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6215 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");
6217 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])
6218 AT_CHECK([get_final_nw_tos], [0], [none
6221 # check at L3 without dscp marking
6224 # Mark DSCP with a valid value
6225 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)
6226 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6230 # check at hv without qos meter
6231 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6234 # Update the meter rate
6235 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6237 # check at hv with a qos meter table
6238 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6240 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6243 # Update the DSCP marking
6244 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6247 # Update the meter rate
6248 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6250 # check at hv with a qos meter table
6251 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6253 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6256 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6259 # Disable DSCP marking
6260 ovn-nbctl --wait=hv qos-del lsw0
6261 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6265 # check at hv without qos meter
6266 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6269 # check meter with chassis not resident
6270 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6271 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6274 # check no meter table
6275 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6277 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6283 AT_SETUP([ovn -- read-only sb db:ptcp access])
6284 AT_SKIP_IF([test $HAVE_PYTHON = no])
6287 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6289 # Add read-only remote to sb ovsdb-server
6291 [ovsdb-tool transact ovn-sb.db \
6292 ['["OVN_Southbound",
6294 "table": "SB_Global",
6296 "connections": ["set", [["named-uuid", "xyz"]]]}},
6298 "table": "Connection",
6300 "row": {"target": "ptcp:0:127.0.0.1",
6301 "read_only": true}}]']], [0], [ignore], [ignore])
6303 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6305 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6307 # read-only accesses should succeed
6308 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6309 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6311 # write access should fail
6312 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6313 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6316 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6319 AT_SETUP([ovn -- read-only sb db:pssl access])
6320 AT_SKIP_IF([test $HAVE_PYTHON = no])
6321 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6322 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6323 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6327 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6329 # Add read-only remote to sb ovsdb-server
6331 [ovsdb-tool transact ovn-sb.db \
6332 ['["OVN_Southbound",
6334 "table": "SB_Global",
6336 "connections": ["set", [["named-uuid", "xyz"]]]}},
6338 "table": "Connection",
6340 "row": {"target": "pssl:0:127.0.0.1",
6341 "read_only": true}}]']], [0], [ignore], [ignore])
6343 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6344 --remote=db:OVN_Southbound,SB_Global,connections \
6345 --private-key="$PKIDIR/testpki-privkey2.pem" \
6346 --certificate="$PKIDIR/testpki-cert2.pem" \
6347 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6350 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6352 # read-only accesses should succeed
6353 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6354 --private-key=$PKIDIR/testpki-privkey.pem \
6355 --certificate=$PKIDIR/testpki-cert.pem \
6356 --ca-cert=$PKIDIR/testpki-cacert.pem \
6357 list SB_Global], [0], [stdout], [ignore])
6358 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6359 --private-key=$PKIDIR/testpki-privkey.pem \
6360 --certificate=$PKIDIR/testpki-cert.pem \
6361 --ca-cert=$PKIDIR/testpki-cacert.pem \
6362 list Connection], [0], [stdout], [ignore])
6364 # write access should fail
6365 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6366 --private-key=$PKIDIR/testpki-privkey.pem \
6367 --certificate=$PKIDIR/testpki-cert.pem \
6368 --ca-cert=$PKIDIR/testpki-cacert.pem \
6369 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6370 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6373 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6376 AT_SETUP([ovn -- nb connection/ssl commands])
6377 AT_SKIP_IF([test $HAVE_PYTHON = no])
6378 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6379 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6380 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6384 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6386 # Start nb db server using db connection/ssl entries (unpopulated initially)
6387 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6388 --remote=db:OVN_Northbound,NB_Global,connections \
6389 --private-key=db:OVN_Northbound,SSL,private_key \
6390 --certificate=db:OVN_Northbound,SSL,certificate \
6391 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6394 # Populate SSL configuration entries in nb db
6396 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6397 $PKIDIR/testpki-cert.pem \
6398 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6400 # Populate a passive SSL connection in nb db
6401 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6403 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6405 # Verify SSL connetivity to nb db server
6406 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6407 --private-key=$PKIDIR/testpki-privkey.pem \
6408 --certificate=$PKIDIR/testpki-cert.pem \
6409 --ca-cert=$PKIDIR/testpki-cacert.pem \
6411 [0], [stdout], [ignore])
6412 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6413 --private-key=$PKIDIR/testpki-privkey.pem \
6414 --certificate=$PKIDIR/testpki-cert.pem \
6415 --ca-cert=$PKIDIR/testpki-cacert.pem \
6417 [0], [stdout], [ignore])
6418 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6419 --private-key=$PKIDIR/testpki-privkey.pem \
6420 --certificate=$PKIDIR/testpki-cert.pem \
6421 --ca-cert=$PKIDIR/testpki-cacert.pem \
6423 [0], [stdout], [ignore])
6425 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6428 AT_SETUP([ovn -- sb connection/ssl commands])
6429 AT_SKIP_IF([test $HAVE_PYTHON = no])
6430 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6431 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6432 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6436 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6438 # Start sb db server using db connection/ssl entries (unpopulated initially)
6439 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6440 --remote=db:OVN_Southbound,SB_Global,connections \
6441 --private-key=db:OVN_Southbound,SSL,private_key \
6442 --certificate=db:OVN_Southbound,SSL,certificate \
6443 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6446 # Populate SSL configuration entries in sb db
6448 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6449 $PKIDIR/testpki-cert.pem \
6450 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6452 # Populate a passive SSL connection in sb db
6453 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6455 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6457 # Verify SSL connetivity to sb db server
6458 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6459 --private-key=$PKIDIR/testpki-privkey.pem \
6460 --certificate=$PKIDIR/testpki-cert.pem \
6461 --ca-cert=$PKIDIR/testpki-cacert.pem \
6463 [0], [stdout], [ignore])
6464 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6465 --private-key=$PKIDIR/testpki-privkey.pem \
6466 --certificate=$PKIDIR/testpki-cert.pem \
6467 --ca-cert=$PKIDIR/testpki-cacert.pem \
6469 [0], [stdout], [ignore])
6470 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6471 --private-key=$PKIDIR/testpki-privkey.pem \
6472 --certificate=$PKIDIR/testpki-cert.pem \
6473 --ca-cert=$PKIDIR/testpki-cacert.pem \
6475 [0], [stdout], [ignore])
6477 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6480 AT_SETUP([ovn -- nested containers])
6484 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6487 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6488 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6491 ovn-nbctl ls-add mgmt
6492 ovn-nbctl ls-add foo
6493 ovn-nbctl ls-add bar
6495 # Connect mgmt to R1
6496 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6497 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6498 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6501 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6502 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6503 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6506 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6507 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6508 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6510 # "mgmt" has VM1 and VM2 connected
6511 ovn-nbctl lsp-add mgmt vm1 \
6512 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6514 ovn-nbctl lsp-add mgmt vm2 \
6515 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6517 # "foo1" and "foo2" are containers belonging to switch "foo"
6518 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6519 ovn-nbctl lsp-add foo foo1 vm1 1 \
6520 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6522 ovn-nbctl lsp-add foo foo2 vm2 2 \
6523 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6525 # "bar1" and "bar2" are containers belonging to switch "bar"
6526 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6527 ovn-nbctl lsp-add bar bar1 vm1 2 \
6528 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6530 ovn-nbctl lsp-add bar bar2 vm2 1 \
6531 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6533 # bar3 is a standalone VM belonging to switch "bar"
6534 ovn-nbctl lsp-add bar bar3 \
6535 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6537 # Create two hypervisor and create OVS ports corresponding to logical ports.
6542 ovs-vsctl add-br br-phys
6543 ovn_attach n1 br-phys 192.168.0.1
6544 ovs-vsctl -- add-port br-int vm1 -- \
6545 set interface vm1 external-ids:iface-id=vm1 \
6546 options:tx_pcap=hv1/vm1-tx.pcap \
6547 options:rxq_pcap=hv1/vm1-rx.pcap \
6550 ovs-vsctl -- add-port br-int bar3 -- \
6551 set interface bar3 external-ids:iface-id=bar3 \
6552 options:tx_pcap=hv1/bar3-tx.pcap \
6553 options:rxq_pcap=hv1/bar3-rx.pcap \
6558 ovs-vsctl add-br br-phys
6559 ovn_attach n1 br-phys 192.168.0.2
6560 ovs-vsctl -- add-port br-int vm2 -- \
6561 set interface vm2 external-ids:iface-id=vm2 \
6562 options:tx_pcap=hv2/vm2-tx.pcap \
6563 options:rxq_pcap=hv2/vm2-rx.pcap \
6566 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6567 # packets for ARP resolution (native tunneling doesn't queue packets
6568 # for ARP resolution).
6571 # Allow some time for ovn-northd and ovn-controller to catch up.
6572 # XXX This should be more systematic.
6576 printf "%02x%02x%02x%02x" "$@"
6579 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6580 # different VLAN tags).
6581 src_mac="f00000010205"
6582 dst_mac="f00000010206"
6583 src_ip=`ip_to_hex 192 168 1 2`
6584 dst_ip=`ip_to_hex 192 168 1 3`
6585 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6586 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6588 # expected packet at foo2
6589 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6590 echo $packet > expected
6591 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6593 # Send ip packets between foo1 and bar2 (different switch, different HV)
6594 src_mac="f00000010205"
6595 dst_mac="000000010203"
6596 src_ip=`ip_to_hex 192 168 1 2`
6597 dst_ip=`ip_to_hex 192 168 2 3`
6598 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6599 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6601 # expected packet at bar2
6602 src_mac="000000010204"
6603 dst_mac="f00000010208"
6604 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6605 echo $packet >> expected
6606 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6608 # Send ip packets between foo1 and bar1
6609 # (different switch, loopback to same vm but different tag)
6610 src_mac="f00000010205"
6611 dst_mac="000000010203"
6612 src_ip=`ip_to_hex 192 168 1 2`
6613 dst_ip=`ip_to_hex 192 168 2 2`
6614 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6615 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6617 # expected packet at bar1
6618 src_mac="000000010204"
6619 dst_mac="f00000010207"
6620 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6621 echo $packet > expected1
6622 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6624 # Send ip packets between bar1 and bar3
6625 # (same switch. But one is container and another is a standalone VM)
6626 src_mac="f00000010207"
6627 dst_mac="f00000010209"
6628 src_ip=`ip_to_hex 192 168 2 2`
6629 dst_ip=`ip_to_hex 192 168 2 3`
6630 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6631 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6633 # expected packet at bar3
6634 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6635 echo $packet > expected
6636 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6638 # Send ip packets between foo1 and vm1.
6639 (different switch, container to the VM hosting it.)
6640 src_mac="f00000010205"
6641 dst_mac="000000010203"
6642 src_ip=`ip_to_hex 192 168 1 2`
6643 dst_ip=`ip_to_hex 172 16 1 2`
6644 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6645 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6647 # expected packet at vm1
6648 src_mac="000000010202"
6649 dst_mac="f00000010203"
6650 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6651 echo $packet >> expected1
6652 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6654 # Send packets from vm1 to bar1.
6655 (different switch, A hosting VM to a container inside it)
6656 src_mac="f00000010203"
6657 dst_mac="000000010202"
6658 src_ip=`ip_to_hex 172 16 1 2`
6659 dst_ip=`ip_to_hex 192 168 2 2`
6660 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6661 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6663 # expected packet at vm1
6664 src_mac="000000010204"
6665 dst_mac="f00000010207"
6666 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6667 echo $packet >> expected1
6668 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6670 OVN_CLEANUP([hv1],[hv2])
6674 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6675 AT_SKIP_IF([test $HAVE_PYTHON = no])
6679 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6680 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6681 # (192.168.2.0/24) connected to it.
6683 # R2 and R3 are gateway routers.
6684 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6685 # connected to it. Note how both alice and bob have the same subnet behind it.
6686 # We are trying to simulate external network via those 2 switches. In real
6687 # world the switch ports of these switches will have addresses set as "unknown"
6688 # to make them learning switches. Or those switches will be "localnet" ones.
6690 # Create three hypervisors and create OVS ports corresponding to logical ports.
6695 ovs-vsctl add-br br-phys
6696 ovn_attach n1 br-phys 192.168.0.1
6697 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6698 set interface hv1-vif1 external-ids:iface-id=foo1 \
6699 options:tx_pcap=hv1/vif1-tx.pcap \
6700 options:rxq_pcap=hv1/vif1-rx.pcap \
6703 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6704 set interface hv1-vif2 external-ids:iface-id=bar1 \
6705 options:tx_pcap=hv1/vif2-tx.pcap \
6706 options:rxq_pcap=hv1/vif2-rx.pcap \
6711 ovs-vsctl add-br br-phys
6712 ovn_attach n1 br-phys 192.168.0.2
6713 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6714 set interface hv2-vif1 external-ids:iface-id=alice1 \
6715 options:tx_pcap=hv2/vif1-tx.pcap \
6716 options:rxq_pcap=hv2/vif1-rx.pcap \
6721 ovs-vsctl add-br br-phys
6722 ovn_attach n1 br-phys 192.168.0.3
6723 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6724 set interface hv3-vif1 external-ids:iface-id=bob1 \
6725 options:tx_pcap=hv3/vif1-tx.pcap \
6726 options:rxq_pcap=hv3/vif1-rx.pcap \
6730 ovn-nbctl create Logical_Router name=R1
6731 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6732 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6734 ovn-nbctl ls-add foo
6735 ovn-nbctl ls-add bar
6736 ovn-nbctl ls-add alice
6737 ovn-nbctl ls-add bob
6738 ovn-nbctl ls-add join
6741 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6742 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6743 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6746 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6747 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6748 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6750 # Connect alice to R2
6751 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6752 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6753 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6756 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6757 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6758 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6760 # Connect R1 to join
6761 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6762 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6763 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6765 # Connect R2 to join
6766 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6767 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6768 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6770 # Connect R3 to join
6771 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6772 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6773 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6775 # Install static routes with source ip address as the policy for routing.
6776 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6777 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6778 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6780 # Install static routes with destination ip address as the policy for routing.
6781 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6783 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6785 # Create logical port foo1 in foo
6786 ovn-nbctl lsp-add foo foo1 \
6787 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6789 # Create logical port bar1 in bar
6790 ovn-nbctl lsp-add bar bar1 \
6791 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6793 # Create logical port alice1 in alice
6794 ovn-nbctl lsp-add alice alice1 \
6795 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6797 # Create logical port bob1 in bob
6798 ovn-nbctl lsp-add bob bob1 \
6799 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6801 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6802 # packets for ARP resolution (native tunneling doesn't queue packets
6803 # for ARP resolution).
6806 # Allow some time for ovn-northd and ovn-controller to catch up.
6807 # XXX This should be more systematic.
6811 printf "%02x%02x%02x%02x" "$@"
6814 sed 's/\(00\)\{1,\}$//'
6817 # Send ip packets between foo1 and bar1
6818 # (East-west traffic should flow normally)
6819 src_mac="f00000010203"
6820 dst_mac="000001010203"
6821 src_ip=`ip_to_hex 192 168 1 2`
6822 dst_ip=`ip_to_hex 192 168 2 2`
6823 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6824 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6826 # Send ip packets between foo1 and alice1
6827 src_mac="f00000010203"
6828 dst_mac="000001010203"
6829 src_ip=`ip_to_hex 192 168 1 2`
6830 dst_ip=`ip_to_hex 172 16 1 3`
6831 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6832 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6833 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6835 # Send ip packets between bar1 and bob1
6836 src_mac="f00000010204"
6837 dst_mac="000001010204"
6838 src_ip=`ip_to_hex 192 168 2 2`
6839 dst_ip=`ip_to_hex 172 16 1 4`
6840 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6841 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6842 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6844 # Packet to expect at bar1
6845 src_mac="000001010204"
6846 dst_mac="f00000010204"
6847 src_ip=`ip_to_hex 192 168 1 2`
6848 dst_ip=`ip_to_hex 192 168 2 2`
6849 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6850 echo $expected > expected
6851 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6853 # Packet to Expect at alice1
6854 src_mac="000002010203"
6855 dst_mac="f00000010205"
6856 src_ip=`ip_to_hex 192 168 1 2`
6857 dst_ip=`ip_to_hex 172 16 1 3`
6858 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6859 echo $expected > expected
6860 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6862 # Packet to Expect at bob1
6863 src_mac="000003010203"
6864 dst_mac="f00000010206"
6865 src_ip=`ip_to_hex 192 168 2 2`
6866 dst_ip=`ip_to_hex 172 16 1 4`
6867 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6868 echo $expected > expected
6869 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6871 for sim in hv1 hv2 hv3; do
6873 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6874 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6875 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6879 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6882 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6885 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6888 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6889 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6893 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6894 AT_SKIP_IF([test $HAVE_PYTHON = no])
6897 ovn-nbctl ls-add ls1
6899 ovn-nbctl lsp-add ls1 ls1-lp1 \
6900 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6902 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6904 ovn-nbctl lsp-add ls1 ls1-lp2 \
6905 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6907 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6909 DNS1=`ovn-nbctl create DNS records={}`
6910 DNS2=`ovn-nbctl create DNS records={}`
6912 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6913 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6914 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6916 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6922 ovs-vsctl add-br br-phys
6923 ovn_attach n1 br-phys 192.168.0.1
6924 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6925 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6926 options:tx_pcap=hv1/vif1-tx.pcap \
6927 options:rxq_pcap=hv1/vif1-rx.pcap \
6930 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6931 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6932 options:tx_pcap=hv1/vif2-tx.pcap \
6933 options:rxq_pcap=hv1/vif2-rx.pcap \
6938 as hv1 ovs-vsctl show
6940 echo "*************************"
6942 echo "*************************"
6945 printf "%02x%02x%02x%02x" "$@"
6951 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6952 options:rxq_pcap=dummy-rx.pcap
6953 rm -f ${pcap_file}*.pcap
6954 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6955 options:rxq_pcap=${pcap_file}-rx.pcap
6958 # set_dns_params host_name
6959 # Sets the dns_req_data and dns_resp_data
6968 query_name=03766d31036f766e036f726700
6969 # IPv4 address - 10.0.0.4
6970 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6974 query_name=03766d32036f766e036f726700
6975 # IPv4 address - 10.0.0.6
6976 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6977 # IPv4 address - 20.0.0.4
6978 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6983 query_name=03766d33036f766e036f726700
6984 # IPv4 address - 40.0.0.4
6985 expected_dns_answer=${query_name}00010001${ttl}000428000004
6989 query_name=03766d31036f766e036f726700
6990 # IPv6 address - aef0::4
6992 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6996 query_name=03766d31036f766e036f726700
6999 # IPv4 address - 10.0.0.4
7000 # IPv6 address - aef0::4
7001 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7002 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7003 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7007 query_name=03766d31036f766e036f726700
7008 # IPv6 address - aef0::4
7016 local dns_req_header=010201200001000000000000
7017 local dns_resp_header=010281200001${an_count}00000000
7018 dns_req_data=${dns_req_header}${query_name}${type}0001
7019 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7022 # This shell function sends a DNS request packet
7023 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7025 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7026 local dns_query_data=$7
7027 shift; shift; shift; shift; shift; shift; shift;
7028 # Packet size => IPv4 header (20) + UDP header (8) +
7029 # DNS data (header + query)
7030 ip_len=`expr 28 + ${#dns_query_data} / 2`
7031 udp_len=`expr $ip_len - 20`
7032 ip_len=$(printf "%x" $ip_len)
7033 udp_len=$(printf "%x" $udp_len)
7034 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7035 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7037 request=${request}${dns_query_data}
7039 if test $dns_reply != 0; then
7041 ip_len=`expr 28 + ${#dns_reply} / 2`
7042 udp_len=`expr $ip_len - 20`
7043 ip_len=$(printf "%x" $ip_len)
7044 udp_len=$(printf "%x" $udp_len)
7045 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7046 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7047 echo $reply >> $inport.expected
7050 echo $request >> $outport.expected
7053 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7057 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7058 local dns_query_data=$7
7059 shift; shift; shift; shift; shift; shift; shift;
7060 # Packet size => UDP header (8) +
7061 # DNS data (header + query)
7062 ip_len=`expr 8 + ${#dns_query_data} / 2`
7064 ip_len=$(printf "%x" $ip_len)
7065 udp_len=$(printf "%x" $udp_len)
7066 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7067 request=${request}9234003500${udp_len}0000
7069 request=${request}${dns_query_data}
7071 if test $dns_reply != 0; then
7073 ip_len=`expr 8 + ${#dns_reply} / 2`
7075 ip_len=$(printf "%x" $ip_len)
7076 udp_len=$(printf "%x" $udp_len)
7077 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7078 reply=${reply}0035923400${udp_len}0000${dns_reply}
7079 echo $reply >> $inport.expected
7082 echo $request >> $outport.expected
7085 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7088 AT_CAPTURE_FILE([ofctl_monitor0.log])
7089 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7090 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7093 src_ip=`ip_to_hex 10 0 0 4`
7094 dst_ip=`ip_to_hex 10 0 0 1`
7096 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7098 # NXT_RESUMEs should be 1.
7099 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7101 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7102 cat 1.expected | cut -c -48 > expout
7103 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7104 # Skipping the IPv4 checksum.
7105 cat 1.expected | cut -c 53- > expout
7106 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7108 reset_pcap_file hv1-vif1 hv1/vif1
7109 reset_pcap_file hv1-vif2 hv1/vif2
7114 src_ip=`ip_to_hex 10 0 0 6`
7115 dst_ip=`ip_to_hex 10 0 0 1`
7117 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7119 # NXT_RESUMEs should be 2.
7120 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7122 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7123 cat 2.expected | cut -c -48 > expout
7124 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7125 # Skipping the IPv4 checksum.
7126 cat 2.expected | cut -c 53- > expout
7127 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7129 reset_pcap_file hv1-vif1 hv1/vif1
7130 reset_pcap_file hv1-vif2 hv1/vif2
7134 # Clear the query name options for ls1-lp2
7135 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7138 src_ip=`ip_to_hex 10 0 0 4`
7139 dst_ip=`ip_to_hex 10 0 0 1`
7141 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7143 # NXT_RESUMEs should be 3.
7144 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7146 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7147 AT_CHECK([cat 1.packets], [0], [])
7149 reset_pcap_file hv1-vif1 hv1/vif1
7150 reset_pcap_file hv1-vif2 hv1/vif2
7154 # Clear the query name for ls1-lp1
7155 # Since ls1 has no query names configued,
7156 # ovn-northd should not add the DNS flows.
7157 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7160 src_ip=`ip_to_hex 10 0 0 6`
7161 dst_ip=`ip_to_hex 10 0 0 1`
7163 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7165 # NXT_RESUMEs should be 3 only.
7166 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7168 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7169 AT_CHECK([cat 2.packets], [0], [])
7171 reset_pcap_file hv1-vif1 hv1/vif1
7172 reset_pcap_file hv1-vif2 hv1/vif2
7176 # Test IPv6 (AAAA records) using IPv4 packet.
7177 # Add back the DNS options for ls1-lp1.
7178 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7180 set_dns_params vm1_ipv6_only
7181 src_ip=`ip_to_hex 10 0 0 6`
7182 dst_ip=`ip_to_hex 10 0 0 1`
7184 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7186 # NXT_RESUMEs should be 4.
7187 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7189 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7190 cat 2.expected | cut -c -48 > expout
7191 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7192 # Skipping the IPv4 checksum.
7193 cat 2.expected | cut -c 53- > expout
7194 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7196 reset_pcap_file hv1-vif1 hv1/vif1
7197 reset_pcap_file hv1-vif2 hv1/vif2
7201 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7202 set_dns_params vm1_ipv4_v6
7203 src_ip=`ip_to_hex 10 0 0 6`
7204 dst_ip=`ip_to_hex 10 0 0 1`
7206 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7208 # NXT_RESUMEs should be 5.
7209 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7211 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7212 cat 2.expected | cut -c -48 > expout
7213 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7214 # Skipping the IPv4 checksum.
7215 cat 2.expected | cut -c 53- > expout
7216 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7218 reset_pcap_file hv1-vif1 hv1/vif1
7219 reset_pcap_file hv1-vif2 hv1/vif2
7224 set_dns_params vm1_invalid_type
7225 src_ip=`ip_to_hex 10 0 0 6`
7226 dst_ip=`ip_to_hex 10 0 0 1`
7228 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7230 # NXT_RESUMEs should be 6.
7231 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7233 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7234 AT_CHECK([cat 2.packets], [0], [])
7236 reset_pcap_file hv1-vif1 hv1/vif1
7237 reset_pcap_file hv1-vif2 hv1/vif2
7241 # Incomplete DNS packet.
7242 set_dns_params vm1_incomplete
7243 src_ip=`ip_to_hex 10 0 0 6`
7244 dst_ip=`ip_to_hex 10 0 0 1`
7246 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7248 # NXT_RESUMEs should be 7.
7249 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7251 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7252 AT_CHECK([cat 2.packets], [0], [])
7254 reset_pcap_file hv1-vif1 hv1/vif1
7255 reset_pcap_file hv1-vif2 hv1/vif2
7259 # Add one more DNS record to the ls1.
7260 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7263 src_ip=`ip_to_hex 10 0 0 4`
7264 dst_ip=`ip_to_hex 10 0 0 1`
7266 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7268 # NXT_RESUMEs should be 8.
7269 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7271 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7272 cat 1.expected | cut -c -48 > expout
7273 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7274 # Skipping the IPv4 checksum.
7275 cat 1.expected | cut -c 53- > expout
7276 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7278 reset_pcap_file hv1-vif1 hv1/vif1
7279 reset_pcap_file hv1-vif2 hv1/vif2
7283 # Try DNS query over IPv6
7285 src_ip=aef00000000000000000000000000004
7286 dst_ip=aef00000000000000000000000000001
7288 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7290 # NXT_RESUMEs should be 9.
7291 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7293 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7294 # Skipping the UDP checksum.
7295 cat 1.expected | cut -c 1-120,125- > expout
7296 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
7298 reset_pcap_file hv1-vif1 hv1/vif1
7299 reset_pcap_file hv1-vif2 hv1/vif2
7304 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7305 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7306 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7309 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7312 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7315 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7318 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7319 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7322 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7323 AT_SKIP_IF([test $HAVE_PYTHON = no])
7330 ovs-vsctl add-br br-phys
7331 ovn_attach n1 br-phys 192.168.0.1
7332 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7333 set interface hv1-vif1 external-ids:iface-id=foo1 \
7334 options:tx_pcap=hv1/vif1-tx.pcap \
7335 options:rxq_pcap=hv1/vif1-rx.pcap \
7340 ovs-vsctl add-br br-phys
7341 ovn_attach n1 br-phys 192.168.0.2
7345 ovs-vsctl add-br br-phys
7346 ovn_attach n1 br-phys 192.168.0.4
7350 ovs-vsctl add-br br-phys
7351 ovn_attach n1 br-phys 192.168.0.3
7352 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7353 set interface ext1-vif1 external-ids:iface-id=outside1 \
7354 options:tx_pcap=ext1/vif1-tx.pcap \
7355 options:rxq_pcap=ext1/vif1-rx.pcap \
7358 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7359 # packets for ARP resolution (native tunneling doesn't queue packets
7360 # for ARP resolution).
7363 ovn-nbctl create Logical_Router name=R1
7365 ovn-nbctl ls-add foo
7366 ovn-nbctl ls-add alice
7367 ovn-nbctl ls-add outside
7370 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7371 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7372 type=router options:router-port=foo \
7373 -- lsp-set-addresses rp-foo router
7375 # Connect alice to R1 as distributed router gateway port on gw1
7376 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7379 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7382 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7385 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7387 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7388 type=router options:router-port=alice \
7389 -- lsp-set-addresses rp-alice router
7391 # Create logical port foo1 in foo
7392 ovn-nbctl lsp-add foo foo1 \
7393 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7395 # Create logical port outside1 in outside
7396 ovn-nbctl lsp-add outside outside1 \
7397 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7399 # Create localnet port in alice
7400 ovn-nbctl lsp-add alice ln-alice
7401 ovn-nbctl lsp-set-addresses ln-alice unknown
7402 ovn-nbctl lsp-set-type ln-alice localnet
7403 ovn-nbctl lsp-set-options ln-alice network_name=phys
7405 # Create localnet port in outside
7406 ovn-nbctl lsp-add outside ln-outside
7407 ovn-nbctl lsp-set-addresses ln-outside unknown
7408 ovn-nbctl lsp-set-type ln-outside localnet
7409 ovn-nbctl lsp-set-options ln-outside network_name=phys
7411 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7412 # mapping to the external network, is the one generating packets
7413 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7414 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7415 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7417 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7419 # Allow some time for ovn-northd and ovn-controller to catch up.
7420 # XXX This should be more systematic.
7424 printf "%02x%02x%02x%02x" "$@"
7430 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7431 options:rxq_pcap=dummy-rx.pcap
7432 rm -f ${pcap_file}*.pcap
7433 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7434 options:rxq_pcap=${pcap_file}-rx.pcap
7442 # Send ip packet between foo1 and outside1
7443 src_mac="f00000010203" # foo1 mac
7444 dst_mac="000001010203" # rp-foo mac (internal router leg)
7445 src_ip=`ip_to_hex 192 168 1 2`
7446 dst_ip=`ip_to_hex 172 16 1 3`
7447 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7449 # ARP request packet to expect at outside1
7450 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7452 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7454 # Send ARP reply from outside1 back to the router
7455 # XXX: note, we could avoid this if we plug this port into a netns
7456 # and setup the IP address into the port, so the kernel would simply reply
7457 src_mac="000002010203"
7458 reply_mac="f00000010204"
7459 dst_ip=`ip_to_hex 172 16 1 3`
7460 src_ip=`ip_to_hex 172 16 1 1`
7461 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7463 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7466 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7467 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7470 # Packet to Expect at ext1 chassis, outside1 port
7471 src_mac="000002010203"
7472 dst_mac="f00000010204"
7473 src_ip=`ip_to_hex 192 168 1 2`
7474 dst_ip=`ip_to_hex 172 16 1 3`
7475 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7476 echo $expected > ext1-vif1.expected
7478 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7479 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7480 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7482 # Resend packet from foo1 to outside1
7483 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7487 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7488 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7489 AT_CHECK([grep $expected packets | sort], [0], [expout])
7490 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7491 AT_CHECK([grep $expected packets | sort], [0], [])
7494 test_ip_packet gw1 gw2
7496 ovn-nbctl --timeout=3 --wait=hv \
7497 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7500 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7503 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7505 test_ip_packet gw2 gw1
7507 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7510 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7511 AT_SKIP_IF([test $HAVE_PYTHON = no])
7518 ovs-vsctl add-br br-phys
7519 ovn_attach n1 br-phys 192.168.0.1
7520 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7521 set interface hv1-vif1 external-ids:iface-id=foo1 \
7522 options:tx_pcap=hv1/vif1-tx.pcap \
7523 options:rxq_pcap=hv1/vif1-rx.pcap \
7528 ovs-vsctl add-br br-phys
7529 ovn_attach n1 br-phys 192.168.0.2
7533 ovs-vsctl add-br br-phys
7534 ovn_attach n1 br-phys 192.168.0.4
7538 ovs-vsctl add-br br-phys
7539 ovn_attach n1 br-phys 192.168.0.3
7540 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7541 set interface ext1-vif1 external-ids:iface-id=outside1 \
7542 options:tx_pcap=ext1/vif1-tx.pcap \
7543 options:rxq_pcap=ext1/vif1-rx.pcap \
7546 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7547 # packets for ARP resolution (native tunneling doesn't queue packets
7548 # for ARP resolution).
7551 ovn-nbctl create Logical_Router name=R0
7552 ovn-nbctl create Logical_Router name=R1
7554 ovn-nbctl ls-add foo
7555 ovn-nbctl ls-add join
7556 ovn-nbctl ls-add alice
7557 ovn-nbctl ls-add outside
7560 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7561 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7562 type=router options:router-port=R0-foo \
7563 -- lsp-set-addresses foo-R0 router
7566 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7567 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7568 type=router options:router-port=R0-join \
7569 -- lsp-set-addresses join-R0 router
7572 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7573 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7574 type=router options:router-port=R1-join \
7575 -- lsp-set-addresses join-R1 router
7578 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7579 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7581 # Connect alice to R1 as distributed router gateway port on gw1
7582 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7585 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7588 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7591 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7593 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7594 type=router options:router-port=alice \
7595 -- lsp-set-addresses rp-alice router
7597 # Create logical port foo1 in foo
7598 ovn-nbctl lsp-add foo foo1 \
7599 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7601 # Create logical port outside1 in outside
7602 ovn-nbctl lsp-add outside outside1 \
7603 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7605 # Create localnet port in alice
7606 ovn-nbctl lsp-add alice ln-alice
7607 ovn-nbctl lsp-set-addresses ln-alice unknown
7608 ovn-nbctl lsp-set-type ln-alice localnet
7609 ovn-nbctl lsp-set-options ln-alice network_name=phys
7611 # Create localnet port in outside
7612 ovn-nbctl lsp-add outside ln-outside
7613 ovn-nbctl lsp-set-addresses ln-outside unknown
7614 ovn-nbctl lsp-set-type ln-outside localnet
7615 ovn-nbctl lsp-set-options ln-outside network_name=phys
7617 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7618 # mapping to the external network, is the one generating packets
7619 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7620 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7621 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7623 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7625 # Allow some time for ovn-northd and ovn-controller to catch up.
7626 # XXX This should be more systematic.
7630 printf "%02x%02x%02x%02x" "$@"
7636 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7637 options:rxq_pcap=dummy-rx.pcap
7638 rm -f ${pcap_file}*.pcap
7639 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7640 options:rxq_pcap=${pcap_file}-rx.pcap
7648 # Send ip packet between foo1 and outside1
7649 src_mac="f00000010203" # foo1 mac
7650 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7651 src_ip=`ip_to_hex 192 168 1 2`
7652 dst_ip=`ip_to_hex 172 16 1 3`
7653 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7655 # ARP request packet to expect at outside1
7656 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7658 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7660 # Send ARP reply from outside1 back to the router
7661 # XXX: note, we could avoid this if we plug this port into a netns
7662 # and setup the IP address into the port, so the kernel would simply reply
7663 src_mac="000002010203"
7664 reply_mac="f00000010204"
7665 dst_ip=`ip_to_hex 172 16 1 3`
7666 src_ip=`ip_to_hex 172 16 1 1`
7667 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7669 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7672 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7673 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7676 # Packet to Expect at ext1 chassis, outside1 port
7677 src_mac="000002010203"
7678 dst_mac="f00000010204"
7679 src_ip=`ip_to_hex 192 168 1 2`
7680 dst_ip=`ip_to_hex 172 16 1 3`
7681 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7682 echo $expected > ext1-vif1.expected
7684 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7685 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7686 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7688 # Resend packet from foo1 to outside1
7689 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7693 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7694 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7695 AT_CHECK([grep $expected packets | sort], [0], [expout])
7696 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7697 AT_CHECK([grep $expected packets | sort], [0], [])
7700 test_ip_packet gw1 gw2
7702 ovn-nbctl --timeout=3 --wait=hv \
7703 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7706 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7709 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7711 test_ip_packet gw2 gw1
7713 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7716 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7717 AT_SKIP_IF([test $HAVE_PYTHON = no])
7721 # One LR R1 that has switches foo (192.168.1.0/24) and
7722 # alice (172.16.1.0/24) connected to it. The logical port
7723 # between R1 and alice has a "redirect-chassis" specified,
7724 # i.e. it is the distributed router gateway port.
7725 # Switch alice also has a localnet port defined.
7726 # An additional switch outside has a localnet port and the
7727 # same subnet as alice (172.16.1.0/24).
7730 # Three hypervisors hv[123].
7731 # hv1 hosts vif foo1.
7732 # hv2 is the "redirect-chassis" that hosts the distributed
7733 # router gateway port.
7734 # hv3 hosts vif outside1.
7735 # In order to show that connectivity works only through hv2,
7736 # an initial round of tests is run without any bridge-mapping
7737 # defined for the localnet on hv2. These tests are expected
7739 # Subsequent tests are run after defining the bridge-mapping
7740 # for the localnet on hv2. These tests are expected to succeed.
7742 # Create three hypervisors and create OVS ports corresponding
7748 ovs-vsctl add-br br-phys
7749 ovn_attach n1 br-phys 192.168.0.1
7750 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7751 set interface hv1-vif1 external-ids:iface-id=foo1 \
7752 options:tx_pcap=hv1/vif1-tx.pcap \
7753 options:rxq_pcap=hv1/vif1-rx.pcap \
7758 ovs-vsctl add-br br-phys
7759 ovn_attach n1 br-phys 192.168.0.2
7763 ovs-vsctl add-br br-phys
7764 ovn_attach n1 br-phys 192.168.0.3
7765 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7766 set interface hv3-vif1 external-ids:iface-id=outside1 \
7767 options:tx_pcap=hv3/vif1-tx.pcap \
7768 options:rxq_pcap=hv3/vif1-rx.pcap \
7771 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7772 # packets for ARP resolution (native tunneling doesn't queue packets
7773 # for ARP resolution).
7776 ovn-nbctl create Logical_Router name=R1
7778 ovn-nbctl ls-add foo
7779 ovn-nbctl ls-add alice
7780 ovn-nbctl ls-add outside
7783 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7784 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7785 type=router options:router-port=foo \
7786 -- lsp-set-addresses rp-foo router
7788 # Connect alice to R1 as distributed router gateway port on hv2
7789 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7790 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7791 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7792 type=router options:router-port=alice \
7793 -- lsp-set-addresses rp-alice router
7795 # Create logical port foo1 in foo
7796 ovn-nbctl lsp-add foo foo1 \
7797 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7799 # Create logical port outside1 in outside
7800 ovn-nbctl lsp-add outside outside1 \
7801 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7803 # Create localnet port in alice
7804 ovn-nbctl lsp-add alice ln-alice
7805 ovn-nbctl lsp-set-addresses ln-alice unknown
7806 ovn-nbctl lsp-set-type ln-alice localnet
7807 ovn-nbctl lsp-set-options ln-alice network_name=phys
7809 # Create localnet port in outside
7810 ovn-nbctl lsp-add outside ln-outside
7811 ovn-nbctl lsp-set-addresses ln-outside unknown
7812 ovn-nbctl lsp-set-type ln-outside localnet
7813 ovn-nbctl lsp-set-options ln-outside network_name=phys
7815 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7816 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7817 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7820 # Allow some time for ovn-northd and ovn-controller to catch up.
7821 # XXX This should be more systematic.
7824 echo "---------NB dump-----"
7826 echo "---------------------"
7827 ovn-nbctl list logical_router
7828 echo "---------------------"
7829 ovn-nbctl list logical_router_port
7830 echo "---------------------"
7832 echo "---------SB dump-----"
7833 ovn-sbctl list datapath_binding
7834 echo "---------------------"
7835 ovn-sbctl list port_binding
7836 echo "---------------------"
7837 ovn-sbctl dump-flows
7838 echo "---------------------"
7839 ovn-sbctl list chassis
7840 ovn-sbctl list encap
7841 echo "------ Gateway_Chassis dump (SBDB) -------"
7842 ovn-sbctl list Gateway_Chassis
7843 echo "------ Port_Binding chassisredirect -------"
7844 ovn-sbctl find Port_Binding type=chassisredirect
7845 echo "-------------------------------------------"
7847 echo "------ hv1 dump ----------"
7848 as hv1 ovs-ofctl show br-int
7849 as hv1 ovs-ofctl dump-flows br-int
7850 echo "------ hv2 dump ----------"
7851 as hv2 ovs-ofctl show br-int
7852 as hv2 ovs-ofctl dump-flows br-int
7853 echo "------ hv3 dump ----------"
7854 as hv3 ovs-ofctl show br-int
7855 as hv3 ovs-ofctl dump-flows br-int
7856 echo "--------------------------"
7859 # Check that redirect mapping is programmed only on hv2
7860 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7862 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7864 # Check that hv1 sends chassisredirect port traffic to hv2
7865 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7867 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7869 # Check that arp reply on distributed gateway port is only programmed on hv2
7870 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7872 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7877 printf "%02x%02x%02x%02x" "$@"
7881 : > hv2-vif1.expected
7882 : > hv3-vif1.expected
7884 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7886 # Causes a packet to be received on INPORT. The packet is an ARP
7887 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7888 # it should be the hardware address of the target to expect to receive in an
7889 # ARP reply; otherwise no reply is expected.
7891 # INPORT is an logical switch port number, e.g. 11 for vif11.
7892 # SHA and REPLY_HA are each 12 hex digits.
7893 # SPA and TPA are each 8 hex digits.
7895 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7896 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7897 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7899 if test X$reply_ha != X; then
7900 # Expect to receive the reply, if any.
7901 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7902 echo $reply >> hv${hv}-vif$inport.expected
7906 rtr_ip=$(ip_to_hex 172 16 1 1)
7907 foo_ip=$(ip_to_hex 192 168 1 2)
7908 outside_ip=$(ip_to_hex 172 16 1 3)
7914 # ARP for router IP address from outside1, no response expected
7915 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7917 # Now check the packets actually received against the ones expected.
7918 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7920 # Send ip packet between foo1 and outside1
7921 src_mac="f00000010203"
7922 dst_mac="000001010203"
7923 src_ip=`ip_to_hex 192 168 1 2`
7924 dst_ip=`ip_to_hex 172 16 1 3`
7925 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7927 # Now check the packets actually received against the ones expected.
7928 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7930 # Now add bridge-mappings on hv2, which should make everything work
7931 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7933 # Allow some time for ovn-northd and ovn-controller to catch up.
7934 # XXX This should be more systematic.
7937 # ARP for router IP address from outside1
7938 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7940 # Now check the packets actually received against the ones expected.
7941 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7943 # Send ip packet between foo1 and outside1
7944 src_mac="f00000010203"
7945 dst_mac="000001010203"
7946 src_ip=`ip_to_hex 192 168 1 2`
7947 dst_ip=`ip_to_hex 172 16 1 3`
7948 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7950 # ARP request packet to expect at outside1
7951 src_mac="000002010203"
7952 src_ip=`ip_to_hex 172 16 1 1`
7953 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7955 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7957 echo $arp_request >> hv3-vif1.expected
7958 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7960 # Send ARP reply from outside1 back to the router
7961 reply_mac="f00000010204"
7962 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7964 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7966 # Allow some time for ovn-northd and ovn-controller to catch up.
7967 # XXX This should be more systematic.
7970 # Packet to Expect at outside1
7971 src_mac="000002010203"
7972 dst_mac="f00000010204"
7973 src_ip=`ip_to_hex 192 168 1 2`
7974 dst_ip=`ip_to_hex 172 16 1 3`
7975 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7977 # Resend packet from foo1 to outside1
7978 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7980 echo "------ hv1 dump ----------"
7981 as hv1 ovs-ofctl show br-int
7982 as hv1 ovs-ofctl dump-flows br-int
7983 echo "------ hv2 dump ----------"
7984 as hv2 ovs-ofctl show br-int
7985 as hv2 ovs-ofctl dump-flows br-int
7986 echo "------ hv3 dump ----------"
7987 as hv3 ovs-ofctl show br-int
7988 as hv3 ovs-ofctl dump-flows br-int
7989 echo "----------------------------"
7991 echo $expected >> hv3-vif1.expected
7992 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7994 #Check ovn-trace over "chassisredirect" port
7995 AT_CAPTURE_FILE([trace])
7997 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8000 echo 'ip.ttl--;' > expout
8001 echo 'eth.src = 00:00:02:01:02:03;' >> expout
8002 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8003 echo 'output("ln-alice");' >> expout
8004 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])
8006 # Create logical port alice1 in alice on hv1
8007 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8008 set interface hv1-vif2 external-ids:iface-id=alice1 \
8009 options:tx_pcap=hv1/vif2-tx.pcap \
8010 options:rxq_pcap=hv1/vif2-rx.pcap \
8013 ovn-nbctl lsp-add alice alice1 \
8014 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8016 # Create logical port foo2 in foo on hv2
8017 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8018 set interface hv2-vif1 external-ids:iface-id=foo2 \
8019 options:tx_pcap=hv2/vif1-tx.pcap \
8020 options:rxq_pcap=hv2/vif1-rx.pcap \
8023 ovn-nbctl lsp-add foo foo2 \
8024 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8026 # Allow some time for ovn-northd and ovn-controller to catch up.
8027 # XXX This should be more systematic.
8030 : > hv1-vif2.expected
8032 # Send ip packet between alice1 and foo2
8033 src_mac="f00000010205"
8034 dst_mac="000002010203"
8035 src_ip=`ip_to_hex 172 16 1 4`
8036 dst_ip=`ip_to_hex 192 168 1 3`
8037 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8039 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8041 # Packet to Expect at foo2
8042 src_mac="000001010203"
8043 dst_mac="f00000010206"
8044 src_ip=`ip_to_hex 172 16 1 4`
8045 dst_ip=`ip_to_hex 192 168 1 3`
8046 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8048 echo $expected >> hv2-vif1.expected
8049 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
8051 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
8054 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
8056 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
8059 OVN_CLEANUP([hv1],[hv2],[hv3])
8063 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8064 AT_SKIP_IF([test $HAVE_PYTHON = no])
8066 # Create logical switches
8067 ovn-nbctl ls-add ls0
8068 ovn-nbctl ls-add ls1
8069 # Create distributed router
8070 ovn-nbctl create Logical_Router name=lr0
8071 # Add distributed gateway port to distributed router
8072 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8073 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8074 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8075 type=router options:router-port=lrp0 addresses="router"
8076 # Add router port to ls1
8077 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8078 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8079 type=router options:router-port=lrp1 addresses="router"
8080 # Add logical ports for NAT rules
8081 ovn-nbctl lsp-add ls1 foo1 \
8082 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8083 ovn-nbctl lsp-add ls1 foo2 \
8084 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
8085 # Add nat-addresses option
8086 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8088 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8089 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8090 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])
8091 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])
8096 ovs-vsctl add-br br-phys
8097 ovn_attach n1 br-phys 192.168.0.1
8099 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8100 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])
8104 ovs-vsctl add-br br-phys
8105 ovn_attach n1 br-phys 192.168.0.2
8106 # Initially test with no bridge-mapping on hv2, expect to receive no packets
8110 ovs-vsctl add-br br-phys
8111 ovn_attach n1 br-phys 192.168.0.3
8112 # Initially test with no bridge-mapping on hv3
8114 # Create a localnet port.
8115 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8116 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8117 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8118 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8120 # Allow some time for ovn-northd and ovn-controller to catch up.
8121 # XXX This should be more systematic.
8124 # Expect no packets when hv2 bridge-mapping is not present
8126 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8128 # Add bridge-mapping on hv2
8129 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8131 # Wait for packets to be received.
8132 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8134 sed 's/\(00\)\{1,\}$//'
8136 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8137 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8138 echo $expected > expout
8139 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8140 echo $expected >> expout
8141 AT_CHECK([sort packets], [0], [expout])
8144 # Temporarily remove nat-addresses option to avoid race conditions
8145 # due to GARP backoff
8146 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8151 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8152 options:rxq_pcap=dummy-rx.pcap
8153 rm -f ${pcap_file}*.pcap
8154 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8155 options:rxq_pcap=${pcap_file}-rx.pcap
8158 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8160 # Add OVS ports for foo1 and foo2 on hv3
8161 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8162 set interface hv3-vif1 external-ids:iface-id=foo1 \
8164 ovs-vsctl -- add-port br-int hv3-vif2 -- \
8165 set interface hv3-vif2 external-ids:iface-id=foo2 \
8168 # Add bridge-mapping on hv3
8169 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8171 # Re-add nat-addresses option
8172 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8174 # Wait for packets to be received.
8175 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8177 sed 's/\(00\)\{1,\}$//'
8180 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8181 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8182 echo $expected >> expout
8183 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8184 echo $expected >> expout
8185 AT_CHECK([sort packets], [0], [expout])
8188 OVN_CLEANUP([hv1],[hv2],[hv3])
8192 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8193 AT_KEYWORDS([ovn-nd_ra])
8194 AT_SKIP_IF([test $HAVE_PYTHON = no])
8197 # In this test case we create 1 lswitch with 3 VIF ports attached,
8198 # and a lrouter connected to the lswitch.
8199 # We generate the Router solicitation packet and verify the Router Advertisement
8200 # reply packet from the ovn-controller.
8202 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8203 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8204 # 'slaac' to allow lrp0 send RA for SLAAC mode.
8205 ovn-nbctl ls-add lsw0
8206 ovn-nbctl lr-add lr0
8207 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8208 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8210 -- lsp-add lsw0 lsp0 \
8211 -- set Logical_Switch_Port lsp0 type=router \
8212 options:router-port=lrp0 \
8213 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8217 ovs-vsctl add-br br-phys
8218 ovn_attach n1 br-phys 192.168.0.2
8220 ovn-nbctl lsp-add lsw0 lp1
8221 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8222 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"
8224 ovn-nbctl lsp-add lsw0 lp2
8225 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8226 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"
8228 ovn-nbctl lsp-add lsw0 lp3
8229 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8230 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"
8232 # Add ACL rule for ICMPv6 on lsw0
8233 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8234 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8235 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8236 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8238 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8239 set interface hv1-vif1 external-ids:iface-id=lp1 \
8240 options:tx_pcap=hv1/vif1-tx.pcap \
8241 options:rxq_pcap=hv1/vif1-rx.pcap \
8244 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8245 set interface hv1-vif2 external-ids:iface-id=lp2 \
8246 options:tx_pcap=hv1/vif2-tx.pcap \
8247 options:rxq_pcap=hv1/vif2-rx.pcap \
8250 ovs-vsctl -- add-port br-int hv1-vif3 -- \
8251 set interface hv1-vif3 external-ids:iface-id=lp3 \
8252 options:tx_pcap=hv1/vif3-tx.pcap \
8253 options:rxq_pcap=hv1/vif3-rx.pcap \
8256 # Allow some time for ovn-northd and ovn-controller to catch up.
8257 # XXX This should be more systematic.
8263 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8264 options:rxq_pcap=dummy-rx.pcap
8265 rm -f ${pcap_file}*.pcap
8266 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8267 options:rxq_pcap=${pcap_file}-rx.pcap
8270 # Make sure that ovn-controller has installed the corresponding OF Flow.
8271 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"`])
8273 # This shell function sends a Router Solicitation packet.
8274 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8276 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8277 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8281 if test $mtu != 0; then
8283 mtu_opt=05010000${mtu}
8286 if test ${#prefix_opt} != 0; then
8287 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8288 len=`expr $len + ${#prefix_opt} / 2`
8291 len=$(printf "%x" $len)
8292 local lrp_mac=fa163e000001
8293 local lrp_lla=fe80000000000000f8163efffe000001
8294 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8295 echo $reply >> $inport.expected
8297 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8300 AT_CAPTURE_FILE([ofctl_monitor0.log])
8301 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8302 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8304 # MTU is not set and the address mode is set to slaac
8306 default_prefix_option_config=030440c0ffffffffffffffff00000000
8307 src_mac=fa163e000002
8308 src_lla=fe80000000000000f8163efffe000002
8309 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8311 # NXT_RESUME should be 1.
8312 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8314 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8316 cat 1.expected | cut -c -112 > expout
8317 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8319 # Skipping the ICMPv6 checksum.
8320 cat 1.expected | cut -c 117- > expout
8321 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8324 reset_pcap_file hv1-vif1 hv1/vif1
8325 reset_pcap_file hv1-vif2 hv1/vif2
8326 reset_pcap_file hv1-vif3 hv1/vif3
8328 # Set the MTU to 1500
8329 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8331 # Make sure that ovn-controller has installed the corresponding OF Flow.
8332 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"`])
8335 default_prefix_option_config=030440c0ffffffffffffffff00000000
8336 src_mac=fa163e000003
8337 src_lla=fe80000000000000f8163efffe000003
8340 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8342 # NXT_RESUME should be 2.
8343 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8345 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8347 cat 2.expected | cut -c -112 > expout
8348 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8350 # Skipping the ICMPv6 checksum.
8351 cat 2.expected | cut -c 117- > expout
8352 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8355 reset_pcap_file hv1-vif1 hv1/vif1
8356 reset_pcap_file hv1-vif2 hv1/vif2
8357 reset_pcap_file hv1-vif3 hv1/vif3
8359 # Set the address mode to dhcpv6_stateful
8360 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8361 # Make sure that ovn-controller has installed the corresponding OF Flow.
8362 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"`])
8365 default_prefix_option_config=""
8366 src_mac=fa163e000004
8367 src_lla=fe80000000000000f8163efffe000004
8370 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8372 # NXT_RESUME should be 3.
8373 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8375 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8377 cat 3.expected | cut -c -112 > expout
8378 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8380 # Skipping the ICMPv6 checksum.
8381 cat 3.expected | cut -c 117- > expout
8382 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8385 reset_pcap_file hv1-vif1 hv1/vif1
8386 reset_pcap_file hv1-vif2 hv1/vif2
8387 reset_pcap_file hv1-vif3 hv1/vif3
8389 # Set the address mode to dhcpv6_stateless
8390 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8391 # Make sure that ovn-controller has installed the corresponding OF Flow.
8392 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"`])
8395 default_prefix_option_config=030440c0ffffffffffffffff00000000
8396 src_mac=fa163e000002
8397 src_lla=fe80000000000000f8163efffe000002
8400 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8402 # NXT_RESUME should be 4.
8403 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8405 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8407 cat 1.expected | cut -c -112 > expout
8408 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8410 # Skipping the ICMPv6 checksum.
8411 cat 1.expected | cut -c 117- > expout
8412 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8415 reset_pcap_file hv1-vif1 hv1/vif1
8416 reset_pcap_file hv1-vif2 hv1/vif2
8417 reset_pcap_file hv1-vif3 hv1/vif3
8419 # Set the address mode to invalid.
8420 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8421 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8422 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"`])
8425 default_prefix_option_config=""
8426 src_mac=fa163e000002
8427 src_lla=fe80000000000000f8163efffe000002
8430 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8432 # NXT_RESUME should be 4 only.
8433 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8435 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8436 AT_CHECK([cat 1.packets], [0], [])
8441 AT_SETUP([ovn -- /32 router IP address])
8442 AT_SKIP_IF([test $HAVE_PYTHON = no])
8446 # 2 LS 'foo' and 'alice' connected via router R1.
8447 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8448 # nexthop to push traffic to a logical port in switch 'alice'
8452 ovn-nbctl ls-add foo
8453 ovn-nbctl ls-add alice
8456 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8457 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8458 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8460 # Connect alice to R1.
8461 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8462 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8463 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8465 # Create logical port foo1 in foo
8466 ovn-nbctl lsp-add foo foo1 \
8467 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8469 # Create logical port alice1 in alice
8470 ovn-nbctl lsp-add alice alice1 \
8471 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8473 #install default route in R1 to use alice1's IP address as nexthop
8474 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8476 # Create two hypervisor and create OVS ports corresponding to logical ports.
8481 ovs-vsctl add-br br-phys
8482 ovn_attach n1 br-phys 192.168.0.1
8483 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8484 set interface hv1-vif1 external-ids:iface-id=foo1 \
8485 options:tx_pcap=hv1/vif1-tx.pcap \
8486 options:rxq_pcap=hv1/vif1-rx.pcap \
8491 ovs-vsctl add-br br-phys
8492 ovn_attach n1 br-phys 192.168.0.2
8493 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8494 set interface hv2-vif1 external-ids:iface-id=alice1 \
8495 options:tx_pcap=hv2/vif1-tx.pcap \
8496 options:rxq_pcap=hv2/vif1-rx.pcap \
8500 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8501 # packets for ARP resolution (native tunneling doesn't queue packets
8502 # for ARP resolution).
8505 # Allow some time for ovn-northd and ovn-controller to catch up.
8506 # XXX This should be more systematic.
8510 printf "%02x%02x%02x%02x" "$@"
8513 # Send ip packets between foo1 and alice1
8514 src_mac="f00000010203"
8515 dst_mac="000000010203"
8516 src_ip=`ip_to_hex 192 168 1 2`
8517 dst_ip=`ip_to_hex 10 0 0 2`
8518 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8520 # Send the first packet to trigger a ARP response and population of
8521 # mac_bindings table.
8522 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8523 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8524 ovn-nbctl --wait=hv sync
8525 # Send the second packet to reach the destination.
8526 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8528 # Packet to Expect at 'alice1'
8529 src_mac="000000010204"
8530 dst_mac="f00000010204"
8531 src_ip=`ip_to_hex 192 168 1 2`
8532 dst_ip=`ip_to_hex 10 0 0 2`
8533 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8535 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8537 OVN_CLEANUP([hv1],[hv2])
8541 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8542 AT_SKIP_IF([test $HAVE_PYTHON = no])
8545 ovn-nbctl ls-add ls1
8547 # Add localport to the switch
8548 ovn-nbctl lsp-add ls1 lp01
8549 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8550 ovn-nbctl lsp-set-type lp01 localport
8557 ovs-vsctl add-br br-phys
8558 ovn_attach n1 br-phys 192.168.0.$i
8559 ovs-vsctl add-port br-int vif01 -- \
8560 set Interface vif01 external-ids:iface-id=lp01 \
8561 options:tx_pcap=hv${i}/vif01-tx.pcap \
8562 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8563 ofport-request=${i}0
8565 ovs-vsctl add-port br-int vif${i}1 -- \
8566 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8567 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8568 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8569 ofport-request=${i}1
8571 ovn-nbctl lsp-add ls1 lp${i}1
8572 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8573 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8575 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8578 ovn-nbctl --wait=sb sync
8579 ovn-sbctl dump-flows
8583 # Given the name of a logical port, prints the name of the hypervisor
8584 # on which it is located.
8589 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8591 # This shell function causes a packet to be received on INPORT. The packet's
8592 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8593 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8594 # logical switch port numbers, e.g. 11 for vif11.
8596 # EOUT is the end-to-end output port, that is, where the packet will end up
8597 # after possibly bouncing through one or more localnet ports. LOUT is the
8598 # logical output port, which might be a localnet port, as seen by ovn-trace
8599 # (which doesn't know what localnet ports are connected to and therefore can't
8600 # figure out the end-to-end answer).
8602 # DEFHV is the default hypervisor from where the packet is going to be sent
8603 # if the source port is a localport.
8610 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8613 # First try tracing the packet.
8614 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8615 if test $lout != drop; then
8616 echo "output(\"$lout\");"
8618 AT_CAPTURE_FILE([trace])
8619 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8621 # Then actually send a packet, for an end-to-end test.
8622 local packet=$(echo $dst$src | sed 's/://g')${eth}
8623 hv=`vif_to_hv $inport`
8624 # If hypervisor 0 (localport) use the defhv parameter
8625 if test $hv = hv0; then
8629 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8630 if test $eout != drop; then
8631 echo $packet >> ${eout#lp}.expected
8636 # lp11 and lp21 are on different hypervisors
8637 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8638 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8640 # Both VIFs should be able to reach the localport on their own HV
8641 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8642 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8644 # Packet sent from localport on same hv should reach the vif
8645 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8646 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8648 # Packet sent from localport on different hv should be dropped
8649 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8650 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8652 # Now check the packets actually received against the ones expected.
8655 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8659 OVN_CLEANUP([hv1],[hv2])
8663 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8664 AT_SKIP_IF([test $HAVE_PYTHON = no])
8669 # create gateways with external network connectivity
8674 ovs-vsctl add-br br-phys
8675 ovn_attach n1 br-phys 192.168.0.$i
8676 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8679 ovn-nbctl ls-add inside
8680 ovn-nbctl ls-add outside
8682 # create hypervisors with a vif port each to an internal network
8687 ovs-vsctl add-br br-phys
8688 ovn_attach n1 br-phys 192.168.0.1$i
8689 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8690 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8691 options:tx_pcap=hv$i/vif1-tx.pcap \
8692 options:rxq_pcap=hv$i/vif1-rx.pcap \
8695 ovn-nbctl lsp-add inside inside$i \
8696 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8702 ovn-nbctl create Logical_Router name=R1
8704 # Connect inside to R1
8705 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8706 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8707 type=router options:router-port=inside \
8708 -- lsp-set-addresses rp-inside router
8710 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8711 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8713 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8714 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8715 --id=@gc1 create Gateway_Chassis \
8716 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8717 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8719 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8720 type=router options:router-port=outside \
8721 -- lsp-set-addresses rp-outside router
8723 # Create localnet port in outside
8724 ovn-nbctl lsp-add outside ln-outside
8725 ovn-nbctl lsp-set-addresses ln-outside unknown
8726 ovn-nbctl lsp-set-type ln-outside localnet
8727 ovn-nbctl lsp-set-options ln-outside network_name=phys
8729 # Allow some time for ovn-northd and ovn-controller to catch up.
8730 # XXX This should be more systematic.
8731 ovn-nbctl --wait=hv --timeout=3 sync
8733 echo "---------NB dump-----"
8735 echo "---------------------"
8736 ovn-nbctl list logical_router
8737 echo "---------------------"
8738 ovn-nbctl list logical_router_port
8739 echo "---------------------"
8741 echo "---------SB dump-----"
8742 ovn-sbctl list datapath_binding
8743 echo "---------------------"
8744 ovn-sbctl list port_binding
8745 echo "---------------------"
8746 ovn-sbctl dump-flows
8747 echo "---------------------"
8748 ovn-sbctl list chassis
8749 ovn-sbctl list encap
8750 echo "---------------------"
8751 echo "------ Gateway_Chassis dump (SBDB) -------"
8752 ovn-sbctl list Gateway_Chassis
8753 echo "------ Port_Binding chassisredirect -------"
8754 ovn-sbctl find Port_Binding type=chassisredirect
8755 echo "-------------------------------------------"
8757 for chassis in gw1 gw2 hv1 hv2; do
8759 echo "------ $chassis dump ----------"
8760 ovs-ofctl show br-int
8761 ovs-ofctl dump-flows br-int
8762 echo "--------------------------"
8764 function bfd_dump() {
8765 for chassis in gw1 gw2 hv1 hv2; do
8767 echo "------ $chassis dump (BFD)----"
8768 echo "BFD (from $chassis):"
8769 # dump BFD config and status to the other chassis
8770 for chassis2 in gw1 gw2 hv1 hv2; do
8771 if [[ "$chassis" != "$chassis2" ]]; then
8772 echo " -> $chassis2:"
8773 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8776 echo "--------------------------"
8782 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8783 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8784 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8785 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8787 echo $hv1_gw1_ofport
8788 echo $hv1_gw2_ofport
8789 echo $hv2_gw1_ofport
8790 echo $hv2_gw2_ofport
8793 as hv1 ovs-ofctl dump-flows br-int table=32
8796 as hv2 ovs-ofctl dump-flows br-int table=32
8798 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8799 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8801 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
8804 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
8807 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8809 # make sure that flows for handling the outside router port reside on gw1
8810 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8812 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8815 # make sure ARP responder flows for outside router port reside on gw1 too
8816 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8818 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8823 # check that the chassis redirect port has been claimed by the gw1 chassis
8824 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8829 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8831 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8832 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8833 --id=@gc1 create Gateway_Chassis \
8834 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8835 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8838 # XXX: Let the change propagate down to the ovn-controllers
8839 ovn-nbctl --wait=hv --timeout=3 sync
8841 # we make sure that the hypervisors noticed, and inverted the slave ports
8842 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
8845 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
8848 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8849 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8853 # check BFD enablement on tunnel ports from gw1 #########
8855 for chassis in gw2 hv1 hv2; do
8856 echo "checking gw1 -> $chassis"
8857 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8863 # check BFD enablement on tunnel ports from gw2 ##########
8865 for chassis in gw1 hv1 hv2; do
8866 echo "checking gw2 -> $chassis"
8867 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8872 # check BFD enablement on tunnel ports from hv1 ###########
8874 for chassis in gw1 gw2; do
8875 echo "checking hv1 -> $chassis"
8876 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8880 # make sure BFD is not enabled to hv2, we don't need it
8881 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8886 # check BFD enablement on tunnel ports from hv2 ##########
8888 for chassis in gw1 gw2; do
8889 echo "checking hv2 -> $chassis"
8890 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8894 # make sure BFD is not enabled to hv1, we don't need it
8895 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8899 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8901 # make sure that flows for handling the outside router port reside on gw2 now
8902 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8904 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8907 # disconnect GW2 from the network, GW1 should take over
8909 port=${sandbox}_br-phys
8910 as main ovs-vsctl del-port n1 $port
8915 # make sure that flows for handling the outside router port reside on gw2 now
8916 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8918 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8921 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8922 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8926 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8930 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8931 AT_SKIP_IF([test $HAVE_PYTHON = no])
8933 ovn-nbctl ls-add ls0
8934 ovn-nbctl ls-add ls1
8935 ovn-nbctl create Logical_Router name=lr0
8936 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8938 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8939 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8940 --id=@gc1 create Gateway_Chassis \
8941 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8942 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8944 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8945 type=router options:router-port=lrp0 addresses="router"
8946 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8947 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8948 type=router options:router-port=lrp1 addresses="router"
8951 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8956 ovs-vsctl add-br br-phys
8957 ovn_attach n1 br-phys 192.168.0.1
8958 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8959 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])
8963 ovs-vsctl add-br br-phys
8964 ovn_attach n1 br-phys 192.168.0.2
8965 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8969 ovs-vsctl add-br br-phys
8970 ovn_attach n1 br-phys 192.168.0.3
8971 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8973 # Create a localnet port.
8974 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8975 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8976 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8977 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8979 # wait for earlier changes to take effect
8980 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
8985 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8986 options:rxq_pcap=dummy-rx.pcap
8987 rm -f ${pcap_file}*.pcap
8988 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8989 options:rxq_pcap=${pcap_file}-rx.pcap
8992 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8993 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8994 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8995 # add nat-addresses option
8996 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8998 # Wait for packets to be received through hv2.
8999 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9001 sed 's/\(00\)\{1,\}$//'
9004 only_broadcast_from_lrp1() {
9005 grep "fffffffffffff00000000001"
9008 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
9011 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
9012 echo "packets on hv1-snoopvif:"
9014 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
9015 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9016 echo "packets on hv2 br-phys tx"
9018 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
9019 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9020 echo "packets on hv3 br-phys tx"
9022 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9025 # at this point, we invert the priority of the gw chassis between hv2 and hv3
9027 ovn-nbctl --wait=hv \
9028 --id=@gc0 create Gateway_Chassis \
9029 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9030 --id=@gc1 create Gateway_Chassis \
9031 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9032 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9035 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9036 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9037 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9039 # Wait for packets to be received.
9040 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9042 sed 's/\(00\)\{1,\}$//'
9045 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9046 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9047 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9048 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9049 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9050 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9052 # change localnet port tag.
9053 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9055 # wait for earlier changes to take effect
9056 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
9058 # update nat-addresses option
9059 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9060 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9062 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9063 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9064 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9066 # Wait for packets to be received.
9067 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9069 sed 's/\(00\)\{1,\}$//'
9072 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9075 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9076 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9077 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9078 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9079 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9080 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9082 OVN_CLEANUP([hv1],[hv2],[hv3])
9086 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9087 AT_SKIP_IF([test $HAVE_PYTHON = no])
9092 # create two gateways with external network connectivity
9096 ovs-vsctl add-br br-phys
9097 ovn_attach n1 br-phys 192.168.0.$i
9098 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9101 ovn-nbctl ls-add inside
9102 ovn-nbctl ls-add outside
9104 # create one hypervisors with a vif port the internal network
9107 ovs-vsctl add-br br-phys
9108 ovn_attach n1 br-phys 192.168.0.11
9109 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9110 set interface hv1-vif1 external-ids:iface-id=inside1 \
9111 options:tx_pcap=hv1/vif1-tx.pcap \
9112 options:rxq_pcap=hv1/vif1-rx.pcap \
9115 ovn-nbctl lsp-add inside inside1 \
9116 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9121 ovn-nbctl create Logical_Router name=R1
9123 # Connect inside to R1
9124 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9125 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9126 type=router options:router-port=inside \
9127 -- lsp-set-addresses rp-inside router
9129 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9130 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9132 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9133 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9134 --id=@gc1 create Gateway_Chassis \
9135 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9136 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9138 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9139 type=router options:router-port=outside \
9140 -- lsp-set-addresses rp-outside router
9142 # Create localnet port in outside
9143 ovn-nbctl lsp-add outside ln-outside
9144 ovn-nbctl lsp-set-addresses ln-outside unknown
9145 ovn-nbctl lsp-set-type ln-outside localnet
9146 ovn-nbctl lsp-set-options ln-outside network_name=phys
9148 # Allow some time for ovn-northd and ovn-controller to catch up.
9149 ovn-nbctl --wait=hv --timeout=3 sync
9151 # currently when ovn-controller is restarted, the old entry is deleted
9152 # and a new one is created, which leaves the Gateway_Chassis with
9153 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
9154 # doesn't have the same effect because "name" is conserved, and the
9155 # Chassis entry is not replaced.
9157 > gw1/ovn-controller.log
9159 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9160 ovn-sbctl destroy Chassis $gw2_chassis
9162 # Ensure ovn-controller has processed latest sbdb update
9163 # ovn-nbctl --wait=hv sync
9165 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9167 OVN_CLEANUP([gw1],[gw2],[hv1])
9171 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9172 AT_KEYWORDS([ovn-nd_ns for unknown mac])
9173 AT_SKIP_IF([test $HAVE_PYTHON = no])
9176 ovn-nbctl ls-add sw0_ip6
9177 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9178 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9179 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9181 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9182 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9184 ovn-nbctl lr-add lr0_ip6
9185 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
9186 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9187 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9188 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9189 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9190 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9192 ovn-nbctl ls-add public
9193 ovn-nbctl lsp-add public ln-public
9194 ovn-nbctl lsp-set-addresses ln-public unknown
9195 ovn-nbctl lsp-set-type ln-public localnet
9196 ovn-nbctl lsp-set-options ln-public network_name=phys
9198 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
9199 2001:db8:1:0:200:02ff:fe01:0204/64 \
9200 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9203 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9204 rp-ip6_public type=router options:router-port=ip6_public \
9205 -- lsp-set-addresses rp-ip6_public router
9210 ovs-vsctl add-br br-phys
9211 ovn_attach n1 br-phys 192.168.0.2
9213 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9214 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9215 options:tx_pcap=hv1/vif1-tx.pcap \
9216 options:rxq_pcap=hv1/vif1-rx.pcap \
9218 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9220 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9221 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9223 # There is only one chassis.
9224 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9225 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
9228 sed 's/\(00\)\{1,\}$//'
9231 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9232 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
9233 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9234 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9235 # This function sends ipv6 packet
9237 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9238 dst_ip=20010db800010000020002fffe010205
9240 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9241 packet=${packet}8000000000000000
9242 shift; shift; shift; shift
9244 dst_mac=3333ff010205
9245 src_mac=000002010204
9246 mcast_node_ip=ff0200000000000000000001ff010205
9247 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9248 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9249 expected_packet=${expected_packet}0101${src_mac}
9251 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9252 echo $expected_packet >> ipv6_ns.expected
9255 src_mac=506400000002
9256 dst_mac=00000000af01
9257 src_ip=aef0000000000000526400fffe000002
9258 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9259 # should be received by the ports attached to br-phys.
9260 test_ipv6 1 $src_mac $dst_mac $src_ip 2
9262 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9263 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9265 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9266 trim_zeros > 1.packets
9267 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9268 trim_zeros > 2.packets
9270 cat ipv6_ns.expected | cut -c -112 > expout
9271 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9272 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9274 # Skipping the ICMPv6 checksum
9275 cat ipv6_ns.expected | cut -c 117- > expout
9276 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9277 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9283 AT_SETUP([ovn -- options:requested-chassis for logical port])
9288 ovn-nbctl ls-add ls0
9289 ovn-nbctl lsp-add ls0 lsp0
9291 # create two hypervisors, each with one vif port
9294 ovs-vsctl add-br br-phys
9295 ovn_attach n1 br-phys 192.168.0.11
9296 ovs-vsctl -- add-port br-int hv1-vif0 -- \
9297 set Interface hv1-vif0 ofport-request=1
9301 ovs-vsctl add-br br-phys
9302 ovn_attach n1 br-phys 192.168.0.12
9303 ovs-vsctl -- add-port br-int hv2-vif0 -- \
9304 set Interface hv2-vif0 ofport-request=1
9306 # Allow only chassis hv1 to bind logical port lsp0.
9307 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9309 # Allow some time for ovn-northd and ovn-controller to catch up.
9310 ovn-nbctl --wait=hv --timeout=3 sync
9312 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9313 ovn-sbctl wait-until chassis hv1
9314 ovn-sbctl wait-until chassis hv2
9315 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9316 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9318 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9319 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9321 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9323 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9324 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9326 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9327 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9328 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9330 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9331 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9333 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9335 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9336 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9338 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9339 as hv1 ovs-ofctl dump-flows br-int
9340 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9341 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9343 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9344 # the requested chassis for lsp0 is changed from hv1 to hv2.
9345 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9347 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9348 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9349 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
9351 # (6) Chassis hv2 should add flows and hv1 should not.
9352 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9353 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9355 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9356 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9358 OVN_CLEANUP([hv1],[hv2])
9362 AT_SETUP([ovn -- options:requested-chassis with hostname])
9366 ovn-nbctl ls-add ls0
9367 ovn-nbctl lsp-add ls0 lsp0
9372 ovs-vsctl add-br br-phys
9373 ovn_attach n1 br-phys 192.168.0.11
9374 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
9376 ovn-sbctl wait-until chassis hv1
9377 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9378 echo "hv1_hostname=${hv1_hostname}"
9379 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9380 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9382 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9383 echo "hv1_uuid=${hv1_uuid}"
9384 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9385 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9386 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9387 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9389 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9390 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9391 ovn-nbctl --wait=hv --timeout=3 sync
9392 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9393 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9394 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9400 AT_SETUP([ovn -- IPv6 periodic RA])
9403 # This test sets up two hypervisors.
9404 # hv1 and hv2 run ovn-controllers, and
9405 # each has a VIF connected to the same
9406 # logical switch in OVN. The logical
9407 # switch is connected to a logical
9408 # router port that is configured to send
9409 # periodic router advertisements.
9411 # The reason for having two ovn-controller
9412 # hypervisors is to ensure that the
9413 # periodic RAs being sent by each ovn-controller
9414 # are kept to their local hypervisors. If the
9415 # packets are not kept local, then each port
9416 # will receive too many RAs.
9422 ovs-vsctl add-br br-phys
9423 ovn_attach n1 br-phys 192.168.0.2
9425 ovs-vsctl add-br br-phys
9426 ovn_attach n1 br-phys 192.168.0.3
9429 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
9432 ovn-nbctl lsp-add sw sw-ro
9433 ovn-nbctl lsp-set-type sw-ro router
9434 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9435 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9436 ovn-nbctl lsp-add sw sw-p1
9437 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9438 ovn-nbctl lsp-add sw sw-p2
9439 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9441 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9442 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9443 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9444 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9448 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9449 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9450 options:tx_pcap=hv$i/vif1-tx.pcap \
9451 options:rxq_pcap=hv$i/vif1-rx.pcap \
9455 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9456 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
9461 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9462 options:rxq_pcap=dummy-rx.pcap
9463 rm -f ${pcap_file}*.pcap
9464 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9465 options:rxq_pcap=${pcap_file}-rx.pcap
9469 construct_expected_ra() {
9470 local src_mac=000000000001
9471 local dst_mac=333300000001
9472 local src_addr=fe80000000000000020000fffe000001
9473 local dst_addr=ff020000000000000000000000000001
9477 local ra_prefix_la=$3
9479 local slla=0101${src_mac}
9481 if test $mtu != 0; then
9482 mtu_opt=05010000${mtu}
9487 while [[ $# -gt 0 ]] ; do
9490 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9494 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
9495 local icmp=8600XXXX${ra}
9497 local ip_len=$(expr ${#icmp} / 2)
9498 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
9500 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9501 local eth=${dst_mac}${src_mac}86dd${ip}
9503 echo $packet >> expected
9507 construct_expected_ra $@
9509 for i in hv1 hv2 ; do
9510 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9512 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9514 cat expected | cut -c -112 > expout
9515 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9517 # Skip ICMPv6 checksum.
9518 cat expected | cut -c 117- > expout
9519 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9522 as $i reset_pcap_file $i-vif1 $i/vif1
9528 # Baseline test with no MTU
9529 ra_test 0 00 c0 40 aef00000000000000000000000000000
9531 # Now make sure an MTU option makes it
9532 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9533 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9535 # Now test for multiple network prefixes
9536 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9537 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9539 # Test a different address mode now
9540 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9541 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9543 # And the other address mode
9544 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9545 ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9547 OVN_CLEANUP([hv1],[hv2])
9550 AT_SETUP([ovn -- ACL reject rule test])
9551 AT_KEYWORDS([acl-reject])
9552 AT_SKIP_IF([test $HAVE_PYTHON = no])
9555 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9557 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9558 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9559 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9560 # unreachable frame generated from ACL rule hit
9562 # INPORT is a lport number, e.g. 11 for vif11.
9563 # HV is a hypervisor number
9564 # ETH_SRC and ETH_DST are each 12 hex digits.
9565 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9566 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9568 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9569 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9573 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9575 local reply_icmp_ttl=ff
9576 local icmp_type_code_response=0301
9577 local icmp_data=00000000
9578 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9579 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9580 echo $reply >> vif$inport.expected
9582 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9585 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9587 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9588 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9589 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9590 test_ipv6_packet() {
9591 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9594 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9595 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9597 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9598 echo $reply >> vif$inport.expected
9600 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9603 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
9605 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9606 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9607 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9609 # INPORT is an lport number, e.g. 11 for vif11.
9610 # HV is an hypervisor number
9611 # ETH_SRC and ETH_DST are each 12 hex digits.
9612 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9613 # TCP_SPORT and TCP_DPORT are 4 hex digits.
9614 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9615 test_tcp_syn_packet() {
9616 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9617 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9618 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9622 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9624 local tcp_rst_ttl=ff
9625 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
9626 echo $reply >> vif$inport.expected
9628 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9631 # Create hypervisors hv[123].
9632 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9633 # Add all of the vifs to a single logical switch sw0.
9636 ovn-nbctl ls-add sw0
9640 ovs-vsctl add-br br-phys
9641 ovn_attach n1 br-phys 192.168.0.$i
9644 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9645 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9647 ovs-vsctl -- add-port br-int vif$i$j -- \
9648 set interface vif$i$j \
9649 external-ids:iface-id=sw0-p$i$j \
9650 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9651 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9657 # allow some time for ovn-northd and ovn-controller to catch up.
9661 printf "%02x%02x%02x%02x" "$@"
9665 : > vif${i}1.expected
9668 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9669 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9670 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
9672 # Allow some time for ovn-northd and ovn-controller to catch up.
9673 ovn-nbctl --timeout=3 --wait=hv sync
9675 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9676 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9677 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9679 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9681 test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
9682 test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
9683 test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486
9686 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9689 OVN_CLEANUP([hv1], [hv2], [hv3])
9692 AT_SETUP([ovn -- Port Groups])
9693 AT_KEYWORDS([ovnpg])
9694 AT_SKIP_IF([test $HAVE_PYTHON = no])
9699 # Three logical switches ls1, ls2, ls3.
9700 # One logical router lr0 connected to ls[123],
9701 # with nine subnets, three per logical switch:
9703 # lrp11 on ls1 for subnet 192.168.11.0/24
9704 # lrp12 on ls1 for subnet 192.168.12.0/24
9705 # lrp13 on ls1 for subnet 192.168.13.0/24
9707 # lrp33 on ls3 for subnet 192.168.33.0/24
9709 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9710 # digits are the subnet and the last digit distinguishes the VIF.
9712 # This test will create two port groups and uses them in ACL.
9715 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9721 ovn-nbctl ls-add ls$i
9725 -- lsp-add ls$i lp$i$j$k \
9726 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9728 # logical ports lp[12]?1 belongs to port group pg1
9729 if test $i != 3 && test $k == 1; then
9730 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9732 # logical ports lp[23]?2 belongs to port group pg2
9733 if test $i != 1 && test $k == 2; then
9734 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9740 ovn-nbctl lr-add lr0
9743 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9745 -- lsp-add ls$i lrp$i$j-attachment \
9746 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9747 options:router-port=lrp$i$j \
9748 addresses='"00:00:00:00:ff:'$i$j'"'
9752 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9753 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9755 # create ACLs on all lswitches to drop traffic from pg2 to pg1
9756 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9757 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9758 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9762 # Three hypervisors hv[123].
9763 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9764 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9765 # lp?3[123] all on hv3.
9767 # Given the name of a logical port, prints the name of the hypervisor
9768 # on which it is located.
9771 ?11) echo 1 ;; dnl (
9772 ?12 | ?21 | ?22) echo 2 ;; dnl (
9773 ?13 | ?23 | ?3?) echo 3 ;;
9777 # Given the name of a logical port, prints the name of its logical router
9778 # port, e.g. "vif_to_lrp 123" yields 12.
9783 # Given the name of a logical port, prints the name of its logical
9784 # switch, e.g. "vif_to_ls 123" yields 1.
9793 ovs-vsctl add-br br-phys
9794 ovn_attach n1 br-phys 192.168.0.$i
9799 hv=`vif_to_hv $i$j$k`
9800 as hv$hv ovs-vsctl \
9801 -- add-port br-int vif$i$j$k \
9802 -- set Interface vif$i$j$k \
9803 external-ids:iface-id=lp$i$j$k \
9804 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9805 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9806 ofport-request=$i$j$k
9811 # Pre-populate the hypervisors' ARP tables so that we don't lose any
9812 # packets for ARP resolution (native tunneling doesn't queue packets
9813 # for ARP resolution).
9816 # Allow some time for ovn-northd and ovn-controller to catch up.
9817 # XXX This should be more systematic.
9820 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9822 # This shell function causes a packet to be received on INPORT. The packet's
9823 # content has Ethernet destination DST and source SRC (each exactly 12 hex
9824 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9825 # more) list the VIFs on which the packet should be received. INPORT and the
9826 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9835 # This packet has bad checksums but logical L3 routing doesn't check.
9836 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9837 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9838 shift; shift; shift; shift; shift
9839 hv=hv`vif_to_hv $inport`
9840 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9841 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9842 in_ls=`vif_to_ls $inport`
9843 in_lrp=`vif_to_lrp $inport`
9845 out_ls=`vif_to_ls $outport`
9846 if test $in_ls = $out_ls; then
9847 # Ports on the same logical switch receive exactly the same packet.
9850 # Routing decrements TTL and updates source and dest MAC
9852 out_lrp=`vif_to_lrp $outport`
9853 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9854 fi >> $outport.expected
9858 as hv1 ovs-vsctl --columns=name,ofport list interface
9859 as hv1 ovn-sbctl list port_binding
9860 as hv1 ovn-sbctl list datapath_binding
9861 as hv1 ovn-sbctl list port_group
9862 as hv1 ovn-sbctl list address_set
9863 as hv1 ovn-sbctl dump-flows
9864 as hv1 ovs-ofctl dump-flows br-int
9866 # Send IP packets between all pairs of source and destination ports,
9867 # packets matches ACL (pg2 to pg1) should be dropped
9869 printf "%02x%02x%02x%02x" "$@"
9877 sip=`ip_to_hex 192 168 $is$js $ks`
9882 dip=`ip_to_hex 192 168 $id$jd $kd`
9883 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
9884 if test $d != $s; then unicast=$d; else unicast=; fi
9886 # packets matches ACL should be dropped
9887 if test $id != 3 && test $kd == 1; then
9888 if test $is != 1 && test $ks == 2; then
9892 test_ip $s $smac $dmac $sip $dip $unicast #1
9900 # Allow some time for packet forwarding.
9901 # XXX This can be improved.
9904 # Now check the packets actually received against the ones expected.
9908 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9914 # Gracefully terminate daemons
9915 OVN_CLEANUP([hv1], [hv2], [hv3])
9918 AT_SETUP([ovn -- ACLs on Port Groups])
9919 AT_KEYWORDS([ovnpg_acl])
9920 AT_SKIP_IF([test $HAVE_PYTHON = no])
9925 # Three logical switches ls1, ls2, ls3.
9926 # One logical router lr0 connected to ls[123],
9927 # with nine subnets, three per logical switch:
9929 # lrp11 on ls1 for subnet 192.168.11.0/24
9930 # lrp12 on ls1 for subnet 192.168.12.0/24
9931 # lrp13 on ls1 for subnet 192.168.13.0/24
9933 # lrp33 on ls3 for subnet 192.168.33.0/24
9935 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9936 # digits are the subnet and the last digit distinguishes the VIF.
9938 # This test will create two port groups and ACLs will be applied on them.
9941 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9947 ovn-nbctl ls-add ls$i
9951 -- lsp-add ls$i lp$i$j$k \
9952 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
9954 # logical ports lp[12]?1 belongs to port group pg1
9955 if test $i != 3 && test $k == 1; then
9956 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9958 # logical ports lp[23]?2 belongs to port group pg2
9959 if test $i != 1 && test $k == 2; then
9960 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9966 ovn-nbctl lr-add lr0
9969 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9971 -- lsp-add ls$i lrp$i$j-attachment \
9972 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9973 options:router-port=lrp$i$j \
9974 addresses='"00:00:00:00:ff:'$i$j'"'
9978 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9979 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9981 # create ACLs on pg1 to drop traffic from pg2 to pg1
9982 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
9983 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
9984 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
9988 # Three hypervisors hv[123].
9989 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9990 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9991 # lp?3[123] all on hv3.
9993 # Given the name of a logical port, prints the name of the hypervisor
9994 # on which it is located.
9997 ?11) echo 1 ;; dnl (
9998 ?12 | ?21 | ?22) echo 2 ;; dnl (
9999 ?13 | ?23 | ?3?) echo 3 ;;
10003 # Given the name of a logical port, prints the name of its logical router
10004 # port, e.g. "vif_to_lrp 123" yields 12.
10009 # Given the name of a logical port, prints the name of its logical
10010 # switch, e.g. "vif_to_ls 123" yields 1.
10019 ovs-vsctl add-br br-phys
10020 ovn_attach n1 br-phys 192.168.0.$i
10025 hv=`vif_to_hv $i$j$k`
10026 as hv$hv ovs-vsctl \
10027 -- add-port br-int vif$i$j$k \
10028 -- set Interface vif$i$j$k \
10029 external-ids:iface-id=lp$i$j$k \
10030 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10031 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10032 ofport-request=$i$j$k
10037 # Pre-populate the hypervisors' ARP tables so that we don't lose any
10038 # packets for ARP resolution (native tunneling doesn't queue packets
10039 # for ARP resolution).
10042 # Allow some time for ovn-northd and ovn-controller to catch up.
10043 # XXX This should be more systematic.
10046 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10048 # This shell function causes a packet to be received on INPORT. The packet's
10049 # content has Ethernet destination DST and source SRC (each exactly 12 hex
10050 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10051 # more) list the VIFs on which the packet should be received. INPORT and the
10052 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10056 : > $i$j$k.expected
10061 # This packet has bad checksums but logical L3 routing doesn't check.
10062 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10063 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10064 shift; shift; shift; shift; shift
10065 hv=hv`vif_to_hv $inport`
10066 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10067 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10068 in_ls=`vif_to_ls $inport`
10069 in_lrp=`vif_to_lrp $inport`
10071 out_ls=`vif_to_ls $outport`
10072 if test $in_ls = $out_ls; then
10073 # Ports on the same logical switch receive exactly the same packet.
10076 # Routing decrements TTL and updates source and dest MAC
10078 out_lrp=`vif_to_lrp $outport`
10079 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10080 fi >> $outport.expected
10084 as hv1 ovs-vsctl --columns=name,ofport list interface
10085 as hv1 ovn-sbctl list port_binding
10086 as hv1 ovn-sbctl list datapath_binding
10087 as hv1 ovn-sbctl list port_group
10088 as hv1 ovn-sbctl list address_set
10089 as hv1 ovn-sbctl dump-flows
10090 as hv1 ovs-ofctl dump-flows br-int
10092 # Send IP packets between all pairs of source and destination ports,
10093 # packets matches ACL1 but not ACL2 should be dropped
10095 printf "%02x%02x%02x%02x" "$@"
10097 for is in 1 2 3; do
10098 for js in 1 2 3; do
10099 for ks in 1 2 3; do
10103 sip=`ip_to_hex 192 168 $is$js $ks`
10104 for id in 1 2 3; do
10105 for jd in 1 2 3; do
10106 for kd in 1 2 3; do
10108 dip=`ip_to_hex 192 168 $id$jd $kd`
10109 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10110 if test $d != $s; then unicast=$d; else unicast=; fi
10112 # packets matches ACL1 but not ACL2 should be dropped
10113 if test $id != 3 && test $kd == 1; then
10114 if test $is == 1 || test $ks != 2; then
10118 test_ip $s $smac $dmac $sip $dip $unicast #1
10126 # Allow some time for packet forwarding.
10127 # XXX This can be improved.
10130 # Now check the packets actually received against the ones expected.
10134 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10140 # Gracefully terminate daemons
10141 OVN_CLEANUP([hv1], [hv2], [hv3])
10144 AT_SETUP([ovn -- ACL conjunction])
10147 ovn-nbctl ls-add ls1
10149 ovn-nbctl lsp-add ls1 ls1-lp1 \
10150 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10152 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10154 ovn-nbctl lsp-add ls1 ls1-lp2 \
10155 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10157 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10163 ovs-vsctl add-br br-phys
10164 ovn_attach n1 br-phys 192.168.0.1
10165 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10166 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10167 options:tx_pcap=hv1/vif1-tx.pcap \
10168 options:rxq_pcap=hv1/vif1-rx.pcap \
10171 ovs-vsctl -- add-port br-int hv1-vif2 -- \
10172 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10173 options:tx_pcap=hv1/vif2-tx.pcap \
10174 options:rxq_pcap=hv1/vif2-rx.pcap \
10177 ovn-nbctl create Address_Set name=set1 \
10178 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10179 ovn-nbctl create Address_Set name=set2 \
10180 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10181 ovn-nbctl acl-add ls1 to-lport 1002 \
10182 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10183 ovn-nbctl acl-add ls1 to-lport 1001 \
10184 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10186 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10188 # This shell function causes an ip packet to be received on INPORT.
10189 # The packet's content has Ethernet destination DST and source SRC
10190 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10191 # The OUTPORTs (zero or more) list the VIFs on which the packet should
10192 # be received. INPORT and the OUTPORTs are specified as logical switch
10193 # port numbers, e.g. 11 for vif11.
10195 # This packet has bad checksums but logical L3 routing doesn't check.
10196 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10197 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10198 ${dst_ip}0035111100080000
10199 shift; shift; shift; shift; shift
10200 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10202 echo $packet >> $outport.expected
10207 printf "%02x%02x%02x%02x" "$@"
10210 reset_pcap_file() {
10213 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10214 options:rxq_pcap=dummy-rx.pcap
10215 rm -f ${pcap_file}*.pcap
10216 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10217 options:rxq_pcap=${pcap_file}-rx.pcap
10221 sip=`ip_to_hex 10 0 0 4`
10222 dip=`ip_to_hex 10 0 0 6`
10224 test_ip 1 f00000000001 f00000000002 $sip $dip 2
10226 cat 2.expected > expout
10227 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10228 AT_CHECK([cat 2.packets], [0], [expout])
10230 # There should be total of 12 flows present with conjunction action and 2 flows
10231 # with conj match. Eg.
10232 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10233 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10234 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10235 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10236 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10237 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10238 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10239 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10240 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10241 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10242 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10243 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10244 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10245 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10247 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10248 grep conjunction | wc -l`])
10249 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10250 grep conj_id | wc -l`])
10252 as hv1 ovs-ofctl dump-flows br-int
10254 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10255 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10256 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10258 reset_pcap_file hv1-vif2 hv1/vif2
10262 sip=`ip_to_hex 10 0 0 4`
10263 dip=`ip_to_hex 10 0 0 7`
10265 test_ip 1 f00000000001 f00000000002 $sip $dip
10266 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10267 AT_CHECK([cat 2.packets], [0], [])