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_name="ovn.org",wpad="https://example.org",bootfile_name="https://127.0.0.1/boot.ipxe",path_prefix="/tftpboot");
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_name = "ovn.org", wpad = "https://example.org", bootfile_name = "https://127.0.0.1/boot.ipxe", path_prefix = "/tftpboot");
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.43.1b.68.74.74.70.73.3a.2f.2f.31.32.37.2e.30.2e.30.2e.31.2f.62.6f.6f.74.2e.69.70.78.65.d2.09.2f.74.66.74.70.62.6f.6f.74,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,tftp_server_address={10.0.0.4,10.0.0.5});
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, tftp_server_address = {10.0.0.4, 10.0.0.5});
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.96.08.0a.00.00.04.0a.00.00.05,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_name=1.2.3.4);
1129 DHCPv4 option domain_name 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 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.05.01.00.00.00.00.05.aa.03.04.40.80.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.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1265 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);
1266 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.05.01.00.00.00.00.05.aa.03.04.40.80.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.03.04.40.80.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.be.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10,pause)
1268 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", 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", slla = ae:01:02:03:04:10);
1271 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1272 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1273 Syntax error at `dhcpv6_stateless' expecting constant.
1274 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1275 Invalid value for "prefix" option
1276 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1277 Invalid value for "addr_mode" option
1278 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1279 IPv6 ND RA option mtu requires numeric value.
1280 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1281 Invalid value for "mtu" option
1284 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1285 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)
1289 formats as icmp4 { drop; };
1290 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1293 # icmp4 with icmp4.frag_mtu
1294 icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1295 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.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1299 icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1300 encodes as controller(userdata=00.00.00.0e.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)
1304 formats as icmp4_error { drop; };
1305 encodes as controller(userdata=00.00.00.0e.00.00.00.00)
1308 # icmp4_error with icmp4.frag_mtu
1309 icmp4_error { eth.dst = ff:ff:ff:ff:ff:ff; icmp4.frag_mtu = 1500; output; }; output;
1310 encodes as controller(userdata=00.00.00.0e.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.28.00.00.23.20.00.25.00.00.00.00.00.00.00.03.00.0e.00.00.00.0d.00.00.00.00.05.dc.00.00.00.04.00.04.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
1313 icmp4.frag_mtu = 1500;
1314 encodes as controller(userdata=00.00.00.0d.00.00.00.00.05.dc,pause)
1317 icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1318 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)
1322 formats as icmp6 { drop; };
1323 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1327 tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1328 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)
1332 formats as tcp_reset { drop; };
1333 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1336 # Contradictionary prerequisites (allowed but not useful):
1337 ip4.src = ip6.src[0..31];
1338 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1339 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1340 ip4.src <-> ip6.src[0..31];
1341 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[]
1342 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1345 reg0[0] = check_pkt_larger(1500);
1346 encodes as check_pkt_larger(1500)->NXM_NX_XXREG0[96]
1348 reg0 = check_pkt_larger(1500);
1349 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1351 reg0 = check_pkt_larger(foo);
1352 Cannot use 32-bit field reg0[0..31] where 1-bit field is required.
1354 reg0[0] = check_pkt_larger(foo);
1355 Syntax error at `foo' expecting `;'.
1357 # Miscellaneous negative tests.
1359 Syntax error at `;'.
1361 Syntax error at `xyzzy' expecting action.
1363 Syntax error at `123'.
1365 Syntax error at `xyzzy' expecting action.
1367 Syntax error at end of input expecting `;'.
1369 sed '/^[[ ]]/d' test-cases.txt > input.txt
1370 cp test-cases.txt expout
1371 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1374 AT_BANNER([OVN end-to-end tests])
1376 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1377 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1378 AT_KEYWORDS([ovnarp])
1379 AT_SKIP_IF([test $HAVE_PYTHON = no])
1382 # Create hypervisors hv[123].
1383 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1384 # Add all of the vifs to a single logical switch lsw0.
1385 # Turn on port security on all the vifs except vif[123]1.
1386 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1387 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1388 ovn-nbctl ls-add lsw0
1393 ovs-vsctl add-br br-phys
1394 ovn_attach n1 br-phys 192.168.0.$i
1397 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
1398 ovn-nbctl lsp-add lsw0 lp$i$j
1399 if test $j = 1; then
1400 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1402 if test $j = 3; then
1403 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1405 ip_addrs="192.168.0.$i$j"
1407 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1408 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1412 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1413 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1414 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1415 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\"
1416 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1419 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1422 ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1423 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1425 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1426 # packets for ARP resolution (native tunneling doesn't queue packets
1427 # for ARP resolution).
1430 # Allow some time for ovn-northd and ovn-controller to catch up.
1431 # XXX This should be more systematic.
1434 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1435 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1436 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1437 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1439 # Given the name of a logical port, prints the name of the hypervisor
1440 # on which it is located.
1445 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1447 # This shell function causes a packet to be received on INPORT. The packet's
1448 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1449 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1450 # more) list the VIFs on which the packet should be received. INPORT and the
1451 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1458 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1459 hv=`vif_to_hv $inport`
1461 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1463 echo $packet >> $outport.expected
1467 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1469 # Causes a packet to be received on INPORT. The packet is an ARP
1470 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1471 # it should be the hardware address of the target to expect to receive in an
1472 # ARP reply; otherwise no reply is expected.
1474 # INPORT is an logical switch port number, e.g. 11 for vif11.
1475 # SHA and REPLY_HA are each 12 hex digits.
1476 # SPA and TPA are each 8 hex digits.
1478 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1479 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1480 hv=`vif_to_hv $inport`
1481 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1483 if test X$reply_ha = X; then
1484 # Expect to receive the broadcast ARP on the other logical switch ports
1485 # if no reply is expected.
1489 if test $i$j != $inport; then
1490 echo $request >> $i$j.expected
1495 # Expect to receive the reply, if any.
1496 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1497 echo $reply >> $inport.expected
1502 printf "%02x%02x%02x%02x" "$@"
1505 # Send packets between all pairs of source and destination ports:
1507 # 1. Unicast packets are delivered to exactly one logical switch port
1508 # (except that packets destined to their input ports are dropped).
1510 # 2. Broadcast and multicast are delivered to all logical switch ports
1511 # except the input port.
1513 # 3. When port security is turned on, the switch drops packets from the wrong
1516 # 4. The switch drops all packets with a VLAN tag.
1518 # 5. The switch drops all packets with a multicast source address. (This only
1519 # affects behavior when port security is turned off, since otherwise port
1520 # security would drop the packet anyway.)
1522 # 6. The switch delivers packets with an unknown destination to logical
1523 # switch ports with "unknown" among their MAC addresses (and port
1524 # security disabled).
1526 # 7. The switch drops unicast packets that violate an ACL.
1528 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1530 # 9. OVN generates responses to ARP requests for known IPs, except for
1531 # requests from a port for the port's own IP.
1533 # 10. No response to ARP requests for unknown IPs.
1546 if test $d != $s; then unicast=$d; else unicast=; fi
1547 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1549 if test $d != $s && test $js = 1; then
1554 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1556 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1557 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1558 if test $d = $s || (test $js = 1 && test $d = 33); then
1559 # Source of 11, 21, or 31 and dest of 33 should be dropped
1560 # due to the 4th ACL that uses address_set(set1).
1565 if test $d = $s || test $d = 22 || test $d = 33; then
1566 # dest of 22 and 33 should be dropped
1567 # due to the 5th ACL that uses port_group(pg1).
1572 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1573 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1574 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1575 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1576 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
1578 test_packet $s f000000000$d f00000000055 810000091234 #4
1579 test_packet $s f000000000$d 0100000000$s $s$d #5
1581 if test $d != $s && test $jd = 1; then
1582 unknown="$unknown $d"
1584 bcast="$bcast $unicast"
1585 bacl2="$bacl2 $acl2"
1586 bacl3="$bacl3 $acl3"
1588 sip=`ip_to_hex 192 168 0 $is$js`
1589 tip=`ip_to_hex 192 168 0 $id$jd`
1590 tip_unknown=`ip_to_hex 11 11 11 11`
1591 if test $d != $s; then
1592 reply_ha=f000000000$d
1596 test_arp $s f000000000$s $sip $tip $reply_ha #9
1597 test_arp $s f000000000$s $sip $tip_unknown #10
1599 if test $jd = 3; then
1600 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1601 tip=`ip_to_hex 192 169 0 $id$jd`
1602 test_arp $s f000000000$s $sip $tip $reply_ha #9
1607 # Broadcast and multicast.
1608 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1609 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1610 if test $js = 1; then
1611 bcast_impersonate=$bcast
1615 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1617 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1619 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1620 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1621 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1622 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1623 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1624 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1628 # set address for lp13 with invalid characters.
1629 # lp13 should be configured with only 192.168.0.13.
1630 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1632 # Allow some time for ovn-northd and ovn-controller to catch up.
1633 # XXX This should be more systematic.
1636 sip=`ip_to_hex 192 168 0 11`
1637 tip=`ip_to_hex 192 168 0 13`
1638 test_arp 11 f00000000011 $sip $tip f00000000013
1640 tip=`ip_to_hex 192 169 0 13`
1641 #arp request for 192.169.0.13 should be flooded
1642 test_arp 11 f00000000011 $sip $tip
1644 # dump information and flows with counters
1645 ovn-sbctl dump-flows -- list multicast_group
1647 echo "------ hv1 dump ------"
1648 as hv1 ovs-vsctl show
1649 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1651 echo "------ hv2 dump ------"
1652 as hv2 ovs-vsctl show
1653 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1655 echo "------ hv3 dump ------"
1656 as hv3 ovs-vsctl show
1657 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1659 # Now check the packets actually received against the ones expected.
1662 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1666 OVN_CLEANUP([hv1],[hv2],[hv3])
1670 # 2 hypervisors, one logical switch, 2 logical ports per hypervisor
1671 # logical ports bound to chassis encap-ip.
1672 AT_SETUP([ovn -- 2 HVs, 1 LS, 2 lports/HV])
1673 AT_KEYWORDS([ovnarp])
1674 AT_SKIP_IF([test $HAVE_PYTHON = no])
1677 # Create hypervisors hv[12].
1678 # Add vif1[12] to hv1, vif2[12] to hv2
1679 ovn-nbctl ls-add lsw0
1684 ovs-vsctl add-br br-phys
1685 ovn_attach n1 br-phys 192.168.0.$i
1688 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
1689 ovn-nbctl lsp-add lsw0 lp$i$j
1690 ip_addrs="192.168.0.$i$j"
1691 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1692 ovn-nbctl --wait=hv lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1697 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1700 # XXX-Check how to pass lp$i1 in AT_CHECK_UNQUOTED, for now just do it
1704 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1707 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1712 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1715 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1719 # Bind the ports to the encap-ip
1723 ovs-vsctl set Interface vif$i$j external-ids:encap-ip=192.168.0.$i
1729 # dump port bindings; since we have vxlan and geneve tunnels, we expect the
1730 # ports to be bound to geneve tunnels.
1733 encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv1 type=geneve ip=192.168.0.1`
1735 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp11], [0], [dnl
1736 encap : ${encap_rec}
1739 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp12], [0], [dnl
1740 encap : ${encap_rec}
1744 encap_rec=`ovn-sbctl --data=bare --no-heading --column _uuid find encap chassis_name=hv2 type=geneve ip=192.168.0.2`
1746 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp21], [0], [dnl
1747 encap : ${encap_rec}
1750 AT_CHECK_UNQUOTED([ovn-sbctl --column encap list port_binding lp22], [0], [dnl
1751 encap : ${encap_rec}
1754 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1755 # packets for ARP resolution (native tunneling doesn't queue packets
1756 # for ARP resolution).
1759 # Allow some time for ovn-northd and ovn-controller to catch up.
1760 # XXX This should be more systematic.
1763 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1764 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1765 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1766 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1768 # Given the name of a logical port, prints the name of the hypervisor
1769 # on which it is located.
1774 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1776 # This shell function causes a packet to be received on INPORT. The packet's
1777 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1778 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1779 # more) list the VIFs on which the packet should be received. INPORT and the
1780 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1787 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1788 hv=`vif_to_hv $inport`
1790 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1792 echo $packet >> $outport.expected
1797 printf "%02x%02x%02x%02x" "$@"
1800 # Send packets between all pairs of source and destination ports:
1802 # 1. Unicast packets are delivered to exactly one logical switch port
1803 # (except that packets destined to their input ports are dropped).
1816 if test $d != $s; then unicast=$d; else unicast=; fi
1817 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1824 # dump information and flows with counters
1825 ovn-sbctl dump-flows -- list multicast_group
1827 echo "------ hv1 dump ------"
1828 as hv1 ovs-vsctl show
1829 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1831 echo "------ hv2 dump ------"
1832 as hv2 ovs-vsctl show
1833 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1835 echo "------ hv3 dump ------"
1836 as hv3 ovs-vsctl show
1837 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1839 # Now check the packets actually received against the ones expected.
1842 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1846 OVN_CLEANUP([hv1],[hv2])
1850 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1851 AT_SKIP_IF([test $HAVE_PYTHON = no])
1854 # Create a logical switch and some logical ports.
1855 # Turn on port security on all lports except ls1.
1856 # Make ls1 a destination for unknown MACs.
1857 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1858 ovn-nbctl ls-add lsw0
1859 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1861 ovn-nbctl lsp-add lsw0 lp$i
1863 ovn-nbctl --wait=sb sync
1865 ovn-sbctl lsp-bind lp$i hv0
1866 if test $i = 1; then
1867 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1869 if test $i = 3; then
1870 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1872 ip_addrs="192.168.0.$i"
1874 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1875 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
1878 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1879 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1880 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1881 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1882 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1884 ovn-nbctl --wait=sb sync
1885 on_exit 'kill `cat ovn-trace.pid`'
1886 ovn-trace --detach --pidfile --no-chdir
1888 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1890 # This shell function causes a packet to be received on INPORT. The packet's
1891 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1892 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1893 # more) list the VIFs on which the packet should be received. INPORT and the
1894 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1896 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1897 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1900 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1901 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1906 echo "output(\"lp$outport\");"
1909 AT_CAPTURE_FILE([trace])
1910 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1913 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1915 # Causes a packet to be received on INPORT. The packet is an ARP
1916 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1917 # it should be the hardware address of the target to expect to receive in an
1918 # ARP reply; otherwise no reply is expected.
1920 # INPORT is an logical switch port number, e.g. 11 for vif11.
1921 # SHA and REPLY_HA are each 12 hex digits.
1922 # SPA and TPA are each 8 hex digits.
1924 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1926 local request="inport == \"lp$inport\"
1927 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1928 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1929 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1931 if test -z "$reply_ha"; then
1935 if test $i != $inport; then
1936 reply="${reply}output(\"lp$i\");
1943 eth.src = $reply_ha;
1946 arp.sha = $reply_ha;
1949 output(\"lp$inport\");
1953 AT_CAPTURE_FILE([trace])
1954 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1957 # Send packets between all pairs of source and destination ports:
1959 # 1. Unicast packets are delivered to exactly one logical switch port
1960 # (except that packets destined to their input ports are dropped).
1962 # 2. Broadcast and multicast are delivered to all logical switch ports
1963 # except the input port.
1965 # 3. When port security is turned on, the switch drops packets from the wrong
1968 # 4. The switch drops all packets with a VLAN tag.
1970 # 5. The switch drops all packets with a multicast source address. (This only
1971 # affects behavior when port security is turned off, since otherwise port
1972 # security would drop the packet anyway.)
1974 # 6. The switch delivers packets with an unknown destination to logical
1975 # switch ports with "unknown" among their MAC addresses (and port
1976 # security disabled).
1978 # 7. The switch drops unicast packets that violate an ACL.
1980 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1982 # 9. OVN generates responses to ARP requests for known IPs, except for
1983 # requests from a port for the port's own IP.
1985 # 10. No response to ARP requests for unknown IPs.
1995 if test $d != $s; then unicast=$d; else unicast=; fi
1996 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1998 if test $d != $s && test $s = 1; then
2003 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
2005 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
2006 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
2007 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
2008 # Source of 1 or 2 and dest of 3 should be dropped
2009 # due to the 4th ACL that uses address_set(set1).
2016 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
2017 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
2018 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
2019 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
2021 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
2022 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
2024 if test $d != $s && test $d = 1; then
2025 unknown="$unknown $d"
2027 bcast="$bcast $unicast"
2028 bacl2="$bacl2 $acl2"
2029 bacl3="$bacl3 $acl3"
2033 tip_unknown=11.11.11.11
2034 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
2035 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
2036 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
2038 if test $d = 3; then
2039 # lp3 has an additional ip 192.169.0.[123]3.
2041 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
2045 # Broadcast and multicast.
2046 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
2047 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
2048 if test $s = 1; then
2049 bcast_impersonate=$bcast
2053 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
2055 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
2058 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
2059 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
2060 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
2063 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
2064 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
2065 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
2070 # 2 hypervisors, 4 logical ports per HV
2071 # 2 locally attached networks (one flat, one vlan tagged over same device)
2072 # 2 ports per HV on each network
2073 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
2074 AT_SKIP_IF([test $HAVE_PYTHON = no])
2077 # In this test cases we create 3 switches, all connected to same
2078 # physical network (through br-phys on each HV). Each switch has
2079 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
2080 # of VIF port name indicates the hypervisor it is bound to, e.g.
2081 # lp23 means VIF 3 on hv2.
2083 # Each switch's VLAN tag and their logical switch ports are:
2086 # - ports: lp11, lp12, lp21, lp22
2089 # - tagged with VLAN 101
2090 # - ports: lp13, lp14, lp23, lp24
2093 # - ports: lp15, lp25
2095 # Note: a localnet port is created for each switch to connect to
2100 ovn-nbctl ls-add $ls_name
2102 if test $i -eq 2; then
2103 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
2105 ovn-nbctl lsp-add $ls_name $ln_port_name
2107 ovn-nbctl lsp-set-addresses $ln_port_name unknown
2108 ovn-nbctl lsp-set-type $ln_port_name localnet
2109 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
2114 # Prints the name of the logical switch that contains LSP.
2117 lp?[[12]]) echo ls1 ;; dnl (
2118 lp?[[34]]) echo ls2 ;; dnl (
2119 lp?5) echo ls3 ;; dnl (
2120 *) AT_FAIL_IF([:]) ;;
2128 ovs-vsctl add-br br-phys
2129 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
2130 ovn_attach n1 br-phys 192.168.0.$i
2132 for j in 1 2 3 4 5; do
2133 ovs-vsctl add-port br-int vif$i$j -- \
2134 set Interface vif$i$j external-ids:iface-id=lp$i$j \
2135 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
2136 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
2140 ls_name=$(lsp_to_ls $lsp_name)
2142 ovn-nbctl lsp-add $ls_name $lsp_name
2143 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
2144 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
2146 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
2149 ovn-nbctl --wait=sb sync
2150 ovn-sbctl dump-flows
2154 # XXX This is now the 3rd copy of these functions in this file ...
2156 # Given the name of a logical port, prints the name of the hypervisor
2157 # on which it is located.
2162 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
2164 # This shell function causes a packet to be received on INPORT. The packet's
2165 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2166 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
2167 # logical switch port numbers, e.g. 11 for vif11.
2169 # EOUT is the end-to-end output port, that is, where the packet will end up
2170 # after possibly bouncing through one or more localnet ports. LOUT is the
2171 # logical output port, which might be a localnet port, as seen by ovn-trace
2172 # (which doesn't know what localnet ports are connected to and therefore can't
2173 # figure out the end-to-end answer).
2175 for j in 1 2 3 4 5; do
2180 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
2183 # First try tracing the packet.
2184 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
2185 if test $lout != drop; then
2186 echo "output(\"$lout\");"
2188 AT_CAPTURE_FILE([trace])
2189 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
2191 # Then actually send a packet, for an end-to-end test.
2192 local packet=$(echo $dst$src | sed 's/://g')${eth}
2193 hv=`vif_to_hv $inport`
2195 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2196 if test $eout != drop; then
2197 echo $packet >> ${eout#lp}.expected
2201 # lp11 and lp21 are on the same network (phys, untagged)
2202 # and on different hypervisors
2203 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
2204 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
2206 # lp11 and lp12 are on the same network (phys, untagged)
2207 # and on the same hypervisor
2208 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
2209 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
2211 # lp13 and lp23 are on the same network (phys, VLAN 101)
2212 # and on different hypervisors
2213 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
2214 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
2216 # lp13 and lp14 are on the same network (phys, VLAN 101)
2217 # and on the same hypervisor
2218 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
2219 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
2221 # lp11 and lp15 are on the same network (phys, untagged),
2222 # same hypervisor, and on different switches
2223 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2224 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
2226 # lp11 and lp25 are on the same network (phys, untagged),
2227 # different hypervisors, and on different switches
2228 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2229 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
2231 # Ports that should not be able to communicate
2232 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2233 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2234 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2235 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2236 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2237 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2238 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2239 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
2241 # Dump a bunch of info helpful for debugging if there's a failure.
2243 echo "------ OVN dump ------"
2247 echo "------ hv1 dump ------"
2248 as hv1 ovs-vsctl show
2249 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2251 echo "------ hv2 dump ------"
2252 as hv2 ovs-vsctl show
2253 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2255 # Now check the packets actually received against the ones expected.
2257 for j in 1 2 3 4 5; do
2258 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2262 OVN_CLEANUP([hv1],[hv2])
2266 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2268 AT_SKIP_IF([test $HAVE_PYTHON = no])
2271 # Configure the Northbound database
2272 ovn-nbctl ls-add lsw0
2274 ovn-nbctl lsp-add lsw0 lp1
2275 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2277 ovn-nbctl lsp-add lsw0 lp2
2278 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2280 ovn-nbctl lsp-add lsw0 lp-vtep
2281 ovn-nbctl lsp-set-type lp-vtep vtep
2282 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2283 ovn-nbctl lsp-set-addresses lp-vtep unknown
2285 # lpr, lr and lrp1 are used for the ARP request handling test only.
2286 ovn-nbctl lsp-add lsw0 lpr
2288 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2289 ovn-nbctl set Logical_Switch_Port lpr type=router \
2290 options:router-port=lrp1 \
2291 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2294 net_add n1 # Network to connect hv1, hv2, and vtep
2295 net_add n2 # Network to connect vtep and hv3
2297 # Create hypervisor hv1 connected to n1
2300 ovs-vsctl add-br br-phys
2301 ovn_attach n1 br-phys 192.168.0.1
2302 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
2304 # Create hypervisor hv2 connected to n1
2307 ovs-vsctl add-br br-phys
2308 ovn_attach n1 br-phys 192.168.0.2
2309 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
2312 # Start the vtep emulator with a leg in both networks
2316 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2317 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2319 ovs-vsctl add-br br-phys
2320 net_attach n1 br-phys
2322 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2323 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2324 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2325 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2327 ovs-vsctl add-br br-vtep
2328 net_attach n2 br-vtep
2330 vtep-ctl add-ps br-vtep
2331 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2332 vtep-ctl add-ls lsw0
2334 start_daemon ovs-vtep br-vtep
2335 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2337 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
2339 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2341 # It takes more time for the update to be processed by ovs-vtep.
2344 # Add hv3 on the other side of the vtep
2347 ovs-vsctl add-br br-phys
2348 net_attach n2 br-phys
2350 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
2352 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2353 # packets for ARP resolution (native tunneling doesn't queue packets
2354 # for ARP resolution).
2357 # Allow some time for ovn-northd and ovn-controller to catch up.
2358 # XXX This should be more systematic.
2361 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2363 # This shell function causes a packet to be received on INPORT. The packet's
2364 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2365 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2366 # more) list the VIFs on which the packet should be received. INPORT and the
2367 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
2372 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2373 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2376 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2378 echo $packet >> $outport.expected
2382 # Send packets between all pairs of source and destination ports:
2384 # 1. Unicast packets are delivered to exactly one logical switch port
2385 # (except that packets destined to their input ports are dropped).
2387 # 2. Broadcast and multicast are delivered to all logical switch ports
2388 # except the input port.
2390 # 3. The switch delivers packets with an unknown destination to logical
2391 # switch ports with "unknown" among their MAC addresses (and port
2392 # security disabled).
2397 if test $d != $s; then unicast=$d; else unicast=; fi
2398 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2400 # The vtep (vif3) is the only one configured for "unknown"
2401 if test $d != $s && test $d = 3; then
2402 unknown="$unknown $d"
2404 bcast="$bcast $unicast"
2407 # Broadcast and multicast.
2408 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2409 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
2411 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2414 # ARP request should not be responded to by logical switch router
2415 # type arp responder on HV1 and HV2 and should reach directly to
2418 printf "%02x%02x%02x%02x" "$@"
2421 spa=`ip_to_hex 192 168 1 2`
2422 tpa=`ip_to_hex 192 168 1 1`
2423 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2424 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2425 echo $request >> 1.expected
2426 echo $request >> 2.expected
2428 # dump information with counters
2429 echo "------ OVN dump ------"
2433 echo "---------SB dump-----"
2434 ovn-sbctl list datapath_binding
2435 echo "---------------------"
2436 ovn-sbctl list port_binding
2437 echo "---------------------"
2438 ovn-sbctl dump-flows
2440 echo "------ hv1 dump ------"
2441 as hv1 ovs-vsctl show
2442 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2443 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2445 echo "------ hv2 dump ------"
2446 as hv2 ovs-vsctl show
2447 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2448 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2450 echo "------ hv3 dump ------"
2451 as hv3 ovs-vsctl show
2452 # note: hv3 has no logical port bind, thus it should not have br-int
2453 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2454 [ovs-ofctl: br-int is not a bridge or a socket
2457 # Now check the packets actually received against the ones expected.
2459 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2462 # Gracefully terminate daemons
2463 OVN_CLEANUP([hv1],[hv2],[vtep])
2464 OVN_CLEANUP_VSWITCH([hv3])
2468 # Similar test to "hardware GW"
2469 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2470 AT_SKIP_IF([test $HAVE_PYTHON = no])
2473 # Configure the Northbound database
2474 ovn-nbctl ls-add lsw0
2476 ovn-nbctl lsp-add lsw0 lp1
2477 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2479 ovn-nbctl lsp-add lsw0 lp2
2480 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2482 ovn-nbctl lsp-add lsw0 lp-gw
2483 ovn-nbctl lsp-set-type lp-gw l2gateway
2484 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2485 ovn-nbctl lsp-set-addresses lp-gw unknown
2487 net_add n1 # Network to connect hv1, hv2, and gw
2488 net_add n2 # Network to connect gw and hv3
2490 # Create hypervisor hv1 connected to n1
2493 ovs-vsctl add-br br-phys
2494 ovn_attach n1 br-phys 192.168.0.1
2495 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
2497 # Create hypervisor hv2 connected to n1
2500 ovs-vsctl add-br br-phys
2501 ovn_attach n1 br-phys 192.168.0.2
2502 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
2504 # Create hypervisor hv_gw connected to n1 and n2
2505 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2508 ovs-vsctl add-br br-phys
2509 ovn_attach n1 br-phys 192.168.0.3
2510 ovs-vsctl add-br br-phys2
2511 net_attach n2 br-phys2
2512 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2514 # Add hv3 on the other side of the GW
2517 ovs-vsctl add-br br-phys
2518 net_attach n2 br-phys
2519 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
2522 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2523 # packets for ARP resolution (native tunneling doesn't queue packets
2524 # for ARP resolution).
2527 # Allow some time for ovn-northd and ovn-controller to catch up.
2528 # XXX This should be more systematic.
2531 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2533 # This shell function causes a packet to be received on INPORT. The packet's
2534 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2535 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2536 # more) list the VIFs on which the packet should be received. INPORT and the
2537 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2542 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2543 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2546 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2548 echo $packet >> $outport.expected
2552 # Send packets between all pairs of source and destination ports:
2554 # 1. Unicast packets are delivered to exactly one lport (except that packets
2555 # destined to their input ports are dropped).
2557 # 2. Broadcast and multicast are delivered to all lports except the input port.
2559 # 3. The lswitch delivers packets with an unknown destination to lports with
2560 # "unknown" among their MAC addresses (and port security disabled).
2565 if test $d != $s; then unicast=$d; else unicast=; fi
2566 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2568 # The vtep (vif3) is the only one configured for "unknown"
2569 if test $d != $s && test $d = 3; then
2570 unknown="$unknown $d"
2572 bcast="$bcast $unicast"
2575 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2576 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2577 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2580 echo "------ ovn-nbctl show ------"
2582 echo "------ ovn-sbctl show ------"
2585 echo "------ hv1 ------"
2586 as hv1 ovs-vsctl show
2587 echo "------ hv1 br-int ------"
2588 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2589 echo "------ hv1 br-phys ------"
2590 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2592 echo "------ hv2 ------"
2593 as hv2 ovs-vsctl show
2594 echo "------ hv2 br-int ------"
2595 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2596 echo "------ hv2 br-phys ------"
2597 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2599 echo "------ hv_gw ------"
2600 as hv_gw ovs-vsctl show
2601 echo "------ hv_gw br-phys ------"
2602 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2603 echo "------ hv_gw br-phys2 ------"
2604 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2606 echo "------ hv3 ------"
2607 as hv3 ovs-vsctl show
2608 echo "------ hv3 br-phys ------"
2609 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2611 # Now check the packets actually received against the ones expected.
2613 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2617 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2618 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2619 AT_SKIP_IF([test $HAVE_PYTHON = no])
2624 # Three logical switches ls1, ls2, ls3.
2625 # One logical router lr0 connected to ls[123],
2626 # with nine subnets, three per logical switch:
2628 # lrp11 on ls1 for subnet 192.168.11.0/24
2629 # lrp12 on ls1 for subnet 192.168.12.0/24
2630 # lrp13 on ls1 for subnet 192.168.13.0/24
2632 # lrp33 on ls3 for subnet 192.168.33.0/24
2634 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2635 # digits are the subnet and the last digit distinguishes the VIF.
2637 ovn-nbctl ls-add ls$i
2640 # Add "unknown" to MAC addresses for lp?11, so packets for
2641 # MAC-IP bindings discovered via ARP later have somewhere to go.
2642 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2645 -- lsp-add ls$i lp$i$j$k \
2646 -- lsp-set-addresses lp$i$j$k \
2647 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
2652 ovn-nbctl lr-add lr0
2655 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2657 -- lsp-add ls$i lrp$i$j-attachment \
2658 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2659 options:router-port=lrp$i$j \
2660 addresses='"00:00:00:00:ff:'$i$j'"'
2664 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2665 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2669 # Three hypervisors hv[123].
2670 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2671 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2672 # lp?3[123] all on hv3.
2675 # Given the name of a logical port, prints the name of the hypervisor
2676 # on which it is located.
2679 ?11) echo 1 ;; dnl (
2680 ?12 | ?21 | ?22) echo 2 ;; dnl (
2681 ?13 | ?23 | ?3?) echo 3 ;;
2685 # Given the name of a logical port, prints the name of its logical router
2686 # port, e.g. "vif_to_lrp 123" yields 12.
2691 # Given the name of a logical port, prints the name of its logical
2692 # switch, e.g. "vif_to_ls 123" yields 1.
2701 ovs-vsctl add-br br-phys
2702 ovn_attach n1 br-phys 192.168.0.$i
2707 hv=`vif_to_hv $i$j$k`
2708 as hv$hv ovs-vsctl \
2709 -- add-port br-int vif$i$j$k \
2710 -- set Interface vif$i$j$k \
2711 external-ids:iface-id=lp$i$j$k \
2712 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2713 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2714 ofport-request=$i$j$k
2719 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2720 # packets for ARP resolution (native tunneling doesn't queue packets
2721 # for ARP resolution).
2724 # Allow some time for ovn-northd and ovn-controller to catch up.
2725 # XXX This should be more systematic.
2728 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2730 # This shell function causes a packet to be received on INPORT. The packet's
2731 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2732 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2733 # more) list the VIFs on which the packet should be received. INPORT and the
2734 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2743 # This packet has bad checksums but logical L3 routing doesn't check.
2744 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2745 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2746 shift; shift; shift; shift; shift
2747 hv=hv`vif_to_hv $inport`
2748 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2749 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2750 in_ls=`vif_to_ls $inport`
2751 in_lrp=`vif_to_lrp $inport`
2753 out_ls=`vif_to_ls $outport`
2754 if test $in_ls = $out_ls; then
2755 # Ports on the same logical switch receive exactly the same packet.
2758 # Routing decrements TTL and updates source and dest MAC
2760 out_lrp=`vif_to_lrp $outport`
2761 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2762 fi >> $outport.expected
2766 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2768 # Causes a packet to be received on INPORT. The packet is an ARP
2769 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2770 # it should be the hardware address of the target to expect to receive in an
2771 # ARP reply; otherwise no reply is expected.
2773 # INPORT is an logical switch port number, e.g. 11 for vif11.
2774 # SHA and REPLY_HA are each 12 hex digits.
2775 # SPA and TPA are each 8 hex digits.
2777 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2778 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2779 hv=hv`vif_to_hv $inport`
2780 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2781 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2783 # Expect to receive the broadcast ARP on the other logical switch ports if
2784 # IP address is not configured to the switch patch port.
2785 local i=`vif_to_ls $inport`
2789 # 192.168.33.254 is configured to the switch patch port for lrp33,
2790 # so no ARP flooding expected for it.
2791 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2792 echo $request >> $i$j$k.expected
2797 # Expect to receive the reply, if any.
2798 if test X$reply_ha != X; then
2799 lrp=`vif_to_lrp $inport`
2800 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2801 echo $reply >> $inport.expected
2805 as hv1 ovs-vsctl --columns=name,ofport list interface
2806 as hv1 ovn-sbctl list port_binding
2807 as hv1 ovn-sbctl list datapath_binding
2808 as hv1 ovn-sbctl dump-flows
2809 as hv1 ovs-ofctl dump-flows br-int
2811 # Send IP packets between all pairs of source and destination ports:
2813 # 1. Unicast IP packets are delivered to exactly one logical switch port
2814 # (except that packets destined to their input ports are dropped).
2816 # 2. Broadcast IP packets are delivered to all logical switch ports
2817 # except the input port.
2819 printf "%02x%02x%02x%02x" "$@"
2827 sip=`ip_to_hex 192 168 $is$js $ks`
2832 dip=`ip_to_hex 192 168 $id$jd $kd`
2833 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2834 if test $d != $s; then unicast=$d; else unicast=; fi
2836 test_ip $s $smac $dmac $sip $dip $unicast #1
2838 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2842 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2847 : > mac_bindings.expected
2849 # 3. Send an IP packet from every logical port to every other subnet,
2850 # to an IP address that does not have a static IP-MAC binding.
2851 # This should generate a broadcast ARP request for the destination
2852 # IP address in the destination subnet.
2853 # Moreover generate an ARP reply for each of the IP addresses ARPed
2859 sip=`ip_to_hex 192 168 $is$js $ks`
2862 if test $is$js = $id$jd; then
2867 dmac=00000000ff$is$js
2868 # Calculate a 4th octet for the destination that is
2869 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2870 # that have static MAC bindings, and fits in the range
2872 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2873 dip=`ip_to_hex 192 168 $id$jd $o4`
2874 test_ip $s $smac $dmac $sip $dip
2876 # Every LP on the destination subnet's lswitch should
2877 # receive the ARP request.
2878 lrmac=00000000ff$id$jd
2879 lrip=`ip_to_hex 192 168 $id$jd 254`
2880 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2881 for jd2 in 1 2 3; do
2883 echo $arp >> $id$jd2$kd.expected
2888 rmac=00000000ff$id$jd
2889 echo ${hmac}${rmac}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> ${id}11.expected
2891 host_mac=8000000000$o4
2892 lrmac=00000000ff$id$jd
2894 arp_reply=${lrmac}${host_mac}08060001080006040002${host_mac}${dip}${lrmac}${lrip}
2896 hv=hv`vif_to_hv ${id}${jd}1`
2897 as $hv ovs-appctl netdev-dummy/receive vif${id}${jd}1 $arp_reply
2899 host_ip_pretty=192.168.$id$jd.$o4
2900 host_mac_pretty=80:00:00:00:00:$o4
2901 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2908 # Test router replies to ARP requests from all source ports:
2910 # 4. Router replies to query for its MAC address from port's own IP address.
2912 # 5. Router replies to query for its MAC address from any random IP address
2915 # 6. No reply to query for IP address other than router IP.
2917 # 7. No reply to query from another subnet.
2921 smac=f00000000$i$j$k # Source MAC
2922 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2923 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2924 rmac=00000000ff$i$j # Router MAC
2925 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2926 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2928 test_arp $i$j$k $smac $sip $rip $rmac #4
2929 test_arp $i$j$k $smac $otherip $rip $rmac #5
2930 test_arp $i$j$k $smac $sip $otherip #6
2932 # When rip is 192.168.33.254, ARP request from externalip won't be
2933 # filtered, because 192.168.33.254 is configured to switch peer port
2936 if test $i = 3 && test $j = 3; then
2939 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2941 # MAC binding should be learned from ARP request.
2942 host_mac_pretty=f0:00:00:00:0$i:$j$k
2944 host_ip_pretty=192.168.$i$j.$k
2945 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2947 # mac_binding is learned and overwritten so only the last one remains.
2948 if test $k = 3; then
2949 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2950 # configured to switch peer port for lrp33.
2951 if test $i != 3 || test $j != 3; then
2952 host_ip_pretty=192.168.$i$j.55
2953 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2962 # Allow some time for packet forwarding.
2963 # XXX This can be improved.
2966 # 8. Send an IP packet from every logical port to every other subnet. These
2967 # are the same packets already sent as #3, but now the destinations' IP-MAC
2968 # bindings have been discovered via ARP, so instead of provoking an ARP
2969 # request, these packets now get routed to their destinations (which don't
2970 # have static MAC bindings, so they go to the port we've designated as
2971 # accepting "unknown" MACs.)
2977 sip=`ip_to_hex 192 168 $is$js $ks`
2980 if test $is$js = $id$jd; then
2985 dmac=00000000ff$is$js
2986 # Calculate a 4th octet for the destination that is
2987 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2988 # that have static MAC bindings, and fits in the range
2990 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2991 dip=`ip_to_hex 192 168 $id$jd $o4`
2992 test_ip $s $smac $dmac $sip $dip
2994 # Expect the packet egress.
2995 host_mac=8000000000$o4
2998 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
3005 ovn-sbctl -f csv -d bare --no-heading \
3006 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
3008 # Now check the packets actually received against the ones expected.
3012 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
3018 # Check the MAC bindings against those expected.
3019 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
3022 # Gracefully terminate daemons
3023 OVN_CLEANUP([hv1], [hv2], [hv3])
3027 AT_SETUP([ovn -- IP relocation using GARP request])
3028 AT_SKIP_IF([test $HAVE_PYTHON = no])
3033 # Two logical switches ls1, ls2.
3034 # One logical router lr0 connected to ls[12],
3035 # with 2 subnets, 1 per logical switch:
3037 # lrp1 on ls1 for subnet 192.168.1.1/24
3038 # lrp2 on ls2 for subnet 192.168.2.1/24
3040 # 4 VIFs, 2 per LS lp[12][12], first digit being LS.
3041 # VIFs' fixed IP addresses are 192.168.[12].1[12].
3043 # There is a secondary IP 192.168.1.100 that is unknown in NB and learned
3044 # through ARP only, and it can move between lp11 and lp12.
3046 ovn-nbctl lr-add lr0
3048 ovn-nbctl ls-add ls$i
3049 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
3051 -- lsp-add ls$i lrp$i-attachment \
3052 -- set Logical_Switch_Port lrp$i-attachment type=router \
3053 options:router-port=lrp$i \
3057 -- lsp-add ls$i lp$i$j \
3058 -- lsp-set-addresses lp$i$j \
3059 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
3064 # 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
3066 # Given the name of a logical port, prints the name of the hypervisor
3067 # on which it is located, e.g. "vif_to_hv 12" yields 2.
3072 # Given the name of a logical port, prints the name of its logical router
3073 # port, e.g. "vif_to_lrp 12" yields 1.
3078 # Given the name of a logical port, prints the name of its logical
3079 # switch, e.g. "vif_to_ls 12" yields 1.
3088 ovs-vsctl add-br br-phys
3089 ovn_attach n1 br-phys 192.168.0.$i
3094 as hv$hv ovs-vsctl \
3095 -- add-port br-int vif$i$j \
3096 -- set Interface vif$i$j \
3097 external-ids:iface-id=lp$i$j \
3098 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
3099 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
3104 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3105 # packets for ARP resolution (native tunneling doesn't queue packets
3106 # for ARP resolution).
3109 # Allow some time for ovn-northd and ovn-controller to catch up.
3110 # XXX This should be more systematic.
3113 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3115 # This shell function causes a packet to be received on INPORT. The packet's
3116 # content has Ethernet destination DST and source SRC (each exactly 12 hex
3117 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
3118 # more) list the VIFs on which the packet should be received. INPORT and the
3119 # OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
3126 # This packet has bad checksums but logical L3 routing doesn't check.
3127 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3128 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3129 shift; shift; shift; shift; shift
3130 hv=hv`vif_to_hv $inport`
3131 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3132 in_ls=`vif_to_ls $inport`
3133 in_lrp=`vif_to_lrp $inport`
3135 out_ls=`vif_to_ls $outport`
3136 if test $in_ls = $out_ls; then
3137 # Ports on the same logical switch receive exactly the same packet.
3140 # Routing decrements TTL and updates source and dest MAC
3142 out_lrp=`vif_to_lrp $outport`
3143 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
3144 fi >> $outport.expected
3148 # test_arp INPORT SHA SPA TPA [REPLY_HA]
3150 # Causes a packet to be received on INPORT. The packet is an ARP
3151 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3152 # it should be the hardware address of the target to expect to receive in an
3153 # ARP reply; otherwise no reply is expected.
3155 # INPORT is an logical switch port number, e.g. 11 for vif11.
3156 # SHA and REPLY_HA are each 12 hex digits.
3157 # SPA and TPA are each 8 hex digits.
3159 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
3160 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3161 hv=hv`vif_to_hv $inport`
3162 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3164 # Expect to receive the broadcast ARP on the other logical switch ports if
3165 # IP address is not configured to the switch patch port.
3166 local i=`vif_to_ls $inport`
3169 if test $i$j != $inport; then
3170 echo $request >> $i$j$k.expected
3174 # Expect to receive the reply, if any.
3175 if test X$reply_ha != X; then
3176 lrp=`vif_to_lrp $inport`
3177 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3178 echo $reply >> $inport.expected
3183 printf "%02x%02x%02x%02x" "$@"
3186 # lp11 send GARP request to announce ownership of 192.168.1.100.
3189 spa=`ip_to_hex 192 168 1 100`
3191 test_arp 11 $sha $spa $tpa
3192 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
3193 ovn-nbctl --wait=hv sync
3195 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
3199 sip=`ip_to_hex 192 168 2 11`
3200 dip=`ip_to_hex 192 168 1 100`
3201 test_ip 21 $smac $dmac $sip $dip 11
3203 # lp12 send GARP request to announce ownership of 192.168.1.100.
3206 test_arp 12 $sha $spa $tpa
3207 OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
3208 ovn-nbctl --wait=hv sync
3209 # give to the hv the time to send queued ip packets
3212 # Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
3214 test_ip 21 $smac $dmac $sip $dip 12
3216 # Now check the packets actually received against the ones expected.
3219 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3224 # Gracefully terminate daemons
3225 OVN_CLEANUP([hv1], [hv2])
3229 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3230 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
3231 AT_SKIP_IF([test $HAVE_PYTHON = no])
3234 # Create hypervisors hv[123].
3235 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3236 # Add all of the vifs to a single logical switch lsw0.
3237 # Turn off port security on vifs vif[123]1
3238 # Turn on l2 port security on vifs vif[123]2
3239 # Turn of l2 and l3 port security on vifs vif[123]3
3240 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
3241 ovn-nbctl ls-add lsw0
3246 ovs-vsctl add-br br-phys
3247 ovn_attach n1 br-phys 192.168.0.$i
3250 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
3251 ovn-nbctl lsp-add lsw0 lp$i$j
3252 if test $j = 1; then
3253 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
3254 elif test $j = 2; then
3255 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3256 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
3258 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
3259 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3260 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3265 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3266 # packets for ARP resolution (native tunneling doesn't queue packets
3267 # for ARP resolution).
3270 # Allow some time for ovn-northd and ovn-controller to catch up.
3271 # XXX This should be more systematic.
3274 # Given the name of a logical port, prints the name of the hypervisor
3275 # on which it is located.
3286 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3288 # This shell function causes an ip packet to be received on INPORT.
3289 # The packet's content has Ethernet destination DST and source SRC
3290 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3291 # The OUTPORTs (zero or more) list the VIFs on which the packet should
3292 # be received. INPORT and the OUTPORTs are specified as logical switch
3293 # port numbers, e.g. 11 for vif11.
3295 # This packet has bad checksums but logical L3 routing doesn't check.
3296 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3297 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3298 shift; shift; shift; shift; shift
3299 hv=`vif_to_hv $inport`
3300 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3301 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3303 echo $packet >> $outport.expected
3307 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3309 # Causes a packet to be received on INPORT. The packet is an ARP
3310 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3311 # it should be the hardware address of the target to expect to receive in an
3312 # ARP reply; otherwise no reply is expected.
3314 # INPORT is an logical switch port number, e.g. 11 for vif11.
3315 # SHA and REPLY_HA are each 12 hex digits.
3316 # SPA and TPA are each 8 hex digits.
3318 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3319 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3320 hv=`vif_to_hv $inport`
3321 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3322 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3323 if test $drop != 1; then
3324 if test X$reply_ha = X; then
3325 # Expect to receive the broadcast ARP on the other logical switch ports
3326 # if no reply is expected.
3330 if test $i$j != $inport; then
3331 echo $request >> $i$j.expected
3336 # Expect to receive the reply, if any.
3337 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3338 echo $reply >> $inport.expected
3343 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3344 # This function is similar to test_ip() except that it sends
3347 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3348 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3349 shift; shift; shift; shift; shift
3350 hv=`vif_to_hv $inport`
3351 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3352 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3354 echo $packet >> $outport.expected
3358 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3359 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
3360 # of the test packet
3362 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3363 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3364 shift; shift; shift; shift; shift; shift
3365 hv=`vif_to_hv $inport`
3366 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3367 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3369 echo $packet >> $outport.expected
3374 printf "%02x%02x%02x%02x" "$@"
3378 sip=`ip_to_hex 192 168 0 12`
3379 tip=`ip_to_hex 192 168 0 13`
3380 # the arp packet should be allowed even if lp[123]1 is
3381 # not configured with mac f00000000023 and ip 192.168.0.12
3383 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3385 if test $i != $j; then
3386 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3392 sip=`ip_to_hex 192 168 0 12`
3393 tip=`ip_to_hex 192 168 0 13`
3395 # arp packet should be allowed since lp22 is configured with
3397 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3399 # arp packet should not be allowed since lp32 is not configured with
3401 test_arp 32 f00000000021 f00000000021 $sip $tip 1
3403 # arp packet with sha set to f00000000021 should not be allowed
3405 test_arp 12 f00000000012 f00000000021 $sip $tip 1
3407 # ip packets should be allowed and received since lp[123]2 do not
3408 # have l3 port security
3409 sip=`ip_to_hex 192 168 0 55`
3410 tip=`ip_to_hex 192 168 0 66`
3413 if test $i != $j; then
3414 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3419 # ipv6 packets should be received by lp[123]2
3420 # lp[123]1 can send ipv6 traffic as there is no port security
3421 sip=fe800000000000000000000000000000
3422 tip=ff020000000000000000000000000000
3425 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3429 # l2 and l3 port security
3430 sip=`ip_to_hex 192 168 0 13`
3431 tip=`ip_to_hex 192 168 0 22`
3432 # arp packet should be allowed since lp13 is configured with
3433 # f00000000013 and 192.168.0.13
3434 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3436 # the arp packet should be dropped because lp23 is not configured
3437 # with mac f00000000022
3438 sip=`ip_to_hex 192 168 0 13`
3439 tip=`ip_to_hex 192 168 0 22`
3440 test_arp 23 f00000000022 f00000000022 $sip $tip 1
3442 # the arp packet should be dropped because lp33 is not configured
3443 # with ip 192.168.0.55
3444 spa=`ip_to_hex 192 168 0 55`
3445 tpa=`ip_to_hex 192 168 0 22`
3446 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3448 # ip packets should not be received by lp[123]3 since
3449 # l3 port security is enabled
3450 sip=`ip_to_hex 192 168 0 55`
3451 tip=`ip_to_hex 192 168 0 66`
3454 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3458 # ipv6 packets should be dropped for lp[123]3 since
3459 # it is configured with only ipv4 address
3460 sip=fe800000000000000000000000000000
3461 tip=ff020000000000000000000000000000
3464 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3467 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3468 # lp[123]1 can send ipv6 traffic as there is no port security
3470 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3473 # lp13 has extra port security with mac f0000000113 and ipv6 addr
3474 # fe80::ea2a:eaff:fe28:0012
3476 # ipv4 packet should be dropped for lp13 with mac f0000000113
3477 sip=`ip_to_hex 192 168 0 13`
3478 tip=`ip_to_hex 192 168 0 23`
3479 test_ip 13 f00000000113 f00000000023 $sip $tip
3481 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3482 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
3483 # lp11 can send ipv6 traffic as there is no port security
3484 sip=ee800000000000000000000000000000
3486 tip=fe80000000000000ea2aeafffe2800${i}3
3487 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
3491 # ipv6 packet should not be received by lp33 with mac f0000000333
3492 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3493 # configured with fe80::ea2a:eaff:fe28:0033
3494 # lp11 can send ipv6 traffic as there is no port security
3496 sip=ee800000000000000000000000000000
3497 tip=fe80000000000000ea2aeafffe280023
3498 test_ipv6 11 f00000000011 f00000000333 $sip $tip
3500 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3501 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
3502 # and should be dropped for any other ip6.src
3503 # lp21 can receive ipv6 traffic as there is no port security
3505 tip=ee800000000000000000000000000000
3507 sip=fe80000000000000ea2aeafffe2800${i}3
3508 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3510 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
3511 sip=00000000000000000000000000000000
3512 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3513 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3514 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3515 # Traffic to non-multicast traffic should be dropped
3516 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3517 # Traffic of other ICMPv6 types should be dropped
3518 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
3521 sip=ae80000000000000ea2aeafffe2800aa
3522 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3525 # configure lsp13 to send and received IPv4 packets with an address range
3526 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"
3530 sip=`ip_to_hex 10 0 0 13`
3531 tip=`ip_to_hex 192 168 0 22`
3532 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
3533 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3535 sip=`ip_to_hex 10 0 0 14`
3536 tip=`ip_to_hex 192 168 0 23`
3537 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
3538 # with dst ip 192.168.0.23 should be allowed
3539 test_ip 13 f00000000013 f00000000023 $sip $tip 23
3541 sip=`ip_to_hex 192 168 0 33`
3542 tip=`ip_to_hex 10 0 0 15`
3543 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3544 # with dst ip 10.0.0.15 should be received by lsp13
3545 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3547 sip=`ip_to_hex 192 168 0 33`
3548 tip=`ip_to_hex 20 0 0 4`
3549 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3550 # with dst ip 20.0.0.4 should be received by lsp13
3551 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3553 sip=`ip_to_hex 192 168 0 33`
3554 tip=`ip_to_hex 20 0 0 5`
3555 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3556 # with dst ip 20.0.0.5 should not be received by lsp13
3557 test_ip 33 f00000000033 f00000000013 $sip $tip
3559 sip=`ip_to_hex 192 168 0 33`
3560 tip=`ip_to_hex 20 0 0 255`
3561 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3562 # with dst ip 20.0.0.255 should be received by lsp13
3563 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3565 sip=`ip_to_hex 192 168 0 33`
3566 tip=`ip_to_hex 192 168 0 255`
3567 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3568 # with dst ip 192.168.0.255 should not be received by lsp13
3569 test_ip 33 f00000000033 f00000000013 $sip $tip
3571 sip=`ip_to_hex 192 168 0 33`
3572 tip=`ip_to_hex 224 0 0 4`
3573 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3574 # with dst ip 224.0.0.4 should be received by lsp13
3575 test_ip 33 f00000000033 f00000000013 $sip $tip 13
3577 #dump information including flow counters
3579 ovn-sbctl dump-flows -- list multicast_group
3581 echo "------ hv1 dump ------"
3582 as hv1 ovs-vsctl show
3583 as hv1 ovs-ofctl -O OpenFlow13 show br-int
3584 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3586 echo "------ hv2 dump ------"
3587 as hv2 ovs-vsctl show
3588 as hv2 ovs-ofctl -O OpenFlow13 show br-int
3589 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3591 echo "------ hv3 dump ------"
3592 as hv3 ovs-vsctl show
3593 as hv3 ovs-ofctl -O OpenFlow13 show br-int
3594 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3596 # Now check the packets actually received against the ones expected.
3599 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
3603 OVN_CLEANUP([hv1],[hv2],[hv3])
3607 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
3608 AT_SKIP_IF([test $HAVE_PYTHON = no])
3612 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3613 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3614 # R2 has ls2 (172.16.1.0/24) connected to it.
3616 ls1_lp1_mac="f0:00:00:01:02:03"
3617 rp_ls1_mac="00:00:00:01:02:03"
3618 rp_ls2_mac="00:00:00:01:02:04"
3619 ls2_lp1_mac="f0:00:00:01:02:04"
3621 ls1_lp1_ip="192.168.1.2"
3622 ls2_lp1_ip="172.16.1.2"
3627 ovn-nbctl ls-add ls1
3628 ovn-nbctl ls-add ls2
3631 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3633 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3634 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3637 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3639 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3640 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3643 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3644 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3646 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3647 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3649 # Create logical port ls1-lp1 in ls1
3650 ovn-nbctl lsp-add ls1 ls1-lp1 \
3651 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3653 # Create logical port ls2-lp1 in ls2
3654 ovn-nbctl lsp-add ls2 ls2-lp1 \
3655 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3657 # Create two hypervisor and create OVS ports corresponding to logical ports.
3662 ovs-vsctl add-br br-phys
3663 ovn_attach n1 br-phys 192.168.0.1
3664 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3665 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3666 options:tx_pcap=hv1/vif1-tx.pcap \
3667 options:rxq_pcap=hv1/vif1-rx.pcap \
3672 ovs-vsctl add-br br-phys
3673 ovn_attach n1 br-phys 192.168.0.2
3674 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3675 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3676 options:tx_pcap=hv2/vif1-tx.pcap \
3677 options:rxq_pcap=hv2/vif1-rx.pcap \
3681 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3682 # packets for ARP resolution (native tunneling doesn't queue packets
3683 # for ARP resolution).
3686 # Allow some time for ovn-northd and ovn-controller to catch up.
3687 # XXX This should be more systematic.
3691 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3692 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3693 udp && udp.src==53 && udp.dst==4369"
3694 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3697 echo "---------NB dump-----"
3699 echo "---------------------"
3700 ovn-nbctl list logical_router
3701 echo "---------------------"
3702 ovn-nbctl list logical_router_port
3703 echo "---------------------"
3705 echo "---------SB dump-----"
3706 ovn-sbctl list datapath_binding
3707 echo "---------------------"
3708 ovn-sbctl list port_binding
3709 echo "---------------------"
3711 echo "------ hv1 dump ----------"
3712 as hv1 ovs-ofctl show br-int
3713 as hv1 ovs-ofctl dump-flows br-int
3714 echo "------ hv2 dump ----------"
3715 as hv2 ovs-ofctl show br-int
3716 as hv2 ovs-ofctl dump-flows br-int
3719 # The TTL should be decremented by 2.
3720 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3721 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3722 udp && udp.src==53 && udp.dst==4369"
3723 echo $packet | ovstest test-ovn expr-to-packets > expected
3725 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3727 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3728 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3731 # Disable the ls2-lp1 port.
3732 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3734 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3735 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3738 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3740 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3741 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3742 udp && udp.src==53 && udp.dst==4369"
3744 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3745 # The 2nd packet sent shound not be received.
3746 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3748 OVN_CLEANUP([hv1],[hv2])
3753 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3754 AT_KEYWORDS([router-admin-state])
3755 AT_SKIP_IF([test $HAVE_PYTHON = no])
3759 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3760 # and 172.16.1.0/24) connected to it.
3764 ovn-nbctl ls-add ls1
3767 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3768 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3769 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3771 # Create logical port ls1-lp1 in ls1
3772 ovn-nbctl lsp-add ls1 ls1-lp1 \
3773 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3775 # Create logical port ls1-lp2 in ls1
3776 ovn-nbctl lsp-add ls1 ls1-lp2 \
3777 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3779 # Create one hypervisor and create OVS ports corresponding to logical ports.
3784 ovs-vsctl add-br br-phys
3785 ovn_attach n1 br-phys 192.168.0.1
3786 ovs-vsctl -- add-port br-int vif1 -- \
3787 set interface vif1 external-ids:iface-id=ls1-lp1 \
3788 options:tx_pcap=hv1/vif1-tx.pcap \
3789 options:rxq_pcap=hv1/vif1-rx.pcap \
3792 ovs-vsctl -- add-port br-int vif2 -- \
3793 set interface vif2 external-ids:iface-id=ls1-lp2 \
3794 options:tx_pcap=hv1/vif2-tx.pcap \
3795 options:rxq_pcap=hv1/vif2-rx.pcap \
3799 # Allow some time for ovn-northd and ovn-controller to catch up.
3800 # XXX This should be more systematic.
3803 # Send ip packets between the two ports.
3805 printf "%02x%02x%02x%02x" "$@"
3809 src_mac="f00000010203"
3810 dst_mac="000000010203"
3811 src_ip=`ip_to_hex 192 168 1 2`
3812 dst_ip=`ip_to_hex 172 16 1 2`
3813 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3814 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3817 echo "---------NB dump-----"
3819 echo "---------------------"
3820 ovn-nbctl list logical_router
3821 echo "---------------------"
3822 ovn-nbctl list logical_router_port
3823 echo "---------------------"
3825 echo "---------SB dump-----"
3826 ovn-sbctl list datapath_binding
3827 echo "---------------------"
3828 ovn-sbctl list logical_flow
3829 echo "---------------------"
3831 echo "------ hv1 dump ----------"
3832 as hv1 ovs-ofctl dump-flows br-int
3836 ovn-nbctl set Logical_Router R1 enabled=false
3838 # Allow some time for ovn-northd and ovn-controller to catch up.
3839 # XXX This should be more systematic.
3842 echo "---------SB dump-----"
3843 ovn-sbctl list datapath_binding
3844 echo "---------------------"
3845 ovn-sbctl list logical_flow
3846 echo "---------------------"
3848 echo "------ hv1 dump ----------"
3849 as hv1 ovs-ofctl dump-flows br-int
3851 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3854 expect_src_mac="000000010203"
3855 expect_dst_mac="f00000010204"
3856 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3858 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3865 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3866 AT_KEYWORDS([router-admin-state])
3867 AT_SKIP_IF([test $HAVE_PYTHON = no])
3871 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3872 # and has switch ls2 (172.16.1.0/24) connected to it.
3876 ovn-nbctl ls-add ls1
3877 ovn-nbctl ls-add ls2
3880 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3881 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3882 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3885 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3886 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3887 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3889 # Create logical port ls1-lp1 in ls1
3890 ovn-nbctl lsp-add ls1 ls1-lp1 \
3891 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3893 # Create logical port ls2-lp1 in ls2
3894 ovn-nbctl lsp-add ls2 ls2-lp1 \
3895 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3897 # Create one hypervisor and create OVS ports corresponding to logical ports.
3902 ovs-vsctl add-br br-phys
3903 ovn_attach n1 br-phys 192.168.0.1
3904 ovs-vsctl -- add-port br-int vif1 -- \
3905 set interface vif1 external-ids:iface-id=ls1-lp1 \
3906 options:tx_pcap=hv1/vif1-tx.pcap \
3907 options:rxq_pcap=hv1/vif1-rx.pcap \
3910 ovs-vsctl -- add-port br-int vif2 -- \
3911 set interface vif2 external-ids:iface-id=ls2-lp1 \
3912 options:tx_pcap=hv1/vif2-tx.pcap \
3913 options:rxq_pcap=hv1/vif2-rx.pcap \
3917 # Allow some time for ovn-northd and ovn-controller to catch up.
3918 # XXX This should be more systematic.
3921 # Send ip packets between the two ports.
3923 printf "%02x%02x%02x%02x" "$@"
3927 src_mac="f00000010203"
3928 dst_mac="000000010203"
3929 src_ip=`ip_to_hex 192 168 1 2`
3930 dst_ip=`ip_to_hex 172 16 1 2`
3931 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3932 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3935 echo "---------NB dump-----"
3937 echo "---------------------"
3938 ovn-nbctl list logical_router
3939 echo "---------------------"
3940 ovn-nbctl list logical_router_port
3941 echo "---------------------"
3943 echo "---------SB dump-----"
3944 ovn-sbctl list datapath_binding
3945 echo "---------------------"
3946 ovn-sbctl list logical_flow
3947 echo "---------------------"
3949 echo "------ hv1 dump ----------"
3950 as hv1 ovs-ofctl dump-flows br-int
3953 ovn-nbctl set Logical_Router R1 enabled=false
3955 echo "---------SB dump-----"
3956 ovn-sbctl list datapath_binding
3957 echo "---------------------"
3958 ovn-sbctl list logical_flow
3959 echo "---------------------"
3961 echo "------ hv1 dump ----------"
3962 as hv1 ovs-ofctl dump-flows br-int
3964 # Allow some time for the disabling of logical router R1 to propagate.
3965 # XXX This should be more systematic.
3968 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3971 expect_src_mac="000000010204"
3972 expect_dst_mac="f00000010204"
3973 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3975 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3981 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3982 AT_SKIP_IF([test $HAVE_PYTHON = no])
3986 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3987 # network. R1 has switchess foo (192.168.1.0/24)
3989 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3994 ovn-nbctl ls-add foo
3995 ovn-nbctl ls-add alice
3996 ovn-nbctl ls-add bob
3999 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4000 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4001 options:router-port=foo addresses=\"00:00:00:01:02:03\"
4003 # Connect alice to R2
4004 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
4005 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4006 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
4009 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
4010 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
4011 options:router-port=bob addresses=\"00:00:00:01:02:05\"
4014 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
4015 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
4017 #install static routes
4018 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4019 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
4020 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4022 # Create logical port foo1 in foo
4023 ovn-nbctl lsp-add foo foo1 \
4024 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4026 # Create logical port alice1 in alice
4027 ovn-nbctl lsp-add alice alice1 \
4028 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4030 # Create logical port bob1 in bob
4031 ovn-nbctl lsp-add bob bob1 \
4032 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
4034 # Create two hypervisor and create OVS ports corresponding to logical ports.
4039 ovs-vsctl add-br br-phys
4040 ovn_attach n1 br-phys 192.168.0.1
4041 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4042 set interface hv1-vif1 external-ids:iface-id=foo1 \
4043 options:tx_pcap=hv1/vif1-tx.pcap \
4044 options:rxq_pcap=hv1/vif1-rx.pcap \
4047 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4048 set interface hv1-vif2 external-ids:iface-id=alice1 \
4049 options:tx_pcap=hv1/vif2-tx.pcap \
4050 options:rxq_pcap=hv1/vif2-rx.pcap \
4055 ovs-vsctl add-br br-phys
4056 ovn_attach n1 br-phys 192.168.0.2
4057 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4058 set interface hv2-vif1 external-ids:iface-id=bob1 \
4059 options:tx_pcap=hv2/vif1-tx.pcap \
4060 options:rxq_pcap=hv2/vif1-rx.pcap \
4064 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4065 # packets for ARP resolution (native tunneling doesn't queue packets
4066 # for ARP resolution).
4069 # Allow some time for ovn-northd and ovn-controller to catch up.
4070 # XXX This should be more systematic.
4074 printf "%02x%02x%02x%02x" "$@"
4077 # Send ip packets between foo1 and alice1
4078 src_mac="f00000010203"
4079 dst_mac="000000010203"
4080 src_ip=`ip_to_hex 192 168 1 2`
4081 dst_ip=`ip_to_hex 172 16 1 2`
4082 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4083 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4085 # Send ip packets between foo1 and bob1
4086 src_mac="f00000010203"
4087 dst_mac="000000010203"
4088 src_ip=`ip_to_hex 192 168 1 2`
4089 dst_ip=`ip_to_hex 172 16 2 2`
4090 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4091 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4093 echo "---------NB dump-----"
4095 echo "---------------------"
4096 ovn-nbctl list logical_router
4097 echo "---------------------"
4098 ovn-nbctl list logical_router_port
4099 echo "---------------------"
4101 echo "---------SB dump-----"
4102 ovn-sbctl list datapath_binding
4103 echo "---------------------"
4104 ovn-sbctl list port_binding
4105 echo "---------------------"
4107 echo "------ hv1 dump ----------"
4108 as hv1 ovs-ofctl dump-flows br-int
4109 echo "------ hv2 dump ----------"
4110 as hv2 ovs-ofctl dump-flows br-int
4112 # Packet to Expect at bob1
4113 src_mac="000000010205"
4114 dst_mac="f00000010205"
4115 src_ip=`ip_to_hex 192 168 1 2`
4116 dst_ip=`ip_to_hex 172 16 2 2`
4117 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4119 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4121 # Packet to Expect at alice1
4122 src_mac="000000010204"
4123 dst_mac="f00000010204"
4124 src_ip=`ip_to_hex 192 168 1 2`
4125 dst_ip=`ip_to_hex 172 16 1 2`
4126 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4128 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4130 OVN_CLEANUP([hv1],[hv2])
4134 AT_SETUP([ovn -- send gratuitous arp on localnet])
4135 AT_SKIP_IF([test $HAVE_PYTHON = no])
4137 ovn-nbctl ls-add lsw0
4145 ovn_attach n1 br-phys 192.168.0.1
4147 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
4148 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])
4151 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
4152 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
4153 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
4155 # Create a localnet port.
4156 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
4157 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
4158 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
4159 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
4161 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
4163 # Wait for packet to be received.
4164 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4165 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4167 # Check GARP packet when restart openflow connection.
4169 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4171 OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
4174 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4176 # Wait for packet to be received.
4177 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4178 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4180 # Delete the localnet ports.
4181 AT_CHECK([ovs-vsctl del-port localvif1])
4182 AT_CHECK([ovn-nbctl lsp-del ln_port])
4188 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
4189 AT_SKIP_IF([test $HAVE_PYTHON = no])
4193 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
4194 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4195 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
4202 ovn-nbctl ls-add foo
4203 ovn-nbctl ls-add alice
4204 ovn-nbctl ls-add bob
4205 ovn-nbctl ls-add join
4208 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4209 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4210 options:router-port=foo addresses=\"00:00:01:01:02:03\"
4212 # Connect alice to R2
4213 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4214 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4215 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4218 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
4219 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
4220 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
4222 # Connect R1 to join
4223 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4224 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4225 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4227 # Connect R2 to join
4228 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4229 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4230 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4232 # Connect R3 to join
4233 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
4234 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
4235 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
4237 #install static routes
4238 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4239 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
4241 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4242 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
4244 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4245 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
4247 # Create logical port foo1 in foo
4248 ovn-nbctl lsp-add foo foo1 \
4249 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4251 # Create logical port alice1 in alice
4252 ovn-nbctl lsp-add alice alice1 \
4253 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4255 # Create logical port bob1 in bob
4256 ovn-nbctl lsp-add bob bob1 \
4257 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
4259 # Create two hypervisor and create OVS ports corresponding to logical ports.
4264 ovs-vsctl add-br br-phys
4265 ovn_attach n1 br-phys 192.168.0.1
4266 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4267 set interface hv1-vif1 external-ids:iface-id=foo1 \
4268 options:tx_pcap=hv1/vif1-tx.pcap \
4269 options:rxq_pcap=hv1/vif1-rx.pcap \
4272 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4273 set interface hv1-vif2 external-ids:iface-id=alice1 \
4274 options:tx_pcap=hv1/vif2-tx.pcap \
4275 options:rxq_pcap=hv1/vif2-rx.pcap \
4280 ovs-vsctl add-br br-phys
4281 ovn_attach n1 br-phys 192.168.0.2
4282 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4283 set interface hv2-vif1 external-ids:iface-id=bob1 \
4284 options:tx_pcap=hv2/vif1-tx.pcap \
4285 options:rxq_pcap=hv2/vif1-rx.pcap \
4289 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4290 # packets for ARP resolution (native tunneling doesn't queue packets
4291 # for ARP resolution).
4294 # Allow some time for ovn-northd and ovn-controller to catch up.
4295 # XXX This should be more systematic.
4299 printf "%02x%02x%02x%02x" "$@"
4302 # Send ip packets between foo1 and alice1
4303 src_mac="f00000010203"
4304 dst_mac="000001010203"
4305 src_ip=`ip_to_hex 192 168 1 2`
4306 dst_ip=`ip_to_hex 172 16 1 2`
4307 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4308 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4309 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4311 # Send ip packets between foo1 and bob1
4312 src_mac="f00000010203"
4313 dst_mac="000001010203"
4314 src_ip=`ip_to_hex 192 168 1 2`
4315 dst_ip=`ip_to_hex 10 32 1 2`
4316 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4317 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4319 echo "---------NB dump-----"
4321 echo "---------------------"
4322 ovn-nbctl list logical_router
4323 echo "---------------------"
4324 ovn-nbctl list logical_router_port
4325 echo "---------------------"
4327 echo "---------SB dump-----"
4328 ovn-sbctl list datapath_binding
4329 echo "---------------------"
4330 ovn-sbctl list port_binding
4331 echo "---------------------"
4332 ovn-sbctl dump-flows
4333 echo "---------------------"
4335 echo "------ hv1 dump ----------"
4336 as hv1 ovs-ofctl show br-int
4337 as hv1 ovs-ofctl dump-flows br-int
4338 echo "------ hv2 dump ----------"
4339 as hv2 ovs-ofctl show br-int
4340 as hv2 ovs-ofctl dump-flows br-int
4341 echo "----------------------------"
4343 # Packet to Expect at bob1
4344 src_mac="000003010203"
4345 dst_mac="f00000010205"
4346 src_ip=`ip_to_hex 192 168 1 2`
4347 dst_ip=`ip_to_hex 10 32 1 2`
4348 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4350 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4352 # Packet to Expect at alice1
4353 src_mac="000002010203"
4354 dst_mac="f00000010204"
4355 src_ip=`ip_to_hex 192 168 1 2`
4356 dst_ip=`ip_to_hex 172 16 1 2`
4357 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
4359 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4361 OVN_CLEANUP([hv1],[hv2])
4365 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
4366 AT_SKIP_IF([test $HAVE_PYTHON = no])
4369 ovn-nbctl ls-add ls1
4371 ovn-nbctl lsp-add ls1 ls1-lp1 \
4372 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4374 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4376 ovn-nbctl lsp-add ls1 ls1-lp2 \
4377 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4379 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4381 ovn-nbctl ls-add ls2
4382 ovn-nbctl lsp-add ls2 ls2-lp1 \
4383 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4384 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4385 ovn-nbctl lsp-add ls2 ls2-lp2 \
4386 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4387 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4389 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
4390 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
4391 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
4393 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4394 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4396 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
4397 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
4398 \"lease_time\"=\"3600\"")"
4400 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
4406 ovs-vsctl add-br br-phys
4407 ovn_attach n1 br-phys 192.168.0.1
4408 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4409 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4410 options:tx_pcap=hv1/vif1-tx.pcap \
4411 options:rxq_pcap=hv1/vif1-rx.pcap \
4414 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4415 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4416 options:tx_pcap=hv1/vif2-tx.pcap \
4417 options:rxq_pcap=hv1/vif2-rx.pcap \
4420 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4421 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4422 options:tx_pcap=hv1/vif3-tx.pcap \
4423 options:rxq_pcap=hv1/vif3-rx.pcap \
4426 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4427 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4428 options:tx_pcap=hv1/vif4-tx.pcap \
4429 options:rxq_pcap=hv1/vif4-rx.pcap \
4436 as hv1 ovs-vsctl show
4438 # This shell function sends a DHCP request packet
4439 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP REQUEST_IP ...
4441 local inport=$1 src_mac=$2 dhcp_type=$3 ciaddr=$4 offer_ip=$5 request_ip=$6 use_ip=$7
4442 shift; shift; shift; shift; shift; shift; shift;
4443 if test $use_ip != 0; then
4448 src_ip=`ip_to_hex 0 0 0 0`
4449 dst_ip=`ip_to_hex 255 255 255 255`
4451 if test $request_ip != 0; then
4458 local request=ffffffffffff${src_mac}08004510${ip_len}0000000080110000${src_ip}${dst_ip}
4459 # udp header and dhcp header
4460 request=${request}00440043${udp_len}0000
4461 request=${request}010106006359aa7600000000${ciaddr}000000000000000000000000${src_mac}
4462 # client hardware padding
4463 request=${request}00000000000000000000
4465 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4466 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4468 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4469 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4470 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4471 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4473 request=${request}63825363
4475 request=${request}3501${dhcp_type}
4476 # dhcp unknown option
4477 request=${request}d70701020304050607
4479 request=${request}00
4480 if test $request_ip != 0; then
4482 request=${request}3204${request_ip}
4485 request=${request}ff
4487 for port in $inport "$@"; do
4490 if test $offer_ip != 0; then
4491 local srv_mac=$1 srv_ip=$2 dhcp_reply_type=$3 expected_dhcp_opts=$4
4492 # total IP length will be the IP length of the request packet
4493 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4494 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4495 udp_len=`expr $ip_len - 20`
4496 ip_len=$(printf "%x" $ip_len)
4497 udp_len=$(printf "%x" $udp_len)
4498 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4499 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4500 # udp header and dhcp header.
4501 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
4502 reply=${reply}004300440${udp_len}0000020106006359aa7600000000${ciaddr}
4503 # your ip address; 0 for NAK
4504 if test $dhcp_reply_type = 06; then
4505 reply=${reply}00000000
4507 reply=${reply}${offer_ip}
4509 # next server ip address, relay agent ip address, client mac address
4510 reply=${reply}0000000000000000${src_mac}
4511 # client hardware padding
4512 reply=${reply}00000000000000000000
4514 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4515 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4517 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4518 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4519 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4520 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4522 reply=${reply}63825363
4523 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
4524 echo $reply >> $inport.expected
4527 echo $request >> $outport.expected
4530 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4536 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4537 options:rxq_pcap=dummy-rx.pcap
4538 rm -f ${pcap_file}*.pcap
4539 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4540 options:rxq_pcap=${pcap_file}-rx.pcap
4544 printf "%02x%02x%02x%02x" "$@"
4547 AT_CAPTURE_FILE([ofctl_monitor0.log])
4548 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4549 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4551 echo "---------NB dump-----"
4553 echo "---------------------"
4554 echo "---------SB dump-----"
4555 ovn-sbctl list datapath_binding
4556 echo "---------------------"
4557 ovn-sbctl list logical_flow
4558 echo "---------------------"
4560 echo "---------------------"
4561 ovn-sbctl dump-flows
4562 echo "---------------------"
4564 echo "------ hv1 dump ----------"
4565 as hv1 ovs-ofctl dump-flows br-int
4567 # Send DHCPDISCOVER.
4568 offer_ip=`ip_to_hex 10 0 0 4`
4569 server_ip=`ip_to_hex 10 0 0 1`
4570 ciaddr=`ip_to_hex 0 0 0 0`
4572 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4573 test_dhcp 1 f00000000001 01 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 02 $expected_dhcp_opts
4575 # NXT_RESUMEs should be 1.
4576 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4578 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4579 cat 1.expected | cut -c -48 > expout
4580 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4581 # Skipping the IPv4 checksum.
4582 cat 1.expected | cut -c 53- > expout
4583 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4585 # ovs-ofctl also resumes the packets and this causes other ports to receive
4586 # the DHCP request packet. So reset the pcap files so that its easier to test.
4587 reset_pcap_file hv1-vif1 hv1/vif1
4588 reset_pcap_file hv1-vif2 hv1/vif2
4592 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with the offered IP
4593 # address in the Requested IP Address option.
4594 offer_ip=`ip_to_hex 10 0 0 6`
4595 server_ip=`ip_to_hex 10 0 0 1`
4596 ciaddr=`ip_to_hex 0 0 0 0`
4597 request_ip=$offer_ip
4598 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4599 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 05 $expected_dhcp_opts
4601 # NXT_RESUMEs should be 2.
4602 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4604 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4605 cat 2.expected | cut -c -48 > expout
4606 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4607 # Skipping the IPv4 checksum.
4608 cat 2.expected | cut -c 53- > expout
4609 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4611 reset_pcap_file hv1-vif1 hv1/vif1
4612 reset_pcap_file hv1-vif2 hv1/vif2
4616 # Send DHCPREQUEST in the SELECTING/INIT-REBOOT state with a mismatched IP in
4617 # the Requested IP Address option, expect a DHCPNAK.
4618 offer_ip=`ip_to_hex 10 0 0 6`
4619 server_ip=`ip_to_hex 10 0 0 1`
4620 ciaddr=`ip_to_hex 0 0 0 0`
4621 request_ip=`ip_to_hex 10 0 0 7`
4622 expected_dhcp_opts=""
4623 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 0 ff1000000001 $server_ip 06 $expected_dhcp_opts
4625 # NXT_RESUMEs should be 3.
4626 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4628 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4629 cat 2.expected | cut -c -48 > expout
4630 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4631 # Skipping the IPv4 checksum.
4632 cat 2.expected | cut -c 53- > expout
4633 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4635 reset_pcap_file hv1-vif1 hv1/vif1
4636 reset_pcap_file hv1-vif2 hv1/vif2
4640 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4641 # but should be resumed without the reply.
4642 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4643 # one from ovn-controller and the other from "ovs-ofctl resume."
4644 ciaddr=`ip_to_hex 0 0 0 0`
4647 test_dhcp 2 f00000000002 08 $ciaddr $offer_ip $request_ip 0 1 1
4649 # NXT_RESUMEs should be 4.
4650 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4652 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
4653 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4655 reset_pcap_file hv1-vif1 hv1/vif1
4656 reset_pcap_file hv1-vif2 hv1/vif2
4660 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4661 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4663 ciaddr=`ip_to_hex 0 0 0 0`
4664 test_dhcp 3 f00000000003 01 $ciaddr 0 0 4 0
4666 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4668 ciaddr=`ip_to_hex 0 0 0 0`
4669 test_dhcp 4 f00000000004 01 $ciaddr 0 0 3 0
4671 # NXT_RESUMEs should be 4.
4672 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4674 #OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4675 #OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4677 # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4678 # and ip4.dst set to 10.0.0.1.
4679 offer_ip=`ip_to_hex 10 0 0 6`
4680 server_ip=`ip_to_hex 10 0 0 1`
4685 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4686 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4688 # NXT_RESUMEs should be 5.
4689 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4691 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4692 cat 2.expected | cut -c -48 > expout
4693 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4694 # Skipping the IPv4 checksum.
4695 cat 2.expected | cut -c 53- > expout
4696 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4698 reset_pcap_file hv1-vif1 hv1/vif1
4699 reset_pcap_file hv1-vif2 hv1/vif2
4703 # Send DHCPREQUEST in the RENEWING/REBINDING state with ip4.src set to 10.0.0.6
4704 # and ip4.dst set to 255.255.255.255.
4705 offer_ip=`ip_to_hex 10 0 0 6`
4706 server_ip=`ip_to_hex 10 0 0 1`
4710 dst_ip=`ip_to_hex 255 255 255 255`
4711 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4712 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 05 $expected_dhcp_opts
4714 # NXT_RESUMEs should be 6.
4715 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4717 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4718 cat 2.expected | cut -c -48 > expout
4719 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4720 # Skipping the IPv4 checksum.
4721 cat 2.expected | cut -c 53- > expout
4722 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4724 reset_pcap_file hv1-vif1 hv1/vif1
4725 reset_pcap_file hv1-vif2 hv1/vif2
4729 # Send DHCPREQUEST in the RENEWING/REBINDING state with a mismatched IP in the
4730 # ciaddr, expect a DHCPNAK.
4731 offer_ip=`ip_to_hex 10 0 0 6`
4732 server_ip=`ip_to_hex 10 0 0 1`
4733 ciaddr=`ip_to_hex 10 0 0 7`
4736 dst_ip=`ip_to_hex 255 255 255 255`
4737 expected_dhcp_opts=""
4738 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4740 # NXT_RESUMEs should be 7.
4741 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4743 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4744 cat 2.expected | cut -c -48 > expout
4745 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4746 # Skipping the IPv4 checksum.
4747 cat 2.expected | cut -c 53- > expout
4748 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4750 reset_pcap_file hv1-vif1 hv1/vif1
4751 reset_pcap_file hv1-vif2 hv1/vif2
4755 # Send DHCPREQUEST in the RENEWING/REBINDING state without a specifyied ciaddr,
4757 offer_ip=`ip_to_hex 10 0 0 6`
4758 server_ip=`ip_to_hex 10 0 0 1`
4759 ciaddr=`ip_to_hex 0 0 0 0`
4762 dst_ip=`ip_to_hex 255 255 255 255`
4763 expected_dhcp_opts=""
4764 test_dhcp 2 f00000000002 03 $ciaddr $offer_ip $request_ip 1 $src_ip $dst_ip ff1000000001 $server_ip 06 $expected_dhcp_opts
4766 # NXT_RESUMEs should be 8.
4767 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4770 cat 2.expected | cut -c -48 > expout
4771 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4772 # Skipping the IPv4 checksum.
4773 cat 2.expected | cut -c 53- > expout
4774 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4776 reset_pcap_file hv1-vif1 hv1/vif1
4777 reset_pcap_file hv1-vif2 hv1/vif2
4781 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4782 # The packet should not be received by ovn-controller.
4783 ciaddr=`ip_to_hex 0 0 0 0`
4784 src_ip=`ip_to_hex 10 0 0 6`
4785 dst_ip=`ip_to_hex 10 0 0 4`
4786 test_dhcp 2 f00000000002 03 $ciaddr 0 0 1 $src_ip $dst_ip 1
4788 # NXT_RESUMEs should be 8.
4789 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4791 # vif1-tx.pcap should have received the DHCPv4 request packet
4792 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4798 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4799 AT_SKIP_IF([test $HAVE_PYTHON = no])
4802 ovn-nbctl ls-add ls1
4803 ovn-nbctl lsp-add ls1 ls1-lp1 \
4804 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4806 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4808 ovn-nbctl lsp-add ls1 ls1-lp2 \
4809 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4811 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4813 ovn-nbctl lsp-add ls1 ls1-lp3 \
4814 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4816 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4818 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4819 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4821 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4822 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4824 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4825 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4827 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4829 ovn-nbctl ls-add ls2
4830 ovn-nbctl lsp-add ls2 ls2-lp1 \
4831 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4832 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4833 ovn-nbctl lsp-add ls2 ls2-lp2 \
4834 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4835 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4841 ovs-vsctl add-br br-phys
4842 ovn_attach n1 br-phys 192.168.0.1
4843 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4844 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4845 options:tx_pcap=hv1/vif1-tx.pcap \
4846 options:rxq_pcap=hv1/vif1-rx.pcap \
4849 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4850 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4851 options:tx_pcap=hv1/vif2-tx.pcap \
4852 options:rxq_pcap=hv1/vif2-rx.pcap \
4855 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4856 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4857 options:tx_pcap=hv1/vif3-tx.pcap \
4858 options:rxq_pcap=hv1/vif3-rx.pcap \
4861 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4862 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4863 options:tx_pcap=hv1/vif4-tx.pcap \
4864 options:rxq_pcap=hv1/vif4-rx.pcap \
4867 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4868 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4869 options:tx_pcap=hv1/vif5-tx.pcap \
4870 options:rxq_pcap=hv1/vif5-rx.pcap \
4878 sed 's/\(00\)\{1,\}$//'
4881 # This shell function sends a DHCPv6 request packet
4882 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4883 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4884 # packet should be received twice (one from ovn-controller and the other
4885 # from the "ovs-ofctl monitor br-int resume"
4887 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4888 if test $msg_code != 0b; then
4893 local request=ffffffffffff${src_mac}86dd0000000000${req_len}1101${src_lla}
4895 request=${request}ff020000000000000000000000010002
4896 # udp header and dhcpv6 header
4897 request=${request}0222022300${req_len}ffff${msg_code}010203
4899 request=${request}0001000a00030001${src_mac}
4900 # Add IA-NA (Identity Association for Non Temporary Address) if msg_code
4901 # is not 11 (information request packet)
4902 if test $msg_code != 0b; then
4903 request=${request}0003000c0102030400000e1000001518
4905 shift; shift; shift; shift; shift;
4906 if test $offer_ip != 0; then
4907 local server_mac=000000100001
4908 local server_lla=fe80000000000000020000fffe100001
4910 if test $msg_code = 01; then
4914 if test $offer_ip = 1; then
4917 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4918 # udp header and dhcpv6 header
4919 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4921 reply=${reply}0001000a00030001${src_mac}
4923 if test $offer_ip != 1; then
4924 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4927 reply=${reply}0002000a00030001${server_mac}
4928 echo $reply | trim_zeros >> $inport.expected
4931 echo $request | trim_zeros >> $outport.expected
4935 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4941 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4942 options:rxq_pcap=dummy-rx.pcap
4943 rm -f ${pcap_file}*.pcap
4944 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4945 options:rxq_pcap=${pcap_file}-rx.pcap
4948 AT_CAPTURE_FILE([ofctl_monitor0.log])
4949 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4950 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4952 echo "---------NB dump-----"
4954 echo "---------------------"
4955 echo "---------SB dump-----"
4956 ovn-sbctl list datapath_binding
4957 echo "---------------------"
4958 ovn-sbctl list logical_flow
4959 echo "---------------------"
4961 echo "---------------------"
4962 ovn-sbctl dump-flows
4963 echo "---------------------"
4965 echo "------ hv1 dump ----------"
4966 as hv1 ovs-ofctl dump-flows br-int
4968 src_mac=f00000000001
4969 src_lla=fe80000000000000f20000fffe000001
4970 offer_ip=ae700000000000000000000000000004
4971 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4973 # NXT_RESUMEs should be 1.
4974 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4976 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4977 # cat 1.expected | trim_zeros > expout
4978 cat 1.expected | cut -c -120 > expout
4979 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4980 # Skipping the UDP checksum
4981 cat 1.expected | cut -c 125- > expout
4982 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4986 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4987 # without any modifications and the packet should be received by ls1-lp1.
4988 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4989 # resume and the other from ovs-ofctl monitor resume.
4991 reset_pcap_file hv1-vif1 hv1/vif1
4992 reset_pcap_file hv1-vif2 hv1/vif2
4994 src_mac=f00000000002
4995 src_lla=fe80000000000000f20000fffe000002
4996 offer_ip=ae700000000000000000000000000005
4997 # Set invalid msg_type
4999 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
5001 # NXT_RESUMEs should be 2.
5002 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5004 # vif2-tx.pcap should not have received the DHCPv6 reply packet
5006 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
5007 AT_CHECK([cat 2.packets], [0], [])
5009 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
5010 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
5011 cat 1.expected > expout
5012 AT_CHECK([cat 1.packets], [0], [expout])
5014 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
5015 # There should be no DHCPv6 reply from ovn-controller and the request packet
5016 # should be received by ls2-lp2.
5018 src_mac=f00000000003
5019 src_lla=fe80000000000000f20000fffe000003
5020 test_dhcpv6 3 $src_mac $src_lla 01 0 4
5022 # NXT_RESUMEs should be 2 only.
5023 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5025 # vif3-tx.pcap should not have received the DHCPv6 reply packet
5026 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
5027 AT_CHECK([cat 3.packets], [0], [])
5029 # vif4-tx.pcap should have received the DHCPv6 request packet
5030 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
5031 cat 4.expected > expout
5032 AT_CHECK([cat 4.packets], [0], [expout])
5034 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
5035 # The DHCPv6 reply shouldn't contain offer_ip.
5036 src_mac=f00000000022
5037 src_lla=fe80000000000000f20000fffe000022
5038 reset_pcap_file hv1-vif5 hv1/vif5
5039 test_dhcpv6 5 $src_mac $src_lla 01 1 5
5041 # NXT_RESUMEs should be 3.
5042 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5044 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
5045 # Skipping the UDP checksum
5046 cat 5.expected | cut -c 1-120,125- > expout
5047 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5049 # Send DHCPv6 information request (code 11) on ls1-lp3. The DHCPv6 reply
5050 # shouldn't contain offer_ip
5051 src_mac=f00000000022
5052 src_lla=fe80000000000000f20000fffe000022
5053 reset_pcap_file hv1-vif5 hv1/vif5
5055 test_dhcpv6 5 $src_mac $src_lla 0b 1 5
5057 # NXT_RESUMEs should be 4.
5058 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
5060 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap |
5061 trim_zeros > 5.packets
5062 # Skipping the UDP checksum
5063 cat 5.expected | cut -c 1-120,125- > expout
5064 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
5070 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
5071 AT_SKIP_IF([test $HAVE_PYTHON = no])
5075 # Two LRs - R1 and R2 that are connected to each other via LS "join"
5076 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
5077 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
5078 # R2 is a gateway router.
5082 # Create two hypervisor and create OVS ports corresponding to logical ports.
5087 ovs-vsctl add-br br-phys
5088 ovn_attach n1 br-phys 192.168.0.1
5089 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5090 set interface hv1-vif1 external-ids:iface-id=foo1 \
5091 options:tx_pcap=hv1/vif1-tx.pcap \
5092 options:rxq_pcap=hv1/vif1-rx.pcap \
5098 ovs-vsctl add-br br-phys
5099 ovn_attach n1 br-phys 192.168.0.2
5100 ovs-vsctl -- add-port br-int hv2-vif1 -- \
5101 set interface hv2-vif1 external-ids:iface-id=alice1 \
5102 options:tx_pcap=hv2/vif1-tx.pcap \
5103 options:rxq_pcap=hv2/vif1-rx.pcap \
5106 # Pre-populate the hypervisors' ARP tables so that we don't lose any
5107 # packets for ARP resolution (native tunneling doesn't queue packets
5108 # for ARP resolution).
5111 ovn-nbctl create Logical_Router name=R1
5112 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5114 ovn-nbctl ls-add foo
5115 ovn-nbctl ls-add alice
5116 ovn-nbctl ls-add join
5119 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5120 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5121 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5123 # Connect alice to R2
5124 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5125 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
5126 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
5128 # Connect R1 to join
5129 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
5130 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
5131 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
5133 # Connect R2 to join
5134 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5135 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
5136 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
5139 #install static routes
5140 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5141 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
5142 R1 static_routes @lrt
5144 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5145 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5146 R2 static_routes @lrt
5148 # Create logical port foo1 in foo
5149 ovn-nbctl lsp-add foo foo1 \
5150 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5152 # Create logical port alice1 in alice
5153 ovn-nbctl lsp-add alice alice1 \
5154 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
5157 # Allow some time for ovn-northd and ovn-controller to catch up.
5158 # XXX This should be more systematic.
5162 printf "%02x%02x%02x%02x" "$@"
5165 # Send ip packets between foo1 and alice1
5166 src_mac="f00000010203"
5167 dst_mac="000001010203"
5168 src_ip=`ip_to_hex 192 168 1 2`
5169 dst_ip=`ip_to_hex 172 16 1 2`
5170 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5172 echo "---------NB dump-----"
5174 echo "---------------------"
5175 ovn-nbctl list logical_router
5176 echo "---------------------"
5177 ovn-nbctl list logical_router_port
5178 echo "---------------------"
5180 echo "---------SB dump-----"
5181 ovn-sbctl list datapath_binding
5182 echo "---------------------"
5183 ovn-sbctl list port_binding
5184 echo "---------------------"
5185 ovn-sbctl dump-flows
5186 echo "---------------------"
5187 ovn-sbctl list chassis
5188 ovn-sbctl list encap
5189 echo "---------------------"
5191 # Packet to Expect at alice1
5192 src_mac="000002010203"
5193 dst_mac="f00000010204"
5194 src_ip=`ip_to_hex 192 168 1 2`
5195 dst_ip=`ip_to_hex 172 16 1 2`
5196 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
5199 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5200 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
5202 echo "------ hv1 dump after packet 1 ----------"
5203 as hv1 ovs-ofctl show br-int
5204 as hv1 ovs-ofctl dump-flows br-int
5205 echo "------ hv2 dump after packet 1 ----------"
5206 as hv2 ovs-ofctl show br-int
5207 as hv2 ovs-ofctl dump-flows br-int
5208 echo "----------------------------"
5210 echo $expected > expected
5211 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
5213 # Delete the router and re-create it. Things should work as before.
5215 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
5216 # Connect alice to R2
5217 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
5218 # Connect R2 to join
5219 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
5221 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
5222 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
5223 R2 static_routes @lrt
5225 # Wait for ovn-controller to catch up.
5228 # Send the packet again.
5229 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5231 echo "------ hv1 dump after packet 2 ----------"
5232 as hv1 ovs-ofctl show br-int
5233 as hv1 ovs-ofctl dump-flows br-int
5234 echo "------ hv2 dump after packet 2 ----------"
5235 as hv2 ovs-ofctl show br-int
5236 as hv2 ovs-ofctl dump-flows br-int
5237 echo "----------------------------"
5239 echo $expected >> expected
5240 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
5242 OVN_CLEANUP([hv1],[hv2])
5246 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5247 AT_KEYWORDS([router-icmp-reply])
5248 AT_SKIP_IF([test $HAVE_PYTHON = no])
5252 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5253 # and has switch ls2 (172.16.1.0/24) connected to it.
5257 ovn-nbctl ls-add ls1
5258 ovn-nbctl ls-add ls2
5261 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5262 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5263 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5266 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5267 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5268 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5270 # Create logical port ls1-lp1 in ls1
5271 ovn-nbctl lsp-add ls1 ls1-lp1 \
5272 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5274 # Create logical port ls2-lp1 in ls2
5275 ovn-nbctl lsp-add ls2 ls2-lp1 \
5276 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5278 # Create one hypervisor and create OVS ports corresponding to logical ports.
5283 ovs-vsctl add-br br-phys
5284 ovn_attach n1 br-phys 192.168.0.1
5285 ovs-vsctl -- add-port br-int vif1 -- \
5286 set interface vif1 external-ids:iface-id=ls1-lp1 \
5287 options:tx_pcap=hv1/vif1-tx.pcap \
5288 options:rxq_pcap=hv1/vif1-rx.pcap \
5291 ovs-vsctl -- add-port br-int vif2 -- \
5292 set interface vif2 external-ids:iface-id=ls2-lp1 \
5293 options:tx_pcap=hv1/vif2-tx.pcap \
5294 options:rxq_pcap=hv1/vif2-rx.pcap \
5298 # Allow some time for ovn-northd and ovn-controller to catch up.
5299 # XXX This should be more systematic.
5304 printf "%02x%02x%02x%02x" "$@"
5309 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5311 # Causes a packet to be received on INPORT. The packet is an ICMPv4
5312 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5313 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5314 # provided, then it should be the ip and icmp checksums of the packet
5315 # responded; otherwise, no reply is expected.
5316 # In the absence of an ip checksum calculation helpers, this relies
5317 # on the caller to provide the checksums for the ip and icmp headers.
5318 # XXX This should be more systematic.
5320 # INPORT is an lport number, e.g. 11 for vif11.
5321 # ETH_SRC and ETH_DST are each 12 hex digits.
5322 # IPV4_SRC and IPV4_DST are each 8 hex digits.
5323 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5324 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5325 test_ipv4_icmp_request() {
5326 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5327 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5328 shift; shift; shift; shift; shift; shift; shift
5331 # Use ttl to exercise section 4.2.2.9 of RFC1812
5335 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5336 local icmp_type_code_request=0800
5337 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5338 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5340 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5341 if test X$exp_icmp_chksum != X; then
5342 # Expect to receive the reply, if any. In same port where packet was sent.
5343 # Note: src and dst fields are expected to be reversed.
5344 local icmp_type_code_response=0000
5345 local reply_icmp_ttl=fe
5346 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5347 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5348 echo $reply >> vif$inport.expected
5352 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
5353 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5354 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5355 l1_ip=$(ip_to_hex 192 168 1 2)
5356 l2_ip=$(ip_to_hex 172 16 1 2)
5358 # Ping router ip address that is on same subnet as the logical port
5359 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5360 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5362 # Ping router ip address that is on the other side of the logical ports
5363 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5364 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5367 echo "---------NB dump-----"
5369 echo "---------------------"
5370 ovn-nbctl list logical_router
5371 echo "---------------------"
5372 ovn-nbctl list logical_router_port
5373 echo "---------------------"
5375 echo "---------SB dump-----"
5376 ovn-sbctl list datapath_binding
5377 echo "---------------------"
5378 ovn-sbctl list logical_flow
5379 echo "---------------------"
5381 echo "------ hv1 dump ----------"
5382 as hv1 ovs-ofctl dump-flows br-int
5384 # Now check the packets actually received against the ones expected.
5385 for inport in 1 2; do
5386 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
5392 AT_SETUP([ovn -- policy-based routing: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
5393 AT_KEYWORDS([policy-based-routing])
5394 AT_SKIP_IF([test $HAVE_PYTHON = no])
5398 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5399 # and has switch ls2 (172.16.1.0/24) connected to it.
5403 ovn-nbctl ls-add ls1
5404 ovn-nbctl ls-add ls2
5405 ovn-nbctl ls-add ls3
5408 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
5409 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5410 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5413 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
5414 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5415 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5418 ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 20.20.1.1/24
5419 ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5420 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5422 # Create logical port ls1-lp1 in ls1
5423 ovn-nbctl lsp-add ls1 ls1-lp1 \
5424 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
5426 # Create logical port ls2-lp1 in ls2
5427 ovn-nbctl lsp-add ls2 ls2-lp1 \
5428 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
5430 # Create logical port ls3-lp1 in ls3
5431 ovn-nbctl lsp-add ls3 ls3-lp1 \
5432 -- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 20.20.1.2"
5434 # Create one hypervisor and create OVS ports corresponding to logical ports.
5439 ovs-vsctl add-br br-phys
5440 ovn_attach n1 br-phys 192.168.0.1
5442 ovs-vsctl -- add-port br-int vif1 -- \
5443 set interface vif1 external-ids:iface-id=ls1-lp1 \
5444 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5445 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5448 ovs-vsctl -- add-port br-int vif2 -- \
5449 set interface vif2 external-ids:iface-id=ls2-lp1 \
5450 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5451 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5454 ovs-vsctl -- add-port br-int vif3 -- \
5455 set interface vif3 external-ids:iface-id=ls3-lp1 \
5456 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5457 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5460 # Allow some time for ovn-northd and ovn-controller to catch up.
5461 # XXX This should be more systematic.
5464 ls1_ro_mac=00:00:00:01:02:f1
5465 ls1_ro_ip=192.168.1.1
5467 ls2_ro_mac=00:00:00:01:02:f2
5468 ls2_ro_ip=172.16.1.1
5470 ls3_ro_mac=00:00:00:01:02:f3
5472 ls1_p1_mac=00:00:00:01:02:03
5473 ls1_p1_ip=192.168.1.2
5475 ls2_p1_mac=00:00:00:01:02:04
5476 ls2_p1_ip=172.16.1.2
5478 ls3_p1_mac=00:00:00:01:02:05
5480 # Create a drop policy
5481 ovn-nbctl lr-policy-add R1 10 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" drop
5483 # Check logical flow
5484 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
5489 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5490 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5491 udp && udp.src==53 && udp.dst==4369"
5493 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5495 # Check if packet hit the drop policy
5496 AT_CHECK([ovs-ofctl dump-flows br-int | \
5497 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24 actions=drop" | \
5498 grep "priority=10" | \
5499 grep "n_packets=1" | wc -l], [0], [dnl
5503 # Expected to drop the packet.
5504 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5505 rcvd_packet=`cat vif2.packets`
5506 AT_FAIL_IF([rcvd_packet = ""])
5508 # Override drop policy with allow
5509 ovn-nbctl lr-policy-add R1 20 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" allow
5511 # Check logical flow
5512 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "192.168.1.0" | wc -l], [0], [dnl
5517 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5518 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5519 udp && udp.src==53 && udp.dst==4369"
5520 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5522 # Check if packet hit the allow policy
5523 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5524 grep "192.168.1.0" | \
5525 grep "priority=20" | wc -l], [0], [dnl
5529 # Expected packet has TTL decreased by 1
5530 expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5531 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5532 udp && udp.src==53 && udp.dst==4369"
5533 echo $expected | ovstest test-ovn expr-to-packets > expected
5535 OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5537 # Override allow policy with reroute
5538 ovn-nbctl lr-policy-add R1 30 "ip4.src==192.168.1.0/24 && ip4.dst==172.16.1.0/24" reroute 20.20.1.2
5540 # Check logical flow
5541 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5542 grep "192.168.1.0" | \
5543 grep "priority=30" | wc -l], [0], [dnl
5548 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5549 ip4 && ip.ttl==64 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5550 udp && udp.src==53 && udp.dst==4369"
5551 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5553 echo "southbound flows"
5555 ovn-sbctl dump-flows | grep lr_in_policy
5557 ovs-ofctl dump-flows br-int
5558 # Check if packet hit the allow policy
5559 AT_CHECK([ovs-ofctl dump-flows br-int | \
5560 grep "nw_src=192.168.1.0/24,nw_dst=172.16.1.0/24" | \
5561 grep "priority=30" | \
5562 grep "n_packets=1" | wc -l], [0], [dnl
5565 echo "packet hit reroute policy"
5567 # Expected packet has TTL decreased by 1
5568 expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5569 ip4 && ip.ttl==63 && ip4.src==$ls1_p1_ip && ip4.dst==$ls2_p1_ip &&
5570 udp && udp.src==53 && udp.dst==4369"
5571 echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5573 OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5575 OVN_CLEANUP([pbr-hv])
5578 AT_SETUP([ovn -- policy-based routing IPv6: 1 HVs, 3 LSs, 1 lport/LS, 1 LR])
5579 AT_KEYWORDS([policy-based-routing])
5580 AT_SKIP_IF([test $HAVE_PYTHON = no])
5584 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
5585 # and has switch ls2 (172.16.1.0/24) connected to it.
5589 ovn-nbctl ls-add ls1
5590 ovn-nbctl ls-add ls2
5591 ovn-nbctl ls-add ls3
5594 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 2001::1/64
5595 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
5596 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
5599 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 2002::1/64
5600 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
5601 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
5604 ovn-nbctl lrp-add R1 ls3 00:00:00:01:02:f3 2003::1/64
5605 ovn-nbctl lsp-add ls3 rp-ls3 -- set Logical_Switch_Port rp-ls3 \
5606 type=router options:router-port=ls3 addresses=\"00:00:00:01:02:f3\"
5608 # Create logical port ls1-lp1 in ls1
5609 ovn-nbctl lsp-add ls1 ls1-lp1 \
5610 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 2001::2"
5612 # Create logical port ls2-lp1 in ls2
5613 ovn-nbctl lsp-add ls2 ls2-lp1 \
5614 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 2002::2"
5616 # Create logical port ls3-lp1 in ls3
5617 ovn-nbctl lsp-add ls3 ls3-lp1 \
5618 -- lsp-set-addresses ls3-lp1 "00:00:00:01:02:05 2003::2"
5620 # Create one hypervisor and create OVS ports corresponding to logical ports.
5625 ovs-vsctl add-br br-phys
5626 ovn_attach n1 br-phys 192.168.0.1
5628 ovs-vsctl -- add-port br-int vif1 -- \
5629 set interface vif1 external-ids:iface-id=ls1-lp1 \
5630 options:tx_pcap=pbr-hv/vif1-tx.pcap \
5631 options:rxq_pcap=pbr-hv/vif1-rx.pcap \
5634 ovs-vsctl -- add-port br-int vif2 -- \
5635 set interface vif2 external-ids:iface-id=ls2-lp1 \
5636 options:tx_pcap=pbr-hv/vif2-tx.pcap \
5637 options:rxq_pcap=pbr-hv/vif2-rx.pcap \
5640 ovs-vsctl -- add-port br-int vif3 -- \
5641 set interface vif3 external-ids:iface-id=ls3-lp1 \
5642 options:tx_pcap=pbr-hv/vif3-tx.pcap \
5643 options:rxq_pcap=pbr-hv/vif3-rx.pcap \
5646 # Allow some time for ovn-northd and ovn-controller to catch up.
5647 # XXX This should be more systematic.
5650 ls1_ro_mac=00:00:00:01:02:f1
5653 ls2_ro_mac=00:00:00:01:02:f2
5656 ls3_ro_mac=00:00:00:01:02:f3
5658 ls1_p1_mac=00:00:00:01:02:03
5661 ls2_p1_mac=00:00:00:01:02:04
5664 ls3_p1_mac=00:00:00:01:02:05
5666 # Create a drop policy
5667 ovn-nbctl lr-policy-add R1 10 "ip6.src==2001::/64 && ip6.dst==2002::/64" drop
5669 # Check logical flow
5670 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
5675 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5676 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5677 udp && udp.src==53 && udp.dst==4369"
5679 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5681 # Check if packet hit the drop policy
5682 AT_CHECK([ovs-ofctl dump-flows br-int | \
5683 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64 actions=drop" | \
5684 grep "priority=10" | \
5685 grep "n_packets=1" | wc -l], [0], [dnl
5689 # Expected to drop the packet.
5690 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" pbr-hv/vif2-tx.pcap > vif2.packets
5691 rcvd_packet=`cat vif2.packets`
5692 AT_FAIL_IF([rcvd_packet = ""])
5694 # Override drop policy with allow
5695 ovn-nbctl lr-policy-add R1 20 "ip6.src==2001::/64 && ip6.dst==2002::/64" allow
5697 # Check logical flow
5698 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | grep "2001" | wc -l], [0], [dnl
5703 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5704 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5705 udp && udp.src==53 && udp.dst==4369"
5706 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5708 # Check if packet hit the allow policy
5709 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5711 grep "priority=20" | wc -l], [0], [dnl
5715 # Expected packet has TTL decreased by 1
5716 expected="eth.src==$ls2_ro_mac && eth.dst==$ls2_p1_mac &&
5717 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5718 udp && udp.src==53 && udp.dst==4369"
5719 echo $expected | ovstest test-ovn expr-to-packets > expected
5721 OVN_CHECK_PACKETS([pbr-hv/vif2-tx.pcap], [expected])
5723 # Override allow policy with reroute
5724 ovn-nbctl lr-policy-add R1 30 "ip6.src==2001::/64 && ip6.dst==2002::/64" reroute 2003::2
5726 # Check logical flow
5727 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_policy | \
5729 grep "priority=30" | wc -l], [0], [dnl
5734 packet="inport==\"ls1-lp1\" && eth.src==$ls1_p1_mac && eth.dst==$ls1_ro_mac &&
5735 ip6 && ip.ttl==64 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5736 udp && udp.src==53 && udp.dst==4369"
5737 as pbr-hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5739 echo "southbound flows"
5741 ovn-sbctl dump-flows | grep lr_in_policy
5743 ovs-ofctl dump-flows br-int
5744 # Check if packet hit the allow policy
5745 AT_CHECK([ovs-ofctl dump-flows br-int | \
5746 grep "ipv6_src=2001::/64,ipv6_dst=2002::/64" | \
5747 grep "priority=30" | \
5748 grep "n_packets=1" | wc -l], [0], [dnl
5751 echo "packet hit reroute policy"
5753 # Expected packet has TTL decreased by 1
5754 expected="eth.src==$ls3_ro_mac && eth.dst==$ls3_p1_mac &&
5755 ip6 && ip.ttl==63 && ip6.src==$ls1_p1_ip && ip6.dst==$ls2_p1_ip &&
5756 udp && udp.src==53 && udp.dst==4369"
5757 echo $expected | ovstest test-ovn expr-to-packets > 3.expected
5759 OVN_CHECK_PACKETS([pbr-hv/vif3-tx.pcap], [3.expected])
5761 OVN_CLEANUP([pbr-hv])
5764 # 1 hypervisor, 1 port
5765 # make sure that the port state is properly set to up and back down
5766 # when created and deleted.
5767 AT_SETUP([ovn -- port state up and down])
5770 ovn-nbctl ls-add ls1
5771 ovn-nbctl lsp-add ls1 lp1
5772 ovn-nbctl lsp-set-addresses lp1 unknown
5776 as hv1 ovs-vsctl add-br br-phys
5777 as hv1 ovn_attach n1 br-phys 192.168.0.1
5779 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5780 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5782 as hv1 ovs-vsctl del-port br-int vif1
5783 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5789 # 1 hypervisor, 1 port
5790 # make sure that the OF rules created to support a datapath are added/cleared
5791 # when logical switch is created and removed.
5792 AT_SETUP([ovn -- datapath rules added/removed])
5793 AT_KEYWORDS([cleanup])
5798 as hv1 ovs-vsctl add-br br-phys
5799 as hv1 ovn_attach n1 br-phys 192.168.0.1
5801 # This shell function checks if OF rules in br-int have clauses
5802 # related to OVN datapaths. The caller determines if it should find
5803 # a match in the output, or not.
5805 # EXPECT_DATAPATH param determines whether flows that refer to
5806 # datapath to should be present or not. 0 means
5807 # they should not be.
5808 # STAGE_INFO param is a simple string to help identify the stage
5809 # in the test when this function was invoked.
5810 test_datapath_in_of_rules() {
5811 local expect_datapath=$1 stage_info=$2
5812 echo "------ ovn-nbctl show ${stage_info} ------"
5814 echo "------ ovn-sbctl show ${stage_info} ------"
5816 echo "------ OF rules ${stage_info} ------"
5817 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5818 # if there is a datapath mentioned in the output, check for the
5819 # magic keyword that represents one, based on the exit status of
5821 if test $expect_datapath != 0; then
5822 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
5824 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
5828 test_datapath_in_of_rules 0 "before ls+port create"
5830 ovn-nbctl ls-add ls1
5831 ovn-nbctl lsp-add ls1 lp1
5832 ovn-nbctl lsp-set-addresses lp1 unknown
5834 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5835 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5837 test_datapath_in_of_rules 1 "after port is bound"
5839 as hv1 ovs-vsctl del-port br-int vif1
5840 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5842 ovn-nbctl lsp-set-addresses lp1
5843 ovn-nbctl lsp-del lp1
5844 ovn-nbctl ls-del ls1
5846 # wait for earlier changes to take effect
5847 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5849 # ensure OF rules are no longer present. There used to be a bug here.
5850 test_datapath_in_of_rules 0 "after lport+ls removal"
5856 AT_SETUP([ovn -- nd_na ])
5857 AT_SKIP_IF([test $HAVE_PYTHON = no])
5860 #TODO: since patch port for IPv6 logical router port is not ready not,
5861 # so we are not going to test vifs on different lswitches cases. Try
5862 # to update for that once relevant stuff implemented.
5864 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
5865 # with. NS packet we test, from one VIF for another VIF, will be replied
5866 # by local ovn-controller, but not by target VIF.
5868 # Create hypervisors and logical switch lsw0.
5869 ovn-nbctl ls-add lsw0
5873 ovs-vsctl add-br br-phys
5874 ovn_attach n1 br-phys 192.168.0.2
5876 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5877 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
5878 ovn-nbctl lsp-add lsw0 lp1
5879 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5880 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"
5882 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5883 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
5884 ovn-nbctl lsp-add lsw0 lp2
5885 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5886 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"
5888 # Add ACL rule for ICMPv6 on lsw0
5889 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5890 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5891 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5893 # Allow some time for ovn-northd and ovn-controller to catch up.
5894 # XXX This should be more systematic.
5897 # Given the name of a logical port, prints the name of the hypervisor
5898 # on which it is located.
5906 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5907 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5908 # vif2 will not receive NS packet, since ovn-controller will reply for it.
5909 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5910 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5912 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
5913 echo $na_packet >> 1.expected
5915 echo "------ hv1 dump ------"
5916 as hv1 ovs-vsctl show
5917 as hv1 ovs-ofctl -O OpenFlow13 show br-int
5918 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5921 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
5928 AT_SETUP([ovn -- address sets modification/removal smoke test])
5935 ovs-vsctl add-br br-phys
5936 ovn_attach n1 br-phys 192.168.0.1
5938 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5939 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5940 ovn-nbctl destroy Address_Set $row
5944 # A bug previously existed in the address set support code
5945 # that caused ovn-controller to crash after an address set
5946 # was updated and then removed. This test case ensures
5947 # that ovn-controller is at least still running after
5948 # creating, updating, and deleting an address set.
5949 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5955 AT_SETUP([ovn -- ipam])
5956 AT_SKIP_IF([test $HAVE_PYTHON = no])
5959 # Add a port to a switch that does not have a subnet set, then set the
5960 # subnet which should result in an address being allocated for the port.
5961 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
5962 ovn-nbctl ls-add sw0
5963 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
5964 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
5965 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5966 ["0a:00:00:a8:01:03 192.168.1.2"
5969 # Add 9 more ports to sw0, addresses should all be unique.
5970 for n in `seq 1 9`; do
5971 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
5973 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5974 ["0a:00:00:a8:01:04 192.168.1.3"
5976 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5977 ["0a:00:00:a8:01:05 192.168.1.4"
5979 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5980 ["0a:00:00:a8:01:06 192.168.1.5"
5982 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5983 ["0a:00:00:a8:01:07 192.168.1.6"
5985 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5986 ["0a:00:00:a8:01:08 192.168.1.7"
5988 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5989 ["0a:00:00:a8:01:09 192.168.1.8"
5991 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5992 ["0a:00:00:a8:01:0a 192.168.1.9"
5994 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5995 ["0a:00:00:a8:01:0b 192.168.1.10"
5997 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5998 ["0a:00:00:a8:01:0c 192.168.1.11"
6001 # Trying similar tests with a second switch. MAC addresses should be unique
6002 # across both switches but IP's only need to be unique within the same switch.
6003 ovn-nbctl ls-add sw1
6004 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
6005 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
6006 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
6007 ["0a:00:00:a8:01:0d 192.168.1.2"
6010 for n in `seq 11 19`; do
6011 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
6013 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
6014 ["0a:00:00:a8:01:0e 192.168.1.3"
6016 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
6017 ["0a:00:00:a8:01:0f 192.168.1.4"
6019 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
6020 ["0a:00:00:a8:01:10 192.168.1.5"
6022 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
6023 ["0a:00:00:a8:01:11 192.168.1.6"
6025 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
6026 ["0a:00:00:a8:01:12 192.168.1.7"
6028 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
6029 ["0a:00:00:a8:01:13 192.168.1.8"
6031 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
6032 ["0a:00:00:a8:01:14 192.168.1.9"
6034 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
6035 ["0a:00:00:a8:01:15 192.168.1.10"
6037 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
6038 ["0a:00:00:a8:01:16 192.168.1.11"
6041 # Change a port's address to test for multiple ip's for a single address entry
6042 # and addresses set by the user.
6043 ovn-nbctl lsp-set-addresses p0 "0a:00:00:a8:01:17 192.168.1.2 192.168.1.12 192.168.1.14"
6044 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
6045 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
6046 ["0a:00:00:a8:01:18 192.168.1.13"
6049 # Test for logical router port address management.
6050 ovn-nbctl create Logical_Router name=R1
6051 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
6052 network="192.168.1.1/24" mac=\"0a:00:00:a8:01:19\" \
6053 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
6054 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
6055 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
6056 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
6057 ["0a:00:00:a8:01:1a 192.168.1.15"
6060 # Test for address reuse after logical port is deleted.
6061 ovn-nbctl lsp-del p0
6062 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
6063 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
6064 ["0a:00:00:a8:01:03 192.168.1.2"
6067 # Test for multiple addresses to one logical port.
6068 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
6069 "0a:00:00:a8:01:1b 192.168.1.12" "0a:00:00:a8:01:1c 192.168.1.14"
6070 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
6071 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
6072 ["0a:00:00:a8:01:17 192.168.1.16"
6075 # Test for exhausting subnet address space.
6076 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
6077 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
6078 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
6079 ["0a:00:00:10:01:03 172.16.1.2"
6082 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
6083 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
6084 ["0a:00:00:00:00:01"
6087 # Test that address management does not add duplicate MAC for lsp/lrp peers.
6088 ovn-nbctl create Logical_Router name=R2
6089 ovn-nbctl ls-add sw3
6090 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
6092 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
6093 network="192.168.2.1/24" mac=\"0a:00:00:a8:01:18\" \
6094 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
6095 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
6096 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
6097 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
6098 ["0a:00:00:a8:01:1d 192.168.1.17"
6101 # Test static MAC address with dynamically allocated IP
6102 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
6103 "fe:dc:ba:98:76:54 dynamic"
6104 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6105 ["fe:dc:ba:98:76:54 192.168.1.18"
6108 # Update the static MAC address with dynamically allocated IP and check
6109 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
6110 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6112 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6113 ["fe:dc:ba:98:76:55 192.168.1.18"
6116 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
6117 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6118 ["0a:00:00:a8:01:1e 192.168.1.18"
6121 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
6122 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
6123 ["fe:dc:ba:98:76:56 192.168.1.18"
6127 # Test the exclude_ips from the IPAM list
6128 ovn-nbctl --wait=sb set logical_switch sw0 \
6129 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
6131 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
6133 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
6134 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
6135 ["0a:00:00:a8:01:1e 192.168.1.20"
6138 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
6140 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
6141 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
6142 ["0a:00:00:a8:01:1f 192.168.1.22"
6145 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
6147 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
6148 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
6149 ["0a:00:00:a8:01:34 192.168.1.51"
6152 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
6153 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
6154 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
6156 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
6157 ["0a:00:00:a8:01:20 192.168.1.19"
6160 # Set invalid data in exclude_ips list. It should be ignored.
6161 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
6162 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
6164 # 192.168.1.21 should be assigned as that's the next free one.
6165 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6166 ["0a:00:00:a8:01:21 192.168.1.21"
6169 # Clear the dynamic addresses assignment request.
6170 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
6171 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
6176 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
6177 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
6180 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
6181 # - aef0::800:ff:fe00:26 (EUI64)
6182 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
6183 ["0a:00:00:a8:01:21 192.168.1.21 aef0::800:ff:fea8:121"
6186 ovn-nbctl --wait=sb ls-add sw4
6187 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
6188 -- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
6189 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
6192 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
6193 ["0a:00:00:a8:02:03 192.168.2.2 bef0::800:ff:fea8:203"
6196 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
6197 "f0:00:00:00:10:12 dynamic"
6199 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
6200 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
6203 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
6204 # p40 should not have an IPv4 address since the pool is exhausted
6205 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
6207 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
6208 ["0a:00:00:00:00:02 bef0::800:ff:fe00:2"
6211 # Test dynamic changes on switch ports.
6213 ovn-nbctl --wait=sb ls-add sw5
6214 ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
6216 # p41 will start with nothing
6217 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6221 # Set a subnet. Now p41 should have an ipv4 address, too
6222 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6223 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6224 ["0a:00:00:a8:01:22 192.168.1.2"
6227 # Clear the other_config. The IPv4 address should be gone
6228 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6229 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6233 # Set an IPv6 prefix. Now p41 should have an IPv6 address.
6234 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
6235 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6236 ["0a:00:00:00:00:03 aef0::800:ff:fe00:3"
6239 # Change the MAC address to a static one. The IPv6 address should update.
6240 ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
6241 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6242 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
6245 # Change the IPv6 prefix. The IPv6 address should update.
6246 ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
6247 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6248 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
6251 # Clear the other_config. The IPv6 address should be gone
6252 ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
6253 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6257 # Set the subnet again. Now p41 should get the IPv4 address again.
6258 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
6259 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6260 ["f0:00:00:00:10:2b 192.168.1.2"
6263 # Add an excluded IP address that conflicts with p41. p41 should update.
6264 ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
6265 exclude_ips="192.168.1.2"
6266 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6267 ["f0:00:00:00:10:2b 192.168.1.3"
6270 # Add static ip address
6271 ovn-nbctl --wait=sb lsp-set-addresses p41 "dynamic 192.168.1.100"
6272 ovn-nbctl list Logical-Switch-Port p41
6273 ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
6274 "dynamic 192.168.1.101"
6275 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
6276 ["0a:00:00:a8:01:65 192.168.1.100"
6278 AT_CHECK([ovn-nbctl get Logical-Switch-Port p42 dynamic_addresses], [0],
6279 ["0a:00:00:a8:01:66 192.168.1.101"
6282 # define a mac address prefix
6283 ovn-nbctl ls-add sw6
6284 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22:33:44:55"
6285 ovn-nbctl --wait=sb set Logical-Switch sw6 other_config:subnet=192.168.100.0/24
6286 for n in $(seq 1 3); do
6287 ovn-nbctl --wait=sb lsp-add sw6 "p5$n" -- lsp-set-addresses "p5$n" dynamic
6289 AT_CHECK([ovn-nbctl get Logical-Switch-Port p51 dynamic_addresses], [0],
6290 ["00:11:22:a8:64:03 192.168.100.2"
6292 AT_CHECK([ovn-nbctl get Logical-Switch-Port p52 dynamic_addresses], [0],
6293 ["00:11:22:a8:64:04 192.168.100.3"
6295 AT_CHECK([ovn-nbctl get Logical-Switch-Port p53 dynamic_addresses], [0],
6296 ["00:11:22:a8:64:05 192.168.100.4"
6299 # verify configuration order does not break IPAM/MACAM
6300 ovn-nbctl ls-add sw7
6301 for n in $(seq 1 3); do
6302 ovn-nbctl --wait=sb lsp-add sw7 "p7$n" -- lsp-set-addresses "p7$n" dynamic
6304 ovn-nbctl --wait=sb set Logical-Switch sw7 other_config:ipv6_prefix="bef0::"
6305 p71_addr=$(ovn-nbctl get Logical-Switch-Port p71 dynamic_addresses)
6306 p72_addr=$(ovn-nbctl get Logical-Switch-Port p72 dynamic_addresses)
6307 p73_addr=$(ovn-nbctl get Logical-Switch-Port p73 dynamic_addresses)
6308 AT_CHECK([test "$p71_addr" != "$p72_addr"], [0], [])
6309 AT_CHECK([test "$p71_addr" != "$p73_addr"], [0], [])
6310 AT_CHECK([test "$p72_addr" != "$p73_addr"], [0], [])
6312 # request to assign mac only
6314 ovn-nbctl ls-add sw8
6315 ovn-nbctl --wait=sb set Logical-Switch sw8 other_config:mac_only=true
6316 for n in $(seq 1 3); do
6317 ovn-nbctl --wait=sb lsp-add sw8 "p8$n" -- lsp-set-addresses "p8$n" dynamic
6319 AT_CHECK([ovn-nbctl get Logical-Switch-Port p81 dynamic_addresses], [0],
6320 ["00:11:22:00:00:06"
6322 AT_CHECK([ovn-nbctl get Logical-Switch-Port p82 dynamic_addresses], [0],
6323 ["00:11:22:00:00:07"
6325 AT_CHECK([ovn-nbctl get Logical-Switch-Port p83 dynamic_addresses], [0],
6326 ["00:11:22:00:00:08"
6329 # clear mac_prefix and check it is allocated in a random manner
6330 ovn-nbctl --wait=hv remove NB_Global . options mac_prefix
6331 ovn-nbctl ls-add sw9
6332 ovn-nbctl --wait=sb set Logical-Switch sw9 other_config:mac_only=true
6333 ovn-nbctl --wait=sb lsp-add sw9 p91 -- lsp-set-addresses p91 dynamic
6335 mac_prefix=$(ovn-nbctl --wait=sb get NB_Global . options:mac_prefix | tr -d \")
6336 port_addr=$(ovn-nbctl get Logical-Switch-Port p91 dynamic_addresses | tr -d \")
6337 AT_CHECK([test "$port_addr" = "${mac_prefix}:00:00:09"], [0], [])
6339 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="00:11:22"
6340 ovn-nbctl ls-add sw10
6341 ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:ipv6_prefix="ae01::"
6342 ovn-nbctl --wait=sb lsp-add sw10 p101 -- lsp-set-addresses p101 "dynamic ae01::1"
6343 AT_CHECK([ovn-nbctl get Logical-Switch-Port p101 dynamic_addresses], [0],
6344 ["00:11:22:00:00:0a ae01::1"
6347 ovn-nbctl --wait=sb set Logical-Switch sw10 other_config:subnet=192.168.110.0/24
6348 ovn-nbctl --wait=sb lsp-add sw10 p102 -- lsp-set-addresses p102 "dynamic 192.168.110.10 ae01::2"
6349 AT_CHECK([ovn-nbctl get Logical-Switch-Port p102 dynamic_addresses], [0],
6350 ["00:11:22:a8:6e:0b 192.168.110.10 ae01::2"
6354 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6357 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6360 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6363 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6367 AT_SETUP([ovn -- ipam connectivity])
6368 AT_SKIP_IF([test $HAVE_PYTHON = no])
6373 # Test for a ping using dynamically allocated addresses.
6374 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
6375 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
6376 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
6379 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6380 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6381 options:router-port=foo \
6382 -- lsp-set-addresses rp-foo router
6384 # Connect alice to R1
6385 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
6386 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
6387 options:router-port=alice addresses=\"00:00:00:01:02:04\"
6389 # Create logical port foo1 in foo
6390 ovn-nbctl --wait=sb lsp-add foo foo1 \
6391 -- lsp-set-addresses foo1 "dynamic"
6392 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:a8:01:03 192.168.1.2"'], [0])
6394 # Create logical port alice1 in alice
6395 ovn-nbctl --wait=sb lsp-add alice alice1 \
6396 -- lsp-set-addresses alice1 "dynamic"
6397 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:a8:02:03 192.168.2.2"'])
6399 # Create logical port foo2 in foo
6400 ovn-nbctl --wait=sb lsp-add foo foo2 \
6401 -- lsp-set-addresses foo2 "dynamic"
6402 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:a8:01:04 192.168.1.3"'])
6404 # Create a hypervisor and create OVS ports corresponding to logical ports.
6409 ovs-vsctl add-br br-phys
6410 ovn_attach n1 br-phys 192.168.0.1
6411 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6412 set interface hv1-vif1 external-ids:iface-id=foo1 \
6413 options:tx_pcap=hv1/vif1-tx.pcap \
6414 options:rxq_pcap=hv1/vif1-rx.pcap \
6417 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6418 set interface hv1-vif2 external-ids:iface-id=foo2 \
6419 options:tx_pcap=hv1/vif2-tx.pcap \
6420 options:rxq_pcap=hv1/vif2-rx.pcap \
6423 ovs-vsctl -- add-port br-int hv1-vif3 -- \
6424 set interface hv1-vif3 external-ids:iface-id=alice1 \
6425 options:tx_pcap=hv1/vif3-tx.pcap \
6426 options:rxq_pcap=hv1/vif3-rx.pcap \
6429 # Allow some time for ovn-northd and ovn-controller to catch up.
6430 # XXX This should be more systematic.
6434 printf "%02x%02x%02x%02x" "$@"
6437 # Send ip packets between foo1 and foo2
6438 src_mac="0a0000a80103"
6439 dst_mac="0a0000a80104"
6440 src_ip=`ip_to_hex 192 168 1 2`
6441 dst_ip=`ip_to_hex 192 168 1 3`
6442 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6443 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6445 # Send ip packets between foo1 and alice1
6446 src_mac="0a0000a80103"
6447 dst_mac="000000010203"
6448 src_ip=`ip_to_hex 192 168 1 2`
6449 dst_ip=`ip_to_hex 192 168 2 2`
6450 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6451 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6453 echo "---------NB dump-----"
6455 echo "---------------------"
6456 ovn-nbctl list logical_router
6457 echo "---------------------"
6458 ovn-nbctl list logical_router_port
6459 echo "---------------------"
6461 echo "---------SB dump-----"
6462 ovn-sbctl list datapath_binding
6463 echo "---------------------"
6464 ovn-sbctl list port_binding
6465 echo "---------------------"
6467 echo "------ hv1 dump ----------"
6468 as hv1 ovs-ofctl dump-flows br-int
6470 # Packet to Expect at foo2
6471 src_mac="0a0000a80103"
6472 dst_mac="0a0000a80104"
6473 src_ip=`ip_to_hex 192 168 1 2`
6474 dst_ip=`ip_to_hex 192 168 1 3`
6475 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6477 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
6478 echo $expected > expout
6479 AT_CHECK([cat received1.packets], [0], [expout])
6481 # Packet to Expect at alice1
6482 src_mac="000000010204"
6483 dst_mac="0a0000a80203"
6484 src_ip=`ip_to_hex 192 168 1 2`
6485 dst_ip=`ip_to_hex 192 168 2 2`
6486 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6488 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
6489 echo $expected > expout
6490 AT_CHECK([cat received2.packets], [0], [expout])
6496 AT_SETUP([ovn -- ovs-vswitchd restart])
6497 AT_KEYWORDS([vswitchd])
6498 AT_SKIP_IF([test $HAVE_PYTHON = no])
6501 ovn-nbctl ls-add ls1
6503 ovn-nbctl lsp-add ls1 ls1-lp1 \
6504 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6506 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
6512 ovs-vsctl add-br br-phys
6513 ovn_attach n1 br-phys 192.168.0.1
6514 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6515 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6516 options:tx_pcap=hv1/vif1-tx.pcap \
6517 options:rxq_pcap=hv1/vif1-rx.pcap \
6523 as hv1 ovs-vsctl show
6525 echo "---------------------"
6526 ovn-sbctl dump-flows
6527 echo "---------------------"
6529 echo "------ hv1 dump ----------"
6530 as hv1 ovs-ofctl dump-flows br-int
6531 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6533 echo "Total flows before vswitchd restart = " $total_flows
6535 # Code taken from ovs-save utility
6537 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
6538 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
6539 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
6540 echo "EOF" >> restore_flows.sh
6543 restart_vswitchd () {
6546 if test $restore_flows = true; then
6551 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6553 if test $restore_flows = true; then
6555 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
6559 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
6560 ovs-ofctl dump-flows br-int
6562 if test $restore_flows = true; then
6563 sh ./restore_flows.sh
6564 echo "Flows after restore"
6566 ovs-ofctl dump-flows br-int
6567 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
6568 flow-restore-wait="true"
6572 # Save the flows, restart vswitchd and restore the flows
6573 restart_vswitchd true
6575 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6576 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6577 test "${total_flows}" = "${total_flows_after_restart}"
6580 # Restart vswitchd without restoring
6581 restart_vswitchd false
6583 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
6584 echo "Total flows after vswitchd restart = " $total_flows_after_restart
6585 test "${total_flows}" = "${total_flows_after_restart}"
6591 AT_SETUP([ovn -- send arp for nexthop])
6592 AT_SKIP_IF([test $HAVE_PYTHON = no])
6595 # Topology: Two LSs - ls1 and ls2 are connected via router r0
6597 # Create logical switches
6598 ovn-nbctl ls-add ls1
6599 ovn-nbctl ls-add ls2
6602 ovn-nbctl create Logical_Router name=lr0
6604 # Add router ls1p1 port to gateway router
6605 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
6606 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
6607 type=router options:router-port=lrp-ls1lp1 \
6608 addresses='"f0:00:00:00:00:01 192.168.0.1"'
6610 # Add router ls2p2 port to gateway router
6611 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
6612 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
6613 type=router options:router-port=lrp-ls2lp1 \
6614 addresses='"f0:00:00:00:00:02 192.168.1.1"'
6616 # Set default gateway (nexthop) to 192.168.1.254
6617 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
6619 # Create logical port ls1lp2 in ls1
6620 ovn-nbctl lsp-add ls1 ls1lp2 \
6621 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
6623 # Create logical port ls2lp2 in ls2
6624 ovn-nbctl lsp-add ls2 ls2lp2 \
6625 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
6630 ovs-vsctl add-br br-phys
6631 ovn_attach n1 br-phys 192.168.0.1
6632 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
6633 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
6634 options:tx_pcap=hv1/ls1lp2-tx.pcap \
6635 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
6637 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
6638 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
6639 options:tx_pcap=hv1/ls2lp2-tx.pcap \
6640 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
6643 # Allow some time for ovn-northd and ovn-controller to catch up.
6644 # XXX This should be more systematic.
6647 echo "---------NB dump-----"
6649 echo "---------------------"
6650 ovn-nbctl list logical_router
6651 echo "---------------------"
6652 ovn-nbctl list logical_router_port
6653 echo "---------------------"
6655 echo "---------SB dump-----"
6656 ovn-sbctl list datapath_binding
6657 echo "---------------------"
6658 ovn-sbctl list port_binding
6659 echo "---------------------"
6660 ovn-sbctl dump-flows
6661 echo "---------------------"
6662 ovn-sbctl list chassis
6663 ovn-sbctl list encap
6664 echo "---------------------"
6666 echo "------Flows dump-----"
6668 ovs-ofctl dump-flows
6669 echo "---------------------"
6672 printf "%02x%02x%02x%02x" "$@"
6675 src_mac="f00000000003"
6676 dst_mac="f00000000001"
6677 src_ip=`ip_to_hex 192 168 0 2`
6678 dst_ip=`ip_to_hex 8 8 8 8`
6679 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6681 # Send IP packet destined to 8.8.8.8 from lsp1lp2
6682 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
6685 sed 's/\(00\)\{1,\}$//'
6688 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
6691 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
6692 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
6693 echo $expected > expout
6694 AT_CHECK([cat packets], [0], [expout])
6701 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
6702 AT_SKIP_IF([test $HAVE_PYTHON = no])
6704 # Create logical switch
6705 ovn-nbctl ls-add ls0
6706 # Create gateway router
6707 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6708 # Add router port to gateway router
6709 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6710 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6711 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6712 # Add nat-address option
6713 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
6722 ovn_attach n1 br-phys 192.168.0.1
6724 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6725 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])
6727 # Create a localnet port.
6728 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6729 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6730 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6731 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6733 # Wait until the patch ports are created in hv1 to connect br-int to br-eth0
6734 OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-vsctl show | \
6735 grep "Port patch-br-int-to-ln_port" | wc -l`])
6737 # Wait for packet to be received.
6738 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6740 sed 's/\(00\)\{1,\}$//'
6742 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6743 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6744 echo $expected > expout
6745 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6746 echo $expected >> expout
6747 AT_CHECK([sort packets], [0], [expout])
6753 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6754 AT_SKIP_IF([test $HAVE_PYTHON = no])
6756 # Create logical switch
6757 ovn-nbctl ls-add ls0
6758 # Create gateway router
6759 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6760 # Add router port to gateway router
6761 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6762 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
6763 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
6764 # Add nat-address option
6765 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6767 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6768 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6769 # Add load balancers
6770 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6771 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6772 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6773 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6782 ovn_attach n1 br-phys 192.168.0.1
6784 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6785 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])
6787 # Create a localnet port.
6788 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6789 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6790 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6791 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6793 # Wait until the patch ports are created to connect br-int to br-eth0
6794 OVS_WAIT_UNTIL([test 1 = `ovs-vsctl show | \
6795 grep "Port patch-br-int-to-ln_port" | wc -l`])
6797 ovn-sbctl list port_binding lrp0-rp
6799 ovn-nbctl list logical_switch_port lrp0-rp
6800 ovn-nbctl list logical_router_port lrp0
6802 # Wait for packet to be received.
6803 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6805 sed 's/\(00\)\{1,\}$//'
6807 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6808 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6809 echo $expected > expout
6810 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6811 echo $expected >> expout
6812 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6813 echo $expected >> expout
6814 AT_CHECK([sort packets], [0], [expout])
6820 AT_SETUP([ovn -- delete mac bindings])
6825 ovs-vsctl -- add-br br-phys
6826 ovn_attach n1 br-phys 192.168.0.1
6827 # Create logical switch ls0
6828 ovn-nbctl ls-add ls0
6829 # Create ports lp0, lp1 in ls0
6830 ovn-nbctl lsp-add ls0 lp0
6831 ovn-nbctl lsp-add ls0 lp1
6832 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6833 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6834 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6835 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6836 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6837 ovn-sbctl find MAC_Binding
6838 # Delete port lp0 and check that its MAC_Binding is deleted.
6839 ovn-nbctl lsp-del lp0
6840 ovn-sbctl find MAC_Binding
6841 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6842 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
6843 ovn-nbctl ls-del ls0
6844 ovn-sbctl find MAC_Binding
6845 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6851 AT_SETUP([ovn -- conntrack zone allocation])
6852 AT_SKIP_IF([test $HAVE_PYTHON = no])
6856 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6857 # connected to a router R1.
6858 # foo has foo1 to act as a client.
6859 # bar has bar1, bar2, bar3 to act as servers.
6865 ovs-vsctl add-br br-phys
6866 ovn_attach n1 br-phys 192.168.0.1
6867 for i in foo1 bar1 bar2 bar3; do
6868 ovs-vsctl -- add-port br-int $i -- \
6869 set interface $i external-ids:iface-id=$i \
6870 options:tx_pcap=hv1/$i-tx.pcap \
6871 options:rxq_pcap=hv1/$i-rx.pcap
6874 ovn-nbctl create Logical_Router name=R1
6875 ovn-nbctl ls-add foo
6876 ovn-nbctl ls-add bar
6879 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6880 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6881 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6884 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6885 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6886 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6888 # Create logical port foo1 in foo
6889 ovn-nbctl lsp-add foo foo1 \
6890 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6892 # Create logical port bar1, bar2 and bar3 in bar
6893 for i in `seq 1 3`; do
6895 ovn-nbctl lsp-add bar bar$i \
6896 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6899 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6905 AT_SETUP([ovn -- tag allocation])
6908 AT_CHECK([ovn-nbctl ls-add ls0])
6909 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6910 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6911 AT_CHECK([ovn-nbctl ls-add ls1])
6913 dnl When a tag is provided, no allocation is done
6914 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6915 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6917 dnl The same 'tag' gets created in southbound database.
6918 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6919 logical_port="c0"], [0], [3
6922 dnl Allocate tags and see it getting created in both NB and SB
6923 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6924 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6926 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6927 logical_port="c1"], [0], [1
6930 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6931 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6933 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6934 logical_port="c2"], [0], [2
6936 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6937 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6939 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6940 logical_port="c3"], [0], [4
6943 dnl A different parent.
6944 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6945 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6947 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6948 logical_port="c4"], [0], [1
6951 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6952 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6954 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6955 logical_port="c5"], [0], [2
6958 dnl Delete a logical port and create a new one.
6959 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6960 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6961 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6963 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6964 logical_port="c6"], [0], [1
6967 dnl Restart northd to see that the same allocation remains.
6969 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6970 start_daemon ovn-northd \
6971 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6972 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6974 dnl Create a switch to make sure that ovn-northd has run through the main loop.
6975 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6976 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6978 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6980 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6982 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6984 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6986 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6989 dnl Create a switch port with a tag that has already been allocated.
6990 dnl It should go through fine with a duplicate tag.
6991 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6992 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6994 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6995 logical_port="c7"], [0], [2
6997 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
7000 AT_CHECK([ovn-nbctl ls-add ls2])
7001 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
7002 dnl gets copied to 'tag'
7003 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
7004 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
7006 dnl The same 'tag' gets created in southbound database.
7007 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
7008 logical_port="local0"], [0], [25
7010 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
7011 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
7012 AT_CHECK([ovn-nbctl lsp-get-tag local1])
7013 dnl change the tag_request.
7014 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
7015 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
7020 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
7022 ovn-nbctl ls-add lsw0
7027 ovs-vsctl add-br br-phys
7028 ovn_attach n1 br-phys 192.168.0.$i
7029 ovs-vsctl add-br br-eth0
7030 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
7033 # Create a localnet port.
7034 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
7035 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7036 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7037 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7041 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
7042 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
7043 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
7044 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
7045 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:02 192.168.1.2"])
7046 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
7047 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
7048 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
7049 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
7051 # Bind the localvif1 to hv1.
7053 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
7055 # On hv1, check that there are no flows outputting bcast to tunnel
7056 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7058 # On hv2, check that no flow outputs bcast to tunnel to hv1.
7060 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7062 # Now bind vif2 on hv2.
7063 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
7065 # At this point, the broadcast flow on vif2 should be deleted.
7066 # because, there is now a localnet vif bound (table=32 programming logic)
7067 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
7069 # Verify that the local net patch port exists on hv2.
7070 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7072 # Now bind vif3 on hv2.
7073 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
7075 # Verify that the local net patch port still exists on hv2
7076 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7079 AT_CHECK([ovn-nbctl lsp-del localvif2])
7081 # Verify that the local net patch port still exists on hv2,
7082 # because, localvif3 is still bound.
7083 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
7085 OVN_CLEANUP([hv1],[hv2])
7090 AT_SETUP([ovn -- ACL logging])
7098 ovs-vsctl add-br br-phys
7099 ovn_attach n1 br-phys 192.168.0.1
7100 for i in lp1 lp2; do
7101 ovs-vsctl -- add-port br-int $i -- \
7102 set interface $i external-ids:iface-id=$i \
7103 options:tx_pcap=hv/$i-tx.pcap \
7104 options:rxq_pcap=hv/$i-rx.pcap
7107 lp1_mac="f0:00:00:00:00:01"
7108 lp1_ip="192.168.1.2"
7110 lp2_mac="f0:00:00:00:00:02"
7111 lp2_ip="192.168.1.3"
7113 ovn-nbctl ls-add lsw0
7114 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7115 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7116 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7117 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7118 ovn-nbctl --wait=sb sync
7120 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7121 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
7123 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
7124 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
7126 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
7127 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
7129 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
7130 ovn-nbctl --wait=hv --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
7132 ovn-sbctl dump-flows
7135 # Send packet that should be dropped without logging.
7136 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7137 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7138 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
7139 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7141 # Send packet that should be dropped with logging.
7142 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7143 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7144 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
7145 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7147 # Send packet that should be allowed without logging.
7148 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7149 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7150 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
7151 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7153 # Send packet that should be allowed with logging.
7154 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7155 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7156 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
7157 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7159 # Send packet that should allow related flows without logging.
7160 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7161 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7162 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
7163 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7165 # Send packet that should allow related flows with logging.
7166 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7167 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7168 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
7169 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7171 # Send packet that should be rejected without logging.
7172 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7173 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7174 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
7175 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7177 # Send packet that should be rejected with logging.
7178 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
7179 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
7180 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
7181 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
7183 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
7185 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
7186 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
7187 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
7188 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
7189 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
7196 AT_SETUP([ovn -- ACL rate-limited logging])
7204 ovs-vsctl add-br br-phys
7205 ovn_attach n1 br-phys 192.168.0.1
7206 for i in lp1 lp2; do
7207 ovs-vsctl -- add-port br-int $i -- \
7208 set interface $i external-ids:iface-id=$i \
7209 options:tx_pcap=hv/$i-tx.pcap \
7210 options:rxq_pcap=hv/$i-rx.pcap
7213 lp1_mac="f0:00:00:00:00:01"
7214 lp1_ip="192.168.1.2"
7216 lp2_mac="f0:00:00:00:00:02"
7217 lp2_ip="192.168.1.3"
7219 ovn-nbctl ls-add lsw0
7220 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7221 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7222 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
7223 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
7224 ovn-nbctl --wait=sb sync
7227 # Add an ACL that rate-limits logs at 10 per second.
7228 ovn-nbctl meter-add http-rl1 drop 10 pktps
7229 ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
7231 # Add an ACL that rate-limits logs at 5 per second.
7232 ovn-nbctl meter-add http-rl2 drop 5 pktps
7233 ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
7235 # Add an ACL that doesn't rate-limit logs.
7236 ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
7237 ovn-nbctl --wait=hv sync
7239 # For each ACL, send 100 packets.
7240 for i in `seq 1 100`; do
7241 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)'
7243 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)'
7245 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)'
7248 # The rate at which packets are sent is highly system-dependent, so we
7249 # can't count on precise drop counts. To work around that, we just
7250 # check that exactly 100 "http-acl3" actions were logged and that there
7251 # were more "http-acl1" actions than "http-acl2" ones.
7252 OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
7254 # On particularly slow or overloaded systems, the transmission rate may
7255 # be lower than the configured meter rate. To prevent false test
7256 # failures, we check the duration count of the meter, and if it's
7257 # greater than nine seconds, just skip the test.
7258 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/')
7260 echo "Meter duration: $d_secs"
7261 AT_SKIP_IF([test $d_secs -gt 9])
7263 # Print some information that may help debugging.
7264 as hv ovs-appctl -t ovn-controller meter-table-list
7265 as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
7267 n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
7268 n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
7269 n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
7271 AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
7272 AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
7278 AT_SETUP([ovn -- DSCP marking and meter check])
7282 ovn-nbctl ls-add lsw0
7283 ovn-nbctl --wait=sb lsp-add lsw0 lp1
7284 ovn-nbctl --wait=sb lsp-add lsw0 lp2
7285 ovn-nbctl --wait=sb lsp-add lsw0 lp3
7286 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
7287 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
7288 ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
7289 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
7290 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
7291 ovn-nbctl --wait=sb sync
7295 ovs-vsctl add-br br-phys
7296 ovn_attach n1 br-phys 192.168.0.1
7297 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
7298 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
7300 AT_CAPTURE_FILE([trace])
7302 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7305 # Extracts nw_tos from the final flow from ofproto/trace output and prints
7306 # it on stdout. Prints "none" if no nw_tos was included.
7307 get_final_nw_tos() {
7308 if flow=$(grep '^Final flow:' stdout); then :; else
7309 # The output didn't have a final flow.
7313 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
7322 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
7324 # First check with ovn-trace for logical flows.
7325 echo "checking for tos $1"
7326 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
7327 echo 'output("lp2");') > expout
7328 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])
7330 # Then re-check with ofproto/trace for a physical packet.
7331 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])
7332 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
7337 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");
7339 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])
7340 AT_CHECK([get_final_nw_tos], [0], [none
7343 # check at L3 without dscp marking
7346 # Mark DSCP with a valid value
7347 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)
7348 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7352 # check at hv without qos meter
7353 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7356 # Update the meter rate
7357 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
7359 # check at hv with a qos meter table
7360 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
7362 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7365 # Update the DSCP marking
7366 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
7369 # Update the meter rate
7370 ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
7372 # check at hv with a qos meter table
7373 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
7375 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
7378 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
7381 # Disable DSCP marking
7382 ovn-nbctl --wait=hv qos-del lsw0
7383 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
7387 # check at hv without qos meter
7388 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7391 # check meter with chassis not resident
7392 ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
7393 AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
7396 # check no meter table
7397 AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
7399 AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
7405 AT_SETUP([ovn -- read-only sb db:ptcp access])
7406 AT_SKIP_IF([test $HAVE_PYTHON = no])
7409 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7411 # Add read-only remote to sb ovsdb-server
7413 [ovsdb-tool transact ovn-sb.db \
7414 ['["OVN_Southbound",
7416 "table": "SB_Global",
7418 "connections": ["set", [["named-uuid", "xyz"]]]}},
7420 "table": "Connection",
7422 "row": {"target": "ptcp:0:127.0.0.1",
7423 "read_only": true}}]']], [0], [ignore], [ignore])
7425 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
7427 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7429 # read-only accesses should succeed
7430 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
7431 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
7433 # write access should fail
7434 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7435 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7438 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7441 AT_SETUP([ovn -- read-only sb db:pssl access])
7442 AT_SKIP_IF([test $HAVE_PYTHON = no])
7443 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7444 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7445 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7449 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7451 # Add read-only remote to sb ovsdb-server
7453 [ovsdb-tool transact ovn-sb.db \
7454 ['["OVN_Southbound",
7456 "table": "SB_Global",
7458 "connections": ["set", [["named-uuid", "xyz"]]]}},
7460 "table": "Connection",
7462 "row": {"target": "pssl:0:127.0.0.1",
7463 "read_only": true}}]']], [0], [ignore], [ignore])
7465 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
7466 --remote=db:OVN_Southbound,SB_Global,connections \
7467 --private-key="$PKIDIR/testpki-privkey2.pem" \
7468 --certificate="$PKIDIR/testpki-cert2.pem" \
7469 --ca-cert="$PKIDIR/testpki-cacert.pem" \
7472 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7474 # read-only accesses should succeed
7475 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7476 --private-key=$PKIDIR/testpki-privkey.pem \
7477 --certificate=$PKIDIR/testpki-cert.pem \
7478 --ca-cert=$PKIDIR/testpki-cacert.pem \
7479 list SB_Global], [0], [stdout], [ignore])
7480 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7481 --private-key=$PKIDIR/testpki-privkey.pem \
7482 --certificate=$PKIDIR/testpki-cert.pem \
7483 --ca-cert=$PKIDIR/testpki-cacert.pem \
7484 list Connection], [0], [stdout], [ignore])
7486 # write access should fail
7487 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7488 --private-key=$PKIDIR/testpki-privkey.pem \
7489 --certificate=$PKIDIR/testpki-cert.pem \
7490 --ca-cert=$PKIDIR/testpki-cacert.pem \
7491 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
7492 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
7495 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7498 AT_SETUP([ovn -- nb connection/ssl commands])
7499 AT_SKIP_IF([test $HAVE_PYTHON = no])
7500 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7501 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7502 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7506 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
7508 # Start nb db server using db connection/ssl entries (unpopulated initially)
7509 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
7510 --remote=db:OVN_Northbound,NB_Global,connections \
7511 --private-key=db:OVN_Northbound,SSL,private_key \
7512 --certificate=db:OVN_Northbound,SSL,certificate \
7513 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
7516 # Populate SSL configuration entries in nb db
7518 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
7519 $PKIDIR/testpki-cert.pem \
7520 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7522 # Populate a passive SSL connection in nb db
7523 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7525 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7527 # Verify SSL connetivity to nb db server
7528 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7529 --private-key=$PKIDIR/testpki-privkey.pem \
7530 --certificate=$PKIDIR/testpki-cert.pem \
7531 --ca-cert=$PKIDIR/testpki-cacert.pem \
7533 [0], [stdout], [ignore])
7534 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7535 --private-key=$PKIDIR/testpki-privkey.pem \
7536 --certificate=$PKIDIR/testpki-cert.pem \
7537 --ca-cert=$PKIDIR/testpki-cacert.pem \
7539 [0], [stdout], [ignore])
7540 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
7541 --private-key=$PKIDIR/testpki-privkey.pem \
7542 --certificate=$PKIDIR/testpki-cert.pem \
7543 --ca-cert=$PKIDIR/testpki-cacert.pem \
7545 [0], [stdout], [ignore])
7547 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7550 AT_SETUP([ovn -- sb connection/ssl commands])
7551 AT_SKIP_IF([test $HAVE_PYTHON = no])
7552 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
7553 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
7554 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
7558 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
7560 # Start sb db server using db connection/ssl entries (unpopulated initially)
7561 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
7562 --remote=db:OVN_Southbound,SB_Global,connections \
7563 --private-key=db:OVN_Southbound,SSL,private_key \
7564 --certificate=db:OVN_Southbound,SSL,certificate \
7565 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
7568 # Populate SSL configuration entries in sb db
7570 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
7571 $PKIDIR/testpki-cert.pem \
7572 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
7574 # Populate a passive SSL connection in sb db
7575 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
7577 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
7579 # Verify SSL connetivity to sb db server
7580 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7581 --private-key=$PKIDIR/testpki-privkey.pem \
7582 --certificate=$PKIDIR/testpki-cert.pem \
7583 --ca-cert=$PKIDIR/testpki-cacert.pem \
7585 [0], [stdout], [ignore])
7586 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7587 --private-key=$PKIDIR/testpki-privkey.pem \
7588 --certificate=$PKIDIR/testpki-cert.pem \
7589 --ca-cert=$PKIDIR/testpki-cacert.pem \
7591 [0], [stdout], [ignore])
7592 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
7593 --private-key=$PKIDIR/testpki-privkey.pem \
7594 --certificate=$PKIDIR/testpki-cert.pem \
7595 --ca-cert=$PKIDIR/testpki-cacert.pem \
7597 [0], [stdout], [ignore])
7599 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7602 AT_SETUP([ovn -- nested containers])
7606 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
7609 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
7610 # and "bar" (192.168.2.0/24). They are all connected to router R1.
7613 ovn-nbctl ls-add mgmt
7614 ovn-nbctl ls-add foo
7615 ovn-nbctl ls-add bar
7617 # Connect mgmt to R1
7618 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
7619 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
7620 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
7623 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7624 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7625 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7628 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
7629 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7630 options:router-port=bar addresses=\"00:00:00:01:02:04\"
7632 # "mgmt" has VM1 and VM2 connected
7633 ovn-nbctl lsp-add mgmt vm1 \
7634 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
7636 ovn-nbctl lsp-add mgmt vm2 \
7637 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
7639 # "foo1" and "foo2" are containers belonging to switch "foo"
7640 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
7641 ovn-nbctl lsp-add foo foo1 vm1 1 \
7642 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
7644 ovn-nbctl lsp-add foo foo2 vm2 2 \
7645 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7647 # "bar1" and "bar2" are containers belonging to switch "bar"
7648 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
7649 ovn-nbctl lsp-add bar bar1 vm1 2 \
7650 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
7652 ovn-nbctl lsp-add bar bar2 vm2 1 \
7653 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
7655 # bar3 is a standalone VM belonging to switch "bar"
7656 ovn-nbctl lsp-add bar bar3 \
7657 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
7659 # Create two hypervisor and create OVS ports corresponding to logical ports.
7664 ovs-vsctl add-br br-phys
7665 ovn_attach n1 br-phys 192.168.0.1
7666 ovs-vsctl -- add-port br-int vm1 -- \
7667 set interface vm1 external-ids:iface-id=vm1 \
7668 options:tx_pcap=hv1/vm1-tx.pcap \
7669 options:rxq_pcap=hv1/vm1-rx.pcap \
7672 ovs-vsctl -- add-port br-int bar3 -- \
7673 set interface bar3 external-ids:iface-id=bar3 \
7674 options:tx_pcap=hv1/bar3-tx.pcap \
7675 options:rxq_pcap=hv1/bar3-rx.pcap \
7680 ovs-vsctl add-br br-phys
7681 ovn_attach n1 br-phys 192.168.0.2
7682 ovs-vsctl -- add-port br-int vm2 -- \
7683 set interface vm2 external-ids:iface-id=vm2 \
7684 options:tx_pcap=hv2/vm2-tx.pcap \
7685 options:rxq_pcap=hv2/vm2-rx.pcap \
7688 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7689 # packets for ARP resolution (native tunneling doesn't queue packets
7690 # for ARP resolution).
7693 # Allow some time for ovn-northd and ovn-controller to catch up.
7694 # XXX This should be more systematic.
7698 printf "%02x%02x%02x%02x" "$@"
7701 # Send ip packets between foo1 and foo2 (same switch, different HVs and
7702 # different VLAN tags).
7703 src_mac="f00000010205"
7704 dst_mac="f00000010206"
7705 src_ip=`ip_to_hex 192 168 1 2`
7706 dst_ip=`ip_to_hex 192 168 1 3`
7707 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7708 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7710 # expected packet at foo2
7711 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7712 echo $packet > expected
7713 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7715 # Send ip packets between foo1 and bar2 (different switch, different HV)
7716 src_mac="f00000010205"
7717 dst_mac="000000010203"
7718 src_ip=`ip_to_hex 192 168 1 2`
7719 dst_ip=`ip_to_hex 192 168 2 3`
7720 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7721 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7723 # expected packet at bar2
7724 src_mac="000000010204"
7725 dst_mac="f00000010208"
7726 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7727 echo $packet >> expected
7728 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
7730 # Send ip packets between foo1 and bar1
7731 # (different switch, loopback to same vm but different tag)
7732 src_mac="f00000010205"
7733 dst_mac="000000010203"
7734 src_ip=`ip_to_hex 192 168 1 2`
7735 dst_ip=`ip_to_hex 192 168 2 2`
7736 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7737 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7739 # expected packet at bar1
7740 src_mac="000000010204"
7741 dst_mac="f00000010207"
7742 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7743 echo $packet > expected1
7744 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7746 # Send ip packets between bar1 and bar3
7747 # (same switch. But one is container and another is a standalone VM)
7748 src_mac="f00000010207"
7749 dst_mac="f00000010209"
7750 src_ip=`ip_to_hex 192 168 2 2`
7751 dst_ip=`ip_to_hex 192 168 2 3`
7752 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7753 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7755 # expected packet at bar3
7756 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7757 echo $packet > expected
7758 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7760 # Send ip packets between foo1 and vm1.
7761 (different switch, container to the VM hosting it.)
7762 src_mac="f00000010205"
7763 dst_mac="000000010203"
7764 src_ip=`ip_to_hex 192 168 1 2`
7765 dst_ip=`ip_to_hex 172 16 1 2`
7766 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7767 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7769 # expected packet at vm1
7770 src_mac="000000010202"
7771 dst_mac="f00000010203"
7772 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7773 echo $packet >> expected1
7774 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7776 # Send packets from vm1 to bar1.
7777 (different switch, A hosting VM to a container inside it)
7778 src_mac="f00000010203"
7779 dst_mac="000000010202"
7780 src_ip=`ip_to_hex 172 16 1 2`
7781 dst_ip=`ip_to_hex 192 168 2 2`
7782 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7783 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7785 # expected packet at vm1
7786 src_mac="000000010204"
7787 dst_mac="f00000010207"
7788 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7789 echo $packet >> expected1
7790 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7792 # Send broadcast packet from foo1. foo1 should not receive the same packet.
7793 src_mac="f00000010205"
7794 dst_mac="ffffffffffff"
7795 src_ip=`ip_to_hex 192 168 1 2`
7796 dst_ip=`ip_to_hex 255 255 255 255`
7797 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7798 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7800 # expected packet at VM1
7801 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7803 OVN_CLEANUP([hv1],[hv2])
7807 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7808 AT_SKIP_IF([test $HAVE_PYTHON = no])
7812 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7813 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7814 # (192.168.2.0/24) connected to it.
7816 # R2 and R3 are gateway routers.
7817 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7818 # connected to it. Note how both alice and bob have the same subnet behind it.
7819 # We are trying to simulate external network via those 2 switches. In real
7820 # world the switch ports of these switches will have addresses set as "unknown"
7821 # to make them learning switches. Or those switches will be "localnet" ones.
7823 # Create three hypervisors and create OVS ports corresponding to logical ports.
7828 ovs-vsctl add-br br-phys
7829 ovn_attach n1 br-phys 192.168.0.1
7830 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7831 set interface hv1-vif1 external-ids:iface-id=foo1 \
7832 options:tx_pcap=hv1/vif1-tx.pcap \
7833 options:rxq_pcap=hv1/vif1-rx.pcap \
7836 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7837 set interface hv1-vif2 external-ids:iface-id=bar1 \
7838 options:tx_pcap=hv1/vif2-tx.pcap \
7839 options:rxq_pcap=hv1/vif2-rx.pcap \
7844 ovs-vsctl add-br br-phys
7845 ovn_attach n1 br-phys 192.168.0.2
7846 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7847 set interface hv2-vif1 external-ids:iface-id=alice1 \
7848 options:tx_pcap=hv2/vif1-tx.pcap \
7849 options:rxq_pcap=hv2/vif1-rx.pcap \
7854 ovs-vsctl add-br br-phys
7855 ovn_attach n1 br-phys 192.168.0.3
7856 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7857 set interface hv3-vif1 external-ids:iface-id=bob1 \
7858 options:tx_pcap=hv3/vif1-tx.pcap \
7859 options:rxq_pcap=hv3/vif1-rx.pcap \
7863 ovn-nbctl create Logical_Router name=R1
7864 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7865 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7867 ovn-nbctl ls-add foo
7868 ovn-nbctl ls-add bar
7869 ovn-nbctl ls-add alice
7870 ovn-nbctl ls-add bob
7871 ovn-nbctl ls-add join
7874 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7875 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7876 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7879 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7880 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7881 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7883 # Connect alice to R2
7884 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7885 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7886 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7889 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7890 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7891 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7893 # Connect R1 to join
7894 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7895 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7896 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7898 # Connect R2 to join
7899 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7900 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7901 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7903 # Connect R3 to join
7904 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7905 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7906 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7908 # Install static routes with source ip address as the policy for routing.
7909 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7910 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7911 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7913 # Install static routes with destination ip address as the policy for routing.
7914 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7916 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7918 # Create logical port foo1 in foo
7919 ovn-nbctl lsp-add foo foo1 \
7920 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7922 # Create logical port bar1 in bar
7923 ovn-nbctl lsp-add bar bar1 \
7924 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7926 # Create logical port alice1 in alice
7927 ovn-nbctl lsp-add alice alice1 \
7928 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7930 # Create logical port bob1 in bob
7931 ovn-nbctl lsp-add bob bob1 \
7932 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7934 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7935 # packets for ARP resolution (native tunneling doesn't queue packets
7936 # for ARP resolution).
7939 # Allow some time for ovn-northd and ovn-controller to catch up.
7940 # XXX This should be more systematic.
7944 printf "%02x%02x%02x%02x" "$@"
7947 sed 's/\(00\)\{1,\}$//'
7950 # Send ip packets between foo1 and bar1
7951 # (East-west traffic should flow normally)
7952 src_mac="f00000010203"
7953 dst_mac="000001010203"
7954 src_ip=`ip_to_hex 192 168 1 2`
7955 dst_ip=`ip_to_hex 192 168 2 2`
7956 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7957 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7959 # Send ip packets between foo1 and alice1
7960 src_mac="f00000010203"
7961 dst_mac="000001010203"
7962 src_ip=`ip_to_hex 192 168 1 2`
7963 dst_ip=`ip_to_hex 172 16 1 3`
7964 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7965 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7966 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
7968 # Send ip packets between bar1 and bob1
7969 src_mac="f00000010204"
7970 dst_mac="000001010204"
7971 src_ip=`ip_to_hex 192 168 2 2`
7972 dst_ip=`ip_to_hex 172 16 1 4`
7973 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7974 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7975 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7977 # Packet to expect at bar1
7978 src_mac="000001010204"
7979 dst_mac="f00000010204"
7980 src_ip=`ip_to_hex 192 168 1 2`
7981 dst_ip=`ip_to_hex 192 168 2 2`
7982 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7983 echo $expected > expected
7984 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7986 # Packet to Expect at alice1
7987 src_mac="000002010203"
7988 dst_mac="f00000010205"
7989 src_ip=`ip_to_hex 192 168 1 2`
7990 dst_ip=`ip_to_hex 172 16 1 3`
7991 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7992 echo $expected > expected
7993 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7995 # Packet to Expect at bob1
7996 src_mac="000003010203"
7997 dst_mac="f00000010206"
7998 src_ip=`ip_to_hex 192 168 2 2`
7999 dst_ip=`ip_to_hex 172 16 1 4`
8000 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8001 echo $expected > expected
8002 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
8004 OVN_CLEANUP([hv1],[hv2],[hv3])
8008 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
8009 AT_SKIP_IF([test $HAVE_PYTHON = no])
8012 ovn-nbctl ls-add ls1
8014 ovn-nbctl lsp-add ls1 ls1-lp1 \
8015 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8017 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
8019 ovn-nbctl lsp-add ls1 ls1-lp2 \
8020 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8022 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
8024 DNS1=`ovn-nbctl create DNS records={}`
8025 DNS2=`ovn-nbctl create DNS records={}`
8027 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8028 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
8029 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
8031 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
8037 ovs-vsctl add-br br-phys
8038 ovn_attach n1 br-phys 192.168.0.1
8039 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8040 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
8041 options:tx_pcap=hv1/vif1-tx.pcap \
8042 options:rxq_pcap=hv1/vif1-rx.pcap \
8045 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8046 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
8047 options:tx_pcap=hv1/vif2-tx.pcap \
8048 options:rxq_pcap=hv1/vif2-rx.pcap \
8053 as hv1 ovs-vsctl show
8055 echo "*************************"
8057 echo "*************************"
8060 printf "%02x%02x%02x%02x" "$@"
8066 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8067 options:rxq_pcap=dummy-rx.pcap
8068 rm -f ${pcap_file}*.pcap
8069 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8070 options:rxq_pcap=${pcap_file}-rx.pcap
8073 # set_dns_params host_name
8074 # Sets the dns_req_data and dns_resp_data
8083 query_name=03766d31036f766e036f726700
8084 # IPv4 address - 10.0.0.4
8085 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8089 query_name=03766d32036f766e036f726700
8090 # IPv4 address - 10.0.0.6
8091 expected_dns_answer=${query_name}00010001${ttl}00040a000006
8092 # IPv4 address - 20.0.0.4
8093 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
8098 query_name=03766d33036f766e036f726700
8099 # IPv4 address - 40.0.0.4
8100 expected_dns_answer=${query_name}00010001${ttl}000428000004
8104 query_name=03766d31036f766e036f726700
8105 # IPv6 address - aef0::4
8107 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
8111 query_name=03766d31036f766e036f726700
8114 # IPv4 address - 10.0.0.4
8115 # IPv6 address - aef0::4
8116 expected_dns_answer=${query_name}00010001${ttl}00040a000004
8117 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
8118 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
8122 query_name=03766d31036f766e036f726700
8123 # IPv6 address - aef0::4
8131 local dns_req_header=010201200001000000000000
8132 local dns_resp_header=010281200001${an_count}00000000
8133 dns_req_data=${dns_req_header}${query_name}${type}0001
8134 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
8137 # This shell function sends a DNS request packet
8138 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
8140 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8141 local dns_query_data=$7
8142 shift; shift; shift; shift; shift; shift; shift;
8143 # Packet size => IPv4 header (20) + UDP header (8) +
8144 # DNS data (header + query)
8145 ip_len=`expr 28 + ${#dns_query_data} / 2`
8146 udp_len=`expr $ip_len - 20`
8147 ip_len=$(printf "%x" $ip_len)
8148 udp_len=$(printf "%x" $udp_len)
8149 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
8150 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
8152 request=${request}${dns_query_data}
8154 if test $dns_reply != 0; then
8156 ip_len=`expr 28 + ${#dns_reply} / 2`
8157 udp_len=`expr $ip_len - 20`
8158 ip_len=$(printf "%x" $ip_len)
8159 udp_len=$(printf "%x" $udp_len)
8160 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
8161 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
8162 echo $reply >> $inport.expected
8165 echo $request >> $outport.expected
8168 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8172 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
8173 local dns_query_data=$7
8174 shift; shift; shift; shift; shift; shift; shift;
8175 # Packet size => UDP header (8) +
8176 # DNS data (header + query)
8177 ip_len=`expr 8 + ${#dns_query_data} / 2`
8179 ip_len=$(printf "%x" $ip_len)
8180 udp_len=$(printf "%x" $udp_len)
8181 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
8182 request=${request}9234003500${udp_len}0000
8184 request=${request}${dns_query_data}
8186 if test $dns_reply != 0; then
8188 ip_len=`expr 8 + ${#dns_reply} / 2`
8190 ip_len=$(printf "%x" $ip_len)
8191 udp_len=$(printf "%x" $udp_len)
8192 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
8193 reply=${reply}0035923400${udp_len}0000${dns_reply}
8194 echo $reply >> $inport.expected
8197 echo $request >> $outport.expected
8200 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
8203 AT_CAPTURE_FILE([ofctl_monitor0.log])
8204 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8205 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8208 src_ip=`ip_to_hex 10 0 0 4`
8209 dst_ip=`ip_to_hex 10 0 0 1`
8211 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8213 # NXT_RESUMEs should be 1.
8214 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8216 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8217 cat 1.expected | cut -c -48 > expout
8218 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8219 # Skipping the IPv4 checksum.
8220 cat 1.expected | cut -c 53- > expout
8221 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8223 reset_pcap_file hv1-vif1 hv1/vif1
8224 reset_pcap_file hv1-vif2 hv1/vif2
8229 src_ip=`ip_to_hex 10 0 0 6`
8230 dst_ip=`ip_to_hex 10 0 0 1`
8232 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8234 # NXT_RESUMEs should be 2.
8235 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8237 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8238 cat 2.expected | cut -c -48 > expout
8239 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8240 # Skipping the IPv4 checksum.
8241 cat 2.expected | cut -c 53- > expout
8242 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8244 reset_pcap_file hv1-vif1 hv1/vif1
8245 reset_pcap_file hv1-vif2 hv1/vif2
8249 # Clear the query name options for ls1-lp2
8250 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
8253 src_ip=`ip_to_hex 10 0 0 4`
8254 dst_ip=`ip_to_hex 10 0 0 1`
8256 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
8258 # NXT_RESUMEs should be 3.
8259 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8261 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8262 AT_CHECK([cat 1.packets], [0], [])
8264 reset_pcap_file hv1-vif1 hv1/vif1
8265 reset_pcap_file hv1-vif2 hv1/vif2
8269 # Clear the query name for ls1-lp1
8270 # Since ls1 has no query names configued,
8271 # ovn-northd should not add the DNS flows.
8272 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
8275 src_ip=`ip_to_hex 10 0 0 6`
8276 dst_ip=`ip_to_hex 10 0 0 1`
8278 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8280 # NXT_RESUMEs should be 3 only.
8281 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8283 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8284 AT_CHECK([cat 2.packets], [0], [])
8286 reset_pcap_file hv1-vif1 hv1/vif1
8287 reset_pcap_file hv1-vif2 hv1/vif2
8291 # Test IPv6 (AAAA records) using IPv4 packet.
8292 # Add back the DNS options for ls1-lp1.
8293 ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
8295 set_dns_params vm1_ipv6_only
8296 src_ip=`ip_to_hex 10 0 0 6`
8297 dst_ip=`ip_to_hex 10 0 0 1`
8299 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8301 # NXT_RESUMEs should be 4.
8302 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8304 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8305 cat 2.expected | cut -c -48 > expout
8306 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8307 # Skipping the IPv4 checksum.
8308 cat 2.expected | cut -c 53- > expout
8309 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8311 reset_pcap_file hv1-vif1 hv1/vif1
8312 reset_pcap_file hv1-vif2 hv1/vif2
8316 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
8317 set_dns_params vm1_ipv4_v6
8318 src_ip=`ip_to_hex 10 0 0 6`
8319 dst_ip=`ip_to_hex 10 0 0 1`
8321 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8323 # NXT_RESUMEs should be 5.
8324 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8326 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8327 cat 2.expected | cut -c -48 > expout
8328 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
8329 # Skipping the IPv4 checksum.
8330 cat 2.expected | cut -c 53- > expout
8331 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
8333 reset_pcap_file hv1-vif1 hv1/vif1
8334 reset_pcap_file hv1-vif2 hv1/vif2
8339 set_dns_params vm1_invalid_type
8340 src_ip=`ip_to_hex 10 0 0 6`
8341 dst_ip=`ip_to_hex 10 0 0 1`
8343 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8345 # NXT_RESUMEs should be 6.
8346 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8348 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8349 AT_CHECK([cat 2.packets], [0], [])
8351 reset_pcap_file hv1-vif1 hv1/vif1
8352 reset_pcap_file hv1-vif2 hv1/vif2
8356 # Incomplete DNS packet.
8357 set_dns_params vm1_incomplete
8358 src_ip=`ip_to_hex 10 0 0 6`
8359 dst_ip=`ip_to_hex 10 0 0 1`
8361 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
8363 # NXT_RESUMEs should be 7.
8364 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8366 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8367 AT_CHECK([cat 2.packets], [0], [])
8369 reset_pcap_file hv1-vif1 hv1/vif1
8370 reset_pcap_file hv1-vif2 hv1/vif2
8374 # Add one more DNS record to the ls1.
8375 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
8378 src_ip=`ip_to_hex 10 0 0 4`
8379 dst_ip=`ip_to_hex 10 0 0 1`
8381 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8383 # NXT_RESUMEs should be 8.
8384 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8386 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8387 cat 1.expected | cut -c -48 > expout
8388 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
8389 # Skipping the IPv4 checksum.
8390 cat 1.expected | cut -c 53- > expout
8391 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
8393 reset_pcap_file hv1-vif1 hv1/vif1
8394 reset_pcap_file hv1-vif2 hv1/vif2
8398 # Try DNS query over IPv6
8400 src_ip=aef00000000000000000000000000004
8401 dst_ip=aef00000000000000000000000000001
8403 test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
8405 # NXT_RESUMEs should be 9.
8406 OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8408 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8409 # Skipping the UDP checksum.
8410 cat 1.expected | cut -c 1-120,125- > expout
8411 AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
8413 reset_pcap_file hv1-vif1 hv1/vif1
8414 reset_pcap_file hv1-vif2 hv1/vif2
8422 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
8423 AT_SKIP_IF([test $HAVE_PYTHON = no])
8430 ovs-vsctl add-br br-phys
8431 ovn_attach n1 br-phys 192.168.0.1
8432 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8433 set interface hv1-vif1 external-ids:iface-id=foo1 \
8434 options:tx_pcap=hv1/vif1-tx.pcap \
8435 options:rxq_pcap=hv1/vif1-rx.pcap \
8440 ovs-vsctl add-br br-phys
8441 ovn_attach n1 br-phys 192.168.0.2
8445 ovs-vsctl add-br br-phys
8446 ovn_attach n1 br-phys 192.168.0.4
8450 ovs-vsctl add-br br-phys
8451 ovn_attach n1 br-phys 192.168.0.3
8452 ovs-vsctl -- add-port br-int ext1-vif1 -- \
8453 set interface ext1-vif1 external-ids:iface-id=outside1 \
8454 options:tx_pcap=ext1/vif1-tx.pcap \
8455 options:rxq_pcap=ext1/vif1-rx.pcap \
8458 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8459 # packets for ARP resolution (native tunneling doesn't queue packets
8460 # for ARP resolution).
8463 ovn-nbctl create Logical_Router name=R1
8465 ovn-nbctl ls-add foo
8466 ovn-nbctl ls-add alice
8467 ovn-nbctl ls-add outside
8470 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8471 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8472 type=router options:router-port=foo \
8473 -- lsp-set-addresses rp-foo router
8475 # Connect alice to R1 as distributed router gateway port on gw1
8476 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8479 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8482 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8485 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8487 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8488 type=router options:router-port=alice \
8489 -- lsp-set-addresses rp-alice router
8491 # Create logical port foo1 in foo
8492 ovn-nbctl lsp-add foo foo1 \
8493 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8495 # Create logical port outside1 in outside
8496 ovn-nbctl lsp-add outside outside1 \
8497 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8499 # Create localnet port in alice
8500 ovn-nbctl lsp-add alice ln-alice
8501 ovn-nbctl lsp-set-addresses ln-alice unknown
8502 ovn-nbctl lsp-set-type ln-alice localnet
8503 ovn-nbctl lsp-set-options ln-alice network_name=phys
8505 # Create localnet port in outside
8506 ovn-nbctl lsp-add outside ln-outside
8507 ovn-nbctl lsp-set-addresses ln-outside unknown
8508 ovn-nbctl lsp-set-type ln-outside localnet
8509 ovn-nbctl lsp-set-options ln-outside network_name=phys
8511 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8512 # mapping to the external network, is the one generating packets
8513 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8514 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8515 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8517 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8519 # Allow some time for ovn-northd and ovn-controller to catch up.
8520 # XXX This should be more systematic.
8524 printf "%02x%02x%02x%02x" "$@"
8530 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8531 options:rxq_pcap=dummy-rx.pcap
8532 rm -f ${pcap_file}*.pcap
8533 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8534 options:rxq_pcap=${pcap_file}-rx.pcap
8541 local backup_vswitchd_dead=$3
8543 # Send ip packet between foo1 and outside1
8544 src_mac="f00000010203" # foo1 mac
8545 dst_mac="000001010203" # rp-foo mac (internal router leg)
8546 src_ip=`ip_to_hex 192 168 1 2`
8547 dst_ip=`ip_to_hex 172 16 1 3`
8548 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8550 # ARP request packet to expect at outside1
8551 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8553 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8555 # Send ARP reply from outside1 back to the router
8556 # XXX: note, we could avoid this if we plug this port into a netns
8557 # and setup the IP address into the port, so the kernel would simply reply
8558 src_mac="000002010203"
8559 reply_mac="f00000010204"
8560 dst_ip=`ip_to_hex 172 16 1 3`
8561 src_ip=`ip_to_hex 172 16 1 1`
8562 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8564 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8567 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8568 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8571 # Packet to Expect at ext1 chassis, outside1 port
8572 src_mac="000002010203"
8573 dst_mac="f00000010204"
8574 src_ip=`ip_to_hex 192 168 1 2`
8575 dst_ip=`ip_to_hex 172 16 1 3`
8576 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8577 echo $expected > ext1-vif1.expected
8578 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
8579 echo $exp_gw_ip_garp >> ext1-vif1.expected
8580 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8582 if test $backup_vswitchd_dead != 1; then
8583 # Reset the file only if vswitchd in backup gw is alive
8584 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8586 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8588 # Resend packet from foo1 to outside1
8589 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8593 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8594 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8595 cat packets | grep $expected > exp
8596 # Its possible that $active_gw/br-phys_n1-tx.pcap may have received multiple
8597 # garp packets. So consider only the first packet.
8598 cat packets | grep $exp_gw_ip_garp | head -1 >> exp
8599 AT_CHECK([cat exp], [0], [expout])
8601 if test $backup_vswitchd_dead != 1; then
8602 # Check for backup gw only if vswitchd is alive
8603 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8604 AT_CHECK([grep $expected packets | sort], [0], [])
8608 test_ip_packet gw1 gw2 0
8610 ovn-nbctl --timeout=3 --wait=hv \
8611 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8614 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8617 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8619 test_ip_packet gw2 gw1 0
8621 # Get the claim count of both gw1 and gw2.
8622 gw1_claim_ct=`grep "cr-alice: Claiming" gw1/ovn-controller.log | wc -l`
8623 gw2_claim_ct=`grep "cr-alice: Claiming" gw2/ovn-controller.log | wc -l`
8625 # Stop ovs-vswitchd in gw2. gw1 should claim the gateway port.
8627 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
8629 # gw1 should claim the cr-alice and the claim count of gw1 should be
8631 gw1_claim_ct=$((gw1_claim_ct+1))
8633 OVS_WAIT_UNTIL([test $gw1_claim_ct = `cat gw1/ovn-controller.log \
8634 | grep -c "cr-alice: Claiming"`])
8636 AT_CHECK([test $gw2_claim_ct = `cat gw2/ovn-controller.log | \
8637 grep -c "cr-alice: Claiming"`])
8639 test_ip_packet gw1 gw2 1
8642 OVS_APP_EXIT_AND_WAIT([ovn-controller])
8643 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
8645 OVN_CLEANUP([hv1],[gw1],[ext1])
8649 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
8650 AT_SKIP_IF([test $HAVE_PYTHON = no])
8657 ovs-vsctl add-br br-phys
8658 ovn_attach n1 br-phys 192.168.0.1
8659 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8660 set interface hv1-vif1 external-ids:iface-id=foo1 \
8661 options:tx_pcap=hv1/vif1-tx.pcap \
8662 options:rxq_pcap=hv1/vif1-rx.pcap \
8667 ovs-vsctl add-br br-phys
8668 ovn_attach n1 br-phys 192.168.0.2
8672 ovs-vsctl add-br br-phys
8673 ovn_attach n1 br-phys 192.168.0.4
8677 ovs-vsctl add-br br-phys
8678 ovn_attach n1 br-phys 192.168.0.3
8679 ovs-vsctl -- add-port br-int ext1-vif1 -- \
8680 set interface ext1-vif1 external-ids:iface-id=outside1 \
8681 options:tx_pcap=ext1/vif1-tx.pcap \
8682 options:rxq_pcap=ext1/vif1-rx.pcap \
8685 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8686 # packets for ARP resolution (native tunneling doesn't queue packets
8687 # for ARP resolution).
8690 ovn-nbctl create Logical_Router name=R0
8691 ovn-nbctl create Logical_Router name=R1
8693 ovn-nbctl ls-add foo
8694 ovn-nbctl ls-add join
8695 ovn-nbctl ls-add alice
8696 ovn-nbctl ls-add outside
8699 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
8700 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
8701 type=router options:router-port=R0-foo \
8702 -- lsp-set-addresses foo-R0 router
8705 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
8706 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
8707 type=router options:router-port=R0-join \
8708 -- lsp-set-addresses join-R0 router
8711 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
8712 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
8713 type=router options:router-port=R1-join \
8714 -- lsp-set-addresses join-R1 router
8717 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
8718 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
8720 # Connect alice to R1 as distributed router gateway port on gw1
8721 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
8724 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8727 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8730 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8732 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8733 type=router options:router-port=alice \
8734 -- lsp-set-addresses rp-alice router
8736 # Create logical port foo1 in foo
8737 ovn-nbctl lsp-add foo foo1 \
8738 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8740 # Create logical port outside1 in outside
8741 ovn-nbctl lsp-add outside outside1 \
8742 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8744 # Create localnet port in alice
8745 ovn-nbctl lsp-add alice ln-alice
8746 ovn-nbctl lsp-set-addresses ln-alice unknown
8747 ovn-nbctl lsp-set-type ln-alice localnet
8748 ovn-nbctl lsp-set-options ln-alice network_name=phys
8750 # Create localnet port in outside
8751 ovn-nbctl lsp-add outside ln-outside
8752 ovn-nbctl lsp-set-addresses ln-outside unknown
8753 ovn-nbctl lsp-set-type ln-outside localnet
8754 ovn-nbctl lsp-set-options ln-outside network_name=phys
8756 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
8757 # mapping to the external network, is the one generating packets
8758 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8759 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8760 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8762 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8764 # hv1 should be in 'ref_chassis' of the ha_chasssi_group as logical
8765 # switch 'foo' can reach the router 'R1' (which has gw router port)
8766 # via foo1 -> foo -> R0 -> join -> R1
8767 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
8769 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
8771 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
8772 test "$hv1_ch_uuid" = "$ref_ch_list"])
8774 # Allow some time for ovn-northd and ovn-controller to catch up.
8775 # XXX This should be more systematic.
8779 printf "%02x%02x%02x%02x" "$@"
8785 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8786 options:rxq_pcap=dummy-rx.pcap
8787 rm -f ${pcap_file}*.pcap
8788 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8789 options:rxq_pcap=${pcap_file}-rx.pcap
8797 # Send ip packet between foo1 and outside1
8798 src_mac="f00000010203" # foo1 mac
8799 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8800 src_ip=`ip_to_hex 192 168 1 2`
8801 dst_ip=`ip_to_hex 172 16 1 3`
8802 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8804 # ARP request packet to expect at outside1
8805 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8807 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8809 # Send ARP reply from outside1 back to the router
8810 # XXX: note, we could avoid this if we plug this port into a netns
8811 # and setup the IP address into the port, so the kernel would simply reply
8812 src_mac="000002010203"
8813 reply_mac="f00000010204"
8814 dst_ip=`ip_to_hex 172 16 1 3`
8815 src_ip=`ip_to_hex 172 16 1 1`
8816 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8818 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8821 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8822 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8825 # Packet to Expect at ext1 chassis, outside1 port
8826 src_mac="000002010203"
8827 dst_mac="f00000010204"
8828 src_ip=`ip_to_hex 192 168 1 2`
8829 dst_ip=`ip_to_hex 172 16 1 3`
8830 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8831 echo $expected > ext1-vif1.expected
8832 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
8833 echo $exp_gw_ip_garp >> ext1-vif1.expected
8835 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8836 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8837 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8839 # Resend packet from foo1 to outside1
8840 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8842 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8843 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8844 cat packets | grep $expected > exp
8845 cat packets | grep $exp_gw_ip_garp | head -1 >> exp
8846 AT_CHECK([cat exp], [0], [expout])
8848 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8849 AT_CHECK([grep $expected packets | sort], [0], [])
8852 test_ip_packet gw1 gw2
8854 ovn-nbctl --timeout=3 --wait=hv \
8855 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8858 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8861 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8863 test_ip_packet gw2 gw1
8865 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8868 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8869 AT_SKIP_IF([test $HAVE_PYTHON = no])
8873 # One LR R1 that has switches foo (192.168.1.0/24) and
8874 # alice (172.16.1.0/24) connected to it. The logical port
8875 # between R1 and alice has a "redirect-chassis" specified,
8876 # i.e. it is the distributed router gateway port.
8877 # Switch alice also has a localnet port defined.
8878 # An additional switch outside has a localnet port and the
8879 # same subnet as alice (172.16.1.0/24).
8882 # Three hypervisors hv[123].
8883 # hv1 hosts vif foo1.
8884 # hv2 is the "redirect-chassis" that hosts the distributed
8885 # router gateway port.
8886 # hv3 hosts vif outside1.
8887 # In order to show that connectivity works only through hv2,
8888 # an initial round of tests is run without any bridge-mapping
8889 # defined for the localnet on hv2. These tests are expected
8891 # Subsequent tests are run after defining the bridge-mapping
8892 # for the localnet on hv2. These tests are expected to succeed.
8894 # Create three hypervisors and create OVS ports corresponding
8900 ovs-vsctl add-br br-phys
8901 ovn_attach n1 br-phys 192.168.0.1
8902 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8903 set interface hv1-vif1 external-ids:iface-id=foo1 \
8904 options:tx_pcap=hv1/vif1-tx.pcap \
8905 options:rxq_pcap=hv1/vif1-rx.pcap \
8910 ovs-vsctl add-br br-phys
8911 ovn_attach n1 br-phys 192.168.0.2
8915 ovs-vsctl add-br br-phys
8916 ovn_attach n1 br-phys 192.168.0.3
8917 ovs-vsctl -- add-port br-int hv3-vif1 -- \
8918 set interface hv3-vif1 external-ids:iface-id=outside1 \
8919 options:tx_pcap=hv3/vif1-tx.pcap \
8920 options:rxq_pcap=hv3/vif1-rx.pcap \
8923 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8924 # packets for ARP resolution (native tunneling doesn't queue packets
8925 # for ARP resolution).
8928 ovn-nbctl create Logical_Router name=R1
8930 ovn-nbctl ls-add foo
8931 ovn-nbctl ls-add alice
8932 ovn-nbctl ls-add outside
8935 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8936 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8937 type=router options:router-port=foo \
8938 -- lsp-set-addresses rp-foo router
8940 # Connect alice to R1 as distributed router gateway port on hv2
8941 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8942 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8943 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8944 type=router options:router-port=alice \
8945 -- lsp-set-addresses rp-alice router
8947 # Create logical port foo1 in foo
8948 ovn-nbctl lsp-add foo foo1 \
8949 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8951 # Create logical port outside1 in outside
8952 ovn-nbctl lsp-add outside outside1 \
8953 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8955 # Create localnet port in alice
8956 ovn-nbctl lsp-add alice ln-alice
8957 ovn-nbctl lsp-set-addresses ln-alice unknown
8958 ovn-nbctl lsp-set-type ln-alice localnet
8959 ovn-nbctl lsp-set-options ln-alice network_name=phys
8961 # Create localnet port in outside
8962 ovn-nbctl lsp-add outside ln-outside
8963 ovn-nbctl lsp-set-addresses ln-outside unknown
8964 ovn-nbctl lsp-set-type ln-outside localnet
8965 ovn-nbctl lsp-set-options ln-outside network_name=phys
8967 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8968 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8969 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8972 # Allow some time for ovn-northd and ovn-controller to catch up.
8973 # XXX This should be more systematic.
8976 echo "---------NB dump-----"
8978 echo "---------------------"
8979 ovn-nbctl list logical_router
8980 echo "---------------------"
8981 ovn-nbctl list logical_router_port
8982 echo "---------------------"
8984 echo "---------SB dump-----"
8985 ovn-sbctl list datapath_binding
8986 echo "---------------------"
8987 ovn-sbctl list port_binding
8988 echo "---------------------"
8989 ovn-sbctl dump-flows
8990 echo "---------------------"
8991 ovn-sbctl list chassis
8992 ovn-sbctl list encap
8993 echo "------ Gateway_Chassis dump (SBDB) -------"
8994 ovn-sbctl list Gateway_Chassis
8995 echo "------ Port_Binding chassisredirect -------"
8996 ovn-sbctl find Port_Binding type=chassisredirect
8997 echo "-------------------------------------------"
8999 echo "------ hv1 dump ----------"
9000 as hv1 ovs-ofctl show br-int
9001 as hv1 ovs-ofctl dump-flows br-int
9002 echo "------ hv2 dump ----------"
9003 as hv2 ovs-ofctl show br-int
9004 as hv2 ovs-ofctl dump-flows br-int
9005 echo "------ hv3 dump ----------"
9006 as hv3 ovs-ofctl show br-int
9007 as hv3 ovs-ofctl dump-flows br-int
9008 echo "--------------------------"
9011 # Check that redirect mapping is programmed only on hv2
9012 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9014 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
9016 # Check that hv1 sends chassisredirect port traffic to hv2
9017 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
9019 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
9021 # Check that arp reply on distributed gateway port is only programmed on hv2
9022 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
9024 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
9029 printf "%02x%02x%02x%02x" "$@"
9033 : > hv2-vif1.expected
9034 : > hv3-vif1.expected
9036 # test_arp INPORT SHA SPA TPA [REPLY_HA]
9038 # Causes a packet to be received on INPORT. The packet is an ARP
9039 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
9040 # it should be the hardware address of the target to expect to receive in an
9041 # ARP reply; otherwise no reply is expected.
9043 # INPORT is an logical switch port number, e.g. 11 for vif11.
9044 # SHA and REPLY_HA are each 12 hex digits.
9045 # SPA and TPA are each 8 hex digits.
9047 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
9048 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
9049 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
9051 if test X$reply_ha != X; then
9052 # Expect to receive the reply, if any.
9053 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
9054 echo $reply >> hv${hv}-vif$inport.expected
9058 rtr_ip=$(ip_to_hex 172 16 1 1)
9059 foo_ip=$(ip_to_hex 192 168 1 2)
9060 outside_ip=$(ip_to_hex 172 16 1 3)
9066 # ARP for router IP address from outside1, no response expected
9067 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
9069 # Now check the packets actually received against the ones expected.
9070 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9072 # Send ip packet between foo1 and outside1
9073 src_mac="f00000010203"
9074 dst_mac="000001010203"
9075 src_ip=`ip_to_hex 192 168 1 2`
9076 dst_ip=`ip_to_hex 172 16 1 3`
9077 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9079 # Now check the packets actually received against the ones expected.
9080 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9082 # Now add bridge-mappings on hv2, which should make everything work
9083 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9085 # Wait until the patch ports are created in hv2 to connect br-int to br-phys
9086 OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
9087 grep "Port patch-br-int-to-ln-alice" | wc -l`])
9089 # ARP for router IP address from outside1
9090 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
9092 # hv3-vif1.expected should also have the gw router port garp packet.
9093 exp_gw_ip_garp=ffffffffffff00000201020308060001080006040001000002010203ac100101000000000000ac100101
9094 echo $exp_gw_ip_garp >> hv3-vif1.expected
9096 # Now check the packets actually received against the ones expected.
9097 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9099 # Send ip packet between foo1 and outside1
9100 src_mac="f00000010203"
9101 dst_mac="000001010203"
9102 src_ip=`ip_to_hex 192 168 1 2`
9103 dst_ip=`ip_to_hex 172 16 1 3`
9104 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9106 # Packet to Expect at outside1
9107 src_mac="000002010203"
9108 dst_mac="f00000010204"
9109 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9111 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9113 echo "------ hv1 dump ----------"
9114 as hv1 ovs-ofctl show br-int
9115 as hv1 ovs-ofctl dump-flows br-int
9116 echo "------ hv2 dump ----------"
9117 as hv2 ovs-ofctl show br-int
9118 as hv2 ovs-ofctl dump-flows br-int
9119 echo "------ hv3 dump ----------"
9120 as hv3 ovs-ofctl show br-int
9121 as hv3 ovs-ofctl dump-flows br-int
9122 echo "----------------------------"
9124 echo $expected >> hv3-vif1.expected
9125 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
9127 #Check ovn-trace over "chassisredirect" port
9128 AT_CAPTURE_FILE([trace])
9130 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
9133 echo 'ip.ttl--;' > expout
9134 echo 'eth.src = 00:00:02:01:02:03;' >> expout
9135 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
9136 echo 'output("ln-alice");' >> expout
9137 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])
9139 # Create logical port alice1 in alice on hv1
9140 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9141 set interface hv1-vif2 external-ids:iface-id=alice1 \
9142 options:tx_pcap=hv1/vif2-tx.pcap \
9143 options:rxq_pcap=hv1/vif2-rx.pcap \
9146 ovn-nbctl lsp-add alice alice1 \
9147 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
9149 # Create logical port foo2 in foo on hv2
9150 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9151 set interface hv2-vif1 external-ids:iface-id=foo2 \
9152 options:tx_pcap=hv2/vif1-tx.pcap \
9153 options:rxq_pcap=hv2/vif1-rx.pcap \
9156 ovn-nbctl lsp-add foo foo2 \
9157 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
9159 # Allow some time for ovn-northd and ovn-controller to catch up.
9160 # XXX This should be more systematic.
9163 : > hv1-vif2.expected
9165 # Send ip packet between alice1 and foo2
9166 src_mac="f00000010205"
9167 dst_mac="000002010203"
9168 src_ip=`ip_to_hex 172 16 1 4`
9169 dst_ip=`ip_to_hex 192 168 1 3`
9170 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9172 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
9174 # Packet to Expect at foo2
9175 src_mac="000001010203"
9176 dst_mac="f00000010206"
9177 src_ip=`ip_to_hex 172 16 1 4`
9178 dst_ip=`ip_to_hex 192 168 1 3`
9179 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
9181 echo $expected >> hv2-vif1.expected
9182 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
9184 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
9187 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
9189 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
9192 OVN_CLEANUP([hv1],[hv2],[hv3])
9196 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
9197 AT_SKIP_IF([test $HAVE_PYTHON = no])
9199 # Create logical switches
9200 ovn-nbctl ls-add ls0
9201 ovn-nbctl ls-add ls1
9202 # Create distributed router
9203 ovn-nbctl create Logical_Router name=lr0
9204 # Add distributed gateway port to distributed router
9205 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
9206 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
9207 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9208 type=router options:router-port=lrp0 addresses="router"
9209 # Add router port to ls1
9210 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9211 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9212 type=router options:router-port=lrp1 addresses="router"
9213 # Add logical ports for NAT rules
9214 ovn-nbctl lsp-add ls1 foo1 \
9215 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
9216 ovn-nbctl lsp-add ls1 foo2 \
9217 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
9218 # Add nat-addresses option
9219 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9221 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
9222 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
9223 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])
9224 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])
9229 ovs-vsctl add-br br-phys
9230 ovn_attach n1 br-phys 192.168.0.1
9232 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9233 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])
9237 ovs-vsctl add-br br-phys
9238 ovn_attach n1 br-phys 192.168.0.2
9239 # Initially test with no bridge-mapping on hv2, expect to receive no packets
9243 ovs-vsctl add-br br-phys
9244 ovn_attach n1 br-phys 192.168.0.3
9245 # Initially test with no bridge-mapping on hv3
9247 # Create a localnet port.
9248 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9249 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9250 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9251 AT_CHECK([ovn-nbctl --wait=hv lsp-set-options ln_port network_name=physnet1])
9253 # Allow some time for ovn-northd and ovn-controller to catch up.
9254 # XXX This should be more systematic.
9257 # Expect no packets when hv2 bridge-mapping is not present
9259 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
9261 # Add bridge-mapping on hv2
9262 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9264 # Wait until the patch ports are created in hv2 to connect br-int to br-phys
9265 OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-vsctl show | \
9266 grep "Port patch-br-int-to-ln_port" | wc -l`])
9268 # Wait for packets to be received.
9269 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9271 sed 's/\(00\)\{1,\}$//'
9273 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9274 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
9275 echo $expected > expout
9276 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
9277 echo $expected >> expout
9278 AT_CHECK([sort packets], [0], [expout])
9281 # Temporarily remove nat-addresses option to avoid race conditions
9282 # due to GARP backoff
9283 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
9288 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9289 options:rxq_pcap=dummy-rx.pcap
9290 rm -f ${pcap_file}*.pcap
9291 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9292 options:rxq_pcap=${pcap_file}-rx.pcap
9295 as hv1 reset_pcap_file snoopvif hv1/snoopvif
9297 # Add OVS ports for foo1 and foo2 on hv3
9298 ovs-vsctl -- add-port br-int hv3-vif1 -- \
9299 set interface hv3-vif1 external-ids:iface-id=foo1 \
9301 ovs-vsctl -- add-port br-int hv3-vif2 -- \
9302 set interface hv3-vif2 external-ids:iface-id=foo2 \
9305 # Add bridge-mapping on hv3
9306 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9308 # Wait until the patch ports are created in hv3 to connect br-int to br-phys
9309 OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-vsctl show | \
9310 grep "Port patch-br-int-to-ln_port" | wc -l`])
9312 # Re-add nat-addresses option
9313 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
9315 # Wait for packets to be received.
9316 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
9318 sed 's/\(00\)\{1,\}$//'
9321 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
9322 garp_1="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
9323 echo $garp_1 > expout
9324 garp_2="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
9325 echo $garp_2 >> expout
9327 cat packets | grep $garp_1 | head -1 > exp
9328 cat packets | grep $garp_2 | head -1 >> exp
9329 AT_CHECK([cat exp], [0], [expout])
9331 OVN_CLEANUP([hv1],[hv2],[hv3])
9335 # VLAN traffic for external network redirected through distributed router
9336 # gateway port should use vlans(i.e input network vlan tag) across hypervisors
9337 # instead of tunneling.
9338 AT_SETUP([ovn -- vlan traffic for external network with distributed router gateway port])
9339 AT_SKIP_IF([test $HAVE_PYTHON = no])
9343 # # One LR R1 that has switches foo (192.168.1.0/24) and
9344 # # alice (172.16.1.0/24) connected to it. The logical port
9345 # # between R1 and alice has a "redirect-chassis" specified,
9346 # # i.e. it is the distributed router gateway port(172.16.1.6).
9347 # # Switch alice also has a localnet port defined.
9348 # # An additional switch outside has the same subnet as alice
9349 # # (172.16.1.0/24), a localnet port and nexthop port(172.16.1.1)
9350 # # which will receive the packet destined for external network
9351 # # (i.e 8.8.8.8 as destination ip).
9354 # # Four hypervisors hv[1234].
9355 # # hv1 hosts vif foo1.
9356 # # hv2 is the "redirect-chassis" that hosts the distributed router gateway port.
9357 # # Later to test GARPs for the router port - foo, hv2 and hv4 are added to the ha_chassis_group
9358 # # hv3 hosts nexthop port vif outside1.
9359 # # All other tests connect hypervisors to network n1 through br-phys for tunneling.
9360 # # But in this test, hv1 won't connect to n1(and no br-phys in hv1), and
9361 # # in order to show vlans(instead of tunneling) used between hv1 and hv2,
9362 # # a new network n2 created and hv1 and hv2 connected to this network through br-ex.
9363 # # hv2 and hv3 are still connected to n1 network through br-phys.
9366 # We are not calling ovn_attach for hv1, to avoid adding br-phys.
9367 # Tunneling won't work in hv1 as ovn-encap-ip is not added to any bridge in hv1
9371 -- set Open_vSwitch . external-ids:system-id=hv1 \
9372 -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
9373 -- set Open_vSwitch . external-ids:ovn-encap-type=geneve,vxlan \
9374 -- set Open_vSwitch . external-ids:ovn-encap-ip=192.168.0.1 \
9376 -- set bridge br-int fail-mode=secure other-config:disable-in-band=true \
9377 -- set Open_vSwitch . external-ids:ovn-bridge-mappings=public:br-ex
9379 start_daemon ovn-controller
9380 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9381 set interface hv1-vif1 external-ids:iface-id=foo1 \
9382 options:tx_pcap=hv1/vif1-tx.pcap \
9383 options:rxq_pcap=hv1/vif1-rx.pcap \
9388 ovs-vsctl add-br br-phys
9389 ovn_attach n1 br-phys 192.168.0.2
9390 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9394 ovs-vsctl add-br br-phys
9395 ovn_attach n1 br-phys 192.168.0.3
9396 ovs-vsctl -- add-port br-int hv3-vif1 -- \
9397 set interface hv3-vif1 external-ids:iface-id=outside1 \
9398 options:tx_pcap=hv3/vif1-tx.pcap \
9399 options:rxq_pcap=hv3/vif1-rx.pcap \
9401 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="phys:br-phys"
9405 ovs-vsctl add-br br-phys
9406 ovn_attach n1 br-phys 192.168.0.4
9407 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings="public:br-ex,phys:br-phys"
9409 # Create network n2 for vlan connectivity between hv1 and hv2
9413 ovs-vsctl add-br br-ex
9417 ovs-vsctl add-br br-ex
9421 ovs-vsctl add-br br-ex
9426 ovn-nbctl create Logical_Router name=R1
9428 ovn-nbctl ls-add foo
9429 ovn-nbctl ls-add alice
9430 ovn-nbctl ls-add outside
9433 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
9434 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
9435 type=router options:router-port=foo \
9436 -- lsp-set-addresses rp-foo router
9438 # Connect alice to R1 as distributed router gateway port (172.16.1.6) on hv2
9439 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.6/24 \
9440 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
9441 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9442 type=router options:router-port=alice \
9443 -- lsp-set-addresses rp-alice router \
9445 # Create logical port foo1 in foo
9446 ovn-nbctl lsp-add foo foo1 \
9447 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9449 # Create logical port outside1 in outside, which is a nexthop address
9451 ovn-nbctl lsp-add outside outside1 \
9452 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.1"
9454 # Set default gateway (nexthop) to 172.16.1.1
9455 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 172.16.1.1 alice
9456 AT_CHECK([ovn-nbctl lr-nat-add R1 snat 172.16.1.6 192.168.1.1/24])
9457 ovn-nbctl set Logical_Switch_Port rp-alice options:nat-addresses=router
9459 ovn-nbctl lsp-add foo ln-foo
9460 ovn-nbctl lsp-set-addresses ln-foo unknown
9461 ovn-nbctl lsp-set-options ln-foo network_name=public
9462 ovn-nbctl lsp-set-type ln-foo localnet
9463 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln-foo tag=2])
9465 # Create localnet port in alice
9466 ovn-nbctl lsp-add alice ln-alice
9467 ovn-nbctl lsp-set-addresses ln-alice unknown
9468 ovn-nbctl lsp-set-type ln-alice localnet
9469 ovn-nbctl lsp-set-options ln-alice network_name=phys
9471 # Create localnet port in outside
9472 ovn-nbctl lsp-add outside ln-outside
9473 ovn-nbctl lsp-set-addresses ln-outside unknown
9474 ovn-nbctl lsp-set-type ln-outside localnet
9475 ovn-nbctl lsp-set-options ln-outside network_name=phys
9477 # Allow some time for ovn-northd and ovn-controller to catch up.
9478 # XXX This should be more systematic.
9479 ovn-nbctl --wait=hv --timeout=3 sync
9481 # Check that there is a logical flow in logical switch foo's pipeline
9482 # to set the outport to rp-foo (which is expected).
9483 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9484 grep rp-foo | grep -v is_chassis_resident | wc -l`])
9486 # Set the option 'reside-on-redirect-chassis' for foo
9487 ovn-nbctl set logical_router_port foo options:reside-on-redirect-chassis=true
9488 # Check that there is a logical flow in logical switch foo's pipeline
9489 # to set the outport to rp-foo with the condition is_chassis_redirect.
9490 ovn-sbctl dump-flows foo
9491 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl dump-flows foo | grep ls_in_l2_lkup | \
9492 grep rp-foo | grep is_chassis_resident | wc -l`])
9494 echo "---------NB dump-----"
9496 echo "---------------------"
9497 ovn-nbctl list logical_router
9498 echo "---------------------"
9500 echo "---------------------"
9501 ovn-nbctl list logical_router_port
9502 echo "---------------------"
9504 echo "---------SB dump-----"
9505 ovn-sbctl list datapath_binding
9506 echo "---------------------"
9507 ovn-sbctl list port_binding
9508 echo "---------------------"
9509 ovn-sbctl dump-flows
9510 echo "---------------------"
9511 ovn-sbctl list chassis
9512 echo "---------------------"
9514 for chassis in hv1 hv2 hv3; do
9516 echo "------ $chassis dump ----------"
9517 ovs-vsctl show br-int
9518 ovs-ofctl show br-int
9519 ovs-ofctl dump-flows br-int
9520 echo "--------------------------"
9524 printf "%02x%02x%02x%02x" "$@"
9527 foo1_ip=$(ip_to_hex 192 168 1 2)
9528 gw_ip=$(ip_to_hex 172 16 1 6)
9529 dst_ip=$(ip_to_hex 8 8 8 8)
9530 nexthop_ip=$(ip_to_hex 172 16 1 1)
9532 foo1_mac="f00000010203"
9533 foo_mac="000001010203"
9534 gw_mac="000002010203"
9535 nexthop_mac="f00000010204"
9537 # Send ip packet from foo1 to 8.8.8.8
9538 src_mac="f00000010203"
9539 dst_mac="000001010203"
9540 packet=${foo_mac}${foo1_mac}08004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9542 # Wait for GARPs announcing gw IP to arrive
9544 test `as hv2 ovs-ofctl dump-flows br-int | grep table=66 | \
9545 grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
9548 # VLAN tagged packet with router port(192.168.1.1) MAC as destination MAC
9549 # is expected on bridge connecting hv1 and hv2
9550 expected=${foo_mac}${foo1_mac}8100000208004500001c0000000040110000${foo1_ip}${dst_ip}0035111100080000
9551 echo $expected > hv1-br-ex_n2.expected
9553 # Packet to Expect at outside1 i.e nexthop(172.16.1.1) port.
9554 # As connection tracking not enabled for this test, snat can't be done on the packet.
9555 # We still see foo1 as the source ip address. But source mac(gateway MAC) and
9556 # dest mac(nexthop mac) are properly configured.
9557 expected=${nexthop_mac}${gw_mac}08004500001c000000003f110100${foo1_ip}${dst_ip}0035111100080000
9558 echo $expected > hv3-vif1.expected
9563 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9564 options:rxq_pcap=dummy-rx.pcap
9565 rm -f ${pcap_file}*.pcap
9566 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9567 options:rxq_pcap=${pcap_file}-rx.pcap
9570 as hv1 reset_pcap_file br-ex_n2 hv1/br-ex_n2
9571 as hv3 reset_pcap_file hv3-vif1 hv3/vif1
9572 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9575 # On hv1, table 32 check that no packet goes via the tunnel port
9576 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 \
9577 | grep "NXM_NX_TUN_ID" | grep -v n_packets=0 | wc -l], [0], [[0
9581 grep "1010203f00000010203"
9584 # Check vlan tagged packet on the bridge connecting hv1 and hv2 with the
9586 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-ex_n2-tx.pcap | ip_packet | uniq > hv1-br-ex_n2
9587 cat hv1-br-ex_n2.expected > expout
9588 AT_CHECK([sort hv1-br-ex_n2], [0], [expout])
9590 # Check expected packet on nexthop interface
9591 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/vif1-tx.pcap | grep ${foo1_ip}${dst_ip} | uniq > hv3-vif1
9592 cat hv3-vif1.expected > expout
9593 AT_CHECK([sort hv3-vif1], [0], [expout])
9595 # Test the GARP for the router port ip - 192.168.1.1
9596 ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
9598 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
9599 as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
9600 as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
9602 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv2 30
9603 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 20
9605 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
9606 ovn-nbctl remove logical_router_port alice options redirect-chassis
9607 ovn-nbctl --wait=sb set logical_router_port alice ha_chassis_group=$hagrp1_uuid
9609 # When hv2 claims the gw router port cr-alice, it should send out
9610 # GARP for 192.168.1.1 and it should be received by foo1 on hv1.
9612 # foo1 (on hv1) should receive GARP without VLAN tag
9613 exp_garp_on_foo1="ffffffffffff00000101020308060001080006040001000001010203c0a80101000000000000c0a80101"
9614 echo $exp_garp_on_foo1 > foo1.expout
9616 # ovn-controller on hv2 should send garp with VLAN tag
9617 sent_garp="ffffffffffff0000010102038100000208060001080006040001000001010203c0a80101000000000000c0a80101"
9619 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
9620 # Wait until we receive atleast 1 packet
9621 OVS_WAIT_UNTIL([test 1=`$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | wc -l`])
9622 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap | head -1 > packets
9623 echo $sent_garp > expout
9624 AT_CHECK([cat packets], [0], [expout])
9625 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv4/br-ex_n2-tx.pcap > empty
9626 AT_CHECK([cat empty], [0], [])
9629 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
9630 as hv4 reset_pcap_file br-ex_n2 hv4/br-ex_n2
9631 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 hv4 40
9633 # Wait till cr-alice is claimed by hv4
9634 hv4_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=hv4)
9635 # check that the chassis redirect port has been claimed by the gw1 chassis
9636 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
9637 logical_port=cr-alice | grep $hv4_chassis | wc -l], [0],[[1
9640 # Reset the pcap file for hv2/br-ex_n2. From now on ovn-controller in hv2
9641 # should not send GARPs for the router ports.
9642 as hv2 reset_pcap_file br-ex_n2 hv2/br-ex_n2
9644 echo $sent_garp > br-ex_n2.expout
9645 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [foo1.expout])
9646 OVN_CHECK_PACKETS([hv4/br-ex_n2-tx.pcap], [br-ex_n2.expout])
9650 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-ex_n2-tx.pcap > empty
9651 AT_CHECK([cat empty], [0], [])
9653 OVN_CLEANUP([hv1],[hv2],[hv3], [hv4])
9656 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
9657 AT_KEYWORDS([ovn-nd_ra])
9658 AT_SKIP_IF([test $HAVE_PYTHON = no])
9661 # In this test case we create 1 lswitch with 3 VIF ports attached,
9662 # and a lrouter connected to the lswitch.
9663 # We generate the Router solicitation packet and verify the Router Advertisement
9664 # reply packet from the ovn-controller.
9666 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
9667 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
9668 # 'slaac' to allow lrp0 send RA for SLAAC mode.
9669 ovn-nbctl ls-add lsw0
9670 ovn-nbctl lr-add lr0
9671 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
9672 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
9674 -- lsp-add lsw0 lsp0 \
9675 -- set Logical_Switch_Port lsp0 type=router \
9676 options:router-port=lrp0 \
9677 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
9681 ovs-vsctl add-br br-phys
9682 ovn_attach n1 br-phys 192.168.0.2
9684 ovn-nbctl lsp-add lsw0 lp1
9685 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
9686 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"
9688 ovn-nbctl lsp-add lsw0 lp2
9689 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
9690 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"
9692 ovn-nbctl lsp-add lsw0 lp3
9693 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
9694 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"
9696 # Add ACL rule for ICMPv6 on lsw0
9697 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
9698 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
9699 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
9700 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
9702 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9703 set interface hv1-vif1 external-ids:iface-id=lp1 \
9704 options:tx_pcap=hv1/vif1-tx.pcap \
9705 options:rxq_pcap=hv1/vif1-rx.pcap \
9708 ovs-vsctl -- add-port br-int hv1-vif2 -- \
9709 set interface hv1-vif2 external-ids:iface-id=lp2 \
9710 options:tx_pcap=hv1/vif2-tx.pcap \
9711 options:rxq_pcap=hv1/vif2-rx.pcap \
9714 ovs-vsctl -- add-port br-int hv1-vif3 -- \
9715 set interface hv1-vif3 external-ids:iface-id=lp3 \
9716 options:tx_pcap=hv1/vif3-tx.pcap \
9717 options:rxq_pcap=hv1/vif3-rx.pcap \
9720 # Allow some time for ovn-northd and ovn-controller to catch up.
9721 # XXX This should be more systematic.
9727 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9728 options:rxq_pcap=dummy-rx.pcap
9729 rm -f ${pcap_file}*.pcap
9730 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9731 options:rxq_pcap=${pcap_file}-rx.pcap
9734 # Make sure that ovn-controller has installed the corresponding OF Flow.
9735 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"`])
9737 # This shell function sends a Router Solicitation packet.
9738 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
9740 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
9741 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
9745 if test $mtu != 0; then
9747 mtu_opt=05010000${mtu}
9750 if test ${#prefix_opt} != 0; then
9751 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
9752 len=`expr $len + ${#prefix_opt} / 2`
9755 len=$(printf "%x" $len)
9756 local lrp_mac=fa163e000001
9757 local lrp_lla=fe80000000000000f8163efffe000001
9758 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
9759 echo $reply >> $inport.expected
9761 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
9764 AT_CAPTURE_FILE([ofctl_monitor0.log])
9765 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
9766 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
9768 # MTU is not set and the address mode is set to slaac
9770 default_prefix_option_config=030440c0ffffffffffffffff00000000
9771 src_mac=fa163e000002
9772 src_lla=fe80000000000000f8163efffe000002
9773 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
9775 # NXT_RESUME should be 1.
9776 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9778 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9780 cat 1.expected | cut -c -112 > expout
9781 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9783 # Skipping the ICMPv6 checksum.
9784 cat 1.expected | cut -c 117- > expout
9785 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9788 reset_pcap_file hv1-vif1 hv1/vif1
9789 reset_pcap_file hv1-vif2 hv1/vif2
9790 reset_pcap_file hv1-vif3 hv1/vif3
9792 # Set the MTU to 1500
9793 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
9795 # Make sure that ovn-controller has installed the corresponding OF Flow.
9796 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"`])
9799 default_prefix_option_config=030440c0ffffffffffffffff00000000
9800 src_mac=fa163e000003
9801 src_lla=fe80000000000000f8163efffe000003
9804 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9806 # NXT_RESUME should be 2.
9807 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9809 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
9811 cat 2.expected | cut -c -112 > expout
9812 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9814 # Skipping the ICMPv6 checksum.
9815 cat 2.expected | cut -c 117- > expout
9816 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9819 reset_pcap_file hv1-vif1 hv1/vif1
9820 reset_pcap_file hv1-vif2 hv1/vif2
9821 reset_pcap_file hv1-vif3 hv1/vif3
9823 # Set the address mode to dhcpv6_stateful
9824 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
9825 # Make sure that ovn-controller has installed the corresponding OF Flow.
9826 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"`])
9829 default_prefix_option_config=03044080ffffffffffffffff00000000
9830 src_mac=fa163e000004
9831 src_lla=fe80000000000000f8163efffe000004
9834 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9836 # NXT_RESUME should be 3.
9837 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9839 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
9841 cat 3.expected | cut -c -112 > expout
9842 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
9844 # Skipping the ICMPv6 checksum.
9845 cat 3.expected | cut -c 117- > expout
9846 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
9849 reset_pcap_file hv1-vif1 hv1/vif1
9850 reset_pcap_file hv1-vif2 hv1/vif2
9851 reset_pcap_file hv1-vif3 hv1/vif3
9853 # Set the address mode to dhcpv6_stateless
9854 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
9855 # Make sure that ovn-controller has installed the corresponding OF Flow.
9856 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"`])
9859 default_prefix_option_config=030440c0ffffffffffffffff00000000
9860 src_mac=fa163e000002
9861 src_lla=fe80000000000000f8163efffe000002
9864 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9866 # NXT_RESUME should be 4.
9867 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9869 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9871 cat 1.expected | cut -c -112 > expout
9872 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9874 # Skipping the ICMPv6 checksum.
9875 cat 1.expected | cut -c 117- > expout
9876 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9879 reset_pcap_file hv1-vif1 hv1/vif1
9880 reset_pcap_file hv1-vif2 hv1/vif2
9881 reset_pcap_file hv1-vif3 hv1/vif3
9883 # Set the address mode to invalid.
9884 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
9885 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
9886 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"`])
9889 default_prefix_option_config=""
9890 src_mac=fa163e000002
9891 src_lla=fe80000000000000f8163efffe000002
9894 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
9896 # NXT_RESUME should be 4 only.
9897 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
9899 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
9900 AT_CHECK([cat 1.packets], [0], [])
9905 AT_SETUP([ovn -- /32 router IP address])
9906 AT_SKIP_IF([test $HAVE_PYTHON = no])
9910 # 2 LS 'foo' and 'alice' connected via router R1.
9911 # R1 connects to 'alice' with a /32 IP address. We use static routes and
9912 # nexthop to push traffic to a logical port in switch 'alice'
9916 ovn-nbctl ls-add foo
9917 ovn-nbctl ls-add alice
9920 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
9921 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
9922 options:router-port=foo addresses=\"00:00:00:01:02:03\"
9924 # Connect alice to R1.
9925 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
9926 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
9927 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
9929 # Create logical port foo1 in foo
9930 ovn-nbctl lsp-add foo foo1 \
9931 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
9933 # Create logical port alice1 in alice
9934 ovn-nbctl lsp-add alice alice1 \
9935 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
9937 #install default route in R1 to use alice1's IP address as nexthop
9938 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
9940 # Create two hypervisor and create OVS ports corresponding to logical ports.
9945 ovs-vsctl add-br br-phys
9946 ovn_attach n1 br-phys 192.168.0.1
9947 ovs-vsctl -- add-port br-int hv1-vif1 -- \
9948 set interface hv1-vif1 external-ids:iface-id=foo1 \
9949 options:tx_pcap=hv1/vif1-tx.pcap \
9950 options:rxq_pcap=hv1/vif1-rx.pcap \
9955 ovs-vsctl add-br br-phys
9956 ovn_attach n1 br-phys 192.168.0.2
9957 ovs-vsctl -- add-port br-int hv2-vif1 -- \
9958 set interface hv2-vif1 external-ids:iface-id=alice1 \
9959 options:tx_pcap=hv2/vif1-tx.pcap \
9960 options:rxq_pcap=hv2/vif1-rx.pcap \
9964 # Pre-populate the hypervisors' ARP tables so that we don't lose any
9965 # packets for ARP resolution (native tunneling doesn't queue packets
9966 # for ARP resolution).
9969 # Allow some time for ovn-northd and ovn-controller to catch up.
9970 # XXX This should be more systematic.
9974 printf "%02x%02x%02x%02x" "$@"
9977 # Send ip packets between foo1 and alice1
9978 src_mac="f00000010203"
9979 dst_mac="000000010203"
9980 src_ip=`ip_to_hex 192 168 1 2`
9981 dst_ip=`ip_to_hex 10 0 0 2`
9982 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9984 # Send the first packet to trigger a ARP response and population of
9985 # mac_bindings table.
9986 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
9987 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
9988 ovn-nbctl --wait=hv sync
9990 # Packet to Expect at 'alice1'
9991 src_mac="000000010204"
9992 dst_mac="f00000010204"
9993 src_ip=`ip_to_hex 192 168 1 2`
9994 dst_ip=`ip_to_hex 10 0 0 2`
9995 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
9997 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
9999 OVN_CLEANUP([hv1],[hv2])
10003 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
10004 AT_SKIP_IF([test $HAVE_PYTHON = no])
10007 ovn-nbctl ls-add ls1
10009 # Add localport to the switch
10010 ovn-nbctl lsp-add ls1 lp01
10011 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
10012 ovn-nbctl lsp-set-type lp01 localport
10019 ovs-vsctl add-br br-phys
10020 ovn_attach n1 br-phys 192.168.0.$i
10021 ovs-vsctl add-port br-int vif01 -- \
10022 set Interface vif01 external-ids:iface-id=lp01 \
10023 options:tx_pcap=hv${i}/vif01-tx.pcap \
10024 options:rxq_pcap=hv${i}/vif01-rx.pcap \
10025 ofport-request=${i}0
10027 ovs-vsctl add-port br-int vif${i}1 -- \
10028 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
10029 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
10030 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
10031 ofport-request=${i}1
10033 ovn-nbctl lsp-add ls1 lp${i}1
10034 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
10035 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
10037 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
10040 ovn-nbctl --wait=sb sync
10041 ovn-sbctl dump-flows
10045 # Given the name of a logical port, prints the name of the hypervisor
10046 # on which it is located.
10051 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
10053 # This shell function causes a packet to be received on INPORT. The packet's
10054 # content has Ethernet destination DST and source SRC (each exactly 12 hex
10055 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
10056 # logical switch port numbers, e.g. 11 for vif11.
10058 # EOUT is the end-to-end output port, that is, where the packet will end up
10059 # after possibly bouncing through one or more localnet ports. LOUT is the
10060 # logical output port, which might be a localnet port, as seen by ovn-trace
10061 # (which doesn't know what localnet ports are connected to and therefore can't
10062 # figure out the end-to-end answer).
10064 # DEFHV is the default hypervisor from where the packet is going to be sent
10065 # if the source port is a localport.
10072 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
10075 # First try tracing the packet.
10076 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
10077 if test $lout != drop; then
10078 echo "output(\"$lout\");"
10080 AT_CAPTURE_FILE([trace])
10081 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
10083 # Then actually send a packet, for an end-to-end test.
10084 local packet=$(echo $dst$src | sed 's/://g')${eth}
10085 hv=`vif_to_hv $inport`
10086 # If hypervisor 0 (localport) use the defhv parameter
10087 if test $hv = hv0; then
10091 as $hv ovs-appctl netdev-dummy/receive $vif $packet
10092 if test $eout != drop; then
10093 echo $packet >> ${eout#lp}.expected
10098 # lp11 and lp21 are on different hypervisors
10099 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
10100 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
10102 # Both VIFs should be able to reach the localport on their own HV
10103 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
10104 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
10106 # Packet sent from localport on same hv should reach the vif
10107 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
10108 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
10110 # Packet sent from localport on different hv should be dropped
10111 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
10112 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
10114 # Now check the packets actually received against the ones expected.
10117 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
10121 OVN_CLEANUP([hv1],[hv2])
10125 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
10126 AT_SKIP_IF([test $HAVE_PYTHON = no])
10131 # create gateways with external network connectivity
10136 ovs-vsctl add-br br-phys
10137 ovn_attach n1 br-phys 192.168.0.$i
10138 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10141 ovn-nbctl ls-add inside
10142 ovn-nbctl ls-add outside
10144 # create hypervisors with a vif port each to an internal network
10149 ovs-vsctl add-br br-phys
10150 ovn_attach n1 br-phys 192.168.0.1$i
10151 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10152 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10153 options:tx_pcap=hv$i/vif1-tx.pcap \
10154 options:rxq_pcap=hv$i/vif1-rx.pcap \
10157 ovn-nbctl lsp-add inside inside$i \
10158 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
10164 ovn-nbctl create Logical_Router name=R1
10166 # Connect inside to R1
10167 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10168 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10169 type=router options:router-port=inside \
10170 -- lsp-set-addresses rp-inside router
10172 # Connect outside to R1 as distributed router gateway port on gw1+gw2
10173 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10175 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10176 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10177 --id=@gc1 create Gateway_Chassis \
10178 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10179 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10181 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10182 type=router options:router-port=outside \
10183 -- lsp-set-addresses rp-outside router
10185 # Create localnet port in outside
10186 ovn-nbctl lsp-add outside ln-outside
10187 ovn-nbctl lsp-set-addresses ln-outside unknown
10188 ovn-nbctl lsp-set-type ln-outside localnet
10189 ovn-nbctl lsp-set-options ln-outside network_name=phys
10191 # Allow some time for ovn-northd and ovn-controller to catch up.
10192 # XXX This should be more systematic.
10193 ovn-nbctl --wait=hv --timeout=3 sync
10195 echo "---------NB dump-----"
10197 echo "---------------------"
10198 ovn-nbctl list logical_router
10199 echo "---------------------"
10200 ovn-nbctl list logical_router_port
10201 echo "---------------------"
10203 echo "---------SB dump-----"
10204 ovn-sbctl list datapath_binding
10205 echo "---------------------"
10206 ovn-sbctl list port_binding
10207 echo "---------------------"
10208 ovn-sbctl dump-flows
10209 echo "---------------------"
10210 ovn-sbctl list chassis
10211 ovn-sbctl list encap
10212 echo "---------------------"
10213 echo "------ Gateway_Chassis dump (SBDB) -------"
10214 ovn-sbctl list Gateway_Chassis
10215 echo "------ Port_Binding chassisredirect -------"
10216 ovn-sbctl find Port_Binding type=chassisredirect
10217 echo "-------------------------------------------"
10219 # There should be one ha_chassis_group with the name "outside"
10220 ha_chassi_grp_name=`ovn-sbctl --bare --columns name find \
10221 ha_chassis_group name="outside"`
10223 AT_CHECK([test $ha_chassi_grp_name = outside])
10225 # There should be 2 ha_chassis rows in SB DB.
10226 AT_CHECK([ovn-sbctl list ha_chassis | grep chassis | \
10227 grep -v chassis-name | awk '{print $3}' \
10228 | grep '-' | wc -l ], [0], [2
10231 ha_ch=`ovn-sbctl --bare --columns ha_chassis find ha_chassis_group`
10233 ha_ch=`echo $ha_ch | sed 's/ //g'`
10236 for i in `ovn-sbctl --bare --columns _uuid list ha_chassis | sort`
10238 ha_ch_list="$ha_ch_list $i"
10242 ha_ch_list=`echo $ha_ch_list | sed 's/ //g'`
10244 AT_CHECK([test "$ha_ch_list" = "$ha_ch"])
10246 for chassis in gw1 gw2 hv1 hv2; do
10248 echo "------ $chassis dump ----------"
10249 ovs-ofctl show br-int
10250 ovs-ofctl dump-flows br-int
10251 echo "--------------------------"
10254 for chassis in gw1 gw2 hv1 hv2; do
10256 echo "------ $chassis dump (BFD)----"
10257 echo "BFD (from $chassis):"
10258 # dump BFD config and status to the other chassis
10259 for chassis2 in gw1 gw2 hv1 hv2; do
10260 if [[ "$chassis" != "$chassis2" ]]; then
10261 echo " -> $chassis2:"
10262 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
10265 echo "--------------------------"
10271 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10272 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10273 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
10274 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
10276 echo $hv1_gw1_ofport
10277 echo $hv1_gw2_ofport
10278 echo $hv2_gw1_ofport
10279 echo $hv2_gw2_ofport
10282 as hv1 ovs-ofctl dump-flows br-int table=32
10285 as hv2 ovs-ofctl dump-flows br-int table=32
10287 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
10288 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10290 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10291 grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10295 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10296 grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10300 # make sure that flows for handling the outside router port reside on gw1
10301 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10302 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10304 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10305 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10308 # make sure ARP responder flows for outside router port reside on gw1 too
10309 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10310 grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10312 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10315 # check that the chassis redirect port has been claimed by the gw1 chassis
10316 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10317 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10320 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10321 hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10324 for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10326 if test $i = $hv1_ch_uuid; then
10327 exp_ref_ch_list="${exp_ref_ch_list}$i"
10328 elif test $i = $hv2_ch_uuid; then
10329 exp_ref_ch_list="${exp_ref_ch_list}$i"
10334 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10336 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10337 test "$exp_ref_ch_list" = "$ref_ch_list"])
10340 # at this point, we invert the priority of the gw chassis between gw1 and gw2
10342 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10343 name=outside_gw1 chassis_name=gw1 priority=10 -- \
10344 --id=@gc1 create Gateway_Chassis \
10345 name=outside_gw2 chassis_name=gw2 priority=20 -- \
10346 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10349 # XXX: Let the change propagate down to the ovn-controllers
10350 ovn-nbctl --wait=hv --timeout=3 sync
10352 # we make sure that the hypervisors noticed, and inverted the slave ports
10353 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10354 grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10358 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10359 grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10363 # check that the chassis redirect port has been reclaimed by the gw2 chassis
10364 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10365 logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10368 # check BFD enablement on tunnel ports from gw1 #########
10370 for chassis in gw2 hv1 hv2; do
10371 echo "checking gw1 -> $chassis"
10372 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10378 # check BFD enablement on tunnel ports from gw2 ##########
10380 for chassis in gw1 hv1 hv2; do
10381 echo "checking gw2 -> $chassis"
10382 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10387 # check BFD enablement on tunnel ports from hv1 ###########
10389 for chassis in gw1 gw2; do
10390 echo "checking hv1 -> $chassis"
10391 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10395 # make sure BFD is not enabled to hv2, we don't need it
10396 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10401 # check BFD enablement on tunnel ports from hv2 ##########
10403 for chassis in gw1 gw2; do
10404 echo "checking hv2 -> $chassis"
10405 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10409 # make sure BFD is not enabled to hv1, we don't need it
10410 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10414 # make sure that flows for handling the outside router port reside on gw2 now
10415 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10416 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10418 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10419 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10422 # disconnect GW2 from the network, GW1 should take over
10424 port=${sandbox}_br-phys
10425 as main ovs-vsctl del-port n1 $port
10429 # make sure that flows for handling the outside router port reside on gw2 now
10430 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=25 | \
10431 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10433 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=25 | \
10434 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10437 # check that the chassis redirect port has been reclaimed by the gw1 chassis
10438 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10439 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10442 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-rx"=2000
10444 for chassis in gw1 hv1 hv2; do
10445 echo "checking gw2 -> $chassis"
10447 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10448 test "$bfd_cfg" = "enable=true min_rx=2000"
10451 ovn-nbctl --wait=hv set NB_Global . options:"bfd-min-tx"=1500
10452 for chassis in gw1 hv1 hv2; do
10453 echo "checking gw2 -> $chassis"
10455 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10456 test "$bfd_cfg" = "enable=true min_rx=2000 min_tx=1500"
10459 ovn-nbctl remove NB_Global . options "bfd-min-rx"
10460 ovn-nbctl --wait=hv set NB_Global . options:"bfd-mult"=5
10461 for chassis in gw1 hv1 hv2; do
10462 echo "checking gw2 -> $chassis"
10464 bfd_cfg=$(ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0)
10465 test "$bfd_cfg" = "enable=true min_tx=1500 mult=5"
10469 # Delete the inside1 vif. The ref_chassis in ha_chassis_group shouldn't have
10470 # reference to hv1.
10471 as hv1 ovs-vsctl del-port hv1-vif1
10474 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10476 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10477 test "$hv2_ch_uuid" = "$ref_ch_list"])
10479 # Delete the inside2 vif.
10482 echo "Deleting hv2-vif1"
10483 as hv2 ovs-vsctl del-port hv2-vif1
10485 # ref_chassis of ha_chassis_group should be empty
10487 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10489 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10491 test "$exp_ref_ch_list" = "$ref_ch_list"])
10493 # Delete the Gateway_Chassis for lrp - outside
10494 ovn-nbctl clear Logical_Router_Port outside gateway_chassis
10496 # There shoud be no ha_chassis_group rows in SB DB.
10497 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis_group | wc -l`])
10498 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10500 ovn-nbctl remove NB_Global . options "bfd-min-rx"
10501 ovn-nbctl remove NB_Global . options "bfd-min-tx"
10502 ovn-nbctl remove NB_Global . options "bfd-mult"
10504 # Now test with HA chassis group instead of Gateway chassis in NB DB
10505 ovn-nbctl --wait=sb ha-chassis-group-add hagrp1
10507 ovn-nbctl list ha_chassis_group
10508 ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1
10509 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name=hagrp1`
10510 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw1 30
10511 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 20
10513 # ovn-northd should not create HA chassis group and HA chassis rows
10514 # unless the HA chassis group in OVN NB DB is associated to
10515 # a logical router port.
10516 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl list ha_chassis | wc -l`])
10518 # Associate hagrp1 to outside logical router port
10519 ovn-nbctl set Logical_Router_Port outside ha_chassis_group=$hagrp1_uuid
10521 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns _uuid \
10522 find ha_chassis_group | wc -l`])
10524 OVS_WAIT_UNTIL([test 2 = `ovn-sbctl list ha_chassis | grep chassis | \
10525 grep -v chassis-name | wc -l`])
10527 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10528 grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport \
10532 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10533 grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport \
10537 # make sure that flows for handling the outside router port reside on gw1
10538 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10539 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10541 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10542 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10545 # make sure ARP responder flows for outside router port reside on gw1 too
10546 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=9 | \
10547 grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
10549 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
10552 # check that the chassis redirect port has been claimed by the gw1 chassis
10553 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10554 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10557 # Re add the ovs ports.
10560 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
10561 set interface hv$i-vif1 external-ids:iface-id=inside$i \
10562 options:tx_pcap=hv$i/vif1-tx.pcap \
10563 options:rxq_pcap=hv$i/vif1-rx.pcap \
10567 hv1_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv1"`
10568 hv2_ch_uuid=`ovn-sbctl --bare --columns _uuid find chassis name="hv2"`
10571 for i in `ovn-sbctl --bare --columns _uuid list chassis | sort`
10573 if test $i = $hv1_ch_uuid; then
10574 exp_ref_ch_list="${exp_ref_ch_list}$i"
10575 elif test $i = $hv2_ch_uuid; then
10576 exp_ref_ch_list="${exp_ref_ch_list}$i"
10581 [ref_ch_list=`ovn-sbctl --bare --columns ref_chassis find ha_chassis_group | sort`
10583 ref_ch_list=`echo $ref_ch_list | sed 's/ //g'`
10584 test "$exp_ref_ch_list" = "$ref_ch_list"])
10586 # Increase the priority of gw2
10587 ovn-nbctl --wait=sb ha-chassis-group-add-chassis hagrp1 gw2 40
10589 OVS_WAIT_UNTIL([as hv1 ovs-ofctl dump-flows br-int table=32 | \
10590 grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport \
10594 OVS_WAIT_UNTIL([as hv2 ovs-ofctl dump-flows br-int table=32 | \
10595 grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport \
10599 # check that the chassis redirect port has been reclaimed by the gw2 chassis
10600 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10601 logical_port=cr-outside | grep $gw2_chassis | wc -l], [0],[[1
10604 # check BFD enablement on tunnel ports from gw1 #########
10606 for chassis in gw2 hv1 hv2; do
10607 echo "checking gw1 -> $chassis"
10608 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10613 # check BFD enablement on tunnel ports from gw2 ##########
10615 for chassis in gw1 hv1 hv2; do
10616 echo "checking gw2 -> $chassis"
10617 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10622 # check BFD enablement on tunnel ports from hv1 ###########
10624 for chassis in gw1 gw2; do
10625 echo "checking hv1 -> $chassis"
10626 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10630 # make sure BFD is not enabled to hv2, we don't need it
10631 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
10635 # check BFD enablement on tunnel ports from hv2 ##########
10637 for chassis in gw1 gw2; do
10638 echo "checking hv2 -> $chassis"
10639 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
10643 # make sure BFD is not enabled to hv1, we don't need it
10644 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
10648 # make sure that flows for handling the outside router port reside on gw2 now
10649 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10650 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10652 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10653 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10656 # disconnect GW2 from the network, GW1 should take over
10658 port=${sandbox}_br-phys
10659 as main ovs-vsctl del-port n1 $port
10663 # make sure that flows for handling the outside router port reside on gw2 now
10664 OVS_WAIT_UNTIL([as gw1 ovs-ofctl dump-flows br-int table=24 | \
10665 grep 00:00:02:01:02:04 | wc -l], [0], [[1
10667 OVS_WAIT_UNTIL([as gw2 ovs-ofctl dump-flows br-int table=24 | \
10668 grep 00:00:02:01:02:04 | wc -l], [0], [[0
10671 # check that the chassis redirect port has been reclaimed by the gw1 chassis
10672 OVS_WAIT_UNTIL([ovn-sbctl --columns chassis --bare find Port_Binding \
10673 logical_port=cr-outside | grep $gw1_chassis | wc -l], [0],[[1
10676 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
10680 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
10681 AT_SKIP_IF([test $HAVE_PYTHON = no])
10683 ovn-nbctl ls-add ls0
10684 ovn-nbctl ls-add ls1
10685 ovn-nbctl create Logical_Router name=lr0
10686 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
10688 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10689 name=outside_gw1 chassis_name=hv2 priority=10 -- \
10690 --id=@gc1 create Gateway_Chassis \
10691 name=outside_gw2 chassis_name=hv3 priority=1 -- \
10692 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10694 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
10695 type=router options:router-port=lrp0 addresses="router"
10696 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
10697 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
10698 type=router options:router-port=lrp1 addresses="router"
10701 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
10706 ovs-vsctl add-br br-phys
10707 ovn_attach n1 br-phys 192.168.0.1
10708 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10709 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])
10713 ovs-vsctl add-br br-phys
10714 ovn_attach n1 br-phys 192.168.0.2
10715 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10719 ovs-vsctl add-br br-phys
10720 ovn_attach n1 br-phys 192.168.0.3
10721 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
10723 # Create a localnet port.
10724 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
10725 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
10726 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
10727 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
10729 # wait for earlier changes to take effect
10730 AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
10732 reset_pcap_file() {
10735 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10736 options:rxq_pcap=dummy-rx.pcap
10737 rm -f ${pcap_file}*.pcap
10738 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10739 options:rxq_pcap=${pcap_file}-rx.pcap
10742 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10743 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10744 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10745 # add nat-addresses option
10746 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10748 # Wait for packets to be received through hv2.
10749 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10751 sed 's/\(00\)\{1,\}$//'
10754 only_broadcast_from_lrp1() {
10755 grep "fffffffffffff00000000001"
10758 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
10759 echo $garp > expout
10761 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
10762 echo "packets on hv1-snoopvif:"
10764 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
10765 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10766 echo "packets on hv2 br-phys tx"
10768 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
10769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10770 echo "packets on hv3 br-phys tx"
10772 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
10775 # at this point, we invert the priority of the gw chassis between hv2 and hv3
10777 ovn-nbctl --wait=hv \
10778 --id=@gc0 create Gateway_Chassis \
10779 name=outside_gw1 chassis_name=hv2 priority=1 -- \
10780 --id=@gc1 create Gateway_Chassis \
10781 name=outside_gw2 chassis_name=hv3 priority=10 -- \
10782 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
10785 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10786 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10787 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10789 # Wait for packets to be received.
10790 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10792 sed 's/\(00\)\{1,\}$//'
10795 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10796 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10797 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10798 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10799 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10800 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10802 # change localnet port tag.
10803 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
10805 # wait for earlier changes to take effect
10806 OVS_WAIT_UNTIL([test 1 = `as hv2 ovs-ofctl dump-flows br-int table=65 | \
10807 grep "actions=mod_vlan_vid:2014" | wc -l`
10810 OVS_WAIT_UNTIL([test 1 = `as hv3 ovs-ofctl dump-flows br-int table=65 | \
10811 grep "actions=mod_vlan_vid:2014" | wc -l`
10814 # update nat-addresses option
10815 ovn-nbctl --wait=hv clear logical_switch_port lrp0-rp options
10817 #Wait until the Port_Binding.nat_addresses is cleared.
10818 OVS_WAIT_UNTIL([test 0 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
10819 logical_port=lrp0-rp | grep is_chassis | wc -l`])
10821 as hv1 reset_pcap_file snoopvif hv1/snoopvif
10822 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
10823 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
10825 ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
10827 #Wait until the Port_Binding.nat_addresses is set.
10828 OVS_WAIT_UNTIL([test 1 = `ovn-sbctl --bare --columns nat_addresses find port_binding \
10829 logical_port=lrp0-rp | grep is_chassis | wc -l`])
10831 # Wait for packets to be received.
10832 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
10834 sed 's/\(00\)\{1,\}$//'
10837 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
10838 echo $garp > expout
10840 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
10841 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
10842 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
10843 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
10844 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
10845 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
10847 OVN_CLEANUP([hv1],[hv2],[hv3])
10851 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
10852 AT_SKIP_IF([test $HAVE_PYTHON = no])
10857 # create two gateways with external network connectivity
10861 ovs-vsctl add-br br-phys
10862 ovn_attach n1 br-phys 192.168.0.$i
10863 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10866 ovn-nbctl ls-add inside
10867 ovn-nbctl ls-add outside
10869 # create one hypervisors with a vif port the internal network
10872 ovs-vsctl add-br br-phys
10873 ovn_attach n1 br-phys 192.168.0.11
10874 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10875 set interface hv1-vif1 external-ids:iface-id=inside1 \
10876 options:tx_pcap=hv1/vif1-tx.pcap \
10877 options:rxq_pcap=hv1/vif1-rx.pcap \
10880 ovn-nbctl lsp-add inside inside1 \
10881 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
10886 ovn-nbctl create Logical_Router name=R1
10888 # Connect inside to R1
10889 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
10890 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
10891 type=router options:router-port=inside \
10892 -- lsp-set-addresses rp-inside router
10894 # Connect outside to R1 as distributed router gateway port on gw1+gw2
10895 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
10897 ovn-nbctl --id=@gc0 create Gateway_Chassis \
10898 name=outside_gw1 chassis_name=gw1 priority=20 -- \
10899 --id=@gc1 create Gateway_Chassis \
10900 name=outside_gw2 chassis_name=gw2 priority=10 -- \
10901 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
10903 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
10904 type=router options:router-port=outside \
10905 -- lsp-set-addresses rp-outside router
10907 # Create localnet port in outside
10908 ovn-nbctl lsp-add outside ln-outside
10909 ovn-nbctl lsp-set-addresses ln-outside unknown
10910 ovn-nbctl lsp-set-type ln-outside localnet
10911 ovn-nbctl lsp-set-options ln-outside network_name=phys
10913 # Allow some time for ovn-northd and ovn-controller to catch up.
10914 ovn-nbctl --wait=hv --timeout=3 sync
10916 # currently when ovn-controller is restarted, the old entry is deleted
10917 # and a new one is created, which leaves the Gateway_Chassis with
10918 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
10919 # doesn't have the same effect because "name" is conserved, and the
10920 # Chassis entry is not replaced.
10922 > gw1/ovn-controller.log
10924 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
10925 ovn-sbctl destroy Chassis $gw2_chassis
10927 OVS_WAIT_UNTIL([test 0 = `grep -c "Releasing lport" gw1/ovn-controller.log`])
10929 OVN_CLEANUP([gw1],[gw2],[hv1])
10933 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
10934 AT_KEYWORDS([ovn-nd_ns for unknown mac])
10935 AT_SKIP_IF([test $HAVE_PYTHON = no])
10938 ovn-nbctl ls-add sw0_ip6
10939 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
10940 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
10941 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10943 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
10944 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
10946 ovn-nbctl lr-add lr0_ip6
10947 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
10948 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
10949 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
10950 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
10951 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
10952 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
10954 ovn-nbctl ls-add public
10955 ovn-nbctl lsp-add public ln-public
10956 ovn-nbctl lsp-set-addresses ln-public unknown
10957 ovn-nbctl lsp-set-type ln-public localnet
10958 ovn-nbctl lsp-set-options ln-public network_name=phys
10960 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
10961 2001:db8:1:0:200:02ff:fe01:0204/64 \
10962 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
10964 #install static route
10965 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
10966 ip_prefix="\:\:/0" nexthop="2001\:db8\:1\:0\:200\:02ff\:fe01\:1305" \
10967 -- add Logical_Router lr0_ip6 static_routes @lrt
10969 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
10970 rp-ip6_public type=router options:router-port=ip6_public \
10971 -- lsp-set-addresses rp-ip6_public router
10976 ovs-vsctl add-br br-phys
10977 ovn_attach n1 br-phys 192.168.0.2
10979 ovs-vsctl -- add-port br-int hv1-vif1 -- \
10980 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
10981 options:tx_pcap=hv1/vif1-tx.pcap \
10982 options:rxq_pcap=hv1/vif1-rx.pcap \
10984 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
10986 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
10988 # There should be 2 Neighbor Advertisement flows for the router port
10989 # aef0:: ip address in logical switch pipeline with action nd_na_router.
10990 AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
10991 grep "nd_na_router" | wc -l], [0], [2
10994 # There should be 4 Neighbor Advertisement flows with action nd_na_router
10995 # in the router pipeline for the router lr0_ip6.
10996 AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
11000 cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
11002 # There is only one chassis.
11003 chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
11004 OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
11007 sed 's/\(00\)\{1,\}$//'
11010 reset_pcap_file() {
11013 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11014 options:rxq_pcap=dummy-rx.pcap
11015 rm -f ${pcap_file}*.pcap
11016 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11017 options:rxq_pcap=${pcap_file}-rx.pcap
11020 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
11021 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
11022 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
11023 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11024 # This function sends ipv6 packet
11026 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11027 local dst_mcast_mac=$6 mcast_node_ip=$7 nd_target=$8
11029 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
11030 packet=${packet}8000000000000000
11032 src_mac=000002010204
11033 expected_packet=${dst_mcast_mac}${src_mac}86dd6000000000203aff${src_ip}
11034 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000
11035 expected_packet=${expected_packet}${nd_target}0101${src_mac}
11037 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
11038 rm -f ipv6_ns.expected
11039 echo $expected_packet >> ipv6_ns.expected
11042 src_mac=506400000002
11043 dst_mac=00000000af01
11044 src_ip=aef0000000000000526400fffe000002
11045 dst_ip=20010db800010000020002fffe010205
11046 dst_mcast_mac=3333ff010205
11047 mcast_node_ip=ff0200000000000000000001ff010205
11048 nd_target=20010db800010000020002fffe010205
11049 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
11050 # should be received by the ports attached to br-phys.
11051 test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
11052 $mcast_node_ip $nd_target
11054 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
11055 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
11057 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
11058 trim_zeros > 1.packets
11059 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
11060 trim_zeros > 2.packets
11062 cat ipv6_ns.expected | cut -c -112 > expout
11063 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
11064 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
11066 # Skipping the ICMPv6 checksum
11067 cat ipv6_ns.expected | cut -c 117- > expout
11068 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
11069 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
11071 # Now send a packet with destination ip other than
11072 # 2001:db8:1:0:200:02ff:fe01:0204/64 prefix.
11073 reset_pcap_file br-phys_n1 hv1/br-phys_n1
11074 reset_pcap_file br-phys hv1/br-phys
11076 src_mac=506400000002
11077 dst_mac=00000000af01
11078 src_ip=aef0000000000000526400fffe000002
11079 dst_ip=20020ab8000100000200020000020306
11080 # multicast mac of the nexthop IP - 2001:db8:1:0:200:02ff:fe01:1305
11081 dst_mcast_mac=3333ff011305
11082 mcast_node_ip=ff0200000000000000000001ff011305
11083 nd_target=20010db800010000020002fffe011305
11084 test_ipv6 1 $src_mac $dst_mac $src_ip $dst_ip $dst_mcast_mac \
11085 $mcast_node_ip $nd_target
11087 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
11088 OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
11090 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
11091 trim_zeros > 1.packets
11092 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
11093 trim_zeros > 2.packets
11095 cat ipv6_ns.expected | cut -c -112 > expout
11096 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
11097 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
11099 # Skipping the ICMPv6 checksum
11100 cat ipv6_ns.expected | cut -c 117- > expout
11101 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
11102 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
11108 AT_SETUP([ovn -- options:requested-chassis for logical port])
11113 ovn-nbctl ls-add ls0
11114 ovn-nbctl lsp-add ls0 lsp0
11116 # create two hypervisors, each with one vif port
11119 ovs-vsctl add-br br-phys
11120 ovn_attach n1 br-phys 192.168.0.11
11121 ovs-vsctl -- add-port br-int hv1-vif0 -- \
11122 set Interface hv1-vif0 ofport-request=1
11126 ovs-vsctl add-br br-phys
11127 ovn_attach n1 br-phys 192.168.0.12
11128 ovs-vsctl -- add-port br-int hv2-vif0 -- \
11129 set Interface hv2-vif0 ofport-request=1
11131 # Allow only chassis hv1 to bind logical port lsp0.
11132 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
11134 # Allow some time for ovn-northd and ovn-controller to catch up.
11135 ovn-nbctl --wait=hv --timeout=3 sync
11137 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
11138 ovn-sbctl wait-until chassis hv1
11139 ovn-sbctl wait-until chassis hv2
11140 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
11141 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
11143 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
11144 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
11146 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
11148 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
11149 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11151 # (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11152 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11153 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11155 # (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
11156 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
11158 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11160 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11161 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
11163 # (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
11164 as hv1 ovs-ofctl dump-flows br-int
11165 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11166 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11168 # (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
11169 # the requested chassis for lsp0 is changed from hv1 to hv2.
11170 echo "verifying that lsp0 binding moves when requested-chassis is changed"
11172 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
11173 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11174 OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
11176 # (6) Chassis hv2 should add flows and hv1 should not.
11177 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11178 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11180 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11181 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11183 OVN_CLEANUP([hv1],[hv2])
11187 AT_SETUP([ovn -- options:requested-chassis with hostname])
11191 ovn-nbctl ls-add ls0
11192 ovn-nbctl lsp-add ls0 lsp0
11197 ovs-vsctl add-br br-phys
11198 ovn_attach n1 br-phys 192.168.0.11
11199 ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
11201 ovn-sbctl wait-until chassis hv1
11202 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
11203 echo "hv1_hostname=${hv1_hostname}"
11204 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
11205 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
11207 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
11208 echo "hv1_uuid=${hv1_uuid}"
11209 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
11210 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
11211 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
11212 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
11214 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
11215 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
11216 ovn-nbctl --wait=hv --timeout=3 sync
11217 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
11218 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
11219 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
11225 AT_SETUP([ovn -- IPv6 periodic RA])
11228 # This test sets up two hypervisors.
11229 # hv1 and hv2 run ovn-controllers, and
11230 # each has a VIF connected to the same
11231 # logical switch in OVN. The logical
11232 # switch is connected to a logical
11233 # router port that is configured to send
11234 # periodic router advertisements.
11236 # The reason for having two ovn-controller
11237 # hypervisors is to ensure that the
11238 # periodic RAs being sent by each ovn-controller
11239 # are kept to their local hypervisors. If the
11240 # packets are not kept local, then each port
11241 # will receive too many RAs.
11247 ovs-vsctl add-br br-phys
11248 ovn_attach n1 br-phys 192.168.0.2
11250 ovs-vsctl add-br br-phys
11251 ovn_attach n1 br-phys 192.168.0.3
11253 ovn-nbctl lr-add ro
11254 ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
11256 ovn-nbctl ls-add sw
11257 ovn-nbctl lsp-add sw sw-ro
11258 ovn-nbctl lsp-set-type sw-ro router
11259 ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
11260 ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
11261 ovn-nbctl lsp-add sw sw-p1
11262 ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
11263 ovn-nbctl lsp-add sw sw-p2
11264 ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
11266 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
11267 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
11268 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
11269 ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
11273 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
11274 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
11275 options:tx_pcap=hv$i/vif1-tx.pcap \
11276 options:rxq_pcap=hv$i/vif1-rx.pcap \
11280 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
11281 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
11283 reset_pcap_file() {
11286 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
11287 options:rxq_pcap=dummy-rx.pcap
11288 rm -f ${pcap_file}*.pcap
11289 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
11290 options:rxq_pcap=${pcap_file}-rx.pcap
11294 construct_expected_ra() {
11295 local src_mac=000000000001
11296 local dst_mac=333300000001
11297 local src_addr=fe80000000000000020000fffe000001
11298 local dst_addr=ff020000000000000000000000000001
11302 local ra_prefix_la=$3
11304 local slla=0101${src_mac}
11306 if test $mtu != 0; then
11307 mtu_opt=05010000${mtu}
11312 while [[ $# -gt 0 ]] ; do
11315 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
11319 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
11320 local icmp=8600XXXX${ra}
11322 local ip_len=$(expr ${#icmp} / 2)
11323 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
11325 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
11326 local eth=${dst_mac}${src_mac}86dd${ip}
11327 local packet=${eth}
11328 echo $packet >> expected
11332 construct_expected_ra $@
11334 for i in hv1 hv2 ; do
11335 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
11337 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
11339 cat expected | cut -c -112 > expout
11340 AT_CHECK([cat packets | cut -c -112], [0], [expout])
11342 # Skip ICMPv6 checksum.
11343 cat expected | cut -c 117- > expout
11344 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
11347 as $i reset_pcap_file $i-vif1 $i/vif1
11353 # Baseline test with no MTU
11354 ra_test 0 00 c0 40 aef00000000000000000000000000000
11356 # Now make sure an MTU option makes it
11357 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
11358 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
11360 # Now test for multiple network prefixes
11361 ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
11362 ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11364 # Test a different address mode now
11365 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
11366 ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11368 # And the other address mode
11369 ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
11370 ra_test 000005dc 40 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
11372 OVN_CLEANUP([hv1],[hv2])
11375 AT_SETUP([ovn -- ACL reject rule test])
11376 AT_KEYWORDS([acl-reject])
11377 AT_SKIP_IF([test $HAVE_PYTHON = no])
11380 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
11382 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
11383 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
11384 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
11385 # unreachable frame generated from ACL rule hit
11387 # INPORT is a lport number, e.g. 11 for vif11.
11388 # HV is a hypervisor number
11389 # ETH_SRC and ETH_DST are each 12 hex digits.
11390 # IPV4_SRC and IPV4_DST are each 8 hex digits.
11391 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
11393 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11394 local exp_ip_chksum=$8 exp_icmp_chksum=$9
11398 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
11400 local reply_icmp_ttl=ff
11401 local icmp_type_code_response=0301
11402 local icmp_data=00000000
11403 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
11404 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
11405 echo $reply >> vif$inport.expected
11407 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11410 # test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
11412 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
11413 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
11414 # EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
11415 test_ipv6_packet() {
11416 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
11419 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
11420 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
11422 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
11423 echo $reply >> vif$inport.expected
11425 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11428 # 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
11430 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
11431 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
11432 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
11434 # INPORT is an lport number, e.g. 11 for vif11.
11435 # HV is an hypervisor number
11436 # ETH_SRC and ETH_DST are each 12 hex digits.
11437 # IPV4_SRC and IPV4_DST are each 8 hex digits.
11438 # TCP_SPORT and TCP_DPORT are 4 hex digits.
11439 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
11440 test_tcp_syn_packet() {
11441 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
11442 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
11443 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
11447 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
11449 local tcp_rst_ttl=ff
11450 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
11451 echo $reply >> vif$inport.expected
11453 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
11456 # Create hypervisors hv[123].
11457 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
11458 # Add all of the vifs to a single logical switch sw0.
11461 ovn-nbctl ls-add sw0
11465 ovs-vsctl add-br br-phys
11466 ovn_attach n1 br-phys 192.168.0.$i
11469 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
11470 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
11472 ovs-vsctl -- add-port br-int vif$i$j -- \
11473 set interface vif$i$j \
11474 external-ids:iface-id=sw0-p$i$j \
11475 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
11476 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
11477 ofport-request=$i$j
11482 # allow some time for ovn-northd and ovn-controller to catch up.
11486 printf "%02x%02x%02x%02x" "$@"
11490 : > vif${i}1.expected
11493 ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
11494 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
11495 ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
11497 # Allow some time for ovn-northd and ovn-controller to catch up.
11498 ovn-nbctl --timeout=3 --wait=hv sync
11500 test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
11501 test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
11502 test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
11504 test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
11506 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
11507 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
11508 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
11511 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
11514 OVN_CLEANUP([hv1], [hv2], [hv3])
11517 AT_SETUP([ovn -- Port Groups])
11518 AT_KEYWORDS([ovnpg])
11519 AT_SKIP_IF([test $HAVE_PYTHON = no])
11524 # Three logical switches ls1, ls2, ls3.
11525 # One logical router lr0 connected to ls[123],
11526 # with nine subnets, three per logical switch:
11528 # lrp11 on ls1 for subnet 192.168.11.0/24
11529 # lrp12 on ls1 for subnet 192.168.12.0/24
11530 # lrp13 on ls1 for subnet 192.168.13.0/24
11532 # lrp33 on ls3 for subnet 192.168.33.0/24
11534 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11535 # digits are the subnet and the last digit distinguishes the VIF.
11537 # This test will create two port groups and uses them in ACL.
11540 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11546 ovn-nbctl ls-add ls$i
11550 -- lsp-add ls$i lp$i$j$k \
11551 -- lsp-set-addresses lp$i$j$k \
11552 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
11553 # logical ports lp[12]?1 belongs to port group pg1
11554 if test $i != 3 && test $k == 1; then
11555 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11557 # logical ports lp[23]?2 belongs to port group pg2
11558 if test $i != 1 && test $k == 2; then
11559 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11565 ovn-nbctl lr-add lr0
11568 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11570 -- lsp-add ls$i lrp$i$j-attachment \
11571 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11572 options:router-port=lrp$i$j \
11573 addresses='"00:00:00:00:ff:'$i$j'"'
11577 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11578 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11580 # create ACLs on all lswitches to drop traffic from pg2 to pg1
11581 ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11582 ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11583 ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
11585 # Physical network:
11587 # Three hypervisors hv[123].
11588 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11589 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11590 # lp?3[123] all on hv3.
11592 # Given the name of a logical port, prints the name of the hypervisor
11593 # on which it is located.
11596 ?11) echo 1 ;; dnl (
11597 ?12 | ?21 | ?22) echo 2 ;; dnl (
11598 ?13 | ?23 | ?3?) echo 3 ;;
11602 # Given the name of a logical port, prints the name of its logical router
11603 # port, e.g. "vif_to_lrp 123" yields 12.
11608 # Given the name of a logical port, prints the name of its logical
11609 # switch, e.g. "vif_to_ls 123" yields 1.
11618 ovs-vsctl add-br br-phys
11619 ovn_attach n1 br-phys 192.168.0.$i
11624 hv=`vif_to_hv $i$j$k`
11625 as hv$hv ovs-vsctl \
11626 -- add-port br-int vif$i$j$k \
11627 -- set Interface vif$i$j$k \
11628 external-ids:iface-id=lp$i$j$k \
11629 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11630 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11631 ofport-request=$i$j$k
11636 # Pre-populate the hypervisors' ARP tables so that we don't lose any
11637 # packets for ARP resolution (native tunneling doesn't queue packets
11638 # for ARP resolution).
11641 # Allow some time for ovn-northd and ovn-controller to catch up.
11642 # XXX This should be more systematic.
11645 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
11647 # This shell function causes a packet to be received on INPORT. The packet's
11648 # content has Ethernet destination DST and source SRC (each exactly 12 hex
11649 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
11650 # more) list the VIFs on which the packet should be received. INPORT and the
11651 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
11655 : > $i$j$k.expected
11660 # This packet has bad checksums but logical L3 routing doesn't check.
11661 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
11662 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
11663 shift; shift; shift; shift; shift
11664 hv=hv`vif_to_hv $inport`
11665 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
11666 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
11667 in_ls=`vif_to_ls $inport`
11668 in_lrp=`vif_to_lrp $inport`
11670 out_ls=`vif_to_ls $outport`
11671 if test $in_ls = $out_ls; then
11672 # Ports on the same logical switch receive exactly the same packet.
11675 # Routing decrements TTL and updates source and dest MAC
11677 out_lrp=`vif_to_lrp $outport`
11678 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
11679 fi >> $outport.expected
11683 as hv1 ovs-vsctl --columns=name,ofport list interface
11684 as hv1 ovn-sbctl list port_binding
11685 as hv1 ovn-sbctl list datapath_binding
11686 as hv1 ovn-sbctl list port_group
11687 as hv1 ovn-sbctl list address_set
11688 as hv1 ovn-sbctl dump-flows
11689 as hv1 ovs-ofctl dump-flows br-int
11691 # Send IP packets between all pairs of source and destination ports,
11692 # packets matches ACL (pg2 to pg1) should be dropped
11694 printf "%02x%02x%02x%02x" "$@"
11696 for is in 1 2 3; do
11697 for js in 1 2 3; do
11698 for ks in 1 2 3; do
11702 sip=`ip_to_hex 192 168 $is$js $ks`
11703 for id in 1 2 3; do
11704 for jd in 1 2 3; do
11705 for kd in 1 2 3; do
11707 dip=`ip_to_hex 192 168 $id$jd $kd`
11708 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
11709 if test $d != $s; then unicast=$d; else unicast=; fi
11711 # packets matches ACL should be dropped
11712 if test $id != 3 && test $kd == 1; then
11713 if test $is != 1 && test $ks == 2; then
11717 test_ip $s $smac $dmac $sip $dip $unicast #1
11725 # Allow some time for packet forwarding.
11726 # XXX This can be improved.
11729 # Now check the packets actually received against the ones expected.
11733 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11739 # Gracefully terminate daemons
11740 OVN_CLEANUP([hv1], [hv2], [hv3])
11743 AT_SETUP([ovn -- ACLs on Port Groups])
11744 AT_KEYWORDS([ovnpg_acl])
11745 AT_SKIP_IF([test $HAVE_PYTHON = no])
11750 # Three logical switches ls1, ls2, ls3.
11751 # One logical router lr0 connected to ls[123],
11752 # with nine subnets, three per logical switch:
11754 # lrp11 on ls1 for subnet 192.168.11.0/24
11755 # lrp12 on ls1 for subnet 192.168.12.0/24
11756 # lrp13 on ls1 for subnet 192.168.13.0/24
11758 # lrp33 on ls3 for subnet 192.168.33.0/24
11760 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
11761 # digits are the subnet and the last digit distinguishes the VIF.
11763 # This test will create two port groups and ACLs will be applied on them.
11766 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
11772 ovn-nbctl ls-add ls$i
11776 -- lsp-add ls$i lp$i$j$k \
11777 -- lsp-set-addresses lp$i$j$k \
11778 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
11779 # logical ports lp[12]?1 belongs to port group pg1
11780 if test $i != 3 && test $k == 1; then
11781 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
11783 # logical ports lp[23]?2 belongs to port group pg2
11784 if test $i != 1 && test $k == 2; then
11785 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
11791 ovn-nbctl lr-add lr0
11794 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
11796 -- lsp-add ls$i lrp$i$j-attachment \
11797 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
11798 options:router-port=lrp$i$j \
11799 addresses='"00:00:00:00:ff:'$i$j'"'
11803 ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
11804 ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
11806 # create ACLs on pg1 to drop traffic from pg2 to pg1
11807 ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
11808 ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
11809 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
11811 # Physical network:
11813 # Three hypervisors hv[123].
11814 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
11815 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
11816 # lp?3[123] all on hv3.
11818 # Given the name of a logical port, prints the name of the hypervisor
11819 # on which it is located.
11822 ?11) echo 1 ;; dnl (
11823 ?12 | ?21 | ?22) echo 2 ;; dnl (
11824 ?13 | ?23 | ?3?) echo 3 ;;
11828 # Given the name of a logical port, prints the name of its logical router
11829 # port, e.g. "vif_to_lrp 123" yields 12.
11834 # Given the name of a logical port, prints the name of its logical
11835 # switch, e.g. "vif_to_ls 123" yields 1.
11844 ovs-vsctl add-br br-phys
11845 ovn_attach n1 br-phys 192.168.0.$i
11850 hv=`vif_to_hv $i$j$k`
11851 as hv$hv ovs-vsctl \
11852 -- add-port br-int vif$i$j$k \
11853 -- set Interface vif$i$j$k \
11854 external-ids:iface-id=lp$i$j$k \
11855 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
11856 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
11857 ofport-request=$i$j$k
11862 # Pre-populate the hypervisors' ARP tables so that we don't lose any
11863 # packets for ARP resolution (native tunneling doesn't queue packets
11864 # for ARP resolution).
11867 # Allow some time for ovn-northd and ovn-controller to catch up.
11868 # XXX This should be more systematic.
11872 echo f0:00:00:00:0${1:0:1}:${1:1:2}
11876 echo 00:00:00:00:ff:$1
11879 # test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
11881 # This shell function causes a ICMP packet to be received on INPORT.
11882 # The OUTPORTs (zero or more) list the VIFs on which the packet should
11883 # be received. INPORT and the OUTPORTs are specified as logical switch
11884 # port numbers, e.g. 123 for vif123.
11888 : > $i$j$k.expected
11894 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
11895 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
11896 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
11897 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
11899 shift; shift; shift; shift; shift; shift
11900 hv=hv`vif_to_hv $inport`
11901 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
11902 in_ls=`vif_to_ls $inport`
11903 in_lrp=`vif_to_lrp $inport`
11905 out_ls=`vif_to_ls $outport`
11906 if test $in_ls = $out_ls; then
11907 # Ports on the same logical switch receive exactly the same packet.
11908 echo $packet | ovstest test-ovn expr-to-packets
11910 # Routing decrements TTL and updates source and dest MAC
11912 out_lrp=`vif_to_lrp $outport`
11913 exp_smac=`lrp_to_mac $out_lrp`
11914 exp_dmac=`lsp_to_mac $outport`
11915 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
11916 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
11917 icmp4.type==$icmp_type && icmp4.code==0"
11918 echo $exp_packet | ovstest test-ovn expr-to-packets
11920 fi >> $outport.expected
11924 as hv1 ovs-vsctl --columns=name,ofport list interface
11925 as hv1 ovn-sbctl list port_binding
11926 as hv1 ovn-sbctl list datapath_binding
11927 as hv1 ovn-sbctl list port_group
11928 as hv1 ovn-sbctl list address_set
11929 as hv1 ovn-sbctl dump-flows
11930 as hv1 ovs-ofctl dump-flows br-int
11932 # Send IP packets between all pairs of source and destination ports,
11933 # packets matches ACL1 but not ACL2 should be dropped
11935 printf "%02x%02x%02x%02x" "$@"
11937 for is in 1 2 3; do
11938 for js in 1 2 3; do
11939 for ks in 1 2 3; do
11942 slsp_mac=`lsp_to_mac $s`
11943 slrp_mac=`lrp_to_mac $is$js`
11944 sip=192.168.$is$js.$ks
11945 for id in 1 2 3; do
11946 for jd in 1 2 3; do
11947 for kd in 1 2 3; do
11949 dlsp_mac=`lsp_to_mac $d`
11950 dlrp_mac=`lrp_to_mac $id$jd`
11951 dip=192.168.$id$jd.$kd
11952 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
11953 if test $d != $s; then unicast=$d; else unicast=; fi
11955 # packets matches ACL1 but not ACL2 should be dropped
11956 if test $id != 3 && test $kd == 1; then
11957 if test $is == 1 || test $ks != 2; then
11961 # icmp request (type = 8)
11962 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
11964 # if packets are not dropped, test the return traffic (icmp echo)
11965 # to make sure stateful works, too.
11966 if test x$unicast != x; then
11967 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
11968 # icmp echo (type = 0)
11969 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
11978 # Allow some time for packet forwarding.
11979 # XXX This can be improved.
11982 # Now check the packets actually received against the ones expected.
11986 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
11992 # Gracefully terminate daemons
11993 OVN_CLEANUP([hv1], [hv2], [hv3])
11996 AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
11999 ovn-nbctl ls-add ls1
12001 ovn-nbctl lsp-add ls1 lp1
12002 ovn-nbctl lsp-add ls1 lp2
12003 ovn-nbctl lsp-add ls1 lp3
12005 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
12006 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
12007 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
12009 ovn-nbctl create Port_Group name=pg1
12010 ovn-nbctl create Port_Group name=pg2
12012 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
12013 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
12014 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
12015 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
12017 ovn-nbctl --wait=sb sync
12019 dnl Check if port group address sets were populated with ports' addresses
12020 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12021 [0], [[["10.0.0.1", "10.0.0.2"]]
12023 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
12024 [0], [[["10.0.0.2", "10.0.0.3"]]
12026 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12027 [0], [[["2001:db8::1", "2001:db8::2"]]
12029 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
12030 [0], [[["2001:db8::2", "2001:db8::3"]]
12033 ovn-nbctl --wait=sb lsp-set-addresses lp1 \
12034 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
12036 dnl Check if updated address got propagated to the port group address sets
12037 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12038 [0], [[["10.0.0.11", "10.0.0.2"]]
12040 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12041 [0], [[["2001:db8::11", "2001:db8::2"]]
12046 AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
12049 ovn-nbctl ls-add ls1
12050 ovn-nbctl ls-add ls2
12051 ovn-nbctl ls-add ls3
12053 ovn-nbctl set Logical_Switch ls1 \
12054 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
12055 ovn-nbctl set Logical_Switch ls2 \
12056 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
12057 ovn-nbctl set Logical_Switch ls3 \
12058 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
12060 ovn-nbctl lsp-add ls1 lp1
12061 ovn-nbctl lsp-add ls2 lp2
12062 ovn-nbctl lsp-add ls3 lp3
12064 ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
12065 ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
12066 ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
12068 ovn-nbctl create Port_Group name=pg1
12069 ovn-nbctl create Port_Group name=pg2
12071 ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
12072 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
12073 ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
12074 ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
12076 ovn-nbctl --wait=sb sync
12078 dnl Check if port group address sets were populated with ports' addresses
12079 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12080 [0], [[["10.1.0.2", "10.2.0.2"]]
12082 AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
12083 [0], [[["10.2.0.2", "10.3.0.2"]]
12085 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12086 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
12088 AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
12089 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
12092 ovn-nbctl --wait=sb set Logical_Switch ls1 \
12093 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
12095 dnl Check if updated address got propagated to the port group address sets
12096 AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
12097 [0], [[["10.11.0.2", "10.2.0.2"]]
12099 AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
12100 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
12105 AT_SETUP([ovn -- ACL conjunction])
12108 ovn-nbctl ls-add ls1
12110 ovn-nbctl lsp-add ls1 ls1-lp1 \
12111 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12113 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
12115 ovn-nbctl lsp-add ls1 ls1-lp2 \
12116 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12118 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
12124 ovs-vsctl add-br br-phys
12125 ovn_attach n1 br-phys 192.168.0.1
12126 ovs-vsctl -- add-port br-int hv1-vif1 -- \
12127 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
12128 options:tx_pcap=hv1/vif1-tx.pcap \
12129 options:rxq_pcap=hv1/vif1-rx.pcap \
12132 ovs-vsctl -- add-port br-int hv1-vif2 -- \
12133 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
12134 options:tx_pcap=hv1/vif2-tx.pcap \
12135 options:rxq_pcap=hv1/vif2-rx.pcap \
12138 ovn-nbctl create Address_Set name=set1 \
12139 addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
12140 ovn-nbctl create Address_Set name=set2 \
12141 addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
12142 ovn-nbctl acl-add ls1 to-lport 1002 \
12143 'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
12144 ovn-nbctl acl-add ls1 to-lport 1001 \
12145 'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
12147 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
12149 # This shell function causes an ip packet to be received on INPORT.
12150 # The packet's content has Ethernet destination DST and source SRC
12151 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
12152 # The OUTPORTs (zero or more) list the VIFs on which the packet should
12153 # be received. INPORT and the OUTPORTs are specified as logical switch
12154 # port numbers, e.g. 11 for vif11.
12156 # This packet has bad checksums but logical L3 routing doesn't check.
12157 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
12158 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
12159 ${dst_ip}0035111100080000
12160 shift; shift; shift; shift; shift
12161 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
12163 echo $packet >> $outport.expected
12168 printf "%02x%02x%02x%02x" "$@"
12171 reset_pcap_file() {
12174 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12175 options:rxq_pcap=dummy-rx.pcap
12176 rm -f ${pcap_file}*.pcap
12177 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12178 options:rxq_pcap=${pcap_file}-rx.pcap
12182 sip=`ip_to_hex 10 0 0 4`
12183 dip=`ip_to_hex 10 0 0 6`
12185 test_ip 1 f00000000001 f00000000002 $sip $dip 2
12187 cat 2.expected > expout
12188 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12189 AT_CHECK([cat 2.packets], [0], [expout])
12191 # There should be total of 12 flows present with conjunction action and 2 flows
12192 # with conj match. Eg.
12193 # table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
12194 # table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
12195 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
12196 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
12197 # priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
12198 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
12199 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
12200 # priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
12201 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
12202 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
12203 # priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
12204 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
12205 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
12206 # priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
12208 OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
12209 grep conjunction | wc -l`])
12210 OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
12211 grep conj_id | wc -l`])
12213 as hv1 ovs-ofctl dump-flows br-int
12215 # Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
12216 ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12217 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
12219 reset_pcap_file hv1-vif2 hv1/vif2
12223 sip=`ip_to_hex 10 0 0 4`
12224 dip=`ip_to_hex 10 0 0 7`
12226 test_ip 1 f00000000001 f00000000002 $sip $dip
12227 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
12228 AT_CHECK([cat 2.packets], [0], [])
12232 AT_SETUP([ovn -- TTL exceeded])
12233 AT_KEYWORDS([ttl-exceeded])
12234 AT_SKIP_IF([test $HAVE_PYTHON = no])
12237 # test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
12239 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12240 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
12241 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
12242 # generated by OVN logical router
12244 # INPORT is a lport number, e.g. 11 for vif11.
12245 # HV is a hypervisor number
12246 # ETH_SRC and ETH_DST are each 12 hex digits.
12247 # IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
12248 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12250 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
12251 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
12255 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
12257 local reply_icmp_ttl=fe
12258 local icmp_type_code_response=0b00
12259 local icmp_data=00000000
12260 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
12261 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12262 echo $reply >> vif$inport.expected
12264 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12267 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
12269 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12270 # packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
12271 # IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
12272 # packet sent by OVN logical router
12273 test_ip6_packet() {
12274 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
12277 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
12278 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
12280 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
12281 echo $reply >> vif$inport.expected
12283 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12287 printf "%02x%02x%02x%02x" "$@"
12292 ovn-nbctl ls-add sw$i
12296 ovs-vsctl add-br br-phys
12297 ovn_attach n$i br-phys 192.168.$i.1
12299 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
12300 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
12302 ovs-vsctl -- add-port br-int vif$i -- \
12303 set interface vif$i \
12304 external-ids:iface-id=sw$i-p${i}0 \
12305 options:tx_pcap=hv$i/vif$i-tx.pcap \
12306 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12310 ovn-nbctl lr-add lr0
12312 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
12313 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12314 -- set Logical_Switch_Port lrp$i-attachment type=router \
12315 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
12319 # allow some time for ovn-northd and ovn-controller to catch up.
12320 ovn-nbctl --wait=hv sync
12322 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
12323 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
12324 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12326 OVN_CLEANUP([hv1], [hv2])
12329 AT_SETUP([ovn -- router port unreachable])
12330 AT_KEYWORDS([router-port-unreachable])
12331 AT_SKIP_IF([test $HAVE_PYTHON = no])
12334 # 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
12336 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
12337 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
12338 # EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
12339 # EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
12341 # INPORT is a lport number, e.g. 11 for vif11.
12342 # HV is a hypervisor number
12343 # ETH_SRC and ETH_DST are each 12 hex digits.
12344 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12345 # IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
12347 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
12348 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
12352 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
12354 local reply_icmp_ttl=fe
12355 local icmp_data=00000000
12356 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
12357 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
12358 echo $reply >> vif$inport.expected
12360 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12363 # 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
12365 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
12366 # ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
12367 # EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
12369 # INPORT is an lport number, e.g. 11 for vif11.
12370 # HV is an hypervisor number
12371 # ETH_SRC and ETH_DST are each 12 hex digits.
12372 # IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
12373 # TCP_SPORT and TCP_DPORT are 4 hex digits.
12374 # IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
12375 test_tcp_syn_packet() {
12376 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
12377 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
12378 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
12382 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12384 local tcp_rst_ttl=fe
12385 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
12386 echo $reply >> vif$inport.expected
12388 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12391 # test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
12393 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
12394 # ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
12395 # EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
12396 test_tcp6_packet() {
12397 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
12398 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
12399 local exp_tcp_rst_chksum=${10}
12402 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
12403 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
12405 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
12406 echo $reply >> vif$inport.expected
12408 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12411 # test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
12413 # Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
12414 # packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
12415 # EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
12416 test_ip6_packet() {
12417 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
12418 local exp_icmp_code=${10} exp_icmp_chksum=${11}
12421 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
12422 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
12424 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
12425 echo $reply >> vif$inport.expected
12427 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
12431 printf "%02x%02x%02x%02x" "$@"
12436 ovn-nbctl ls-add sw$i
12440 ovs-vsctl add-br br-phys
12441 ovn_attach n$i br-phys 192.168.$i.1
12443 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
12444 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
12446 ovs-vsctl -- add-port br-int vif$i -- \
12447 set interface vif$i \
12448 external-ids:iface-id=sw$i-p${i}0 \
12449 options:tx_pcap=hv$i/vif$i-tx.pcap \
12450 options:rxq_pcap=hv$i/vif$i-rx.pcap \
12454 ovn-nbctl lr-add lr0
12456 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
12457 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
12458 -- set Logical_Switch_Port lrp$i-attachment type=router \
12459 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
12463 # allow some time for ovn-northd and ovn-controller to catch up.
12464 ovn-nbctl --wait=hv sync
12466 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
12467 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
12468 test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
12469 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
12471 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
12472 test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
12473 test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
12474 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
12476 OVN_CLEANUP([hv1], [hv2])
12479 AT_SETUP([ovn -- ovn-controller exit])
12480 AT_SKIP_IF([test $HAVE_PYTHON = no])
12483 # One Logical Router: ro, with two logical switches sw1 and sw2.
12484 # sw1 is for subnet 10.0.0.0/8
12485 # sw2 is for subnet 20.0.0.0/8
12486 # sw1 has a single port bound on hv1
12487 # sw2 has a single port bound on hv2
12489 ovn-nbctl lr-add ro
12490 ovn-nbctl ls-add sw1
12491 ovn-nbctl ls-add sw2
12493 sw1_ro_mac=00:00:10:00:00:01
12495 sw2_ro_mac=00:00:20:00:00:01
12497 sw1_p1_mac=00:00:10:00:00:02
12499 sw2_p1_mac=00:00:20:00:00:02
12502 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
12503 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
12504 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
12505 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
12506 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
12507 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
12509 ovn-nbctl lsp-add sw1 sw1-p1 \
12510 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
12512 ovn-nbctl lsp-add sw2 sw2-p1 \
12513 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
12519 ovs-vsctl add-br br-phys
12520 ovn_attach n1 br-phys 192.168.0.1
12521 ovs-vsctl -- add-port br-int hv1-vif1 -- \
12522 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
12523 options:tx_pcap=hv1/vif1-tx.pcap \
12524 options:rxq_pcap=hv1/vif1-rx.pcap \
12529 ovs-vsctl add-br br-phys
12530 ovn_attach n1 br-phys 192.168.0.2
12531 ovs-vsctl -- add-port br-int hv2-vif1 -- \
12532 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
12533 options:tx_pcap=hv2/vif1-tx.pcap \
12534 options:rxq_pcap=hv2/vif1-rx.pcap \
12541 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
12542 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12543 udp && udp.src==53 && udp.dst==4369"
12545 # Start by Sending the packet and make sure it makes it there as expected
12546 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12548 # Expected packet has TTL decreased by 1
12549 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
12550 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
12551 udp && udp.src==53 && udp.dst==4369"
12552 echo $expected | ovstest test-ovn expr-to-packets > expected
12554 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12556 # Stop ovn-controller on hv2
12557 as hv2 ovs-appctl -t ovn-controller exit
12559 # Now send the packet again. This time, it should not arrive.
12560 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
12562 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
12564 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
12565 as hv2 start_daemon ovn-controller
12567 OVN_CLEANUP([hv1],[hv2])
12570 AT_SETUP([ovn -- external logical port])
12571 AT_SKIP_IF([test $HAVE_PYTHON = no])
12579 ovn-nbctl ls-add ls1
12580 ovn-nbctl lsp-add ls1 ls1-lp1 \
12581 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
12583 # Add a couple of external logical port
12584 ovn-nbctl lsp-add ls1 ls1-lp_ext1 \
12585 -- lsp-set-addresses ls1-lp_ext1 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12586 ovn-nbctl lsp-set-port-security ls1-lp_ext1 \
12587 "f0:00:00:00:00:03 10.0.0.6 ae70::6"
12588 ovn-nbctl lsp-set-type ls1-lp_ext1 external
12590 ovn-nbctl lsp-add ls1 ls1-lp_ext2 \
12591 -- lsp-set-addresses ls1-lp_ext2 "f0:00:00:00:00:04 10.0.0.7 ae70::7"
12592 ovn-nbctl lsp-set-port-security ls1-lp_ext2 \
12593 "f0:00:00:00:00:04 10.0.0.7 ae70::8"
12594 ovn-nbctl lsp-set-type ls1-lp_ext2 external
12596 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
12597 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
12598 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
12600 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
12601 options="\"server_id\"=\"00:00:00:10:00:01\"")"
12603 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
12604 ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext1 ${d1}
12605 ovn-nbctl lsp-set-dhcpv4-options ls1-lp_ext2 ${d1}
12607 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d2}
12608 ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext1 ${d2}
12609 ovn-nbctl lsp-set-dhcpv6-options ls1-lp_ext2 ${d2}
12611 # Create a logical router and connect it to ls1
12612 ovn-nbctl lr-add lr0
12613 ovn-nbctl lrp-add lr0 lr0-ls1 a0:10:00:00:00:01 10.0.0.1/24
12614 ovn-nbctl lsp-add ls1 ls1-lr0
12615 ovn-nbctl set Logical_Switch_Port ls1-lr0 type=router \
12616 options:router-port=lr0-ls1 addresses=router
12618 # Create HA chassis group
12619 ovn-nbctl ha-chassis-group-add hagrp1
12620 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
12622 hagrp1_uuid=`ovn-nbctl --bare --columns _uuid find ha_chassis_group name="hagrp1"`
12624 # There should be 1 HA_Chassis rows with chassis sets
12625 OVS_WAIT_UNTIL([ovn-sbctl list ha_chassis | grep chassis | awk '{print $3}' \
12626 | grep '-' | wc -l ], [0], [1
12630 ovs-vsctl add-br br-phys
12631 ovn_attach n1 br-phys 192.168.0.1
12632 ovs-vsctl -- add-port br-phys hv1-ext1 -- \
12633 set interface hv1-ext1 options:tx_pcap=hv1/ext1-tx.pcap \
12634 options:rxq_pcap=hv1/ext1-rx.pcap \
12636 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12639 ovs-vsctl add-br br-phys
12640 ovn_attach n1 br-phys 192.168.0.2
12641 ovs-vsctl -- add-port br-phys hv2-ext2 -- \
12642 set interface hv2-ext2 options:tx_pcap=hv2/ext2-tx.pcap \
12643 options:rxq_pcap=hv2/ext2-rx.pcap \
12645 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12648 ovs-vsctl add-br br-phys
12649 ovn_attach n1 br-phys 192.168.0.3
12650 ovs-vsctl -- add-port br-phys hv3-ext3 -- \
12651 set interface hv3-ext3 options:tx_pcap=hv3/ext3-tx.pcap \
12652 options:rxq_pcap=hv3/ext3-rx.pcap \
12654 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
12656 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and
12657 # hv2 as ha-chassis-group is not set and no localnet port added to ls1.
12658 AT_CHECK([ovn-sbctl dump-flows ls1 | grep "offerip = 10.0.0.6" | \
12661 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12662 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12664 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12665 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12667 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12668 grep controller | grep tp_src=546 | grep \
12669 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12671 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12672 grep controller | grep tp_src=546 | grep \
12673 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12676 hv1_uuid=$(ovn-sbctl list chassis hv1 | grep uuid | awk '{print $3}')
12677 hv2_uuid=$(ovn-sbctl list chassis hv2 | grep uuid | awk '{print $3}')
12678 hv3_uuid=$(ovn-sbctl list chassis hv3 | grep uuid | awk '{print $3}')
12680 # The port_binding row for ls1-lp_ext1 should have empty chassis
12681 chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12682 logical_port=ls1-lp_ext1`
12684 AT_CHECK([test x$chassis == x], [0], [])
12686 # Associate hagrp1 ha-chassis-group to ls1-lp_ext1
12687 ovn-nbctl --wait=hv set Logical_Switch_Port ls1-lp_ext1 \
12688 ha-chassis-group=$hagrp1_uuid
12690 # Get the hagrp1 uuid in SB DB.
12691 sb_hagrp1_uuid=`ovn-sbctl --bare --columns _uuid find ha_chassis_group \
12694 # Wait till ls1-lp_ext1 port_binding has ha_chassis_group set
12696 [sb_pb_hagrp=`ovn-sbctl --bare --columns ha_chassis_group find \
12697 port_binding logical_port=ls1-lp_ext1`
12698 test "$sb_pb_hagrp" = "$sb_hagrp1_uuid"])
12700 # No DHCPv4/v6 flows for the external port - ls1-lp_ext1 - 10.0.0.6 in hv1 and hv2
12701 # as no localnet port added to ls1 yet.
12702 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12703 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12705 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12706 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12708 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12709 grep controller | grep tp_src=546 | grep \
12710 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12712 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12713 grep controller | grep tp_src=546 | grep \
12714 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12717 # Add the localnet port to the logical switch ls1
12718 ovn-nbctl lsp-add ls1 ln-public
12719 ovn-nbctl lsp-set-addresses ln-public unknown
12720 ovn-nbctl lsp-set-type ln-public localnet
12721 ovn-nbctl --wait=hv lsp-set-options ln-public network_name=phys
12723 ln_public_key=$(ovn-sbctl list port_binding ln-public | grep tunnel_key | \
12726 # The ls1-lp_ext1 should be bound to hv1 as only hv1 is part of the
12727 # ha chassis group.
12729 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12730 logical_port=ls1-lp_ext1`
12731 test "$chassis" = "$hv1_uuid"])
12733 # There should be DHCPv4/v6 OF flows for the ls1-lp_ext1 port in hv1
12734 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12735 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
12738 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12739 grep controller | grep tp_src=546 | grep \
12740 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
12741 grep reg14=0x$ln_public_key | wc -l], [0], [1
12744 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv2
12745 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12746 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
12748 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12749 grep controller | grep tp_src=546 | grep \
12750 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | wc -l], [0], [0
12753 # No DHCPv4/v6 flows for the external port - ls1-lp_ext2 - 10.0.0.7 in hv1 and
12754 # hv2 as requested-chassis option is not set.
12755 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12756 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12758 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12759 grep controller | grep "0a.00.00.07" | wc -l], [0], [0
12761 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
12762 grep controller | grep tp_src=546 | grep \
12763 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12765 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
12766 grep controller | grep tp_src=546 | grep \
12767 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.07" | wc -l], [0], [0
12773 # This shell function sends a DHCP request packet
12774 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
12776 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
12777 shift; shift; shift; shift; shift;
12778 if test $use_ip != 0; then
12783 src_ip=`ip_to_hex 0 0 0 0`
12784 dst_ip=`ip_to_hex 255 255 255 255`
12786 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
12787 # udp header and dhcp header
12788 request=${request}0044004300fc0000
12789 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
12790 # client hardware padding
12791 request=${request}00000000000000000000
12793 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12794 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12796 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12797 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12798 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12799 request=${request}0000000000000000000000000000000000000000000000000000000000000000
12800 # dhcp magic cookie
12801 request=${request}63825363
12802 # dhcp message type
12803 request=${request}3501${dhcp_type}ff
12805 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
12806 # total IP length will be the IP length of the request packet
12807 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
12808 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
12809 udp_len=`expr $ip_len - 20`
12810 ip_len=$(printf "%x" $ip_len)
12811 udp_len=$(printf "%x" $udp_len)
12812 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
12813 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
12814 # udp header and dhcp header.
12815 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
12816 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
12818 reply=${reply}${offer_ip}
12819 # next server ip address, relay agent ip address, client mac address
12820 reply=${reply}0000000000000000${src_mac}
12821 # client hardware padding
12822 reply=${reply}00000000000000000000
12824 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12825 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12827 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12828 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12829 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12830 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
12831 # dhcp magic cookie
12832 reply=${reply}63825363
12833 # dhcp message type
12834 local dhcp_reply_type=02
12835 if test $dhcp_type = 03; then
12838 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
12839 echo $reply >> ext1_v4.expected
12841 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12846 sed 's/\(00\)\{1,\}$//'
12849 # This shell function sends a DHCPv6 request packet
12850 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
12851 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
12852 # packet should be received twice (one from ovn-controller and the other
12853 # from the "ovs-ofctl monitor br-int resume"
12855 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
12856 local req_pkt_in_expected=$6
12857 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
12859 request=${request}ff020000000000000000000000010002
12860 # udp header and dhcpv6 header
12861 request=${request}02220223002affff${msg_code}010203
12862 # Client identifier
12863 request=${request}0001000a00030001${src_mac}
12864 # IA-NA (Identity Association for Non Temporary Address)
12865 request=${request}0003000c0102030400000e1000001518
12866 shift; shift; shift; shift; shift;
12868 local server_mac=000000100001
12869 local server_lla=fe80000000000000020000fffe100001
12870 local reply_code=07
12871 if test $msg_code = 01; then
12875 if test $offer_ip = 1; then
12878 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101
12879 reply=${reply}${server_lla}${src_lla}
12881 # udp header and dhcpv6 header
12882 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
12883 # Client identifier
12884 reply=${reply}0001000a00030001${src_mac}
12886 if test $offer_ip != 1; then
12887 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}
12888 reply=${reply}ffffffffffffffff
12890 # Server identifier
12891 reply=${reply}0002000a00030001${server_mac}
12893 echo $reply | trim_zeros >> ext${inport}_v6.expected
12894 # The inport also receives the request packet since it is connected
12896 #echo $request >> ext${inport}_v6.expected
12898 as hv1 ovs-appctl netdev-dummy/receive hv${inport}-ext${inport} $request
12901 reset_pcap_file() {
12904 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
12905 options:rxq_pcap=dummy-rx.pcap
12906 rm -f ${pcap_file}*.pcap
12907 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
12908 options:rxq_pcap=${pcap_file}-rx.pcap
12912 printf "%02x%02x%02x%02x" "$@"
12915 AT_CAPTURE_FILE([ofctl_monitor0_hv1.log])
12916 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
12917 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv1.log
12919 AT_CAPTURE_FILE([ofctl_monitor0_hv2.log])
12920 as hv2 ovs-ofctl monitor br-int resume --detach --no-chdir \
12921 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv2.log
12923 AT_CAPTURE_FILE([ofctl_monitor0_hv3.log])
12924 as hv3 ovs-ofctl monitor br-int resume --detach --no-chdir \
12925 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0_hv3.log
12928 reset_pcap_file hv1-ext1 hv1/ext1
12930 # Send DHCPDISCOVER.
12931 offer_ip=`ip_to_hex 10 0 0 6`
12932 server_ip=`ip_to_hex 10 0 0 1`
12933 server_mac=ff1000000001
12934 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
12935 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
12936 $expected_dhcp_opts
12938 # NXT_RESUMEs should be 1 in hv1.
12939 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12941 # NXT_RESUMEs should be 0 in hv2.
12942 OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12944 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
12945 cat ext1_v4.expected | cut -c -48 > expout
12946 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
12947 # Skipping the IPv4 checksum.
12948 cat ext1_v4.expected | cut -c 53- > expout
12949 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
12951 # ovs-ofctl also resumes the packets and this causes other ports to receive
12952 # the DHCP request packet. So reset the pcap files so that its easier to test.
12954 reset_pcap_file hv1-ext1 hv1/ext1
12956 rm -f ext1_v4.expected
12957 rm -f ext1_v4.packets
12959 # Send DHCPv6 request
12960 src_mac=f00000000003
12961 src_lla=fe80000000000000f20000fffe000003
12962 offer_ip=ae700000000000000000000000000006
12963 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
12965 # NXT_RESUMEs should be 2 in hv1.
12966 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
12968 # NXT_RESUMEs should be 0 in hv2.
12969 OVS_WAIT_UNTIL([test 0 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
12971 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
12972 sort > ext1_v6.packets
12973 cat ext1_v6.expected | cut -c -120 > expout
12974 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
12975 # Skipping the UDP checksum
12976 cat ext1_v6.expected | cut -c 125- > expout
12977 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
12979 rm -f ext1_v6.expected
12980 rm -f ext1_v6.packets
12983 reset_pcap_file hv1-ext1 hv1/ext1
12985 # Delete the ha-chassis hv1.
12986 ovn-nbctl ha-chassis-group-remove-chassis hagrp1 hv1
12988 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
12989 logical_port=ls1-lp_ext1`
12990 test "$chassis" = ""])
12992 # Add hv2 to the ha chassis group
12993 ovn-nbctl --wait=hv ha-chassis-group-add-chassis hagrp1 hv2 20
12995 ovn-sbctl list ha_chassis_group
12996 ovn-sbctl list ha_chassis
12998 ovn-sbctl find port_binding logical_port=ls1-lp_ext1
13000 # The ls1-lp_ext1 should be bound to hv2
13002 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13003 logical_port=ls1-lp_ext1`
13004 test "$chassis" = "$hv2_uuid"])
13006 # There should be OF flows for DHCP4/v6 for the ls1-lp_ext1 port in hv2
13007 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
13008 grep controller | grep "0a.00.00.06" | grep reg14=0x$ln_public_key | \
13011 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep table=20 | \
13012 grep controller | grep tp_src=546 | grep \
13013 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
13014 grep reg14=0x$ln_public_key | wc -l], [0], [1
13017 # There should be no DHCPv4/v6 flows for ls1-lp_ext1 on hv1
13018 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
13019 grep controller | grep "0a.00.00.06" | wc -l], [0], [0
13021 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep table=20 | \
13022 grep controller | grep tp_src=546 | grep \
13023 "ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.06" | \
13024 grep reg14=0x$ln_public_key | wc -l], [0], [0
13027 # Send DHCPDISCOVER again for hv1/ext1. The DHCP response should come from
13028 # hv2 ovn-controller.
13029 offer_ip=`ip_to_hex 10 0 0 6`
13030 server_ip=`ip_to_hex 10 0 0 1`
13031 server_mac=ff1000000001
13032 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13033 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13034 $expected_dhcp_opts
13036 # NXT_RESUMEs should be 2 in hv1.
13037 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13039 # NXT_RESUMEs should be 1 in hv2.
13040 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13042 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13043 cat ext1_v4.expected | cut -c -48 > expout
13044 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13045 # Skipping the IPv4 checksum.
13046 cat ext1_v4.expected | cut -c 53- > expout
13047 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13049 # ovs-ofctl also resumes the packets and this causes other ports to receive
13050 # the DHCP request packet. So reset the pcap files so that its easier to test.
13052 reset_pcap_file hv1-ext1 hv1/ext1
13054 rm -f ext1_v4.expected
13056 # Send DHCPv6 request again
13057 src_mac=f00000000003
13058 src_lla=fe80000000000000f20000fffe000003
13059 offer_ip=ae700000000000000000000000000006
13060 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip 1
13062 # NXT_RESUMEs should be 2 in hv1.
13063 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13065 # NXT_RESUMEs should be 2 in hv2.
13066 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13068 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13069 sort > ext1_v6.packets
13070 cat ext1_v6.expected | cut -c -120 > expout
13071 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13072 # Skipping the UDP checksum
13073 cat ext1_v6.expected | cut -c 125- > expout
13074 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13076 rm -f ext1_v6.expected
13077 rm -f ext1_v6.packets
13081 reset_pcap_file hv1-ext1 hv1/ext1
13082 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13083 reset_pcap_file br-phys hv1/br-phys
13087 reset_pcap_file hv2-ext2 hv2/ext2
13088 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13089 reset_pcap_file br-phys hv2/br-phys
13091 # From ls1-lp_ext1, send ARP request for the router ip. The ARP
13092 # response should come from the router pipeline of hv2.
13093 ext1_mac=f00000000003
13094 router_mac=a01000000001
13095 ext1_ip=`ip_to_hex 10 0 0 6`
13096 router_ip=`ip_to_hex 10 0 0 1`
13097 arp_request=ffffffffffff${ext1_mac}08060001080006040001${ext1_mac}${ext1_ip}000000000000${router_ip}
13099 as hv1 ovs-appctl netdev-dummy/receive hv1-ext1 $arp_request
13100 expected_response=${src_mac}${router_mac}08060001080006040002${router_mac}${router_ip}${ext1_mac}${ext1_ip}
13101 echo $expected_response > expout
13102 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_arp_resp
13103 AT_CHECK([cat ext1_arp_resp], [0], [expout])
13105 # Verify that the response came from hv2
13106 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap > ext1_arp_resp
13107 AT_CHECK([cat ext1_arp_resp], [0], [expout])
13109 # Now add 3 ha chassis to the ha chassis group
13110 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv1 30
13111 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv2 20
13112 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 10
13114 # hv1 should be master and claim ls1-lp_ext1
13116 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13117 logical_port=ls1-lp_ext1`
13118 test "$chassis" = "$hv1_uuid"])
13122 reset_pcap_file hv1-ext1 hv1/ext1
13123 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13124 reset_pcap_file br-phys hv1/br-phys
13128 reset_pcap_file hv2-ext2 hv2/ext2
13129 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13130 reset_pcap_file br-phys hv2/br-phys
13134 reset_pcap_file hv3-ext3 hv3/ext3
13135 reset_pcap_file br-phys_n1 hv3/br-phys_n1
13136 reset_pcap_file br-phys hv3/br-phys
13138 # Send DHCPDISCOVER.
13139 offer_ip=`ip_to_hex 10 0 0 6`
13140 server_ip=`ip_to_hex 10 0 0 1`
13141 server_mac=ff1000000001
13142 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13143 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13144 $expected_dhcp_opts
13146 # NXT_RESUMEs should be 3 in hv1.
13147 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13149 # NXT_RESUMEs should be 2 in hv2.
13150 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13152 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13153 cat ext1_v4.expected | cut -c -48 > expout
13154 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13155 # Skipping the IPv4 checksum.
13156 cat ext1_v4.expected | cut -c 53- > expout
13157 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13159 # ovs-ofctl also resumes the packets and this causes other ports to receive
13160 # the DHCP request packet. So reset the pcap files so that its easier to test.
13162 reset_pcap_file hv1-ext1 hv1/ext1
13164 rm -f ext1_v4.expected
13165 rm -f ext1_v4.packets
13167 # Send DHCPv6 request
13168 src_mac=f00000000003
13169 src_lla=fe80000000000000f20000fffe000003
13170 offer_ip=ae700000000000000000000000000006
13171 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13173 # NXT_RESUMEs should be 4 in hv1.
13174 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13176 # NXT_RESUMEs should be 2 in hv2.
13177 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13179 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13180 sort > ext1_v6.packets
13181 cat ext1_v6.expected | cut -c -120 > expout
13182 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13183 # Skipping the UDP checksum
13184 cat ext1_v6.expected | cut -c 125- > expout
13185 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13187 rm -f ext1_v6.expected
13188 rm -f ext1_v6.packets
13189 as hv1 reset_pcap_file hv1-ext1 hv1/ext1
13191 # Now increase the priority of hv3 so it becomes master.
13192 ovn-nbctl ha-chassis-group-add-chassis hagrp1 hv3 50
13194 # hv3 should be master and claim ls1-lp_ext1
13196 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13197 logical_port=ls1-lp_ext1`
13198 test "$chassis" = "$hv3_uuid"])
13202 reset_pcap_file hv1-ext1 hv1/ext1
13203 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13204 reset_pcap_file br-phys hv1/br-phys
13208 reset_pcap_file hv2-ext2 hv2/ext2
13209 reset_pcap_file br-phys_n1 hv2/br-phys_n1
13210 reset_pcap_file br-phys hv2/br-phys
13214 reset_pcap_file hv3-ext3 hv3/ext3
13215 reset_pcap_file br-phys_n1 hv3/br-phys_n1
13216 reset_pcap_file br-phys hv3/br-phys
13218 # Send DHCPDISCOVER.
13219 offer_ip=`ip_to_hex 10 0 0 6`
13220 server_ip=`ip_to_hex 10 0 0 1`
13221 server_mac=ff1000000001
13222 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
13223 test_dhcp 1 f00000000003 01 $offer_ip 0 $server_mac $server_ip \
13224 $expected_dhcp_opts
13226 # NXT_RESUMEs should be 4 in hv1.
13227 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13229 # NXT_RESUMEs should be 2 in hv2.
13230 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13232 # NXT_RESUMEs should be 1 in hv3.
13233 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13235 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap > ext1_v4.packets
13236 cat ext1_v4.expected | cut -c -48 > expout
13237 AT_CHECK([cat ext1_v4.packets | cut -c -48], [0], [expout])
13238 # Skipping the IPv4 checksum.
13239 cat ext1_v4.expected | cut -c 53- > expout
13240 AT_CHECK([cat ext1_v4.packets | cut -c 53-], [0], [expout])
13242 # ovs-ofctl also resumes the packets and this causes other ports to receive
13243 # the DHCP request packet. So reset the pcap files so that its easier to test.
13245 reset_pcap_file hv1-ext1 hv1/ext1
13247 rm -f ext1_v4.expected
13248 rm -f ext1_v4.packets
13250 # Send DHCPv6 request
13251 src_mac=f00000000003
13252 src_lla=fe80000000000000f20000fffe000003
13253 offer_ip=ae700000000000000000000000000006
13254 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
13256 # NXT_RESUMEs should be 4 in hv1.
13257 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor0_hv1.log | grep -c NXT_RESUME`])
13259 # NXT_RESUMEs should be 2 in hv2.
13260 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv2.log | grep -c NXT_RESUME`])
13262 # NXT_RESUMEs should be 2 in hv3.
13263 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor0_hv3.log | grep -c NXT_RESUME`])
13265 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ext1-tx.pcap | \
13266 sort > ext1_v6.packets
13267 cat ext1_v6.expected | cut -c -120 > expout
13268 AT_CHECK([cat ext1_v6.packets | cut -c -120], [0], [expout])
13269 # Skipping the UDP checksum
13270 cat ext1_v6.expected | cut -c 125- > expout
13271 AT_CHECK([cat ext1_v6.packets | cut -c 125-], [0], [expout])
13273 # disconnect hv3 from the network, hv1 should take over
13275 port=${sandbox}_br-phys
13276 as main ovs-vsctl del-port n1 $port
13278 # hv1 should be master and claim ls1-lp_ext1
13280 [chassis=`ovn-sbctl --bare --columns chassis find port_binding \
13281 logical_port=ls1-lp_ext1`
13282 test "$chassis" = "$hv1_uuid"])
13284 OVN_CLEANUP([hv1],[hv2],[hv3])
13287 AT_SETUP([ovn -- Address Set Incremental Processing])
13288 AT_KEYWORDS([ovn_as_inc])
13289 AT_SKIP_IF([test $HAVE_PYTHON = no])
13295 ovs-vsctl add-br br-phys
13296 ovn_attach n1 br-phys 192.168.0.10
13298 ovn-nbctl ls-add ls1
13300 ovn-nbctl lsp-add ls1 lp$i \
13301 -- lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.1.$i"
13303 -- add-port br-int vif$i \
13304 -- set Interface vif$i \
13305 external-ids:iface-id=lp$i
13309 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13310 as2_uuid=`ovn-nbctl --wait=hv create addr name=as2`
13311 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13312 'outport=="lp1" && ip4 && ip4.src == {$as1, $as2}' allow-related
13313 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10"
13314 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [0], [ignore])
13316 # Update address set as1
13317 ovn-nbctl --wait=hv set addr as1 addresses="10.1.2.10 10.1.2.11"
13318 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.11"], [0], [ignore])
13320 # Update address set as2
13321 ovn-nbctl --wait=hv set addr as2 addresses="10.1.2.12 10.1.2.13"
13322 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13324 # Add another ACL referencing as1
13325 n_flows_before=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13326 ovn-nbctl --wait=hv acl-add ls1 to-lport 200 \
13327 'outport=="lp2" && ip4 && ip4.src == $as1' allow-related
13328 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13329 AT_CHECK([test $(expr $n_flows_before \* 2) = $n_flows_after], [0], [ignore])
13332 ovn-nbctl --wait=hv acl-del ls1 to-lport 200 \
13333 'outport=="lp2" && ip4 && ip4.src == $as1'
13334 n_flows_after=`ovs-ofctl dump-flows br-int | grep "10.1.2.10" | wc -l`
13335 AT_CHECK([test $n_flows_before = $n_flows_after], [0], [ignore])
13337 # Remove as1 while it is still used by an ACL, the lflows should be reparsed and
13338 # parsing should fail.
13339 echo "before del as1"
13340 ovn-nbctl list addr | grep as1
13341 ovn-nbctl --wait=hv destroy addr $as1_uuid
13342 echo "after del as1"
13343 ovn-nbctl list addr | grep as1
13344 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.10"], [1], [ignore])
13345 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13348 as1_uuid=`ovn-nbctl --wait=hv create addr name=as1`
13349 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [0], [ignore])
13351 # Remove ACLs and address sets
13352 ovn-nbctl --wait=hv destroy addr $as1_uuid -- destroy addr $as2_uuid
13353 AT_CHECK([ovs-ofctl dump-flows br-int | grep "10.1.2.12"], [1], [ignore])
13355 ovn-nbctl --wait=hv acl-del ls1
13358 # Gracefully terminate daemons
13362 AT_SETUP([ovn -- ovn-controller restart])
13363 AT_SKIP_IF([test $HAVE_PYTHON = no])
13367 # One Logical Router: ro, with two logical switches sw1 and sw2.
13368 # sw1 is for subnet 10.0.0.0/8
13369 # sw2 is for subnet 20.0.0.0/8
13370 # sw1 has a single port bound on hv1
13371 # sw2 has a single port bound on hv2
13373 ovn-nbctl lr-add ro
13374 ovn-nbctl ls-add sw1
13375 ovn-nbctl ls-add sw2
13377 sw1_ro_mac=00:00:10:00:00:01
13379 sw2_ro_mac=00:00:20:00:00:01
13381 sw1_p1_mac=00:00:10:00:00:02
13383 sw2_p1_mac=00:00:20:00:00:02
13386 ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
13387 ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
13388 ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
13389 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
13390 ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
13391 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
13393 ovn-nbctl lsp-add sw1 sw1-p1 \
13394 -- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
13396 ovn-nbctl lsp-add sw2 sw2-p1 \
13397 -- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
13403 ovs-vsctl add-br br-phys
13404 ovn_attach n1 br-phys 192.168.0.1
13405 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13406 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
13407 options:tx_pcap=hv1/vif1-tx.pcap \
13408 options:rxq_pcap=hv1/vif1-rx.pcap \
13413 ovs-vsctl add-br br-phys
13414 ovn_attach n1 br-phys 192.168.0.2
13415 ovs-vsctl -- add-port br-int hv2-vif1 -- \
13416 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
13417 options:tx_pcap=hv2/vif1-tx.pcap \
13418 options:rxq_pcap=hv2/vif1-rx.pcap \
13425 packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
13426 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13427 udp && udp.src==53 && udp.dst==4369"
13429 # Start by Sending the packet and make sure it makes it there as expected
13430 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13432 # Expected packet has TTL decreased by 1
13433 expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
13434 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
13435 udp && udp.src==53 && udp.dst==4369"
13436 echo $expected | ovstest test-ovn expr-to-packets > expected
13438 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13440 # Stop ovn-controller on hv2 with --restart flag
13441 as hv2 ovs-appctl -t ovn-controller exit --restart
13443 # Now send the packet again. This time, it should still arrive
13444 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
13446 cat expected expected > expected2
13448 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
13450 # Start ovn-controller again just so OVN_CLEANUP doesn't complain
13451 as hv2 start_daemon ovn-controller
13453 OVN_CLEANUP([hv1],[hv2])
13458 AT_SETUP([ovn -- ovn-nbctl duplicate addresses])
13461 # Set up a switch with some switch ports of varying address types
13462 ovn-nbctl ls-add sw1
13463 ovn-nbctl set logical_switch sw1 other_config:subnet=192.168.0.0/24
13465 ovn-nbctl lsp-add sw1 sw1-p1
13466 ovn-nbctl lsp-add sw1 sw1-p2
13467 ovn-nbctl lsp-add sw1 sw1-p3
13468 ovn-nbctl lsp-add sw1 sw1-p4
13470 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"
13471 ovn-nbctl lsp-set-addresses sw1-p2 "00:00:00:00:00:03 dynamic"
13472 ovn-nbctl lsp-set-addresses sw1-p3 "dynamic"
13473 ovn-nbctl lsp-set-addresses sw1-p4 "router"
13474 ovn-nbctl lsp-set-addresses sw1-p5 "unknown"
13476 ovn-nbctl list logical_switch_port
13478 # Now try to add duplicate addresses on a new port. These should all fail
13479 ovn-nbctl --wait=sb lsp-add sw1 sw1-p5
13480 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.1"], [1], [],
13481 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.1
13483 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 10.0.0.2"], [1], [],
13484 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 10.0.0.2
13486 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::1"], [1], [],
13487 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::1
13489 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 aef0::2"], [1], [],
13490 [ovn-nbctl: Error on switch sw1: duplicate IPv6 address aef0::2
13492 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.2"], [1], [],
13493 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.2
13495 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p5 "00:00:00:00:00:04 192.168.0.3"], [1], [],
13496 [ovn-nbctl: Error on switch sw1: duplicate IPv4 address 192.168.0.3
13499 # Now try re-setting sw1-p1. This should succeed
13500 AT_CHECK([ovn-nbctl lsp-set-addresses sw1-p1 "00:00:00:00:00:01 10.0.0.1 aef0::1"])
13502 # Now create a new switch and try setting IP addresses the same as the
13503 # first switch. This should succeed.
13504 ovn-nbctl ls-add sw2
13505 ovn-nbctl lsp-add sw2 sw2-p1
13507 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 10.0.0.1"])
13508 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.2"])
13509 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 192.168.0.3"])
13510 AT_CHECK([ovn-nbctl lsp-set-addresses sw2-p1 "00:00:00:00:00:04 aef0::1"])
13514 AT_SETUP([ovn -- router - check packet length - icmp defrag])
13515 AT_KEYWORDS([check packet length])
13516 AT_SKIP_IF([test $HAVE_PYTHON = no])
13519 ovn-nbctl ls-add sw0
13520 ovn-nbctl lsp-add sw0 sw0-port1
13521 ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 10.0.0.3"
13523 ovn-nbctl lr-add lr0
13524 ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
13525 ovn-nbctl lsp-add sw0 sw0-lr0
13526 ovn-nbctl lsp-set-type sw0-lr0 router
13527 ovn-nbctl lsp-set-addresses sw0-lr0 router
13528 ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
13530 ovn-nbctl ls-add public
13531 ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 172.168.0.100/24
13532 ovn-nbctl lsp-add public public-lr0
13533 ovn-nbctl lsp-set-type public-lr0 router
13534 ovn-nbctl lsp-set-addresses public-lr0 router
13535 ovn-nbctl lsp-set-options public-lr0 router-port=lr0-public
13538 ovn-nbctl lsp-add public ln-public
13539 ovn-nbctl lsp-set-type ln-public localnet
13540 ovn-nbctl lsp-set-addresses ln-public unknown
13541 ovn-nbctl lsp-set-options ln-public network_name=phys
13543 ovn-nbctl lrp-set-gateway-chassis lr0-public hv1 20
13544 ovn-nbctl lr-nat-add lr0 snat 172.168.0.100 10.0.0.0/24
13550 ovs-vsctl add-br br-phys
13551 ovn_attach n1 br-phys 192.168.0.1
13552 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13553 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13554 set interface hv1-vif1 external-ids:iface-id=sw0-port1 \
13555 options:tx_pcap=hv1/vif1-tx.pcap \
13556 options:rxq_pcap=hv1/vif1-rx.pcap \
13559 reset_pcap_file() {
13562 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
13563 options:rxq_pcap=dummy-rx.pcap
13564 rm -f ${pcap_file}*.pcap
13565 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
13566 options:rxq_pcap=${pcap_file}-rx.pcap
13570 printf "%02x%02x%02x%02x" "$@"
13573 test_ip_packet_larger() {
13574 local icmp_pmtu_reply_expected=$1
13576 # Send ip packet from sw0-port1 to outside
13577 src_mac="505400000001" # sw-port1 mac
13578 dst_mac="00000000ff01" # sw0-lr0 mac (internal router leg)
13579 src_ip=`ip_to_hex 10 0 0 3`
13580 dst_ip=`ip_to_hex 172 168 0 3`
13581 # Set the packet length to 100.
13583 packet=${dst_mac}${src_mac}08004500${pkt_len}0000000040010000
13584 orig_packet_l3=${src_ip}${dst_ip}0304000000000000
13585 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13586 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13587 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13588 orig_packet_l3=${orig_packet_l3}000000000000000000000000000000000000
13589 packet=${packet}${orig_packet_l3}
13591 gw_ip_garp=ffffffffffff00002020121308060001080006040001000020201213aca80064000000000000aca80064
13593 # If icmp_pmtu_reply_expected is 0, it means the packet is lesser than
13594 # the gateway mtu and should be delivered to the provider bridge via the
13596 # If icmp_pmtu_reply_expected is 1, it means the packet is larger than
13597 # the gateway mtu and ovn-controller should drop the packet and instead
13598 # generate ICMPv4 Destination Unreachable message with pmtu set to 42.
13599 if test $icmp_pmtu_reply_expected = 0; then
13600 # Packet to expect at br-phys.
13601 src_mac="000020201213"
13602 dst_mac="00000012af11"
13603 src_ip=`ip_to_hex 10 0 0 3`
13604 dst_ip=`ip_to_hex 172 168 0 3`
13605 expected=${dst_mac}${src_mac}08004500${pkt_len}000000003f010100
13606 expected=${expected}${src_ip}${dst_ip}0304000000000000
13607 expected=${expected}000000000000000000000000000000000000
13608 expected=${expected}000000000000000000000000000000000000
13609 expected=${expected}000000000000000000000000000000000000
13610 expected=${expected}000000000000000000000000000000000000
13611 echo $expected > br_phys_n1.expected
13612 echo $gw_ip_garp >> br_phys_n1.expected
13614 # MTU would be 100 - 18 = 82 (hex 0052)
13616 src_ip=`ip_to_hex 10 0 0 1`
13617 dst_ip=`ip_to_hex 10 0 0 3`
13618 # pkt len should be 128 (28 (icmp packet) + 100 (orig ip + payload))
13621 icmp_reply=${src_mac}${dst_mac}08004500${reply_pkt_len}00004000fe016879
13622 icmp_reply=${icmp_reply}${src_ip}${dst_ip}0304${ip_csum}0000${mtu}
13623 icmp_reply=${icmp_reply}4500${pkt_len}000000003f010100
13624 icmp_reply=${icmp_reply}${orig_packet_l3}
13625 echo $icmp_reply > hv1-vif1.expected
13628 as hv1 reset_pcap_file br-phys_n1 hv1/br-phys_n1
13629 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
13631 # Send packet from sw0-port1 to outside
13632 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
13634 if test $icmp_pmtu_reply_expected = 0; then
13635 OVN_CHECK_PACKETS([hv1/br-phys_n1-tx.pcap], [br_phys_n1.expected])
13636 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > pkts
13637 # hv1/vif1-tx.pcap can receive the GARP packet generated by ovn-controller
13638 # for the gateway router port. So ignore this packet.
13639 cat pkts | grep -v $gw_ip_garp > packets
13640 AT_CHECK([cat packets], [0], [])
13642 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [hv1-vif1.expected])
13643 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap > \
13645 # hv1/br-phys_n1-tx.pcap can receive the GARP packet generated by ovn-controller
13646 # for the gateway router port. So ignore this packet.
13647 cat pkts | grep -v $gw_ip_garp > packets
13648 AT_CHECK([cat packets], [0], [])
13655 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int \
13656 | grep "check_pkt_larger" | wc -l], [0], [[0
13658 dp_uuid=$(ovn-sbctl find datapath_binding | grep sw0 -B2 | grep _uuid | \
13660 ovn-sbctl create MAC_Binding ip=172.168.0.3 datapath=$dp_uuid \
13661 logical_port=lr0-public mac="00\:00\:00\:12\:af\:11"
13663 # Set the gateway mtu to 100. If the packet length is > 100, ovn-controller
13664 # should send icmp host not reachable with pmtu set to 100.
13665 ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=100
13666 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13668 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(100)" | \
13672 icmp_reply_expected=1
13673 test_ip_packet_larger $icmp_reply_expected
13675 # Set the gateway mtu to 500.
13676 ovn-nbctl --wait=hv set logical_router_port lr0-public options:gateway_mtu=500
13677 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
13679 test `as hv1 ovs-ofctl dump-flows br-int | grep "check_pkt_larger(500)" | \
13683 # Now the packet should be sent via the localnet port to br-phys.
13684 icmp_reply_expected=0
13685 test_ip_packet_larger $icmp_reply_expected
13689 AT_SETUP([ovn -- IP packet buffering])
13690 AT_KEYWORDS([ip-buffering])
13691 AT_SKIP_IF([test $HAVE_PYTHON = no])
13695 # One LR lr0 that has switches sw0 (192.168.1.0/24) and
13696 # sw1 (172.16.1.0/24) connected to it.
13698 # Physical network:
13699 # Tw0 hypervisors hv[12].
13700 # hv1 hosts vif sw0-p0.
13701 # hv1 hosts vif sw1-p0.
13703 send_icmp_packet() {
13704 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7 data=$8
13709 local packet=${eth_dst}${eth_src}08004500${ip_len}00004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${data}
13710 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13713 send_icmp6_packet() {
13714 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
13717 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
13718 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}8000dcb662f00001
13720 as hv$hv ovs-appctl netdev-dummy/receive hv$hv-vif$inport $packet
13724 local eth_src=$1 spa=$2 tpa=$3
13725 local request=ffffffffffff${eth_src}08060001080006040001${eth_src}${spa}000000000000${tpa}
13730 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 spa=$5 tpa=$6
13731 local request=${eth_dst}${eth_src}08060001080006040002${eth_src}${spa}${eth_dst}${tpa}
13732 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13736 local hv=$1 inport=$2 eth_src=$3 eth_dst=$4 src_ip=$5 dst_ip=$6
13737 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13738 local request=${eth_dst}${eth_src}86dd${ip6_hdr}8800d78440000000${src_ip}0201${eth_src}
13740 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
13744 local eth_src=$1 src_ip=$2 dst_ip=$3 ta=$4
13745 local ip6_hdr=6000000000203aff${src_ip}${dst_ip}
13746 request=3333ff000010${eth_src}86dd${ip6_hdr}8700357600000000${ta}0101${eth_src}
13755 ovs-vsctl add-br br-phys
13756 ovn_attach n1 br-phys 192.168.0.1
13757 ovs-vsctl -- add-port br-int hv1-vif1 -- \
13758 set interface hv1-vif1 external-ids:iface-id=sw0-p0 \
13759 options:tx_pcap=hv1/vif1-tx.pcap \
13760 options:rxq_pcap=hv1/vif1-rx.pcap \
13765 ovs-vsctl add-br br-phys
13766 ovn_attach n1 br-phys 192.168.0.2
13767 ovs-vsctl -- add-port br-int hv2-vif1 -- \
13768 set interface hv2-vif1 external-ids:iface-id=sw1-p0 \
13769 options:tx_pcap=hv2/vif1-tx.pcap \
13770 options:rxq_pcap=hv2/vif1-rx.pcap \
13773 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
13774 ovn-nbctl ls-add sw0
13775 ovn-nbctl ls-add sw1
13777 ovn-nbctl lrp-add lr0 sw0 00:00:01:01:02:03 192.168.1.1/24 2001:0:0:0:0:0:0:1/64
13778 ovn-nbctl lsp-add sw0 rp-sw0 -- set Logical_Switch_Port rp-sw0 \
13779 type=router options:router-port=sw0 \
13780 -- lsp-set-addresses rp-sw0 router
13782 ovn-nbctl lrp-add lr0 sw1 00:00:02:01:02:03 172.16.1.1/24 2002:0:0:0:0:0:0:1/64
13783 ovn-nbctl lsp-add sw1 rp-sw1 -- set Logical_Switch_Port rp-sw1 \
13784 type=router options:router-port=sw1 \
13785 -- lsp-set-addresses rp-sw1 router
13787 ovn-nbctl lsp-add sw0 sw0-p0 \
13788 -- lsp-set-addresses sw0-p0 "f0:00:00:01:02:03 192.168.1.2 2001::2"
13790 ovn-nbctl lsp-add sw1 sw1-p0 \
13791 -- lsp-set-addresses sw1-p0 unknown
13794 ovn-nbctl --wait=hv sync
13797 printf "%02x%02x%02x%02x" "$@"
13800 src_mac=f00000010203
13801 src_ip=$(ip_to_hex 192 168 1 2)
13802 src_ip6=20010000000000000000000000000002
13804 router_mac0=000001010203
13805 router_mac1=000002010203
13806 router_ip=$(ip_to_hex 172 16 1 1)
13807 router_ip6=20020000000000000000000000000001
13809 dst_mac=001122334455
13810 dst_ip=$(ip_to_hex 172 16 1 10)
13811 dst_ip6=20020000000000000000000000000010
13813 data=0800bee4391a0001
13815 send_icmp_packet 1 1 $src_mac $router_mac0 $src_ip $dst_ip 0000 $data
13816 send_arp_reply 2 1 $dst_mac $router_mac1 $dst_ip $router_ip
13817 echo $(get_arp_req $router_mac1 $router_ip $dst_ip) > expected
13818 echo "${dst_mac}${router_mac1}08004500001c00004000fe010100${src_ip}${dst_ip}${data}" >> expected
13820 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13822 nd_ip=ff0200000000000000000001ff000010
13823 ip6_hdr=6000000000083afe${src_ip6}${dst_ip6}
13825 send_icmp6_packet 1 1 $src_mac $router_mac0 $src_ip6 $dst_ip6
13826 echo $(get_nd $router_mac1 $src_ip6 $nd_ip $dst_ip6) >> expected
13827 echo "${dst_mac}${router_mac1}86dd${ip6_hdr}8000dcb662f00001" >> expected
13828 send_na 2 1 $dst_mac $router_mac1 $dst_ip6 $router_ip6
13830 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
13832 OVN_CLEANUP([hv1],[hv2])
13835 AT_SETUP([ovn -- neighbor update on same HV])
13836 AT_SKIP_IF([test $HAVE_PYTHON = no])
13840 # A public switch (pub) with a localnet port connected to two LRs (lr0 and lr1)
13841 # each with a distributed gateway port.
13842 # Two VMs: lp0 on sw0 connected to lr0
13843 # lp1 on sw1 connected to lr1
13845 # This test adds a floating IP to each VM so when they are bound to the same
13846 # hypervisor, it checks that the GARP sent by ovn-controller causes the
13847 # MAC_Binding entries to be updated properly on each logical router.
13848 # It will also capture packets on the physical interface to make sure that the
13849 # GARPs have been sent out to the external network as well.
13851 # Create logical switches
13852 ovn-nbctl ls-add sw0
13853 ovn-nbctl ls-add sw1
13854 ovn-nbctl ls-add pub
13856 # Created localnet port on public switch
13857 ovn-nbctl lsp-add pub ln-pub
13858 ovn-nbctl lsp-set-type ln-pub localnet
13859 ovn-nbctl lsp-set-addresses ln-pub unknown
13860 ovn-nbctl lsp-set-options ln-pub network_name=phys
13862 # Create logical routers and connect them to public switch
13863 ovn-nbctl create Logical_Router name=lr0
13864 ovn-nbctl create Logical_Router name=lr1
13866 ovn-nbctl lrp-add lr0 lr0-pub f0:00:00:00:00:01 172.24.4.220/24
13867 ovn-nbctl lsp-add pub pub-lr0 -- set Logical_Switch_Port pub-lr0 \
13868 type=router options:router-port=lr0-pub options:nat-addresses="router" addresses="router"
13869 ovn-nbctl lrp-add lr1 lr1-pub f0:00:00:00:01:01 172.24.4.221/24
13870 ovn-nbctl lsp-add pub pub-lr1 -- set Logical_Switch_Port pub-lr1 \
13871 type=router options:router-port=lr1-pub options:nat-addresses="router" addresses="router"
13873 ovn-nbctl lrp-set-gateway-chassis lr0-pub hv1 10
13874 ovn-nbctl lrp-set-gateway-chassis lr1-pub hv1 10
13876 # Connect sw0 and sw1 to lr0 and lr1
13877 ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.254/24
13878 ovn-nbctl lsp-add sw0 sw0-lr0 -- set Logical_Switch_Port sw0-lr0 type=router \
13879 options:router-port=lr0-sw0 addresses="router"
13880 ovn-nbctl lrp-add lr1 lr1-sw1 00:00:00:00:ff:02 20.0.0.254/24
13881 ovn-nbctl lsp-add sw1 sw1-lr1 -- set Logical_Switch_Port sw1-lr1 type=router \
13882 options:router-port=lr1-sw1 addresses="router"
13886 ovn-nbctl lr-nat-add lr0 snat 172.24.4.220 10.0.0.0/24
13887 ovn-nbctl lr-nat-add lr1 snat 172.24.4.221 20.0.0.0/24
13892 ovs-vsctl add-br br-phys
13893 ovn_attach n1 br-phys 172.24.4.1
13894 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
13896 ovs-vsctl add-port br-int vif0 -- set Interface vif0 external-ids:iface-id=lp0
13897 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
13899 ovn-nbctl lsp-add sw0 lp0
13900 ovn-nbctl lsp-add sw1 lp1
13901 ovn-nbctl lsp-set-addresses lp0 "50:54:00:00:00:01 10.0.0.10"
13902 ovn-nbctl lsp-set-addresses lp1 "50:54:00:00:00:02 20.0.0.10"
13904 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp0` = xup])
13905 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
13907 # Create two floating IPs, one for each VIF
13908 ovn-nbctl lr-nat-add lr0 dnat_and_snat 172.24.4.100 10.0.0.10
13909 ovn-nbctl lr-nat-add lr1 dnat_and_snat 172.24.4.200 20.0.0.10
13911 # Check that the MAC_Binding entries have been properly created
13912 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr0-pub" ip="172.24.4.200" | wc -l` -gt 0])
13913 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding logical_port="lr1-pub" ip="172.24.4.100" | wc -l` -gt 0])
13915 # Check that the GARPs went also to the external physical network
13916 # Wait until at least 4 packets have arrived and copy them to a separate file as
13917 # more GARPs are expected in the capture in order to avoid race conditions.
13918 OVS_WAIT_UNTIL([test `$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | wc -l` -gt 4])
13919 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | head -n4 > hv1/br-phys-tx4.pcap
13921 # GARP for lp0 172.24.4.100 on lr0-pub MAC (f0:00:00:00:00:01)
13922 echo "fffffffffffff0000000000108060001080006040001f00000000001ac180464000000000000ac180464" > expout
13923 # GARP for 172.24.4.220 on lr0-pub (f0:00:00:00:00:01)
13924 echo "fffffffffffff0000000000108060001080006040001f00000000001ac1804dc000000000000ac1804dc" >> expout
13925 #Â GARP for lp1 172.24.4.200 on lr1-pub MAC (f0:00:00:00:01:01)
13926 echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804c8000000000000ac1804c8" >> expout
13927 # GARP for 172.24.4.221 on lr1-pub (f0:00:00:00:01:01)
13928 echo "fffffffffffff0000000010108060001080006040001f00000000101ac1804dd000000000000ac1804dd" >> expout
13929 AT_CHECK([sort hv1/br-phys-tx4.pcap], [0], [expout])
13930 #OVN_CHECK_PACKETS([hv1/br-phys-tx4.pcap], [br-phys.expected])
13935 AT_SETUP([ovn -- ipam to non-ipam])
13938 ovn-nbctl --wait=hv set NB_Global . options:mac_prefix="0a:00:00:00:00:00"
13939 ovn-nbctl ls-add sw0
13940 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
13941 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
13943 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
13944 ["0a:00:00:a8:01:03 192.168.1.2"
13947 ovn-nbctl --wait=sb lsp-set-addresses p0 router
13949 ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses
13951 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0], [[[]]
13955 AT_SETUP([ovn -- ipam router ports])
13958 ovn-nbctl ls-add sw
13959 ovn-nbctl set logical_switch sw other-config:subnet=192.168.1.0/24
13962 ovn-nbctl lr-add ro$i
13963 ovn-nbctl lsp-add sw swp$i
13964 ovn-nbctl --wait=sb lsp-set-addresses swp$i "02:00:00:00:00:0$i dynamic"
13965 cidr=$(ovn-nbctl get logical_switch_port swp$i dynamic_addresses |cut -f2 -d' '|cut -f1 -d\")
13966 ovn-nbctl lrp-add ro$i rop$i 02:00:00:00:00:0$i $cidr/24 -- set logical_switch_port swp$i type=router options:router-port=rop$i addresses=router;
13967 AT_CHECK_UNQUOTED([ovn-nbctl get logical_router_port rop$i networks], [0], [[["192.168.1.$i/24"]]
13971 ovn-nbctl list logical_switch_port
13972 ovn-nbctl list logical_router_port
13976 AT_SETUP([ovn -- test transport zones])
13980 for i in 1 2 3 4 5; do
13983 ovs-vsctl add-br br-phys
13984 ovn_attach n1 br-phys 192.168.$i.1
13987 dnl Wait for the changes to be propagated
13988 ovn-nbctl --wait=sb --timeout=3 sync
13989 ovn-nbctl --wait=hv --timeout=3 sync
13991 dnl Assert that each Chassis has a tunnel formed to every other Chassis
13993 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14001 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14009 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14017 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14025 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14032 dnl Let's now add some Chassis to different transport zones
14033 dnl * hv1: Will be part of two transport zones: tz1 and tz2 so it
14034 dnl should have tunnels formed between the other two Chassis (hv2 and hv3)
14036 dnl * hv2: Will be part of one transport zone: tz1. It should have a tunnel
14037 dnl to hv1 but not to hv3
14039 dnl * hv3: Will be part of one transport zone: tz2. It should have a tunnel
14040 dnl to hv1 but not to hv2
14042 dnl * hv4 and hv5: Will not have any TZ set so they will keep the tunnels
14043 dnl between themselves and remove the tunnels to other Chassis which now
14044 dnl belongs to some TZs
14047 ovs-vsctl set open . external-ids:ovn-transport-zones=tz1,tz2
14050 ovs-vsctl set open . external-ids:ovn-transport-zones=tz1
14053 ovs-vsctl set open . external-ids:ovn-transport-zones=tz2
14055 dnl Wait for the changes to be propagated
14056 ovn-nbctl --wait=sb --timeout=3 sync
14057 ovn-nbctl --wait=hv --timeout=3 sync
14060 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14066 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14071 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14076 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14081 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14085 dnl Removing the transport zones should make all Chassis to create
14086 dnl tunnels between every other Chassis again
14089 ovs-vsctl remove open . external-ids ovn-transport-zones
14092 dnl Wait for the changes to be propagated
14093 ovn-nbctl --wait=sb --timeout=3 sync
14094 ovn-nbctl --wait=hv --timeout=3 sync
14097 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14105 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14113 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14121 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14129 AT_CHECK([ovs-vsctl --bare --columns=name find interface type="geneve" | awk NF | sort], [0],
14136 OVN_CLEANUP([hv1], [hv2], [hv3])
14139 AT_SETUP([ovn -- 2 HVs, 2 lports/HV, localnet ports, DVR chassis mac])
14143 # In this test cases we create 2 switches, all connected to same
14144 # physical network (through br-phys on each HV). Each switch has
14145 # 1 VIF. Each HV has 1 VIF port. The first digit
14146 # of VIF port name indicates the hypervisor it is bound to, e.g.
14147 # lp23 means VIF 3 on hv2.
14149 # Each switch's VLAN tag and their logical switch ports are:
14151 # - tagged with VLAN 101
14154 # - tagged with VLAN 201
14157 # Note: a localnet port is created for each switch to connect to
14158 # physical network.
14162 ovn-nbctl ls-add $ls_name
14164 if test $i -eq 1; then
14165 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
14166 elif test $i -eq 2; then
14167 ovn-nbctl lsp-add $ls_name $ln_port_name "" 201
14169 ovn-nbctl lsp-set-addresses $ln_port_name unknown
14170 ovn-nbctl lsp-set-type $ln_port_name localnet
14171 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
14176 # Prints the name of the logical switch that contains LSP.
14179 lp?[[11]]) echo ls1 ;; dnl (
14180 lp?[[12]]) echo ls2 ;; dnl (
14181 *) AT_FAIL_IF([:]) ;;
14187 vif?[[11]]) echo ls1 ;; dnl (
14188 vif?[[12]]) echo ls2 ;; dnl (
14189 *) AT_FAIL_IF([:]) ;;
14195 hv1) echo 1 ;; dnl (
14196 hv2) echo 2 ;; dnl (
14197 *) AT_FAIL_IF([:]) ;;
14203 vif22) echo 22 ;; dnl (
14204 vif21) echo 21 ;; dnl (
14205 *) AT_FAIL_IF([:]) ;;
14211 vif[[1]]?) echo hv1 ;; dnl (
14212 vif[[2]]?) echo hv2 ;; dnl (
14213 *) AT_FAIL_IF([:]) ;;
14218 echo router-to-`vif_to_ls $1`
14221 hv_to_chassis_mac () {
14223 hv[[1]]) echo aa:bb:cc:dd:ee:11 ;; dnl (
14224 hv[[2]]) echo aa:bb:cc:dd:ee:22 ;; dnl (
14225 *) AT_FAIL_IF([:]) ;;
14230 printf "%02x%02x%02x%02x" "$@"
14237 ovs-vsctl add-br br-phys
14238 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
14239 ovs-vsctl set open . external-ids:ovn-chassis-mac-mappings="phys:aa:bb:cc:dd:ee:$i$i"
14240 ovn_attach n1 br-phys 192.168.0.$i
14242 ovs-vsctl add-port br-int vif$i$i -- \
14243 set Interface vif$i$i external-ids:iface-id=lp$i$i \
14244 options:tx_pcap=hv$i/vif$i$i-tx.pcap \
14245 options:rxq_pcap=hv$i/vif$i$i-rx.pcap \
14246 ofport-request=$i$i
14249 ls_name=$(lsp_to_ls $lsp_name)
14251 ovn-nbctl lsp-add $ls_name $lsp_name
14252 ovn-nbctl lsp-set-addresses $lsp_name "f0:00:00:00:00:$i$i 192.168.$i.$i"
14253 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$i
14255 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
14259 ovn-nbctl lr-add router
14260 ovn-nbctl lrp-add router router-to-ls1 00:00:01:01:02:03 192.168.1.3/24
14261 ovn-nbctl lrp-add router router-to-ls2 00:00:01:01:02:05 192.168.2.3/24
14263 ovn-nbctl lsp-add ls1 ls1-to-router -- set Logical_Switch_Port ls1-to-router type=router options:router-port=router-to-ls1 -- lsp-set-addresses ls1-to-router router
14264 ovn-nbctl lsp-add ls2 ls2-to-router -- set Logical_Switch_Port ls2-to-router type=router options:router-port=router-to-ls2 -- lsp-set-addresses ls2-to-router router
14266 ovn-nbctl --wait=sb sync
14267 #ovn-sbctl dump-flows
14275 # This packet has bad checksums but logical L3 routing doesn't check.
14276 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
14277 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
14278 shift; shift; shift; shift; shift
14279 hv=`vif_to_hv $inport`
14280 hv_num=`hv_to_num $hv`
14281 chassis_mac=`hv_to_chassis_mac $hv`
14282 as $hv ovs-appctl netdev-dummy/receive $inport $packet
14283 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
14284 in_ls=`vif_to_ls $inport`
14285 in_lrp=`vif_to_lrp $inport`
14287 out_ls=`vif_to_ls $outport`
14288 if test $in_ls = $out_ls; then
14289 # Ports on the same logical switch receive exactly the same packet.
14292 # Routing decrements TTL and updates source and dest MAC
14294 outport_num=`vif_to_num $outport`
14295 out_lrp=`vif_to_lrp $outport`
14296 echo f000000000${outport_num}aabbccddee${hv_num}${hv_num}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
14297 fi >> $outport.expected
14301 # Dump a bunch of info helpful for debugging if there's a failure.
14303 echo "------ OVN dump ------"
14307 echo "------ hv1 dump ------"
14308 as hv1 ovs-vsctl show
14309 as hv1 ovs-vsctl list Open_Vswitch
14311 echo "------ hv2 dump ------"
14312 as hv2 ovs-vsctl show
14313 as hv2 ovs-vsctl list Open_Vswitch
14315 echo "Send traffic"
14316 sip=`ip_to_hex 192 168 1 1`
14317 dip=`ip_to_hex 192 168 2 2`
14318 test_ip vif11 f00000000011 000001010203 $sip $dip vif22
14320 echo "----------- Post Traffic hv1 dump -----------"
14321 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
14322 as hv1 ovs-appctl fdb/show br-phys
14324 echo "----------- Post Traffic hv2 dump -----------"
14325 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
14326 as hv2 ovs-appctl fdb/show br-phys
14328 OVN_CHECK_PACKETS([hv2/vif22-tx.pcap], [vif22.expected])
14330 OVN_CLEANUP([hv1],[hv2])
14334 # Run ovn-nbctl in daemon mode, change to a backup database and verify that
14335 # an insert operation is not allowed.
14336 AT_SETUP([ovn -- can't write to a backup database server instance])
14338 on_exit 'kill $(cat ovn-nbctl.pid)'
14339 export OVN_NB_DAEMON=$(ovn-nbctl --pidfile --detach)
14341 AT_CHECK([ovn-nbctl ls-add sw0])
14343 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep active | wc -l], [0], [1
14345 ovs-appctl -t ovsdb-server ovsdb-server/set-active-ovsdb-server tcp:192.0.2.2:6641
14346 ovs-appctl -t ovsdb-server ovsdb-server/connect-active-ovsdb-server
14347 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/sync-status | grep -c backup], [0], [1
14349 AT_CHECK([ovn-nbctl ls-add sw1], [1], [ignore],
14350 [ovn-nbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}