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 echo "rcv_n=$rcv_n exp_n=$exp_n"
24 test $rcv_n -ge $exp_n])
25 sort $exp_text > expout
28 m4_define([OVN_CHECK_PACKETS],
29 [ovn_check_packets__ "$1" "$2"
30 AT_CHECK([sort $rcv_text], [0], [expout])])
32 AT_BANNER([OVN components])
34 AT_SETUP([ovn -- lexer])
35 dnl For lines without =>, input and expected output are identical.
36 dnl For lines with =>, input precedes => and expected output follows =>.
37 AT_DATA([test-cases.txt], [dnl
38 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
39 "abc\u0020def" => "abc def"
40 " => error("Input ends inside quoted string.")dnl "
42 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
43 $1 => error("`$' must be followed by a valid identifier.") 1
48 a/*/b => a error("`/*' without matching `*/'.")
50 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
52 0 1 12345 18446744073709551615
53 18446744073709551616 => error("Decimal constants must be less than 2**64.")
54 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
55 01 => error("Decimal constants must not have leading zeros.")
59 1/0 => error("Value contains unmasked 1-bits.")
63 1/ => error("Integer constant expected.")
65 1/0x123 => error("Value and mask have incompatible formats.")
72 0XFEDCBA9876543210 => 0xfedcba9876543210
73 0xfedcba9876543210fedcba9876543210
74 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
75 0x => error("Hex digits expected following 0x.")
76 0X => error("Hex digits expected following 0X.")
79 0x1/0x0 => error("Value contains unmasked 1-bits.")
81 0x. => error("Invalid syntax in hexadecimal constant.")
83 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
84 256.1.2.3 => error("Invalid numeric constant.")
86 192.168.0.0/255.255.0.0 => 192.168.0.0/16
87 192.168.0.0/255.255.255.0 => 192.168.0.0/24
88 192.168.0.0/255.255.0.255
89 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
91 192.168.0.0/255.255.255.255 => 192.168.0.0/32
92 1.2.3.4:5 => 1.2.3.4 : 5
96 ff00::1234 => ff00::1234
97 2001:db8:85a3::8a2e:370:7334
98 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
99 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
101 ::ffff:c000:0280 => ::ffff:192.0.2.128
103 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106 ff00::/ff00:: => ff00::/8
109 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
111 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
112 01:00:00:00:00:00/01:00:00:00:00:00
113 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
114 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
115 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
116 fe:x => error("Invalid numeric constant.")
117 00:01:02:03:04:x => error("Invalid numeric constant.")
119 # Test that operators are tokenized as expected, even without white space.
120 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
121 & => error("`&' is only valid as part of `&&'.")
122 | => error("`|' is only valid as part of `||'.")
123 - => error("`-' is only valid as part of `--'.")
125 ^ => error("Invalid character `^' in input.")
127 AT_CAPTURE_FILE([input.txt])
128 sed 's/ =>.*//' test-cases.txt > input.txt
129 sed 's/.* => //' test-cases.txt > expout
130 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133 dnl The OVN expression parser needs to know what fields overlap with one
134 dnl another. This test therefore verifies that all the smaller registers
135 dnl are defined as terms of subfields of the larger ones.
137 dnl When we add or remove registers this test needs to be updated, of course.
138 AT_SETUP([ovn -- registers])
139 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
140 [[reg0 = xxreg0[96..127]
141 reg1 = xxreg0[64..95]
142 reg2 = xxreg0[32..63]
144 reg4 = xxreg1[96..127]
145 reg5 = xxreg1[64..95]
146 reg6 = xxreg1[32..63]
150 xreg0 = xxreg0[64..127]
151 xreg1 = xxreg0[0..63]
152 xreg2 = xxreg1[64..127]
153 xreg3 = xxreg1[0..63]
154 xreg4 = OXM_OF_PKT_REG4
155 xxreg0 = NXM_NX_XXREG0
156 xxreg1 = NXM_NX_XXREG1
160 dnl Check that the OVN conntrack field definitions are correct.
161 AT_SETUP([ovn -- conntrack fields])
162 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
163 [[ct.dnat = ct_state[7]
169 ct.snat = ct_state[6]
171 ct_label = NXM_NX_CT_LABEL
172 ct_label.blocked = ct_label[0]
173 ct_mark = NXM_NX_CT_MARK
174 ct_state = NXM_NX_CT_STATE
178 AT_SETUP([ovn -- composition])
179 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
182 AT_SETUP([ovn -- expression parser])
183 dnl For lines without =>, input and expected output are identical.
184 dnl For lines with =>, input precedes => and expected output follows =>.
185 AT_DATA([test-cases.txt], [[
187 eth.type==0x800 => eth.type == 0x800
188 eth.type[0..15] == 0x800 => eth.type == 0x800
191 vlan.present == 1 => vlan.present
192 !(vlan.present == 0) => vlan.present
193 !(vlan.present != 1) => vlan.present
195 vlan.present == 0 => !vlan.present
196 vlan.present != 1 => !vlan.present
197 !(vlan.present == 1) => !vlan.present
198 !(vlan.present != 0) => !vlan.present
201 eth.dst[0] == 1 => eth.dst[0]
202 eth.dst[0] != 0 => eth.dst[0]
203 !(eth.dst[0] == 0) => eth.dst[0]
204 !(eth.dst[0] != 1) => eth.dst[0]
207 eth.dst[0] == 0 => !eth.dst[0]
208 eth.dst[0] != 1 => !eth.dst[0]
209 !(eth.dst[0] == 1) => !eth.dst[0]
210 !(eth.dst[0] != 0) => !eth.dst[0]
212 vlan.tci[12..15] == 0x3
213 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
214 vlan.tci[12..15] != 0x3
215 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
217 !vlan.pcp => vlan.pcp == 0
218 !(vlan.pcp) => vlan.pcp == 0
225 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
226 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
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 0x4 == vlan.pcp => vlan.pcp == 0x4
232 0x4 != vlan.pcp => 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
244 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
245 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && 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 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
250 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
251 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
252 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
253 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
254 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
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 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
259 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
260 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
261 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
263 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
264 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
267 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 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)
270 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)
273 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
274 ip6.src == ::1 => ip6.src == 0x1
276 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
277 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
278 ip6.src == ::1 => ip6.src == 0x1
286 !(inport != "eth0") => inport == "eth0"
288 (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => 0
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 ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) => Parentheses nested too deeply.
359 ct_label > $set4 => Only == and != operators may be used to compare a field against an empty value set.
361 sed 's/ =>.*//' test-cases.txt > input.txt
362 sed 's/.* => //' test-cases.txt > expout
363 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
366 AT_SETUP([ovn -- expression annotation])
367 dnl Input precedes =>, expected output follows =>.
368 dnl Empty lines and lines starting with # are ignored.
369 AT_DATA([test-cases.txt], [[
370 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
371 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
372 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
373 ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
374 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
376 # Nested expressions over a single symbol should be annotated with symbol's
377 # prerequisites only once, at the top level.
378 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)
380 ip => eth.type == 0x800 || eth.type == 0x86dd
381 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
382 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
383 ip > 0 => Only == and != operators may be used with nominal field ip.
384 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
385 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
387 vlan.present => vlan.tci[12]
388 !vlan.present => !vlan.tci[12]
390 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
391 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
392 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
394 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
395 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
396 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
398 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
399 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
400 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'.
401 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'.
403 sed 's/ =>.*//' test-cases.txt > input.txt
404 sed 's/.* => //' test-cases.txt > expout
405 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
408 AT_SETUP([ovn -- 1-term expression conversion])
409 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
410 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
414 AT_SETUP([ovn -- 2-term expression conversion])
415 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
416 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
420 AT_SETUP([ovn -- 3-term expression conversion])
421 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
422 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
426 AT_SETUP([ovn -- 3-term numeric expression simplification])
427 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
428 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
432 AT_SETUP([ovn -- 4-term string expression simplification])
433 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
434 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
438 AT_SETUP([ovn -- 3-term mixed expression simplification])
439 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
440 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
444 AT_SETUP([ovn -- simplification special cases])
446 echo "$1" | ovstest test-ovn simplify-expr
448 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
450 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
452 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
453 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
455 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
456 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
458 AT_CHECK([simplify 'tcp.dst > 0'], [0],
459 [[(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)
461 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
462 [[(!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)
466 AT_SETUP([ovn -- is_chassis_resident simplification])
468 echo "$1" | ovstest test-ovn simplify-expr
470 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
472 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
474 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
476 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
480 AT_SETUP([ovn -- 4-term numeric expression normalization])
481 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
482 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
486 AT_SETUP([ovn -- 4-term string expression normalization])
487 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
488 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
492 AT_SETUP([ovn -- 4-term mixed expression normalization])
493 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
494 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
498 AT_SETUP([ovn -- 5-term numeric expression normalization])
499 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
500 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
504 AT_SETUP([ovn -- 5-term string expression normalization])
505 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
506 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
510 AT_SETUP([ovn -- 5-term mixed expression normalization])
511 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
512 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
516 AT_SETUP([ovn -- 4-term numeric expressions to flows])
517 AT_KEYWORDS([expression])
518 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
519 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
523 AT_SETUP([ovn -- 4-term string expressions to flows])
524 AT_KEYWORDS([expression])
525 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
526 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
530 AT_SETUP([ovn -- 4-term mixed expressions to flows])
531 AT_KEYWORDS([expression])
532 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
533 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
537 AT_SETUP([ovn -- 3-term numeric expressions to flows])
538 AT_KEYWORDS([expression])
539 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
540 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
544 AT_SETUP([ovn -- converting expressions to flows -- string fields])
545 AT_KEYWORDS([expression])
547 echo "$1" | ovstest test-ovn expr-to-flows | sort
549 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
551 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
553 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
555 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
559 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
563 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
565 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
570 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
576 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
581 AT_SETUP([ovn -- converting expressions to flows -- address sets])
582 AT_KEYWORDS([expression])
584 echo "$1" | ovstest test-ovn expr-to-flows | sort
586 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
591 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
596 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
602 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
609 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
614 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
620 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
621 dl_src=00:00:00:00:00:01
622 dl_src=00:00:00:00:00:02
623 dl_src=00:00:00:00:00:03
625 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
626 dl_src=00:00:00:00:00:01
627 dl_src=00:00:00:00:00:02
628 dl_src=00:00:00:00:00:03
630 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
631 dl_src=00:00:00:00:00:01
632 dl_src=00:00:00:00:00:02
633 dl_src=00:00:00:00:00:03
634 dl_src=ba:be:be:ef:de:ad
636 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
639 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
642 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
645 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
648 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
649 ip,nw_src=0.0.0.0/1.0.0.0
650 ip,nw_src=128.0.0.0/1
651 ip,nw_src=16.0.0.0/16.0.0.0
652 ip,nw_src=2.0.0.0/2.0.0.0
653 ip,nw_src=32.0.0.0/32.0.0.0
654 ip,nw_src=4.0.0.0/4.0.0.0
655 ip,nw_src=64.0.0.0/64.0.0.0
656 ip,nw_src=8.0.0.0/8.0.0.0
658 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
659 ip,nw_src=0.0.0.0/1.0.0.0
660 ip,nw_src=128.0.0.0/1
661 ip,nw_src=16.0.0.0/16.0.0.0
662 ip,nw_src=2.0.0.0/2.0.0.0
663 ip,nw_src=32.0.0.0/32.0.0.0
664 ip,nw_src=4.0.0.0/4.0.0.0
665 ip,nw_src=64.0.0.0/64.0.0.0
666 ip,nw_src=8.0.0.0/8.0.0.0
670 AT_SETUP([ovn -- converting expressions to flows -- port groups])
671 AT_KEYWORDS([expression])
673 echo "$1" | ovstest test-ovn expr-to-flows | sort
675 AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
680 AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
683 AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
688 AT_SETUP([ovn -- converting expressions to flows -- conjunction])
689 AT_KEYWORDS([conjunction])
691 echo "$1" | ovstest test-ovn expr-to-flows | sort
694 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
695 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
696 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
698 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
699 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
700 ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
701 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
702 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
703 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
706 lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
707 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
708 ct_state=+est+trk,ct_label=0x1/0x1,ip
709 ct_state=+est+trk,ct_label=0x1/0x1,ipv6
711 ct_state=-est+trk,ipv6
714 lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
715 ip4.dst == {20.0.0.1, 20.0.0.2}"
716 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
718 ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
719 ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
720 ip,nw_src=10.0.0.1: conjunction(1, 1/2)
721 ip,nw_src=10.0.0.2: conjunction(1, 1/2)
722 ip,nw_src=10.0.0.3: conjunction(1, 1/2)
725 lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
726 ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
727 tcp.dst >= 1000 && tcp.dst <= 1010"
729 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
731 tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
732 tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
733 tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
734 tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
735 tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
736 tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
737 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
738 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
739 tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
740 tcp,tp_dst=1000: conjunction(1, 2/3)
741 tcp,tp_dst=1001: conjunction(1, 2/3)
742 tcp,tp_dst=1010: conjunction(1, 2/3)
745 lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
746 ((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
747 tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
748 || ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
750 AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
752 ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
753 ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
754 ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
755 ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
756 ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
757 ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
758 tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
759 tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
760 tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
761 tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
762 tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
763 tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
764 tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
765 tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
766 tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
767 tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
768 tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
769 tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
770 tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
771 tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
772 tcp,tp_dst=1000: conjunction(1, 2/4)
773 tcp,tp_dst=1001: conjunction(1, 2/4)
774 tcp,tp_dst=2000: conjunction(1, 2/4)
775 tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
776 tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
777 tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
778 tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
779 tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
780 tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
781 tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
782 tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
783 tcp,tp_src=1000: conjunction(1, 3/4)
784 tcp,tp_src=1001: conjunction(1, 3/4)
785 tcp,tp_src=2000: conjunction(1, 3/4)
789 AT_SETUP([ovn -- action parsing])
790 dnl Unindented text is input (a set of OVN logical actions).
791 dnl Indented text is expected output.
792 AT_DATA([test-cases.txt],
797 Syntax error at `next' expecting end of input.
799 Syntax error at `drop' expecting action.
803 encodes as resubmit(,64)
807 encodes as resubmit(,19)
810 encodes as resubmit(,19)
812 encodes as resubmit(,8)
814 encodes as resubmit(,31)
817 Syntax error at `)' expecting "pipeline" or "table".
819 Syntax error at `;' expecting `)'.
821 "next" action cannot advance beyond table 23.
825 encodes as resubmit(,19)
826 next(pipeline=ingress);
828 encodes as resubmit(,19)
829 next(table=11, pipeline=ingress);
831 encodes as resubmit(,19)
832 next(pipeline=ingress, table=11);
834 encodes as resubmit(,19)
836 next(pipeline=egress);
837 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
841 encodes as resubmit(,18)
843 # Loading a constant value.
845 formats as tcp.dst = 80;
846 encodes as set_field:80->tcp_dst
847 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
849 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
851 encodes as set_field:0x4000/0xe000->vlan_tci
852 has prereqs vlan.tci[12]
853 vlan.tci[13..15] = 2;
854 encodes as set_field:0x4000/0xe000->vlan_tci
856 encodes as set_field:0->reg14
858 formats as ip.ttl = 4;
859 encodes as set_field:4->nw_ttl
860 has prereqs eth.type == 0x800 || eth.type == 0x86dd
861 outport="eth0"; next; outport="LOCAL"; next;
862 formats as outport = "eth0"; next; outport = "LOCAL"; next;
863 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
866 Cannot select subfield of string field inport.
868 Cannot select subfield of nominal field ip.proto.
870 Syntax error at `==' expecting `=' or `<->'.
872 Predicate symbol ip used where lvalue required.
874 Field ip.proto is not modifiable.
876 Syntax error at `{' expecting constant.
878 Syntax error at `{' expecting constant.
880 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
882 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'.
884 Predicate symbol vlan.present used where lvalue required.
886 # Moving one field into another.
888 formats as reg0 = reg1;
889 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
890 vlan.pcp = reg0[0..2];
891 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
892 has prereqs vlan.tci[12]
893 reg0[10] = vlan.pcp[1];
894 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
895 has prereqs vlan.tci[12]
897 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
899 reg0[0] = vlan.present;
900 Predicate symbol vlan.present used where lvalue required.
902 Can't assign 11-bit value to 32-bit destination.
904 Can't assign integer field (reg0) to string field (inport).
906 String fields inport and big_string are incompatible for assignment.
907 ip.proto = reg0[0..7];
908 Field ip.proto is not modifiable.
912 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]
913 vlan.pcp <-> reg0[0..2];
914 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]
915 has prereqs vlan.tci[12]
916 reg0[10] <-> vlan.pcp[1];
917 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
918 has prereqs vlan.tci[12]
920 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
922 reg0[0] <-> vlan.present;
923 Predicate symbol vlan.present used where lvalue required.
924 reg0 <-> reg1[0..10];
925 Can't exchange 32-bit field with 11-bit field.
927 Can't exchange string field (inport) with integer field (reg0).
928 inport <-> big_string;
929 String fields inport and big_string are incompatible for exchange.
930 ip.proto <-> reg0[0..7];
931 Field ip.proto is not modifiable.
932 reg0[0..7] <-> ip.proto;
933 Field ip.proto is not modifiable.
940 Syntax error at end of input expecting `--'.
944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
948 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
950 ct_lb(192.168.1.2:80, 192.168.1.3:80);
953 ct_lb(192.168.1.2, 192.168.1.3, );
954 formats as ct_lb(192.168.1.2, 192.168.1.3);
957 ct_lb(fd0f::2, fd0f::3, );
958 formats as ct_lb(fd0f::2, fd0f::3);
963 Syntax error at `)' expecting port number.
964 ct_lb(192.168.1.2:123456);
965 Syntax error at `123456' expecting port number.
967 Syntax error at `foo' expecting IP address.
968 ct_lb([192.168.1.2]);
969 Syntax error at `192.168.1.2' expecting IPv6 address.
973 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
981 formats as ct_commit;
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
984 ct_commit(ct_mark=1);
985 formats as ct_commit(ct_mark=0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
988 ct_commit(ct_mark=1/1);
989 formats as ct_commit(ct_mark=0x1/0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
992 ct_commit(ct_label=1);
993 formats as ct_commit(ct_label=0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
996 ct_commit(ct_label=1/1);
997 formats as ct_commit(ct_label=0x1/0x1);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
1000 ct_commit(ct_mark=1, ct_label=2);
1001 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
1002 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
1005 ct_commit(ct_label=0x01020304050607080910111213141516);
1006 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1009 ct_commit(ct_label=0x181716151413121110090807060504030201);
1010 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1011 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1013 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1016 ct_commit(ct_label=18446744073709551615);
1017 formats as ct_commit(ct_label=0xffffffffffffffff);
1018 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1020 ct_commit(ct_label=18446744073709551616);
1021 Decimal constants must be less than 2**64.
1025 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
1027 ct_dnat(192.168.1.2);
1028 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
1031 ct_dnat(192.168.1.2, 192.168.1.3);
1032 Syntax error at `,' expecting `)'.
1034 Syntax error at `foo' expecting IPv4 address.
1036 Syntax error at `foo' expecting IPv4 address.
1038 Syntax error at `)' expecting IPv4 address.
1042 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
1044 ct_snat(192.168.1.2);
1045 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
1048 ct_snat(192.168.1.2, 192.168.1.3);
1049 Syntax error at `,' expecting `)'.
1051 Syntax error at `foo' expecting IPv4 address.
1053 Syntax error at `foo' expecting IPv4 address.
1055 Syntax error at `)' expecting IPv4 address.
1062 clone { ip4.dst = 255.255.255.255; output; }; next;
1063 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
1064 has prereqs eth.type == 0x800
1067 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1068 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)
1071 formats as arp { drop; };
1072 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1076 get_arp(outport, ip4.dst);
1077 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[]
1078 has prereqs eth.type == 0x800
1079 get_arp(inport, reg0);
1080 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[]
1083 Syntax error at `;' expecting `('.
1085 Syntax error at `)' expecting field name.
1087 Syntax error at `)' expecting `,'.
1088 get_arp(inport ip4.dst);
1089 Syntax error at `ip4.dst' expecting `,'.
1090 get_arp(inport, ip4.dst;
1091 Syntax error at `;' expecting `)'.
1092 get_arp(inport, eth.dst);
1093 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1094 get_arp(inport, outport);
1095 Cannot use string field outport where numeric field is required.
1096 get_arp(reg0, ip4.dst);
1097 Cannot use numeric field reg0 where string field is required.
1100 put_arp(inport, arp.spa, arp.sha);
1101 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[]
1102 has prereqs eth.type == 0x806 && eth.type == 0x806
1105 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1106 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)
1107 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",wpad="https://example.org");
1108 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", wpad = "https://example.org");
1109 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.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67,pause)
1110 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);
1111 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);
1112 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)
1114 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1115 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1116 reg1[0] = put_dhcp_opts();
1117 put_dhcp_opts requires offerip to be specified.
1118 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1119 Syntax error at `x' expecting DHCPv4 option name.
1120 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1121 put_dhcp_opts requires offerip to be specified.
1122 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1123 Syntax error at `"hi"'.
1124 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1125 Syntax error at `xyzzy' expecting DHCPv4 option name.
1126 reg1[0] = put_dhcp_opts(offerip="xyzzy");
1127 DHCPv4 option offerip requires numeric value.
1128 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1129 DHCPv4 option domain requires string value.
1132 nd_ns { nd.target = xxreg0; output; };
1133 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)
1137 formats as nd_ns { drop; };
1138 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1142 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; };
1143 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1144 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)
1147 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; };
1148 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; };
1149 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)
1153 get_nd(outport, ip6.dst);
1154 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[]
1155 has prereqs eth.type == 0x86dd
1156 get_nd(inport, xxreg0);
1157 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[]
1159 Syntax error at `;' expecting `('.
1161 Syntax error at `)' expecting field name.
1163 Syntax error at `)' expecting `,'.
1164 get_nd(inport ip6.dst);
1165 Syntax error at `ip6.dst' expecting `,'.
1166 get_nd(inport, ip6.dst;
1167 Syntax error at `;' expecting `)'.
1168 get_nd(inport, eth.dst);
1169 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1170 get_nd(inport, outport);
1171 Cannot use string field outport where numeric field is required.
1172 get_nd(xxreg0, ip6.dst);
1173 Cannot use numeric field xxreg0 where string field is required.
1176 put_nd(inport, nd.target, nd.sll);
1177 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[]
1178 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)
1181 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1182 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)
1183 reg1[0] = put_dhcpv6_opts();
1184 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1185 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1186 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1187 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)
1188 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1189 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1190 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)
1191 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1192 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)
1193 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1194 Syntax error at `x' expecting DHCPv6 option name.
1195 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1196 Syntax error at `"hi"'.
1197 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1198 Syntax error at `xyzzy' expecting DHCPv6 option name.
1199 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1200 DHCPv6 option ia_addr requires numeric value.
1201 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1202 DHCPv6 option domain_search requires string value.
1206 encodes as set_queue:0
1208 encodes as set_queue:61440
1210 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1213 reg1[0] = dns_lookup();
1214 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1216 reg1[0] = dns_lookup("foo");
1217 dns_lookup doesn't take any parameters
1221 Rate 0 for set_meter is not in valid.
1224 set_meter(100, 1000);
1226 set_meter(100, 1000, );
1227 Syntax error at `,' expecting `)'.
1228 set_meter(4294967295, 4294967295);
1232 log(verdict=allow, severity=warning);
1233 encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
1234 log(name="test1", verdict=drop, severity=info);
1235 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
1236 log(verdict=drop, severity=info, meter="meter1");
1237 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
1238 log(name="test1", verdict=drop, severity=info, meter="meter1");
1239 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
1241 formats as log(verdict=drop, severity=info);
1242 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
1243 log(verdict=bad_verdict, severity=info);
1244 Syntax error at `bad_verdict' unknown verdict.
1245 log(verdict=drop, severity=bad_severity);
1246 Syntax error at `bad_severity' unknown severity.
1247 log(severity=notice);
1248 Syntax error at `;' expecting verdict.
1251 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1252 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)
1254 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1255 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)
1257 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1258 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)
1260 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1261 slla option not present
1262 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);
1263 prefix option can't be set when address mode is dhcpv6_stateful.
1264 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);
1265 prefix option can't be set when address mode is dhcpv6_stateful.
1266 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1267 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1268 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1269 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1270 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1271 Syntax error at `dhcpv6_stateless' expecting constant.
1272 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1273 Invalid value for "prefix" option
1274 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1275 Invalid value for "addr_mode" option
1276 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1277 IPv6 ND RA option mtu requires numeric value.
1278 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1279 Invalid value for "mtu" option
1282 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1283 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)
1287 formats as icmp4 { drop; };
1288 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1292 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1293 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)
1297 formats as icmp6 { drop; };
1298 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1302 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1303 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)
1307 formats as tcp_reset { drop; };
1308 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1311 # Contradictionary prerequisites (allowed but not useful):
1312 ip4.src = ip6.src[0..31];
1313 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1314 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1315 ip4.src <-> ip6.src[0..31];
1316 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[]
1317 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1319 # Miscellaneous negative tests.
1321 Syntax error at `;'.
1323 Syntax error at `xyzzy' expecting action.
1325 Syntax error at `123'.
1327 Syntax error at `xyzzy' expecting action.
1329 Syntax error at end of input expecting `;'.
1331 sed '/^[[ ]]/d' test-cases.txt > input.txt
1332 cp test-cases.txt expout
1333 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1336 AT_BANNER([OVN end-to-end tests])
1338 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1339 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1340 AT_KEYWORDS([ovnarp])
1341 AT_SKIP_IF([test $HAVE_PYTHON = no])
1344 # Create hypervisors hv[123].
1345 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1346 # Add all of the vifs to a single logical switch lsw0.
1347 # Turn on port security on all the vifs except vif[123]1.
1348 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1349 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1350 ovn-nbctl ls-add lsw0
1355 ovs-vsctl add-br br-phys
1356 ovn_attach n1 br-phys 192.168.0.$i
1359 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
1360 ovn-nbctl lsp-add lsw0 lp$i$j
1361 if test $j = 1; then
1362 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1364 if test $j = 3; then
1365 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1367 ip_addrs="192.168.0.$i$j"
1369 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1370 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1374 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1375 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1376 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1377 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\"
1378 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1381 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1384 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1385 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1387 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1388 # packets for ARP resolution (native tunneling doesn't queue packets
1389 # for ARP resolution).
1392 # Allow some time for ovn-northd and ovn-controller to catch up.
1393 # XXX This should be more systematic.
1396 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1397 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1398 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1399 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1401 # Given the name of a logical port, prints the name of the hypervisor
1402 # on which it is located.
1407 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1409 # This shell function causes a packet to be received on INPORT. The packet's
1410 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1411 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1412 # more) list the VIFs on which the packet should be received. INPORT and the
1413 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1420 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1421 hv=`vif_to_hv $inport`
1423 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1425 echo $packet >> $outport.expected
1429 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1431 # Causes a packet to be received on INPORT. The packet is an ARP
1432 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1433 # it should be the hardware address of the target to expect to receive in an
1434 # ARP reply; otherwise no reply is expected.
1436 # INPORT is an logical switch port number, e.g. 11 for vif11.
1437 # SHA and REPLY_HA are each 12 hex digits.
1438 # SPA and TPA are each 8 hex digits.
1440 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1441 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1442 hv=`vif_to_hv $inport`
1443 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1445 if test X$reply_ha = X; then
1446 # Expect to receive the broadcast ARP on the other logical switch ports
1447 # if no reply is expected.
1451 if test $i$j != $inport; then
1452 echo $request >> $i$j.expected
1457 # Expect to receive the reply, if any.
1458 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1459 echo $reply >> $inport.expected
1464 printf "%02x%02x%02x%02x" "$@"
1467 # Send packets between all pairs of source and destination ports:
1469 # 1. Unicast packets are delivered to exactly one logical switch port
1470 # (except that packets destined to their input ports are dropped).
1472 # 2. Broadcast and multicast are delivered to all logical switch ports
1473 # except the input port.
1475 # 3. When port security is turned on, the switch drops packets from the wrong
1478 # 4. The switch drops all packets with a VLAN tag.
1480 # 5. The switch drops all packets with a multicast source address. (This only
1481 # affects behavior when port security is turned off, since otherwise port
1482 # security would drop the packet anyway.)
1484 # 6. The switch delivers packets with an unknown destination to logical
1485 # switch ports with "unknown" among their MAC addresses (and port
1486 # security disabled).
1488 # 7. The switch drops unicast packets that violate an ACL.
1490 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1492 # 9. OVN generates responses to ARP requests for known IPs, except for
1493 # requests from a port for the port's own IP.
1495 # 10. No response to ARP requests for unknown IPs.
1508 if test $d != $s; then unicast=$d; else unicast=; fi
1509 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1511 if test $d != $s && test $js = 1; then
1516 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1518 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1519 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1520 if test $d = $s || (test $js = 1 && test $d = 33); then
1521 # Source of 11, 21, or 31 and dest of 33 should be dropped
1522 # due to the 4th ACL that uses address_set(set1).
1527 if test $d = $s || test $d = 22 || test $d = 33; then
1528 # dest of 22 and 33 should be dropped
1529 # due to the 5th ACL that uses port_group(pg1).
1534 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1535 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1536 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1537 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1538 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1540 test_packet $s f000000000$d f00000000055 810000091234 #4
1541 test_packet $s f000000000$d 0100000000$s $s$d #5
1543 if test $d != $s && test $jd = 1; then
1544 unknown="$unknown $d"
1546 bcast="$bcast $unicast"
1547 bacl2="$bacl2 $acl2"
1548 bacl3="$bacl3 $acl3"
1550 sip=`ip_to_hex 192 168 0 $is$js`
1551 tip=`ip_to_hex 192 168 0 $id$jd`
1552 tip_unknown=`ip_to_hex 11 11 11 11`
1553 if test $d != $s; then
1554 reply_ha=f000000000$d
1558 test_arp $s f000000000$s $sip $tip $reply_ha #9
1559 test_arp $s f000000000$s $sip $tip_unknown #10
1561 if test $jd = 3; then
1562 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1563 tip=`ip_to_hex 192 169 0 $id$jd`
1564 test_arp $s f000000000$s $sip $tip $reply_ha #9
1569 # Broadcast and multicast.
1570 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1571 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1572 if test $js = 1; then
1573 bcast_impersonate=$bcast
1577 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1579 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1581 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1582 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1583 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1584 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1585 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1586 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1590 # set address for lp13 with invalid characters.
1591 # lp13 should be configured with only 192.168.0.13.
1592 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1594 # Allow some time for ovn-northd and ovn-controller to catch up.
1595 # XXX This should be more systematic.
1598 sip=`ip_to_hex 192 168 0 11`
1599 tip=`ip_to_hex 192 168 0 13`
1600 test_arp 11 f00000000011 $sip $tip f00000000013
1602 tip=`ip_to_hex 192 169 0 13`
1603 #arp request for 192.169.0.13 should be flooded
1604 test_arp 11 f00000000011 $sip $tip
1606 # dump information and flows with counters
1607 ovn-sbctl dump-flows -- list multicast_group
1609 echo "------ hv1 dump ------"
1610 as hv1 ovs-vsctl show
1611 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1613 echo "------ hv2 dump ------"
1614 as hv2 ovs-vsctl show
1615 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1617 echo "------ hv3 dump ------"
1618 as hv3 ovs-vsctl show
1619 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1621 # Now check the packets actually received against the ones expected.
1624 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1628 OVN_CLEANUP([hv1],[hv2],[hv3])
1632 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1633 AT_SKIP_IF([test $HAVE_PYTHON = no])
1636 # Create a logical switch and some logical ports.
1637 # Turn on port security on all lports except ls1.
1638 # Make ls1 a destination for unknown MACs.
1639 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1640 ovn-nbctl ls-add lsw0
1641 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1643 ovn-nbctl lsp-add lsw0 lp$i
1645 ovn-nbctl --wait=sb sync
1647 ovn-sbctl lsp-bind lp$i hv0
1648 if test $i = 1; then
1649 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1651 if test $i = 3; then
1652 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1654 ip_addrs="192.168.0.$i"
1656 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1657 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1660 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1661 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1662 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1663 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1664 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1666 ovn-nbctl --wait=sb sync
1667 on_exit 'kill `cat ovn-trace.pid`'
1668 ovn-trace --detach --pidfile --no-chdir
1670 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1672 # This shell function causes a packet to be received on INPORT. The packet's
1673 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1674 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1675 # more) list the VIFs on which the packet should be received. INPORT and the
1676 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1678 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1679 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1682 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1683 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1688 echo "output(\"lp$outport\");"
1691 AT_CAPTURE_FILE([trace])
1692 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1695 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1697 # Causes a packet to be received on INPORT. The packet is an ARP
1698 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1699 # it should be the hardware address of the target to expect to receive in an
1700 # ARP reply; otherwise no reply is expected.
1702 # INPORT is an logical switch port number, e.g. 11 for vif11.
1703 # SHA and REPLY_HA are each 12 hex digits.
1704 # SPA and TPA are each 8 hex digits.
1706 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1708 local request="inport == \"lp$inport\"
1709 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1710 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1711 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1713 if test -z "$reply_ha"; then
1717 if test $i != $inport; then
1718 reply="${reply}output(\"lp$i\");
1725 eth.src = $reply_ha;
1728 arp.sha = $reply_ha;
1731 output(\"lp$inport\");
1735 AT_CAPTURE_FILE([trace])
1736 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1739 # Send packets between all pairs of source and destination ports:
1741 # 1. Unicast packets are delivered to exactly one logical switch port
1742 # (except that packets destined to their input ports are dropped).
1744 # 2. Broadcast and multicast are delivered to all logical switch ports
1745 # except the input port.
1747 # 3. When port security is turned on, the switch drops packets from the wrong
1750 # 4. The switch drops all packets with a VLAN tag.
1752 # 5. The switch drops all packets with a multicast source address. (This only
1753 # affects behavior when port security is turned off, since otherwise port
1754 # security would drop the packet anyway.)
1756 # 6. The switch delivers packets with an unknown destination to logical
1757 # switch ports with "unknown" among their MAC addresses (and port
1758 # security disabled).
1760 # 7. The switch drops unicast packets that violate an ACL.
1762 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1764 # 9. OVN generates responses to ARP requests for known IPs, except for
1765 # requests from a port for the port's own IP.
1767 # 10. No response to ARP requests for unknown IPs.
1777 if test $d != $s; then unicast=$d; else unicast=; fi
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1780 if test $d != $s && test $s = 1; then
1785 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1787 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1788 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1789 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1790 # Source of 1 or 2 and dest of 3 should be dropped
1791 # due to the 4th ACL that uses address_set(set1).
1798 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1799 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1800 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1801 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1803 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1804 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1806 if test $d != $s && test $d = 1; then
1807 unknown="$unknown $d"
1809 bcast="$bcast $unicast"
1810 bacl2="$bacl2 $acl2"
1811 bacl3="$bacl3 $acl3"
1815 tip_unknown=11.11.11.11
1816 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1817 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1818 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1820 if test $d = 3; then
1821 # lp3 has an additional ip 192.169.0.[123]3.
1823 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1827 # Broadcast and multicast.
1828 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1829 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1830 if test $s = 1; then
1831 bcast_impersonate=$bcast
1835 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1837 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1840 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1841 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1842 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1845 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1846 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1847 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1852 # 2 hypervisors, 4 logical ports per HV
1853 # 2 locally attached networks (one flat, one vlan tagged over same device)
1854 # 2 ports per HV on each network
1855 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1856 AT_SKIP_IF([test $HAVE_PYTHON = no])
1859 # In this test cases we create 3 switches, all connected to same
1860 # physical network (through br-phys on each HV). Each switch has
1861 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1862 # of VIF port name indicates the hypervisor it is bound to, e.g.
1863 # lp23 means VIF 3 on hv2.
1865 # Each switch's VLAN tag and their logical switch ports are:
1868 # - ports: lp11, lp12, lp21, lp22
1871 # - tagged with VLAN 101
1872 # - ports: lp13, lp14, lp23, lp24
1875 # - ports: lp15, lp25
1877 # Note: a localnet port is created for each switch to connect to
1882 ovn-nbctl ls-add $ls_name
1884 if test $i -eq 2; then
1885 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1887 ovn-nbctl lsp-add $ls_name $ln_port_name
1889 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1890 ovn-nbctl lsp-set-type $ln_port_name localnet
1891 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1896 # Prints the name of the logical switch that contains LSP.
1899 lp?[[12]]) echo ls1 ;; dnl (
1900 lp?[[34]]) echo ls2 ;; dnl (
1901 lp?5) echo ls3 ;; dnl (
1902 *) AT_FAIL_IF([:]) ;;
1910 ovs-vsctl add-br br-phys
1911 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1912 ovn_attach n1 br-phys 192.168.0.$i
1914 for j in 1 2 3 4 5; do
1915 ovs-vsctl add-port br-int vif$i$j -- \
1916 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1917 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1918 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1922 ls_name=$(lsp_to_ls $lsp_name)
1924 ovn-nbctl lsp-add $ls_name $lsp_name
1925 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1926 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1928 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1931 ovn-nbctl --wait=sb sync
1932 ovn-sbctl dump-flows
1936 # XXX This is now the 3rd copy of these functions in this file ...
1938 # Given the name of a logical port, prints the name of the hypervisor
1939 # on which it is located.
1944 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1946 # This shell function causes a packet to be received on INPORT. The packet's
1947 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1948 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1949 # logical switch port numbers, e.g. 11 for vif11.
1951 # EOUT is the end-to-end output port, that is, where the packet will end up
1952 # after possibly bouncing through one or more localnet ports. LOUT is the
1953 # logical output port, which might be a localnet port, as seen by ovn-trace
1954 # (which doesn't know what localnet ports are connected to and therefore can't
1955 # figure out the end-to-end answer).
1957 for j in 1 2 3 4 5; do
1962 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1965 # First try tracing the packet.
1966 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1967 if test $lout != drop; then
1968 echo "output(\"$lout\");"
1970 AT_CAPTURE_FILE([trace])
1971 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1973 # Then actually send a packet, for an end-to-end test.
1974 local packet=$(echo $dst$src | sed 's/://g')${eth}
1975 hv=`vif_to_hv $inport`
1977 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1978 if test $eout != drop; then
1979 echo $packet >> ${eout#lp}.expected
1983 # lp11 and lp21 are on the same network (phys, untagged)
1984 # and on different hypervisors
1985 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1986 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1988 # lp11 and lp12 are on the same network (phys, untagged)
1989 # and on the same hypervisor
1990 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1991 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1993 # lp13 and lp23 are on the same network (phys, VLAN 101)
1994 # and on different hypervisors
1995 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1996 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1998 # lp13 and lp14 are on the same network (phys, VLAN 101)
1999 # and on the same hypervisor
2000 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2001 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
2003 # lp11 and lp15 are on the same network (phys, untagged),
2004 # same hypervisor, and on different switches
2005 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2006 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
2008 # lp11 and lp25 are on the same network (phys, untagged),
2009 # different hypervisors, and on different switches
2010 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2011 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
2013 # Ports that should not be able to communicate
2014 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2015 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2016 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2017 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2018 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2019 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2020 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2021 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
2023 # Dump a bunch of info helpful for debugging if there's a failure.
2025 echo "------ OVN dump ------"
2029 echo "------ hv1 dump ------"
2030 as hv1 ovs-vsctl show
2031 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2033 echo "------ hv2 dump ------"
2034 as hv2 ovs-vsctl show
2035 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2037 # Now check the packets actually received against the ones expected.
2039 for j in 1 2 3 4 5; do
2040 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2044 OVN_CLEANUP([hv1],[hv2])
2048 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2050 AT_SKIP_IF([test $HAVE_PYTHON = no])
2053 # Configure the Northbound database
2054 ovn-nbctl ls-add lsw0
2056 ovn-nbctl lsp-add lsw0 lp1
2057 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2059 ovn-nbctl lsp-add lsw0 lp2
2060 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2062 ovn-nbctl lsp-add lsw0 lp-vtep
2063 ovn-nbctl lsp-set-type lp-vtep vtep
2064 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2065 ovn-nbctl lsp-set-addresses lp-vtep unknown
2067 # lpr, lr and lrp1 are used for the ARP request handling test only.
2068 ovn-nbctl lsp-add lsw0 lpr
2070 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2071 ovn-nbctl set Logical_Switch_Port lpr type=router \
2072 options:router-port=lrp1 \
2073 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2076 net_add n1 # Network to connect hv1, hv2, and vtep
2077 net_add n2 # Network to connect vtep and hv3
2079 # Create hypervisor hv1 connected to n1
2082 ovs-vsctl add-br br-phys
2083 ovn_attach n1 br-phys 192.168.0.1
2084 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
2086 # Create hypervisor hv2 connected to n1
2089 ovs-vsctl add-br br-phys
2090 ovn_attach n1 br-phys 192.168.0.2
2091 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
2094 # Start the vtep emulator with a leg in both networks
2098 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2099 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2101 ovs-vsctl add-br br-phys
2102 net_attach n1 br-phys
2104 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2105 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2106 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2107 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2109 ovs-vsctl add-br br-vtep
2110 net_attach n2 br-vtep
2112 vtep-ctl add-ps br-vtep
2113 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2114 vtep-ctl add-ls lsw0
2116 start_daemon ovs-vtep br-vtep
2117 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2119 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2121 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2123 # It takes more time for the update to be processed by ovs-vtep.
2126 # Add hv3 on the other side of the vtep
2129 ovs-vsctl add-br br-phys
2130 net_attach n2 br-phys
2132 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
2134 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2135 # packets for ARP resolution (native tunneling doesn't queue packets
2136 # for ARP resolution).
2139 # Allow some time for ovn-northd and ovn-controller to catch up.
2140 # XXX This should be more systematic.
2143 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2145 # This shell function causes a packet to be received on INPORT. The packet's
2146 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2147 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2148 # more) list the VIFs on which the packet should be received. INPORT and the
2149 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2154 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2155 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2158 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2160 echo $packet >> $outport.expected
2164 # Send packets between all pairs of source and destination ports:
2166 # 1. Unicast packets are delivered to exactly one logical switch port
2167 # (except that packets destined to their input ports are dropped).
2169 # 2. Broadcast and multicast are delivered to all logical switch ports
2170 # except the input port.
2172 # 3. The switch delivers packets with an unknown destination to logical
2173 # switch ports with "unknown" among their MAC addresses (and port
2174 # security disabled).
2179 if test $d != $s; then unicast=$d; else unicast=; fi
2180 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2182 # The vtep (vif3) is the only one configured for "unknown"
2183 if test $d != $s && test $d = 3; then
2184 unknown="$unknown $d"
2186 bcast="$bcast $unicast"
2189 # Broadcast and multicast.
2190 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2191 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2193 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2196 # ARP request should not be responded to by logical switch router
2197 # type arp responder on HV1 and HV2 and should reach directly to
2200 printf "%02x%02x%02x%02x" "$@"
2203 spa=`ip_to_hex 192 168 1 2`
2204 tpa=`ip_to_hex 192 168 1 1`
2205 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2206 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2207 echo $request >> 1.expected
2208 echo $request >> 2.expected
2210 # dump information with counters
2211 echo "------ OVN dump ------"
2215 echo "---------SB dump-----"
2216 ovn-sbctl list datapath_binding
2217 echo "---------------------"
2218 ovn-sbctl list port_binding
2219 echo "---------------------"
2220 ovn-sbctl dump-flows
2222 echo "------ hv1 dump ------"
2223 as hv1 ovs-vsctl show
2224 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2225 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2227 echo "------ hv2 dump ------"
2228 as hv2 ovs-vsctl show
2229 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2230 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2232 echo "------ hv3 dump ------"
2233 as hv3 ovs-vsctl show
2234 # note: hv3 has no logical port bind, thus it should not have br-int
2235 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2236 [ovs-ofctl: br-int is not a bridge or a socket
2239 # Now check the packets actually received against the ones expected.
2241 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2244 # Gracefully terminate daemons
2245 OVN_CLEANUP([hv1],[hv2],[vtep])
2246 OVN_CLEANUP_VSWITCH([hv3])
2250 # Similar test to "hardware GW"
2251 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2252 AT_SKIP_IF([test $HAVE_PYTHON = no])
2255 # Configure the Northbound database
2256 ovn-nbctl ls-add lsw0
2258 ovn-nbctl lsp-add lsw0 lp1
2259 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2261 ovn-nbctl lsp-add lsw0 lp2
2262 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2264 ovn-nbctl lsp-add lsw0 lp-gw
2265 ovn-nbctl lsp-set-type lp-gw l2gateway
2266 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2267 ovn-nbctl lsp-set-addresses lp-gw unknown
2269 net_add n1 # Network to connect hv1, hv2, and gw
2270 net_add n2 # Network to connect gw and hv3
2272 # Create hypervisor hv1 connected to n1
2275 ovs-vsctl add-br br-phys
2276 ovn_attach n1 br-phys 192.168.0.1
2277 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
2279 # Create hypervisor hv2 connected to n1
2282 ovs-vsctl add-br br-phys
2283 ovn_attach n1 br-phys 192.168.0.2
2284 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
2286 # Create hypervisor hv_gw connected to n1 and n2
2287 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2290 ovs-vsctl add-br br-phys
2291 ovn_attach n1 br-phys 192.168.0.3
2292 ovs-vsctl add-br br-phys2
2293 net_attach n2 br-phys2
2294 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2296 # Add hv3 on the other side of the GW
2299 ovs-vsctl add-br br-phys
2300 net_attach n2 br-phys
2301 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
2304 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2305 # packets for ARP resolution (native tunneling doesn't queue packets
2306 # for ARP resolution).
2309 # Allow some time for ovn-northd and ovn-controller to catch up.
2310 # XXX This should be more systematic.
2313 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2315 # This shell function causes a packet to be received on INPORT. The packet's
2316 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2317 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2318 # more) list the VIFs on which the packet should be received. INPORT and the
2319 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2324 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2325 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2328 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2330 echo $packet >> $outport.expected
2334 # Send packets between all pairs of source and destination ports:
2336 # 1. Unicast packets are delivered to exactly one lport (except that packets
2337 # destined to their input ports are dropped).
2339 # 2. Broadcast and multicast are delivered to all lports except the input port.
2341 # 3. The lswitch delivers packets with an unknown destination to lports with
2342 # "unknown" among their MAC addresses (and port security disabled).
2347 if test $d != $s; then unicast=$d; else unicast=; fi
2348 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2350 # The vtep (vif3) is the only one configured for "unknown"
2351 if test $d != $s && test $d = 3; then
2352 unknown="$unknown $d"
2354 bcast="$bcast $unicast"
2357 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2358 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2359 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2362 echo "------ ovn-nbctl show ------"
2364 echo "------ ovn-sbctl show ------"
2367 echo "------ hv1 ------"
2368 as hv1 ovs-vsctl show
2369 echo "------ hv1 br-int ------"
2370 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2371 echo "------ hv1 br-phys ------"
2372 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2374 echo "------ hv2 ------"
2375 as hv2 ovs-vsctl show
2376 echo "------ hv2 br-int ------"
2377 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2378 echo "------ hv2 br-phys ------"
2379 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2381 echo "------ hv_gw ------"
2382 as hv_gw ovs-vsctl show
2383 echo "------ hv_gw br-phys ------"
2384 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2385 echo "------ hv_gw br-phys2 ------"
2386 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2388 echo "------ hv3 ------"
2389 as hv3 ovs-vsctl show
2390 echo "------ hv3 br-phys ------"
2391 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2393 # Now check the packets actually received against the ones expected.
2395 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2399 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2400 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2401 AT_SKIP_IF([test $HAVE_PYTHON = no])
2406 # Three logical switches ls1, ls2, ls3.
2407 # One logical router lr0 connected to ls[123],
2408 # with nine subnets, three per logical switch:
2410 # lrp11 on ls1 for subnet 192.168.11.0/24
2411 # lrp12 on ls1 for subnet 192.168.12.0/24
2412 # lrp13 on ls1 for subnet 192.168.13.0/24
2414 # lrp33 on ls3 for subnet 192.168.33.0/24
2416 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2417 # digits are the subnet and the last digit distinguishes the VIF.
2419 ovn-nbctl ls-add ls$i
2422 # Add "unknown" to MAC addresses for lp?11, so packets for
2423 # MAC-IP bindings discovered via ARP later have somewhere to go.
2424 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2427 -- lsp-add ls$i lp$i$j$k \
2428 -- lsp-set-addresses lp$i$j$k \
2429 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
2434 ovn-nbctl lr-add lr0
2437 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2439 -- lsp-add ls$i lrp$i$j-attachment \
2440 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2441 options:router-port=lrp$i$j \
2442 addresses='"00:00:00:00:ff:'$i$j'"'
2446 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2447 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2451 # Three hypervisors hv[123].
2452 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2453 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2454 # lp?3[123] all on hv3.
2457 # Given the name of a logical port, prints the name of the hypervisor
2458 # on which it is located.
2461 ?11) echo 1 ;; dnl (
2462 ?12 | ?21 | ?22) echo 2 ;; dnl (
2463 ?13 | ?23 | ?3?) echo 3 ;;
2467 # Given the name of a logical port, prints the name of its logical router
2468 # port, e.g. "vif_to_lrp 123" yields 12.
2473 # Given the name of a logical port, prints the name of its logical
2474 # switch, e.g. "vif_to_ls 123" yields 1.
2483 ovs-vsctl add-br br-phys
2484 ovn_attach n1 br-phys 192.168.0.$i
2489 hv=`vif_to_hv $i$j$k`
2490 as hv$hv ovs-vsctl \
2491 -- add-port br-int vif$i$j$k \
2492 -- set Interface vif$i$j$k \
2493 external-ids:iface-id=lp$i$j$k \
2494 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2495 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2496 ofport-request=$i$j$k
2501 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2502 # packets for ARP resolution (native tunneling doesn't queue packets
2503 # for ARP resolution).
2506 # Allow some time for ovn-northd and ovn-controller to catch up.
2507 # XXX This should be more systematic.
2510 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2512 # This shell function causes a packet to be received on INPORT. The packet's
2513 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2514 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2515 # more) list the VIFs on which the packet should be received. INPORT and the
2516 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2525 # This packet has bad checksums but logical L3 routing doesn't check.
2526 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2527 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2528 shift; shift; shift; shift; shift
2529 hv=hv`vif_to_hv $inport`
2530 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2531 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2532 in_ls=`vif_to_ls $inport`
2533 in_lrp=`vif_to_lrp $inport`
2535 out_ls=`vif_to_ls $outport`
2536 if test $in_ls = $out_ls; then
2537 # Ports on the same logical switch receive exactly the same packet.
2540 # Routing decrements TTL and updates source and dest MAC
2542 out_lrp=`vif_to_lrp $outport`
2543 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2544 fi >> $outport.expected
2548 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2550 # Causes a packet to be received on INPORT. The packet is an ARP
2551 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2552 # it should be the hardware address of the target to expect to receive in an
2553 # ARP reply; otherwise no reply is expected.
2555 # INPORT is an logical switch port number, e.g. 11 for vif11.
2556 # SHA and REPLY_HA are each 12 hex digits.
2557 # SPA and TPA are each 8 hex digits.
2559 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2560 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2561 hv=hv`vif_to_hv $inport`
2562 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2563 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2565 # Expect to receive the broadcast ARP on the other logical switch ports if
2566 # IP address is not configured to the switch patch port.
2567 local i=`vif_to_ls $inport`
2571 # 192.168.33.254 is configured to the switch patch port for lrp33,
2572 # so no ARP flooding expected for it.
2573 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2574 echo $request >> $i$j$k.expected
2579 # Expect to receive the reply, if any.
2580 if test X$reply_ha != X; then
2581 lrp=`vif_to_lrp $inport`
2582 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2583 echo $reply >> $inport.expected
2587 as hv1 ovs-vsctl --columns=name,ofport list interface
2588 as hv1 ovn-sbctl list port_binding
2589 as hv1 ovn-sbctl list datapath_binding
2590 as hv1 ovn-sbctl dump-flows
2591 as hv1 ovs-ofctl dump-flows br-int
2593 # Send IP packets between all pairs of source and destination ports:
2595 # 1. Unicast IP packets are delivered to exactly one logical switch port
2596 # (except that packets destined to their input ports are dropped).
2598 # 2. Broadcast IP packets are delivered to all logical switch ports
2599 # except the input port.
2601 printf "%02x%02x%02x%02x" "$@"
2609 sip=`ip_to_hex 192 168 $is$js $ks`
2614 dip=`ip_to_hex 192 168 $id$jd $kd`
2615 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2616 if test $d != $s; then unicast=$d; else unicast=; fi
2618 test_ip $s $smac $dmac $sip $dip $unicast #1
2620 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2624 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2629 : > mac_bindings.expected
2631 # 3. Send an IP packet from every logical port to every other subnet,
2632 # to an IP address that does not have a static IP-MAC binding.
2633 # This should generate a broadcast ARP request for the destination
2634 # IP address in the destination subnet.
2635 # Moreover generate an ARP reply for each of the IP addresses ARPed
2641 sip=`ip_to_hex 192 168 $is$js $ks`
2644 if test $is$js = $id$jd; then
2649 dmac=00000000ff$is$js
2650 # Calculate a 4th octet for the destination that is
2651 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2652 # that have static MAC bindings, and fits in the range
2654 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2655 dip=`ip_to_hex 192 168 $id$jd $o4`
2656 test_ip $s $smac $dmac $sip $dip
2658 # Every LP on the destination subnet's lswitch should
2659 # receive the ARP request.
2660 lrmac=00000000ff$id$jd
2661 lrip=`ip_to_hex 192 168 $id$jd 254`
2662 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2663 for jd2 in 1 2 3; do
2665 echo $arp >> $id$jd2$kd.expected
2668 if test $(vif_to_hv ${is}${js}${ks}) = $(vif_to_hv ${id}${jd}1); then
2670 rmac=00000000ff$id$jd
2671 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
2674 host_mac=8000000000$o4
2675 lrmac=00000000ff$id$jd
2677 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2679 hv=hv`vif_to_hv ${id}${jd}1`
2680 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2682 host_ip_pretty=192.168.$id$jd.$o4
2683 host_mac_pretty=80:00:00:00:00:$o4
2684 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2691 # Test router replies to ARP requests from all source ports:
2693 # 4. Router replies to query for its MAC address from port's own IP address.
2695 # 5. Router replies to query for its MAC address from any random IP address
2698 # 6. No reply to query for IP address other than router IP.
2700 # 7. No reply to query from another subnet.
2704 smac=f00000000$i$j$k # Source MAC
2705 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2706 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2707 rmac=00000000ff$i$j # Router MAC
2708 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2709 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2711 test_arp $i$j$k $smac $sip $rip $rmac #4
2712 test_arp $i$j$k $smac $otherip $rip $rmac #5
2713 test_arp $i$j$k $smac $sip $otherip #6
2715 # When rip is 192.168.33.254, ARP request from externalip won't be
2716 # filtered, because 192.168.33.254 is configured to switch peer port
2719 if test $i = 3 && test $j = 3; then
2722 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2724 # MAC binding should be learned from ARP request.
2725 host_mac_pretty=f0:00:00:00:0$i:$j$k
2727 host_ip_pretty=192.168.$i$j.$k
2728 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2730 # mac_binding is learned and overwritten so only the last one remains.
2731 if test $k = 3; then
2732 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2733 # configured to switch peer port for lrp33.
2734 if test $i != 3 || test $j != 3; then
2735 host_ip_pretty=192.168.$i$j.55
2736 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2745 # Allow some time for packet forwarding.
2746 # XXX This can be improved.
2749 # 8. Send an IP packet from every logical port to every other subnet. These
2750 # are the same packets already sent as #3, but now the destinations' IP-MAC
2751 # bindings have been discovered via ARP, so instead of provoking an ARP
2752 # request, these packets now get routed to their destinations (which don't
2753 # have static MAC bindings, so they go to the port we've designated as
2754 # accepting "unknown" MACs.)
2760 sip=`ip_to_hex 192 168 $is$js $ks`
2763 if test $is$js = $id$jd; then
2768 dmac=00000000ff$is$js
2769 # Calculate a 4th octet for the destination that is
2770 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2771 # that have static MAC bindings, and fits in the range
2773 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2774 dip=`ip_to_hex 192 168 $id$jd $o4`
2775 test_ip $s $smac $dmac $sip $dip
2777 # Expect the packet egress.
2778 host_mac=8000000000$o4
2781 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2788 ovn-sbctl -f csv -d bare --no-heading \
2789 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2791 # Now check the packets actually received against the ones expected.
2795 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2801 # Check the MAC bindings against those expected.
2802 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2805 # Gracefully terminate daemons
2806 OVN_CLEANUP([hv1], [hv2], [hv3])
2810 AT_SETUP([ovn -- IP relocation using GARP request])
2811 AT_SKIP_IF([test $HAVE_PYTHON = no])
2816 # Two logical switches ls1, ls2.
2817 # One logical router lr0 connected to ls[12],
2818 # with 2 subnets, 1 per logical switch:
2820 # lrp1 on ls1 for subnet 192.168.1.1/24
2821 # lrp2 on ls2 for subnet 192.168.2.1/24
2823 # 4 VIFs, 2 per LS lp[12][12], first digit being LS.
2824 # VIFs' fixed IP addresses are 192.168.[12].1[12].
2826 # There is a secondary IP 192.168.1.100 that is unknown in NB and learned
2827 # through ARP only, and it can move between lp11 and lp12.
2829 ovn-nbctl lr-add lr0
2831 ovn-nbctl ls-add ls$i
2832 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
2834 -- lsp-add ls$i lrp$i-attachment \
2835 -- set Logical_Switch_Port lrp$i-attachment type=router \
2836 options:router-port=lrp$i \
2840 -- lsp-add ls$i lp$i$j \
2841 -- lsp-set-addresses lp$i$j \
2842 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
2847 # 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
2849 # Given the name of a logical port, prints the name of the hypervisor
2850 # on which it is located, e.g. "vif_to_hv 12" yields 2.
2855 # Given the name of a logical port, prints the name of its logical router
2856 # port, e.g. "vif_to_lrp 12" yields 1.
2861 # Given the name of a logical port, prints the name of its logical
2862 # switch, e.g. "vif_to_ls 12" yields 1.
2871 ovs-vsctl add-br br-phys
2872 ovn_attach n1 br-phys 192.168.0.$i
2877 as hv$hv ovs-vsctl \
2878 -- add-port br-int vif$i$j \
2879 -- set Interface vif$i$j \
2880 external-ids:iface-id=lp$i$j \
2881 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
2882 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
2887 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2888 # packets for ARP resolution (native tunneling doesn't queue packets
2889 # for ARP resolution).
2892 # Allow some time for ovn-northd and ovn-controller to catch up.
2893 # XXX This should be more systematic.
2896 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2898 # This shell function causes a packet to be received on INPORT. The packet's
2899 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2900 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2901 # more) list the VIFs on which the packet should be received. INPORT and the
2902 # OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
2909 # This packet has bad checksums but logical L3 routing doesn't check.
2910 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2911 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2912 shift; shift; shift; shift; shift
2913 hv=hv`vif_to_hv $inport`
2914 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2915 in_ls=`vif_to_ls $inport`
2916 in_lrp=`vif_to_lrp $inport`
2918 out_ls=`vif_to_ls $outport`
2919 if test $in_ls = $out_ls; then
2920 # Ports on the same logical switch receive exactly the same packet.
2923 # Routing decrements TTL and updates source and dest MAC
2925 out_lrp=`vif_to_lrp $outport`
2926 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2927 fi >> $outport.expected
2931 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2933 # Causes a packet to be received on INPORT. The packet is an ARP
2934 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2935 # it should be the hardware address of the target to expect to receive in an
2936 # ARP reply; otherwise no reply is expected.
2938 # INPORT is an logical switch port number, e.g. 11 for vif11.
2939 # SHA and REPLY_HA are each 12 hex digits.
2940 # SPA and TPA are each 8 hex digits.
2942 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2943 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2944 hv=hv`vif_to_hv $inport`
2945 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2947 # Expect to receive the broadcast ARP on the other logical switch ports if
2948 # IP address is not configured to the switch patch port.
2949 local i=`vif_to_ls $inport`
2952 if test $i$j != $inport; then
2953 echo $request >> $i$j$k.expected
2957 # Expect to receive the reply, if any.
2958 if test X$reply_ha != X; then
2959 lrp=`vif_to_lrp $inport`
2960 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2961 echo $reply >> $inport.expected
2966 printf "%02x%02x%02x%02x" "$@"
2969 # lp11 send GARP request to announce ownership of 192.168.1.100.
2972 spa=`ip_to_hex 192 168 1 100`
2974 test_arp 11 $sha $spa $tpa
2975 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
2976 ovn-nbctl --wait=hv sync
2978 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
2982 sip=`ip_to_hex 192 168 2 11`
2983 dip=`ip_to_hex 192 168 1 100`
2984 test_ip 21 $smac $dmac $sip $dip 11
2986 # lp12 send GARP request to announce ownership of 192.168.1.100.
2989 test_arp 12 $sha $spa $tpa
2990 OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
2991 ovn-nbctl --wait=hv sync
2993 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
2995 test_ip 21 $smac $dmac $sip $dip 12
2997 # Now check the packets actually received against the ones expected.
3000 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3005 # Gracefully terminate daemons
3006 OVN_CLEANUP([hv1], [hv2])
3010 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3011 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
3012 AT_SKIP_IF([test $HAVE_PYTHON = no])
3015 # Create hypervisors hv[123].
3016 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3017 # Add all of the vifs to a single logical switch lsw0.
3018 # Turn off port security on vifs vif[123]1
3019 # Turn on l2 port security on vifs vif[123]2
3020 # Turn of l2 and l3 port security on vifs vif[123]3
3021 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
3022 ovn-nbctl ls-add lsw0
3027 ovs-vsctl add-br br-phys
3028 ovn_attach n1 br-phys 192.168.0.$i
3031 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
3032 ovn-nbctl lsp-add lsw0 lp$i$j
3033 if test $j = 1; then
3034 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
3035 elif test $j = 2; then
3036 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3037 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
3039 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
3040 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3041 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3046 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3047 # packets for ARP resolution (native tunneling doesn't queue packets
3048 # for ARP resolution).
3051 # Allow some time for ovn-northd and ovn-controller to catch up.
3052 # XXX This should be more systematic.
3055 # Given the name of a logical port, prints the name of the hypervisor
3056 # on which it is located.
3067 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3069 # This shell function causes an ip packet to be received on INPORT.
3070 # The packet's content has Ethernet destination DST and source SRC
3071 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3072 # The OUTPORTs (zero or more) list the VIFs on which the packet should
3073 # be received. INPORT and the OUTPORTs are specified as logical switch
3074 # port numbers, e.g. 11 for vif11.
3076 # This packet has bad checksums but logical L3 routing doesn't check.
3077 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3078 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3079 shift; shift; shift; shift; shift
3080 hv=`vif_to_hv $inport`
3081 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3082 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3084 echo $packet >> $outport.expected
3088 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3090 # Causes a packet to be received on INPORT. The packet is an ARP
3091 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3092 # it should be the hardware address of the target to expect to receive in an
3093 # ARP reply; otherwise no reply is expected.
3095 # INPORT is an logical switch port number, e.g. 11 for vif11.
3096 # SHA and REPLY_HA are each 12 hex digits.
3097 # SPA and TPA are each 8 hex digits.
3099 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3100 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3101 hv=`vif_to_hv $inport`
3102 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3103 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3104 if test $drop != 1; then
3105 if test X$reply_ha = X; then
3106 # Expect to receive the broadcast ARP on the other logical switch ports
3107 # if no reply is expected.
3111 if test $i$j != $inport; then
3112 echo $request >> $i$j.expected
3117 # Expect to receive the reply, if any.
3118 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3119 echo $reply >> $inport.expected
3124 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3125 # This function is similar to test_ip() except that it sends
3128 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3129 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3130 shift; shift; shift; shift; shift
3131 hv=`vif_to_hv $inport`
3132 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3133 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3135 echo $packet >> $outport.expected
3139 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3140 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
3141 # of the test packet
3143 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3144 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3145 shift; shift; shift; shift; shift; shift
3146 hv=`vif_to_hv $inport`
3147 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3148 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3150 echo $packet >> $outport.expected
3155 printf "%02x%02x%02x%02x" "$@"
3159 sip=`ip_to_hex 192 168 0 12`
3160 tip=`ip_to_hex 192 168 0 13`
3161 # the arp packet should be allowed even if lp[123]1 is
3162 # not configured with mac f00000000023 and ip 192.168.0.12
3164 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3166 if test $i != $j; then
3167 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3173 sip=`ip_to_hex 192 168 0 12`
3174 tip=`ip_to_hex 192 168 0 13`
3176 # arp packet should be allowed since lp22 is configured with
3178 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3180 # arp packet should not be allowed since lp32 is not configured with
3182 test_arp 32 f00000000021 f00000000021 $sip $tip 1
3184 # arp packet with sha set to f00000000021 should not be allowed
3186 test_arp 12 f00000000012 f00000000021 $sip $tip 1
3188 # ip packets should be allowed and received since lp[123]2 do not
3189 # have l3 port security
3190 sip=`ip_to_hex 192 168 0 55`
3191 tip=`ip_to_hex 192 168 0 66`
3194 if test $i != $j; then
3195 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3200 # ipv6 packets should be received by lp[123]2
3201 # lp[123]1 can send ipv6 traffic as there is no port security
3202 sip=fe800000000000000000000000000000
3203 tip=ff020000000000000000000000000000
3206 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3210 # l2 and l3 port security
3211 sip=`ip_to_hex 192 168 0 13`
3212 tip=`ip_to_hex 192 168 0 22`
3213 # arp packet should be allowed since lp13 is configured with
3214 # f00000000013 and 192.168.0.13
3215 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3217 # the arp packet should be dropped because lp23 is not configured
3218 # with mac f00000000022
3219 sip=`ip_to_hex 192 168 0 13`
3220 tip=`ip_to_hex 192 168 0 22`
3221 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3223 # the arp packet should be dropped because lp33 is not configured
3224 # with ip 192.168.0.55
3225 spa=`ip_to_hex 192 168 0 55`
3226 tpa=`ip_to_hex 192 168 0 22`
3227 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3229 # ip packets should not be received by lp[123]3 since
3230 # l3 port security is enabled
3231 sip=`ip_to_hex 192 168 0 55`
3232 tip=`ip_to_hex 192 168 0 66`
3235 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3239 # ipv6 packets should be dropped for lp[123]3 since
3240 # it is configured with only ipv4 address
3241 sip=fe800000000000000000000000000000
3242 tip=ff020000000000000000000000000000
3245 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3248 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3249 # lp[123]1 can send ipv6 traffic as there is no port security
3251 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3254 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3255 # fe80::ea2a:eaff:fe28:0012
3257 # ipv4 packet should be dropped for lp13 with mac f0000000113
3258 sip=`ip_to_hex 192 168 0 13`
3259 tip=`ip_to_hex 192 168 0 23`
3260 test_ip 13 f00000000113 f00000000023 $sip $tip
3262 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3263 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3264 # lp11 can send ipv6 traffic as there is no port security
3265 sip=ee800000000000000000000000000000
3267 tip=fe80000000000000ea2aeafffe2800${i}3
3268 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3272 # ipv6 packet should not be received by lp33 with mac f0000000333
3273 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3274 # configured with fe80::ea2a:eaff:fe28:0033
3275 # lp11 can send ipv6 traffic as there is no port security
3277 sip=ee800000000000000000000000000000
3278 tip=fe80000000000000ea2aeafffe280023
3279 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3281 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3282 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3283 # and should be dropped for any other ip6.src
3284 # lp21 can receive ipv6 traffic as there is no port security
3286 tip=ee800000000000000000000000000000
3288 sip=fe80000000000000ea2aeafffe2800${i}3
3289 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3291 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3292 sip=00000000000000000000000000000000
3293 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3294 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3295 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3296 # Traffic to non-multicast traffic should be dropped
3297 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3298 # Traffic of other ICMPv6 types should be dropped
3299 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3302 sip=ae80000000000000ea2aeafffe2800aa
3303 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3306 # configure lsp13 to send and received IPv4 packets with an address range
3307 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"
3311 sip=`ip_to_hex 10 0 0 13`
3312 tip=`ip_to_hex 192 168 0 22`
3313 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3314 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3316 sip=`ip_to_hex 10 0 0 14`
3317 tip=`ip_to_hex 192 168 0 23`
3318 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3319 # with dst ip 192.168.0.23 should be allowed
3320 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3322 sip=`ip_to_hex 192 168 0 33`
3323 tip=`ip_to_hex 10 0 0 15`
3324 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3325 # with dst ip 10.0.0.15 should be received by lsp13
3326 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3328 sip=`ip_to_hex 192 168 0 33`
3329 tip=`ip_to_hex 20 0 0 4`
3330 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3331 # with dst ip 20.0.0.4 should be received by lsp13
3332 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3334 sip=`ip_to_hex 192 168 0 33`
3335 tip=`ip_to_hex 20 0 0 5`
3336 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3337 # with dst ip 20.0.0.5 should not be received by lsp13
3338 test_ip 33 f00000000033 f00000000013 $sip $tip
3340 sip=`ip_to_hex 192 168 0 33`
3341 tip=`ip_to_hex 20 0 0 255`
3342 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3343 # with dst ip 20.0.0.255 should be received by lsp13
3344 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3346 sip=`ip_to_hex 192 168 0 33`
3347 tip=`ip_to_hex 192 168 0 255`
3348 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3349 # with dst ip 192.168.0.255 should not be received by lsp13
3350 test_ip 33 f00000000033 f00000000013 $sip $tip
3352 sip=`ip_to_hex 192 168 0 33`
3353 tip=`ip_to_hex 224 0 0 4`
3354 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3355 # with dst ip 224.0.0.4 should be received by lsp13
3356 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3358 #dump information including flow counters
3360 ovn-sbctl dump-flows -- list multicast_group
3362 echo "------ hv1 dump ------"
3363 as hv1 ovs-vsctl show
3364 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3365 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3367 echo "------ hv2 dump ------"
3368 as hv2 ovs-vsctl show
3369 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3370 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3372 echo "------ hv3 dump ------"
3373 as hv3 ovs-vsctl show
3374 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3375 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3377 # Now check the packets actually received against the ones expected.
3380 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3384 OVN_CLEANUP([hv1],[hv2],[hv3])
3388 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3389 AT_SKIP_IF([test $HAVE_PYTHON = no])
3393 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3394 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3395 # R2 has ls2 (172.16.1.0/24) connected to it.
3397 ls1_lp1_mac="f0:00:00:01:02:03"
3398 rp_ls1_mac="00:00:00:01:02:03"
3399 rp_ls2_mac="00:00:00:01:02:04"
3400 ls2_lp1_mac="f0:00:00:01:02:04"
3402 ls1_lp1_ip="192.168.1.2"
3403 ls2_lp1_ip="172.16.1.2"
3408 ovn-nbctl ls-add ls1
3409 ovn-nbctl ls-add ls2
3412 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3414 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3415 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3418 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3420 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3421 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3424 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3425 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3427 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3428 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3430 # Create logical port ls1-lp1 in ls1
3431 ovn-nbctl lsp-add ls1 ls1-lp1 \
3432 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3434 # Create logical port ls2-lp1 in ls2
3435 ovn-nbctl lsp-add ls2 ls2-lp1 \
3436 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3438 # Create two hypervisor and create OVS ports corresponding to logical ports.
3443 ovs-vsctl add-br br-phys
3444 ovn_attach n1 br-phys 192.168.0.1
3445 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3446 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3447 options:tx_pcap=hv1/vif1-tx.pcap \
3448 options:rxq_pcap=hv1/vif1-rx.pcap \
3453 ovs-vsctl add-br br-phys
3454 ovn_attach n1 br-phys 192.168.0.2
3455 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3456 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3457 options:tx_pcap=hv2/vif1-tx.pcap \
3458 options:rxq_pcap=hv2/vif1-rx.pcap \
3462 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3463 # packets for ARP resolution (native tunneling doesn't queue packets
3464 # for ARP resolution).
3467 # Allow some time for ovn-northd and ovn-controller to catch up.
3468 # XXX This should be more systematic.
3472 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3473 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3474 udp && udp.src==53 && udp.dst==4369"
3475 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3478 echo "---------NB dump-----"
3480 echo "---------------------"
3481 ovn-nbctl list logical_router
3482 echo "---------------------"
3483 ovn-nbctl list logical_router_port
3484 echo "---------------------"
3486 echo "---------SB dump-----"
3487 ovn-sbctl list datapath_binding
3488 echo "---------------------"
3489 ovn-sbctl list port_binding
3490 echo "---------------------"
3492 echo "------ hv1 dump ----------"
3493 as hv1 ovs-ofctl show br-int
3494 as hv1 ovs-ofctl dump-flows br-int
3495 echo "------ hv2 dump ----------"
3496 as hv2 ovs-ofctl show br-int
3497 as hv2 ovs-ofctl dump-flows br-int
3500 # The TTL should be decremented by 2.
3501 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3502 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3503 udp && udp.src==53 && udp.dst==4369"
3504 echo $packet | ovstest test-ovn expr-to-packets > expected
3506 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3508 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3509 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3512 # Disable the ls2-lp1 port.
3513 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3515 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3516 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3519 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3521 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3522 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3523 udp && udp.src==53 && udp.dst==4369"
3525 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3526 # The 2nd packet sent shound not be received.
3527 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3529 OVN_CLEANUP([hv1],[hv2])
3534 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3535 AT_KEYWORDS([router-admin-state])
3536 AT_SKIP_IF([test $HAVE_PYTHON = no])
3540 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3541 # and 172.16.1.0/24) connected to it.
3545 ovn-nbctl ls-add ls1
3548 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3549 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3550 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3552 # Create logical port ls1-lp1 in ls1
3553 ovn-nbctl lsp-add ls1 ls1-lp1 \
3554 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3556 # Create logical port ls1-lp2 in ls1
3557 ovn-nbctl lsp-add ls1 ls1-lp2 \
3558 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3560 # Create one hypervisor and create OVS ports corresponding to logical ports.
3565 ovs-vsctl add-br br-phys
3566 ovn_attach n1 br-phys 192.168.0.1
3567 ovs-vsctl -- add-port br-int vif1 -- \
3568 set interface vif1 external-ids:iface-id=ls1-lp1 \
3569 options:tx_pcap=hv1/vif1-tx.pcap \
3570 options:rxq_pcap=hv1/vif1-rx.pcap \
3573 ovs-vsctl -- add-port br-int vif2 -- \
3574 set interface vif2 external-ids:iface-id=ls1-lp2 \
3575 options:tx_pcap=hv1/vif2-tx.pcap \
3576 options:rxq_pcap=hv1/vif2-rx.pcap \
3580 # Allow some time for ovn-northd and ovn-controller to catch up.
3581 # XXX This should be more systematic.
3584 # Send ip packets between the two ports.
3586 printf "%02x%02x%02x%02x" "$@"
3590 src_mac="f00000010203"
3591 dst_mac="000000010203"
3592 src_ip=`ip_to_hex 192 168 1 2`
3593 dst_ip=`ip_to_hex 172 16 1 2`
3594 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3595 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3598 echo "---------NB dump-----"
3600 echo "---------------------"
3601 ovn-nbctl list logical_router
3602 echo "---------------------"
3603 ovn-nbctl list logical_router_port
3604 echo "---------------------"
3606 echo "---------SB dump-----"
3607 ovn-sbctl list datapath_binding
3608 echo "---------------------"
3609 ovn-sbctl list logical_flow
3610 echo "---------------------"
3612 echo "------ hv1 dump ----------"
3613 as hv1 ovs-ofctl dump-flows br-int
3617 ovn-nbctl set Logical_Router R1 enabled=false
3619 # Allow some time for ovn-northd and ovn-controller to catch up.
3620 # XXX This should be more systematic.
3623 echo "---------SB dump-----"
3624 ovn-sbctl list datapath_binding
3625 echo "---------------------"
3626 ovn-sbctl list logical_flow
3627 echo "---------------------"
3629 echo "------ hv1 dump ----------"
3630 as hv1 ovs-ofctl dump-flows br-int
3632 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3635 expect_src_mac="000000010203"
3636 expect_dst_mac="f00000010204"
3637 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3639 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3643 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3644 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3645 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3648 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3651 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3654 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3657 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3658 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3663 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3664 AT_KEYWORDS([router-admin-state])
3665 AT_SKIP_IF([test $HAVE_PYTHON = no])
3669 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3670 # and has switch ls2 (172.16.1.0/24) connected to it.
3674 ovn-nbctl ls-add ls1
3675 ovn-nbctl ls-add ls2
3678 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3679 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3680 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3683 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3684 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3685 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3687 # Create logical port ls1-lp1 in ls1
3688 ovn-nbctl lsp-add ls1 ls1-lp1 \
3689 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3691 # Create logical port ls2-lp1 in ls2
3692 ovn-nbctl lsp-add ls2 ls2-lp1 \
3693 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3695 # Create one hypervisor and create OVS ports corresponding to logical ports.
3700 ovs-vsctl add-br br-phys
3701 ovn_attach n1 br-phys 192.168.0.1
3702 ovs-vsctl -- add-port br-int vif1 -- \
3703 set interface vif1 external-ids:iface-id=ls1-lp1 \
3704 options:tx_pcap=hv1/vif1-tx.pcap \
3705 options:rxq_pcap=hv1/vif1-rx.pcap \
3708 ovs-vsctl -- add-port br-int vif2 -- \
3709 set interface vif2 external-ids:iface-id=ls2-lp1 \
3710 options:tx_pcap=hv1/vif2-tx.pcap \
3711 options:rxq_pcap=hv1/vif2-rx.pcap \
3715 # Allow some time for ovn-northd and ovn-controller to catch up.
3716 # XXX This should be more systematic.
3719 # Send ip packets between the two ports.
3721 printf "%02x%02x%02x%02x" "$@"
3725 src_mac="f00000010203"
3726 dst_mac="000000010203"
3727 src_ip=`ip_to_hex 192 168 1 2`
3728 dst_ip=`ip_to_hex 172 16 1 2`
3729 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3730 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3733 echo "---------NB dump-----"
3735 echo "---------------------"
3736 ovn-nbctl list logical_router
3737 echo "---------------------"
3738 ovn-nbctl list logical_router_port
3739 echo "---------------------"
3741 echo "---------SB dump-----"
3742 ovn-sbctl list datapath_binding
3743 echo "---------------------"
3744 ovn-sbctl list logical_flow
3745 echo "---------------------"
3747 echo "------ hv1 dump ----------"
3748 as hv1 ovs-ofctl dump-flows br-int
3751 ovn-nbctl set Logical_Router R1 enabled=false
3753 echo "---------SB dump-----"
3754 ovn-sbctl list datapath_binding
3755 echo "---------------------"
3756 ovn-sbctl list logical_flow
3757 echo "---------------------"
3759 echo "------ hv1 dump ----------"
3760 as hv1 ovs-ofctl dump-flows br-int
3762 # Allow some time for the disabling of logical router R1 to propagate.
3763 # XXX This should be more systematic.
3766 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3769 expect_src_mac="000000010204"
3770 expect_dst_mac="f00000010204"
3771 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3773 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3779 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3780 AT_SKIP_IF([test $HAVE_PYTHON = no])
3784 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3785 # network. R1 has switchess foo (192.168.1.0/24)
3787 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3792 ovn-nbctl ls-add foo
3793 ovn-nbctl ls-add alice
3794 ovn-nbctl ls-add bob
3797 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3798 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3799 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3801 # Connect alice to R2
3802 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3803 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3804 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3807 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3808 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3809 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3812 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3813 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3815 #install static routes
3816 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3817 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3818 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3820 # Create logical port foo1 in foo
3821 ovn-nbctl lsp-add foo foo1 \
3822 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3824 # Create logical port alice1 in alice
3825 ovn-nbctl lsp-add alice alice1 \
3826 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3828 # Create logical port bob1 in bob
3829 ovn-nbctl lsp-add bob bob1 \
3830 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3832 # Create two hypervisor and create OVS ports corresponding to logical ports.
3837 ovs-vsctl add-br br-phys
3838 ovn_attach n1 br-phys 192.168.0.1
3839 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3840 set interface hv1-vif1 external-ids:iface-id=foo1 \
3841 options:tx_pcap=hv1/vif1-tx.pcap \
3842 options:rxq_pcap=hv1/vif1-rx.pcap \
3845 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3846 set interface hv1-vif2 external-ids:iface-id=alice1 \
3847 options:tx_pcap=hv1/vif2-tx.pcap \
3848 options:rxq_pcap=hv1/vif2-rx.pcap \
3853 ovs-vsctl add-br br-phys
3854 ovn_attach n1 br-phys 192.168.0.2
3855 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3856 set interface hv2-vif1 external-ids:iface-id=bob1 \
3857 options:tx_pcap=hv2/vif1-tx.pcap \
3858 options:rxq_pcap=hv2/vif1-rx.pcap \
3862 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3863 # packets for ARP resolution (native tunneling doesn't queue packets
3864 # for ARP resolution).
3867 # Allow some time for ovn-northd and ovn-controller to catch up.
3868 # XXX This should be more systematic.
3872 printf "%02x%02x%02x%02x" "$@"
3875 # Send ip packets between foo1 and alice1
3876 src_mac="f00000010203"
3877 dst_mac="000000010203"
3878 src_ip=`ip_to_hex 192 168 1 2`
3879 dst_ip=`ip_to_hex 172 16 1 2`
3880 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3881 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3883 # Send ip packets between foo1 and bob1
3884 src_mac="f00000010203"
3885 dst_mac="000000010203"
3886 src_ip=`ip_to_hex 192 168 1 2`
3887 dst_ip=`ip_to_hex 172 16 2 2`
3888 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3889 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3891 echo "---------NB dump-----"
3893 echo "---------------------"
3894 ovn-nbctl list logical_router
3895 echo "---------------------"
3896 ovn-nbctl list logical_router_port
3897 echo "---------------------"
3899 echo "---------SB dump-----"
3900 ovn-sbctl list datapath_binding
3901 echo "---------------------"
3902 ovn-sbctl list port_binding
3903 echo "---------------------"
3905 echo "------ hv1 dump ----------"
3906 as hv1 ovs-ofctl dump-flows br-int
3907 echo "------ hv2 dump ----------"
3908 as hv2 ovs-ofctl dump-flows br-int
3910 # Packet to Expect at bob1
3911 src_mac="000000010205"
3912 dst_mac="f00000010205"
3913 src_ip=`ip_to_hex 192 168 1 2`
3914 dst_ip=`ip_to_hex 172 16 2 2`
3915 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3917 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3919 # Packet to Expect at alice1
3920 src_mac="000000010204"
3921 dst_mac="f00000010204"
3922 src_ip=`ip_to_hex 192 168 1 2`
3923 dst_ip=`ip_to_hex 172 16 1 2`
3924 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3926 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3928 OVN_CLEANUP([hv1],[hv2])
3932 AT_SETUP([ovn -- send gratuitous arp on localnet])
3933 AT_SKIP_IF([test $HAVE_PYTHON = no])
3935 ovn-nbctl ls-add lsw0
3943 ovn_attach n1 br-phys 192.168.0.1
3945 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3946 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])
3949 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3950 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3951 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3953 # Create a localnet port.
3954 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3955 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3956 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3957 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3959 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3961 # Wait for packet to be received.
3962 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3963 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3965 # Check GARP packet when restart openflow connection.
3967 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3969 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3972 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3974 # Wait for packet to be received.
3975 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3976 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3978 # Delete the localnet ports.
3979 AT_CHECK([ovs-vsctl del-port localvif1])
3980 AT_CHECK([ovn-nbctl lsp-del ln_port])
3986 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3987 AT_SKIP_IF([test $HAVE_PYTHON = no])
3991 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3992 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3993 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
4000 ovn-nbctl ls-add foo
4001 ovn-nbctl ls-add alice
4002 ovn-nbctl ls-add bob
4003 ovn-nbctl ls-add join
4006 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4007 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4008 options:router-port=foo addresses=\"00:00:01:01:02:03\"
4010 # Connect alice to R2
4011 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4012 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4013 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4016 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
4017 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
4018 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
4020 # Connect R1 to join
4021 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4022 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4023 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4025 # Connect R2 to join
4026 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4027 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4028 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4030 # Connect R3 to join
4031 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
4032 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
4033 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
4035 #install static routes
4036 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4037 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
4039 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4040 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
4042 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4043 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
4045 # Create logical port foo1 in foo
4046 ovn-nbctl lsp-add foo foo1 \
4047 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4049 # Create logical port alice1 in alice
4050 ovn-nbctl lsp-add alice alice1 \
4051 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4053 # Create logical port bob1 in bob
4054 ovn-nbctl lsp-add bob bob1 \
4055 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
4057 # Create two hypervisor and create OVS ports corresponding to logical ports.
4062 ovs-vsctl add-br br-phys
4063 ovn_attach n1 br-phys 192.168.0.1
4064 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4065 set interface hv1-vif1 external-ids:iface-id=foo1 \
4066 options:tx_pcap=hv1/vif1-tx.pcap \
4067 options:rxq_pcap=hv1/vif1-rx.pcap \
4070 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4071 set interface hv1-vif2 external-ids:iface-id=alice1 \
4072 options:tx_pcap=hv1/vif2-tx.pcap \
4073 options:rxq_pcap=hv1/vif2-rx.pcap \
4078 ovs-vsctl add-br br-phys
4079 ovn_attach n1 br-phys 192.168.0.2
4080 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4081 set interface hv2-vif1 external-ids:iface-id=bob1 \
4082 options:tx_pcap=hv2/vif1-tx.pcap \
4083 options:rxq_pcap=hv2/vif1-rx.pcap \
4087 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4088 # packets for ARP resolution (native tunneling doesn't queue packets
4089 # for ARP resolution).
4092 # Allow some time for ovn-northd and ovn-controller to catch up.
4093 # XXX This should be more systematic.
4097 printf "%02x%02x%02x%02x" "$@"
4100 # Send ip packets between foo1 and alice1
4101 src_mac="f00000010203"
4102 dst_mac="000001010203"
4103 src_ip=`ip_to_hex 192 168 1 2`
4104 dst_ip=`ip_to_hex 172 16 1 2`
4105 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4106 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4107 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4109 # Send ip packets between foo1 and bob1
4110 src_mac="f00000010203"
4111 dst_mac="000001010203"
4112 src_ip=`ip_to_hex 192 168 1 2`
4113 dst_ip=`ip_to_hex 10 32 1 2`
4114 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4115 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4117 echo "---------NB dump-----"
4119 echo "---------------------"
4120 ovn-nbctl list logical_router
4121 echo "---------------------"
4122 ovn-nbctl list logical_router_port
4123 echo "---------------------"
4125 echo "---------SB dump-----"
4126 ovn-sbctl list datapath_binding
4127 echo "---------------------"
4128 ovn-sbctl list port_binding
4129 echo "---------------------"
4130 ovn-sbctl dump-flows
4131 echo "---------------------"
4133 echo "------ hv1 dump ----------"
4134 as hv1 ovs-ofctl show br-int
4135 as hv1 ovs-ofctl dump-flows br-int
4136 echo "------ hv2 dump ----------"
4137 as hv2 ovs-ofctl show br-int
4138 as hv2 ovs-ofctl dump-flows br-int
4139 echo "----------------------------"
4141 # Packet to Expect at bob1
4142 src_mac="000003010203"
4143 dst_mac="f00000010205"
4144 src_ip=`ip_to_hex 192 168 1 2`
4145 dst_ip=`ip_to_hex 10 32 1 2`
4146 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4148 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4150 # Packet to Expect at alice1
4151 src_mac="000002010203"
4152 dst_mac="f00000010204"
4153 src_ip=`ip_to_hex 192 168 1 2`
4154 dst_ip=`ip_to_hex 172 16 1 2`
4155 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4157 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4159 OVN_CLEANUP([hv1],[hv2])
4163 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
4164 AT_SKIP_IF([test $HAVE_PYTHON = no])
4167 ovn-nbctl ls-add ls1
4169 ovn-nbctl lsp-add ls1 ls1-lp1 \
4170 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4172 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4174 ovn-nbctl lsp-add ls1 ls1-lp2 \
4175 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4177 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4179 ovn-nbctl ls-add ls2
4180 ovn-nbctl lsp-add ls2 ls2-lp1 \
4181 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4182 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4183 ovn-nbctl lsp-add ls2 ls2-lp2 \
4184 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4185 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4187 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
4188 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
4189 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
4191 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4192 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4194 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
4195 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
4196 \"lease_time\"=\"3600\"")"
4198 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
4204 ovs-vsctl add-br br-phys
4205 ovn_attach n1 br-phys 192.168.0.1
4206 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4207 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4208 options:tx_pcap=hv1/vif1-tx.pcap \
4209 options:rxq_pcap=hv1/vif1-rx.pcap \
4212 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4213 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4214 options:tx_pcap=hv1/vif2-tx.pcap \
4215 options:rxq_pcap=hv1/vif2-rx.pcap \
4218 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4219 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4220 options:tx_pcap=hv1/vif3-tx.pcap \
4221 options:rxq_pcap=hv1/vif3-rx.pcap \
4224 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4225 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4226 options:tx_pcap=hv1/vif4-tx.pcap \
4227 options:rxq_pcap=hv1/vif4-rx.pcap \
4234 as hv1 ovs-vsctl show
4236 # This shell function sends a DHCP request packet
4237 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4239 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4240 shift; shift; shift; shift; shift;
4241 if test $use_ip != 0; then
4246 src_ip=`ip_to_hex 0 0 0 0`
4247 dst_ip=`ip_to_hex 255 255 255 255`
4249 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
4250 # udp header and dhcp header
4251 request=${request}0044004300fc0000
4252 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
4253 # client hardware padding
4254 request=${request}00000000000000000000
4256 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4257 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4259 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4260 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4261 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4262 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4264 request=${request}63825363
4266 request=${request}3501${dhcp_type}ff
4268 for port in $inport "$@"; do
4271 if test $offer_ip != 0; then
4272 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
4273 # total IP length will be the IP length of the request packet
4274 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4275 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4276 udp_len=`expr $ip_len - 20`
4277 ip_len=$(printf "%x" $ip_len)
4278 udp_len=$(printf "%x" $udp_len)
4279 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4280 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4281 # udp header and dhcp header.
4282 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4283 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
4285 reply=${reply}${offer_ip}
4286 # next server ip address, relay agent ip address, client mac address
4287 reply=${reply}0000000000000000${src_mac}
4288 # client hardware padding
4289 reply=${reply}00000000000000000000
4291 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4292 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4294 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4295 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4296 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4297 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4299 reply=${reply}63825363
4301 local dhcp_reply_type=02
4302 if test $dhcp_type = 03; then
4305 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4306 echo $reply >> $inport.expected
4309 echo $request >> $outport.expected
4312 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4318 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4319 options:rxq_pcap=dummy-rx.pcap
4320 rm -f ${pcap_file}*.pcap
4321 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4322 options:rxq_pcap=${pcap_file}-rx.pcap
4326 printf "%02x%02x%02x%02x" "$@"
4329 AT_CAPTURE_FILE([ofctl_monitor0.log])
4330 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4331 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4333 echo "---------NB dump-----"
4335 echo "---------------------"
4336 echo "---------SB dump-----"
4337 ovn-sbctl list datapath_binding
4338 echo "---------------------"
4339 ovn-sbctl list logical_flow
4340 echo "---------------------"
4342 echo "---------------------"
4343 ovn-sbctl dump-flows
4344 echo "---------------------"
4346 echo "------ hv1 dump ----------"
4347 as hv1 ovs-ofctl dump-flows br-int
4349 # Send DHCPDISCOVER.
4350 offer_ip=`ip_to_hex 10 0 0 4`
4351 server_ip=`ip_to_hex 10 0 0 1`
4352 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4353 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4355 # NXT_RESUMEs should be 1.
4356 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4358 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4359 cat 1.expected | cut -c -48 > expout
4360 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4361 # Skipping the IPv4 checksum.
4362 cat 1.expected | cut -c 53- > expout
4363 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4365 # ovs-ofctl also resumes the packets and this causes other ports to receive
4366 # the DHCP request packet. So reset the pcap files so that its easier to test.
4367 reset_pcap_file hv1-vif1 hv1/vif1
4368 reset_pcap_file hv1-vif2 hv1/vif2
4373 offer_ip=`ip_to_hex 10 0 0 6`
4374 server_ip=`ip_to_hex 10 0 0 1`
4375 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4376 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
4378 # NXT_RESUMEs should be 2.
4379 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4381 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4382 cat 2.expected | cut -c -48 > expout
4383 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4384 # Skipping the IPv4 checksum.
4385 cat 2.expected | cut -c 53- > expout
4386 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4388 reset_pcap_file hv1-vif1 hv1/vif1
4389 reset_pcap_file hv1-vif2 hv1/vif2
4393 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4394 # but should be resumed without the reply.
4395 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4396 # one from ovn-controller and the other from "ovs-ofctl resume."
4398 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
4400 # NXT_RESUMEs should be 3.
4401 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4403 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4404 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4406 reset_pcap_file hv1-vif1 hv1/vif1
4407 reset_pcap_file hv1-vif2 hv1/vif2
4411 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4412 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4414 test_dhcp 3 f00000000003 01 0 4 0
4416 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4418 test_dhcp 4 f00000000004 01 0 3 0
4420 # NXT_RESUMEs should be 3.
4421 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4423 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4424 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4426 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4427 offer_ip=`ip_to_hex 10 0 0 6`
4428 server_ip=`ip_to_hex 10 0 0 1`
4429 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4432 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4434 # NXT_RESUMEs should be 4.
4435 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4437 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4438 cat 2.expected | cut -c -48 > expout
4439 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4440 # Skipping the IPv4 checksum.
4441 cat 2.expected | cut -c 53- > expout
4442 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4444 reset_pcap_file hv1-vif1 hv1/vif1
4445 reset_pcap_file hv1-vif2 hv1/vif2
4449 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4450 offer_ip=`ip_to_hex 10 0 0 6`
4451 server_ip=`ip_to_hex 10 0 0 1`
4452 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4454 dst_ip=`ip_to_hex 255 255 255 255`
4455 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4457 # NXT_RESUMEs should be 5.
4458 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4460 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4461 cat 2.expected | cut -c -48 > expout
4462 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4463 # Skipping the IPv4 checksum.
4464 cat 2.expected | cut -c 53- > expout
4465 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4467 reset_pcap_file hv1-vif1 hv1/vif1
4468 reset_pcap_file hv1-vif2 hv1/vif2
4472 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4473 # The packet should not be received by ovn-controller.
4474 src_ip=`ip_to_hex 10 0 0 6`
4475 dst_ip=`ip_to_hex 10 0 0 4`
4476 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4478 # NXT_RESUMEs should be 5.
4479 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4481 # vif1-tx.pcap should have received the DHCPv4 request packet
4482 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4485 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4486 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4487 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4490 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4493 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4496 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4499 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4500 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4504 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4505 AT_SKIP_IF([test $HAVE_PYTHON = no])
4508 ovn-nbctl ls-add ls1
4509 ovn-nbctl lsp-add ls1 ls1-lp1 \
4510 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4512 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4514 ovn-nbctl lsp-add ls1 ls1-lp2 \
4515 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4517 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4519 ovn-nbctl lsp-add ls1 ls1-lp3 \
4520 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4522 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4524 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4525 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4527 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4528 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4530 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4531 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4533 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4535 ovn-nbctl ls-add ls2
4536 ovn-nbctl lsp-add ls2 ls2-lp1 \
4537 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4538 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4539 ovn-nbctl lsp-add ls2 ls2-lp2 \
4540 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4541 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4547 ovs-vsctl add-br br-phys
4548 ovn_attach n1 br-phys 192.168.0.1
4549 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4550 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4551 options:tx_pcap=hv1/vif1-tx.pcap \
4552 options:rxq_pcap=hv1/vif1-rx.pcap \
4555 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4556 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4557 options:tx_pcap=hv1/vif2-tx.pcap \
4558 options:rxq_pcap=hv1/vif2-rx.pcap \
4561 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4562 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4563 options:tx_pcap=hv1/vif3-tx.pcap \
4564 options:rxq_pcap=hv1/vif3-rx.pcap \
4567 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4568 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4569 options:tx_pcap=hv1/vif4-tx.pcap \
4570 options:rxq_pcap=hv1/vif4-rx.pcap \
4573 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4574 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4575 options:tx_pcap=hv1/vif5-tx.pcap \
4576 options:rxq_pcap=hv1/vif5-rx.pcap \
4584 sed 's/\(00\)\{1,\}$//'
4587 # This shell function sends a DHCPv6 request packet
4588 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4589 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4590 # packet should be received twice (one from ovn-controller and the other
4591 # from the "ovs-ofctl monitor br-int resume"
4593 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4594 if test $msg_code != 0b; then
4599 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
4601 request=${request}ff020000000000000000000000010002
4602 # udp header and dhcpv6 header
4603 request=${request}0222022300${req_len}ffff${msg_code}010203
4605 request=${request}0001000a00030001${src_mac}
4606 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4607 # is not 11 (information request packet)
4608 if test $msg_code != 0b; then
4609 request=${request}0003000c0102030400000e1000001518
4611 shift; shift; shift; shift; shift;
4612 if test $offer_ip != 0; then
4613 local server_mac=000000100001
4614 local server_lla=fe80000000000000020000fffe100001
4616 if test $msg_code = 01; then
4620 if test $offer_ip = 1; then
4623 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4624 # udp header and dhcpv6 header
4625 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4627 reply=${reply}0001000a00030001${src_mac}
4629 if test $offer_ip != 1; then
4630 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4633 reply=${reply}0002000a00030001${server_mac}
4634 echo $reply | trim_zeros >> $inport.expected
4637 echo $request | trim_zeros >> $outport.expected
4641 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4647 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4648 options:rxq_pcap=dummy-rx.pcap
4649 rm -f ${pcap_file}*.pcap
4650 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4651 options:rxq_pcap=${pcap_file}-rx.pcap
4654 AT_CAPTURE_FILE([ofctl_monitor0.log])
4655 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4656 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4658 echo "---------NB dump-----"
4660 echo "---------------------"
4661 echo "---------SB dump-----"
4662 ovn-sbctl list datapath_binding
4663 echo "---------------------"
4664 ovn-sbctl list logical_flow
4665 echo "---------------------"
4667 echo "---------------------"
4668 ovn-sbctl dump-flows
4669 echo "---------------------"
4671 echo "------ hv1 dump ----------"
4672 as hv1 ovs-ofctl dump-flows br-int
4674 src_mac=f00000000001
4675 src_lla=fe80000000000000f20000fffe000001
4676 offer_ip=ae700000000000000000000000000004
4677 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4679 # NXT_RESUMEs should be 1.
4680 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4682 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4683 # cat 1.expected | trim_zeros > expout
4684 cat 1.expected | cut -c -120 > expout
4685 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4686 # Skipping the UDP checksum
4687 cat 1.expected | cut -c 125- > expout
4688 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4692 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4693 # without any modifications and the packet should be received by ls1-lp1.
4694 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4695 # resume and the other from ovs-ofctl monitor resume.
4697 reset_pcap_file hv1-vif1 hv1/vif1
4698 reset_pcap_file hv1-vif2 hv1/vif2
4700 src_mac=f00000000002
4701 src_lla=fe80000000000000f20000fffe000002
4702 offer_ip=ae700000000000000000000000000005
4703 # Set invalid msg_type
4705 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4707 # NXT_RESUMEs should be 2.
4708 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4710 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4712 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4713 AT_CHECK([cat 2.packets], [0], [])
4715 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4716 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4717 cat 1.expected > expout
4718 AT_CHECK([cat 1.packets], [0], [expout])
4720 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4721 # There should be no DHCPv6 reply from ovn-controller and the request packet
4722 # should be received by ls2-lp2.
4724 src_mac=f00000000003
4725 src_lla=fe80000000000000f20000fffe000003
4726 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4728 # NXT_RESUMEs should be 2 only.
4729 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4731 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4732 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4733 AT_CHECK([cat 3.packets], [0], [])
4735 # vif4-tx.pcap should have received the DHCPv6 request packet
4736 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4737 cat 4.expected > expout
4738 AT_CHECK([cat 4.packets], [0], [expout])
4740 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4741 # The DHCPv6 reply shouldn't contain offer_ip.
4742 src_mac=f00000000022
4743 src_lla=fe80000000000000f20000fffe000022
4744 reset_pcap_file hv1-vif5 hv1/vif5
4745 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4747 # NXT_RESUMEs should be 3.
4748 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4750 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4751 # Skipping the UDP checksum
4752 cat 5.expected | cut -c 1-120,125- > expout
4753 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4755 # Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
4756 # shouldn't contain offer_ip
4757 src_mac=f00000000022
4758 src_lla=fe80000000000000f20000fffe000022
4759 reset_pcap_file hv1-vif5 hv1/vif5
4761 test_dhcpv6 5 $src_mac $src_lla 0b 1 5
4763 # NXT_RESUMEs should be 4.
4764 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4766 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
4767 trim_zeros > 5.packets
4768 # Skipping the UDP checksum
4769 cat 5.expected | cut -c 1-120,125- > expout
4770 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4773 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4774 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4775 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4778 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4781 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4784 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4787 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4788 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4792 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4793 AT_SKIP_IF([test $HAVE_PYTHON = no])
4797 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4798 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4799 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4800 # R2 is a gateway router.
4804 # Create two hypervisor and create OVS ports corresponding to logical ports.
4809 ovs-vsctl add-br br-phys
4810 ovn_attach n1 br-phys 192.168.0.1
4811 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4812 set interface hv1-vif1 external-ids:iface-id=foo1 \
4813 options:tx_pcap=hv1/vif1-tx.pcap \
4814 options:rxq_pcap=hv1/vif1-rx.pcap \
4820 ovs-vsctl add-br br-phys
4821 ovn_attach n1 br-phys 192.168.0.2
4822 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4823 set interface hv2-vif1 external-ids:iface-id=alice1 \
4824 options:tx_pcap=hv2/vif1-tx.pcap \
4825 options:rxq_pcap=hv2/vif1-rx.pcap \
4828 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4829 # packets for ARP resolution (native tunneling doesn't queue packets
4830 # for ARP resolution).
4833 ovn-nbctl create Logical_Router name=R1
4834 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4836 ovn-nbctl ls-add foo
4837 ovn-nbctl ls-add alice
4838 ovn-nbctl ls-add join
4841 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4842 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4843 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4845 # Connect alice to R2
4846 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4847 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4848 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4850 # Connect R1 to join
4851 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4852 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4853 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4855 # Connect R2 to join
4856 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4857 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4858 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4861 #install static routes
4862 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4863 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4864 R1 static_routes @lrt
4866 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4867 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4868 R2 static_routes @lrt
4870 # Create logical port foo1 in foo
4871 ovn-nbctl lsp-add foo foo1 \
4872 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4874 # Create logical port alice1 in alice
4875 ovn-nbctl lsp-add alice alice1 \
4876 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4879 # Allow some time for ovn-northd and ovn-controller to catch up.
4880 # XXX This should be more systematic.
4884 printf "%02x%02x%02x%02x" "$@"
4887 # Send ip packets between foo1 and alice1
4888 src_mac="f00000010203"
4889 dst_mac="000001010203"
4890 src_ip=`ip_to_hex 192 168 1 2`
4891 dst_ip=`ip_to_hex 172 16 1 2`
4892 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4894 echo "---------NB dump-----"
4896 echo "---------------------"
4897 ovn-nbctl list logical_router
4898 echo "---------------------"
4899 ovn-nbctl list logical_router_port
4900 echo "---------------------"
4902 echo "---------SB dump-----"
4903 ovn-sbctl list datapath_binding
4904 echo "---------------------"
4905 ovn-sbctl list port_binding
4906 echo "---------------------"
4907 ovn-sbctl dump-flows
4908 echo "---------------------"
4909 ovn-sbctl list chassis
4910 ovn-sbctl list encap
4911 echo "---------------------"
4913 # Packet to Expect at alice1
4914 src_mac="000002010203"
4915 dst_mac="f00000010204"
4916 src_ip=`ip_to_hex 192 168 1 2`
4917 dst_ip=`ip_to_hex 172 16 1 2`
4918 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4921 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4922 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4924 echo "------ hv1 dump after packet 1 ----------"
4925 as hv1 ovs-ofctl show br-int
4926 as hv1 ovs-ofctl dump-flows br-int
4927 echo "------ hv2 dump after packet 1 ----------"
4928 as hv2 ovs-ofctl show br-int
4929 as hv2 ovs-ofctl dump-flows br-int
4930 echo "----------------------------"
4932 echo $expected > expected
4933 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4935 # Delete the router and re-create it. Things should work as before.
4937 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4938 # Connect alice to R2
4939 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4940 # Connect R2 to join
4941 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4943 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4944 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4945 R2 static_routes @lrt
4947 # Wait for ovn-controller to catch up.
4950 # Send the packet again.
4951 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4953 echo "------ hv1 dump after packet 2 ----------"
4954 as hv1 ovs-ofctl show br-int
4955 as hv1 ovs-ofctl dump-flows br-int
4956 echo "------ hv2 dump after packet 2 ----------"
4957 as hv2 ovs-ofctl show br-int
4958 as hv2 ovs-ofctl dump-flows br-int
4959 echo "----------------------------"
4961 echo $expected >> expected
4962 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4964 OVN_CLEANUP([hv1],[hv2])
4968 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4969 AT_KEYWORDS([router-icmp-reply])
4970 AT_SKIP_IF([test $HAVE_PYTHON = no])
4974 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4975 # and has switch ls2 (172.16.1.0/24) connected to it.
4979 ovn-nbctl ls-add ls1
4980 ovn-nbctl ls-add ls2
4983 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4984 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4985 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4988 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4989 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4990 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4992 # Create logical port ls1-lp1 in ls1
4993 ovn-nbctl lsp-add ls1 ls1-lp1 \
4994 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4996 # Create logical port ls2-lp1 in ls2
4997 ovn-nbctl lsp-add ls2 ls2-lp1 \
4998 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5000 # Create one hypervisor and create OVS ports corresponding to logical ports.
5005 ovs-vsctl add-br br-phys
5006 ovn_attach n1 br-phys 192.168.0.1
5007 ovs-vsctl -- add-port br-int vif1 -- \
5008 set interface vif1 external-ids:iface-id=ls1-lp1 \
5009 options:tx_pcap=hv1/vif1-tx.pcap \
5010 options:rxq_pcap=hv1/vif1-rx.pcap \
5013 ovs-vsctl -- add-port br-int vif2 -- \
5014 set interface vif2 external-ids:iface-id=ls2-lp1 \
5015 options:tx_pcap=hv1/vif2-tx.pcap \
5016 options:rxq_pcap=hv1/vif2-rx.pcap \
5020 # Allow some time for ovn-northd and ovn-controller to catch up.
5021 # XXX This should be more systematic.
5026 printf "%02x%02x%02x%02x" "$@"
5031 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5033 # Causes a packet to be received on INPORT. The packet is an ICMPv4
5034 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5035 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5036 # provided, then it should be the ip and icmp checksums of the packet
5037 # responded; otherwise, no reply is expected.
5038 # In the absence of an ip checksum calculation helpers, this relies
5039 # on the caller to provide the checksums for the ip and icmp headers.
5040 # XXX This should be more systematic.
5042 # INPORT is an lport number, e.g. 11 for vif11.
5043 # ETH_SRC and ETH_DST are each 12 hex digits.
5044 # IPV4_SRC and IPV4_DST are each 8 hex digits.
5045 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5046 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5047 test_ipv4_icmp_request() {
5048 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5049 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5050 shift; shift; shift; shift; shift; shift; shift
5053 # Use ttl to exercise section 4.2.2.9 of RFC1812
5057 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5058 local icmp_type_code_request=0800
5059 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5060 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5062 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5063 if test X$exp_icmp_chksum != X; then
5064 # Expect to receive the reply, if any. In same port where packet was sent.
5065 # Note: src and dst fields are expected to be reversed.
5066 local icmp_type_code_response=0000
5067 local reply_icmp_ttl=fe
5068 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5069 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5070 echo $reply >> vif$inport.expected
5074 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
5075 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5076 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5077 l1_ip=$(ip_to_hex 192 168 1 2)
5078 l2_ip=$(ip_to_hex 172 16 1 2)
5080 # Ping router ip address that is on same subnet as the logical port
5081 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5082 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5084 # Ping router ip address that is on the other side of the logical ports
5085 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5086 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5088 echo "---------NB dump-----"
5090 echo "---------------------"
5091 ovn-nbctl list logical_router
5092 echo "---------------------"
5093 ovn-nbctl list logical_router_port
5094 echo "---------------------"
5096 echo "---------SB dump-----"
5097 ovn-sbctl list datapath_binding
5098 echo "---------------------"
5099 ovn-sbctl list logical_flow
5100 echo "---------------------"
5102 echo "------ hv1 dump ----------"
5103 as hv1 ovs-ofctl dump-flows br-int
5105 # Now check the packets actually received against the ones expected.
5106 for inport in 1 2; do
5107 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
5114 # 1 hypervisor, 1 port
5115 # make sure that the port state is properly set to up and back down
5116 # when created and deleted.
5117 AT_SETUP([ovn -- port state up and down])
5120 ovn-nbctl ls-add ls1
5121 ovn-nbctl lsp-add ls1 lp1
5122 ovn-nbctl lsp-set-addresses lp1 unknown
5126 as hv1 ovs-vsctl add-br br-phys
5127 as hv1 ovn_attach n1 br-phys 192.168.0.1
5129 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5130 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5132 as hv1 ovs-vsctl del-port br-int vif1
5133 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5139 # 1 hypervisor, 1 port
5140 # make sure that the OF rules created to support a datapath are added/cleared
5141 # when logical switch is created and removed.
5142 AT_SETUP([ovn -- datapath rules added/removed])
5143 AT_KEYWORDS([cleanup])
5148 as hv1 ovs-vsctl add-br br-phys
5149 as hv1 ovn_attach n1 br-phys 192.168.0.1
5151 # This shell function checks if OF rules in br-int have clauses
5152 # related to OVN datapaths. The caller determines if it should find
5153 # a match in the output, or not.
5155 # EXPECT_DATAPATH param determines whether flows that refer to
5156 # datapath to should be present or not. 0 means
5157 # they should not be.
5158 # STAGE_INFO param is a simple string to help identify the stage
5159 # in the test when this function was invoked.
5160 test_datapath_in_of_rules() {
5161 local expect_datapath=$1 stage_info=$2
5162 echo "------ ovn-nbctl show ${stage_info} ------"
5164 echo "------ ovn-sbctl show ${stage_info} ------"
5166 echo "------ OF rules ${stage_info} ------"
5167 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5168 # if there is a datapath mentioned in the output, check for the
5169 # magic keyword that represents one, based on the exit status of
5171 if test $expect_datapath != 0; then
5172 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
5174 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
5178 test_datapath_in_of_rules 0 "before ls+port create"
5180 ovn-nbctl ls-add ls1
5181 ovn-nbctl lsp-add ls1 lp1
5182 ovn-nbctl lsp-set-addresses lp1 unknown
5184 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5185 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5187 test_datapath_in_of_rules 1 "after port is bound"
5189 as hv1 ovs-vsctl del-port br-int vif1
5190 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5192 ovn-nbctl lsp-set-addresses lp1
5193 ovn-nbctl lsp-del lp1
5194 ovn-nbctl ls-del ls1
5196 # wait for earlier changes to take effect
5197 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5199 # ensure OF rules are no longer present. There used to be a bug here.
5200 test_datapath_in_of_rules 0 "after lport+ls removal"
5206 AT_SETUP([ovn -- nd_na ])
5207 AT_SKIP_IF([test $HAVE_PYTHON = no])
5210 #TODO: since patch port for IPv6 logical router port is not ready not,
5211 # so we are not going to test vifs on different lswitches cases. Try
5212 # to update for that once relevant stuff implemented.
5214 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
5215 # with. NS packet we test, from one VIF for another VIF, will be replied
5216 # by local ovn-controller, but not by target VIF.
5218 # Create hypervisors and logical switch lsw0.
5219 ovn-nbctl ls-add lsw0
5223 ovs-vsctl add-br br-phys
5224 ovn_attach n1 br-phys 192.168.0.2
5226 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5227 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
5228 ovn-nbctl lsp-add lsw0 lp1
5229 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5230 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"
5232 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5233 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
5234 ovn-nbctl lsp-add lsw0 lp2
5235 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5236 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"
5238 # Add ACL rule for ICMPv6 on lsw0
5239 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5240 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5241 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5243 # Allow some time for ovn-northd and ovn-controller to catch up.
5244 # XXX This should be more systematic.
5247 # Given the name of a logical port, prints the name of the hypervisor
5248 # on which it is located.
5256 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5257 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5258 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5259 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5260 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5262 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5263 echo $na_packet >> 1.expected
5265 echo "------ hv1 dump ------"
5266 as hv1 ovs-vsctl show
5267 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5268 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5271 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5278 AT_SETUP([ovn -- address sets modification/removal smoke test])
5285 ovs-vsctl add-br br-phys
5286 ovn_attach n1 br-phys 192.168.0.1
5288 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5289 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5290 ovn-nbctl destroy Address_Set $row
5294 # A bug previously existed in the address set support code
5295 # that caused ovn-controller to crash after an address set
5296 # was updated and then removed. This test case ensures
5297 # that ovn-controller is at least still running after
5298 # creating, updating, and deleting an address set.
5299 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5305 AT_SETUP([ovn -- ipam])
5306 AT_SKIP_IF([test $HAVE_PYTHON = no])
5309 # Add a port to a switch that does not have a subnet set, then set the
5310 # subnet which should result in an address being allocated for the port.
5311 ovn-nbctl ls-add sw0
5312 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5313 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5314 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5315 ["0a:00:00:00:00:01 192.168.1.2"
5318 # Add 9 more ports to sw0, addresses should all be unique.
5319 for n in `seq 1 9`; do
5320 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5322 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5323 ["0a:00:00:00:00:02 192.168.1.3"
5325 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5326 ["0a:00:00:00:00:03 192.168.1.4"
5328 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5329 ["0a:00:00:00:00:04 192.168.1.5"
5331 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5332 ["0a:00:00:00:00:05 192.168.1.6"
5334 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5335 ["0a:00:00:00:00:06 192.168.1.7"
5337 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5338 ["0a:00:00:00:00:07 192.168.1.8"
5340 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5341 ["0a:00:00:00:00:08 192.168.1.9"
5343 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5344 ["0a:00:00:00:00:09 192.168.1.10"
5346 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5347 ["0a:00:00:00:00:0a 192.168.1.11"
5350 # Trying similar tests with a second switch. MAC addresses should be unique
5351 # across both switches but IP's only need to be unique within the same switch.
5352 ovn-nbctl ls-add sw1
5353 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
5354 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
5355 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5356 ["0a:00:00:00:00:0b 192.168.1.2"
5359 for n in `seq 11 19`; do
5360 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
5362 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5363 ["0a:00:00:00:00:0c 192.168.1.3"
5365 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5366 ["0a:00:00:00:00:0d 192.168.1.4"
5368 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5369 ["0a:00:00:00:00:0e 192.168.1.5"
5371 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5372 ["0a:00:00:00:00:0f 192.168.1.6"
5374 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5375 ["0a:00:00:00:00:10 192.168.1.7"
5377 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5378 ["0a:00:00:00:00:11 192.168.1.8"
5380 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5381 ["0a:00:00:00:00:12 192.168.1.9"
5383 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5384 ["0a:00:00:00:00:13 192.168.1.10"
5386 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5387 ["0a:00:00:00:00:14 192.168.1.11"
5390 # Change a port's address to test for multiple ip's for a single address entry
5391 # and addresses set by the user.
5392 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.2 192.168.1.12 192.168.1.14"
5393 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
5394 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5395 ["0a:00:00:00:00:16 192.168.1.13"
5398 # Test for logical router port address management.
5399 ovn-nbctl create Logical_Router name=R1
5400 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5401 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5402 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5403 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
5404 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
5405 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5406 ["0a:00:00:00:00:18 192.168.1.15"
5409 # Test for address reuse after logical port is deleted.
5410 ovn-nbctl lsp-del p0
5411 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
5412 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5413 ["0a:00:00:00:00:19 192.168.1.2"
5416 # Test for multiple addresses to one logical port.
5417 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5418 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
5419 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
5420 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5421 ["0a:00:00:00:00:1c 192.168.1.16"
5424 # Test for exhausting subnet address space.
5425 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
5426 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
5427 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5428 ["0a:00:00:00:00:1d 172.16.1.2"
5431 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
5432 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
5433 ["0a:00:00:00:00:1e"
5436 # Test that address management does not add duplicate MAC for lsp/lrp peers.
5437 ovn-nbctl create Logical_Router name=R2
5438 ovn-nbctl ls-add sw3
5439 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
5441 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5442 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5443 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5444 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
5445 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
5446 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5447 ["0a:00:00:00:00:20 192.168.1.17"
5450 # Test static MAC address with dynamically allocated IP
5451 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5452 "fe:dc:ba:98:76:54 dynamic"
5453 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5454 ["fe:dc:ba:98:76:54 192.168.1.18"
5457 # Update the static MAC address with dynamically allocated IP and check
5458 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5459 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5461 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5462 ["fe:dc:ba:98:76:55 192.168.1.18"
5465 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5466 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5467 ["0a:00:00:00:00:21 192.168.1.18"
5470 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5471 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5472 ["fe:dc:ba:98:76:56 192.168.1.18"
5476 # Test the exclude_ips from the IPAM list
5477 ovn-nbctl --wait=sb set logical_switch sw0 \
5478 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5480 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5482 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5483 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5484 ["0a:00:00:00:00:22 192.168.1.20"
5487 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5489 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5490 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5491 ["0a:00:00:00:00:23 192.168.1.22"
5494 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5496 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5497 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5498 ["0a:00:00:00:00:24 192.168.1.51"
5501 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5502 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5503 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5505 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5506 ["0a:00:00:00:00:25 192.168.1.19"
5509 # Set invalid data in exclude_ips list. It should be ignored.
5510 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5511 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5513 # 192.168.1.21 should be assigned as that's the next free one.
5514 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5515 ["0a:00:00:00:00:26 192.168.1.21"
5518 # Clear the dynamic addresses assignment request.
5519 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5520 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5525 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5526 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5529 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5530 # - aef0::800:ff:fe00:26 (EUI64)
5531 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5532 ["0a:00:00:00:00:27 192.168.1.21 aef0::800:ff:fe00:27"
5535 ovn-nbctl --wait=sb ls-add sw4
5536 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
5537 -- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
5538 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5541 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5542 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5545 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5546 "f0:00:00:00:10:12 dynamic"
5548 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5549 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5552 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5553 # p40 should not have an IPv4 address since the pool is exhausted
5554 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5556 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5557 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5560 # Test dynamic changes on switch ports.
5562 ovn-nbctl --wait=sb ls-add sw5
5563 ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
5565 # p41 will start with nothing
5566 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5570 # Set a subnet. Now p41 should have an ipv4 address, too
5571 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5572 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5573 ["0a:00:00:00:00:2a 192.168.1.2"
5576 # Clear the other_config. The IPv4 address should be gone
5577 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5578 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5582 # Set an IPv6 prefix. Now p41 should have an IPv6 address.
5583 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
5584 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5585 ["0a:00:00:00:00:2b aef0::800:ff:fe00:2b"
5588 # Change the MAC address to a static one. The IPv6 address should update.
5589 ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
5590 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5591 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
5594 # Change the IPv6 prefix. The IPv6 address should update.
5595 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
5596 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5597 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
5600 # Clear the other_config. The IPv6 address should be gone
5601 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5602 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5606 # Set the subnet again. Now p41 should get the IPv4 address again.
5607 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5608 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5609 ["f0:00:00:00:10:2b 192.168.1.2"
5612 # Add an excluded IP address that conflicts with p41. p41 should update.
5613 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
5614 exclude_ips="192.168.1.2"
5615 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5616 ["f0:00:00:00:10:2b 192.168.1.3"
5619 # define a mac address prefix
5620 ovn-nbctl ls-add sw6
5621 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
5622 ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
5623 for n in $(seq 1 3); do
5624 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
5626 AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
5627 ["00:11:22:00:00:4d 192.168.100.2"
5629 AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
5630 ["00:11:22:00:00:4e 192.168.100.3"
5632 AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
5633 ["00:11:22:00:00:4f 192.168.100.4"
5637 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5640 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5643 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5647 AT_SETUP([ovn -- ipam connectivity])
5648 AT_SKIP_IF([test $HAVE_PYTHON = no])
5653 # Test for a ping using dynamically allocated addresses.
5654 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5655 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5658 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5659 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5660 options:router-port=foo \
5661 -- lsp-set-addresses rp-foo router
5663 # Connect alice to R1
5664 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5665 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5666 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5668 # Create logical port foo1 in foo
5669 ovn-nbctl --wait=sb lsp-add foo foo1 \
5670 -- lsp-set-addresses foo1 "dynamic"
5671 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])
5673 # Create logical port alice1 in alice
5674 ovn-nbctl --wait=sb lsp-add alice alice1 \
5675 -- lsp-set-addresses alice1 "dynamic"
5676 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5678 # Create logical port foo2 in foo
5679 ovn-nbctl --wait=sb lsp-add foo foo2 \
5680 -- lsp-set-addresses foo2 "dynamic"
5681 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5683 # Create a hypervisor and create OVS ports corresponding to logical ports.
5688 ovs-vsctl add-br br-phys
5689 ovn_attach n1 br-phys 192.168.0.1
5690 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5691 set interface hv1-vif1 external-ids:iface-id=foo1 \
5692 options:tx_pcap=hv1/vif1-tx.pcap \
5693 options:rxq_pcap=hv1/vif1-rx.pcap \
5696 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5697 set interface hv1-vif2 external-ids:iface-id=foo2 \
5698 options:tx_pcap=hv1/vif2-tx.pcap \
5699 options:rxq_pcap=hv1/vif2-rx.pcap \
5702 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5703 set interface hv1-vif3 external-ids:iface-id=alice1 \
5704 options:tx_pcap=hv1/vif3-tx.pcap \
5705 options:rxq_pcap=hv1/vif3-rx.pcap \
5708 # Allow some time for ovn-northd and ovn-controller to catch up.
5709 # XXX This should be more systematic.
5713 printf "%02x%02x%02x%02x" "$@"
5716 # Send ip packets between foo1 and foo2
5717 src_mac="0a0000000001"
5718 dst_mac="0a0000000003"
5719 src_ip=`ip_to_hex 192 168 1 2`
5720 dst_ip=`ip_to_hex 192 168 1 3`
5721 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5722 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5724 # Send ip packets between foo1 and alice1
5725 src_mac="0a0000000001"
5726 dst_mac="000000010203"
5727 src_ip=`ip_to_hex 192 168 1 2`
5728 dst_ip=`ip_to_hex 192 168 2 2`
5729 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5730 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5732 echo "---------NB dump-----"
5734 echo "---------------------"
5735 ovn-nbctl list logical_router
5736 echo "---------------------"
5737 ovn-nbctl list logical_router_port
5738 echo "---------------------"
5740 echo "---------SB dump-----"
5741 ovn-sbctl list datapath_binding
5742 echo "---------------------"
5743 ovn-sbctl list port_binding
5744 echo "---------------------"
5746 echo "------ hv1 dump ----------"
5747 as hv1 ovs-ofctl dump-flows br-int
5749 # Packet to Expect at foo2
5750 src_mac="0a0000000001"
5751 dst_mac="0a0000000003"
5752 src_ip=`ip_to_hex 192 168 1 2`
5753 dst_ip=`ip_to_hex 192 168 1 3`
5754 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5756 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5757 echo $expected > expout
5758 AT_CHECK([cat received1.packets], [0], [expout])
5760 # Packet to Expect at alice1
5761 src_mac="000000010204"
5762 dst_mac="0a0000000002"
5763 src_ip=`ip_to_hex 192 168 1 2`
5764 dst_ip=`ip_to_hex 192 168 2 2`
5765 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5767 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5768 echo $expected > expout
5769 AT_CHECK([cat received2.packets], [0], [expout])
5775 AT_SETUP([ovn -- ovs-vswitchd restart])
5776 AT_KEYWORDS([vswitchd])
5777 AT_SKIP_IF([test $HAVE_PYTHON = no])
5780 ovn-nbctl ls-add ls1
5782 ovn-nbctl lsp-add ls1 ls1-lp1 \
5783 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5785 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5791 ovs-vsctl add-br br-phys
5792 ovn_attach n1 br-phys 192.168.0.1
5793 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5794 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5795 options:tx_pcap=hv1/vif1-tx.pcap \
5796 options:rxq_pcap=hv1/vif1-rx.pcap \
5802 as hv1 ovs-vsctl show
5804 echo "---------------------"
5805 ovn-sbctl dump-flows
5806 echo "---------------------"
5808 echo "------ hv1 dump ----------"
5809 as hv1 ovs-ofctl dump-flows br-int
5810 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5812 echo "Total flows before vswitchd restart = " $total_flows
5814 # Code taken from ovs-save utility
5816 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5817 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5818 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5819 echo "EOF" >> restore_flows.sh
5822 restart_vswitchd () {
5825 if test $restore_flows = true; then
5830 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5832 if test $restore_flows = true; then
5834 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5838 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5839 ovs-ofctl dump-flows br-int
5841 if test $restore_flows = true; then
5842 sh ./restore_flows.sh
5843 echo "Flows after restore"
5845 ovs-ofctl dump-flows br-int
5846 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5847 flow-restore-wait="true"
5851 # Save the flows, restart vswitchd and restore the flows
5852 restart_vswitchd true
5854 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5855 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5856 test "${total_flows}" = "${total_flows_after_restart}"
5859 # Restart vswitchd without restoring
5860 restart_vswitchd false
5862 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5863 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5864 test "${total_flows}" = "${total_flows_after_restart}"
5870 AT_SETUP([ovn -- send arp for nexthop])
5871 AT_SKIP_IF([test $HAVE_PYTHON = no])
5874 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5876 # Create logical switches
5877 ovn-nbctl ls-add ls1
5878 ovn-nbctl ls-add ls2
5881 ovn-nbctl create Logical_Router name=lr0
5883 # Add router ls1p1 port to gateway router
5884 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5885 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5886 type=router options:router-port=lrp-ls1lp1 \
5887 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5889 # Add router ls2p2 port to gateway router
5890 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5891 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5892 type=router options:router-port=lrp-ls2lp1 \
5893 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5895 # Set default gateway (nexthop) to 192.168.1.254
5896 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5898 # Create logical port ls1lp2 in ls1
5899 ovn-nbctl lsp-add ls1 ls1lp2 \
5900 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5902 # Create logical port ls2lp2 in ls2
5903 ovn-nbctl lsp-add ls2 ls2lp2 \
5904 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5909 ovs-vsctl add-br br-phys
5910 ovn_attach n1 br-phys 192.168.0.1
5911 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5912 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5913 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5914 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5916 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5917 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5918 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5919 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5922 # Allow some time for ovn-northd and ovn-controller to catch up.
5923 # XXX This should be more systematic.
5926 echo "---------NB dump-----"
5928 echo "---------------------"
5929 ovn-nbctl list logical_router
5930 echo "---------------------"
5931 ovn-nbctl list logical_router_port
5932 echo "---------------------"
5934 echo "---------SB dump-----"
5935 ovn-sbctl list datapath_binding
5936 echo "---------------------"
5937 ovn-sbctl list port_binding
5938 echo "---------------------"
5939 ovn-sbctl dump-flows
5940 echo "---------------------"
5941 ovn-sbctl list chassis
5942 ovn-sbctl list encap
5943 echo "---------------------"
5945 echo "------Flows dump-----"
5947 ovs-ofctl dump-flows
5948 echo "---------------------"
5951 printf "%02x%02x%02x%02x" "$@"
5954 src_mac="f00000000003"
5955 dst_mac="f00000000001"
5956 src_ip=`ip_to_hex 192 168 0 2`
5957 dst_ip=`ip_to_hex 8 8 8 8`
5958 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5960 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5961 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5964 sed 's/\(00\)\{1,\}$//'
5967 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5970 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5971 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5972 echo $expected > expout
5973 AT_CHECK([cat packets], [0], [expout])
5980 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5981 AT_SKIP_IF([test $HAVE_PYTHON = no])
5983 # Create logical switch
5984 ovn-nbctl ls-add ls0
5985 # Create gateway router
5986 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5987 # Add router port to gateway router
5988 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5989 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5990 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5991 # Add nat-address option
5992 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6001 ovn_attach n1 br-phys 192.168.0.1
6003 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6004 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])
6006 # Create a localnet port.
6007 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6008 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6009 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6010 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6013 # Wait for packet to be received.
6014 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6016 sed 's/\(00\)\{1,\}$//'
6018 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6019 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6020 echo $expected > expout
6021 AT_CHECK([sort packets], [0], [expout])
6028 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6029 AT_SKIP_IF([test $HAVE_PYTHON = no])
6031 # Create logical switch
6032 ovn-nbctl ls-add ls0
6033 # Create gateway router
6034 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6035 # Add router port to gateway router
6036 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6037 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6038 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6039 # Add nat-address option
6040 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6042 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6043 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6044 # Add load balancers
6045 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6046 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6047 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6048 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6057 ovn_attach n1 br-phys 192.168.0.1
6059 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6060 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])
6062 # Create a localnet port.
6063 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6064 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6065 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6066 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6069 # Wait for packet to be received.
6070 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6072 sed 's/\(00\)\{1,\}$//'
6074 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6075 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6076 echo $expected > expout
6077 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6078 echo $expected >> expout
6079 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6080 echo $expected >> expout
6081 AT_CHECK([sort packets], [0], [expout])
6088 AT_SETUP([ovn -- delete mac bindings])
6093 ovs-vsctl -- add-br br-phys
6094 ovn_attach n1 br-phys 192.168.0.1
6095 # Create logical switch ls0
6096 ovn-nbctl ls-add ls0
6097 # Create ports lp0, lp1 in ls0
6098 ovn-nbctl lsp-add ls0 lp0
6099 ovn-nbctl lsp-add ls0 lp1
6100 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6101 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6102 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6103 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6104 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6105 ovn-sbctl find MAC_Binding
6106 # Delete port lp0 and check that its MAC_Binding is deleted.
6107 ovn-nbctl lsp-del lp0
6108 ovn-sbctl find MAC_Binding
6109 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6110 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
6111 ovn-nbctl ls-del ls0
6112 ovn-sbctl find MAC_Binding
6113 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6119 AT_SETUP([ovn -- conntrack zone allocation])
6120 AT_SKIP_IF([test $HAVE_PYTHON = no])
6124 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6125 # connected to a router R1.
6126 # foo has foo1 to act as a client.
6127 # bar has bar1, bar2, bar3 to act as servers.
6133 ovs-vsctl add-br br-phys
6134 ovn_attach n1 br-phys 192.168.0.1
6135 for i in foo1 bar1 bar2 bar3; do
6136 ovs-vsctl -- add-port br-int $i -- \
6137 set interface $i external-ids:iface-id=$i \
6138 options:tx_pcap=hv1/$i-tx.pcap \
6139 options:rxq_pcap=hv1/$i-rx.pcap
6142 ovn-nbctl create Logical_Router name=R1
6143 ovn-nbctl ls-add foo
6144 ovn-nbctl ls-add bar
6147 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6148 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6149 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6152 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6153 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6154 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6156 # Create logical port foo1 in foo
6157 ovn-nbctl lsp-add foo foo1 \
6158 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6160 # Create logical port bar1, bar2 and bar3 in bar
6161 for i in `seq 1 3`; do
6163 ovn-nbctl lsp-add bar bar$i \
6164 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6167 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6173 AT_SETUP([ovn -- tag allocation])
6176 AT_CHECK([ovn-nbctl ls-add ls0])
6177 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6178 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6179 AT_CHECK([ovn-nbctl ls-add ls1])
6181 dnl When a tag is provided, no allocation is done
6182 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6183 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6185 dnl The same 'tag' gets created in southbound database.
6186 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6187 logical_port="c0"], [0], [3
6190 dnl Allocate tags and see it getting created in both NB and SB
6191 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6192 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6194 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6195 logical_port="c1"], [0], [1
6198 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6199 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6201 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6202 logical_port="c2"], [0], [2
6204 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6205 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6207 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6208 logical_port="c3"], [0], [4
6211 dnl A different parent.
6212 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6213 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6215 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6216 logical_port="c4"], [0], [1
6219 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6220 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6222 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6223 logical_port="c5"], [0], [2
6226 dnl Delete a logical port and create a new one.
6227 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6228 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6229 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6231 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6232 logical_port="c6"], [0], [1
6235 dnl Restart northd to see that the same allocation remains.
6237 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6238 start_daemon ovn-northd \
6239 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6240 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6242 dnl Create a switch to make sure that ovn-northd has run through the main loop.
6243 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6244 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6246 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6248 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6250 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6252 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6254 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6257 dnl Create a switch port with a tag that has already been allocated.
6258 dnl It should go through fine with a duplicate tag.
6259 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6260 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6262 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6263 logical_port="c7"], [0], [2
6265 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6268 AT_CHECK([ovn-nbctl ls-add ls2])
6269 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6270 dnl gets copied to 'tag'
6271 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6272 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6274 dnl The same 'tag' gets created in southbound database.
6275 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6276 logical_port="local0"], [0], [25
6278 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
6279 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
6280 AT_CHECK([ovn-nbctl lsp-get-tag local1])
6281 dnl change the tag_request.
6282 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
6283 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
6288 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
6290 ovn-nbctl ls-add lsw0
6295 ovs-vsctl add-br br-phys
6296 ovn_attach n1 br-phys 192.168.0.$i
6297 ovs-vsctl add-br br-eth0
6298 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6301 # Create a localnet port.
6302 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
6303 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6304 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6305 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6309 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6310 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6311 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6312 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6313 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
6314 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6315 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6316 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6317 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6319 # Bind the localvif1 to hv1.
6321 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6323 # On hv1, check that there are no flows outputting bcast to tunnel
6324 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6326 # On hv2, check that no flow outputs bcast to tunnel to hv1.
6328 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6330 # Now bind vif2 on hv2.
6331 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6333 # At this point, the broadcast flow on vif2 should be deleted.
6334 # because, there is now a localnet vif bound (table=32 programming logic)
6335 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6337 # Verify that the local net patch port exists on hv2.
6338 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6340 # Now bind vif3 on hv2.
6341 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6343 # Verify that the local net patch port still exists on hv2
6344 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6347 AT_CHECK([ovn-nbctl lsp-del localvif2])
6349 # Verify that the local net patch port still exists on hv2,
6350 # because, localvif3 is still bound.
6351 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6353 OVN_CLEANUP([hv1],[hv2])
6358 AT_SETUP([ovn -- ACL logging])
6366 ovs-vsctl add-br br-phys
6367 ovn_attach n1 br-phys 192.168.0.1
6368 for i in lp1 lp2; do
6369 ovs-vsctl -- add-port br-int $i -- \
6370 set interface $i external-ids:iface-id=$i \
6371 options:tx_pcap=hv/$i-tx.pcap \
6372 options:rxq_pcap=hv/$i-rx.pcap
6375 lp1_mac="f0:00:00:00:00:01"
6376 lp1_ip="192.168.1.2"
6378 lp2_mac="f0:00:00:00:00:02"
6379 lp2_ip="192.168.1.3"
6381 ovn-nbctl ls-add lsw0
6382 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6383 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6384 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6385 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6386 ovn-nbctl --wait=sb sync
6388 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6389 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6391 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6392 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6394 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6395 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6397 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6398 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6400 ovn-sbctl dump-flows
6403 # Send packet that should be dropped without logging.
6404 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6405 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6406 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6407 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6409 # Send packet that should be dropped with logging.
6410 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6411 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6412 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6413 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6415 # Send packet that should be allowed without logging.
6416 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6417 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6418 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6419 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6421 # Send packet that should be allowed with logging.
6422 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6423 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6424 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6425 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6427 # Send packet that should allow related flows without logging.
6428 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6429 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6430 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6431 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6433 # Send packet that should allow related flows with logging.
6434 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6435 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6436 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6437 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6439 # Send packet that should be rejected without logging.
6440 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6441 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6442 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6443 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6445 # Send packet that should be rejected with logging.
6446 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6447 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6448 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6449 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6451 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6453 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6454 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
6455 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
6456 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
6457 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
6464 AT_SETUP([ovn -- ACL rate-limited logging])
6472 ovs-vsctl add-br br-phys
6473 ovn_attach n1 br-phys 192.168.0.1
6474 for i in lp1 lp2; do
6475 ovs-vsctl -- add-port br-int $i -- \
6476 set interface $i external-ids:iface-id=$i \
6477 options:tx_pcap=hv/$i-tx.pcap \
6478 options:rxq_pcap=hv/$i-rx.pcap
6481 lp1_mac="f0:00:00:00:00:01"
6482 lp1_ip="192.168.1.2"
6484 lp2_mac="f0:00:00:00:00:02"
6485 lp2_ip="192.168.1.3"
6487 ovn-nbctl ls-add lsw0
6488 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6489 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6490 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6491 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6492 ovn-nbctl --wait=sb sync
6495 # Add an ACL that rate-limits logs at 10 per second.
6496 ovn-nbctl meter-add http-rl1 drop 10 pktps
6497 ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6499 # Add an ACL that rate-limits logs at 5 per second.
6500 ovn-nbctl meter-add http-rl2 drop 5 pktps
6501 ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6503 # Add an ACL that doesn't rate-limit logs.
6504 ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6507 # For each ACL, send 100 packets.
6508 for i in `seq 1 100`; do
6509 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
6511 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
6513 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
6516 # The rate at which packets are sent is highly system-dependent, so we
6517 # can't count on precise drop counts. To work around that, we just
6518 # check that exactly 100 "http-acl3" actions were logged and that there
6519 # were more "http-acl1" actions than "http-acl2" ones.
6520 OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6522 # On particularly slow or overloaded systems, the transmission rate may
6523 # be lower than the configured meter rate. To prevent false test
6524 # failures, we check the duration count of the meter, and if it's
6525 # greater than nine seconds, just skip the test.
6526 d_secs=$(as hv ovs-ofctl -O OpenFlow13 meter-stats br-int | grep "meter:1" | sed 's/.* duration:\([[0-9]]\{1,\}\)\.[[0-9]]\+s .*/\1/')
6528 echo "Meter duration: $d_secs"
6529 AT_SKIP_IF([test $d_secs -gt 9])
6531 # Print some information that may help debugging.
6532 as hv ovs-appctl -t ovn-controller meter-table-list
6533 as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6535 n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6536 n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6537 n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6539 AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6540 AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6546 AT_SETUP([ovn -- DSCP marking and meter check])
6550 ovn-nbctl ls-add lsw0
6551 ovn-nbctl --wait=sb lsp-add lsw0 lp1
6552 ovn-nbctl --wait=sb lsp-add lsw0 lp2
6553 ovn-nbctl --wait=sb lsp-add lsw0 lp3
6554 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6555 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
6556 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
6557 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6558 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6559 ovn-nbctl --wait=sb sync
6563 ovs-vsctl add-br br-phys
6564 ovn_attach n1 br-phys 192.168.0.1
6565 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
6566 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
6568 AT_CAPTURE_FILE([trace])
6570 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6573 # Extracts nw_tos from the final flow from ofproto/trace output and prints
6574 # it on stdout. Prints "none" if no nw_tos was included.
6575 get_final_nw_tos() {
6576 if flow=$(grep '^Final flow:' stdout); then :; else
6577 # The output didn't have a final flow.
6581 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6590 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6592 # First check with ovn-trace for logical flows.
6593 echo "checking for tos $1"
6594 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6595 echo 'output("lp2");') > expout
6596 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])
6598 # Then re-check with ofproto/trace for a physical packet.
6599 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])
6600 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6605 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");
6607 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])
6608 AT_CHECK([get_final_nw_tos], [0], [none
6611 # check at L3 without dscp marking
6614 # Mark DSCP with a valid value
6615 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)
6616 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6620 # check at hv without qos meter
6621 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6624 # Update the meter rate
6625 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6627 # check at hv with a qos meter table
6628 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6630 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6633 # Update the DSCP marking
6634 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6637 # Update the meter rate
6638 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6640 # check at hv with a qos meter table
6641 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6643 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6646 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6649 # Disable DSCP marking
6650 ovn-nbctl --wait=hv qos-del lsw0
6651 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6655 # check at hv without qos meter
6656 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6659 # check meter with chassis not resident
6660 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6661 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6664 # check no meter table
6665 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6667 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6673 AT_SETUP([ovn -- read-only sb db:ptcp access])
6674 AT_SKIP_IF([test $HAVE_PYTHON = no])
6677 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6679 # Add read-only remote to sb ovsdb-server
6681 [ovsdb-tool transact ovn-sb.db \
6682 ['["OVN_Southbound",
6684 "table": "SB_Global",
6686 "connections": ["set", [["named-uuid", "xyz"]]]}},
6688 "table": "Connection",
6690 "row": {"target": "ptcp:0:127.0.0.1",
6691 "read_only": true}}]']], [0], [ignore], [ignore])
6693 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6695 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6697 # read-only accesses should succeed
6698 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6699 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6701 # write access should fail
6702 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6703 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6706 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6709 AT_SETUP([ovn -- read-only sb db:pssl access])
6710 AT_SKIP_IF([test $HAVE_PYTHON = no])
6711 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6712 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6713 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6717 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6719 # Add read-only remote to sb ovsdb-server
6721 [ovsdb-tool transact ovn-sb.db \
6722 ['["OVN_Southbound",
6724 "table": "SB_Global",
6726 "connections": ["set", [["named-uuid", "xyz"]]]}},
6728 "table": "Connection",
6730 "row": {"target": "pssl:0:127.0.0.1",
6731 "read_only": true}}]']], [0], [ignore], [ignore])
6733 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6734 --remote=db:OVN_Southbound,SB_Global,connections \
6735 --private-key="$PKIDIR/testpki-privkey2.pem" \
6736 --certificate="$PKIDIR/testpki-cert2.pem" \
6737 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6740 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6742 # read-only accesses should succeed
6743 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6744 --private-key=$PKIDIR/testpki-privkey.pem \
6745 --certificate=$PKIDIR/testpki-cert.pem \
6746 --ca-cert=$PKIDIR/testpki-cacert.pem \
6747 list SB_Global], [0], [stdout], [ignore])
6748 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6749 --private-key=$PKIDIR/testpki-privkey.pem \
6750 --certificate=$PKIDIR/testpki-cert.pem \
6751 --ca-cert=$PKIDIR/testpki-cacert.pem \
6752 list Connection], [0], [stdout], [ignore])
6754 # write access should fail
6755 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6756 --private-key=$PKIDIR/testpki-privkey.pem \
6757 --certificate=$PKIDIR/testpki-cert.pem \
6758 --ca-cert=$PKIDIR/testpki-cacert.pem \
6759 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6760 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6763 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6766 AT_SETUP([ovn -- nb connection/ssl commands])
6767 AT_SKIP_IF([test $HAVE_PYTHON = no])
6768 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6769 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6770 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6774 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6776 # Start nb db server using db connection/ssl entries (unpopulated initially)
6777 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6778 --remote=db:OVN_Northbound,NB_Global,connections \
6779 --private-key=db:OVN_Northbound,SSL,private_key \
6780 --certificate=db:OVN_Northbound,SSL,certificate \
6781 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6784 # Populate SSL configuration entries in nb db
6786 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6787 $PKIDIR/testpki-cert.pem \
6788 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6790 # Populate a passive SSL connection in nb db
6791 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6793 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6795 # Verify SSL connetivity to nb db server
6796 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6797 --private-key=$PKIDIR/testpki-privkey.pem \
6798 --certificate=$PKIDIR/testpki-cert.pem \
6799 --ca-cert=$PKIDIR/testpki-cacert.pem \
6801 [0], [stdout], [ignore])
6802 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6803 --private-key=$PKIDIR/testpki-privkey.pem \
6804 --certificate=$PKIDIR/testpki-cert.pem \
6805 --ca-cert=$PKIDIR/testpki-cacert.pem \
6807 [0], [stdout], [ignore])
6808 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6809 --private-key=$PKIDIR/testpki-privkey.pem \
6810 --certificate=$PKIDIR/testpki-cert.pem \
6811 --ca-cert=$PKIDIR/testpki-cacert.pem \
6813 [0], [stdout], [ignore])
6815 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6818 AT_SETUP([ovn -- sb connection/ssl commands])
6819 AT_SKIP_IF([test $HAVE_PYTHON = no])
6820 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6821 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6822 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6826 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6828 # Start sb db server using db connection/ssl entries (unpopulated initially)
6829 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6830 --remote=db:OVN_Southbound,SB_Global,connections \
6831 --private-key=db:OVN_Southbound,SSL,private_key \
6832 --certificate=db:OVN_Southbound,SSL,certificate \
6833 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6836 # Populate SSL configuration entries in sb db
6838 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6839 $PKIDIR/testpki-cert.pem \
6840 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6842 # Populate a passive SSL connection in sb db
6843 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6845 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6847 # Verify SSL connetivity to sb db server
6848 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6849 --private-key=$PKIDIR/testpki-privkey.pem \
6850 --certificate=$PKIDIR/testpki-cert.pem \
6851 --ca-cert=$PKIDIR/testpki-cacert.pem \
6853 [0], [stdout], [ignore])
6854 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6855 --private-key=$PKIDIR/testpki-privkey.pem \
6856 --certificate=$PKIDIR/testpki-cert.pem \
6857 --ca-cert=$PKIDIR/testpki-cacert.pem \
6859 [0], [stdout], [ignore])
6860 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6861 --private-key=$PKIDIR/testpki-privkey.pem \
6862 --certificate=$PKIDIR/testpki-cert.pem \
6863 --ca-cert=$PKIDIR/testpki-cacert.pem \
6865 [0], [stdout], [ignore])
6867 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6870 AT_SETUP([ovn -- nested containers])
6874 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6877 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6878 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6881 ovn-nbctl ls-add mgmt
6882 ovn-nbctl ls-add foo
6883 ovn-nbctl ls-add bar
6885 # Connect mgmt to R1
6886 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6887 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6888 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6891 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6892 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6893 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6896 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6897 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6898 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6900 # "mgmt" has VM1 and VM2 connected
6901 ovn-nbctl lsp-add mgmt vm1 \
6902 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6904 ovn-nbctl lsp-add mgmt vm2 \
6905 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6907 # "foo1" and "foo2" are containers belonging to switch "foo"
6908 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6909 ovn-nbctl lsp-add foo foo1 vm1 1 \
6910 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6912 ovn-nbctl lsp-add foo foo2 vm2 2 \
6913 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6915 # "bar1" and "bar2" are containers belonging to switch "bar"
6916 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6917 ovn-nbctl lsp-add bar bar1 vm1 2 \
6918 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6920 ovn-nbctl lsp-add bar bar2 vm2 1 \
6921 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6923 # bar3 is a standalone VM belonging to switch "bar"
6924 ovn-nbctl lsp-add bar bar3 \
6925 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6927 # Create two hypervisor and create OVS ports corresponding to logical ports.
6932 ovs-vsctl add-br br-phys
6933 ovn_attach n1 br-phys 192.168.0.1
6934 ovs-vsctl -- add-port br-int vm1 -- \
6935 set interface vm1 external-ids:iface-id=vm1 \
6936 options:tx_pcap=hv1/vm1-tx.pcap \
6937 options:rxq_pcap=hv1/vm1-rx.pcap \
6940 ovs-vsctl -- add-port br-int bar3 -- \
6941 set interface bar3 external-ids:iface-id=bar3 \
6942 options:tx_pcap=hv1/bar3-tx.pcap \
6943 options:rxq_pcap=hv1/bar3-rx.pcap \
6948 ovs-vsctl add-br br-phys
6949 ovn_attach n1 br-phys 192.168.0.2
6950 ovs-vsctl -- add-port br-int vm2 -- \
6951 set interface vm2 external-ids:iface-id=vm2 \
6952 options:tx_pcap=hv2/vm2-tx.pcap \
6953 options:rxq_pcap=hv2/vm2-rx.pcap \
6956 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6957 # packets for ARP resolution (native tunneling doesn't queue packets
6958 # for ARP resolution).
6961 # Allow some time for ovn-northd and ovn-controller to catch up.
6962 # XXX This should be more systematic.
6966 printf "%02x%02x%02x%02x" "$@"
6969 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6970 # different VLAN tags).
6971 src_mac="f00000010205"
6972 dst_mac="f00000010206"
6973 src_ip=`ip_to_hex 192 168 1 2`
6974 dst_ip=`ip_to_hex 192 168 1 3`
6975 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6976 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6978 # expected packet at foo2
6979 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6980 echo $packet > expected
6981 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6983 # Send ip packets between foo1 and bar2 (different switch, different HV)
6984 src_mac="f00000010205"
6985 dst_mac="000000010203"
6986 src_ip=`ip_to_hex 192 168 1 2`
6987 dst_ip=`ip_to_hex 192 168 2 3`
6988 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6989 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6991 # expected packet at bar2
6992 src_mac="000000010204"
6993 dst_mac="f00000010208"
6994 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6995 echo $packet >> expected
6996 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6998 # Send ip packets between foo1 and bar1
6999 # (different switch, loopback to same vm but different tag)
7000 src_mac="f00000010205"
7001 dst_mac="000000010203"
7002 src_ip=`ip_to_hex 192 168 1 2`
7003 dst_ip=`ip_to_hex 192 168 2 2`
7004 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7005 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7007 # expected packet at bar1
7008 src_mac="000000010204"
7009 dst_mac="f00000010207"
7010 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7011 echo $packet > expected1
7012 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7014 # Send ip packets between bar1 and bar3
7015 # (same switch. But one is container and another is a standalone VM)
7016 src_mac="f00000010207"
7017 dst_mac="f00000010209"
7018 src_ip=`ip_to_hex 192 168 2 2`
7019 dst_ip=`ip_to_hex 192 168 2 3`
7020 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7021 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7023 # expected packet at bar3
7024 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7025 echo $packet > expected
7026 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7028 # Send ip packets between foo1 and vm1.
7029 (different switch, container to the VM hosting it.)
7030 src_mac="f00000010205"
7031 dst_mac="000000010203"
7032 src_ip=`ip_to_hex 192 168 1 2`
7033 dst_ip=`ip_to_hex 172 16 1 2`
7034 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7035 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7037 # expected packet at vm1
7038 src_mac="000000010202"
7039 dst_mac="f00000010203"
7040 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7041 echo $packet >> expected1
7042 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7044 # Send packets from vm1 to bar1.
7045 (different switch, A hosting VM to a container inside it)
7046 src_mac="f00000010203"
7047 dst_mac="000000010202"
7048 src_ip=`ip_to_hex 172 16 1 2`
7049 dst_ip=`ip_to_hex 192 168 2 2`
7050 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7051 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7053 # expected packet at vm1
7054 src_mac="000000010204"
7055 dst_mac="f00000010207"
7056 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7057 echo $packet >> expected1
7058 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7060 # Send broadcast packet from foo1. foo1 should not receive the same packet.
7061 src_mac="f00000010205"
7062 dst_mac="ffffffffffff"
7063 src_ip=`ip_to_hex 192 168 1 2`
7064 dst_ip=`ip_to_hex 255 255 255 255`
7065 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7066 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7068 # expected packet at VM1
7069 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7071 OVN_CLEANUP([hv1],[hv2])
7075 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7076 AT_SKIP_IF([test $HAVE_PYTHON = no])
7080 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7081 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7082 # (192.168.2.0/24) connected to it.
7084 # R2 and R3 are gateway routers.
7085 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7086 # connected to it. Note how both alice and bob have the same subnet behind it.
7087 # We are trying to simulate external network via those 2 switches. In real
7088 # world the switch ports of these switches will have addresses set as "unknown"
7089 # to make them learning switches. Or those switches will be "localnet" ones.
7091 # Create three hypervisors and create OVS ports corresponding to logical ports.
7096 ovs-vsctl add-br br-phys
7097 ovn_attach n1 br-phys 192.168.0.1
7098 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7099 set interface hv1-vif1 external-ids:iface-id=foo1 \
7100 options:tx_pcap=hv1/vif1-tx.pcap \
7101 options:rxq_pcap=hv1/vif1-rx.pcap \
7104 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7105 set interface hv1-vif2 external-ids:iface-id=bar1 \
7106 options:tx_pcap=hv1/vif2-tx.pcap \
7107 options:rxq_pcap=hv1/vif2-rx.pcap \
7112 ovs-vsctl add-br br-phys
7113 ovn_attach n1 br-phys 192.168.0.2
7114 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7115 set interface hv2-vif1 external-ids:iface-id=alice1 \
7116 options:tx_pcap=hv2/vif1-tx.pcap \
7117 options:rxq_pcap=hv2/vif1-rx.pcap \
7122 ovs-vsctl add-br br-phys
7123 ovn_attach n1 br-phys 192.168.0.3
7124 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7125 set interface hv3-vif1 external-ids:iface-id=bob1 \
7126 options:tx_pcap=hv3/vif1-tx.pcap \
7127 options:rxq_pcap=hv3/vif1-rx.pcap \
7131 ovn-nbctl create Logical_Router name=R1
7132 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7133 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7135 ovn-nbctl ls-add foo
7136 ovn-nbctl ls-add bar
7137 ovn-nbctl ls-add alice
7138 ovn-nbctl ls-add bob
7139 ovn-nbctl ls-add join
7142 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7143 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7144 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7147 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7148 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7149 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7151 # Connect alice to R2
7152 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7153 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7154 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7157 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7158 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7159 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7161 # Connect R1 to join
7162 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7163 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7164 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7166 # Connect R2 to join
7167 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7168 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7169 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7171 # Connect R3 to join
7172 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7173 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7174 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7176 # Install static routes with source ip address as the policy for routing.
7177 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7178 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7179 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7181 # Install static routes with destination ip address as the policy for routing.
7182 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7184 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7186 # Create logical port foo1 in foo
7187 ovn-nbctl lsp-add foo foo1 \
7188 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7190 # Create logical port bar1 in bar
7191 ovn-nbctl lsp-add bar bar1 \
7192 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7194 # Create logical port alice1 in alice
7195 ovn-nbctl lsp-add alice alice1 \
7196 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7198 # Create logical port bob1 in bob
7199 ovn-nbctl lsp-add bob bob1 \
7200 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7202 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7203 # packets for ARP resolution (native tunneling doesn't queue packets
7204 # for ARP resolution).
7207 # Allow some time for ovn-northd and ovn-controller to catch up.
7208 # XXX This should be more systematic.
7212 printf "%02x%02x%02x%02x" "$@"
7215 sed 's/\(00\)\{1,\}$//'
7218 # Send ip packets between foo1 and bar1
7219 # (East-west traffic should flow normally)
7220 src_mac="f00000010203"
7221 dst_mac="000001010203"
7222 src_ip=`ip_to_hex 192 168 1 2`
7223 dst_ip=`ip_to_hex 192 168 2 2`
7224 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7225 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7227 # Send ip packets between foo1 and alice1
7228 src_mac="f00000010203"
7229 dst_mac="000001010203"
7230 src_ip=`ip_to_hex 192 168 1 2`
7231 dst_ip=`ip_to_hex 172 16 1 3`
7232 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7233 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7234 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
7236 # Send ip packets between bar1 and bob1
7237 src_mac="f00000010204"
7238 dst_mac="000001010204"
7239 src_ip=`ip_to_hex 192 168 2 2`
7240 dst_ip=`ip_to_hex 172 16 1 4`
7241 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7242 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7243 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7245 # Packet to expect at bar1
7246 src_mac="000001010204"
7247 dst_mac="f00000010204"
7248 src_ip=`ip_to_hex 192 168 1 2`
7249 dst_ip=`ip_to_hex 192 168 2 2`
7250 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7251 echo $expected > expected
7252 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7254 # Packet to Expect at alice1
7255 src_mac="000002010203"
7256 dst_mac="f00000010205"
7257 src_ip=`ip_to_hex 192 168 1 2`
7258 dst_ip=`ip_to_hex 172 16 1 3`
7259 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7260 echo $expected > expected
7261 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7263 # Packet to Expect at bob1
7264 src_mac="000003010203"
7265 dst_mac="f00000010206"
7266 src_ip=`ip_to_hex 192 168 2 2`
7267 dst_ip=`ip_to_hex 172 16 1 4`
7268 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7269 echo $expected > expected
7270 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7272 for sim in hv1 hv2 hv3; do
7274 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7275 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7276 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7280 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7283 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7286 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7289 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7290 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7294 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7295 AT_SKIP_IF([test $HAVE_PYTHON = no])
7298 ovn-nbctl ls-add ls1
7300 ovn-nbctl lsp-add ls1 ls1-lp1 \
7301 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7303 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7305 ovn-nbctl lsp-add ls1 ls1-lp2 \
7306 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7308 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7310 DNS1=`ovn-nbctl create DNS records={}`
7311 DNS2=`ovn-nbctl create DNS records={}`
7313 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7314 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
7315 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
7317 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
7323 ovs-vsctl add-br br-phys
7324 ovn_attach n1 br-phys 192.168.0.1
7325 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7326 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
7327 options:tx_pcap=hv1/vif1-tx.pcap \
7328 options:rxq_pcap=hv1/vif1-rx.pcap \
7331 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7332 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7333 options:tx_pcap=hv1/vif2-tx.pcap \
7334 options:rxq_pcap=hv1/vif2-rx.pcap \
7339 as hv1 ovs-vsctl show
7341 echo "*************************"
7343 echo "*************************"
7346 printf "%02x%02x%02x%02x" "$@"
7352 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7353 options:rxq_pcap=dummy-rx.pcap
7354 rm -f ${pcap_file}*.pcap
7355 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7356 options:rxq_pcap=${pcap_file}-rx.pcap
7359 # set_dns_params host_name
7360 # Sets the dns_req_data and dns_resp_data
7369 query_name=03766d31036f766e036f726700
7370 # IPv4 address - 10.0.0.4
7371 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7375 query_name=03766d32036f766e036f726700
7376 # IPv4 address - 10.0.0.6
7377 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7378 # IPv4 address - 20.0.0.4
7379 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7384 query_name=03766d33036f766e036f726700
7385 # IPv4 address - 40.0.0.4
7386 expected_dns_answer=${query_name}00010001${ttl}000428000004
7390 query_name=03766d31036f766e036f726700
7391 # IPv6 address - aef0::4
7393 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7397 query_name=03766d31036f766e036f726700
7400 # IPv4 address - 10.0.0.4
7401 # IPv6 address - aef0::4
7402 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7403 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7404 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7408 query_name=03766d31036f766e036f726700
7409 # IPv6 address - aef0::4
7417 local dns_req_header=010201200001000000000000
7418 local dns_resp_header=010281200001${an_count}00000000
7419 dns_req_data=${dns_req_header}${query_name}${type}0001
7420 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7423 # This shell function sends a DNS request packet
7424 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7426 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7427 local dns_query_data=$7
7428 shift; shift; shift; shift; shift; shift; shift;
7429 # Packet size => IPv4 header (20) + UDP header (8) +
7430 # DNS data (header + query)
7431 ip_len=`expr 28 + ${#dns_query_data} / 2`
7432 udp_len=`expr $ip_len - 20`
7433 ip_len=$(printf "%x" $ip_len)
7434 udp_len=$(printf "%x" $udp_len)
7435 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7436 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7438 request=${request}${dns_query_data}
7440 if test $dns_reply != 0; then
7442 ip_len=`expr 28 + ${#dns_reply} / 2`
7443 udp_len=`expr $ip_len - 20`
7444 ip_len=$(printf "%x" $ip_len)
7445 udp_len=$(printf "%x" $udp_len)
7446 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7447 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7448 echo $reply >> $inport.expected
7451 echo $request >> $outport.expected
7454 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7458 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7459 local dns_query_data=$7
7460 shift; shift; shift; shift; shift; shift; shift;
7461 # Packet size => UDP header (8) +
7462 # DNS data (header + query)
7463 ip_len=`expr 8 + ${#dns_query_data} / 2`
7465 ip_len=$(printf "%x" $ip_len)
7466 udp_len=$(printf "%x" $udp_len)
7467 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7468 request=${request}9234003500${udp_len}0000
7470 request=${request}${dns_query_data}
7472 if test $dns_reply != 0; then
7474 ip_len=`expr 8 + ${#dns_reply} / 2`
7476 ip_len=$(printf "%x" $ip_len)
7477 udp_len=$(printf "%x" $udp_len)
7478 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7479 reply=${reply}0035923400${udp_len}0000${dns_reply}
7480 echo $reply >> $inport.expected
7483 echo $request >> $outport.expected
7486 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7489 AT_CAPTURE_FILE([ofctl_monitor0.log])
7490 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7491 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7494 src_ip=`ip_to_hex 10 0 0 4`
7495 dst_ip=`ip_to_hex 10 0 0 1`
7497 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7499 # NXT_RESUMEs should be 1.
7500 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7502 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7503 cat 1.expected | cut -c -48 > expout
7504 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7505 # Skipping the IPv4 checksum.
7506 cat 1.expected | cut -c 53- > expout
7507 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7509 reset_pcap_file hv1-vif1 hv1/vif1
7510 reset_pcap_file hv1-vif2 hv1/vif2
7515 src_ip=`ip_to_hex 10 0 0 6`
7516 dst_ip=`ip_to_hex 10 0 0 1`
7518 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7520 # NXT_RESUMEs should be 2.
7521 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7523 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7524 cat 2.expected | cut -c -48 > expout
7525 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7526 # Skipping the IPv4 checksum.
7527 cat 2.expected | cut -c 53- > expout
7528 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7530 reset_pcap_file hv1-vif1 hv1/vif1
7531 reset_pcap_file hv1-vif2 hv1/vif2
7535 # Clear the query name options for ls1-lp2
7536 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7539 src_ip=`ip_to_hex 10 0 0 4`
7540 dst_ip=`ip_to_hex 10 0 0 1`
7542 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7544 # NXT_RESUMEs should be 3.
7545 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7547 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7548 AT_CHECK([cat 1.packets], [0], [])
7550 reset_pcap_file hv1-vif1 hv1/vif1
7551 reset_pcap_file hv1-vif2 hv1/vif2
7555 # Clear the query name for ls1-lp1
7556 # Since ls1 has no query names configued,
7557 # ovn-northd should not add the DNS flows.
7558 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7561 src_ip=`ip_to_hex 10 0 0 6`
7562 dst_ip=`ip_to_hex 10 0 0 1`
7564 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7566 # NXT_RESUMEs should be 3 only.
7567 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7569 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7570 AT_CHECK([cat 2.packets], [0], [])
7572 reset_pcap_file hv1-vif1 hv1/vif1
7573 reset_pcap_file hv1-vif2 hv1/vif2
7577 # Test IPv6 (AAAA records) using IPv4 packet.
7578 # Add back the DNS options for ls1-lp1.
7579 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7581 set_dns_params vm1_ipv6_only
7582 src_ip=`ip_to_hex 10 0 0 6`
7583 dst_ip=`ip_to_hex 10 0 0 1`
7585 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7587 # NXT_RESUMEs should be 4.
7588 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7590 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7591 cat 2.expected | cut -c -48 > expout
7592 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7593 # Skipping the IPv4 checksum.
7594 cat 2.expected | cut -c 53- > expout
7595 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7597 reset_pcap_file hv1-vif1 hv1/vif1
7598 reset_pcap_file hv1-vif2 hv1/vif2
7602 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7603 set_dns_params vm1_ipv4_v6
7604 src_ip=`ip_to_hex 10 0 0 6`
7605 dst_ip=`ip_to_hex 10 0 0 1`
7607 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7609 # NXT_RESUMEs should be 5.
7610 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7612 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7613 cat 2.expected | cut -c -48 > expout
7614 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7615 # Skipping the IPv4 checksum.
7616 cat 2.expected | cut -c 53- > expout
7617 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7619 reset_pcap_file hv1-vif1 hv1/vif1
7620 reset_pcap_file hv1-vif2 hv1/vif2
7625 set_dns_params vm1_invalid_type
7626 src_ip=`ip_to_hex 10 0 0 6`
7627 dst_ip=`ip_to_hex 10 0 0 1`
7629 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7631 # NXT_RESUMEs should be 6.
7632 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7634 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7635 AT_CHECK([cat 2.packets], [0], [])
7637 reset_pcap_file hv1-vif1 hv1/vif1
7638 reset_pcap_file hv1-vif2 hv1/vif2
7642 # Incomplete DNS packet.
7643 set_dns_params vm1_incomplete
7644 src_ip=`ip_to_hex 10 0 0 6`
7645 dst_ip=`ip_to_hex 10 0 0 1`
7647 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7649 # NXT_RESUMEs should be 7.
7650 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7652 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7653 AT_CHECK([cat 2.packets], [0], [])
7655 reset_pcap_file hv1-vif1 hv1/vif1
7656 reset_pcap_file hv1-vif2 hv1/vif2
7660 # Add one more DNS record to the ls1.
7661 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7664 src_ip=`ip_to_hex 10 0 0 4`
7665 dst_ip=`ip_to_hex 10 0 0 1`
7667 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7669 # NXT_RESUMEs should be 8.
7670 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7672 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7673 cat 1.expected | cut -c -48 > expout
7674 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7675 # Skipping the IPv4 checksum.
7676 cat 1.expected | cut -c 53- > expout
7677 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7679 reset_pcap_file hv1-vif1 hv1/vif1
7680 reset_pcap_file hv1-vif2 hv1/vif2
7684 # Try DNS query over IPv6
7686 src_ip=aef00000000000000000000000000004
7687 dst_ip=aef00000000000000000000000000001
7689 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7691 # NXT_RESUMEs should be 9.
7692 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7694 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7695 # Skipping the UDP checksum.
7696 cat 1.expected | cut -c 1-120,125- > expout
7697 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
7699 reset_pcap_file hv1-vif1 hv1/vif1
7700 reset_pcap_file hv1-vif2 hv1/vif2
7705 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7706 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7707 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7710 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7713 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7716 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7719 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7720 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7723 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7724 AT_SKIP_IF([test $HAVE_PYTHON = no])
7731 ovs-vsctl add-br br-phys
7732 ovn_attach n1 br-phys 192.168.0.1
7733 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7734 set interface hv1-vif1 external-ids:iface-id=foo1 \
7735 options:tx_pcap=hv1/vif1-tx.pcap \
7736 options:rxq_pcap=hv1/vif1-rx.pcap \
7741 ovs-vsctl add-br br-phys
7742 ovn_attach n1 br-phys 192.168.0.2
7746 ovs-vsctl add-br br-phys
7747 ovn_attach n1 br-phys 192.168.0.4
7751 ovs-vsctl add-br br-phys
7752 ovn_attach n1 br-phys 192.168.0.3
7753 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7754 set interface ext1-vif1 external-ids:iface-id=outside1 \
7755 options:tx_pcap=ext1/vif1-tx.pcap \
7756 options:rxq_pcap=ext1/vif1-rx.pcap \
7759 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7760 # packets for ARP resolution (native tunneling doesn't queue packets
7761 # for ARP resolution).
7764 ovn-nbctl create Logical_Router name=R1
7766 ovn-nbctl ls-add foo
7767 ovn-nbctl ls-add alice
7768 ovn-nbctl ls-add outside
7771 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7772 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7773 type=router options:router-port=foo \
7774 -- lsp-set-addresses rp-foo router
7776 # Connect alice to R1 as distributed router gateway port on gw1
7777 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7780 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7783 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7786 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7788 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7789 type=router options:router-port=alice \
7790 -- lsp-set-addresses rp-alice router
7792 # Create logical port foo1 in foo
7793 ovn-nbctl lsp-add foo foo1 \
7794 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7796 # Create logical port outside1 in outside
7797 ovn-nbctl lsp-add outside outside1 \
7798 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7800 # Create localnet port in alice
7801 ovn-nbctl lsp-add alice ln-alice
7802 ovn-nbctl lsp-set-addresses ln-alice unknown
7803 ovn-nbctl lsp-set-type ln-alice localnet
7804 ovn-nbctl lsp-set-options ln-alice network_name=phys
7806 # Create localnet port in outside
7807 ovn-nbctl lsp-add outside ln-outside
7808 ovn-nbctl lsp-set-addresses ln-outside unknown
7809 ovn-nbctl lsp-set-type ln-outside localnet
7810 ovn-nbctl lsp-set-options ln-outside network_name=phys
7812 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7813 # mapping to the external network, is the one generating packets
7814 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7815 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7816 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7818 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7820 # Allow some time for ovn-northd and ovn-controller to catch up.
7821 # XXX This should be more systematic.
7825 printf "%02x%02x%02x%02x" "$@"
7831 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7832 options:rxq_pcap=dummy-rx.pcap
7833 rm -f ${pcap_file}*.pcap
7834 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7835 options:rxq_pcap=${pcap_file}-rx.pcap
7843 # Send ip packet between foo1 and outside1
7844 src_mac="f00000010203" # foo1 mac
7845 dst_mac="000001010203" # rp-foo mac (internal router leg)
7846 src_ip=`ip_to_hex 192 168 1 2`
7847 dst_ip=`ip_to_hex 172 16 1 3`
7848 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7850 # ARP request packet to expect at outside1
7851 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7853 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7855 # Send ARP reply from outside1 back to the router
7856 # XXX: note, we could avoid this if we plug this port into a netns
7857 # and setup the IP address into the port, so the kernel would simply reply
7858 src_mac="000002010203"
7859 reply_mac="f00000010204"
7860 dst_ip=`ip_to_hex 172 16 1 3`
7861 src_ip=`ip_to_hex 172 16 1 1`
7862 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7864 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7867 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7868 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7871 # Packet to Expect at ext1 chassis, outside1 port
7872 src_mac="000002010203"
7873 dst_mac="f00000010204"
7874 src_ip=`ip_to_hex 192 168 1 2`
7875 dst_ip=`ip_to_hex 172 16 1 3`
7876 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7877 echo $expected > ext1-vif1.expected
7879 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7880 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7881 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7883 # Resend packet from foo1 to outside1
7884 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7888 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7889 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7890 AT_CHECK([grep $expected packets | sort], [0], [expout])
7891 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7892 AT_CHECK([grep $expected packets | sort], [0], [])
7895 test_ip_packet gw1 gw2
7897 ovn-nbctl --timeout=3 --wait=hv \
7898 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7901 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7904 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7906 test_ip_packet gw2 gw1
7908 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7911 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7912 AT_SKIP_IF([test $HAVE_PYTHON = no])
7919 ovs-vsctl add-br br-phys
7920 ovn_attach n1 br-phys 192.168.0.1
7921 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7922 set interface hv1-vif1 external-ids:iface-id=foo1 \
7923 options:tx_pcap=hv1/vif1-tx.pcap \
7924 options:rxq_pcap=hv1/vif1-rx.pcap \
7929 ovs-vsctl add-br br-phys
7930 ovn_attach n1 br-phys 192.168.0.2
7934 ovs-vsctl add-br br-phys
7935 ovn_attach n1 br-phys 192.168.0.4
7939 ovs-vsctl add-br br-phys
7940 ovn_attach n1 br-phys 192.168.0.3
7941 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7942 set interface ext1-vif1 external-ids:iface-id=outside1 \
7943 options:tx_pcap=ext1/vif1-tx.pcap \
7944 options:rxq_pcap=ext1/vif1-rx.pcap \
7947 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7948 # packets for ARP resolution (native tunneling doesn't queue packets
7949 # for ARP resolution).
7952 ovn-nbctl create Logical_Router name=R0
7953 ovn-nbctl create Logical_Router name=R1
7955 ovn-nbctl ls-add foo
7956 ovn-nbctl ls-add join
7957 ovn-nbctl ls-add alice
7958 ovn-nbctl ls-add outside
7961 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7962 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7963 type=router options:router-port=R0-foo \
7964 -- lsp-set-addresses foo-R0 router
7967 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7968 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7969 type=router options:router-port=R0-join \
7970 -- lsp-set-addresses join-R0 router
7973 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7974 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7975 type=router options:router-port=R1-join \
7976 -- lsp-set-addresses join-R1 router
7979 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7980 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7982 # Connect alice to R1 as distributed router gateway port on gw1
7983 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7986 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7989 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7992 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7994 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7995 type=router options:router-port=alice \
7996 -- lsp-set-addresses rp-alice router
7998 # Create logical port foo1 in foo
7999 ovn-nbctl lsp-add foo foo1 \
8000 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8002 # Create logical port outside1 in outside
8003 ovn-nbctl lsp-add outside outside1 \
8004 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8006 # Create localnet port in alice
8007 ovn-nbctl lsp-add alice ln-alice
8008 ovn-nbctl lsp-set-addresses ln-alice unknown
8009 ovn-nbctl lsp-set-type ln-alice localnet
8010 ovn-nbctl lsp-set-options ln-alice network_name=phys
8012 # Create localnet port in outside
8013 ovn-nbctl lsp-add outside ln-outside
8014 ovn-nbctl lsp-set-addresses ln-outside unknown
8015 ovn-nbctl lsp-set-type ln-outside localnet
8016 ovn-nbctl lsp-set-options ln-outside network_name=phys
8018 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8019 # mapping to the external network, is the one generating packets
8020 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8021 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8022 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8024 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8026 # Allow some time for ovn-northd and ovn-controller to catch up.
8027 # XXX This should be more systematic.
8031 printf "%02x%02x%02x%02x" "$@"
8037 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8038 options:rxq_pcap=dummy-rx.pcap
8039 rm -f ${pcap_file}*.pcap
8040 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8041 options:rxq_pcap=${pcap_file}-rx.pcap
8049 # Send ip packet between foo1 and outside1
8050 src_mac="f00000010203" # foo1 mac
8051 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8052 src_ip=`ip_to_hex 192 168 1 2`
8053 dst_ip=`ip_to_hex 172 16 1 3`
8054 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8056 # ARP request packet to expect at outside1
8057 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8059 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8061 # Send ARP reply from outside1 back to the router
8062 # XXX: note, we could avoid this if we plug this port into a netns
8063 # and setup the IP address into the port, so the kernel would simply reply
8064 src_mac="000002010203"
8065 reply_mac="f00000010204"
8066 dst_ip=`ip_to_hex 172 16 1 3`
8067 src_ip=`ip_to_hex 172 16 1 1`
8068 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8070 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8073 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8074 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8077 # Packet to Expect at ext1 chassis, outside1 port
8078 src_mac="000002010203"
8079 dst_mac="f00000010204"
8080 src_ip=`ip_to_hex 192 168 1 2`
8081 dst_ip=`ip_to_hex 172 16 1 3`
8082 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8083 echo $expected > ext1-vif1.expected
8085 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8086 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8087 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8089 # Resend packet from foo1 to outside1
8090 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8094 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8095 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8096 AT_CHECK([grep $expected packets | sort], [0], [expout])
8097 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8098 AT_CHECK([grep $expected packets | sort], [0], [])
8101 test_ip_packet gw1 gw2
8103 ovn-nbctl --timeout=3 --wait=hv \
8104 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8107 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8110 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8112 test_ip_packet gw2 gw1
8114 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8117 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8118 AT_SKIP_IF([test $HAVE_PYTHON = no])
8122 # One LR R1 that has switches foo (192.168.1.0/24) and
8123 # alice (172.16.1.0/24) connected to it. The logical port
8124 # between R1 and alice has a "redirect-chassis" specified,
8125 # i.e. it is the distributed router gateway port.
8126 # Switch alice also has a localnet port defined.
8127 # An additional switch outside has a localnet port and the
8128 # same subnet as alice (172.16.1.0/24).
8131 # Three hypervisors hv[123].
8132 # hv1 hosts vif foo1.
8133 # hv2 is the "redirect-chassis" that hosts the distributed
8134 # router gateway port.
8135 # hv3 hosts vif outside1.
8136 # In order to show that connectivity works only through hv2,
8137 # an initial round of tests is run without any bridge-mapping
8138 # defined for the localnet on hv2. These tests are expected
8140 # Subsequent tests are run after defining the bridge-mapping
8141 # for the localnet on hv2. These tests are expected to succeed.
8143 # Create three hypervisors and create OVS ports corresponding
8149 ovs-vsctl add-br br-phys
8150 ovn_attach n1 br-phys 192.168.0.1
8151 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8152 set interface hv1-vif1 external-ids:iface-id=foo1 \
8153 options:tx_pcap=hv1/vif1-tx.pcap \
8154 options:rxq_pcap=hv1/vif1-rx.pcap \
8159 ovs-vsctl add-br br-phys
8160 ovn_attach n1 br-phys 192.168.0.2
8164 ovs-vsctl add-br br-phys
8165 ovn_attach n1 br-phys 192.168.0.3
8166 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8167 set interface hv3-vif1 external-ids:iface-id=outside1 \
8168 options:tx_pcap=hv3/vif1-tx.pcap \
8169 options:rxq_pcap=hv3/vif1-rx.pcap \
8172 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8173 # packets for ARP resolution (native tunneling doesn't queue packets
8174 # for ARP resolution).
8177 ovn-nbctl create Logical_Router name=R1
8179 ovn-nbctl ls-add foo
8180 ovn-nbctl ls-add alice
8181 ovn-nbctl ls-add outside
8184 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8185 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8186 type=router options:router-port=foo \
8187 -- lsp-set-addresses rp-foo router
8189 # Connect alice to R1 as distributed router gateway port on hv2
8190 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8191 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8192 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8193 type=router options:router-port=alice \
8194 -- lsp-set-addresses rp-alice router
8196 # Create logical port foo1 in foo
8197 ovn-nbctl lsp-add foo foo1 \
8198 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8200 # Create logical port outside1 in outside
8201 ovn-nbctl lsp-add outside outside1 \
8202 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8204 # Create localnet port in alice
8205 ovn-nbctl lsp-add alice ln-alice
8206 ovn-nbctl lsp-set-addresses ln-alice unknown
8207 ovn-nbctl lsp-set-type ln-alice localnet
8208 ovn-nbctl lsp-set-options ln-alice network_name=phys
8210 # Create localnet port in outside
8211 ovn-nbctl lsp-add outside ln-outside
8212 ovn-nbctl lsp-set-addresses ln-outside unknown
8213 ovn-nbctl lsp-set-type ln-outside localnet
8214 ovn-nbctl lsp-set-options ln-outside network_name=phys
8216 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8217 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8218 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8221 # Allow some time for ovn-northd and ovn-controller to catch up.
8222 # XXX This should be more systematic.
8225 echo "---------NB dump-----"
8227 echo "---------------------"
8228 ovn-nbctl list logical_router
8229 echo "---------------------"
8230 ovn-nbctl list logical_router_port
8231 echo "---------------------"
8233 echo "---------SB dump-----"
8234 ovn-sbctl list datapath_binding
8235 echo "---------------------"
8236 ovn-sbctl list port_binding
8237 echo "---------------------"
8238 ovn-sbctl dump-flows
8239 echo "---------------------"
8240 ovn-sbctl list chassis
8241 ovn-sbctl list encap
8242 echo "------ Gateway_Chassis dump (SBDB) -------"
8243 ovn-sbctl list Gateway_Chassis
8244 echo "------ Port_Binding chassisredirect -------"
8245 ovn-sbctl find Port_Binding type=chassisredirect
8246 echo "-------------------------------------------"
8248 echo "------ hv1 dump ----------"
8249 as hv1 ovs-ofctl show br-int
8250 as hv1 ovs-ofctl dump-flows br-int
8251 echo "------ hv2 dump ----------"
8252 as hv2 ovs-ofctl show br-int
8253 as hv2 ovs-ofctl dump-flows br-int
8254 echo "------ hv3 dump ----------"
8255 as hv3 ovs-ofctl show br-int
8256 as hv3 ovs-ofctl dump-flows br-int
8257 echo "--------------------------"
8260 # Check that redirect mapping is programmed only on hv2
8261 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8263 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8265 # Check that hv1 sends chassisredirect port traffic to hv2
8266 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8268 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8270 # Check that arp reply on distributed gateway port is only programmed on hv2
8271 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
8273 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
8278 printf "%02x%02x%02x%02x" "$@"
8282 : > hv2-vif1.expected
8283 : > hv3-vif1.expected
8285 # test_arp INPORT SHA SPA TPA [REPLY_HA]
8287 # Causes a packet to be received on INPORT. The packet is an ARP
8288 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
8289 # it should be the hardware address of the target to expect to receive in an
8290 # ARP reply; otherwise no reply is expected.
8292 # INPORT is an logical switch port number, e.g. 11 for vif11.
8293 # SHA and REPLY_HA are each 12 hex digits.
8294 # SPA and TPA are each 8 hex digits.
8296 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
8297 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
8298 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
8300 if test X$reply_ha != X; then
8301 # Expect to receive the reply, if any.
8302 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
8303 echo $reply >> hv${hv}-vif$inport.expected
8307 rtr_ip=$(ip_to_hex 172 16 1 1)
8308 foo_ip=$(ip_to_hex 192 168 1 2)
8309 outside_ip=$(ip_to_hex 172 16 1 3)
8315 # ARP for router IP address from outside1, no response expected
8316 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
8318 # Now check the packets actually received against the ones expected.
8319 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8321 # Send ip packet between foo1 and outside1
8322 src_mac="f00000010203"
8323 dst_mac="000001010203"
8324 src_ip=`ip_to_hex 192 168 1 2`
8325 dst_ip=`ip_to_hex 172 16 1 3`
8326 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8328 # Now check the packets actually received against the ones expected.
8329 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8331 # Now add bridge-mappings on hv2, which should make everything work
8332 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8334 # Allow some time for ovn-northd and ovn-controller to catch up.
8335 # XXX This should be more systematic.
8338 # ARP for router IP address from outside1
8339 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8341 # Now check the packets actually received against the ones expected.
8342 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8344 # Send ip packet between foo1 and outside1
8345 src_mac="f00000010203"
8346 dst_mac="000001010203"
8347 src_ip=`ip_to_hex 192 168 1 2`
8348 dst_ip=`ip_to_hex 172 16 1 3`
8349 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8351 # Packet to Expect at outside1
8352 src_mac="000002010203"
8353 dst_mac="f00000010204"
8354 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8356 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8358 echo "------ hv1 dump ----------"
8359 as hv1 ovs-ofctl show br-int
8360 as hv1 ovs-ofctl dump-flows br-int
8361 echo "------ hv2 dump ----------"
8362 as hv2 ovs-ofctl show br-int
8363 as hv2 ovs-ofctl dump-flows br-int
8364 echo "------ hv3 dump ----------"
8365 as hv3 ovs-ofctl show br-int
8366 as hv3 ovs-ofctl dump-flows br-int
8367 echo "----------------------------"
8369 echo $expected >> hv3-vif1.expected
8370 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8372 #Check ovn-trace over "chassisredirect" port
8373 AT_CAPTURE_FILE([trace])
8375 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8378 echo 'ip.ttl--;' > expout
8379 echo 'eth.src = 00:00:02:01:02:03;' >> expout
8380 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8381 echo 'output("ln-alice");' >> expout
8382 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])
8384 # Create logical port alice1 in alice on hv1
8385 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8386 set interface hv1-vif2 external-ids:iface-id=alice1 \
8387 options:tx_pcap=hv1/vif2-tx.pcap \
8388 options:rxq_pcap=hv1/vif2-rx.pcap \
8391 ovn-nbctl lsp-add alice alice1 \
8392 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8394 # Create logical port foo2 in foo on hv2
8395 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8396 set interface hv2-vif1 external-ids:iface-id=foo2 \
8397 options:tx_pcap=hv2/vif1-tx.pcap \
8398 options:rxq_pcap=hv2/vif1-rx.pcap \
8401 ovn-nbctl lsp-add foo foo2 \
8402 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8404 # Allow some time for ovn-northd and ovn-controller to catch up.
8405 # XXX This should be more systematic.
8408 : > hv1-vif2.expected
8410 # Send ip packet between alice1 and foo2
8411 src_mac="f00000010205"
8412 dst_mac="000002010203"
8413 src_ip=`ip_to_hex 172 16 1 4`
8414 dst_ip=`ip_to_hex 192 168 1 3`
8415 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8417 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8419 # Packet to Expect at foo2
8420 src_mac="000001010203"
8421 dst_mac="f00000010206"
8422 src_ip=`ip_to_hex 172 16 1 4`
8423 dst_ip=`ip_to_hex 192 168 1 3`
8424 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8426 echo $expected >> hv2-vif1.expected
8427 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
8429 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
8432 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
8434 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
8437 OVN_CLEANUP([hv1],[hv2],[hv3])
8441 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8442 AT_SKIP_IF([test $HAVE_PYTHON = no])
8444 # Create logical switches
8445 ovn-nbctl ls-add ls0
8446 ovn-nbctl ls-add ls1
8447 # Create distributed router
8448 ovn-nbctl create Logical_Router name=lr0
8449 # Add distributed gateway port to distributed router
8450 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8451 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8452 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8453 type=router options:router-port=lrp0 addresses="router"
8454 # Add router port to ls1
8455 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8456 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8457 type=router options:router-port=lrp1 addresses="router"
8458 # Add logical ports for NAT rules
8459 ovn-nbctl lsp-add ls1 foo1 \
8460 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8461 ovn-nbctl lsp-add ls1 foo2 \
8462 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
8463 # Add nat-addresses option
8464 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8466 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8467 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8468 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])
8469 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])
8474 ovs-vsctl add-br br-phys
8475 ovn_attach n1 br-phys 192.168.0.1
8477 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8478 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])
8482 ovs-vsctl add-br br-phys
8483 ovn_attach n1 br-phys 192.168.0.2
8484 # Initially test with no bridge-mapping on hv2, expect to receive no packets
8488 ovs-vsctl add-br br-phys
8489 ovn_attach n1 br-phys 192.168.0.3
8490 # Initially test with no bridge-mapping on hv3
8492 # Create a localnet port.
8493 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8494 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8495 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8496 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8498 # Allow some time for ovn-northd and ovn-controller to catch up.
8499 # XXX This should be more systematic.
8502 # Expect no packets when hv2 bridge-mapping is not present
8504 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8506 # Add bridge-mapping on hv2
8507 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8509 # Wait for packets to be received.
8510 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8512 sed 's/\(00\)\{1,\}$//'
8514 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8515 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8516 echo $expected > expout
8517 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8518 echo $expected >> expout
8519 AT_CHECK([sort packets], [0], [expout])
8522 # Temporarily remove nat-addresses option to avoid race conditions
8523 # due to GARP backoff
8524 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8529 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8530 options:rxq_pcap=dummy-rx.pcap
8531 rm -f ${pcap_file}*.pcap
8532 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8533 options:rxq_pcap=${pcap_file}-rx.pcap
8536 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8538 # Add OVS ports for foo1 and foo2 on hv3
8539 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8540 set interface hv3-vif1 external-ids:iface-id=foo1 \
8542 ovs-vsctl -- add-port br-int hv3-vif2 -- \
8543 set interface hv3-vif2 external-ids:iface-id=foo2 \
8546 # Add bridge-mapping on hv3
8547 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8549 # Re-add nat-addresses option
8550 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8552 # Wait for packets to be received.
8553 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8555 sed 's/\(00\)\{1,\}$//'
8558 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8559 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8560 echo $expected >> expout
8561 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8562 echo $expected >> expout
8563 AT_CHECK([sort packets], [0], [expout])
8566 OVN_CLEANUP([hv1],[hv2],[hv3])
8570 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8571 AT_KEYWORDS([ovn-nd_ra])
8572 AT_SKIP_IF([test $HAVE_PYTHON = no])
8575 # In this test case we create 1 lswitch with 3 VIF ports attached,
8576 # and a lrouter connected to the lswitch.
8577 # We generate the Router solicitation packet and verify the Router Advertisement
8578 # reply packet from the ovn-controller.
8580 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8581 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8582 # 'slaac' to allow lrp0 send RA for SLAAC mode.
8583 ovn-nbctl ls-add lsw0
8584 ovn-nbctl lr-add lr0
8585 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8586 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8588 -- lsp-add lsw0 lsp0 \
8589 -- set Logical_Switch_Port lsp0 type=router \
8590 options:router-port=lrp0 \
8591 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8595 ovs-vsctl add-br br-phys
8596 ovn_attach n1 br-phys 192.168.0.2
8598 ovn-nbctl lsp-add lsw0 lp1
8599 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8600 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"
8602 ovn-nbctl lsp-add lsw0 lp2
8603 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8604 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"
8606 ovn-nbctl lsp-add lsw0 lp3
8607 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8608 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"
8610 # Add ACL rule for ICMPv6 on lsw0
8611 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8612 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8613 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8614 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8616 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8617 set interface hv1-vif1 external-ids:iface-id=lp1 \
8618 options:tx_pcap=hv1/vif1-tx.pcap \
8619 options:rxq_pcap=hv1/vif1-rx.pcap \
8622 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8623 set interface hv1-vif2 external-ids:iface-id=lp2 \
8624 options:tx_pcap=hv1/vif2-tx.pcap \
8625 options:rxq_pcap=hv1/vif2-rx.pcap \
8628 ovs-vsctl -- add-port br-int hv1-vif3 -- \
8629 set interface hv1-vif3 external-ids:iface-id=lp3 \
8630 options:tx_pcap=hv1/vif3-tx.pcap \
8631 options:rxq_pcap=hv1/vif3-rx.pcap \
8634 # Allow some time for ovn-northd and ovn-controller to catch up.
8635 # XXX This should be more systematic.
8641 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8642 options:rxq_pcap=dummy-rx.pcap
8643 rm -f ${pcap_file}*.pcap
8644 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8645 options:rxq_pcap=${pcap_file}-rx.pcap
8648 # Make sure that ovn-controller has installed the corresponding OF Flow.
8649 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"`])
8651 # This shell function sends a Router Solicitation packet.
8652 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8654 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8655 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8659 if test $mtu != 0; then
8661 mtu_opt=05010000${mtu}
8664 if test ${#prefix_opt} != 0; then
8665 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8666 len=`expr $len + ${#prefix_opt} / 2`
8669 len=$(printf "%x" $len)
8670 local lrp_mac=fa163e000001
8671 local lrp_lla=fe80000000000000f8163efffe000001
8672 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8673 echo $reply >> $inport.expected
8675 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8678 AT_CAPTURE_FILE([ofctl_monitor0.log])
8679 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8680 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8682 # MTU is not set and the address mode is set to slaac
8684 default_prefix_option_config=030440c0ffffffffffffffff00000000
8685 src_mac=fa163e000002
8686 src_lla=fe80000000000000f8163efffe000002
8687 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8689 # NXT_RESUME should be 1.
8690 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8692 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8694 cat 1.expected | cut -c -112 > expout
8695 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8697 # Skipping the ICMPv6 checksum.
8698 cat 1.expected | cut -c 117- > expout
8699 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8702 reset_pcap_file hv1-vif1 hv1/vif1
8703 reset_pcap_file hv1-vif2 hv1/vif2
8704 reset_pcap_file hv1-vif3 hv1/vif3
8706 # Set the MTU to 1500
8707 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8709 # Make sure that ovn-controller has installed the corresponding OF Flow.
8710 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"`])
8713 default_prefix_option_config=030440c0ffffffffffffffff00000000
8714 src_mac=fa163e000003
8715 src_lla=fe80000000000000f8163efffe000003
8718 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8720 # NXT_RESUME should be 2.
8721 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8723 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8725 cat 2.expected | cut -c -112 > expout
8726 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8728 # Skipping the ICMPv6 checksum.
8729 cat 2.expected | cut -c 117- > expout
8730 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8733 reset_pcap_file hv1-vif1 hv1/vif1
8734 reset_pcap_file hv1-vif2 hv1/vif2
8735 reset_pcap_file hv1-vif3 hv1/vif3
8737 # Set the address mode to dhcpv6_stateful
8738 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8739 # Make sure that ovn-controller has installed the corresponding OF Flow.
8740 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"`])
8743 default_prefix_option_config=""
8744 src_mac=fa163e000004
8745 src_lla=fe80000000000000f8163efffe000004
8748 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8750 # NXT_RESUME should be 3.
8751 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8753 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8755 cat 3.expected | cut -c -112 > expout
8756 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8758 # Skipping the ICMPv6 checksum.
8759 cat 3.expected | cut -c 117- > expout
8760 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8763 reset_pcap_file hv1-vif1 hv1/vif1
8764 reset_pcap_file hv1-vif2 hv1/vif2
8765 reset_pcap_file hv1-vif3 hv1/vif3
8767 # Set the address mode to dhcpv6_stateless
8768 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8769 # Make sure that ovn-controller has installed the corresponding OF Flow.
8770 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"`])
8773 default_prefix_option_config=030440c0ffffffffffffffff00000000
8774 src_mac=fa163e000002
8775 src_lla=fe80000000000000f8163efffe000002
8778 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8780 # NXT_RESUME should be 4.
8781 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8783 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8785 cat 1.expected | cut -c -112 > expout
8786 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8788 # Skipping the ICMPv6 checksum.
8789 cat 1.expected | cut -c 117- > expout
8790 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8793 reset_pcap_file hv1-vif1 hv1/vif1
8794 reset_pcap_file hv1-vif2 hv1/vif2
8795 reset_pcap_file hv1-vif3 hv1/vif3
8797 # Set the address mode to invalid.
8798 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8799 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8800 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"`])
8803 default_prefix_option_config=""
8804 src_mac=fa163e000002
8805 src_lla=fe80000000000000f8163efffe000002
8808 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8810 # NXT_RESUME should be 4 only.
8811 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8813 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8814 AT_CHECK([cat 1.packets], [0], [])
8819 AT_SETUP([ovn -- /32 router IP address])
8820 AT_SKIP_IF([test $HAVE_PYTHON = no])
8824 # 2 LS 'foo' and 'alice' connected via router R1.
8825 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8826 # nexthop to push traffic to a logical port in switch 'alice'
8830 ovn-nbctl ls-add foo
8831 ovn-nbctl ls-add alice
8834 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8835 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8836 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8838 # Connect alice to R1.
8839 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8840 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8841 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8843 # Create logical port foo1 in foo
8844 ovn-nbctl lsp-add foo foo1 \
8845 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8847 # Create logical port alice1 in alice
8848 ovn-nbctl lsp-add alice alice1 \
8849 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8851 #install default route in R1 to use alice1's IP address as nexthop
8852 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8854 # Create two hypervisor and create OVS ports corresponding to logical ports.
8859 ovs-vsctl add-br br-phys
8860 ovn_attach n1 br-phys 192.168.0.1
8861 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8862 set interface hv1-vif1 external-ids:iface-id=foo1 \
8863 options:tx_pcap=hv1/vif1-tx.pcap \
8864 options:rxq_pcap=hv1/vif1-rx.pcap \
8869 ovs-vsctl add-br br-phys
8870 ovn_attach n1 br-phys 192.168.0.2
8871 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8872 set interface hv2-vif1 external-ids:iface-id=alice1 \
8873 options:tx_pcap=hv2/vif1-tx.pcap \
8874 options:rxq_pcap=hv2/vif1-rx.pcap \
8878 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8879 # packets for ARP resolution (native tunneling doesn't queue packets
8880 # for ARP resolution).
8883 # Allow some time for ovn-northd and ovn-controller to catch up.
8884 # XXX This should be more systematic.
8888 printf "%02x%02x%02x%02x" "$@"
8891 # Send ip packets between foo1 and alice1
8892 src_mac="f00000010203"
8893 dst_mac="000000010203"
8894 src_ip=`ip_to_hex 192 168 1 2`
8895 dst_ip=`ip_to_hex 10 0 0 2`
8896 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8898 # Send the first packet to trigger a ARP response and population of
8899 # mac_bindings table.
8900 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8901 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8902 ovn-nbctl --wait=hv sync
8904 # Packet to Expect at 'alice1'
8905 src_mac="000000010204"
8906 dst_mac="f00000010204"
8907 src_ip=`ip_to_hex 192 168 1 2`
8908 dst_ip=`ip_to_hex 10 0 0 2`
8909 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8911 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8913 OVN_CLEANUP([hv1],[hv2])
8917 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8918 AT_SKIP_IF([test $HAVE_PYTHON = no])
8921 ovn-nbctl ls-add ls1
8923 # Add localport to the switch
8924 ovn-nbctl lsp-add ls1 lp01
8925 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8926 ovn-nbctl lsp-set-type lp01 localport
8933 ovs-vsctl add-br br-phys
8934 ovn_attach n1 br-phys 192.168.0.$i
8935 ovs-vsctl add-port br-int vif01 -- \
8936 set Interface vif01 external-ids:iface-id=lp01 \
8937 options:tx_pcap=hv${i}/vif01-tx.pcap \
8938 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8939 ofport-request=${i}0
8941 ovs-vsctl add-port br-int vif${i}1 -- \
8942 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8943 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8944 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8945 ofport-request=${i}1
8947 ovn-nbctl lsp-add ls1 lp${i}1
8948 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8949 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8951 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8954 ovn-nbctl --wait=sb sync
8955 ovn-sbctl dump-flows
8959 # Given the name of a logical port, prints the name of the hypervisor
8960 # on which it is located.
8965 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8967 # This shell function causes a packet to be received on INPORT. The packet's
8968 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8969 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8970 # logical switch port numbers, e.g. 11 for vif11.
8972 # EOUT is the end-to-end output port, that is, where the packet will end up
8973 # after possibly bouncing through one or more localnet ports. LOUT is the
8974 # logical output port, which might be a localnet port, as seen by ovn-trace
8975 # (which doesn't know what localnet ports are connected to and therefore can't
8976 # figure out the end-to-end answer).
8978 # DEFHV is the default hypervisor from where the packet is going to be sent
8979 # if the source port is a localport.
8986 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8989 # First try tracing the packet.
8990 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8991 if test $lout != drop; then
8992 echo "output(\"$lout\");"
8994 AT_CAPTURE_FILE([trace])
8995 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8997 # Then actually send a packet, for an end-to-end test.
8998 local packet=$(echo $dst$src | sed 's/://g')${eth}
8999 hv=`vif_to_hv $inport`
9000 # If hypervisor 0 (localport) use the defhv parameter
9001 if test $hv = hv0; then
9005 as $hv ovs-appctl netdev-dummy/receive $vif $packet
9006 if test $eout != drop; then
9007 echo $packet >> ${eout#lp}.expected
9012 # lp11 and lp21 are on different hypervisors
9013 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
9014 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
9016 # Both VIFs should be able to reach the localport on their own HV
9017 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
9018 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
9020 # Packet sent from localport on same hv should reach the vif
9021 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
9022 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
9024 # Packet sent from localport on different hv should be dropped
9025 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
9026 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
9028 # Now check the packets actually received against the ones expected.
9031 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
9035 OVN_CLEANUP([hv1],[hv2])
9039 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
9040 AT_SKIP_IF([test $HAVE_PYTHON = no])
9045 # create gateways with external network connectivity
9050 ovs-vsctl add-br br-phys
9051 ovn_attach n1 br-phys 192.168.0.$i
9052 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9055 ovn-nbctl ls-add inside
9056 ovn-nbctl ls-add outside
9058 # create hypervisors with a vif port each to an internal network
9063 ovs-vsctl add-br br-phys
9064 ovn_attach n1 br-phys 192.168.0.1$i
9065 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9066 set interface hv$i-vif1 external-ids:iface-id=inside$i \
9067 options:tx_pcap=hv$i/vif1-tx.pcap \
9068 options:rxq_pcap=hv$i/vif1-rx.pcap \
9071 ovn-nbctl lsp-add inside inside$i \
9072 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
9078 ovn-nbctl create Logical_Router name=R1
9080 # Connect inside to R1
9081 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9082 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9083 type=router options:router-port=inside \
9084 -- lsp-set-addresses rp-inside router
9086 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9087 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9089 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9090 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9091 --id=@gc1 create Gateway_Chassis \
9092 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9093 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9095 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9096 type=router options:router-port=outside \
9097 -- lsp-set-addresses rp-outside router
9099 # Create localnet port in outside
9100 ovn-nbctl lsp-add outside ln-outside
9101 ovn-nbctl lsp-set-addresses ln-outside unknown
9102 ovn-nbctl lsp-set-type ln-outside localnet
9103 ovn-nbctl lsp-set-options ln-outside network_name=phys
9105 # Allow some time for ovn-northd and ovn-controller to catch up.
9106 # XXX This should be more systematic.
9107 ovn-nbctl --wait=hv --timeout=3 sync
9109 echo "---------NB dump-----"
9111 echo "---------------------"
9112 ovn-nbctl list logical_router
9113 echo "---------------------"
9114 ovn-nbctl list logical_router_port
9115 echo "---------------------"
9117 echo "---------SB dump-----"
9118 ovn-sbctl list datapath_binding
9119 echo "---------------------"
9120 ovn-sbctl list port_binding
9121 echo "---------------------"
9122 ovn-sbctl dump-flows
9123 echo "---------------------"
9124 ovn-sbctl list chassis
9125 ovn-sbctl list encap
9126 echo "---------------------"
9127 echo "------ Gateway_Chassis dump (SBDB) -------"
9128 ovn-sbctl list Gateway_Chassis
9129 echo "------ Port_Binding chassisredirect -------"
9130 ovn-sbctl find Port_Binding type=chassisredirect
9131 echo "-------------------------------------------"
9133 for chassis in gw1 gw2 hv1 hv2; do
9135 echo "------ $chassis dump ----------"
9136 ovs-ofctl show br-int
9137 ovs-ofctl dump-flows br-int
9138 echo "--------------------------"
9140 function bfd_dump() {
9141 for chassis in gw1 gw2 hv1 hv2; do
9143 echo "------ $chassis dump (BFD)----"
9144 echo "BFD (from $chassis):"
9145 # dump BFD config and status to the other chassis
9146 for chassis2 in gw1 gw2 hv1 hv2; do
9147 if [[ "$chassis" != "$chassis2" ]]; then
9148 echo " -> $chassis2:"
9149 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
9152 echo "--------------------------"
9158 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9159 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9160 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9161 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9163 echo $hv1_gw1_ofport
9164 echo $hv1_gw2_ofport
9165 echo $hv2_gw1_ofport
9166 echo $hv2_gw2_ofport
9169 as hv1 ovs-ofctl dump-flows br-int table=32
9172 as hv2 ovs-ofctl dump-flows br-int table=32
9174 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
9175 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9177 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
9180 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
9183 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9185 # make sure that flows for handling the outside router port reside on gw1
9186 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
9188 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
9191 # make sure ARP responder flows for outside router port reside on gw1 too
9192 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
9194 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
9199 # check that the chassis redirect port has been claimed by the gw1 chassis
9200 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9205 # at this point, we invert the priority of the gw chassis between gw1 and gw2
9207 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9208 name=outside_gw1 chassis_name=gw1 priority=10 -- \
9209 --id=@gc1 create Gateway_Chassis \
9210 name=outside_gw2 chassis_name=gw2 priority=20 -- \
9211 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9214 # XXX: Let the change propagate down to the ovn-controllers
9215 ovn-nbctl --wait=hv --timeout=3 sync
9217 # we make sure that the hypervisors noticed, and inverted the slave ports
9218 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
9221 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
9224 # check that the chassis redirect port has been reclaimed by the gw2 chassis
9225 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
9229 # check BFD enablement on tunnel ports from gw1 #########
9231 for chassis in gw2 hv1 hv2; do
9232 echo "checking gw1 -> $chassis"
9233 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9239 # check BFD enablement on tunnel ports from gw2 ##########
9241 for chassis in gw1 hv1 hv2; do
9242 echo "checking gw2 -> $chassis"
9243 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9248 # check BFD enablement on tunnel ports from hv1 ###########
9250 for chassis in gw1 gw2; do
9251 echo "checking hv1 -> $chassis"
9252 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9256 # make sure BFD is not enabled to hv2, we don't need it
9257 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
9262 # check BFD enablement on tunnel ports from hv2 ##########
9264 for chassis in gw1 gw2; do
9265 echo "checking hv2 -> $chassis"
9266 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9270 # make sure BFD is not enabled to hv1, we don't need it
9271 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
9275 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9277 # make sure that flows for handling the outside router port reside on gw2 now
9278 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
9280 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
9283 # disconnect GW2 from the network, GW1 should take over
9285 port=${sandbox}_br-phys
9286 as main ovs-vsctl del-port n1 $port
9291 # make sure that flows for handling the outside router port reside on gw2 now
9292 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
9294 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
9297 # check that the chassis redirect port has been reclaimed by the gw1 chassis
9298 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9302 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
9304 for chassis in gw1 hv1 hv2; do
9305 echo "checking gw2 -> $chassis"
9307 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9308 test "$bfd_cfg" = "enable=true min_rx=2000"
9311 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
9312 for chassis in gw1 hv1 hv2; do
9313 echo "checking gw2 -> $chassis"
9315 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9316 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
9319 ovn-nbctl remove NB_Global . options "bfd-min-rx"
9320 ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
9321 for chassis in gw1 hv1 hv2; do
9322 echo "checking gw2 -> $chassis"
9324 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
9325 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
9329 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9333 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9334 AT_SKIP_IF([test $HAVE_PYTHON = no])
9336 ovn-nbctl ls-add ls0
9337 ovn-nbctl ls-add ls1
9338 ovn-nbctl create Logical_Router name=lr0
9339 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9341 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9342 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9343 --id=@gc1 create Gateway_Chassis \
9344 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9345 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9347 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9348 type=router options:router-port=lrp0 addresses="router"
9349 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9350 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9351 type=router options:router-port=lrp1 addresses="router"
9354 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9359 ovs-vsctl add-br br-phys
9360 ovn_attach n1 br-phys 192.168.0.1
9361 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9362 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])
9366 ovs-vsctl add-br br-phys
9367 ovn_attach n1 br-phys 192.168.0.2
9368 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9372 ovs-vsctl add-br br-phys
9373 ovn_attach n1 br-phys 192.168.0.3
9374 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9376 # Create a localnet port.
9377 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9378 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9379 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9380 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9382 # wait for earlier changes to take effect
9383 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
9388 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9389 options:rxq_pcap=dummy-rx.pcap
9390 rm -f ${pcap_file}*.pcap
9391 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9392 options:rxq_pcap=${pcap_file}-rx.pcap
9395 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9396 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9397 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9398 # add nat-addresses option
9399 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9401 # Wait for packets to be received through hv2.
9402 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9404 sed 's/\(00\)\{1,\}$//'
9407 only_broadcast_from_lrp1() {
9408 grep "fffffffffffff00000000001"
9411 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
9414 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
9415 echo "packets on hv1-snoopvif:"
9417 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
9418 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9419 echo "packets on hv2 br-phys tx"
9421 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
9422 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9423 echo "packets on hv3 br-phys tx"
9425 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9428 # at this point, we invert the priority of the gw chassis between hv2 and hv3
9430 ovn-nbctl --wait=hv \
9431 --id=@gc0 create Gateway_Chassis \
9432 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9433 --id=@gc1 create Gateway_Chassis \
9434 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9435 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9438 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9439 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9440 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9442 # Wait for packets to be received.
9443 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9445 sed 's/\(00\)\{1,\}$//'
9448 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9449 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9450 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9451 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9452 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9453 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9455 # change localnet port tag.
9456 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9458 # wait for earlier changes to take effect
9459 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
9461 # update nat-addresses option
9462 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9463 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9465 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9466 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9467 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9469 # Wait for packets to be received.
9470 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9472 sed 's/\(00\)\{1,\}$//'
9475 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9478 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9479 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9480 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9481 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9482 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9483 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9485 OVN_CLEANUP([hv1],[hv2],[hv3])
9489 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9490 AT_SKIP_IF([test $HAVE_PYTHON = no])
9495 # create two gateways with external network connectivity
9499 ovs-vsctl add-br br-phys
9500 ovn_attach n1 br-phys 192.168.0.$i
9501 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9504 ovn-nbctl ls-add inside
9505 ovn-nbctl ls-add outside
9507 # create one hypervisors with a vif port the internal network
9510 ovs-vsctl add-br br-phys
9511 ovn_attach n1 br-phys 192.168.0.11
9512 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9513 set interface hv1-vif1 external-ids:iface-id=inside1 \
9514 options:tx_pcap=hv1/vif1-tx.pcap \
9515 options:rxq_pcap=hv1/vif1-rx.pcap \
9518 ovn-nbctl lsp-add inside inside1 \
9519 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9524 ovn-nbctl create Logical_Router name=R1
9526 # Connect inside to R1
9527 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9528 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9529 type=router options:router-port=inside \
9530 -- lsp-set-addresses rp-inside router
9532 # Connect outside to R1 as distributed router gateway port on gw1+gw2
9533 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9535 ovn-nbctl --id=@gc0 create Gateway_Chassis \
9536 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9537 --id=@gc1 create Gateway_Chassis \
9538 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9539 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9541 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9542 type=router options:router-port=outside \
9543 -- lsp-set-addresses rp-outside router
9545 # Create localnet port in outside
9546 ovn-nbctl lsp-add outside ln-outside
9547 ovn-nbctl lsp-set-addresses ln-outside unknown
9548 ovn-nbctl lsp-set-type ln-outside localnet
9549 ovn-nbctl lsp-set-options ln-outside network_name=phys
9551 # Allow some time for ovn-northd and ovn-controller to catch up.
9552 ovn-nbctl --wait=hv --timeout=3 sync
9554 # currently when ovn-controller is restarted, the old entry is deleted
9555 # and a new one is created, which leaves the Gateway_Chassis with
9556 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
9557 # doesn't have the same effect because "name" is conserved, and the
9558 # Chassis entry is not replaced.
9560 > gw1/ovn-controller.log
9562 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9563 ovn-sbctl destroy Chassis $gw2_chassis
9565 # Ensure ovn-controller has processed latest sbdb update
9566 # ovn-nbctl --wait=hv sync
9568 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9570 OVN_CLEANUP([gw1],[gw2],[hv1])
9574 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9575 AT_KEYWORDS([ovn-nd_ns for unknown mac])
9576 AT_SKIP_IF([test $HAVE_PYTHON = no])
9579 ovn-nbctl ls-add sw0_ip6
9580 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9581 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9582 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9584 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9585 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9587 ovn-nbctl lr-add lr0_ip6
9588 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
9589 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9590 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9591 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
9592 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9593 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9595 ovn-nbctl ls-add public
9596 ovn-nbctl lsp-add public ln-public
9597 ovn-nbctl lsp-set-addresses ln-public unknown
9598 ovn-nbctl lsp-set-type ln-public localnet
9599 ovn-nbctl lsp-set-options ln-public network_name=phys
9601 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
9602 2001:db8:1:0:200:02ff:fe01:0204/64 \
9603 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9606 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9607 rp-ip6_public type=router options:router-port=ip6_public \
9608 -- lsp-set-addresses rp-ip6_public router
9613 ovs-vsctl add-br br-phys
9614 ovn_attach n1 br-phys 192.168.0.2
9616 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9617 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9618 options:tx_pcap=hv1/vif1-tx.pcap \
9619 options:rxq_pcap=hv1/vif1-rx.pcap \
9621 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9623 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9625 # There should be 2 Neighbor Advertisement flows for the router port
9626 # aef0:: ip address in logical switch pipeline with action nd_na_router.
9627 AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
9628 grep "nd_na_router" | wc -l], [0], [2
9631 # There should be 4 Neighbor Advertisement flows with action nd_na_router
9632 # in the router pipeline for the router lr0_ip6.
9633 AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
9637 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9639 # There is only one chassis.
9640 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9641 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
9644 sed 's/\(00\)\{1,\}$//'
9647 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9648 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
9649 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9650 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9651 # This function sends ipv6 packet
9653 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9654 dst_ip=20010db800010000020002fffe010205
9656 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9657 packet=${packet}8000000000000000
9658 shift; shift; shift; shift
9660 dst_mac=3333ff010205
9661 src_mac=000002010204
9662 mcast_node_ip=ff0200000000000000000001ff010205
9663 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9664 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9665 expected_packet=${expected_packet}0101${src_mac}
9667 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9668 echo $expected_packet >> ipv6_ns.expected
9671 src_mac=506400000002
9672 dst_mac=00000000af01
9673 src_ip=aef0000000000000526400fffe000002
9674 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9675 # should be received by the ports attached to br-phys.
9676 test_ipv6 1 $src_mac $dst_mac $src_ip 2
9678 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9679 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9681 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9682 trim_zeros > 1.packets
9683 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9684 trim_zeros > 2.packets
9686 cat ipv6_ns.expected | cut -c -112 > expout
9687 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9688 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9690 # Skipping the ICMPv6 checksum
9691 cat ipv6_ns.expected | cut -c 117- > expout
9692 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9693 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9699 AT_SETUP([ovn -- options:requested-chassis for logical port])
9704 ovn-nbctl ls-add ls0
9705 ovn-nbctl lsp-add ls0 lsp0
9707 # create two hypervisors, each with one vif port
9710 ovs-vsctl add-br br-phys
9711 ovn_attach n1 br-phys 192.168.0.11
9712 ovs-vsctl -- add-port br-int hv1-vif0 -- \
9713 set Interface hv1-vif0 ofport-request=1
9717 ovs-vsctl add-br br-phys
9718 ovn_attach n1 br-phys 192.168.0.12
9719 ovs-vsctl -- add-port br-int hv2-vif0 -- \
9720 set Interface hv2-vif0 ofport-request=1
9722 # Allow only chassis hv1 to bind logical port lsp0.
9723 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9725 # Allow some time for ovn-northd and ovn-controller to catch up.
9726 ovn-nbctl --wait=hv --timeout=3 sync
9728 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9729 ovn-sbctl wait-until chassis hv1
9730 ovn-sbctl wait-until chassis hv2
9731 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9732 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9734 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9735 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9737 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9739 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9740 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9742 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9743 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9744 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9746 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9747 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9749 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9751 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9752 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9754 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9755 as hv1 ovs-ofctl dump-flows br-int
9756 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9757 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9759 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9760 # the requested chassis for lsp0 is changed from hv1 to hv2.
9761 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9763 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9764 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9765 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
9767 # (6) Chassis hv2 should add flows and hv1 should not.
9768 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9769 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9771 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9772 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9774 OVN_CLEANUP([hv1],[hv2])
9778 AT_SETUP([ovn -- options:requested-chassis with hostname])
9782 ovn-nbctl ls-add ls0
9783 ovn-nbctl lsp-add ls0 lsp0
9788 ovs-vsctl add-br br-phys
9789 ovn_attach n1 br-phys 192.168.0.11
9790 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
9792 ovn-sbctl wait-until chassis hv1
9793 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9794 echo "hv1_hostname=${hv1_hostname}"
9795 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9796 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9798 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9799 echo "hv1_uuid=${hv1_uuid}"
9800 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9801 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9802 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9803 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9805 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9806 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9807 ovn-nbctl --wait=hv --timeout=3 sync
9808 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9809 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9810 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9816 AT_SETUP([ovn -- IPv6 periodic RA])
9819 # This test sets up two hypervisors.
9820 # hv1 and hv2 run ovn-controllers, and
9821 # each has a VIF connected to the same
9822 # logical switch in OVN. The logical
9823 # switch is connected to a logical
9824 # router port that is configured to send
9825 # periodic router advertisements.
9827 # The reason for having two ovn-controller
9828 # hypervisors is to ensure that the
9829 # periodic RAs being sent by each ovn-controller
9830 # are kept to their local hypervisors. If the
9831 # packets are not kept local, then each port
9832 # will receive too many RAs.
9838 ovs-vsctl add-br br-phys
9839 ovn_attach n1 br-phys 192.168.0.2
9841 ovs-vsctl add-br br-phys
9842 ovn_attach n1 br-phys 192.168.0.3
9845 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
9848 ovn-nbctl lsp-add sw sw-ro
9849 ovn-nbctl lsp-set-type sw-ro router
9850 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9851 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9852 ovn-nbctl lsp-add sw sw-p1
9853 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9854 ovn-nbctl lsp-add sw sw-p2
9855 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9857 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9858 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9859 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9860 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9864 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9865 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9866 options:tx_pcap=hv$i/vif1-tx.pcap \
9867 options:rxq_pcap=hv$i/vif1-rx.pcap \
9871 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9872 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
9877 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9878 options:rxq_pcap=dummy-rx.pcap
9879 rm -f ${pcap_file}*.pcap
9880 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9881 options:rxq_pcap=${pcap_file}-rx.pcap
9885 construct_expected_ra() {
9886 local src_mac=000000000001
9887 local dst_mac=333300000001
9888 local src_addr=fe80000000000000020000fffe000001
9889 local dst_addr=ff020000000000000000000000000001
9893 local ra_prefix_la=$3
9895 local slla=0101${src_mac}
9897 if test $mtu != 0; then
9898 mtu_opt=05010000${mtu}
9903 while [[ $# -gt 0 ]] ; do
9906 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9910 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
9911 local icmp=8600XXXX${ra}
9913 local ip_len=$(expr ${#icmp} / 2)
9914 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
9916 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9917 local eth=${dst_mac}${src_mac}86dd${ip}
9919 echo $packet >> expected
9923 construct_expected_ra $@
9925 for i in hv1 hv2 ; do
9926 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9928 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9930 cat expected | cut -c -112 > expout
9931 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9933 # Skip ICMPv6 checksum.
9934 cat expected | cut -c 117- > expout
9935 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9938 as $i reset_pcap_file $i-vif1 $i/vif1
9944 # Baseline test with no MTU
9945 ra_test 0 00 c0 40 aef00000000000000000000000000000
9947 # Now make sure an MTU option makes it
9948 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9949 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9951 # Now test for multiple network prefixes
9952 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9953 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9955 # Test a different address mode now
9956 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9957 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9959 # And the other address mode
9960 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9961 ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9963 OVN_CLEANUP([hv1],[hv2])
9966 AT_SETUP([ovn -- ACL reject rule test])
9967 AT_KEYWORDS([acl-reject])
9968 AT_SKIP_IF([test $HAVE_PYTHON = no])
9971 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9973 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9974 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9975 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9976 # unreachable frame generated from ACL rule hit
9978 # INPORT is a lport number, e.g. 11 for vif11.
9979 # HV is a hypervisor number
9980 # ETH_SRC and ETH_DST are each 12 hex digits.
9981 # IPV4_SRC and IPV4_DST are each 8 hex digits.
9982 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9984 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9985 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9989 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9991 local reply_icmp_ttl=ff
9992 local icmp_type_code_response=0301
9993 local icmp_data=00000000
9994 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9995 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9996 echo $reply >> vif$inport.expected
9998 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10001 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
10003 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
10004 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
10005 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
10006 test_ipv6_packet() {
10007 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
10010 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
10011 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
10013 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
10014 echo $reply >> vif$inport.expected
10016 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10019 # 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
10021 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10022 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10023 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
10025 # INPORT is an lport number, e.g. 11 for vif11.
10026 # HV is an hypervisor number
10027 # ETH_SRC and ETH_DST are each 12 hex digits.
10028 # IPV4_SRC and IPV4_DST are each 8 hex digits.
10029 # TCP_SPORT and TCP_DPORT are 4 hex digits.
10030 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10031 test_tcp_syn_packet() {
10032 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
10033 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10034 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10038 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10040 local tcp_rst_ttl=ff
10041 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
10042 echo $reply >> vif$inport.expected
10044 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10047 # Create hypervisors hv[123].
10048 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
10049 # Add all of the vifs to a single logical switch sw0.
10052 ovn-nbctl ls-add sw0
10056 ovs-vsctl add-br br-phys
10057 ovn_attach n1 br-phys 192.168.0.$i
10060 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
10061 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
10063 ovs-vsctl -- add-port br-int vif$i$j -- \
10064 set interface vif$i$j \
10065 external-ids:iface-id=sw0-p$i$j \
10066 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
10067 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
10068 ofport-request=$i$j
10073 # allow some time for ovn-northd and ovn-controller to catch up.
10077 printf "%02x%02x%02x%02x" "$@"
10081 : > vif${i}1.expected
10084 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
10085 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
10086 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
10088 # Allow some time for ovn-northd and ovn-controller to catch up.
10089 ovn-nbctl --timeout=3 --wait=hv sync
10091 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
10092 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
10093 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
10095 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
10097 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
10098 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
10099 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
10102 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
10105 OVN_CLEANUP([hv1], [hv2], [hv3])
10108 AT_SETUP([ovn -- Port Groups])
10109 AT_KEYWORDS([ovnpg])
10110 AT_SKIP_IF([test $HAVE_PYTHON = no])
10115 # Three logical switches ls1, ls2, ls3.
10116 # One logical router lr0 connected to ls[123],
10117 # with nine subnets, three per logical switch:
10119 # lrp11 on ls1 for subnet 192.168.11.0/24
10120 # lrp12 on ls1 for subnet 192.168.12.0/24
10121 # lrp13 on ls1 for subnet 192.168.13.0/24
10123 # lrp33 on ls3 for subnet 192.168.33.0/24
10125 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10126 # digits are the subnet and the last digit distinguishes the VIF.
10128 # This test will create two port groups and uses them in ACL.
10131 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10137 ovn-nbctl ls-add ls$i
10141 -- lsp-add ls$i lp$i$j$k \
10142 -- lsp-set-addresses lp$i$j$k \
10143 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
10144 # logical ports lp[12]?1 belongs to port group pg1
10145 if test $i != 3 && test $k == 1; then
10146 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10148 # logical ports lp[23]?2 belongs to port group pg2
10149 if test $i != 1 && test $k == 2; then
10150 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10156 ovn-nbctl lr-add lr0
10159 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10161 -- lsp-add ls$i lrp$i$j-attachment \
10162 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10163 options:router-port=lrp$i$j \
10164 addresses='"00:00:00:00:ff:'$i$j'"'
10168 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10169 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10171 # create ACLs on all lswitches to drop traffic from pg2 to pg1
10172 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10173 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10174 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10176 # Physical network:
10178 # Three hypervisors hv[123].
10179 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10180 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10181 # lp?3[123] all on hv3.
10183 # Given the name of a logical port, prints the name of the hypervisor
10184 # on which it is located.
10187 ?11) echo 1 ;; dnl (
10188 ?12 | ?21 | ?22) echo 2 ;; dnl (
10189 ?13 | ?23 | ?3?) echo 3 ;;
10193 # Given the name of a logical port, prints the name of its logical router
10194 # port, e.g. "vif_to_lrp 123" yields 12.
10199 # Given the name of a logical port, prints the name of its logical
10200 # switch, e.g. "vif_to_ls 123" yields 1.
10209 ovs-vsctl add-br br-phys
10210 ovn_attach n1 br-phys 192.168.0.$i
10215 hv=`vif_to_hv $i$j$k`
10216 as hv$hv ovs-vsctl \
10217 -- add-port br-int vif$i$j$k \
10218 -- set Interface vif$i$j$k \
10219 external-ids:iface-id=lp$i$j$k \
10220 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10221 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10222 ofport-request=$i$j$k
10227 # Pre-populate the hypervisors' ARP tables so that we don't lose any
10228 # packets for ARP resolution (native tunneling doesn't queue packets
10229 # for ARP resolution).
10232 # Allow some time for ovn-northd and ovn-controller to catch up.
10233 # XXX This should be more systematic.
10236 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10238 # This shell function causes a packet to be received on INPORT. The packet's
10239 # content has Ethernet destination DST and source SRC (each exactly 12 hex
10240 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10241 # more) list the VIFs on which the packet should be received. INPORT and the
10242 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10246 : > $i$j$k.expected
10251 # This packet has bad checksums but logical L3 routing doesn't check.
10252 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10253 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10254 shift; shift; shift; shift; shift
10255 hv=hv`vif_to_hv $inport`
10256 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10257 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10258 in_ls=`vif_to_ls $inport`
10259 in_lrp=`vif_to_lrp $inport`
10261 out_ls=`vif_to_ls $outport`
10262 if test $in_ls = $out_ls; then
10263 # Ports on the same logical switch receive exactly the same packet.
10266 # Routing decrements TTL and updates source and dest MAC
10268 out_lrp=`vif_to_lrp $outport`
10269 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10270 fi >> $outport.expected
10274 as hv1 ovs-vsctl --columns=name,ofport list interface
10275 as hv1 ovn-sbctl list port_binding
10276 as hv1 ovn-sbctl list datapath_binding
10277 as hv1 ovn-sbctl list port_group
10278 as hv1 ovn-sbctl list address_set
10279 as hv1 ovn-sbctl dump-flows
10280 as hv1 ovs-ofctl dump-flows br-int
10282 # Send IP packets between all pairs of source and destination ports,
10283 # packets matches ACL (pg2 to pg1) should be dropped
10285 printf "%02x%02x%02x%02x" "$@"
10287 for is in 1 2 3; do
10288 for js in 1 2 3; do
10289 for ks in 1 2 3; do
10293 sip=`ip_to_hex 192 168 $is$js $ks`
10294 for id in 1 2 3; do
10295 for jd in 1 2 3; do
10296 for kd in 1 2 3; do
10298 dip=`ip_to_hex 192 168 $id$jd $kd`
10299 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10300 if test $d != $s; then unicast=$d; else unicast=; fi
10302 # packets matches ACL should be dropped
10303 if test $id != 3 && test $kd == 1; then
10304 if test $is != 1 && test $ks == 2; then
10308 test_ip $s $smac $dmac $sip $dip $unicast #1
10316 # Allow some time for packet forwarding.
10317 # XXX This can be improved.
10320 # Now check the packets actually received against the ones expected.
10324 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10330 # Gracefully terminate daemons
10331 OVN_CLEANUP([hv1], [hv2], [hv3])
10334 AT_SETUP([ovn -- ACLs on Port Groups])
10335 AT_KEYWORDS([ovnpg_acl])
10336 AT_SKIP_IF([test $HAVE_PYTHON = no])
10341 # Three logical switches ls1, ls2, ls3.
10342 # One logical router lr0 connected to ls[123],
10343 # with nine subnets, three per logical switch:
10345 # lrp11 on ls1 for subnet 192.168.11.0/24
10346 # lrp12 on ls1 for subnet 192.168.12.0/24
10347 # lrp13 on ls1 for subnet 192.168.13.0/24
10349 # lrp33 on ls3 for subnet 192.168.33.0/24
10351 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10352 # digits are the subnet and the last digit distinguishes the VIF.
10354 # This test will create two port groups and ACLs will be applied on them.
10357 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10363 ovn-nbctl ls-add ls$i
10367 -- lsp-add ls$i lp$i$j$k \
10368 -- lsp-set-addresses lp$i$j$k \
10369 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
10370 # logical ports lp[12]?1 belongs to port group pg1
10371 if test $i != 3 && test $k == 1; then
10372 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10374 # logical ports lp[23]?2 belongs to port group pg2
10375 if test $i != 1 && test $k == 2; then
10376 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10382 ovn-nbctl lr-add lr0
10385 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10387 -- lsp-add ls$i lrp$i$j-attachment \
10388 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10389 options:router-port=lrp$i$j \
10390 addresses='"00:00:00:00:ff:'$i$j'"'
10394 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10395 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10397 # create ACLs on pg1 to drop traffic from pg2 to pg1
10398 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10399 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
10400 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
10402 # Physical network:
10404 # Three hypervisors hv[123].
10405 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10406 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10407 # lp?3[123] all on hv3.
10409 # Given the name of a logical port, prints the name of the hypervisor
10410 # on which it is located.
10413 ?11) echo 1 ;; dnl (
10414 ?12 | ?21 | ?22) echo 2 ;; dnl (
10415 ?13 | ?23 | ?3?) echo 3 ;;
10419 # Given the name of a logical port, prints the name of its logical router
10420 # port, e.g. "vif_to_lrp 123" yields 12.
10425 # Given the name of a logical port, prints the name of its logical
10426 # switch, e.g. "vif_to_ls 123" yields 1.
10435 ovs-vsctl add-br br-phys
10436 ovn_attach n1 br-phys 192.168.0.$i
10441 hv=`vif_to_hv $i$j$k`
10442 as hv$hv ovs-vsctl \
10443 -- add-port br-int vif$i$j$k \
10444 -- set Interface vif$i$j$k \
10445 external-ids:iface-id=lp$i$j$k \
10446 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10447 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10448 ofport-request=$i$j$k
10453 # Pre-populate the hypervisors' ARP tables so that we don't lose any
10454 # packets for ARP resolution (native tunneling doesn't queue packets
10455 # for ARP resolution).
10458 # Allow some time for ovn-northd and ovn-controller to catch up.
10459 # XXX This should be more systematic.
10463 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10467 echo 00:00:00:00:ff:$1
10470 # test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
10472 # This shell function causes a ICMP packet to be received on INPORT.
10473 # The OUTPORTs (zero or more) list the VIFs on which the packet should
10474 # be received. INPORT and the OUTPORTs are specified as logical switch
10475 # port numbers, e.g. 123 for vif123.
10479 : > $i$j$k.expected
10485 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10486 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10487 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10488 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10490 shift; shift; shift; shift; shift; shift
10491 hv=hv`vif_to_hv $inport`
10492 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
10493 in_ls=`vif_to_ls $inport`
10494 in_lrp=`vif_to_lrp $inport`
10496 out_ls=`vif_to_ls $outport`
10497 if test $in_ls = $out_ls; then
10498 # Ports on the same logical switch receive exactly the same packet.
10499 echo $packet | ovstest test-ovn expr-to-packets
10501 # Routing decrements TTL and updates source and dest MAC
10503 out_lrp=`vif_to_lrp $outport`
10504 exp_smac=`lrp_to_mac $out_lrp`
10505 exp_dmac=`lsp_to_mac $outport`
10506 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10507 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10508 icmp4.type==$icmp_type && icmp4.code==0"
10509 echo $exp_packet | ovstest test-ovn expr-to-packets
10511 fi >> $outport.expected
10515 as hv1 ovs-vsctl --columns=name,ofport list interface
10516 as hv1 ovn-sbctl list port_binding
10517 as hv1 ovn-sbctl list datapath_binding
10518 as hv1 ovn-sbctl list port_group
10519 as hv1 ovn-sbctl list address_set
10520 as hv1 ovn-sbctl dump-flows
10521 as hv1 ovs-ofctl dump-flows br-int
10523 # Send IP packets between all pairs of source and destination ports,
10524 # packets matches ACL1 but not ACL2 should be dropped
10526 printf "%02x%02x%02x%02x" "$@"
10528 for is in 1 2 3; do
10529 for js in 1 2 3; do
10530 for ks in 1 2 3; do
10533 slsp_mac=`lsp_to_mac $s`
10534 slrp_mac=`lrp_to_mac $is$js`
10535 sip=192.168.$is$js.$ks
10536 for id in 1 2 3; do
10537 for jd in 1 2 3; do
10538 for kd in 1 2 3; do
10540 dlsp_mac=`lsp_to_mac $d`
10541 dlrp_mac=`lrp_to_mac $id$jd`
10542 dip=192.168.$id$jd.$kd
10543 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
10544 if test $d != $s; then unicast=$d; else unicast=; fi
10546 # packets matches ACL1 but not ACL2 should be dropped
10547 if test $id != 3 && test $kd == 1; then
10548 if test $is == 1 || test $ks != 2; then
10552 # icmp request (type = 8)
10553 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
10555 # if packets are not dropped, test the return traffic (icmp echo)
10556 # to make sure stateful works, too.
10557 if test x$unicast != x; then
10558 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
10559 # icmp echo (type = 0)
10560 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
10569 # Allow some time for packet forwarding.
10570 # XXX This can be improved.
10573 # Now check the packets actually received against the ones expected.
10577 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10583 # Gracefully terminate daemons
10584 OVN_CLEANUP([hv1], [hv2], [hv3])
10587 AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
10590 ovn-nbctl ls-add ls1
10592 ovn-nbctl lsp-add ls1 lp1
10593 ovn-nbctl lsp-add ls1 lp2
10594 ovn-nbctl lsp-add ls1 lp3
10596 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
10597 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
10598 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
10600 ovn-nbctl create Port_Group name=pg1
10601 ovn-nbctl create Port_Group name=pg2
10603 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10604 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10605 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10606 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10608 ovn-nbctl --wait=sb sync
10610 dnl Check if port group address sets were populated with ports' addresses
10611 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10612 [0], [[["10.0.0.1", "10.0.0.2"]]
10614 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10615 [0], [[["10.0.0.2", "10.0.0.3"]]
10617 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10618 [0], [[["2001:db8::1", "2001:db8::2"]]
10620 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10621 [0], [[["2001:db8::2", "2001:db8::3"]]
10624 ovn-nbctl --wait=sb lsp-set-addresses lp1 \
10625 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
10627 dnl Check if updated address got propagated to the port group address sets
10628 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10629 [0], [[["10.0.0.11", "10.0.0.2"]]
10631 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10632 [0], [[["2001:db8::11", "2001:db8::2"]]
10637 AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
10640 ovn-nbctl ls-add ls1
10641 ovn-nbctl ls-add ls2
10642 ovn-nbctl ls-add ls3
10644 ovn-nbctl set Logical_Switch ls1 \
10645 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
10646 ovn-nbctl set Logical_Switch ls2 \
10647 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
10648 ovn-nbctl set Logical_Switch ls3 \
10649 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
10651 ovn-nbctl lsp-add ls1 lp1
10652 ovn-nbctl lsp-add ls2 lp2
10653 ovn-nbctl lsp-add ls3 lp3
10655 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
10656 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
10657 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
10659 ovn-nbctl create Port_Group name=pg1
10660 ovn-nbctl create Port_Group name=pg2
10662 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10663 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10664 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10665 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10667 ovn-nbctl --wait=sb sync
10669 dnl Check if port group address sets were populated with ports' addresses
10670 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10671 [0], [[["10.1.0.2", "10.2.0.2"]]
10673 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10674 [0], [[["10.2.0.2", "10.3.0.2"]]
10676 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10677 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
10679 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10680 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
10683 ovn-nbctl set Logical_Switch ls1 \
10684 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
10686 dnl Check if updated address got propagated to the port group address sets
10687 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10688 [0], [[["10.11.0.2", "10.2.0.2"]]
10690 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10691 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
10696 AT_SETUP([ovn -- ACL conjunction])
10699 ovn-nbctl ls-add ls1
10701 ovn-nbctl lsp-add ls1 ls1-lp1 \
10702 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10704 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10706 ovn-nbctl lsp-add ls1 ls1-lp2 \
10707 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10709 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10715 ovs-vsctl add-br br-phys
10716 ovn_attach n1 br-phys 192.168.0.1
10717 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10718 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10719 options:tx_pcap=hv1/vif1-tx.pcap \
10720 options:rxq_pcap=hv1/vif1-rx.pcap \
10723 ovs-vsctl -- add-port br-int hv1-vif2 -- \
10724 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10725 options:tx_pcap=hv1/vif2-tx.pcap \
10726 options:rxq_pcap=hv1/vif2-rx.pcap \
10729 ovn-nbctl create Address_Set name=set1 \
10730 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10731 ovn-nbctl create Address_Set name=set2 \
10732 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10733 ovn-nbctl acl-add ls1 to-lport 1002 \
10734 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10735 ovn-nbctl acl-add ls1 to-lport 1001 \
10736 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10738 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10740 # This shell function causes an ip packet to be received on INPORT.
10741 # The packet's content has Ethernet destination DST and source SRC
10742 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10743 # The OUTPORTs (zero or more) list the VIFs on which the packet should
10744 # be received. INPORT and the OUTPORTs are specified as logical switch
10745 # port numbers, e.g. 11 for vif11.
10747 # This packet has bad checksums but logical L3 routing doesn't check.
10748 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10749 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10750 ${dst_ip}0035111100080000
10751 shift; shift; shift; shift; shift
10752 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10754 echo $packet >> $outport.expected
10759 printf "%02x%02x%02x%02x" "$@"
10762 reset_pcap_file() {
10765 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10766 options:rxq_pcap=dummy-rx.pcap
10767 rm -f ${pcap_file}*.pcap
10768 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10769 options:rxq_pcap=${pcap_file}-rx.pcap
10773 sip=`ip_to_hex 10 0 0 4`
10774 dip=`ip_to_hex 10 0 0 6`
10776 test_ip 1 f00000000001 f00000000002 $sip $dip 2
10778 cat 2.expected > expout
10779 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10780 AT_CHECK([cat 2.packets], [0], [expout])
10782 # There should be total of 12 flows present with conjunction action and 2 flows
10783 # with conj match. Eg.
10784 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10785 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10786 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10787 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10788 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10789 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10790 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10791 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10792 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10793 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10794 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10795 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10796 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10797 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10799 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10800 grep conjunction | wc -l`])
10801 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10802 grep conj_id | wc -l`])
10804 as hv1 ovs-ofctl dump-flows br-int
10806 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10807 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10808 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10810 reset_pcap_file hv1-vif2 hv1/vif2
10814 sip=`ip_to_hex 10 0 0 4`
10815 dip=`ip_to_hex 10 0 0 7`
10817 test_ip 1 f00000000001 f00000000002 $sip $dip
10818 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10819 AT_CHECK([cat 2.packets], [0], [])
10823 AT_SETUP([ovn -- TTL exceeded])
10824 AT_KEYWORDS([ttl-exceeded])
10825 AT_SKIP_IF([test $HAVE_PYTHON = no])
10828 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10830 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10831 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
10832 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
10833 # generated by OVN logical router
10835 # INPORT is a lport number, e.g. 11 for vif11.
10836 # HV is a hypervisor number
10837 # ETH_SRC and ETH_DST are each 12 hex digits.
10838 # IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
10839 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10841 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
10842 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
10846 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10848 local reply_icmp_ttl=fe
10849 local icmp_type_code_response=0b00
10850 local icmp_data=00000000
10851 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10852 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10853 echo $reply >> vif$inport.expected
10855 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10858 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
10860 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10861 # packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
10862 # IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
10863 # packet sent by OVN logical router
10864 test_ip6_packet() {
10865 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
10868 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
10869 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
10871 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
10872 echo $reply >> vif$inport.expected
10874 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10878 printf "%02x%02x%02x%02x" "$@"
10883 ovn-nbctl ls-add sw$i
10887 ovs-vsctl add-br br-phys
10888 ovn_attach n$i br-phys 192.168.$i.1
10890 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
10891 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
10893 ovs-vsctl -- add-port br-int vif$i -- \
10894 set interface vif$i \
10895 external-ids:iface-id=sw$i-p${i}0 \
10896 options:tx_pcap=hv$i/vif$i-tx.pcap \
10897 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10901 ovn-nbctl lr-add lr0
10903 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
10904 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10905 -- set Logical_Switch_Port lrp$i-attachment type=router \
10906 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
10910 # allow some time for ovn-northd and ovn-controller to catch up.
10911 ovn-nbctl --wait=hv sync
10913 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
10914 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
10915 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10917 OVN_CLEANUP([hv1], [hv2])
10920 AT_SETUP([ovn -- router port unreachable])
10921 AT_KEYWORDS([router-port-unreachable])
10922 AT_SKIP_IF([test $HAVE_PYTHON = no])
10925 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
10927 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10928 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
10929 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
10930 # EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
10932 # INPORT is a lport number, e.g. 11 for vif11.
10933 # HV is a hypervisor number
10934 # ETH_SRC and ETH_DST are each 12 hex digits.
10935 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10936 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10938 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
10939 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
10943 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
10945 local reply_icmp_ttl=fe
10946 local icmp_data=00000000
10947 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
10948 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10949 echo $reply >> vif$inport.expected
10951 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10954 # test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
10956 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10957 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10958 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
10960 # INPORT is an lport number, e.g. 11 for vif11.
10961 # HV is an hypervisor number
10962 # ETH_SRC and ETH_DST are each 12 hex digits.
10963 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10964 # TCP_SPORT and TCP_DPORT are 4 hex digits.
10965 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10966 test_tcp_syn_packet() {
10967 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
10968 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10969 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10973 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10975 local tcp_rst_ttl=fe
10976 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10977 echo $reply >> vif$inport.expected
10979 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10982 # test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
10984 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
10985 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
10986 # EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
10987 test_tcp6_packet() {
10988 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
10989 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
10990 local exp_tcp_rst_chksum=${10}
10993 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
10994 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10996 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10997 echo $reply >> vif$inport.expected
10999 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11002 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
11004 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
11005 # packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
11006 # EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
11007 test_ip6_packet() {
11008 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
11009 local exp_icmp_code=${10} exp_icmp_chksum=${11}
11012 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
11013 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
11015 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
11016 echo $reply >> vif$inport.expected
11018 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11022 printf "%02x%02x%02x%02x" "$@"
11027 ovn-nbctl ls-add sw$i
11031 ovs-vsctl add-br br-phys
11032 ovn_attach n$i br-phys 192.168.$i.1
11034 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
11035 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
11037 ovs-vsctl -- add-port br-int vif$i -- \
11038 set interface vif$i \
11039 external-ids:iface-id=sw$i-p${i}0 \
11040 options:tx_pcap=hv$i/vif$i-tx.pcap \
11041 options:rxq_pcap=hv$i/vif$i-rx.pcap \
11045 ovn-nbctl lr-add lr0
11047 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
11048 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
11049 -- set Logical_Switch_Port lrp$i-attachment type=router \
11050 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
11054 # allow some time for ovn-northd and ovn-controller to catch up.
11055 ovn-nbctl --wait=hv sync
11057 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
11058 test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
11059 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
11060 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11062 test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
11063 test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
11064 test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
11065 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
11067 OVN_CLEANUP([hv1], [hv2])
11070 AT_SETUP([ovn -- ovn-controller exit])
11071 AT_SKIP_IF([test $HAVE_PYTHON = no])
11074 # One Logical Router: ro, with two logical switches sw1 and sw2.
11075 # sw1 is for subnet 10.0.0.0/8
11076 # sw2 is for subnet 20.0.0.0/8
11077 # sw1 has a single port bound on hv1
11078 # sw2 has a single port bound on hv2
11080 ovn-nbctl lr-add ro
11081 ovn-nbctl ls-add sw1
11082 ovn-nbctl ls-add sw2
11084 sw1_ro_mac=00:00:10:00:00:01
11086 sw2_ro_mac=00:00:20:00:00:01
11088 sw1_p1_mac=00:00:10:00:00:02
11090 sw2_p1_mac=00:00:20:00:00:02
11093 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11094 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11095 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11096 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11097 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11098 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11100 ovn-nbctl lsp-add sw1 sw1-p1 \
11101 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11103 ovn-nbctl lsp-add sw2 sw2-p1 \
11104 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11110 ovs-vsctl add-br br-phys
11111 ovn_attach n1 br-phys 192.168.0.1
11112 ovs-vsctl -- add-port br-int hv1-vif1 -- \
11113 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11114 options:tx_pcap=hv1/vif1-tx.pcap \
11115 options:rxq_pcap=hv1/vif1-rx.pcap \
11120 ovs-vsctl add-br br-phys
11121 ovn_attach n1 br-phys 192.168.0.2
11122 ovs-vsctl -- add-port br-int hv2-vif1 -- \
11123 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11124 options:tx_pcap=hv2/vif1-tx.pcap \
11125 options:rxq_pcap=hv2/vif1-rx.pcap \
11132 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11133 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11134 udp && udp.src==53 && udp.dst==4369"
11136 # Start by Sending the packet and make sure it makes it there as expected
11137 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11139 # Expected packet has TTL decreased by 1
11140 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11141 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11142 udp && udp.src==53 && udp.dst==4369"
11143 echo $expected | ovstest test-ovn expr-to-packets > expected
11145 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11147 # Stop ovn-controller on hv2
11148 as hv2 ovs-appctl -t ovn-controller exit
11150 # Now send the packet again. This time, it should not arrive.
11151 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11153 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11155 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
11156 as hv2 start_daemon ovn-controller
11158 OVN_CLEANUP([hv1],[hv2])
11161 AT_SETUP([ovn -- ovn-controller restart])
11162 AT_SKIP_IF([test $HAVE_PYTHON = no])
11166 # One Logical Router: ro, with two logical switches sw1 and sw2.
11167 # sw1 is for subnet 10.0.0.0/8
11168 # sw2 is for subnet 20.0.0.0/8
11169 # sw1 has a single port bound on hv1
11170 # sw2 has a single port bound on hv2
11172 ovn-nbctl lr-add ro
11173 ovn-nbctl ls-add sw1
11174 ovn-nbctl ls-add sw2
11176 sw1_ro_mac=00:00:10:00:00:01
11178 sw2_ro_mac=00:00:20:00:00:01
11180 sw1_p1_mac=00:00:10:00:00:02
11182 sw2_p1_mac=00:00:20:00:00:02
11185 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11186 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11187 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11188 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11189 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11190 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11192 ovn-nbctl lsp-add sw1 sw1-p1 \
11193 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11195 ovn-nbctl lsp-add sw2 sw2-p1 \
11196 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11202 ovs-vsctl add-br br-phys
11203 ovn_attach n1 br-phys 192.168.0.1
11204 ovs-vsctl -- add-port br-int hv1-vif1 -- \
11205 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11206 options:tx_pcap=hv1/vif1-tx.pcap \
11207 options:rxq_pcap=hv1/vif1-rx.pcap \
11212 ovs-vsctl add-br br-phys
11213 ovn_attach n1 br-phys 192.168.0.2
11214 ovs-vsctl -- add-port br-int hv2-vif1 -- \
11215 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11216 options:tx_pcap=hv2/vif1-tx.pcap \
11217 options:rxq_pcap=hv2/vif1-rx.pcap \
11224 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11225 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11226 udp && udp.src==53 && udp.dst==4369"
11228 # Start by Sending the packet and make sure it makes it there as expected
11229 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11231 # Expected packet has TTL decreased by 1
11232 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11233 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11234 udp && udp.src==53 && udp.dst==4369"
11235 echo $expected | ovstest test-ovn expr-to-packets > expected
11237 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11239 # Stop ovn-controller on hv2 with --restart flag
11240 as hv2 ovs-appctl -t ovn-controller exit --restart
11242 # Now send the packet again. This time, it should still arrive
11243 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11245 cat expected expected > expected2
11247 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
11249 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
11250 as hv2 start_daemon ovn-controller
11252 OVN_CLEANUP([hv1],[hv2])
11256 AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
11259 # Set up a switch with some switch ports of varying address types
11260 ovn-nbctl ls-add sw1
11261 ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
11263 ovn-nbctl lsp-add sw1 sw1-p1
11264 ovn-nbctl lsp-add sw1 sw1-p2
11265 ovn-nbctl lsp-add sw1 sw1-p3
11266 ovn-nbctl lsp-add sw1 sw1-p4
11268 ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1" "00:00:00:00:00:02 10.0.0.2 aef0::2"
11269 ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
11270 ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
11271 ovn-nbctl lsp-set-addresses sw1-p4 "router"
11272 ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
11274 ovn-nbctl list logical_switch_port
11276 # Now try to add duplicate addresses on a new port. These should all fail
11277 ovn-nbctl lsp-add sw1 sw1-p5
11278 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
11279 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
11281 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
11282 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
11284 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
11285 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
11287 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
11288 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
11290 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
11291 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
11293 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
11294 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
11297 # Now try re-setting sw1-p1. This should succeed
11298 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
11300 # Now create a new switch and try setting IP addresses the same as the
11301 # first switch. This should succeed.
11302 ovn-nbctl ls-add sw2
11303 ovn-nbctl lsp-add sw2 sw2-p1
11305 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
11306 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
11307 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
11308 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
11312 AT_SETUP([ovn -- IP packet buffering])
11313 AT_KEYWORDS([ip-buffering])
11314 AT_SKIP_IF([test $HAVE_PYTHON = no])
11318 # One LR lr0 that has switches sw0 (192.168.1.0/24) and
11319 # sw1 (172.16.1.0/24) connected to it.
11321 # Physical network:
11322 # Tw0 hypervisors hv[12].
11323 # hv1 hosts vif sw0-p0.
11324 # hv1 hosts vif sw1-p0.
11326 send_icmp_packet() {
11327 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
11332 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
11333 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11336 send_icmp6_packet() {
11337 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
11340 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11341 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
11343 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
11347 local eth_src=$1 spa=$2 tpa=$3
11348 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
11353 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
11354 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
11355 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11359 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
11360 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11361 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
11363 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
11367 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
11368 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
11369 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
11378 ovs-vsctl add-br br-phys
11379 ovn_attach n1 br-phys 192.168.0.1
11380 ovs-vsctl -- add-port br-int hv1-vif1 -- \
11381 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
11382 options:tx_pcap=hv1/vif1-tx.pcap \
11383 options:rxq_pcap=hv1/vif1-rx.pcap \
11388 ovs-vsctl add-br br-phys
11389 ovn_attach n1 br-phys 192.168.0.2
11390 ovs-vsctl -- add-port br-int hv2-vif1 -- \
11391 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
11392 options:tx_pcap=hv2/vif1-tx.pcap \
11393 options:rxq_pcap=hv2/vif1-rx.pcap \
11396 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
11397 ovn-nbctl ls-add sw0
11398 ovn-nbctl ls-add sw1
11400 ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001::1/64
11401 ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
11402 type=router options:router-port=sw0 \
11403 -- lsp-set-addresses rp-sw0 router
11405 ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002::1/64
11406 ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
11407 type=router options:router-port=sw1 \
11408 -- lsp-set-addresses rp-sw1 router
11410 ovn-nbctl lsp-add sw0 sw0-p0 \
11411 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
11413 ovn-nbctl lsp-add sw1 sw1-p0 \
11414 -- lsp-set-addresses sw1-p0 unknown
11417 ovn-nbctl --wait=hv sync
11420 printf "%02x%02x%02x%02x" "$@"
11423 src_mac=f00000010203
11424 src_ip=$(ip_to_hex 192 168 1 2)
11425 src_ip6=20010000000000000000000000000002
11427 router_mac0=000001010203
11428 router_mac1=000002010203
11429 router_ip=$(ip_to_hex 172 16 1 1)
11430 router_ip6=20020000000000000000000000000001
11432 dst_mac=001122334455
11433 dst_ip=$(ip_to_hex 172 16 1 10)
11434 dst_ip6=20020000000000000000000000000010
11436 data=0800bee4391a0001
11438 send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
11439 send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
11440 echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
11441 echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
11443 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11445 nd_ip=ff0200000000000000000001ff000010
11446 ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
11448 send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
11449 echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
11450 echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
11451 send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
11453 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11455 OVN_CLEANUP([hv1],[hv2])