1 # OVN_CHECK_PACKETS([PCAP], [EXPECTED])
3 # This compares packets read from PCAP, in pcap format, to those read
4 # from EXPECTED, which is a text file containing packets as hex
5 # strings, one per line. If PCAP contains fewer packets than
6 # EXPECTED, it waits up to 10 seconds for more packets to appear.
8 # The implementation is an m4 macro that is mostly implemented in
9 # terms of a shell function. This reduces the size of the generated
10 # testsuite file since the shell function is only emitted once even
11 # when this macro is invoked many times.
12 m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
15 echo "checking packets in $1 against $2:"
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
19 exp_n=`wc -l < "$exp_text"`
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
27 sort $exp_text > expout
30 m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
34 AT_BANNER([OVN components])
36 AT_SETUP([ovn -- lexer])
37 dnl For lines without =>, input and expected output are identical.
38 dnl For lines with =>, input precedes => and expected output follows =>.
39 AT_DATA([test-cases.txt], [dnl
40 foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41 "abc\u0020def" => "abc def"
42 " => error("Input ends inside quoted string.")dnl "
44 $foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45 $1 => error("`$' must be followed by a valid identifier.") 1
50 a/*/b => a error("`/*' without matching `*/'.")
52 a/b => a error("`/' is only valid as part of `//' or `/*'.") b
54 0 1 12345 18446744073709551615
55 18446744073709551616 => error("Decimal constants must be less than 2**64.")
56 9999999999999999999999 => error("Decimal constants must be less than 2**64.")
57 01 => error("Decimal constants must not have leading zeros.")
61 1/0 => error("Value contains unmasked 1-bits.")
65 1/ => error("Integer constant expected.")
67 1/0x123 => error("Value and mask have incompatible formats.")
74 0XFEDCBA9876543210 => 0xfedcba9876543210
75 0xfedcba9876543210fedcba9876543210
76 0x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
77 0x => error("Hex digits expected following 0x.")
78 0X => error("Hex digits expected following 0X.")
81 0x1/0x0 => error("Value contains unmasked 1-bits.")
83 0x. => error("Invalid syntax in hexadecimal constant.")
85 192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86 256.1.2.3 => error("Invalid numeric constant.")
88 192.168.0.0/255.255.0.0 => 192.168.0.0/16
89 192.168.0.0/255.255.255.0 => 192.168.0.0/24
90 192.168.0.0/255.255.0.255
91 192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
93 192.168.0.0/255.255.255.255 => 192.168.0.0/32
94 1.2.3.4:5 => 1.2.3.4 : 5
98 ff00::1234 => ff00::1234
99 2001:db8:85a3::8a2e:370:7334
100 2001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
101 2001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
103 ::ffff:c000:0280 => ::ffff:192.0.2.128
105 ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
108 ff00::/ff00:: => ff00::/8
111 01:23:45:67:AB:CD => 01:23:45:67:ab:cd
113 FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
114 01:00:00:00:00:00/01:00:00:00:00:00
115 ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116 fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117 ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118 fe:x => error("Invalid numeric constant.")
119 00:01:02:03:04:x => error("Invalid numeric constant.")
121 # Test that operators are tokenized as expected, even without white space.
122 (){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
123 & => error("`&' is only valid as part of `&&'.")
124 | => error("`|' is only valid as part of `||'.")
125 - => error("`-' is only valid as part of `--'.")
127 ^ => error("Invalid character `^' in input.")
129 AT_CAPTURE_FILE([input.txt])
130 sed 's/ =>.*//' test-cases.txt > input.txt
131 sed 's/.* => //' test-cases.txt > expout
132 AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
135 dnl The OVN expression parser needs to know what fields overlap with one
136 dnl another. This test therefore verifies that all the smaller registers
137 dnl are defined as terms of subfields of the larger ones.
139 dnl When we add or remove registers this test needs to be updated, of course.
140 AT_SETUP([ovn -- registers])
141 AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142 [[reg0 = xxreg0[96..127]
143 reg1 = xxreg0[64..95]
144 reg2 = xxreg0[32..63]
146 reg4 = xxreg1[96..127]
147 reg5 = xxreg1[64..95]
148 reg6 = xxreg1[32..63]
152 xreg0 = xxreg0[64..127]
153 xreg1 = xxreg0[0..63]
154 xreg2 = xxreg1[64..127]
155 xreg3 = xxreg1[0..63]
156 xreg4 = OXM_OF_PKT_REG4
157 xxreg0 = NXM_NX_XXREG0
158 xxreg1 = NXM_NX_XXREG1
162 dnl Check that the OVN conntrack field definitions are correct.
163 AT_SETUP([ovn -- conntrack fields])
164 AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
165 [[ct.dnat = ct_state[7]
171 ct.snat = ct_state[6]
173 ct_label = NXM_NX_CT_LABEL
174 ct_label.blocked = ct_label[0]
175 ct_mark = NXM_NX_CT_MARK
176 ct_state = NXM_NX_CT_STATE
180 AT_SETUP([ovn -- compsition])
181 AT_CHECK([ovstest test-ovn composition 2], [0], [ignore])
184 AT_SETUP([ovn -- expression parser])
185 dnl For lines without =>, input and expected output are identical.
186 dnl For lines with =>, input precedes => and expected output follows =>.
187 AT_DATA([test-cases.txt], [[
189 eth.type==0x800 => eth.type == 0x800
190 eth.type[0..15] == 0x800 => eth.type == 0x800
193 vlan.present == 1 => vlan.present
194 !(vlan.present == 0) => vlan.present
195 !(vlan.present != 1) => vlan.present
197 vlan.present == 0 => !vlan.present
198 vlan.present != 1 => !vlan.present
199 !(vlan.present == 1) => !vlan.present
200 !(vlan.present != 0) => !vlan.present
203 eth.dst[0] == 1 => eth.dst[0]
204 eth.dst[0] != 0 => eth.dst[0]
205 !(eth.dst[0] == 0) => eth.dst[0]
206 !(eth.dst[0] != 1) => eth.dst[0]
209 eth.dst[0] == 0 => !eth.dst[0]
210 eth.dst[0] != 1 => !eth.dst[0]
211 !(eth.dst[0] == 1) => !eth.dst[0]
212 !(eth.dst[0] != 0) => !eth.dst[0]
214 vlan.tci[12..15] == 0x3
215 vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
216 vlan.tci[12..15] != 0x3
217 vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
219 !vlan.pcp => vlan.pcp == 0
220 !(vlan.pcp) => vlan.pcp == 0
227 !(vlan.pcp != 0x4) => vlan.pcp == 0x4
228 !(vlan.pcp == 0x4) => vlan.pcp != 0x4
229 !(vlan.pcp <= 0x4) => vlan.pcp > 0x4
230 !(vlan.pcp < 0x4) => vlan.pcp >= 0x4
231 !(vlan.pcp >= 0x4) => vlan.pcp < 0x4
232 !(vlan.pcp > 0x4) => vlan.pcp <= 0x4
233 0x4 == vlan.pcp => vlan.pcp == 0x4
234 0x4 != vlan.pcp => vlan.pcp != 0x4
235 0x4 < vlan.pcp => vlan.pcp > 0x4
236 0x4 <= vlan.pcp => vlan.pcp >= 0x4
237 0x4 > vlan.pcp => vlan.pcp < 0x4
238 0x4 >= vlan.pcp => vlan.pcp <= 0x4
239 !(0x4 != vlan.pcp) => vlan.pcp == 0x4
240 !(0x4 == vlan.pcp) => vlan.pcp != 0x4
241 !(0x4 >= vlan.pcp) => vlan.pcp > 0x4
242 !(0x4 > vlan.pcp) => vlan.pcp >= 0x4
243 !(0x4 <= vlan.pcp) => vlan.pcp < 0x4
244 !(0x4 < vlan.pcp) => vlan.pcp <= 0x4
246 1 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
247 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
248 1 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
249 1 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
250 1 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
251 4 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
252 4 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
253 4 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
254 4 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
255 !(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
256 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
257 !(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
258 !(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
259 !(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
260 !(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
261 !(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
262 !(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
263 !(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
265 vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
266 vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
268 vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
269 vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
271 vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
272 vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
273 vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
275 ip4.src == {10.0.0.0/8, 192.168.0.0/16, 172.16.20.0/24, 8.8.8.8} => ip4.src[24..31] == 0xa || ip4.src[16..31] == 0xc0a8 || ip4.src[8..31] == 0xac1014 || ip4.src == 0x8080808
276 ip6.src == ::1 => ip6.src == 0x1
278 ip4.src == 1.2.3.4 => ip4.src == 0x1020304
279 ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
280 ip6.src == ::1 => ip6.src == 0x1
288 !(inport != "eth0") => inport == "eth0"
290 ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
291 inport == 1 => String field inport is not compatible with integer constant.
292 ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
294 ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
295 eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
296 vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
298 inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
299 !(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
300 eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
301 !(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
302 inport = "eth0" => Syntax error at `=' expecting relational operator.
304 123 == 123 => Syntax error at `123' expecting field name.
306 $name => Syntax error at `$name' expecting address set name.
308 123 == xyzzy => Syntax error at `xyzzy' expecting field name.
309 xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311 inport[1] == 1 => Cannot select subfield of string field inport.
313 eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
314 eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
315 eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317 eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319 eth.type[5..1] => Invalid bit range 5 to 1.
321 eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323 eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325 eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327 !(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329 123 => Syntax error at end of input expecting relational operator.
331 123 x => Syntax error at `x' expecting relational operator.
333 {1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335 eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337 (1 x) => Syntax error at `x' expecting `)'.
339 !0x800 != eth.type => Missing parentheses around operand of !.
341 eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343 eth.dst == {} => Syntax error at `}' expecting constant.
345 eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff => Only == and != operators may be used with masked constants. Consider using subfields instead (e.g. eth.src[0..15] > 0x1111 in place of eth.src > 00:00:00:00:11:11/00:00:00:00:ff:ff).
347 ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
349 1 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
351 eth.dst[40] x => Syntax error at `x' expecting end of input.
353 ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
354 eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
356 sed 's/ =>.*//' test-cases.txt > input.txt
357 sed 's/.* => //' test-cases.txt > expout
358 AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
361 AT_SETUP([ovn -- expression annotation])
362 dnl Input precedes =>, expected output follows =>.
363 AT_DATA([test-cases.txt], [[
364 ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
365 ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
366 ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
367 ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
368 ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
370 ip => eth.type == 0x800 || eth.type == 0x86dd
371 ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
372 ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
373 ip > 0 => Only == and != operators may be used with nominal field ip.
374 !ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
375 ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
377 vlan.present => vlan.tci[12]
378 !vlan.present => !vlan.tci[12]
380 !vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
381 vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
382 !reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
384 ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
385 !ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
386 ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
388 bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
389 self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
390 mutual_recurse_1 != 0 => Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_1'.
391 mutual_recurse_2 != 0 => Error parsing expression `mutual_recurse_1 != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `mutual_recurse_2 != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `mutual_recurse_2'.
393 sed 's/ =>.*//' test-cases.txt > input.txt
394 sed 's/.* => //' test-cases.txt > expout
395 AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
398 AT_SETUP([ovn -- 1-term expression conversion])
399 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
400 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
404 AT_SETUP([ovn -- 2-term expression conversion])
405 AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
406 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
410 AT_SETUP([ovn -- 3-term expression conversion])
411 AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
412 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
416 AT_SETUP([ovn -- 3-term numeric expression simplification])
417 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
418 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
422 AT_SETUP([ovn -- 4-term string expression simplification])
423 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
424 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
428 AT_SETUP([ovn -- 3-term mixed expression simplification])
429 AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
430 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
434 AT_SETUP([ovn -- simplification special cases])
436 echo "$1" | ovstest test-ovn simplify-expr
438 AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
440 AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
442 AT_CHECK([simplify 'tcp.dst >= 0'], [0],
443 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
445 AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
446 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
448 AT_CHECK([simplify 'tcp.dst > 0'], [0],
449 [[(tcp.dst[0] || tcp.dst[1] || tcp.dst[2] || tcp.dst[3] || tcp.dst[4] || tcp.dst[5] || tcp.dst[6] || tcp.dst[7] || tcp.dst[8] || tcp.dst[9] || tcp.dst[10] || tcp.dst[11] || tcp.dst[12] || tcp.dst[13] || tcp.dst[14] || tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
451 AT_CHECK([simplify 'tcp.dst < 65535'], [0],
452 [[(!tcp.dst[0] || !tcp.dst[1] || !tcp.dst[2] || !tcp.dst[3] || !tcp.dst[4] || !tcp.dst[5] || !tcp.dst[6] || !tcp.dst[7] || !tcp.dst[8] || !tcp.dst[9] || !tcp.dst[10] || !tcp.dst[11] || !tcp.dst[12] || !tcp.dst[13] || !tcp.dst[14] || !tcp.dst[15]) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
456 AT_SETUP([ovn -- is_chassis_resident simplification])
458 echo "$1" | ovstest test-ovn simplify-expr
460 AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
462 AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
464 AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
466 AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
470 AT_SETUP([ovn -- 4-term numeric expression normalization])
471 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
472 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
476 AT_SETUP([ovn -- 4-term string expression normalization])
477 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
478 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
482 AT_SETUP([ovn -- 4-term mixed expression normalization])
483 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
484 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
488 AT_SETUP([ovn -- 5-term numeric expression normalization])
489 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
490 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
494 AT_SETUP([ovn -- 5-term string expression normalization])
495 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
496 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
500 AT_SETUP([ovn -- 5-term mixed expression normalization])
501 AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
506 AT_SETUP([ovn -- 4-term numeric expressions to flows])
507 AT_KEYWORDS([expression])
508 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
509 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
513 AT_SETUP([ovn -- 4-term string expressions to flows])
514 AT_KEYWORDS([expression])
515 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
516 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
520 AT_SETUP([ovn -- 4-term mixed expressions to flows])
521 AT_KEYWORDS([expression])
522 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
523 [Tested converting to flows 48312 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
527 AT_SETUP([ovn -- 3-term numeric expressions to flows])
528 AT_KEYWORDS([expression])
529 AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
530 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
534 AT_SETUP([ovn -- converting expressions to flows -- string fields])
535 AT_KEYWORDS([expression])
537 echo "$1" | ovstest test-ovn expr-to-flows | sort
539 AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
541 AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
543 AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
545 AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
549 AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
553 AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
555 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
560 AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
566 AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
571 AT_SETUP([ovn -- converting expressions to flows -- address sets])
572 AT_KEYWORDS([expression])
574 echo "$1" | ovstest test-ovn expr-to-flows | sort
576 AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
581 AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
586 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
592 AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599 AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
604 AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
610 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, 00:00:00:00:00:02, 00:00:00:00:00:03}'], [0], [dnl
611 dl_src=00:00:00:00:00:01
612 dl_src=00:00:00:00:00:02
613 dl_src=00:00:00:00:00:03
615 AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
616 dl_src=00:00:00:00:00:01
617 dl_src=00:00:00:00:00:02
618 dl_src=00:00:00:00:00:03
620 AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
621 dl_src=00:00:00:00:00:01
622 dl_src=00:00:00:00:00:02
623 dl_src=00:00:00:00:00:03
624 dl_src=ba:be:be:ef:de:ad
626 AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
629 AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
632 AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
635 AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
638 AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
639 ip,nw_src=0.0.0.0/1.0.0.0
640 ip,nw_src=128.0.0.0/1
641 ip,nw_src=16.0.0.0/16.0.0.0
642 ip,nw_src=2.0.0.0/2.0.0.0
643 ip,nw_src=32.0.0.0/32.0.0.0
644 ip,nw_src=4.0.0.0/4.0.0.0
645 ip,nw_src=64.0.0.0/64.0.0.0
646 ip,nw_src=8.0.0.0/8.0.0.0
648 AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
649 ip,nw_src=0.0.0.0/1.0.0.0
650 ip,nw_src=128.0.0.0/1
651 ip,nw_src=16.0.0.0/16.0.0.0
652 ip,nw_src=2.0.0.0/2.0.0.0
653 ip,nw_src=32.0.0.0/32.0.0.0
654 ip,nw_src=4.0.0.0/4.0.0.0
655 ip,nw_src=64.0.0.0/64.0.0.0
656 ip,nw_src=8.0.0.0/8.0.0.0
660 AT_SETUP([ovn -- action parsing])
661 dnl Unindented text is input (a set of OVN logical actions).
662 dnl Indented text is expected output.
663 AT_DATA([test-cases.txt],
668 Syntax error at `next' expecting end of input.
670 Syntax error at `drop' expecting action.
674 encodes as resubmit(,64)
678 encodes as resubmit(,19)
681 encodes as resubmit(,19)
683 encodes as resubmit(,8)
685 encodes as resubmit(,31)
688 Syntax error at `)' expecting "pipeline" or "table".
690 Syntax error at `;' expecting `)'.
692 "next" action cannot advance beyond table 23.
696 encodes as resubmit(,19)
697 next(pipeline=ingress);
699 encodes as resubmit(,19)
700 next(table=11, pipeline=ingress);
702 encodes as resubmit(,19)
703 next(pipeline=ingress, table=11);
705 encodes as resubmit(,19)
707 next(pipeline=egress);
708 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
712 encodes as resubmit(,18)
714 # Loading a constant value.
716 formats as tcp.dst = 80;
717 encodes as set_field:80->tcp_dst
718 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
720 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
722 encodes as set_field:0x4000/0xe000->vlan_tci
723 has prereqs vlan.tci[12]
724 vlan.tci[13..15] = 2;
725 encodes as set_field:0x4000/0xe000->vlan_tci
727 encodes as set_field:0->reg14
729 formats as ip.ttl = 4;
730 encodes as set_field:4->nw_ttl
731 has prereqs eth.type == 0x800 || eth.type == 0x86dd
732 outport="eth0"; next; outport="LOCAL"; next;
733 formats as outport = "eth0"; next; outport = "LOCAL"; next;
734 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
737 Cannot select subfield of string field inport.
739 Cannot select subfield of nominal field ip.proto.
741 Syntax error at `==' expecting `=' or `<->'.
743 Predicate symbol ip used where lvalue required.
745 Field ip.proto is not modifiable.
747 Syntax error at `{' expecting constant.
749 Syntax error at `{' expecting constant.
751 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
753 Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
755 Predicate symbol vlan.present used where lvalue required.
757 # Moving one field into another.
759 formats as reg0 = reg1;
760 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
761 vlan.pcp = reg0[0..2];
762 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
763 has prereqs vlan.tci[12]
764 reg0[10] = vlan.pcp[1];
765 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
766 has prereqs vlan.tci[12]
768 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
770 reg0[0] = vlan.present;
771 Predicate symbol vlan.present used where lvalue required.
773 Can't assign 11-bit value to 32-bit destination.
775 Can't assign integer field (reg0) to string field (inport).
777 String fields inport and big_string are incompatible for assignment.
778 ip.proto = reg0[0..7];
779 Field ip.proto is not modifiable.
783 encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
784 vlan.pcp <-> reg0[0..2];
785 encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
786 has prereqs vlan.tci[12]
787 reg0[10] <-> vlan.pcp[1];
788 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
789 has prereqs vlan.tci[12]
791 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
793 reg0[0] <-> vlan.present;
794 Predicate symbol vlan.present used where lvalue required.
795 reg0 <-> reg1[0..10];
796 Can't exchange 32-bit field with 11-bit field.
798 Can't exchange string field (inport) with integer field (reg0).
799 inport <-> big_string;
800 String fields inport and big_string are incompatible for exchange.
801 ip.proto <-> reg0[0..7];
802 Field ip.proto is not modifiable.
803 reg0[0..7] <-> ip.proto;
804 Field ip.proto is not modifiable.
811 Syntax error at end of input expecting `--'.
815 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
819 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
821 ct_lb(192.168.1.2:80, 192.168.1.3:80);
824 ct_lb(192.168.1.2, 192.168.1.3, );
825 formats as ct_lb(192.168.1.2, 192.168.1.3);
828 ct_lb(fd0f::2, fd0f::3, );
829 formats as ct_lb(fd0f::2, fd0f::3);
834 Syntax error at `)' expecting port number.
835 ct_lb(192.168.1.2:123456);
836 Syntax error at `123456' expecting port number.
838 Syntax error at `foo' expecting IP address.
839 ct_lb([192.168.1.2]);
840 Syntax error at `192.168.1.2' expecting IPv6 address.
844 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
849 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
852 formats as ct_commit;
853 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
855 ct_commit(ct_mark=1);
856 formats as ct_commit(ct_mark=0x1);
857 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
859 ct_commit(ct_mark=1/1);
860 formats as ct_commit(ct_mark=0x1/0x1);
861 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
863 ct_commit(ct_label=1);
864 formats as ct_commit(ct_label=0x1);
865 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
867 ct_commit(ct_label=1/1);
868 formats as ct_commit(ct_label=0x1/0x1);
869 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
871 ct_commit(ct_mark=1, ct_label=2);
872 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
873 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
876 ct_commit(ct_label=0x01020304050607080910111213141516);
877 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
878 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
880 ct_commit(ct_label=0x181716151413121110090807060504030201);
881 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
882 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
884 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
885 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
887 ct_commit(ct_label=18446744073709551615);
888 formats as ct_commit(ct_label=0xffffffffffffffff);
889 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
891 ct_commit(ct_label=18446744073709551616);
892 Decimal constants must be less than 2**64.
896 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
898 ct_dnat(192.168.1.2);
899 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
902 ct_dnat(192.168.1.2, 192.168.1.3);
903 Syntax error at `,' expecting `)'.
905 Syntax error at `foo' expecting IPv4 address.
907 Syntax error at `foo' expecting IPv4 address.
909 Syntax error at `)' expecting IPv4 address.
913 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
915 ct_snat(192.168.1.2);
916 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
919 ct_snat(192.168.1.2, 192.168.1.3);
920 Syntax error at `,' expecting `)'.
922 Syntax error at `foo' expecting IPv4 address.
924 Syntax error at `foo' expecting IPv4 address.
926 Syntax error at `)' expecting IPv4 address.
933 clone { ip4.dst = 255.255.255.255; output; }; next;
934 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
935 has prereqs eth.type == 0x800
938 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
939 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00),resubmit(,64)
942 formats as arp { drop; };
943 encodes as controller(userdata=00.00.00.00.00.00.00.00)
947 get_arp(outport, ip4.dst);
948 encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
949 has prereqs eth.type == 0x800
950 get_arp(inport, reg0);
951 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
954 Syntax error at `;' expecting `('.
956 Syntax error at `)' expecting field name.
958 Syntax error at `)' expecting `,'.
959 get_arp(inport ip4.dst);
960 Syntax error at `ip4.dst' expecting `,'.
961 get_arp(inport, ip4.dst;
962 Syntax error at `;' expecting `)'.
963 get_arp(inport, eth.dst);
964 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
965 get_arp(inport, outport);
966 Cannot use string field outport where numeric field is required.
967 get_arp(reg0, ip4.dst);
968 Cannot use numeric field reg0 where string field is required.
971 put_arp(inport, arp.spa, arp.sha);
972 encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
973 has prereqs eth.type == 0x806 && eth.type == 0x806
976 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
977 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
978 reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
979 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org");
980 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67,pause)
981 reg0[15] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.255.0,mtu=1400,ip_forward_enable=1,default_ttl=121,dns_server={8.8.8.8,7.7.7.7},classless_static_route={30.0.0.0/24,10.0.0.4,40.0.0.0/16,10.0.0.6,0.0.0.0/0,10.0.0.1},ethernet_encap=1,router_discovery=0);
982 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0);
983 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
985 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
986 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
987 reg1[0] = put_dhcp_opts();
988 put_dhcp_opts requires offerip to be specified.
989 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
990 Syntax error at `x' expecting DHCPv4 option name.
991 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
992 put_dhcp_opts requires offerip to be specified.
993 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
994 Syntax error at `"hi"'.
995 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
996 Syntax error at `xyzzy' expecting DHCPv4 option name.
997 reg1[0] = put_dhcp_opts(offerip="xyzzy");
998 DHCPv4 option offerip requires numeric value.
999 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1000 DHCPv4 option domain requires string value.
1003 nd_ns { nd.target = xxreg0; output; };
1004 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1008 formats as nd_ns { drop; };
1009 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1013 nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1014 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1015 encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1019 get_nd(outport, ip6.dst);
1020 encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
1021 has prereqs eth.type == 0x86dd
1022 get_nd(inport, xxreg0);
1023 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
1025 Syntax error at `;' expecting `('.
1027 Syntax error at `)' expecting field name.
1029 Syntax error at `)' expecting `,'.
1030 get_nd(inport ip6.dst);
1031 Syntax error at `ip6.dst' expecting `,'.
1032 get_nd(inport, ip6.dst;
1033 Syntax error at `;' expecting `)'.
1034 get_nd(inport, eth.dst);
1035 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1036 get_nd(inport, outport);
1037 Cannot use string field outport where numeric field is required.
1038 get_nd(xxreg0, ip6.dst);
1039 Cannot use numeric field xxreg0 where string field is required.
1042 put_nd(inport, nd.target, nd.sll);
1043 encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
1044 has prereqs ((icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd)) || (icmp6.type == 0x88 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd))) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
1047 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1048 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.05.00.10.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.00.02.00.06.00.00.00.00.10.02,pause)
1049 reg1[0] = put_dhcpv6_opts();
1050 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1051 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1052 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1053 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
1054 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1055 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1056 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.02.00.06.12.34.56.78.9a.bc.00.17.00.20.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
1057 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1058 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.00.18.00.07.6f.76.6e.2e.6f.72.67,pause)
1059 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1060 Syntax error at `x' expecting DHCPv6 option name.
1061 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1062 Syntax error at `"hi"'.
1063 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1064 Syntax error at `xyzzy' expecting DHCPv6 option name.
1065 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1066 DHCPv6 option ia_addr requires numeric value.
1067 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1068 DHCPv6 option domain_search requires string value.
1072 encodes as set_queue:0
1074 encodes as set_queue:61440
1076 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1079 reg1[0] = dns_lookup();
1080 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1082 reg1[0] = dns_lookup("foo");
1083 dns_lookup doesn't take any parameters
1086 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1087 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)
1089 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1090 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)
1092 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1093 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)
1095 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1096 slla option not present
1097 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);
1098 prefix option can't be set when address mode is dhcpv6_stateful.
1099 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);
1100 prefix option can't be set when address mode is dhcpv6_stateful.
1101 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1102 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1103 reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1104 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1105 reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1106 Syntax error at `dhcpv6_stateless' expecting constant.
1107 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1108 Invalid value for "prefix" option
1109 reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1110 Invalid value for "addr_mode" option
1111 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1112 IPv6 ND RA option mtu requires numeric value.
1113 reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1114 Invalid value for "mtu" option
1116 # Contradictionary prerequisites (allowed but not useful):
1117 ip4.src = ip6.src[0..31];
1118 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1119 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1120 ip4.src <-> ip6.src[0..31];
1121 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[]
1122 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1124 # Miscellaneous negative tests.
1126 Syntax error at `;'.
1128 Syntax error at `xyzzy' expecting action.
1130 Syntax error at `123'.
1132 Syntax error at `xyzzy' expecting action.
1134 Syntax error at end of input expecting `;'.
1136 sed '/^[[ ]]/d' test-cases.txt > input.txt
1137 cp test-cases.txt expout
1138 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1141 AT_BANNER([OVN end-to-end tests])
1143 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1144 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1145 AT_KEYWORDS([ovnarp])
1146 AT_SKIP_IF([test $HAVE_PYTHON = no])
1149 # Create hypervisors hv[123].
1150 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1151 # Add all of the vifs to a single logical switch lsw0.
1152 # Turn on port security on all the vifs except vif[123]1.
1153 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1154 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1155 ovn-nbctl ls-add lsw0
1160 ovs-vsctl add-br br-phys
1161 ovn_attach n1 br-phys 192.168.0.$i
1164 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
1165 ovn-nbctl lsp-add lsw0 lp$i$j
1166 if test $j = 1; then
1167 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1169 if test $j = 3; then
1170 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1172 ip_addrs="192.168.0.$i$j"
1174 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1175 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1179 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1180 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1181 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1182 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\"
1183 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1185 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1186 # packets for ARP resolution (native tunneling doesn't queue packets
1187 # for ARP resolution).
1190 # Allow some time for ovn-northd and ovn-controller to catch up.
1191 # XXX This should be more systematic.
1194 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1195 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1196 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1197 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1199 # Given the name of a logical port, prints the name of the hypervisor
1200 # on which it is located.
1205 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1207 # This shell function causes a packet to be received on INPORT. The packet's
1208 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1209 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1210 # more) list the VIFs on which the packet should be received. INPORT and the
1211 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1218 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1219 hv=`vif_to_hv $inport`
1221 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1223 echo $packet >> $outport.expected
1227 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1229 # Causes a packet to be received on INPORT. The packet is an ARP
1230 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1231 # it should be the hardware address of the target to expect to receive in an
1232 # ARP reply; otherwise no reply is expected.
1234 # INPORT is an logical switch port number, e.g. 11 for vif11.
1235 # SHA and REPLY_HA are each 12 hex digits.
1236 # SPA and TPA are each 8 hex digits.
1238 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1239 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1240 hv=`vif_to_hv $inport`
1241 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1243 if test X$reply_ha = X; then
1244 # Expect to receive the broadcast ARP on the other logical switch ports
1245 # if no reply is expected.
1249 if test $i$j != $inport; then
1250 echo $request >> $i$j.expected
1255 # Expect to receive the reply, if any.
1256 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1257 echo $reply >> $inport.expected
1262 printf "%02x%02x%02x%02x" "$@"
1265 # Send packets between all pairs of source and destination ports:
1267 # 1. Unicast packets are delivered to exactly one logical switch port
1268 # (except that packets destined to their input ports are dropped).
1270 # 2. Broadcast and multicast are delivered to all logical switch ports
1271 # except the input port.
1273 # 3. When port security is turned on, the switch drops packets from the wrong
1276 # 4. The switch drops all packets with a VLAN tag.
1278 # 5. The switch drops all packets with a multicast source address. (This only
1279 # affects behavior when port security is turned off, since otherwise port
1280 # security would drop the packet anyway.)
1282 # 6. The switch delivers packets with an unknown destination to logical
1283 # switch ports with "unknown" among their MAC addresses (and port
1284 # security disabled).
1286 # 7. The switch drops unicast packets that violate an ACL.
1288 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1290 # 9. OVN generates responses to ARP requests for known IPs, except for
1291 # requests from a port for the port's own IP.
1293 # 10. No response to ARP requests for unknown IPs.
1306 if test $d != $s; then unicast=$d; else unicast=; fi
1307 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1309 if test $d != $s && test $js = 1; then
1314 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1316 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1317 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1318 if test $d = $s || (test $js = 1 && test $d = 33); then
1319 # Source of 11, 21, or 31 and dest of 33 should be dropped
1320 # due to the 4th ACL that uses address_set(set1).
1325 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1326 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1327 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1328 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1330 test_packet $s f000000000$d f00000000055 810000091234 #4
1331 test_packet $s f000000000$d 0100000000$s $s$d #5
1333 if test $d != $s && test $jd = 1; then
1334 unknown="$unknown $d"
1336 bcast="$bcast $unicast"
1337 bacl2="$bacl2 $acl2"
1338 bacl3="$bacl3 $acl3"
1340 sip=`ip_to_hex 192 168 0 $i$j`
1341 tip=`ip_to_hex 192 168 0 $id$jd`
1342 tip_unknown=`ip_to_hex 11 11 11 11`
1343 if test $d != $s; then
1344 reply_ha=f000000000$d
1348 test_arp $s f000000000$s $sip $tip $reply_ha #9
1349 test_arp $s f000000000$s $sip $tip_unknown #10
1351 if test $jd = 3; then
1352 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1353 tip=`ip_to_hex 192 169 0 $id$jd`
1354 test_arp $s f000000000$s $sip $tip $reply_ha #9
1359 # Broadcast and multicast.
1360 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1361 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1362 if test $js = 1; then
1363 bcast_impersonate=$bcast
1367 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1369 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1371 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1372 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1373 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1374 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1375 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1376 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1380 # set address for lp13 with invalid characters.
1381 # lp13 should be configured with only 192.168.0.13.
1382 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1384 # Allow some time for ovn-northd and ovn-controller to catch up.
1385 # XXX This should be more systematic.
1388 sip=`ip_to_hex 192 168 0 11`
1389 tip=`ip_to_hex 192 168 0 13`
1390 test_arp 11 f00000000011 $sip $tip f00000000013
1392 tip=`ip_to_hex 192 169 0 13`
1393 #arp request for 192.169.0.13 should be flooded
1394 test_arp 11 f00000000011 $sip $tip
1396 # dump information and flows with counters
1397 ovn-sbctl dump-flows -- list multicast_group
1399 echo "------ hv1 dump ------"
1400 as hv1 ovs-vsctl show
1401 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1403 echo "------ hv2 dump ------"
1404 as hv2 ovs-vsctl show
1405 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1407 echo "------ hv3 dump ------"
1408 as hv3 ovs-vsctl show
1409 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1411 # Now check the packets actually received against the ones expected.
1414 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1418 OVN_CLEANUP([hv1],[hv2],[hv3])
1422 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1423 AT_SKIP_IF([test $HAVE_PYTHON = no])
1426 # Create a logical switch and some logical ports.
1427 # Turn on port security on all lports except ls1.
1428 # Make ls1 a destination for unknown MACs.
1429 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1430 ovn-nbctl ls-add lsw0
1431 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1433 ovn-nbctl lsp-add lsw0 lp$i
1435 ovn-nbctl --wait=sb sync
1437 ovn-sbctl lsp-bind lp$i hv0
1438 if test $i = 1; then
1439 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1441 if test $i = 3; then
1442 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1444 ip_addrs="192.168.0.$i"
1446 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1447 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
1450 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1451 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1452 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1453 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1454 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1456 ovn-nbctl --wait=sb sync
1457 on_exit 'kill `cat ovn-trace.pid`'
1458 ovn-trace --detach --pidfile --no-chdir
1460 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1462 # This shell function causes a packet to be received on INPORT. The packet's
1463 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1464 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1465 # more) list the VIFs on which the packet should be received. INPORT and the
1466 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1468 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1469 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1472 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1473 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1478 echo "output(\"lp$outport\");"
1481 AT_CAPTURE_FILE([trace])
1482 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1485 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1487 # Causes a packet to be received on INPORT. The packet is an ARP
1488 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1489 # it should be the hardware address of the target to expect to receive in an
1490 # ARP reply; otherwise no reply is expected.
1492 # INPORT is an logical switch port number, e.g. 11 for vif11.
1493 # SHA and REPLY_HA are each 12 hex digits.
1494 # SPA and TPA are each 8 hex digits.
1496 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1498 local request="inport == \"lp$inport\"
1499 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1500 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1501 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1503 if test -z "$reply_ha"; then
1507 if test $i != $inport; then
1508 reply="${reply}output(\"lp$i\");
1515 eth.src = $reply_ha;
1518 arp.sha = $reply_ha;
1521 output(\"lp$inport\");
1525 AT_CAPTURE_FILE([trace])
1526 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1529 # Send packets between all pairs of source and destination ports:
1531 # 1. Unicast packets are delivered to exactly one logical switch port
1532 # (except that packets destined to their input ports are dropped).
1534 # 2. Broadcast and multicast are delivered to all logical switch ports
1535 # except the input port.
1537 # 3. When port security is turned on, the switch drops packets from the wrong
1540 # 4. The switch drops all packets with a VLAN tag.
1542 # 5. The switch drops all packets with a multicast source address. (This only
1543 # affects behavior when port security is turned off, since otherwise port
1544 # security would drop the packet anyway.)
1546 # 6. The switch delivers packets with an unknown destination to logical
1547 # switch ports with "unknown" among their MAC addresses (and port
1548 # security disabled).
1550 # 7. The switch drops unicast packets that violate an ACL.
1552 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1554 # 9. OVN generates responses to ARP requests for known IPs, except for
1555 # requests from a port for the port's own IP.
1557 # 10. No response to ARP requests for unknown IPs.
1567 if test $d != $s; then unicast=$d; else unicast=; fi
1568 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1570 if test $d != $s && test $s = 1; then
1575 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1577 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1578 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1579 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1580 # Source of 1 or 2 and dest of 3 should be dropped
1581 # due to the 4th ACL that uses address_set(set1).
1588 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1589 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1590 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1591 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1593 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1594 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1596 if test $d != $s && test $d = 1; then
1597 unknown="$unknown $d"
1599 bcast="$bcast $unicast"
1600 bacl2="$bacl2 $acl2"
1601 bacl3="$bacl3 $acl3"
1605 tip_unknown=11.11.11.11
1606 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1607 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1608 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1610 if test $d = 3; then
1611 # lp3 has an additional ip 192.169.0.[123]3.
1613 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1617 # Broadcast and multicast.
1618 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1619 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1620 if test $s = 1; then
1621 bcast_impersonate=$bcast
1625 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1627 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1630 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1631 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1632 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1635 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1636 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1637 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1642 # 2 hypervisors, 4 logical ports per HV
1643 # 2 locally attached networks (one flat, one vlan tagged over same device)
1644 # 2 ports per HV on each network
1645 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1646 AT_SKIP_IF([test $HAVE_PYTHON = no])
1649 # In this test cases we create 3 switches, all connected to same
1650 # physical network (through br-phys on each HV). Each switch has
1651 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1652 # of VIF port name indicates the hypervisor it is bound to, e.g.
1653 # lp23 means VIF 3 on hv2.
1655 # Each switch's VLAN tag and their logical switch ports are:
1658 # - ports: lp11, lp12, lp21, lp22
1661 # - tagged with VLAN 101
1662 # - ports: lp13, lp14, lp23, lp24
1665 # - ports: lp15, lp25
1667 # Note: a localnet port is created for each switch to connect to
1672 ovn-nbctl ls-add $ls_name
1674 if test $i -eq 2; then
1675 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1677 ovn-nbctl lsp-add $ls_name $ln_port_name
1679 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1680 ovn-nbctl lsp-set-type $ln_port_name localnet
1681 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1686 # Prints the name of the logical switch that contains LSP.
1689 lp?[[12]]) echo ls1 ;; dnl (
1690 lp?[[34]]) echo ls2 ;; dnl (
1691 lp?5) echo ls3 ;; dnl (
1692 *) AT_FAIL_IF([:]) ;;
1700 ovs-vsctl add-br br-phys
1701 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1702 ovn_attach n1 br-phys 192.168.0.$i
1704 for j in 1 2 3 4 5; do
1705 ovs-vsctl add-port br-int vif$i$j -- \
1706 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1707 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1708 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1712 ls_name=$(lsp_to_ls $lsp_name)
1714 ovn-nbctl lsp-add $ls_name $lsp_name
1715 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1716 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1718 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1721 ovn-nbctl --wait=sb sync
1722 ovn-sbctl dump-flows
1726 # XXX This is now the 3rd copy of these functions in this file ...
1728 # Given the name of a logical port, prints the name of the hypervisor
1729 # on which it is located.
1734 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1736 # This shell function causes a packet to be received on INPORT. The packet's
1737 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1738 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1739 # logical switch port numbers, e.g. 11 for vif11.
1741 # EOUT is the end-to-end output port, that is, where the packet will end up
1742 # after possibly bouncing through one or more localnet ports. LOUT is the
1743 # logical output port, which might be a localnet port, as seen by ovn-trace
1744 # (which doesn't know what localnet ports are connected to and therefore can't
1745 # figure out the end-to-end answer).
1747 for j in 1 2 3 4 5; do
1752 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1755 # First try tracing the packet.
1756 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1757 if test $lout != drop; then
1758 echo "output(\"$lout\");"
1760 AT_CAPTURE_FILE([trace])
1761 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1763 # Then actually send a packet, for an end-to-end test.
1764 local packet=$(echo $dst$src | sed 's/://g')${eth}
1765 hv=`vif_to_hv $inport`
1767 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1768 if test $eout != drop; then
1769 echo $packet >> ${eout#lp}.expected
1773 # lp11 and lp21 are on the same network (phys, untagged)
1774 # and on different hypervisors
1775 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1776 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1778 # lp11 and lp12 are on the same network (phys, untagged)
1779 # and on the same hypervisor
1780 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1781 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1783 # lp13 and lp23 are on the same network (phys, VLAN 101)
1784 # and on different hypervisors
1785 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1786 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1788 # lp13 and lp14 are on the same network (phys, VLAN 101)
1789 # and on the same hypervisor
1790 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1791 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1793 # lp11 and lp15 are on the same network (phys, untagged),
1794 # same hypervisor, and on different switches
1795 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1796 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1798 # lp11 and lp25 are on the same network (phys, untagged),
1799 # different hypervisors, and on different switches
1800 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1801 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1803 # Ports that should not be able to communicate
1804 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1805 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1806 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1807 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1808 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1809 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1810 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1811 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1813 # Dump a bunch of info helpful for debugging if there's a failure.
1815 echo "------ OVN dump ------"
1819 echo "------ hv1 dump ------"
1820 as hv1 ovs-vsctl show
1821 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1823 echo "------ hv2 dump ------"
1824 as hv2 ovs-vsctl show
1825 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1827 # Now check the packets actually received against the ones expected.
1829 for j in 1 2 3 4 5; do
1830 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1834 OVN_CLEANUP([hv1],[hv2])
1838 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1840 AT_SKIP_IF([test $HAVE_PYTHON = no])
1843 # Configure the Northbound database
1844 ovn-nbctl ls-add lsw0
1846 ovn-nbctl lsp-add lsw0 lp1
1847 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1849 ovn-nbctl lsp-add lsw0 lp2
1850 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1852 ovn-nbctl lsp-add lsw0 lp-vtep
1853 ovn-nbctl lsp-set-type lp-vtep vtep
1854 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1855 ovn-nbctl lsp-set-addresses lp-vtep unknown
1857 # lpr, lr and lrp1 are used for the ARP request handling test only.
1858 ovn-nbctl lsp-add lsw0 lpr
1860 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1861 ovn-nbctl set Logical_Switch_Port lpr type=router \
1862 options:router-port=lrp1 \
1863 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1866 net_add n1 # Network to connect hv1, hv2, and vtep
1867 net_add n2 # Network to connect vtep and hv3
1869 # Create hypervisor hv1 connected to n1
1872 ovs-vsctl add-br br-phys
1873 ovn_attach n1 br-phys 192.168.0.1
1874 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
1876 # Create hypervisor hv2 connected to n1
1879 ovs-vsctl add-br br-phys
1880 ovn_attach n1 br-phys 192.168.0.2
1881 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
1884 # Start the vtep emulator with a leg in both networks
1888 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1889 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1891 ovs-vsctl add-br br-phys
1892 net_attach n1 br-phys
1894 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1895 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1896 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1897 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1899 ovs-vsctl add-br br-vtep
1900 net_attach n2 br-vtep
1902 vtep-ctl add-ps br-vtep
1903 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1904 vtep-ctl add-ls lsw0
1906 start_daemon ovs-vtep br-vtep
1907 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1909 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1911 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1913 # It takes more time for the update to be processed by ovs-vtep.
1916 # Add hv3 on the other side of the vtep
1919 ovs-vsctl add-br br-phys
1920 net_attach n2 br-phys
1922 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
1924 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1925 # packets for ARP resolution (native tunneling doesn't queue packets
1926 # for ARP resolution).
1929 # Allow some time for ovn-northd and ovn-controller to catch up.
1930 # XXX This should be more systematic.
1933 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1935 # This shell function causes a packet to be received on INPORT. The packet's
1936 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1937 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1938 # more) list the VIFs on which the packet should be received. INPORT and the
1939 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
1944 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1945 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1948 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1950 echo $packet >> $outport.expected
1954 # Send packets between all pairs of source and destination ports:
1956 # 1. Unicast packets are delivered to exactly one logical switch port
1957 # (except that packets destined to their input ports are dropped).
1959 # 2. Broadcast and multicast are delivered to all logical switch ports
1960 # except the input port.
1962 # 3. The switch delivers packets with an unknown destination to logical
1963 # switch ports with "unknown" among their MAC addresses (and port
1964 # security disabled).
1969 if test $d != $s; then unicast=$d; else unicast=; fi
1970 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1972 # The vtep (vif3) is the only one configured for "unknown"
1973 if test $d != $s && test $d = 3; then
1974 unknown="$unknown $d"
1976 bcast="$bcast $unicast"
1979 # Broadcast and multicast.
1980 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1981 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
1983 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1986 # ARP request should not be responded to by logical switch router
1987 # type arp responder on HV1 and HV2 and should reach directly to
1990 printf "%02x%02x%02x%02x" "$@"
1993 spa=`ip_to_hex 192 168 1 2`
1994 tpa=`ip_to_hex 192 168 1 1`
1995 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1996 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1997 echo $request >> 1.expected
1998 echo $request >> 2.expected
2000 # dump information with counters
2001 echo "------ OVN dump ------"
2005 echo "---------SB dump-----"
2006 ovn-sbctl list datapath_binding
2007 echo "---------------------"
2008 ovn-sbctl list port_binding
2009 echo "---------------------"
2010 ovn-sbctl dump-flows
2012 echo "------ hv1 dump ------"
2013 as hv1 ovs-vsctl show
2014 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2015 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2017 echo "------ hv2 dump ------"
2018 as hv2 ovs-vsctl show
2019 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2020 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2022 echo "------ hv3 dump ------"
2023 as hv3 ovs-vsctl show
2024 # note: hv3 has no logical port bind, thus it should not have br-int
2025 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2026 [ovs-ofctl: br-int is not a bridge or a socket
2029 # Now check the packets actually received against the ones expected.
2031 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2034 # Gracefully terminate daemons
2035 OVN_CLEANUP([hv1],[hv2],[vtep])
2036 OVN_CLEANUP_VSWITCH([hv3])
2040 # Similar test to "hardware GW"
2041 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2042 AT_SKIP_IF([test $HAVE_PYTHON = no])
2045 # Configure the Northbound database
2046 ovn-nbctl ls-add lsw0
2048 ovn-nbctl lsp-add lsw0 lp1
2049 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2051 ovn-nbctl lsp-add lsw0 lp2
2052 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2054 ovn-nbctl lsp-add lsw0 lp-gw
2055 ovn-nbctl lsp-set-type lp-gw l2gateway
2056 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2057 ovn-nbctl lsp-set-addresses lp-gw unknown
2059 net_add n1 # Network to connect hv1, hv2, and gw
2060 net_add n2 # Network to connect gw and hv3
2062 # Create hypervisor hv1 connected to n1
2065 ovs-vsctl add-br br-phys
2066 ovn_attach n1 br-phys 192.168.0.1
2067 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
2069 # Create hypervisor hv2 connected to n1
2072 ovs-vsctl add-br br-phys
2073 ovn_attach n1 br-phys 192.168.0.2
2074 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
2076 # Create hypervisor hv_gw connected to n1 and n2
2077 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2080 ovs-vsctl add-br br-phys
2081 ovn_attach n1 br-phys 192.168.0.3
2082 ovs-vsctl add-br br-phys2
2083 net_attach n2 br-phys2
2084 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2086 # Add hv3 on the other side of the GW
2089 ovs-vsctl add-br br-phys
2090 net_attach n2 br-phys
2091 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
2094 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2095 # packets for ARP resolution (native tunneling doesn't queue packets
2096 # for ARP resolution).
2099 # Allow some time for ovn-northd and ovn-controller to catch up.
2100 # XXX This should be more systematic.
2103 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2105 # This shell function causes a packet to be received on INPORT. The packet's
2106 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2107 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2108 # more) list the VIFs on which the packet should be received. INPORT and the
2109 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2114 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2115 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2118 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2120 echo $packet >> $outport.expected
2124 # Send packets between all pairs of source and destination ports:
2126 # 1. Unicast packets are delivered to exactly one lport (except that packets
2127 # destined to their input ports are dropped).
2129 # 2. Broadcast and multicast are delivered to all lports except the input port.
2131 # 3. The lswitch delivers packets with an unknown destination to lports with
2132 # "unknown" among their MAC addresses (and port security disabled).
2137 if test $d != $s; then unicast=$d; else unicast=; fi
2138 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2140 # The vtep (vif3) is the only one configured for "unknown"
2141 if test $d != $s && test $d = 3; then
2142 unknown="$unknown $d"
2144 bcast="$bcast $unicast"
2147 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2148 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2149 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2152 echo "------ ovn-nbctl show ------"
2154 echo "------ ovn-sbctl show ------"
2157 echo "------ hv1 ------"
2158 as hv1 ovs-vsctl show
2159 echo "------ hv1 br-int ------"
2160 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2161 echo "------ hv1 br-phys ------"
2162 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2164 echo "------ hv2 ------"
2165 as hv2 ovs-vsctl show
2166 echo "------ hv2 br-int ------"
2167 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2168 echo "------ hv2 br-phys ------"
2169 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2171 echo "------ hv_gw ------"
2172 as hv_gw ovs-vsctl show
2173 echo "------ hv_gw br-phys ------"
2174 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2175 echo "------ hv_gw br-phys2 ------"
2176 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2178 echo "------ hv3 ------"
2179 as hv3 ovs-vsctl show
2180 echo "------ hv3 br-phys ------"
2181 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2183 # Now check the packets actually received against the ones expected.
2185 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2189 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2190 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2191 AT_SKIP_IF([test $HAVE_PYTHON = no])
2196 # Three logical switches ls1, ls2, ls3.
2197 # One logical router lr0 connected to ls[123],
2198 # with nine subnets, three per logical switch:
2200 # lrp11 on ls1 for subnet 192.168.11.0/24
2201 # lrp12 on ls1 for subnet 192.168.12.0/24
2202 # lrp13 on ls1 for subnet 192.168.13.0/24
2204 # lrp33 on ls3 for subnet 192.168.33.0/24
2206 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2207 # digits are the subnet and the last digit distinguishes the VIF.
2209 ovn-nbctl ls-add ls$i
2212 # Add "unknown" to MAC addresses for lp?11, so packets for
2213 # MAC-IP bindings discovered via ARP later have somewhere to go.
2214 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2217 -- lsp-add ls$i lp$i$j$k \
2218 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2219 192.168.$i$j.$k" $unknown
2224 ovn-nbctl lr-add lr0
2227 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2229 -- lsp-add ls$i lrp$i$j-attachment \
2230 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2231 options:router-port=lrp$i$j \
2232 addresses='"00:00:00:00:ff:'$i$j'"'
2236 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2237 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2241 # Three hypervisors hv[123].
2242 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2243 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2244 # lp?3[123] all on hv3.
2247 # Given the name of a logical port, prints the name of the hypervisor
2248 # on which it is located.
2251 ?11) echo 1 ;; dnl (
2252 ?12 | ?21 | ?22) echo 2 ;; dnl (
2253 ?13 | ?23 | ?3?) echo 3 ;;
2257 # Given the name of a logical port, prints the name of its logical router
2258 # port, e.g. "vif_to_lrp 123" yields 12.
2263 # Given the name of a logical port, prints the name of its logical
2264 # switch, e.g. "vif_to_ls 123" yields 1.
2273 ovs-vsctl add-br br-phys
2274 ovn_attach n1 br-phys 192.168.0.$i
2279 hv=`vif_to_hv $i$j$k`
2280 as hv$hv ovs-vsctl \
2281 -- add-port br-int vif$i$j$k \
2282 -- set Interface vif$i$j$k \
2283 external-ids:iface-id=lp$i$j$k \
2284 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2285 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2286 ofport-request=$i$j$k
2291 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2292 # packets for ARP resolution (native tunneling doesn't queue packets
2293 # for ARP resolution).
2296 # Allow some time for ovn-northd and ovn-controller to catch up.
2297 # XXX This should be more systematic.
2300 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2302 # This shell function causes a packet to be received on INPORT. The packet's
2303 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2304 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2305 # more) list the VIFs on which the packet should be received. INPORT and the
2306 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2315 # This packet has bad checksums but logical L3 routing doesn't check.
2316 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2317 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2318 shift; shift; shift; shift; shift
2319 hv=hv`vif_to_hv $inport`
2320 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2321 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2322 in_ls=`vif_to_ls $inport`
2323 in_lrp=`vif_to_lrp $inport`
2325 out_ls=`vif_to_ls $outport`
2326 if test $in_ls = $out_ls; then
2327 # Ports on the same logical switch receive exactly the same packet.
2330 # Routing decrements TTL and updates source and dest MAC
2332 out_lrp=`vif_to_lrp $outport`
2333 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2334 fi >> $outport.expected
2338 as hv1 ovs-vsctl --columns=name,ofport list interface
2339 as hv1 ovn-sbctl list port_binding
2340 as hv1 ovn-sbctl list datapath_binding
2341 as hv1 ovn-sbctl dump-flows
2342 as hv1 ovs-ofctl dump-flows br-int
2344 # Send IP packets between all pairs of source and destination ports:
2346 # 1. Unicast IP packets are delivered to exactly one logical switch port
2347 # (except that packets destined to their input ports are dropped).
2349 # 2. Broadcast IP packets are delivered to all logical switch ports
2350 # except the input port.
2352 printf "%02x%02x%02x%02x" "$@"
2360 sip=`ip_to_hex 192 168 $is$js $ks`
2365 dip=`ip_to_hex 192 168 $id$jd $kd`
2366 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2367 if test $d != $s; then unicast=$d; else unicast=; fi
2369 test_ip $s $smac $dmac $sip $dip $unicast #1
2371 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2375 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2380 # 3. Send an IP packet from every logical port to every other subnet,
2381 # to an IP address that does not have a static IP-MAC binding.
2382 # This should generate a broadcast ARP request for the destination
2383 # IP address in the destination subnet.
2389 sip=`ip_to_hex 192 168 $is$js $ks`
2392 if test $is$js = $id$jd; then
2397 dmac=00000000ff$is$js
2398 # Calculate a 4th octet for the destination that is
2399 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2400 # that have static MAC bindings, and fits in the range
2402 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2403 dip=`ip_to_hex 192 168 $id$jd $o4`
2404 test_ip $s $smac $dmac $sip $dip
2406 # Every LP on the destination subnet's lswitch should
2407 # receive the ARP request.
2408 lrmac=00000000ff$id$jd
2409 lrip=`ip_to_hex 192 168 $id$jd 254`
2410 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2411 for jd2 in 1 2 3; do
2413 echo $arp >> $id$jd2$kd.expected
2422 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2424 # Causes a packet to be received on INPORT. The packet is an ARP
2425 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2426 # it should be the hardware address of the target to expect to receive in an
2427 # ARP reply; otherwise no reply is expected.
2429 # INPORT is an logical switch port number, e.g. 11 for vif11.
2430 # SHA and REPLY_HA are each 12 hex digits.
2431 # SPA and TPA are each 8 hex digits.
2433 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2434 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2435 hv=hv`vif_to_hv $inport`
2436 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2437 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2439 # Expect to receive the broadcast ARP on the other logical switch ports if
2440 # IP address is not configured to the switch patch port.
2441 local i=`vif_to_ls $inport`
2445 # 192.168.33.254 is configured to the switch patch port for lrp33,
2446 # so no ARP flooding expected for it.
2447 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2448 echo $request >> $i$j$k.expected
2453 # Expect to receive the reply, if any.
2454 if test X$reply_ha != X; then
2455 lrp=`vif_to_lrp $inport`
2456 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2457 echo $reply >> $inport.expected
2461 # Test router replies to ARP requests from all source ports:
2463 # 4. Router replies to query for its MAC address from port's own IP address.
2465 # 5. Router replies to query for its MAC address from any random IP address
2468 # 6. Router replies to query for its MAC address from another subnet.
2470 # 7. No reply to query for IP address other than router IP.
2474 smac=f00000000$i$j$k # Source MAC
2475 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2476 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2477 rmac=00000000ff$i$j # Router MAC
2478 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2479 test_arp $i$j$k $smac $sip $rip $rmac #4
2480 test_arp $i$j$k $smac $otherip $rip $rmac #5
2481 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2482 test_arp $i$j$k $smac $sip $otherip #7
2487 # Allow some time for packet forwarding.
2488 # XXX This can be improved.
2491 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2494 # Here, the $s is the VIF that originated the ARP request and $d is
2495 # the VIF that sends the ARP reply, which is somewhat backward but
2496 # it means that $s and $d are the same as #3.
2497 : > mac_bindings.expected
2504 if test $is$js = $id$jd; then
2511 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2512 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2513 host_mac=8000000000$o4
2515 lrmac=00000000ff$id$jd
2516 lrip=`ip_to_hex 192 168 $id$jd 254`
2518 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2524 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2525 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2526 #as $hv ovs-ofctl dump-flows br-int table=19
2528 host_ip_pretty=192.168.$id$jd.$o4
2529 host_mac_pretty=80:00:00:00:00:$o4
2530 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2537 # Allow some time for packet forwarding.
2538 # XXX This can be improved.
2541 # 9. Send an IP packet from every logical port to every other subnet. These
2542 # are the same packets already sent as #3, but now the destinations' IP-MAC
2543 # bindings have been discovered via ARP, so instead of provoking an ARP
2544 # request, these packets now get routed to their destinations (which don't
2545 # have static MAC bindings, so they go to the port we've designated as
2546 # accepting "unknown" MACs.)
2552 sip=`ip_to_hex 192 168 $is$js $ks`
2555 if test $is$js = $id$jd; then
2560 dmac=00000000ff$is$js
2561 # Calculate a 4th octet for the destination that is
2562 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2563 # that have static MAC bindings, and fits in the range
2565 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2566 dip=`ip_to_hex 192 168 $id$jd $o4`
2567 test_ip $s $smac $dmac $sip $dip
2569 # Expect the packet egress.
2570 host_mac=8000000000$o4
2573 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2580 ovn-sbctl -f csv -d bare --no-heading \
2581 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2583 # Now check the packets actually received against the ones expected.
2587 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2593 # Check the MAC bindings against those expected.
2594 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2597 # Gracefully terminate daemons
2598 OVN_CLEANUP([hv1], [hv2], [hv3])
2602 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2603 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2604 AT_SKIP_IF([test $HAVE_PYTHON = no])
2607 # Create hypervisors hv[123].
2608 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2609 # Add all of the vifs to a single logical switch lsw0.
2610 # Turn off port security on vifs vif[123]1
2611 # Turn on l2 port security on vifs vif[123]2
2612 # Turn of l2 and l3 port security on vifs vif[123]3
2613 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2614 ovn-nbctl ls-add lsw0
2619 ovs-vsctl add-br br-phys
2620 ovn_attach n1 br-phys 192.168.0.$i
2623 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
2624 ovn-nbctl lsp-add lsw0 lp$i$j
2625 if test $j = 1; then
2626 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2627 elif test $j = 2; then
2628 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2629 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2631 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2632 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2633 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2638 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2639 # packets for ARP resolution (native tunneling doesn't queue packets
2640 # for ARP resolution).
2643 # Allow some time for ovn-northd and ovn-controller to catch up.
2644 # XXX This should be more systematic.
2647 # Given the name of a logical port, prints the name of the hypervisor
2648 # on which it is located.
2659 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2661 # This shell function causes an ip packet to be received on INPORT.
2662 # The packet's content has Ethernet destination DST and source SRC
2663 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2664 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2665 # be received. INPORT and the OUTPORTs are specified as logical switch
2666 # port numbers, e.g. 11 for vif11.
2668 # This packet has bad checksums but logical L3 routing doesn't check.
2669 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2670 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2671 shift; shift; shift; shift; shift
2672 hv=`vif_to_hv $inport`
2673 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2674 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2676 echo $packet >> $outport.expected
2680 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2682 # Causes a packet to be received on INPORT. The packet is an ARP
2683 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2684 # it should be the hardware address of the target to expect to receive in an
2685 # ARP reply; otherwise no reply is expected.
2687 # INPORT is an logical switch port number, e.g. 11 for vif11.
2688 # SHA and REPLY_HA are each 12 hex digits.
2689 # SPA and TPA are each 8 hex digits.
2691 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2692 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2693 hv=`vif_to_hv $inport`
2694 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2695 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2696 if test $drop != 1; then
2697 if test X$reply_ha = X; then
2698 # Expect to receive the broadcast ARP on the other logical switch ports
2699 # if no reply is expected.
2703 if test $i$j != $inport; then
2704 echo $request >> $i$j.expected
2709 # Expect to receive the reply, if any.
2710 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2711 echo $reply >> $inport.expected
2716 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2717 # This function is similar to test_ip() except that it sends
2720 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2721 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2722 shift; shift; shift; shift; shift
2723 hv=`vif_to_hv $inport`
2724 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2725 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2727 echo $packet >> $outport.expected
2731 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2732 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2733 # of the test packet
2735 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2736 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2737 shift; shift; shift; shift; shift; shift
2738 hv=`vif_to_hv $inport`
2739 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2740 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2742 echo $packet >> $outport.expected
2747 printf "%02x%02x%02x%02x" "$@"
2751 sip=`ip_to_hex 192 168 0 12`
2752 tip=`ip_to_hex 192 168 0 13`
2753 # the arp packet should be allowed even if lp[123]1 is
2754 # not configured with mac f00000000023 and ip 192.168.0.12
2756 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2758 if test $i != $j; then
2759 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2765 sip=`ip_to_hex 192 168 0 12`
2766 tip=`ip_to_hex 192 168 0 13`
2768 # arp packet should be allowed since lp22 is configured with
2770 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2772 # arp packet should not be allowed since lp32 is not configured with
2774 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2776 # arp packet with sha set to f00000000021 should not be allowed
2778 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2780 # ip packets should be allowed and received since lp[123]2 do not
2781 # have l3 port security
2782 sip=`ip_to_hex 192 168 0 55`
2783 tip=`ip_to_hex 192 168 0 66`
2786 if test $i != $j; then
2787 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2792 # ipv6 packets should be received by lp[123]2
2793 # lp[123]1 can send ipv6 traffic as there is no port security
2794 sip=fe800000000000000000000000000000
2795 tip=ff020000000000000000000000000000
2798 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2802 # l2 and l3 port security
2803 sip=`ip_to_hex 192 168 0 13`
2804 tip=`ip_to_hex 192 168 0 22`
2805 # arp packet should be allowed since lp13 is configured with
2806 # f00000000013 and 192.168.0.13
2807 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2809 # the arp packet should be dropped because lp23 is not configured
2810 # with mac f00000000022
2811 sip=`ip_to_hex 192 168 0 13`
2812 tip=`ip_to_hex 192 168 0 22`
2813 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2815 # the arp packet should be dropped because lp33 is not configured
2816 # with ip 192.168.0.55
2817 spa=`ip_to_hex 192 168 0 55`
2818 tpa=`ip_to_hex 192 168 0 22`
2819 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2821 # ip packets should not be received by lp[123]3 since
2822 # l3 port security is enabled
2823 sip=`ip_to_hex 192 168 0 55`
2824 tip=`ip_to_hex 192 168 0 66`
2827 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2831 # ipv6 packets should be dropped for lp[123]3 since
2832 # it is configured with only ipv4 address
2833 sip=fe800000000000000000000000000000
2834 tip=ff020000000000000000000000000000
2837 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2840 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2841 # lp[123]1 can send ipv6 traffic as there is no port security
2843 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2846 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2847 # fe80::ea2a:eaff:fe28:0012
2849 # ipv4 packet should be dropped for lp13 with mac f0000000113
2850 sip=`ip_to_hex 192 168 0 13`
2851 tip=`ip_to_hex 192 168 0 23`
2852 test_ip 13 f00000000113 f00000000023 $sip $tip
2854 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2855 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2856 # lp11 can send ipv6 traffic as there is no port security
2857 sip=ee800000000000000000000000000000
2859 tip=fe80000000000000ea2aeafffe2800${i}3
2860 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2864 # ipv6 packet should not be received by lp33 with mac f0000000333
2865 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2866 # configured with fe80::ea2a:eaff:fe28:0033
2867 # lp11 can send ipv6 traffic as there is no port security
2869 sip=ee800000000000000000000000000000
2870 tip=fe80000000000000ea2aeafffe280023
2871 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2873 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2874 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2875 # and should be dropped for any other ip6.src
2876 # lp21 can receive ipv6 traffic as there is no port security
2878 tip=ee800000000000000000000000000000
2880 sip=fe80000000000000ea2aeafffe2800${i}3
2881 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2883 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2884 sip=00000000000000000000000000000000
2885 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2886 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2887 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2888 # Traffic to non-multicast traffic should be dropped
2889 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2890 # Traffic of other ICMPv6 types should be dropped
2891 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2894 sip=ae80000000000000ea2aeafffe2800aa
2895 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2898 # configure lsp13 to send and received IPv4 packets with an address range
2899 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"
2903 sip=`ip_to_hex 10 0 0 13`
2904 tip=`ip_to_hex 192 168 0 22`
2905 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2906 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2908 sip=`ip_to_hex 10 0 0 14`
2909 tip=`ip_to_hex 192 168 0 23`
2910 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2911 # with dst ip 192.168.0.23 should be allowed
2912 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2914 sip=`ip_to_hex 192 168 0 33`
2915 tip=`ip_to_hex 10 0 0 15`
2916 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2917 # with dst ip 10.0.0.15 should be received by lsp13
2918 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2920 sip=`ip_to_hex 192 168 0 33`
2921 tip=`ip_to_hex 20 0 0 4`
2922 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2923 # with dst ip 20.0.0.4 should be received by lsp13
2924 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2926 sip=`ip_to_hex 192 168 0 33`
2927 tip=`ip_to_hex 20 0 0 5`
2928 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2929 # with dst ip 20.0.0.5 should not be received by lsp13
2930 test_ip 33 f00000000033 f00000000013 $sip $tip
2932 sip=`ip_to_hex 192 168 0 33`
2933 tip=`ip_to_hex 20 0 0 255`
2934 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2935 # with dst ip 20.0.0.255 should be received by lsp13
2936 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2938 sip=`ip_to_hex 192 168 0 33`
2939 tip=`ip_to_hex 192 168 0 255`
2940 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2941 # with dst ip 192.168.0.255 should not be received by lsp13
2942 test_ip 33 f00000000033 f00000000013 $sip $tip
2944 sip=`ip_to_hex 192 168 0 33`
2945 tip=`ip_to_hex 224 0 0 4`
2946 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2947 # with dst ip 224.0.0.4 should be received by lsp13
2948 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2950 #dump information including flow counters
2952 ovn-sbctl dump-flows -- list multicast_group
2954 echo "------ hv1 dump ------"
2955 as hv1 ovs-vsctl show
2956 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2957 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2959 echo "------ hv2 dump ------"
2960 as hv2 ovs-vsctl show
2961 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2962 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2964 echo "------ hv3 dump ------"
2965 as hv3 ovs-vsctl show
2966 as hv3 ovs-ofctl -O OpenFlow13 show br-int
2967 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2969 # Now check the packets actually received against the ones expected.
2972 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2976 OVN_CLEANUP([hv1],[hv2],[hv3])
2980 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2981 AT_SKIP_IF([test $HAVE_PYTHON = no])
2985 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2986 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2987 # R2 has ls2 (172.16.1.0/24) connected to it.
2989 ls1_lp1_mac="f0:00:00:01:02:03"
2990 rp_ls1_mac="00:00:00:01:02:03"
2991 rp_ls2_mac="00:00:00:01:02:04"
2992 ls2_lp1_mac="f0:00:00:01:02:04"
2994 ls1_lp1_ip="192.168.1.2"
2995 ls2_lp1_ip="172.16.1.2"
3000 ovn-nbctl ls-add ls1
3001 ovn-nbctl ls-add ls2
3004 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
3006 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3007 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
3010 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
3012 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3013 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
3016 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3017 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3019 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3020 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
3022 # Create logical port ls1-lp1 in ls1
3023 ovn-nbctl lsp-add ls1 ls1-lp1 \
3024 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
3026 # Create logical port ls2-lp1 in ls2
3027 ovn-nbctl lsp-add ls2 ls2-lp1 \
3028 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
3030 # Create two hypervisor and create OVS ports corresponding to logical ports.
3035 ovs-vsctl add-br br-phys
3036 ovn_attach n1 br-phys 192.168.0.1
3037 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3038 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3039 options:tx_pcap=hv1/vif1-tx.pcap \
3040 options:rxq_pcap=hv1/vif1-rx.pcap \
3045 ovs-vsctl add-br br-phys
3046 ovn_attach n1 br-phys 192.168.0.2
3047 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3048 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3049 options:tx_pcap=hv2/vif1-tx.pcap \
3050 options:rxq_pcap=hv2/vif1-rx.pcap \
3054 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3055 # packets for ARP resolution (native tunneling doesn't queue packets
3056 # for ARP resolution).
3059 # Allow some time for ovn-northd and ovn-controller to catch up.
3060 # XXX This should be more systematic.
3064 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3065 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3066 udp && udp.src==53 && udp.dst==4369"
3067 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3070 echo "---------NB dump-----"
3072 echo "---------------------"
3073 ovn-nbctl list logical_router
3074 echo "---------------------"
3075 ovn-nbctl list logical_router_port
3076 echo "---------------------"
3078 echo "---------SB dump-----"
3079 ovn-sbctl list datapath_binding
3080 echo "---------------------"
3081 ovn-sbctl list port_binding
3082 echo "---------------------"
3084 echo "------ hv1 dump ----------"
3085 as hv1 ovs-ofctl show br-int
3086 as hv1 ovs-ofctl dump-flows br-int
3087 echo "------ hv2 dump ----------"
3088 as hv2 ovs-ofctl show br-int
3089 as hv2 ovs-ofctl dump-flows br-int
3092 # The TTL should be decremented by 2.
3093 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3094 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3095 udp && udp.src==53 && udp.dst==4369"
3096 echo $packet | ovstest test-ovn expr-to-packets > expected
3098 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3100 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3101 grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3104 # Disable the ls2-lp1 port.
3105 ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3107 AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3108 grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3111 # Generate the packet destined for ls2-lp1 and it should not be delivered.
3113 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3114 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3115 udp && udp.src==53 && udp.dst==4369"
3117 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3118 # The 2nd packet sent shound not be received.
3119 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3121 OVN_CLEANUP([hv1],[hv2])
3126 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3127 AT_KEYWORDS([router-admin-state])
3128 AT_SKIP_IF([test $HAVE_PYTHON = no])
3132 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3133 # and 172.16.1.0/24) connected to it.
3137 ovn-nbctl ls-add ls1
3140 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3141 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3142 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3144 # Create logical port ls1-lp1 in ls1
3145 ovn-nbctl lsp-add ls1 ls1-lp1 \
3146 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3148 # Create logical port ls1-lp2 in ls1
3149 ovn-nbctl lsp-add ls1 ls1-lp2 \
3150 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3152 # Create one hypervisor and create OVS ports corresponding to logical ports.
3157 ovs-vsctl add-br br-phys
3158 ovn_attach n1 br-phys 192.168.0.1
3159 ovs-vsctl -- add-port br-int vif1 -- \
3160 set interface vif1 external-ids:iface-id=ls1-lp1 \
3161 options:tx_pcap=hv1/vif1-tx.pcap \
3162 options:rxq_pcap=hv1/vif1-rx.pcap \
3165 ovs-vsctl -- add-port br-int vif2 -- \
3166 set interface vif2 external-ids:iface-id=ls1-lp2 \
3167 options:tx_pcap=hv1/vif2-tx.pcap \
3168 options:rxq_pcap=hv1/vif2-rx.pcap \
3172 # Allow some time for ovn-northd and ovn-controller to catch up.
3173 # XXX This should be more systematic.
3176 # Send ip packets between the two ports.
3178 printf "%02x%02x%02x%02x" "$@"
3182 src_mac="f00000010203"
3183 dst_mac="000000010203"
3184 src_ip=`ip_to_hex 192 168 1 2`
3185 dst_ip=`ip_to_hex 172 16 1 2`
3186 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3187 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3190 echo "---------NB dump-----"
3192 echo "---------------------"
3193 ovn-nbctl list logical_router
3194 echo "---------------------"
3195 ovn-nbctl list logical_router_port
3196 echo "---------------------"
3198 echo "---------SB dump-----"
3199 ovn-sbctl list datapath_binding
3200 echo "---------------------"
3201 ovn-sbctl list logical_flow
3202 echo "---------------------"
3204 echo "------ hv1 dump ----------"
3205 as hv1 ovs-ofctl dump-flows br-int
3209 ovn-nbctl set Logical_Router R1 enabled=false
3211 # Allow some time for ovn-northd and ovn-controller to catch up.
3212 # XXX This should be more systematic.
3215 echo "---------SB dump-----"
3216 ovn-sbctl list datapath_binding
3217 echo "---------------------"
3218 ovn-sbctl list logical_flow
3219 echo "---------------------"
3221 echo "------ hv1 dump ----------"
3222 as hv1 ovs-ofctl dump-flows br-int
3224 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3227 expect_src_mac="000000010203"
3228 expect_dst_mac="f00000010204"
3229 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3231 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3235 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3236 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3237 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3240 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3243 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3246 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3249 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3250 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3255 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3256 AT_KEYWORDS([router-admin-state])
3257 AT_SKIP_IF([test $HAVE_PYTHON = no])
3261 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3262 # and has switch ls2 (172.16.1.0/24) connected to it.
3266 ovn-nbctl ls-add ls1
3267 ovn-nbctl ls-add ls2
3270 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3271 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3272 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3275 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3276 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3277 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3279 # Create logical port ls1-lp1 in ls1
3280 ovn-nbctl lsp-add ls1 ls1-lp1 \
3281 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3283 # Create logical port ls2-lp1 in ls2
3284 ovn-nbctl lsp-add ls2 ls2-lp1 \
3285 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3287 # Create one hypervisor and create OVS ports corresponding to logical ports.
3292 ovs-vsctl add-br br-phys
3293 ovn_attach n1 br-phys 192.168.0.1
3294 ovs-vsctl -- add-port br-int vif1 -- \
3295 set interface vif1 external-ids:iface-id=ls1-lp1 \
3296 options:tx_pcap=hv1/vif1-tx.pcap \
3297 options:rxq_pcap=hv1/vif1-rx.pcap \
3300 ovs-vsctl -- add-port br-int vif2 -- \
3301 set interface vif2 external-ids:iface-id=ls2-lp1 \
3302 options:tx_pcap=hv1/vif2-tx.pcap \
3303 options:rxq_pcap=hv1/vif2-rx.pcap \
3307 # Allow some time for ovn-northd and ovn-controller to catch up.
3308 # XXX This should be more systematic.
3311 # Send ip packets between the two ports.
3313 printf "%02x%02x%02x%02x" "$@"
3317 src_mac="f00000010203"
3318 dst_mac="000000010203"
3319 src_ip=`ip_to_hex 192 168 1 2`
3320 dst_ip=`ip_to_hex 172 16 1 2`
3321 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3322 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3325 echo "---------NB dump-----"
3327 echo "---------------------"
3328 ovn-nbctl list logical_router
3329 echo "---------------------"
3330 ovn-nbctl list logical_router_port
3331 echo "---------------------"
3333 echo "---------SB dump-----"
3334 ovn-sbctl list datapath_binding
3335 echo "---------------------"
3336 ovn-sbctl list logical_flow
3337 echo "---------------------"
3339 echo "------ hv1 dump ----------"
3340 as hv1 ovs-ofctl dump-flows br-int
3343 ovn-nbctl set Logical_Router R1 enabled=false
3345 echo "---------SB dump-----"
3346 ovn-sbctl list datapath_binding
3347 echo "---------------------"
3348 ovn-sbctl list logical_flow
3349 echo "---------------------"
3351 echo "------ hv1 dump ----------"
3352 as hv1 ovs-ofctl dump-flows br-int
3354 # Allow some time for the disabling of logical router R1 to propagate.
3355 # XXX This should be more systematic.
3358 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3361 expect_src_mac="000000010204"
3362 expect_dst_mac="f00000010204"
3363 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3365 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3371 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3372 AT_SKIP_IF([test $HAVE_PYTHON = no])
3376 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3377 # network. R1 has switchess foo (192.168.1.0/24)
3379 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3384 ovn-nbctl ls-add foo
3385 ovn-nbctl ls-add alice
3386 ovn-nbctl ls-add bob
3389 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3390 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3391 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3393 # Connect alice to R2
3394 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3395 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3396 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3399 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3400 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3401 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3404 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3405 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3407 #install static routes
3408 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3409 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3410 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3412 # Create logical port foo1 in foo
3413 ovn-nbctl lsp-add foo foo1 \
3414 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3416 # Create logical port alice1 in alice
3417 ovn-nbctl lsp-add alice alice1 \
3418 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3420 # Create logical port bob1 in bob
3421 ovn-nbctl lsp-add bob bob1 \
3422 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3424 # Create two hypervisor and create OVS ports corresponding to logical ports.
3429 ovs-vsctl add-br br-phys
3430 ovn_attach n1 br-phys 192.168.0.1
3431 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3432 set interface hv1-vif1 external-ids:iface-id=foo1 \
3433 options:tx_pcap=hv1/vif1-tx.pcap \
3434 options:rxq_pcap=hv1/vif1-rx.pcap \
3437 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3438 set interface hv1-vif2 external-ids:iface-id=alice1 \
3439 options:tx_pcap=hv1/vif2-tx.pcap \
3440 options:rxq_pcap=hv1/vif2-rx.pcap \
3445 ovs-vsctl add-br br-phys
3446 ovn_attach n1 br-phys 192.168.0.2
3447 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3448 set interface hv2-vif1 external-ids:iface-id=bob1 \
3449 options:tx_pcap=hv2/vif1-tx.pcap \
3450 options:rxq_pcap=hv2/vif1-rx.pcap \
3454 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3455 # packets for ARP resolution (native tunneling doesn't queue packets
3456 # for ARP resolution).
3459 # Allow some time for ovn-northd and ovn-controller to catch up.
3460 # XXX This should be more systematic.
3464 printf "%02x%02x%02x%02x" "$@"
3467 # Send ip packets between foo1 and alice1
3468 src_mac="f00000010203"
3469 dst_mac="000000010203"
3470 src_ip=`ip_to_hex 192 168 1 2`
3471 dst_ip=`ip_to_hex 172 16 1 2`
3472 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3473 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3475 # Send ip packets between foo1 and bob1
3476 src_mac="f00000010203"
3477 dst_mac="000000010203"
3478 src_ip=`ip_to_hex 192 168 1 2`
3479 dst_ip=`ip_to_hex 172 16 2 2`
3480 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3481 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3483 echo "---------NB dump-----"
3485 echo "---------------------"
3486 ovn-nbctl list logical_router
3487 echo "---------------------"
3488 ovn-nbctl list logical_router_port
3489 echo "---------------------"
3491 echo "---------SB dump-----"
3492 ovn-sbctl list datapath_binding
3493 echo "---------------------"
3494 ovn-sbctl list port_binding
3495 echo "---------------------"
3497 echo "------ hv1 dump ----------"
3498 as hv1 ovs-ofctl dump-flows br-int
3499 echo "------ hv2 dump ----------"
3500 as hv2 ovs-ofctl dump-flows br-int
3502 # Packet to Expect at bob1
3503 src_mac="000000010205"
3504 dst_mac="f00000010205"
3505 src_ip=`ip_to_hex 192 168 1 2`
3506 dst_ip=`ip_to_hex 172 16 2 2`
3507 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3509 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3511 # Packet to Expect at alice1
3512 src_mac="000000010204"
3513 dst_mac="f00000010204"
3514 src_ip=`ip_to_hex 192 168 1 2`
3515 dst_ip=`ip_to_hex 172 16 1 2`
3516 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3518 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3520 OVN_CLEANUP([hv1],[hv2])
3524 AT_SETUP([ovn -- send gratuitous arp on localnet])
3525 AT_SKIP_IF([test $HAVE_PYTHON = no])
3527 ovn-nbctl ls-add lsw0
3535 ovn_attach n1 br-phys 192.168.0.1
3537 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3538 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])
3541 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3542 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3543 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3545 # Create a localnet port.
3546 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3547 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3548 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3549 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3551 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3553 # Wait for packet to be received.
3554 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3555 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3557 # Delete the localnet ports.
3558 AT_CHECK([ovs-vsctl del-port localvif1])
3559 AT_CHECK([ovn-nbctl lsp-del ln_port])
3565 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3566 AT_SKIP_IF([test $HAVE_PYTHON = no])
3570 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3571 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3572 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3579 ovn-nbctl ls-add foo
3580 ovn-nbctl ls-add alice
3581 ovn-nbctl ls-add bob
3582 ovn-nbctl ls-add join
3585 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3586 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3587 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3589 # Connect alice to R2
3590 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3591 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3592 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3595 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3596 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3597 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3599 # Connect R1 to join
3600 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3601 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3602 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3604 # Connect R2 to join
3605 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3606 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3607 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3609 # Connect R3 to join
3610 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3611 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3612 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3614 #install static routes
3615 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3616 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3618 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3619 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3621 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3622 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3624 # Create logical port foo1 in foo
3625 ovn-nbctl lsp-add foo foo1 \
3626 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3628 # Create logical port alice1 in alice
3629 ovn-nbctl lsp-add alice alice1 \
3630 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3632 # Create logical port bob1 in bob
3633 ovn-nbctl lsp-add bob bob1 \
3634 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3636 # Create two hypervisor and create OVS ports corresponding to logical ports.
3641 ovs-vsctl add-br br-phys
3642 ovn_attach n1 br-phys 192.168.0.1
3643 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3644 set interface hv1-vif1 external-ids:iface-id=foo1 \
3645 options:tx_pcap=hv1/vif1-tx.pcap \
3646 options:rxq_pcap=hv1/vif1-rx.pcap \
3649 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3650 set interface hv1-vif2 external-ids:iface-id=alice1 \
3651 options:tx_pcap=hv1/vif2-tx.pcap \
3652 options:rxq_pcap=hv1/vif2-rx.pcap \
3657 ovs-vsctl add-br br-phys
3658 ovn_attach n1 br-phys 192.168.0.2
3659 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3660 set interface hv2-vif1 external-ids:iface-id=bob1 \
3661 options:tx_pcap=hv2/vif1-tx.pcap \
3662 options:rxq_pcap=hv2/vif1-rx.pcap \
3666 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3667 # packets for ARP resolution (native tunneling doesn't queue packets
3668 # for ARP resolution).
3671 # Allow some time for ovn-northd and ovn-controller to catch up.
3672 # XXX This should be more systematic.
3676 printf "%02x%02x%02x%02x" "$@"
3679 # Send ip packets between foo1 and alice1
3680 src_mac="f00000010203"
3681 dst_mac="000001010203"
3682 src_ip=`ip_to_hex 192 168 1 2`
3683 dst_ip=`ip_to_hex 172 16 1 2`
3684 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3685 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3686 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3688 # Send ip packets between foo1 and bob1
3689 src_mac="f00000010203"
3690 dst_mac="000001010203"
3691 src_ip=`ip_to_hex 192 168 1 2`
3692 dst_ip=`ip_to_hex 10 32 1 2`
3693 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3694 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3696 echo "---------NB dump-----"
3698 echo "---------------------"
3699 ovn-nbctl list logical_router
3700 echo "---------------------"
3701 ovn-nbctl list logical_router_port
3702 echo "---------------------"
3704 echo "---------SB dump-----"
3705 ovn-sbctl list datapath_binding
3706 echo "---------------------"
3707 ovn-sbctl list port_binding
3708 echo "---------------------"
3709 ovn-sbctl dump-flows
3710 echo "---------------------"
3712 echo "------ hv1 dump ----------"
3713 as hv1 ovs-ofctl show br-int
3714 as hv1 ovs-ofctl dump-flows br-int
3715 echo "------ hv2 dump ----------"
3716 as hv2 ovs-ofctl show br-int
3717 as hv2 ovs-ofctl dump-flows br-int
3718 echo "----------------------------"
3720 # Packet to Expect at bob1
3721 src_mac="000003010203"
3722 dst_mac="f00000010205"
3723 src_ip=`ip_to_hex 192 168 1 2`
3724 dst_ip=`ip_to_hex 10 32 1 2`
3725 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3727 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3729 # Packet to Expect at alice1
3730 src_mac="000002010203"
3731 dst_mac="f00000010204"
3732 src_ip=`ip_to_hex 192 168 1 2`
3733 dst_ip=`ip_to_hex 172 16 1 2`
3734 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3736 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3738 OVN_CLEANUP([hv1],[hv2])
3742 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3743 AT_SKIP_IF([test $HAVE_PYTHON = no])
3746 ovn-nbctl ls-add ls1
3748 ovn-nbctl lsp-add ls1 ls1-lp1 \
3749 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3751 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3753 ovn-nbctl lsp-add ls1 ls1-lp2 \
3754 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3756 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3758 ovn-nbctl ls-add ls2
3759 ovn-nbctl lsp-add ls2 ls2-lp1 \
3760 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3761 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3762 ovn-nbctl lsp-add ls2 ls2-lp2 \
3763 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3764 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3766 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3767 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3768 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3770 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3771 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3773 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3774 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3775 \"lease_time\"=\"3600\"")"
3777 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3783 ovs-vsctl add-br br-phys
3784 ovn_attach n1 br-phys 192.168.0.1
3785 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3786 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3787 options:tx_pcap=hv1/vif1-tx.pcap \
3788 options:rxq_pcap=hv1/vif1-rx.pcap \
3791 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3792 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3793 options:tx_pcap=hv1/vif2-tx.pcap \
3794 options:rxq_pcap=hv1/vif2-rx.pcap \
3797 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3798 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3799 options:tx_pcap=hv1/vif3-tx.pcap \
3800 options:rxq_pcap=hv1/vif3-rx.pcap \
3803 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3804 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3805 options:tx_pcap=hv1/vif4-tx.pcap \
3806 options:rxq_pcap=hv1/vif4-rx.pcap \
3813 as hv1 ovs-vsctl show
3815 # This shell function sends a DHCP request packet
3816 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3818 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3819 shift; shift; shift; shift; shift;
3820 if test $use_ip != 0; then
3825 src_ip=`ip_to_hex 0 0 0 0`
3826 dst_ip=`ip_to_hex 255 255 255 255`
3828 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
3829 # udp header and dhcp header
3830 request=${request}0044004300fc0000
3831 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3832 # client hardware padding
3833 request=${request}00000000000000000000
3835 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3836 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3838 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3839 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3840 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3841 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3843 request=${request}63825363
3845 request=${request}3501${dhcp_type}ff
3847 if test $offer_ip != 0; then
3848 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
3849 # total IP length will be the IP length of the request packet
3850 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3851 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3852 udp_len=`expr $ip_len - 20`
3853 ip_len=$(printf "%x" $ip_len)
3854 udp_len=$(printf "%x" $udp_len)
3855 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3856 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3857 # udp header and dhcp header.
3858 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3859 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3861 reply=${reply}${offer_ip}
3862 # next server ip address, relay agent ip address, client mac address
3863 reply=${reply}0000000000000000${src_mac}
3864 # client hardware padding
3865 reply=${reply}00000000000000000000
3867 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3868 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3870 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3871 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3872 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3873 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3875 reply=${reply}63825363
3877 local dhcp_reply_type=02
3878 if test $dhcp_type = 03; then
3881 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3882 echo $reply >> $inport.expected
3885 echo $request >> $outport.expected
3888 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3894 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3895 options:rxq_pcap=dummy-rx.pcap
3896 rm -f ${pcap_file}*.pcap
3897 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3898 options:rxq_pcap=${pcap_file}-rx.pcap
3902 printf "%02x%02x%02x%02x" "$@"
3905 AT_CAPTURE_FILE([ofctl_monitor0.log])
3906 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3907 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3909 echo "---------NB dump-----"
3911 echo "---------------------"
3912 echo "---------SB dump-----"
3913 ovn-sbctl list datapath_binding
3914 echo "---------------------"
3915 ovn-sbctl list logical_flow
3916 echo "---------------------"
3918 echo "---------------------"
3919 ovn-sbctl dump-flows
3920 echo "---------------------"
3922 echo "------ hv1 dump ----------"
3923 as hv1 ovs-ofctl dump-flows br-int
3925 # Send DHCPDISCOVER.
3926 offer_ip=`ip_to_hex 10 0 0 4`
3927 server_ip=`ip_to_hex 10 0 0 1`
3928 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3929 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3931 # NXT_RESUMEs should be 1.
3932 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3934 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3935 cat 1.expected | cut -c -48 > expout
3936 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3937 # Skipping the IPv4 checksum.
3938 cat 1.expected | cut -c 53- > expout
3939 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3941 # ovs-ofctl also resumes the packets and this causes other ports to receive
3942 # the DHCP request packet. So reset the pcap files so that its easier to test.
3943 reset_pcap_file hv1-vif1 hv1/vif1
3944 reset_pcap_file hv1-vif2 hv1/vif2
3949 offer_ip=`ip_to_hex 10 0 0 6`
3950 server_ip=`ip_to_hex 10 0 0 1`
3951 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3952 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3954 # NXT_RESUMEs should be 2.
3955 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3957 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3958 cat 2.expected | cut -c -48 > expout
3959 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3960 # Skipping the IPv4 checksum.
3961 cat 2.expected | cut -c 53- > expout
3962 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3964 reset_pcap_file hv1-vif1 hv1/vif1
3965 reset_pcap_file hv1-vif2 hv1/vif2
3969 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3970 # but should be resumed without the reply.
3971 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3972 # one from ovn-controller and the other from "ovs-ofctl resume."
3974 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
3976 # NXT_RESUMEs should be 3.
3977 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3979 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
3980 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3982 reset_pcap_file hv1-vif1 hv1/vif1
3983 reset_pcap_file hv1-vif2 hv1/vif2
3987 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3988 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3990 test_dhcp 3 f00000000003 01 0 4 0
3992 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3994 test_dhcp 4 f00000000004 01 0 3 0
3996 # NXT_RESUMEs should be 3.
3997 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3999 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4000 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
4002 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4003 offer_ip=`ip_to_hex 10 0 0 6`
4004 server_ip=`ip_to_hex 10 0 0 1`
4005 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4008 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4010 # NXT_RESUMEs should be 4.
4011 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4013 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4014 cat 2.expected | cut -c -48 > expout
4015 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4016 # Skipping the IPv4 checksum.
4017 cat 2.expected | cut -c 53- > expout
4018 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4020 reset_pcap_file hv1-vif1 hv1/vif1
4021 reset_pcap_file hv1-vif2 hv1/vif2
4025 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4026 offer_ip=`ip_to_hex 10 0 0 6`
4027 server_ip=`ip_to_hex 10 0 0 1`
4028 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4030 dst_ip=`ip_to_hex 255 255 255 255`
4031 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4033 # NXT_RESUMEs should be 5.
4034 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4036 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4037 cat 2.expected | cut -c -48 > expout
4038 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4039 # Skipping the IPv4 checksum.
4040 cat 2.expected | cut -c 53- > expout
4041 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4043 reset_pcap_file hv1-vif1 hv1/vif1
4044 reset_pcap_file hv1-vif2 hv1/vif2
4048 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4049 # The packet should not be received by ovn-controller.
4050 src_ip=`ip_to_hex 10 0 0 6`
4051 dst_ip=`ip_to_hex 10 0 0 4`
4052 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4054 # NXT_RESUMEs should be 5.
4055 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4057 # vif1-tx.pcap should have received the DHCPv4 request packet
4058 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4061 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4062 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4063 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4066 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4069 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4072 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4075 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4076 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4080 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4081 AT_SKIP_IF([test $HAVE_PYTHON = no])
4084 ovn-nbctl ls-add ls1
4085 ovn-nbctl lsp-add ls1 ls1-lp1 \
4086 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4088 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4090 ovn-nbctl lsp-add ls1 ls1-lp2 \
4091 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4093 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4095 ovn-nbctl lsp-add ls1 ls1-lp3 \
4096 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4098 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4100 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4101 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4103 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4104 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4106 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4107 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4109 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4111 ovn-nbctl ls-add ls2
4112 ovn-nbctl lsp-add ls2 ls2-lp1 \
4113 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4114 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4115 ovn-nbctl lsp-add ls2 ls2-lp2 \
4116 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4117 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4123 ovs-vsctl add-br br-phys
4124 ovn_attach n1 br-phys 192.168.0.1
4125 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4126 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4127 options:tx_pcap=hv1/vif1-tx.pcap \
4128 options:rxq_pcap=hv1/vif1-rx.pcap \
4131 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4132 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4133 options:tx_pcap=hv1/vif2-tx.pcap \
4134 options:rxq_pcap=hv1/vif2-rx.pcap \
4137 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4138 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4139 options:tx_pcap=hv1/vif3-tx.pcap \
4140 options:rxq_pcap=hv1/vif3-rx.pcap \
4143 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4144 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4145 options:tx_pcap=hv1/vif4-tx.pcap \
4146 options:rxq_pcap=hv1/vif4-rx.pcap \
4149 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4150 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4151 options:tx_pcap=hv1/vif5-tx.pcap \
4152 options:rxq_pcap=hv1/vif5-rx.pcap \
4160 sed 's/\(00\)\{1,\}$//'
4163 # This shell function sends a DHCPv6 request packet
4164 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4165 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4166 # packet should be received twice (one from ovn-controller and the other
4167 # from the "ovs-ofctl monitor br-int resume"
4169 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4170 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4172 request=${request}ff020000000000000000000000010002
4173 # udp header and dhcpv6 header
4174 request=${request}02220223002affff${msg_code}010203
4176 request=${request}0001000a00030001${src_mac}
4177 # IA-NA (Identity Association for Non Temporary Address)
4178 request=${request}0003000c0102030400000e1000001518
4179 shift; shift; shift; shift; shift;
4180 if test $offer_ip != 0; then
4181 local server_mac=000000100001
4182 local server_lla=fe80000000000000020000fffe100001
4184 if test $msg_code = 01; then
4188 if test $offer_ip = 1; then
4191 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4192 # udp header and dhcpv6 header
4193 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4195 reply=${reply}0001000a00030001${src_mac}
4197 if test $offer_ip != 1; then
4198 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4201 reply=${reply}0002000a00030001${server_mac}
4202 echo $reply | trim_zeros >> $inport.expected
4205 echo $request | trim_zeros >> $outport.expected
4209 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4215 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4216 options:rxq_pcap=dummy-rx.pcap
4217 rm -f ${pcap_file}*.pcap
4218 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4219 options:rxq_pcap=${pcap_file}-rx.pcap
4222 AT_CAPTURE_FILE([ofctl_monitor0.log])
4223 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4224 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4226 echo "---------NB dump-----"
4228 echo "---------------------"
4229 echo "---------SB dump-----"
4230 ovn-sbctl list datapath_binding
4231 echo "---------------------"
4232 ovn-sbctl list logical_flow
4233 echo "---------------------"
4235 echo "---------------------"
4236 ovn-sbctl dump-flows
4237 echo "---------------------"
4239 echo "------ hv1 dump ----------"
4240 as hv1 ovs-ofctl dump-flows br-int
4242 src_mac=f00000000001
4243 src_lla=fe80000000000000f20000fffe000001
4244 offer_ip=ae700000000000000000000000000004
4245 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4247 # NXT_RESUMEs should be 1.
4248 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4250 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4251 # cat 1.expected | trim_zeros > expout
4252 cat 1.expected | cut -c -120 > expout
4253 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4254 # Skipping the UDP checksum
4255 cat 1.expected | cut -c 125- > expout
4256 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4260 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4261 # without any modifications and the packet should be received by ls1-lp1.
4262 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4263 # resume and the other from ovs-ofctl monitor resume.
4265 reset_pcap_file hv1-vif1 hv1/vif1
4266 reset_pcap_file hv1-vif2 hv1/vif2
4268 src_mac=f00000000002
4269 src_lla=fe80000000000000f20000fffe000002
4270 offer_ip=ae700000000000000000000000000005
4271 # Set invalid msg_type
4273 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4275 # NXT_RESUMEs should be 2.
4276 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4278 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4280 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4281 AT_CHECK([cat 2.packets], [0], [])
4283 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4284 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4285 cat 1.expected > expout
4286 AT_CHECK([cat 1.packets], [0], [expout])
4288 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4289 # There should be no DHCPv6 reply from ovn-controller and the request packet
4290 # should be received by ls2-lp2.
4292 src_mac=f00000000003
4293 src_lla=fe80000000000000f20000fffe000003
4294 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4296 # NXT_RESUMEs should be 2 only.
4297 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4299 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4300 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4301 AT_CHECK([cat 3.packets], [0], [])
4303 # vif4-tx.pcap should have received the DHCPv6 request packet
4304 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4305 cat 4.expected > expout
4306 AT_CHECK([cat 4.packets], [0], [expout])
4308 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4309 # The DHCPv6 reply should doesn't contian offer_ip.
4310 src_mac=f00000000022
4311 src_lla=fe80000000000000f20000fffe000022
4312 reset_pcap_file hv1-vif5 hv1/vif5
4313 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4315 # NXT_RESUMEs should be 3.
4316 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4318 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4319 # Skipping the UDP checksum
4320 cat 5.expected | cut -c 1-120,125- > expout
4321 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4324 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4325 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4326 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4329 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4332 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4335 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4338 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4339 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4343 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4344 AT_SKIP_IF([test $HAVE_PYTHON = no])
4348 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4349 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4350 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4351 # R2 is a gateway router.
4355 # Create two hypervisor and create OVS ports corresponding to logical ports.
4360 ovs-vsctl add-br br-phys
4361 ovn_attach n1 br-phys 192.168.0.1
4362 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4363 set interface hv1-vif1 external-ids:iface-id=foo1 \
4364 options:tx_pcap=hv1/vif1-tx.pcap \
4365 options:rxq_pcap=hv1/vif1-rx.pcap \
4371 ovs-vsctl add-br br-phys
4372 ovn_attach n1 br-phys 192.168.0.2
4373 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4374 set interface hv2-vif1 external-ids:iface-id=alice1 \
4375 options:tx_pcap=hv2/vif1-tx.pcap \
4376 options:rxq_pcap=hv2/vif1-rx.pcap \
4379 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4380 # packets for ARP resolution (native tunneling doesn't queue packets
4381 # for ARP resolution).
4384 ovn-nbctl create Logical_Router name=R1
4385 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4387 ovn-nbctl ls-add foo
4388 ovn-nbctl ls-add alice
4389 ovn-nbctl ls-add join
4392 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4393 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4394 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4396 # Connect alice to R2
4397 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4398 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4399 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4401 # Connect R1 to join
4402 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4403 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4404 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4406 # Connect R2 to join
4407 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4408 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4409 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4412 #install static routes
4413 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4414 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4415 R1 static_routes @lrt
4417 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4418 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4419 R2 static_routes @lrt
4421 # Create logical port foo1 in foo
4422 ovn-nbctl lsp-add foo foo1 \
4423 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4425 # Create logical port alice1 in alice
4426 ovn-nbctl lsp-add alice alice1 \
4427 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4430 # Allow some time for ovn-northd and ovn-controller to catch up.
4431 # XXX This should be more systematic.
4435 printf "%02x%02x%02x%02x" "$@"
4438 # Send ip packets between foo1 and alice1
4439 src_mac="f00000010203"
4440 dst_mac="000001010203"
4441 src_ip=`ip_to_hex 192 168 1 2`
4442 dst_ip=`ip_to_hex 172 16 1 2`
4443 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4445 echo "---------NB dump-----"
4447 echo "---------------------"
4448 ovn-nbctl list logical_router
4449 echo "---------------------"
4450 ovn-nbctl list logical_router_port
4451 echo "---------------------"
4453 echo "---------SB dump-----"
4454 ovn-sbctl list datapath_binding
4455 echo "---------------------"
4456 ovn-sbctl list port_binding
4457 echo "---------------------"
4458 ovn-sbctl dump-flows
4459 echo "---------------------"
4460 ovn-sbctl list chassis
4461 ovn-sbctl list encap
4462 echo "---------------------"
4464 # Packet to Expect at alice1
4465 src_mac="000002010203"
4466 dst_mac="f00000010204"
4467 src_ip=`ip_to_hex 192 168 1 2`
4468 dst_ip=`ip_to_hex 172 16 1 2`
4469 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4472 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4473 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4475 echo "------ hv1 dump after packet 1 ----------"
4476 as hv1 ovs-ofctl show br-int
4477 as hv1 ovs-ofctl dump-flows br-int
4478 echo "------ hv2 dump after packet 1 ----------"
4479 as hv2 ovs-ofctl show br-int
4480 as hv2 ovs-ofctl dump-flows br-int
4481 echo "----------------------------"
4483 echo $expected > expected
4484 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4486 # Delete the router and re-create it. Things should work as before.
4488 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4489 # Connect alice to R2
4490 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4491 # Connect R2 to join
4492 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4494 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4495 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4496 R2 static_routes @lrt
4498 # Wait for ovn-controller to catch up.
4501 # Send the packet again.
4502 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4504 echo "------ hv1 dump after packet 2 ----------"
4505 as hv1 ovs-ofctl show br-int
4506 as hv1 ovs-ofctl dump-flows br-int
4507 echo "------ hv2 dump after packet 2 ----------"
4508 as hv2 ovs-ofctl show br-int
4509 as hv2 ovs-ofctl dump-flows br-int
4510 echo "----------------------------"
4512 echo $expected >> expected
4513 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4515 OVN_CLEANUP([hv1],[hv2])
4519 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4520 AT_KEYWORDS([router-icmp-reply])
4521 AT_SKIP_IF([test $HAVE_PYTHON = no])
4525 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4526 # and has switch ls2 (172.16.1.0/24) connected to it.
4530 ovn-nbctl ls-add ls1
4531 ovn-nbctl ls-add ls2
4534 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4535 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4536 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4539 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4540 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4541 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4543 # Create logical port ls1-lp1 in ls1
4544 ovn-nbctl lsp-add ls1 ls1-lp1 \
4545 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4547 # Create logical port ls2-lp1 in ls2
4548 ovn-nbctl lsp-add ls2 ls2-lp1 \
4549 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4551 # Create one hypervisor and create OVS ports corresponding to logical ports.
4556 ovs-vsctl add-br br-phys
4557 ovn_attach n1 br-phys 192.168.0.1
4558 ovs-vsctl -- add-port br-int vif1 -- \
4559 set interface vif1 external-ids:iface-id=ls1-lp1 \
4560 options:tx_pcap=hv1/vif1-tx.pcap \
4561 options:rxq_pcap=hv1/vif1-rx.pcap \
4564 ovs-vsctl -- add-port br-int vif2 -- \
4565 set interface vif2 external-ids:iface-id=ls2-lp1 \
4566 options:tx_pcap=hv1/vif2-tx.pcap \
4567 options:rxq_pcap=hv1/vif2-rx.pcap \
4571 # Allow some time for ovn-northd and ovn-controller to catch up.
4572 # XXX This should be more systematic.
4577 printf "%02x%02x%02x%02x" "$@"
4582 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4584 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4585 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4586 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4587 # provided, then it should be the ip and icmp checksums of the packet
4588 # responded; otherwise, no reply is expected.
4589 # In the absence of an ip checksum calculation helpers, this relies
4590 # on the caller to provide the checksums for the ip and icmp headers.
4591 # XXX This should be more systematic.
4593 # INPORT is an lport number, e.g. 11 for vif11.
4594 # ETH_SRC and ETH_DST are each 12 hex digits.
4595 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4596 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4597 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4598 test_ipv4_icmp_request() {
4599 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4600 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4601 shift; shift; shift; shift; shift; shift; shift
4604 # Use ttl to exercise section 4.2.2.9 of RFC1812
4608 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4609 local icmp_type_code_request=0800
4610 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4611 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4613 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4614 if test X$exp_icmp_chksum != X; then
4615 # Expect to receive the reply, if any. In same port where packet was sent.
4616 # Note: src and dst fields are expected to be reversed.
4617 local icmp_type_code_response=0000
4618 local reply_icmp_ttl=fe
4619 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4620 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4621 echo $reply >> vif$inport.expected
4625 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4626 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4627 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4628 l1_ip=$(ip_to_hex 192 168 1 2)
4629 l2_ip=$(ip_to_hex 172 16 1 2)
4631 # Ping router ip address that is on same subnet as the logical port
4632 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4633 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4635 # Ping router ip address that is on the other side of the logical ports
4636 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4637 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4639 echo "---------NB dump-----"
4641 echo "---------------------"
4642 ovn-nbctl list logical_router
4643 echo "---------------------"
4644 ovn-nbctl list logical_router_port
4645 echo "---------------------"
4647 echo "---------SB dump-----"
4648 ovn-sbctl list datapath_binding
4649 echo "---------------------"
4650 ovn-sbctl list logical_flow
4651 echo "---------------------"
4653 echo "------ hv1 dump ----------"
4654 as hv1 ovs-ofctl dump-flows br-int
4656 # Now check the packets actually received against the ones expected.
4657 for inport in 1 2; do
4658 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4665 # 1 hypervisor, 1 port
4666 # make sure that the port state is properly set to up and back down
4667 # when created and deleted.
4668 AT_SETUP([ovn -- port state up and down])
4671 ovn-nbctl ls-add ls1
4672 ovn-nbctl lsp-add ls1 lp1
4673 ovn-nbctl lsp-set-addresses lp1 unknown
4677 as hv1 ovs-vsctl add-br br-phys
4678 as hv1 ovn_attach n1 br-phys 192.168.0.1
4680 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4681 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4683 as hv1 ovs-vsctl del-port br-int vif1
4684 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4690 # 1 hypervisor, 1 port
4691 # make sure that the OF rules created to support a datapath are added/cleared
4692 # when logical switch is created and removed.
4693 AT_SETUP([ovn -- datapath rules added/removed])
4694 AT_KEYWORDS([cleanup])
4699 as hv1 ovs-vsctl add-br br-phys
4700 as hv1 ovn_attach n1 br-phys 192.168.0.1
4702 # This shell function checks if OF rules in br-int have clauses
4703 # related to OVN datapaths. The caller determines if it should find
4704 # a match in the output, or not.
4706 # EXPECT_DATAPATH param determines whether flows that refer to
4707 # datapath to should be present or not. 0 means
4708 # they should not be.
4709 # STAGE_INFO param is a simple string to help identify the stage
4710 # in the test when this function was invoked.
4711 test_datapath_in_of_rules() {
4712 local expect_datapath=$1 stage_info=$2
4713 echo "------ ovn-nbctl show ${stage_info} ------"
4715 echo "------ ovn-sbctl show ${stage_info} ------"
4717 echo "------ OF rules ${stage_info} ------"
4718 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4719 # if there is a datapath mentioned in the output, check for the
4720 # magic keyword that represents one, based on the exit status of
4722 if test $expect_datapath != 0; then
4723 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4725 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4729 test_datapath_in_of_rules 0 "before ls+port create"
4731 ovn-nbctl ls-add ls1
4732 ovn-nbctl lsp-add ls1 lp1
4733 ovn-nbctl lsp-set-addresses lp1 unknown
4735 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4736 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4738 test_datapath_in_of_rules 1 "after port is bound"
4740 as hv1 ovs-vsctl del-port br-int vif1
4741 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4743 ovn-nbctl lsp-set-addresses lp1
4744 ovn-nbctl lsp-del lp1
4745 ovn-nbctl ls-del ls1
4747 # wait for earlier changes to take effect
4748 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4750 # ensure OF rules are no longer present. There used to be a bug here.
4751 test_datapath_in_of_rules 0 "after lport+ls removal"
4757 AT_SETUP([ovn -- nd_na ])
4758 AT_SKIP_IF([test $HAVE_PYTHON = no])
4761 #TODO: since patch port for IPv6 logical router port is not ready not,
4762 # so we are not going to test vifs on different lswitches cases. Try
4763 # to update for that once relevant stuff implemented.
4765 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4766 # with. NS packet we test, from one VIF for another VIF, will be replied
4767 # by local ovn-controller, but not by target VIF.
4769 # Create hypervisors and logical switch lsw0.
4770 ovn-nbctl ls-add lsw0
4774 ovs-vsctl add-br br-phys
4775 ovn_attach n1 br-phys 192.168.0.2
4777 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4778 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
4779 ovn-nbctl lsp-add lsw0 lp1
4780 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4781 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"
4783 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4784 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
4785 ovn-nbctl lsp-add lsw0 lp2
4786 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4787 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"
4789 # Add ACL rule for ICMPv6 on lsw0
4790 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4791 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4792 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4794 # Allow some time for ovn-northd and ovn-controller to catch up.
4795 # XXX This should be more systematic.
4798 # Given the name of a logical port, prints the name of the hypervisor
4799 # on which it is located.
4807 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4808 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4809 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4810 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4811 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4813 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4814 echo $na_packet >> 1.expected
4816 echo "------ hv1 dump ------"
4817 as hv1 ovs-vsctl show
4818 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4819 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4822 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4829 AT_SETUP([ovn -- address sets modification/removal smoke test])
4836 ovs-vsctl add-br br-phys
4837 ovn_attach n1 br-phys 192.168.0.1
4839 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4840 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4841 ovn-nbctl destroy Address_Set $row
4845 # A bug previously existed in the address set support code
4846 # that caused ovn-controller to crash after an address set
4847 # was updated and then removed. This test case ensures
4848 # that ovn-controller is at least still running after
4849 # creating, updating, and deleting an address set.
4850 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4856 AT_SETUP([ovn -- ipam])
4857 AT_SKIP_IF([test $HAVE_PYTHON = no])
4860 # Add a port to a switch that does not have a subnet set, then set the
4861 # subnet which should result in an address being allocated for the port.
4862 ovn-nbctl ls-add sw0
4863 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4864 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4865 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4866 ["0a:00:00:00:00:01 192.168.1.2"
4869 # Add 9 more ports to sw0, addresses should all be unique.
4870 for n in `seq 1 9`; do
4871 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4873 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4874 ["0a:00:00:00:00:02 192.168.1.3"
4876 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4877 ["0a:00:00:00:00:03 192.168.1.4"
4879 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4880 ["0a:00:00:00:00:04 192.168.1.5"
4882 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4883 ["0a:00:00:00:00:05 192.168.1.6"
4885 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4886 ["0a:00:00:00:00:06 192.168.1.7"
4888 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4889 ["0a:00:00:00:00:07 192.168.1.8"
4891 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4892 ["0a:00:00:00:00:08 192.168.1.9"
4894 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4895 ["0a:00:00:00:00:09 192.168.1.10"
4897 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4898 ["0a:00:00:00:00:0a 192.168.1.11"
4901 # Trying similar tests with a second switch. MAC addresses should be unique
4902 # across both switches but IP's only need to be unique within the same switch.
4903 ovn-nbctl ls-add sw1
4904 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4905 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4906 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4907 ["0a:00:00:00:00:0b 192.168.1.2"
4910 for n in `seq 11 19`; do
4911 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4913 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4914 ["0a:00:00:00:00:0c 192.168.1.3"
4916 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4917 ["0a:00:00:00:00:0d 192.168.1.4"
4919 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4920 ["0a:00:00:00:00:0e 192.168.1.5"
4922 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4923 ["0a:00:00:00:00:0f 192.168.1.6"
4925 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4926 ["0a:00:00:00:00:10 192.168.1.7"
4928 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4929 ["0a:00:00:00:00:11 192.168.1.8"
4931 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4932 ["0a:00:00:00:00:12 192.168.1.9"
4934 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4935 ["0a:00:00:00:00:13 192.168.1.10"
4937 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4938 ["0a:00:00:00:00:14 192.168.1.11"
4941 # Change a port's address to test for multiple ip's for a single address entry
4942 # and addresses set by the user.
4943 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4944 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4945 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4946 ["0a:00:00:00:00:16 192.168.1.13"
4949 # Test for logical router port address management.
4950 ovn-nbctl create Logical_Router name=R1
4951 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4952 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4953 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4954 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4955 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4956 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4957 ["0a:00:00:00:00:18 192.168.1.15"
4960 # Test for address reuse after logical port is deleted.
4961 ovn-nbctl lsp-del p0
4962 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4963 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4964 ["0a:00:00:00:00:19 192.168.1.2"
4967 # Test for multiple addresses to one logical port.
4968 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4969 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
4970 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
4971 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4972 ["0a:00:00:00:00:1c 192.168.1.16"
4975 # Test for exhausting subnet address space.
4976 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
4977 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
4978 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4979 ["0a:00:00:00:00:1d 172.16.1.2"
4982 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
4983 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4984 ["0a:00:00:00:00:1e"
4987 # Test that address management does not add duplicate MAC for lsp/lrp peers.
4988 ovn-nbctl create Logical_Router name=R2
4989 ovn-nbctl ls-add sw3
4990 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4992 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4993 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4994 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4995 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
4996 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
4997 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4998 ["0a:00:00:00:00:20 192.168.1.17"
5001 # Test static MAC address with dynamically allocated IP
5002 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5003 "fe:dc:ba:98:76:54 dynamic"
5004 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5005 ["fe:dc:ba:98:76:54 192.168.1.18"
5008 # Update the static MAC address with dynamically allocated IP and check
5009 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5010 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5011 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5013 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5014 ["fe:dc:ba:98:76:55 192.168.1.18"
5017 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5018 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5019 ["fe:dc:ba:98:76:55 192.168.1.18"
5022 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5023 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5024 ["fe:dc:ba:98:76:56 192.168.1.18"
5028 # Test the exclude_ips from the IPAM list
5029 ovn-nbctl --wait=sb set logical_switch sw0 \
5030 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5032 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5034 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5035 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5036 ["0a:00:00:00:00:21 192.168.1.20"
5039 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5041 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5042 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5043 ["0a:00:00:00:00:22 192.168.1.22"
5046 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5048 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5049 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5050 ["0a:00:00:00:00:23 192.168.1.51"
5053 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5054 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5055 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5057 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5058 ["0a:00:00:00:00:24 192.168.1.19"
5061 # Set invalid data in exclude_ips list. It should be ignored.
5062 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5063 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5065 # 192.168.1.21 should be assigned as that's the next free one.
5066 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5067 ["0a:00:00:00:00:25 192.168.1.21"
5070 # Clear the dynamic addresses assignment request.
5071 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5072 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5077 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5078 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5081 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5082 # - aef0::800:ff:fe00:26 (EUI64)
5083 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5084 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5087 ovn-nbctl --wait=sb ls-add sw4
5088 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5089 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5092 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5093 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5096 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5097 "f0:00:00:00:10:12 dynamic"
5099 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5100 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5103 # Clear the other_config for sw4. No dynamic ip should be assigned.
5104 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5105 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5108 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5112 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5113 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5114 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5116 # Now p40 should be assigned with dynamic addresses.
5117 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5118 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5121 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5123 # p41 should not have IPv4 address (as the pool is exhausted).
5124 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5125 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5129 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5132 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5135 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5139 AT_SETUP([ovn -- ipam connectivity])
5140 AT_SKIP_IF([test $HAVE_PYTHON = no])
5145 # Test for a ping using dynamically allocated addresses.
5146 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5147 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5150 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5151 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5152 options:router-port=foo \
5153 -- lsp-set-addresses rp-foo router
5155 # Connect alice to R1
5156 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5157 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5158 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5160 # Create logical port foo1 in foo
5161 ovn-nbctl --wait=sb lsp-add foo foo1 \
5162 -- lsp-set-addresses foo1 "dynamic"
5163 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:00:00:01 192.168.1.2"'], [0])
5165 # Create logical port alice1 in alice
5166 ovn-nbctl --wait=sb lsp-add alice alice1 \
5167 -- lsp-set-addresses alice1 "dynamic"
5168 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5170 # Create logical port foo2 in foo
5171 ovn-nbctl --wait=sb lsp-add foo foo2 \
5172 -- lsp-set-addresses foo2 "dynamic"
5173 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5175 # Create a hypervisor and create OVS ports corresponding to logical ports.
5180 ovs-vsctl add-br br-phys
5181 ovn_attach n1 br-phys 192.168.0.1
5182 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5183 set interface hv1-vif1 external-ids:iface-id=foo1 \
5184 options:tx_pcap=hv1/vif1-tx.pcap \
5185 options:rxq_pcap=hv1/vif1-rx.pcap \
5188 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5189 set interface hv1-vif2 external-ids:iface-id=foo2 \
5190 options:tx_pcap=hv1/vif2-tx.pcap \
5191 options:rxq_pcap=hv1/vif2-rx.pcap \
5194 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5195 set interface hv1-vif3 external-ids:iface-id=alice1 \
5196 options:tx_pcap=hv1/vif3-tx.pcap \
5197 options:rxq_pcap=hv1/vif3-rx.pcap \
5200 # Allow some time for ovn-northd and ovn-controller to catch up.
5201 # XXX This should be more systematic.
5205 printf "%02x%02x%02x%02x" "$@"
5208 # Send ip packets between foo1 and foo2
5209 src_mac="0a0000000001"
5210 dst_mac="0a0000000003"
5211 src_ip=`ip_to_hex 192 168 1 2`
5212 dst_ip=`ip_to_hex 192 168 1 3`
5213 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5214 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5216 # Send ip packets between foo1 and alice1
5217 src_mac="0a0000000001"
5218 dst_mac="000000010203"
5219 src_ip=`ip_to_hex 192 168 1 2`
5220 dst_ip=`ip_to_hex 192 168 2 2`
5221 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5222 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5224 echo "---------NB dump-----"
5226 echo "---------------------"
5227 ovn-nbctl list logical_router
5228 echo "---------------------"
5229 ovn-nbctl list logical_router_port
5230 echo "---------------------"
5232 echo "---------SB dump-----"
5233 ovn-sbctl list datapath_binding
5234 echo "---------------------"
5235 ovn-sbctl list port_binding
5236 echo "---------------------"
5238 echo "------ hv1 dump ----------"
5239 as hv1 ovs-ofctl dump-flows br-int
5241 # Packet to Expect at foo2
5242 src_mac="0a0000000001"
5243 dst_mac="0a0000000003"
5244 src_ip=`ip_to_hex 192 168 1 2`
5245 dst_ip=`ip_to_hex 192 168 1 3`
5246 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5248 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5249 echo $expected > expout
5250 AT_CHECK([cat received1.packets], [0], [expout])
5252 # Packet to Expect at alice1
5253 src_mac="000000010204"
5254 dst_mac="0a0000000002"
5255 src_ip=`ip_to_hex 192 168 1 2`
5256 dst_ip=`ip_to_hex 192 168 2 2`
5257 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5259 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5260 echo $expected > expout
5261 AT_CHECK([cat received2.packets], [0], [expout])
5267 AT_SETUP([ovn -- ovs-vswitchd restart])
5268 AT_KEYWORDS([vswitchd])
5269 AT_SKIP_IF([test $HAVE_PYTHON = no])
5272 ovn-nbctl ls-add ls1
5274 ovn-nbctl lsp-add ls1 ls1-lp1 \
5275 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5277 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5283 ovs-vsctl add-br br-phys
5284 ovn_attach n1 br-phys 192.168.0.1
5285 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5286 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5287 options:tx_pcap=hv1/vif1-tx.pcap \
5288 options:rxq_pcap=hv1/vif1-rx.pcap \
5294 as hv1 ovs-vsctl show
5296 echo "---------------------"
5297 ovn-sbctl dump-flows
5298 echo "---------------------"
5300 echo "------ hv1 dump ----------"
5301 as hv1 ovs-ofctl dump-flows br-int
5302 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5304 echo "Total flows before vswitchd restart = " $total_flows
5306 # Code taken from ovs-save utility
5308 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5309 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5310 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5311 echo "EOF" >> restore_flows.sh
5314 restart_vswitchd () {
5317 if test $restore_flows = true; then
5322 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5324 if test $restore_flows = true; then
5326 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5330 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5331 ovs-ofctl dump-flows br-int
5333 if test $restore_flows = true; then
5334 sh ./restore_flows.sh
5335 echo "Flows after restore"
5337 ovs-ofctl dump-flows br-int
5338 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5339 flow-restore-wait="true"
5343 # Save the flows, restart vswitchd and restore the flows
5344 restart_vswitchd true
5346 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5347 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5348 test "${total_flows}" = "${total_flows_after_restart}"
5351 # Restart vswitchd without restoring
5352 restart_vswitchd false
5354 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5355 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5356 test "${total_flows}" = "${total_flows_after_restart}"
5362 AT_SETUP([ovn -- send arp for nexthop])
5363 AT_SKIP_IF([test $HAVE_PYTHON = no])
5366 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5368 # Create logical switches
5369 ovn-nbctl ls-add ls1
5370 ovn-nbctl ls-add ls2
5373 ovn-nbctl create Logical_Router name=lr0
5375 # Add router ls1p1 port to gateway router
5376 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5377 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5378 type=router options:router-port=lrp-ls1lp1 \
5379 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5381 # Add router ls2p2 port to gateway router
5382 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5383 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5384 type=router options:router-port=lrp-ls2lp1 \
5385 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5387 # Set default gateway (nexthop) to 192.168.1.254
5388 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5390 # Create logical port ls1lp2 in ls1
5391 ovn-nbctl lsp-add ls1 ls1lp2 \
5392 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5394 # Create logical port ls2lp2 in ls2
5395 ovn-nbctl lsp-add ls2 ls2lp2 \
5396 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5401 ovs-vsctl add-br br-phys
5402 ovn_attach n1 br-phys 192.168.0.1
5403 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5404 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5405 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5406 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5408 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5409 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5410 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5411 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5414 # Allow some time for ovn-northd and ovn-controller to catch up.
5415 # XXX This should be more systematic.
5418 echo "---------NB dump-----"
5420 echo "---------------------"
5421 ovn-nbctl list logical_router
5422 echo "---------------------"
5423 ovn-nbctl list logical_router_port
5424 echo "---------------------"
5426 echo "---------SB dump-----"
5427 ovn-sbctl list datapath_binding
5428 echo "---------------------"
5429 ovn-sbctl list port_binding
5430 echo "---------------------"
5431 ovn-sbctl dump-flows
5432 echo "---------------------"
5433 ovn-sbctl list chassis
5434 ovn-sbctl list encap
5435 echo "---------------------"
5437 echo "------Flows dump-----"
5439 ovs-ofctl dump-flows
5440 echo "---------------------"
5443 printf "%02x%02x%02x%02x" "$@"
5446 src_mac="f00000000003"
5447 dst_mac="f00000000001"
5448 src_ip=`ip_to_hex 192 168 0 2`
5449 dst_ip=`ip_to_hex 8 8 8 8`
5450 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5452 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5453 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5456 sed 's/\(00\)\{1,\}$//'
5459 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5462 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5463 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5464 echo $expected > expout
5465 AT_CHECK([cat packets], [0], [expout])
5472 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5473 AT_SKIP_IF([test $HAVE_PYTHON = no])
5475 # Create logical switch
5476 ovn-nbctl ls-add ls0
5477 # Create gateway router
5478 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5479 # Add router port to gateway router
5480 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5481 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5482 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5483 # Add nat-address option
5484 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5493 ovn_attach n1 br-phys 192.168.0.1
5495 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5496 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])
5498 # Create a localnet port.
5499 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5500 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5501 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5502 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5505 # Wait for packet to be received.
5506 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5508 sed 's/\(00\)\{1,\}$//'
5510 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5511 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5512 echo $expected > expout
5513 AT_CHECK([sort packets], [0], [expout])
5520 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5521 AT_SKIP_IF([test $HAVE_PYTHON = no])
5523 # Create logical switch
5524 ovn-nbctl ls-add ls0
5525 # Create gateway router
5526 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5527 # Add router port to gateway router
5528 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5529 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5530 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5531 # Add nat-address option
5532 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5534 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5535 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5536 # Add load balancers
5537 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5538 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5539 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5540 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5549 ovn_attach n1 br-phys 192.168.0.1
5551 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5552 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])
5554 # Create a localnet port.
5555 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5556 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5557 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5558 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5561 # Wait for packet to be received.
5562 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5564 sed 's/\(00\)\{1,\}$//'
5566 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5567 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5568 echo $expected > expout
5569 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5570 echo $expected >> expout
5571 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5572 echo $expected >> expout
5573 AT_CHECK([sort packets], [0], [expout])
5580 AT_SETUP([ovn -- delete mac bindings])
5585 ovs-vsctl -- add-br br-phys
5586 ovn_attach n1 br-phys 192.168.0.1
5587 # Create logical switch ls0
5588 ovn-nbctl ls-add ls0
5589 # Create ports lp0, lp1 in ls0
5590 ovn-nbctl lsp-add ls0 lp0
5591 ovn-nbctl lsp-add ls0 lp1
5592 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5593 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5594 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5595 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5596 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5597 ovn-sbctl find MAC_Binding
5598 # Delete port lp0 and check that its MAC_Binding is deleted.
5599 ovn-nbctl lsp-del lp0
5600 ovn-sbctl find MAC_Binding
5601 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5602 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5603 ovn-nbctl ls-del ls0
5604 ovn-sbctl find MAC_Binding
5605 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5611 AT_SETUP([ovn -- conntrack zone allocation])
5612 AT_SKIP_IF([test $HAVE_PYTHON = no])
5616 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5617 # connected to a router R1.
5618 # foo has foo1 to act as a client.
5619 # bar has bar1, bar2, bar3 to act as servers.
5625 ovs-vsctl add-br br-phys
5626 ovn_attach n1 br-phys 192.168.0.1
5627 for i in foo1 bar1 bar2 bar3; do
5628 ovs-vsctl -- add-port br-int $i -- \
5629 set interface $i external-ids:iface-id=$i \
5630 options:tx_pcap=hv1/$i-tx.pcap \
5631 options:rxq_pcap=hv1/$i-rx.pcap
5634 ovn-nbctl create Logical_Router name=R1
5635 ovn-nbctl ls-add foo
5636 ovn-nbctl ls-add bar
5639 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5640 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5641 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5644 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5645 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5646 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5648 # Create logical port foo1 in foo
5649 ovn-nbctl lsp-add foo foo1 \
5650 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5652 # Create logical port bar1, bar2 and bar3 in bar
5653 for i in `seq 1 3`; do
5655 ovn-nbctl lsp-add bar bar$i \
5656 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5659 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5665 AT_SETUP([ovn -- tag allocation])
5668 AT_CHECK([ovn-nbctl ls-add ls0])
5669 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5670 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5671 AT_CHECK([ovn-nbctl ls-add ls1])
5673 dnl When a tag is provided, no allocation is done
5674 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5675 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5677 dnl The same 'tag' gets created in southbound database.
5678 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5679 logical_port="c0"], [0], [3
5682 dnl Allocate tags and see it getting created in both NB and SB
5683 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5684 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5686 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5687 logical_port="c1"], [0], [1
5690 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5691 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5693 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5694 logical_port="c2"], [0], [2
5696 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5697 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5699 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5700 logical_port="c3"], [0], [4
5703 dnl A different parent.
5704 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5705 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5707 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5708 logical_port="c4"], [0], [1
5711 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5712 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5714 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5715 logical_port="c5"], [0], [2
5718 dnl Delete a logical port and create a new one.
5719 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5720 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5721 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5723 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5724 logical_port="c6"], [0], [1
5727 dnl Restart northd to see that the same allocation remains.
5729 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5730 start_daemon ovn-northd \
5731 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5732 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5734 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5735 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5736 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5738 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5740 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5742 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5744 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5746 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5749 dnl Create a switch port with a tag that has already been allocated.
5750 dnl It should go through fine with a duplicate tag.
5751 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5752 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5754 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5755 logical_port="c7"], [0], [2
5757 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5760 AT_CHECK([ovn-nbctl ls-add ls2])
5761 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5762 dnl gets copied to 'tag'
5763 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5764 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5766 dnl The same 'tag' gets created in southbound database.
5767 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5768 logical_port="local0"], [0], [25
5770 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5771 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5772 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5773 dnl change the tag_request.
5774 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5775 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5780 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5782 ovn-nbctl ls-add lsw0
5787 ovs-vsctl add-br br-phys
5788 ovn_attach n1 br-phys 192.168.0.$i
5789 ovs-vsctl add-br br-eth0
5790 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5793 # Create a localnet port.
5794 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5795 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5796 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5797 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5801 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5802 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5803 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5804 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5805 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5806 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5807 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5808 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5809 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5811 # Bind the localvif1 to hv1.
5813 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5815 # On hv1, check that there are no flows outputting bcast to tunnel
5816 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5818 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5820 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5822 # Now bind vif2 on hv2.
5823 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5825 # At this point, the broadcast flow on vif2 should be deleted.
5826 # because, there is now a localnet vif bound (table=32 programming logic)
5827 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5829 # Verify that the local net patch port exists on hv2.
5830 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5832 # Now bind vif3 on hv2.
5833 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5835 # Verify that the local net patch port still exists on hv2
5836 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5839 AT_CHECK([ovn-nbctl lsp-del localvif2])
5841 # Verify that the local net patch port still exists on hv2,
5842 # because, localvif3 is still bound.
5843 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5845 OVN_CLEANUP([hv1],[hv2])
5850 AT_SETUP([ovn -- ACL logging])
5858 ovs-vsctl add-br br-phys
5859 ovn_attach n1 br-phys 192.168.0.1
5860 for i in lp1 lp2; do
5861 ovs-vsctl -- add-port br-int $i -- \
5862 set interface $i external-ids:iface-id=$i \
5863 options:tx_pcap=hv/$i-tx.pcap \
5864 options:rxq_pcap=hv/$i-rx.pcap
5867 lp1_mac="f0:00:00:00:00:01"
5868 lp1_ip="192.168.1.2"
5870 lp2_mac="f0:00:00:00:00:02"
5871 lp2_ip="192.168.1.3"
5873 ovn-nbctl ls-add lsw0
5874 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5875 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5876 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5877 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5878 ovn-nbctl --wait=sb sync
5880 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5881 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5883 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5884 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5886 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5887 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5889 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5890 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5892 ovn-sbctl dump-flows
5895 # Send packet that should be dropped without logging.
5896 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5897 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5898 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5899 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5901 # Send packet that should be dropped with logging.
5902 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5903 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5904 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5905 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5907 # Send packet that should be allowed without logging.
5908 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5909 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5910 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
5911 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5913 # Send packet that should be allowed with logging.
5914 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5915 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5916 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
5917 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5919 # Send packet that should allow related flows without logging.
5920 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5921 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5922 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
5923 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5925 # Send packet that should allow related flows with logging.
5926 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5927 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5928 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
5929 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5931 # Send packet that should be rejected without logging.
5932 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5933 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5934 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
5935 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5937 # Send packet that should be rejected with logging.
5938 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5939 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5940 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
5941 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5943 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
5945 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
5946 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
5947 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
5948 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
5949 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
5956 AT_SETUP([ovn -- DSCP marking check])
5960 ovn-nbctl ls-add lsw0
5961 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5962 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5963 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5964 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5965 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5966 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5967 ovn-nbctl --wait=sb sync
5971 ovs-vsctl add-br br-phys
5972 ovn_attach n1 br-phys 192.168.0.1
5973 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
5974 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
5976 AT_CAPTURE_FILE([trace])
5978 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5981 # Extracts nw_tos from the final flow from ofproto/trace output and prints
5982 # it on stdout. Prints "none" if no nw_tos was included.
5983 get_final_nw_tos() {
5984 if flow=$(grep '^Final flow:' stdout); then :; else
5985 # The output didn't have a final flow.
5989 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5998 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6000 # First check with ovn-trace for logical flows.
6001 echo "checking for tos $1"
6002 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6003 echo 'output("lp2");') > expout
6004 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])
6006 # Then re-check with ofproto/trace for a physical packet.
6007 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])
6008 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6013 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");
6015 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])
6016 AT_CHECK([get_final_nw_tos], [0], [none
6019 # check at L3 without dscp marking
6022 # Mark DSCP with a valid value
6023 qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
6026 # Update the DSCP marking
6027 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6030 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6033 # Disable DSCP marking
6034 ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
6040 AT_SETUP([ovn -- read-only sb db:ptcp access])
6041 AT_SKIP_IF([test $HAVE_PYTHON = no])
6044 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6046 # Add read-only remote to sb ovsdb-server
6048 [ovsdb-tool transact ovn-sb.db \
6049 ['["OVN_Southbound",
6051 "table": "SB_Global",
6053 "connections": ["set", [["named-uuid", "xyz"]]]}},
6055 "table": "Connection",
6057 "row": {"target": "ptcp:0:127.0.0.1",
6058 "read_only": true}}]']], [0], [ignore], [ignore])
6060 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6062 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6064 # read-only accesses should succeed
6065 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6066 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6068 # write access should fail
6069 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6070 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6073 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6076 AT_SETUP([ovn -- read-only sb db:pssl access])
6077 AT_SKIP_IF([test $HAVE_PYTHON = no])
6078 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6079 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6080 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6084 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6086 # Add read-only remote to sb ovsdb-server
6088 [ovsdb-tool transact ovn-sb.db \
6089 ['["OVN_Southbound",
6091 "table": "SB_Global",
6093 "connections": ["set", [["named-uuid", "xyz"]]]}},
6095 "table": "Connection",
6097 "row": {"target": "pssl:0:127.0.0.1",
6098 "read_only": true}}]']], [0], [ignore], [ignore])
6100 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6101 --remote=db:OVN_Southbound,SB_Global,connections \
6102 --private-key="$PKIDIR/testpki-privkey2.pem" \
6103 --certificate="$PKIDIR/testpki-cert2.pem" \
6104 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6107 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6109 # read-only accesses should succeed
6110 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6111 --private-key=$PKIDIR/testpki-privkey.pem \
6112 --certificate=$PKIDIR/testpki-cert.pem \
6113 --ca-cert=$PKIDIR/testpki-cacert.pem \
6114 list SB_Global], [0], [stdout], [ignore])
6115 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6116 --private-key=$PKIDIR/testpki-privkey.pem \
6117 --certificate=$PKIDIR/testpki-cert.pem \
6118 --ca-cert=$PKIDIR/testpki-cacert.pem \
6119 list Connection], [0], [stdout], [ignore])
6121 # write access should fail
6122 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6123 --private-key=$PKIDIR/testpki-privkey.pem \
6124 --certificate=$PKIDIR/testpki-cert.pem \
6125 --ca-cert=$PKIDIR/testpki-cacert.pem \
6126 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6127 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6130 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6133 AT_SETUP([ovn -- nb connection/ssl commands])
6134 AT_SKIP_IF([test $HAVE_PYTHON = no])
6135 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6136 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6137 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6141 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6143 # Start nb db server using db connection/ssl entries (unpopulated initially)
6144 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6145 --remote=db:OVN_Northbound,NB_Global,connections \
6146 --private-key=db:OVN_Northbound,SSL,private_key \
6147 --certificate=db:OVN_Northbound,SSL,certificate \
6148 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6151 # Populate SSL configuration entries in nb db
6153 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6154 $PKIDIR/testpki-cert.pem \
6155 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6157 # Populate a passive SSL connection in nb db
6158 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6160 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6162 # Verify SSL connetivity to nb db server
6163 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6164 --private-key=$PKIDIR/testpki-privkey.pem \
6165 --certificate=$PKIDIR/testpki-cert.pem \
6166 --ca-cert=$PKIDIR/testpki-cacert.pem \
6168 [0], [stdout], [ignore])
6169 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6170 --private-key=$PKIDIR/testpki-privkey.pem \
6171 --certificate=$PKIDIR/testpki-cert.pem \
6172 --ca-cert=$PKIDIR/testpki-cacert.pem \
6174 [0], [stdout], [ignore])
6175 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6176 --private-key=$PKIDIR/testpki-privkey.pem \
6177 --certificate=$PKIDIR/testpki-cert.pem \
6178 --ca-cert=$PKIDIR/testpki-cacert.pem \
6180 [0], [stdout], [ignore])
6182 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6185 AT_SETUP([ovn -- sb connection/ssl commands])
6186 AT_SKIP_IF([test $HAVE_PYTHON = no])
6187 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6188 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6189 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6193 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6195 # Start sb db server using db connection/ssl entries (unpopulated initially)
6196 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6197 --remote=db:OVN_Southbound,SB_Global,connections \
6198 --private-key=db:OVN_Southbound,SSL,private_key \
6199 --certificate=db:OVN_Southbound,SSL,certificate \
6200 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6203 # Populate SSL configuration entries in sb db
6205 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6206 $PKIDIR/testpki-cert.pem \
6207 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6209 # Populate a passive SSL connection in sb db
6210 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6212 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6214 # Verify SSL connetivity to sb db server
6215 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6216 --private-key=$PKIDIR/testpki-privkey.pem \
6217 --certificate=$PKIDIR/testpki-cert.pem \
6218 --ca-cert=$PKIDIR/testpki-cacert.pem \
6220 [0], [stdout], [ignore])
6221 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6222 --private-key=$PKIDIR/testpki-privkey.pem \
6223 --certificate=$PKIDIR/testpki-cert.pem \
6224 --ca-cert=$PKIDIR/testpki-cacert.pem \
6226 [0], [stdout], [ignore])
6227 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6228 --private-key=$PKIDIR/testpki-privkey.pem \
6229 --certificate=$PKIDIR/testpki-cert.pem \
6230 --ca-cert=$PKIDIR/testpki-cacert.pem \
6232 [0], [stdout], [ignore])
6234 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6237 AT_SETUP([ovn -- nested containers])
6241 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6244 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6245 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6248 ovn-nbctl ls-add mgmt
6249 ovn-nbctl ls-add foo
6250 ovn-nbctl ls-add bar
6252 # Connect mgmt to R1
6253 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6254 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6255 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6258 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6259 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6260 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6263 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6264 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6265 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6267 # "mgmt" has VM1 and VM2 connected
6268 ovn-nbctl lsp-add mgmt vm1 \
6269 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6271 ovn-nbctl lsp-add mgmt vm2 \
6272 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6274 # "foo1" and "foo2" are containers belonging to switch "foo"
6275 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6276 ovn-nbctl lsp-add foo foo1 vm1 1 \
6277 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6279 ovn-nbctl lsp-add foo foo2 vm2 2 \
6280 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6282 # "bar1" and "bar2" are containers belonging to switch "bar"
6283 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6284 ovn-nbctl lsp-add bar bar1 vm1 2 \
6285 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6287 ovn-nbctl lsp-add bar bar2 vm2 1 \
6288 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6290 # bar3 is a standalone VM belonging to switch "bar"
6291 ovn-nbctl lsp-add bar bar3 \
6292 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6294 # Create two hypervisor and create OVS ports corresponding to logical ports.
6299 ovs-vsctl add-br br-phys
6300 ovn_attach n1 br-phys 192.168.0.1
6301 ovs-vsctl -- add-port br-int vm1 -- \
6302 set interface vm1 external-ids:iface-id=vm1 \
6303 options:tx_pcap=hv1/vm1-tx.pcap \
6304 options:rxq_pcap=hv1/vm1-rx.pcap \
6307 ovs-vsctl -- add-port br-int bar3 -- \
6308 set interface bar3 external-ids:iface-id=bar3 \
6309 options:tx_pcap=hv1/bar3-tx.pcap \
6310 options:rxq_pcap=hv1/bar3-rx.pcap \
6315 ovs-vsctl add-br br-phys
6316 ovn_attach n1 br-phys 192.168.0.2
6317 ovs-vsctl -- add-port br-int vm2 -- \
6318 set interface vm2 external-ids:iface-id=vm2 \
6319 options:tx_pcap=hv2/vm2-tx.pcap \
6320 options:rxq_pcap=hv2/vm2-rx.pcap \
6323 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6324 # packets for ARP resolution (native tunneling doesn't queue packets
6325 # for ARP resolution).
6328 # Allow some time for ovn-northd and ovn-controller to catch up.
6329 # XXX This should be more systematic.
6333 printf "%02x%02x%02x%02x" "$@"
6336 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6337 # different VLAN tags).
6338 src_mac="f00000010205"
6339 dst_mac="f00000010206"
6340 src_ip=`ip_to_hex 192 168 1 2`
6341 dst_ip=`ip_to_hex 192 168 1 3`
6342 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6343 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6345 # expected packet at foo2
6346 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6347 echo $packet > expected
6348 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6350 # Send ip packets between foo1 and bar2 (different switch, different HV)
6351 src_mac="f00000010205"
6352 dst_mac="000000010203"
6353 src_ip=`ip_to_hex 192 168 1 2`
6354 dst_ip=`ip_to_hex 192 168 2 3`
6355 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6356 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6358 # expected packet at bar2
6359 src_mac="000000010204"
6360 dst_mac="f00000010208"
6361 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6362 echo $packet >> expected
6363 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6365 # Send ip packets between foo1 and bar1
6366 # (different switch, loopback to same vm but different tag)
6367 src_mac="f00000010205"
6368 dst_mac="000000010203"
6369 src_ip=`ip_to_hex 192 168 1 2`
6370 dst_ip=`ip_to_hex 192 168 2 2`
6371 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6372 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6374 # expected packet at bar1
6375 src_mac="000000010204"
6376 dst_mac="f00000010207"
6377 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6378 echo $packet > expected1
6379 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6381 # Send ip packets between bar1 and bar3
6382 # (same switch. But one is container and another is a standalone VM)
6383 src_mac="f00000010207"
6384 dst_mac="f00000010209"
6385 src_ip=`ip_to_hex 192 168 2 2`
6386 dst_ip=`ip_to_hex 192 168 2 3`
6387 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6388 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6390 # expected packet at bar3
6391 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6392 echo $packet > expected
6393 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6395 # Send ip packets between foo1 and vm1.
6396 (different switch, container to the VM hosting it.)
6397 src_mac="f00000010205"
6398 dst_mac="000000010203"
6399 src_ip=`ip_to_hex 192 168 1 2`
6400 dst_ip=`ip_to_hex 172 16 1 2`
6401 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6402 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6404 # expected packet at vm1
6405 src_mac="000000010202"
6406 dst_mac="f00000010203"
6407 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6408 echo $packet >> expected1
6409 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6411 # Send packets from vm1 to bar1.
6412 (different switch, A hosting VM to a container inside it)
6413 src_mac="f00000010203"
6414 dst_mac="000000010202"
6415 src_ip=`ip_to_hex 172 16 1 2`
6416 dst_ip=`ip_to_hex 192 168 2 2`
6417 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6418 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6420 # expected packet at vm1
6421 src_mac="000000010204"
6422 dst_mac="f00000010207"
6423 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6424 echo $packet >> expected1
6425 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6427 OVN_CLEANUP([hv1],[hv2])
6431 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6432 AT_SKIP_IF([test $HAVE_PYTHON = no])
6436 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6437 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6438 # (192.168.2.0/24) connected to it.
6440 # R2 and R3 are gateway routers.
6441 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6442 # connected to it. Note how both alice and bob have the same subnet behind it.
6443 # We are trying to simulate external network via those 2 switches. In real
6444 # world the switch ports of these switches will have addresses set as "unknown"
6445 # to make them learning switches. Or those switches will be "localnet" ones.
6447 # Create three hypervisors and create OVS ports corresponding to logical ports.
6452 ovs-vsctl add-br br-phys
6453 ovn_attach n1 br-phys 192.168.0.1
6454 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6455 set interface hv1-vif1 external-ids:iface-id=foo1 \
6456 options:tx_pcap=hv1/vif1-tx.pcap \
6457 options:rxq_pcap=hv1/vif1-rx.pcap \
6460 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6461 set interface hv1-vif2 external-ids:iface-id=bar1 \
6462 options:tx_pcap=hv1/vif2-tx.pcap \
6463 options:rxq_pcap=hv1/vif2-rx.pcap \
6468 ovs-vsctl add-br br-phys
6469 ovn_attach n1 br-phys 192.168.0.2
6470 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6471 set interface hv2-vif1 external-ids:iface-id=alice1 \
6472 options:tx_pcap=hv2/vif1-tx.pcap \
6473 options:rxq_pcap=hv2/vif1-rx.pcap \
6478 ovs-vsctl add-br br-phys
6479 ovn_attach n1 br-phys 192.168.0.3
6480 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6481 set interface hv3-vif1 external-ids:iface-id=bob1 \
6482 options:tx_pcap=hv3/vif1-tx.pcap \
6483 options:rxq_pcap=hv3/vif1-rx.pcap \
6487 ovn-nbctl create Logical_Router name=R1
6488 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6489 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6491 ovn-nbctl ls-add foo
6492 ovn-nbctl ls-add bar
6493 ovn-nbctl ls-add alice
6494 ovn-nbctl ls-add bob
6495 ovn-nbctl ls-add join
6498 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6499 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6500 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6503 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6504 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6505 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6507 # Connect alice to R2
6508 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6509 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6510 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6513 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6514 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6515 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6517 # Connect R1 to join
6518 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6519 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6520 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6522 # Connect R2 to join
6523 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6524 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6525 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6527 # Connect R3 to join
6528 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6529 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6530 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6532 # Install static routes with source ip address as the policy for routing.
6533 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6534 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6535 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6537 # Install static routes with destination ip address as the policy for routing.
6538 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6540 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6542 # Create logical port foo1 in foo
6543 ovn-nbctl lsp-add foo foo1 \
6544 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6546 # Create logical port bar1 in bar
6547 ovn-nbctl lsp-add bar bar1 \
6548 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6550 # Create logical port alice1 in alice
6551 ovn-nbctl lsp-add alice alice1 \
6552 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6554 # Create logical port bob1 in bob
6555 ovn-nbctl lsp-add bob bob1 \
6556 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6558 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6559 # packets for ARP resolution (native tunneling doesn't queue packets
6560 # for ARP resolution).
6563 # Allow some time for ovn-northd and ovn-controller to catch up.
6564 # XXX This should be more systematic.
6568 printf "%02x%02x%02x%02x" "$@"
6571 sed 's/\(00\)\{1,\}$//'
6574 # Send ip packets between foo1 and bar1
6575 # (East-west traffic should flow normally)
6576 src_mac="f00000010203"
6577 dst_mac="000001010203"
6578 src_ip=`ip_to_hex 192 168 1 2`
6579 dst_ip=`ip_to_hex 192 168 2 2`
6580 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6581 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6583 # Send ip packets between foo1 and alice1
6584 src_mac="f00000010203"
6585 dst_mac="000001010203"
6586 src_ip=`ip_to_hex 192 168 1 2`
6587 dst_ip=`ip_to_hex 172 16 1 3`
6588 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6589 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6590 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6592 # Send ip packets between bar1 and bob1
6593 src_mac="f00000010204"
6594 dst_mac="000001010204"
6595 src_ip=`ip_to_hex 192 168 2 2`
6596 dst_ip=`ip_to_hex 172 16 1 4`
6597 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6598 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6599 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6601 # Packet to expect at bar1
6602 src_mac="000001010204"
6603 dst_mac="f00000010204"
6604 src_ip=`ip_to_hex 192 168 1 2`
6605 dst_ip=`ip_to_hex 192 168 2 2`
6606 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6607 echo $expected > expected
6608 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6610 # Packet to Expect at alice1
6611 src_mac="000002010203"
6612 dst_mac="f00000010205"
6613 src_ip=`ip_to_hex 192 168 1 2`
6614 dst_ip=`ip_to_hex 172 16 1 3`
6615 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6616 echo $expected > expected
6617 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6619 # Packet to Expect at bob1
6620 src_mac="000003010203"
6621 dst_mac="f00000010206"
6622 src_ip=`ip_to_hex 192 168 2 2`
6623 dst_ip=`ip_to_hex 172 16 1 4`
6624 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6625 echo $expected > expected
6626 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6628 for sim in hv1 hv2 hv3; do
6630 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6631 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6632 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6636 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6639 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6642 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6645 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6646 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6650 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6651 AT_SKIP_IF([test $HAVE_PYTHON = no])
6654 ovn-nbctl ls-add ls1
6656 ovn-nbctl lsp-add ls1 ls1-lp1 \
6657 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6659 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6661 ovn-nbctl lsp-add ls1 ls1-lp2 \
6662 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6664 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6666 DNS1=`ovn-nbctl create DNS records={}`
6667 DNS2=`ovn-nbctl create DNS records={}`
6669 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6670 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6671 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6673 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6679 ovs-vsctl add-br br-phys
6680 ovn_attach n1 br-phys 192.168.0.1
6681 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6682 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6683 options:tx_pcap=hv1/vif1-tx.pcap \
6684 options:rxq_pcap=hv1/vif1-rx.pcap \
6687 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6688 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6689 options:tx_pcap=hv1/vif2-tx.pcap \
6690 options:rxq_pcap=hv1/vif2-rx.pcap \
6695 as hv1 ovs-vsctl show
6697 echo "*************************"
6699 echo "*************************"
6702 printf "%02x%02x%02x%02x" "$@"
6708 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6709 options:rxq_pcap=dummy-rx.pcap
6710 rm -f ${pcap_file}*.pcap
6711 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6712 options:rxq_pcap=${pcap_file}-rx.pcap
6715 # set_dns_params host_name
6716 # Sets the dns_req_data and dns_resp_data
6725 query_name=03766d31036f766e036f726700
6726 # IPv4 address - 10.0.0.4
6727 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6731 query_name=03766d32036f766e036f726700
6732 # IPv4 address - 10.0.0.6
6733 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6734 # IPv4 address - 20.0.0.4
6735 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6740 query_name=03766d33036f766e036f726700
6741 # IPv4 address - 40.0.0.4
6742 expected_dns_answer=${query_name}00010001${ttl}000428000004
6746 query_name=03766d31036f766e036f726700
6747 # IPv6 address - aef0::4
6749 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6753 query_name=03766d31036f766e036f726700
6756 # IPv4 address - 10.0.0.4
6757 # IPv6 address - aef0::4
6758 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6759 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6760 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6764 query_name=03766d31036f766e036f726700
6765 # IPv6 address - aef0::4
6773 local dns_req_header=010201200001000000000000
6774 local dns_resp_header=010281200001${an_count}00000000
6775 dns_req_data=${dns_req_header}${query_name}${type}0001
6776 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6779 # This shell function sends a DNS request packet
6780 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6782 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6783 local dns_query_data=$7
6784 shift; shift; shift; shift; shift; shift; shift;
6785 # Packet size => IPv4 header (20) + UDP header (8) +
6786 # DNS data (header + query)
6787 ip_len=`expr 28 + ${#dns_query_data} / 2`
6788 udp_len=`expr $ip_len - 20`
6789 ip_len=$(printf "%x" $ip_len)
6790 udp_len=$(printf "%x" $udp_len)
6791 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6792 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6794 request=${request}${dns_query_data}
6796 if test $dns_reply != 0; then
6798 ip_len=`expr 28 + ${#dns_reply} / 2`
6799 udp_len=`expr $ip_len - 20`
6800 ip_len=$(printf "%x" $ip_len)
6801 udp_len=$(printf "%x" $udp_len)
6802 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6803 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6804 echo $reply >> $inport.expected
6807 echo $request >> $outport.expected
6810 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6813 AT_CAPTURE_FILE([ofctl_monitor0.log])
6814 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6815 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6818 src_ip=`ip_to_hex 10 0 0 4`
6819 dst_ip=`ip_to_hex 10 0 0 1`
6821 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6823 # NXT_RESUMEs should be 1.
6824 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6826 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6827 cat 1.expected | cut -c -48 > expout
6828 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6829 # Skipping the IPv4 checksum.
6830 cat 1.expected | cut -c 53- > expout
6831 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6833 reset_pcap_file hv1-vif1 hv1/vif1
6834 reset_pcap_file hv1-vif2 hv1/vif2
6839 src_ip=`ip_to_hex 10 0 0 6`
6840 dst_ip=`ip_to_hex 10 0 0 1`
6842 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6844 # NXT_RESUMEs should be 2.
6845 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6847 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6848 cat 2.expected | cut -c -48 > expout
6849 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6850 # Skipping the IPv4 checksum.
6851 cat 2.expected | cut -c 53- > expout
6852 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6854 reset_pcap_file hv1-vif1 hv1/vif1
6855 reset_pcap_file hv1-vif2 hv1/vif2
6859 # Clear the query name options for ls1-lp2
6860 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
6863 src_ip=`ip_to_hex 10 0 0 4`
6864 dst_ip=`ip_to_hex 10 0 0 1`
6866 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
6868 # NXT_RESUMEs should be 3.
6869 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6871 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6872 AT_CHECK([cat 1.packets], [0], [])
6874 reset_pcap_file hv1-vif1 hv1/vif1
6875 reset_pcap_file hv1-vif2 hv1/vif2
6879 # Clear the query name for ls1-lp1
6880 # Since ls1 has no query names configued,
6881 # ovn-northd should not add the DNS flows.
6882 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
6885 src_ip=`ip_to_hex 10 0 0 6`
6886 dst_ip=`ip_to_hex 10 0 0 1`
6888 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6890 # NXT_RESUMEs should be 3 only.
6891 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6893 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6894 AT_CHECK([cat 2.packets], [0], [])
6896 reset_pcap_file hv1-vif1 hv1/vif1
6897 reset_pcap_file hv1-vif2 hv1/vif2
6901 # Test IPv6 (AAAA records) using IPv4 packet.
6902 # Add back the DNS options for ls1-lp1.
6903 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6905 set_dns_params vm1_ipv6_only
6906 src_ip=`ip_to_hex 10 0 0 6`
6907 dst_ip=`ip_to_hex 10 0 0 1`
6909 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6911 # NXT_RESUMEs should be 4.
6912 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6914 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6915 cat 2.expected | cut -c -48 > expout
6916 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6917 # Skipping the IPv4 checksum.
6918 cat 2.expected | cut -c 53- > expout
6919 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6921 reset_pcap_file hv1-vif1 hv1/vif1
6922 reset_pcap_file hv1-vif2 hv1/vif2
6926 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
6927 set_dns_params vm1_ipv4_v6
6928 src_ip=`ip_to_hex 10 0 0 6`
6929 dst_ip=`ip_to_hex 10 0 0 1`
6931 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6933 # NXT_RESUMEs should be 5.
6934 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6936 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6937 cat 2.expected | cut -c -48 > expout
6938 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6939 # Skipping the IPv4 checksum.
6940 cat 2.expected | cut -c 53- > expout
6941 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6943 reset_pcap_file hv1-vif1 hv1/vif1
6944 reset_pcap_file hv1-vif2 hv1/vif2
6949 set_dns_params vm1_invalid_type
6950 src_ip=`ip_to_hex 10 0 0 6`
6951 dst_ip=`ip_to_hex 10 0 0 1`
6953 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6955 # NXT_RESUMEs should be 6.
6956 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6958 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6959 AT_CHECK([cat 2.packets], [0], [])
6961 reset_pcap_file hv1-vif1 hv1/vif1
6962 reset_pcap_file hv1-vif2 hv1/vif2
6966 # Incomplete DNS packet.
6967 set_dns_params vm1_incomplete
6968 src_ip=`ip_to_hex 10 0 0 6`
6969 dst_ip=`ip_to_hex 10 0 0 1`
6971 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6973 # NXT_RESUMEs should be 7.
6974 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6976 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6977 AT_CHECK([cat 2.packets], [0], [])
6979 reset_pcap_file hv1-vif1 hv1/vif1
6980 reset_pcap_file hv1-vif2 hv1/vif2
6984 # Add one more DNS record to the ls1.
6985 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
6988 src_ip=`ip_to_hex 10 0 0 4`
6989 dst_ip=`ip_to_hex 10 0 0 1`
6991 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6993 # NXT_RESUMEs should be 8.
6994 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6996 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6997 cat 1.expected | cut -c -48 > expout
6998 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6999 # Skipping the IPv4 checksum.
7000 cat 1.expected | cut -c 53- > expout
7001 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7003 reset_pcap_file hv1-vif1 hv1/vif1
7004 reset_pcap_file hv1-vif2 hv1/vif2
7009 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7010 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7011 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7014 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7017 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7020 OVS_APP_EXIT_AND_WAIT([ovn-northd])
7023 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7024 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7027 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
7028 AT_SKIP_IF([test $HAVE_PYTHON = no])
7035 ovs-vsctl add-br br-phys
7036 ovn_attach n1 br-phys 192.168.0.1
7037 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7038 set interface hv1-vif1 external-ids:iface-id=foo1 \
7039 options:tx_pcap=hv1/vif1-tx.pcap \
7040 options:rxq_pcap=hv1/vif1-rx.pcap \
7045 ovs-vsctl add-br br-phys
7046 ovn_attach n1 br-phys 192.168.0.2
7050 ovs-vsctl add-br br-phys
7051 ovn_attach n1 br-phys 192.168.0.4
7055 ovs-vsctl add-br br-phys
7056 ovn_attach n1 br-phys 192.168.0.3
7057 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7058 set interface ext1-vif1 external-ids:iface-id=outside1 \
7059 options:tx_pcap=ext1/vif1-tx.pcap \
7060 options:rxq_pcap=ext1/vif1-rx.pcap \
7063 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7064 # packets for ARP resolution (native tunneling doesn't queue packets
7065 # for ARP resolution).
7068 ovn-nbctl create Logical_Router name=R1
7070 ovn-nbctl ls-add foo
7071 ovn-nbctl ls-add alice
7072 ovn-nbctl ls-add outside
7075 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7076 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7077 type=router options:router-port=foo \
7078 -- lsp-set-addresses rp-foo router
7080 # Connect alice to R1 as distributed router gateway port on gw1
7081 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7084 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7087 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7090 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7092 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7093 type=router options:router-port=alice \
7094 -- lsp-set-addresses rp-alice router
7096 # Create logical port foo1 in foo
7097 ovn-nbctl lsp-add foo foo1 \
7098 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7100 # Create logical port outside1 in outside
7101 ovn-nbctl lsp-add outside outside1 \
7102 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7104 # Create localnet port in alice
7105 ovn-nbctl lsp-add alice ln-alice
7106 ovn-nbctl lsp-set-addresses ln-alice unknown
7107 ovn-nbctl lsp-set-type ln-alice localnet
7108 ovn-nbctl lsp-set-options ln-alice network_name=phys
7110 # Create localnet port in outside
7111 ovn-nbctl lsp-add outside ln-outside
7112 ovn-nbctl lsp-set-addresses ln-outside unknown
7113 ovn-nbctl lsp-set-type ln-outside localnet
7114 ovn-nbctl lsp-set-options ln-outside network_name=phys
7116 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7117 # mapping to the external network, is the one generating packets
7118 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7119 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7120 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7122 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7124 # Allow some time for ovn-northd and ovn-controller to catch up.
7125 # XXX This should be more systematic.
7129 printf "%02x%02x%02x%02x" "$@"
7135 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7136 options:rxq_pcap=dummy-rx.pcap
7137 rm -f ${pcap_file}*.pcap
7138 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7139 options:rxq_pcap=${pcap_file}-rx.pcap
7147 # Send ip packet between foo1 and outside1
7148 src_mac="f00000010203" # foo1 mac
7149 dst_mac="000001010203" # rp-foo mac (internal router leg)
7150 src_ip=`ip_to_hex 192 168 1 2`
7151 dst_ip=`ip_to_hex 172 16 1 3`
7152 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7154 # ARP request packet to expect at outside1
7155 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7157 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7159 # Send ARP reply from outside1 back to the router
7160 # XXX: note, we could avoid this if we plug this port into a netns
7161 # and setup the IP address into the port, so the kernel would simply reply
7162 src_mac="000002010203"
7163 reply_mac="f00000010204"
7164 dst_ip=`ip_to_hex 172 16 1 3`
7165 src_ip=`ip_to_hex 172 16 1 1`
7166 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7168 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7170 # Packet to Expect at ext1 chassis, outside1 port
7171 src_mac="000002010203"
7172 dst_mac="f00000010204"
7173 src_ip=`ip_to_hex 192 168 1 2`
7174 dst_ip=`ip_to_hex 172 16 1 3`
7175 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7176 echo $expected > ext1-vif1.expected
7178 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7179 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7180 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7182 # Resend packet from foo1 to outside1
7183 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7187 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7188 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7189 AT_CHECK([grep $expected packets | sort], [0], [expout])
7190 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7191 AT_CHECK([grep $expected packets | sort], [0], [])
7194 test_ip_packet gw1 gw2
7196 ovn-nbctl --timeout=3 --wait=hv \
7197 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7200 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7203 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7205 test_ip_packet gw2 gw1
7207 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7210 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7211 AT_SKIP_IF([test $HAVE_PYTHON = no])
7218 ovs-vsctl add-br br-phys
7219 ovn_attach n1 br-phys 192.168.0.1
7220 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7221 set interface hv1-vif1 external-ids:iface-id=foo1 \
7222 options:tx_pcap=hv1/vif1-tx.pcap \
7223 options:rxq_pcap=hv1/vif1-rx.pcap \
7228 ovs-vsctl add-br br-phys
7229 ovn_attach n1 br-phys 192.168.0.2
7233 ovs-vsctl add-br br-phys
7234 ovn_attach n1 br-phys 192.168.0.4
7238 ovs-vsctl add-br br-phys
7239 ovn_attach n1 br-phys 192.168.0.3
7240 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7241 set interface ext1-vif1 external-ids:iface-id=outside1 \
7242 options:tx_pcap=ext1/vif1-tx.pcap \
7243 options:rxq_pcap=ext1/vif1-rx.pcap \
7246 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7247 # packets for ARP resolution (native tunneling doesn't queue packets
7248 # for ARP resolution).
7251 ovn-nbctl create Logical_Router name=R0
7252 ovn-nbctl create Logical_Router name=R1
7254 ovn-nbctl ls-add foo
7255 ovn-nbctl ls-add join
7256 ovn-nbctl ls-add alice
7257 ovn-nbctl ls-add outside
7260 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7261 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7262 type=router options:router-port=R0-foo \
7263 -- lsp-set-addresses foo-R0 router
7266 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7267 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7268 type=router options:router-port=R0-join \
7269 -- lsp-set-addresses join-R0 router
7272 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7273 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7274 type=router options:router-port=R1-join \
7275 -- lsp-set-addresses join-R1 router
7278 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7279 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7281 # Connect alice to R1 as distributed router gateway port on gw1
7282 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7285 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7288 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7291 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7293 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7294 type=router options:router-port=alice \
7295 -- lsp-set-addresses rp-alice router
7297 # Create logical port foo1 in foo
7298 ovn-nbctl lsp-add foo foo1 \
7299 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7301 # Create logical port outside1 in outside
7302 ovn-nbctl lsp-add outside outside1 \
7303 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7305 # Create localnet port in alice
7306 ovn-nbctl lsp-add alice ln-alice
7307 ovn-nbctl lsp-set-addresses ln-alice unknown
7308 ovn-nbctl lsp-set-type ln-alice localnet
7309 ovn-nbctl lsp-set-options ln-alice network_name=phys
7311 # Create localnet port in outside
7312 ovn-nbctl lsp-add outside ln-outside
7313 ovn-nbctl lsp-set-addresses ln-outside unknown
7314 ovn-nbctl lsp-set-type ln-outside localnet
7315 ovn-nbctl lsp-set-options ln-outside network_name=phys
7317 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7318 # mapping to the external network, is the one generating packets
7319 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7320 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7321 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7323 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7325 # Allow some time for ovn-northd and ovn-controller to catch up.
7326 # XXX This should be more systematic.
7330 printf "%02x%02x%02x%02x" "$@"
7336 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7337 options:rxq_pcap=dummy-rx.pcap
7338 rm -f ${pcap_file}*.pcap
7339 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7340 options:rxq_pcap=${pcap_file}-rx.pcap
7348 # Send ip packet between foo1 and outside1
7349 src_mac="f00000010203" # foo1 mac
7350 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7351 src_ip=`ip_to_hex 192 168 1 2`
7352 dst_ip=`ip_to_hex 172 16 1 3`
7353 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7355 # ARP request packet to expect at outside1
7356 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7358 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7360 # Send ARP reply from outside1 back to the router
7361 # XXX: note, we could avoid this if we plug this port into a netns
7362 # and setup the IP address into the port, so the kernel would simply reply
7363 src_mac="000002010203"
7364 reply_mac="f00000010204"
7365 dst_ip=`ip_to_hex 172 16 1 3`
7366 src_ip=`ip_to_hex 172 16 1 1`
7367 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7369 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7371 # Packet to Expect at ext1 chassis, outside1 port
7372 src_mac="000002010203"
7373 dst_mac="f00000010204"
7374 src_ip=`ip_to_hex 192 168 1 2`
7375 dst_ip=`ip_to_hex 172 16 1 3`
7376 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7377 echo $expected > ext1-vif1.expected
7379 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7380 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7381 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7383 # Resend packet from foo1 to outside1
7384 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7388 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7389 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7390 AT_CHECK([grep $expected packets | sort], [0], [expout])
7391 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7392 AT_CHECK([grep $expected packets | sort], [0], [])
7395 test_ip_packet gw1 gw2
7397 ovn-nbctl --timeout=3 --wait=hv \
7398 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7401 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7404 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7406 test_ip_packet gw2 gw1
7408 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7411 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7412 AT_SKIP_IF([test $HAVE_PYTHON = no])
7416 # One LR R1 that has switches foo (192.168.1.0/24) and
7417 # alice (172.16.1.0/24) connected to it. The logical port
7418 # between R1 and alice has a "redirect-chassis" specified,
7419 # i.e. it is the distributed router gateway port.
7420 # Switch alice also has a localnet port defined.
7421 # An additional switch outside has a localnet port and the
7422 # same subnet as alice (172.16.1.0/24).
7425 # Three hypervisors hv[123].
7426 # hv1 hosts vif foo1.
7427 # hv2 is the "redirect-chassis" that hosts the distributed
7428 # router gateway port.
7429 # hv3 hosts vif outside1.
7430 # In order to show that connectivity works only through hv2,
7431 # an initial round of tests is run without any bridge-mapping
7432 # defined for the localnet on hv2. These tests are expected
7434 # Subsequent tests are run after defining the bridge-mapping
7435 # for the localnet on hv2. These tests are expected to succeed.
7437 # Create three hypervisors and create OVS ports corresponding
7443 ovs-vsctl add-br br-phys
7444 ovn_attach n1 br-phys 192.168.0.1
7445 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7446 set interface hv1-vif1 external-ids:iface-id=foo1 \
7447 options:tx_pcap=hv1/vif1-tx.pcap \
7448 options:rxq_pcap=hv1/vif1-rx.pcap \
7453 ovs-vsctl add-br br-phys
7454 ovn_attach n1 br-phys 192.168.0.2
7458 ovs-vsctl add-br br-phys
7459 ovn_attach n1 br-phys 192.168.0.3
7460 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7461 set interface hv3-vif1 external-ids:iface-id=outside1 \
7462 options:tx_pcap=hv3/vif1-tx.pcap \
7463 options:rxq_pcap=hv3/vif1-rx.pcap \
7466 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7467 # packets for ARP resolution (native tunneling doesn't queue packets
7468 # for ARP resolution).
7471 ovn-nbctl create Logical_Router name=R1
7473 ovn-nbctl ls-add foo
7474 ovn-nbctl ls-add alice
7475 ovn-nbctl ls-add outside
7478 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7479 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7480 type=router options:router-port=foo \
7481 -- lsp-set-addresses rp-foo router
7483 # Connect alice to R1 as distributed router gateway port on hv2
7484 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7485 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7486 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7487 type=router options:router-port=alice \
7488 -- lsp-set-addresses rp-alice router
7490 # Create logical port foo1 in foo
7491 ovn-nbctl lsp-add foo foo1 \
7492 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7494 # Create logical port outside1 in outside
7495 ovn-nbctl lsp-add outside outside1 \
7496 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7498 # Create localnet port in alice
7499 ovn-nbctl lsp-add alice ln-alice
7500 ovn-nbctl lsp-set-addresses ln-alice unknown
7501 ovn-nbctl lsp-set-type ln-alice localnet
7502 ovn-nbctl lsp-set-options ln-alice network_name=phys
7504 # Create localnet port in outside
7505 ovn-nbctl lsp-add outside ln-outside
7506 ovn-nbctl lsp-set-addresses ln-outside unknown
7507 ovn-nbctl lsp-set-type ln-outside localnet
7508 ovn-nbctl lsp-set-options ln-outside network_name=phys
7510 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7511 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7512 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7515 # Allow some time for ovn-northd and ovn-controller to catch up.
7516 # XXX This should be more systematic.
7519 echo "---------NB dump-----"
7521 echo "---------------------"
7522 ovn-nbctl list logical_router
7523 echo "---------------------"
7524 ovn-nbctl list logical_router_port
7525 echo "---------------------"
7527 echo "---------SB dump-----"
7528 ovn-sbctl list datapath_binding
7529 echo "---------------------"
7530 ovn-sbctl list port_binding
7531 echo "---------------------"
7532 ovn-sbctl dump-flows
7533 echo "---------------------"
7534 ovn-sbctl list chassis
7535 ovn-sbctl list encap
7536 echo "------ Gateway_Chassis dump (SBDB) -------"
7537 ovn-sbctl list Gateway_Chassis
7538 echo "------ Port_Binding chassisredirect -------"
7539 ovn-sbctl find Port_Binding type=chassisredirect
7540 echo "-------------------------------------------"
7542 echo "------ hv1 dump ----------"
7543 as hv1 ovs-ofctl show br-int
7544 as hv1 ovs-ofctl dump-flows br-int
7545 echo "------ hv2 dump ----------"
7546 as hv2 ovs-ofctl show br-int
7547 as hv2 ovs-ofctl dump-flows br-int
7548 echo "------ hv3 dump ----------"
7549 as hv3 ovs-ofctl show br-int
7550 as hv3 ovs-ofctl dump-flows br-int
7551 echo "--------------------------"
7554 # Check that redirect mapping is programmed only on hv2
7555 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7557 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7559 # Check that hv1 sends chassisredirect port traffic to hv2
7560 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7562 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7564 # Check that arp reply on distributed gateway port is only programmed on hv2
7565 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7567 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7572 printf "%02x%02x%02x%02x" "$@"
7576 : > hv2-vif1.expected
7577 : > hv3-vif1.expected
7579 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7581 # Causes a packet to be received on INPORT. The packet is an ARP
7582 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7583 # it should be the hardware address of the target to expect to receive in an
7584 # ARP reply; otherwise no reply is expected.
7586 # INPORT is an logical switch port number, e.g. 11 for vif11.
7587 # SHA and REPLY_HA are each 12 hex digits.
7588 # SPA and TPA are each 8 hex digits.
7590 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7591 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7592 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7594 if test X$reply_ha != X; then
7595 # Expect to receive the reply, if any.
7596 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7597 echo $reply >> hv${hv}-vif$inport.expected
7601 rtr_ip=$(ip_to_hex 172 16 1 1)
7602 foo_ip=$(ip_to_hex 192 168 1 2)
7603 outside_ip=$(ip_to_hex 172 16 1 3)
7609 # ARP for router IP address from outside1, no response expected
7610 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7612 # Now check the packets actually received against the ones expected.
7613 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7615 # Send ip packet between foo1 and outside1
7616 src_mac="f00000010203"
7617 dst_mac="000001010203"
7618 src_ip=`ip_to_hex 192 168 1 2`
7619 dst_ip=`ip_to_hex 172 16 1 3`
7620 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7622 # Now check the packets actually received against the ones expected.
7623 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7625 # Now add bridge-mappings on hv2, which should make everything work
7626 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7628 # Allow some time for ovn-northd and ovn-controller to catch up.
7629 # XXX This should be more systematic.
7632 # ARP for router IP address from outside1
7633 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7635 # Now check the packets actually received against the ones expected.
7636 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7638 # Send ip packet between foo1 and outside1
7639 src_mac="f00000010203"
7640 dst_mac="000001010203"
7641 src_ip=`ip_to_hex 192 168 1 2`
7642 dst_ip=`ip_to_hex 172 16 1 3`
7643 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7645 # ARP request packet to expect at outside1
7646 src_mac="000002010203"
7647 src_ip=`ip_to_hex 172 16 1 1`
7648 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7650 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7652 echo $arp_request >> hv3-vif1.expected
7653 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7655 # Send ARP reply from outside1 back to the router
7656 reply_mac="f00000010204"
7657 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7659 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7661 # Allow some time for ovn-northd and ovn-controller to catch up.
7662 # XXX This should be more systematic.
7665 # Packet to Expect at outside1
7666 src_mac="000002010203"
7667 dst_mac="f00000010204"
7668 src_ip=`ip_to_hex 192 168 1 2`
7669 dst_ip=`ip_to_hex 172 16 1 3`
7670 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7672 # Resend packet from foo1 to outside1
7673 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7675 echo "------ hv1 dump ----------"
7676 as hv1 ovs-ofctl show br-int
7677 as hv1 ovs-ofctl dump-flows br-int
7678 echo "------ hv2 dump ----------"
7679 as hv2 ovs-ofctl show br-int
7680 as hv2 ovs-ofctl dump-flows br-int
7681 echo "------ hv3 dump ----------"
7682 as hv3 ovs-ofctl show br-int
7683 as hv3 ovs-ofctl dump-flows br-int
7684 echo "----------------------------"
7686 echo $expected >> hv3-vif1.expected
7687 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7689 #Check ovn-trace over "chassisredirect" port
7690 AT_CAPTURE_FILE([trace])
7692 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7695 echo 'ip.ttl--;' > expout
7696 echo 'eth.src = 00:00:02:01:02:03;' >> expout
7697 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7698 echo 'output("ln-alice");' >> expout
7699 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])
7701 # Create logical port alice1 in alice on hv1
7702 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7703 set interface hv1-vif2 external-ids:iface-id=alice1 \
7704 options:tx_pcap=hv1/vif2-tx.pcap \
7705 options:rxq_pcap=hv1/vif2-rx.pcap \
7708 ovn-nbctl lsp-add alice alice1 \
7709 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7711 # Create logical port foo2 in foo on hv2
7712 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7713 set interface hv2-vif1 external-ids:iface-id=foo2 \
7714 options:tx_pcap=hv2/vif1-tx.pcap \
7715 options:rxq_pcap=hv2/vif1-rx.pcap \
7718 ovn-nbctl lsp-add foo foo2 \
7719 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7721 # Allow some time for ovn-northd and ovn-controller to catch up.
7722 # XXX This should be more systematic.
7725 : > hv1-vif2.expected
7727 # Send ip packet between alice1 and foo2
7728 src_mac="f00000010205"
7729 dst_mac="000002010203"
7730 src_ip=`ip_to_hex 172 16 1 4`
7731 dst_ip=`ip_to_hex 192 168 1 3`
7732 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7734 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7736 # Packet to Expect at foo2
7737 src_mac="000001010203"
7738 dst_mac="f00000010206"
7739 src_ip=`ip_to_hex 172 16 1 4`
7740 dst_ip=`ip_to_hex 192 168 1 3`
7741 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7743 echo $expected >> hv2-vif1.expected
7744 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
7746 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
7749 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
7751 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
7754 OVN_CLEANUP([hv1],[hv2],[hv3])
7758 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7759 AT_SKIP_IF([test $HAVE_PYTHON = no])
7761 # Create logical switches
7762 ovn-nbctl ls-add ls0
7763 ovn-nbctl ls-add ls1
7764 # Create distributed router
7765 ovn-nbctl create Logical_Router name=lr0
7766 # Add distributed gateway port to distributed router
7767 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7768 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7769 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7770 type=router options:router-port=lrp0 addresses="router"
7771 # Add router port to ls1
7772 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7773 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7774 type=router options:router-port=lrp1 addresses="router"
7775 # Add logical ports for NAT rules
7776 ovn-nbctl lsp-add ls1 foo1 \
7777 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7778 ovn-nbctl lsp-add ls1 foo2 \
7779 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
7780 # Add nat-addresses option
7781 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7783 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7784 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7785 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])
7786 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])
7791 ovs-vsctl add-br br-phys
7792 ovn_attach n1 br-phys 192.168.0.1
7794 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7795 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])
7799 ovs-vsctl add-br br-phys
7800 ovn_attach n1 br-phys 192.168.0.2
7801 # Initially test with no bridge-mapping on hv2, expect to receive no packets
7805 ovs-vsctl add-br br-phys
7806 ovn_attach n1 br-phys 192.168.0.3
7807 # Initially test with no bridge-mapping on hv3
7809 # Create a localnet port.
7810 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
7811 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7812 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7813 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7815 # Allow some time for ovn-northd and ovn-controller to catch up.
7816 # XXX This should be more systematic.
7819 # Expect no packets when hv2 bridge-mapping is not present
7821 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
7823 # Add bridge-mapping on hv2
7824 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7826 # Wait for packets to be received.
7827 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
7829 sed 's/\(00\)\{1,\}$//'
7831 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7832 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
7833 echo $expected > expout
7834 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
7835 echo $expected >> expout
7836 AT_CHECK([sort packets], [0], [expout])
7839 # Temporarily remove nat-addresses option to avoid race conditions
7840 # due to GARP backoff
7841 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
7846 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7847 options:rxq_pcap=dummy-rx.pcap
7848 rm -f ${pcap_file}*.pcap
7849 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7850 options:rxq_pcap=${pcap_file}-rx.pcap
7853 as hv1 reset_pcap_file snoopvif hv1/snoopvif
7855 # Add OVS ports for foo1 and foo2 on hv3
7856 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7857 set interface hv3-vif1 external-ids:iface-id=foo1 \
7859 ovs-vsctl -- add-port br-int hv3-vif2 -- \
7860 set interface hv3-vif2 external-ids:iface-id=foo2 \
7863 # Add bridge-mapping on hv3
7864 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7866 # Re-add nat-addresses option
7867 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7869 # Wait for packets to be received.
7870 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
7872 sed 's/\(00\)\{1,\}$//'
7875 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7876 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
7877 echo $expected >> expout
7878 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
7879 echo $expected >> expout
7880 AT_CHECK([sort packets], [0], [expout])
7883 OVN_CLEANUP([hv1],[hv2],[hv3])
7887 AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
7888 AT_KEYWORDS([ovn-nd_ra])
7889 AT_SKIP_IF([test $HAVE_PYTHON = no])
7892 # In this test case we create 1 lswitch with 3 VIF ports attached,
7893 # and a lrouter connected to the lswitch.
7894 # We generate the Router solicitation packet and verify the Router Advertisement
7895 # reply packet from the ovn-controller.
7897 # Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
7898 # onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
7899 # 'slaac' to allow lrp0 send RA for SLAAC mode.
7900 ovn-nbctl ls-add lsw0
7901 ovn-nbctl lr-add lr0
7902 ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
7903 ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
7905 -- lsp-add lsw0 lsp0 \
7906 -- set Logical_Switch_Port lsp0 type=router \
7907 options:router-port=lrp0 \
7908 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
7912 ovs-vsctl add-br br-phys
7913 ovn_attach n1 br-phys 192.168.0.2
7915 ovn-nbctl lsp-add lsw0 lp1
7916 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
7917 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"
7919 ovn-nbctl lsp-add lsw0 lp2
7920 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
7921 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"
7923 ovn-nbctl lsp-add lsw0 lp3
7924 ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
7925 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"
7927 # Add ACL rule for ICMPv6 on lsw0
7928 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
7929 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
7930 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
7931 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
7933 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7934 set interface hv1-vif1 external-ids:iface-id=lp1 \
7935 options:tx_pcap=hv1/vif1-tx.pcap \
7936 options:rxq_pcap=hv1/vif1-rx.pcap \
7939 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7940 set interface hv1-vif2 external-ids:iface-id=lp2 \
7941 options:tx_pcap=hv1/vif2-tx.pcap \
7942 options:rxq_pcap=hv1/vif2-rx.pcap \
7945 ovs-vsctl -- add-port br-int hv1-vif3 -- \
7946 set interface hv1-vif3 external-ids:iface-id=lp3 \
7947 options:tx_pcap=hv1/vif3-tx.pcap \
7948 options:rxq_pcap=hv1/vif3-rx.pcap \
7951 # Allow some time for ovn-northd and ovn-controller to catch up.
7952 # XXX This should be more systematic.
7958 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7959 options:rxq_pcap=dummy-rx.pcap
7960 rm -f ${pcap_file}*.pcap
7961 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7962 options:rxq_pcap=${pcap_file}-rx.pcap
7965 # Make sure that ovn-controller has installed the corresponding OF Flow.
7966 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"`])
7968 # This shell function sends a Router Solicitation packet.
7969 # test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
7971 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
7972 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
7976 if test $mtu != 0; then
7978 mtu_opt=05010000${mtu}
7981 if test ${#prefix_opt} != 0; then
7982 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
7983 len=`expr $len + ${#prefix_opt} / 2`
7986 len=$(printf "%x" $len)
7987 local lrp_mac=fa163e000001
7988 local lrp_lla=fe80000000000000f8163efffe000001
7989 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
7990 echo $reply >> $inport.expected
7992 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
7995 AT_CAPTURE_FILE([ofctl_monitor0.log])
7996 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7997 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7999 # MTU is not set and the address mode is set to slaac
8001 default_prefix_option_config=030440c0ffffffffffffffff00000000
8002 src_mac=fa163e000002
8003 src_lla=fe80000000000000f8163efffe000002
8004 test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8006 # NXT_RESUME should be 1.
8007 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8009 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8011 cat 1.expected | cut -c -112 > expout
8012 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8014 # Skipping the ICMPv6 checksum.
8015 cat 1.expected | cut -c 117- > expout
8016 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8019 reset_pcap_file hv1-vif1 hv1/vif1
8020 reset_pcap_file hv1-vif2 hv1/vif2
8021 reset_pcap_file hv1-vif3 hv1/vif3
8023 # Set the MTU to 1500
8024 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8026 # Make sure that ovn-controller has installed the corresponding OF Flow.
8027 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"`])
8030 default_prefix_option_config=030440c0ffffffffffffffff00000000
8031 src_mac=fa163e000003
8032 src_lla=fe80000000000000f8163efffe000003
8035 test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8037 # NXT_RESUME should be 2.
8038 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8040 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8042 cat 2.expected | cut -c -112 > expout
8043 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8045 # Skipping the ICMPv6 checksum.
8046 cat 2.expected | cut -c 117- > expout
8047 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8050 reset_pcap_file hv1-vif1 hv1/vif1
8051 reset_pcap_file hv1-vif2 hv1/vif2
8052 reset_pcap_file hv1-vif3 hv1/vif3
8054 # Set the address mode to dhcpv6_stateful
8055 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8056 # Make sure that ovn-controller has installed the corresponding OF Flow.
8057 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"`])
8060 default_prefix_option_config=""
8061 src_mac=fa163e000004
8062 src_lla=fe80000000000000f8163efffe000004
8065 test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8067 # NXT_RESUME should be 3.
8068 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8070 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8072 cat 3.expected | cut -c -112 > expout
8073 AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8075 # Skipping the ICMPv6 checksum.
8076 cat 3.expected | cut -c 117- > expout
8077 AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8080 reset_pcap_file hv1-vif1 hv1/vif1
8081 reset_pcap_file hv1-vif2 hv1/vif2
8082 reset_pcap_file hv1-vif3 hv1/vif3
8084 # Set the address mode to dhcpv6_stateless
8085 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8086 # Make sure that ovn-controller has installed the corresponding OF Flow.
8087 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"`])
8090 default_prefix_option_config=030440c0ffffffffffffffff00000000
8091 src_mac=fa163e000002
8092 src_lla=fe80000000000000f8163efffe000002
8095 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8097 # NXT_RESUME should be 4.
8098 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8100 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8102 cat 1.expected | cut -c -112 > expout
8103 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8105 # Skipping the ICMPv6 checksum.
8106 cat 1.expected | cut -c 117- > expout
8107 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8110 reset_pcap_file hv1-vif1 hv1/vif1
8111 reset_pcap_file hv1-vif2 hv1/vif2
8112 reset_pcap_file hv1-vif3 hv1/vif3
8114 # Set the address mode to invalid.
8115 ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8116 # Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8117 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"`])
8120 default_prefix_option_config=""
8121 src_mac=fa163e000002
8122 src_lla=fe80000000000000f8163efffe000002
8125 test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8127 # NXT_RESUME should be 4 only.
8128 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8130 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8131 AT_CHECK([cat 1.packets], [0], [])
8136 AT_SETUP([ovn -- /32 router IP address])
8137 AT_SKIP_IF([test $HAVE_PYTHON = no])
8141 # 2 LS 'foo' and 'alice' connected via router R1.
8142 # R1 connects to 'alice' with a /32 IP address. We use static routes and
8143 # nexthop to push traffic to a logical port in switch 'alice'
8147 ovn-nbctl ls-add foo
8148 ovn-nbctl ls-add alice
8151 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8152 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8153 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8155 # Connect alice to R1.
8156 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8157 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8158 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8160 # Create logical port foo1 in foo
8161 ovn-nbctl lsp-add foo foo1 \
8162 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8164 # Create logical port alice1 in alice
8165 ovn-nbctl lsp-add alice alice1 \
8166 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8168 #install default route in R1 to use alice1's IP address as nexthop
8169 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8171 # Create two hypervisor and create OVS ports corresponding to logical ports.
8176 ovs-vsctl add-br br-phys
8177 ovn_attach n1 br-phys 192.168.0.1
8178 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8179 set interface hv1-vif1 external-ids:iface-id=foo1 \
8180 options:tx_pcap=hv1/vif1-tx.pcap \
8181 options:rxq_pcap=hv1/vif1-rx.pcap \
8186 ovs-vsctl add-br br-phys
8187 ovn_attach n1 br-phys 192.168.0.2
8188 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8189 set interface hv2-vif1 external-ids:iface-id=alice1 \
8190 options:tx_pcap=hv2/vif1-tx.pcap \
8191 options:rxq_pcap=hv2/vif1-rx.pcap \
8195 # Pre-populate the hypervisors' ARP tables so that we don't lose any
8196 # packets for ARP resolution (native tunneling doesn't queue packets
8197 # for ARP resolution).
8200 # Allow some time for ovn-northd and ovn-controller to catch up.
8201 # XXX This should be more systematic.
8205 printf "%02x%02x%02x%02x" "$@"
8208 # Send ip packets between foo1 and alice1
8209 src_mac="f00000010203"
8210 dst_mac="000000010203"
8211 src_ip=`ip_to_hex 192 168 1 2`
8212 dst_ip=`ip_to_hex 10 0 0 2`
8213 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8215 # Send the first packet to trigger a ARP response and population of
8216 # mac_bindings table.
8217 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8218 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
8220 # Send the second packet to reach the destination.
8221 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8223 # Packet to Expect at 'alice1'
8224 src_mac="000000010204"
8225 dst_mac="f00000010204"
8226 src_ip=`ip_to_hex 192 168 1 2`
8227 dst_ip=`ip_to_hex 10 0 0 2`
8228 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8230 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8232 OVN_CLEANUP([hv1],[hv2])
8236 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8237 AT_SKIP_IF([test $HAVE_PYTHON = no])
8240 ovn-nbctl ls-add ls1
8242 # Add localport to the switch
8243 ovn-nbctl lsp-add ls1 lp01
8244 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8245 ovn-nbctl lsp-set-type lp01 localport
8252 ovs-vsctl add-br br-phys
8253 ovn_attach n1 br-phys 192.168.0.$i
8254 ovs-vsctl add-port br-int vif01 -- \
8255 set Interface vif01 external-ids:iface-id=lp01 \
8256 options:tx_pcap=hv${i}/vif01-tx.pcap \
8257 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8258 ofport-request=${i}0
8260 ovs-vsctl add-port br-int vif${i}1 -- \
8261 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8262 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8263 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8264 ofport-request=${i}1
8266 ovn-nbctl lsp-add ls1 lp${i}1
8267 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8268 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8270 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8273 ovn-nbctl --wait=sb sync
8274 ovn-sbctl dump-flows
8278 # Given the name of a logical port, prints the name of the hypervisor
8279 # on which it is located.
8284 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8286 # This shell function causes a packet to be received on INPORT. The packet's
8287 # content has Ethernet destination DST and source SRC (each exactly 12 hex
8288 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8289 # logical switch port numbers, e.g. 11 for vif11.
8291 # EOUT is the end-to-end output port, that is, where the packet will end up
8292 # after possibly bouncing through one or more localnet ports. LOUT is the
8293 # logical output port, which might be a localnet port, as seen by ovn-trace
8294 # (which doesn't know what localnet ports are connected to and therefore can't
8295 # figure out the end-to-end answer).
8297 # DEFHV is the default hypervisor from where the packet is going to be sent
8298 # if the source port is a localport.
8305 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8308 # First try tracing the packet.
8309 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8310 if test $lout != drop; then
8311 echo "output(\"$lout\");"
8313 AT_CAPTURE_FILE([trace])
8314 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8316 # Then actually send a packet, for an end-to-end test.
8317 local packet=$(echo $dst$src | sed 's/://g')${eth}
8318 hv=`vif_to_hv $inport`
8319 # If hypervisor 0 (localport) use the defhv parameter
8320 if test $hv = hv0; then
8324 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8325 if test $eout != drop; then
8326 echo $packet >> ${eout#lp}.expected
8331 # lp11 and lp21 are on different hypervisors
8332 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8333 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8335 # Both VIFs should be able to reach the localport on their own HV
8336 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8337 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8339 # Packet sent from localport on same hv should reach the vif
8340 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8341 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8343 # Packet sent from localport on different hv should be dropped
8344 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8345 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8347 # Now check the packets actually received against the ones expected.
8350 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8354 OVN_CLEANUP([hv1],[hv2])
8358 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8359 AT_SKIP_IF([test $HAVE_PYTHON = no])
8364 # create gateways with external network connectivity
8369 ovs-vsctl add-br br-phys
8370 ovn_attach n1 br-phys 192.168.0.$i
8371 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8374 ovn-nbctl ls-add inside
8375 ovn-nbctl ls-add outside
8377 # create hypervisors with a vif port each to an internal network
8382 ovs-vsctl add-br br-phys
8383 ovn_attach n1 br-phys 192.168.0.1$i
8384 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8385 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8386 options:tx_pcap=hv$i/vif1-tx.pcap \
8387 options:rxq_pcap=hv$i/vif1-rx.pcap \
8390 ovn-nbctl lsp-add inside inside$i \
8391 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8397 ovn-nbctl create Logical_Router name=R1
8399 # Connect inside to R1
8400 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8401 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8402 type=router options:router-port=inside \
8403 -- lsp-set-addresses rp-inside router
8405 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8406 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8408 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8409 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8410 --id=@gc1 create Gateway_Chassis \
8411 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8412 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8414 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8415 type=router options:router-port=outside \
8416 -- lsp-set-addresses rp-outside router
8418 # Create localnet port in outside
8419 ovn-nbctl lsp-add outside ln-outside
8420 ovn-nbctl lsp-set-addresses ln-outside unknown
8421 ovn-nbctl lsp-set-type ln-outside localnet
8422 ovn-nbctl lsp-set-options ln-outside network_name=phys
8424 # Allow some time for ovn-northd and ovn-controller to catch up.
8425 # XXX This should be more systematic.
8426 ovn-nbctl --wait=hv --timeout=3 sync
8428 echo "---------NB dump-----"
8430 echo "---------------------"
8431 ovn-nbctl list logical_router
8432 echo "---------------------"
8433 ovn-nbctl list logical_router_port
8434 echo "---------------------"
8436 echo "---------SB dump-----"
8437 ovn-sbctl list datapath_binding
8438 echo "---------------------"
8439 ovn-sbctl list port_binding
8440 echo "---------------------"
8441 ovn-sbctl dump-flows
8442 echo "---------------------"
8443 ovn-sbctl list chassis
8444 ovn-sbctl list encap
8445 echo "---------------------"
8446 echo "------ Gateway_Chassis dump (SBDB) -------"
8447 ovn-sbctl list Gateway_Chassis
8448 echo "------ Port_Binding chassisredirect -------"
8449 ovn-sbctl find Port_Binding type=chassisredirect
8450 echo "-------------------------------------------"
8452 for chassis in gw1 gw2 hv1 hv2; do
8454 echo "------ $chassis dump ----------"
8455 ovs-ofctl show br-int
8456 ovs-ofctl dump-flows br-int
8457 echo "--------------------------"
8459 function bfd_dump() {
8460 for chassis in gw1 gw2 hv1 hv2; do
8462 echo "------ $chassis dump (BFD)----"
8463 echo "BFD (from $chassis):"
8464 # dump BFD config and status to the other chassis
8465 for chassis2 in gw1 gw2 hv1 hv2; do
8466 if [[ "$chassis" != "$chassis2" ]]; then
8467 echo " -> $chassis2:"
8468 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8471 echo "--------------------------"
8477 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8478 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8479 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8480 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8482 echo $hv1_gw1_ofport
8483 echo $hv1_gw2_ofport
8484 echo $hv2_gw1_ofport
8485 echo $hv2_gw2_ofport
8488 as hv1 ovs-ofctl dump-flows br-int table=32
8491 as hv2 ovs-ofctl dump-flows br-int table=32
8493 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8494 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8496 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
8499 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
8502 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8504 # make sure that flows for handling the outside router port reside on gw1
8505 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8507 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8510 # make sure ARP responder flows for outside router port reside on gw1 too
8511 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8513 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8518 # check that the chassis redirect port has been claimed by the gw1 chassis
8519 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8524 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8526 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8527 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8528 --id=@gc1 create Gateway_Chassis \
8529 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8530 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8533 # XXX: Let the change propagate down to the ovn-controllers
8534 ovn-nbctl --wait=hv --timeout=3 sync
8536 # we make sure that the hypervisors noticed, and inverted the slave ports
8537 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
8540 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
8543 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8544 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8548 # check BFD enablement on tunnel ports from gw1 #########
8550 for chassis in gw2 hv1 hv2; do
8551 echo "checking gw1 -> $chassis"
8552 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8558 # check BFD enablement on tunnel ports from gw2 ##########
8560 for chassis in gw1 hv1 hv2; do
8561 echo "checking gw2 -> $chassis"
8562 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8567 # check BFD enablement on tunnel ports from hv1 ###########
8569 for chassis in gw1 gw2; do
8570 echo "checking hv1 -> $chassis"
8571 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8575 # make sure BFD is not enabled to hv2, we don't need it
8576 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8581 # check BFD enablement on tunnel ports from hv2 ##########
8583 for chassis in gw1 gw2; do
8584 echo "checking hv2 -> $chassis"
8585 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8589 # make sure BFD is not enabled to hv1, we don't need it
8590 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8594 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8596 # make sure that flows for handling the outside router port reside on gw2 now
8597 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8599 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8602 # disconnect GW2 from the network, GW1 should take over
8604 port=${sandbox}_br-phys
8605 as main ovs-vsctl del-port n1 $port
8610 # make sure that flows for handling the outside router port reside on gw2 now
8611 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8613 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8616 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8617 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8621 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8625 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8626 AT_SKIP_IF([test $HAVE_PYTHON = no])
8628 ovn-nbctl ls-add ls0
8629 ovn-nbctl ls-add ls1
8630 ovn-nbctl create Logical_Router name=lr0
8631 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8633 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8634 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8635 --id=@gc1 create Gateway_Chassis \
8636 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8637 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8639 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8640 type=router options:router-port=lrp0 addresses="router"
8641 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8642 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8643 type=router options:router-port=lrp1 addresses="router"
8646 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8651 ovs-vsctl add-br br-phys
8652 ovn_attach n1 br-phys 192.168.0.1
8653 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8654 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])
8658 ovs-vsctl add-br br-phys
8659 ovn_attach n1 br-phys 192.168.0.2
8660 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8664 ovs-vsctl add-br br-phys
8665 ovn_attach n1 br-phys 192.168.0.3
8666 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8668 # Create a localnet port.
8669 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8670 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8671 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8672 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8674 # wait for earlier changes to take effect
8675 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8680 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8681 options:rxq_pcap=dummy-rx.pcap
8682 rm -f ${pcap_file}*.pcap
8683 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8684 options:rxq_pcap=${pcap_file}-rx.pcap
8687 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8688 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8689 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8690 # add nat-addresses option
8691 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8693 # Wait for packets to be received through hv2.
8694 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8696 sed 's/\(00\)\{1,\}$//'
8699 only_broadcast_from_lrp1() {
8700 grep "fffffffffffff00000000001"
8703 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
8706 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
8707 echo "packets on hv1-snoopvif:"
8709 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
8710 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8711 echo "packets on hv2 br-phys tx"
8713 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
8714 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8715 echo "packets on hv3 br-phys tx"
8717 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8720 # at this point, we invert the priority of the gw chassis between hv2 and hv3
8722 ovn-nbctl --wait=hv \
8723 --id=@gc0 create Gateway_Chassis \
8724 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8725 --id=@gc1 create Gateway_Chassis \
8726 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8727 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8730 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8731 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8732 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8734 # Wait for packets to be received.
8735 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8737 sed 's/\(00\)\{1,\}$//'
8740 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8741 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8742 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8743 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8744 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8745 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8747 # change localnet port tag.
8748 AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
8750 # wait for earlier changes to take effect
8751 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8753 # update nat-addresses option
8754 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0
8755 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8757 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8758 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8759 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8761 # Wait for packets to be received.
8762 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8764 sed 's/\(00\)\{1,\}$//'
8767 garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
8770 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8771 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8772 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8773 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8774 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8775 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8777 OVN_CLEANUP([hv1],[hv2],[hv3])
8781 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8782 AT_SKIP_IF([test $HAVE_PYTHON = no])
8787 # create two gateways with external network connectivity
8791 ovs-vsctl add-br br-phys
8792 ovn_attach n1 br-phys 192.168.0.$i
8793 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8796 ovn-nbctl ls-add inside
8797 ovn-nbctl ls-add outside
8799 # create one hypervisors with a vif port the internal network
8802 ovs-vsctl add-br br-phys
8803 ovn_attach n1 br-phys 192.168.0.11
8804 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8805 set interface hv1-vif1 external-ids:iface-id=inside1 \
8806 options:tx_pcap=hv1/vif1-tx.pcap \
8807 options:rxq_pcap=hv1/vif1-rx.pcap \
8810 ovn-nbctl lsp-add inside inside1 \
8811 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
8816 ovn-nbctl create Logical_Router name=R1
8818 # Connect inside to R1
8819 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8820 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8821 type=router options:router-port=inside \
8822 -- lsp-set-addresses rp-inside router
8824 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8825 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8827 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8828 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8829 --id=@gc1 create Gateway_Chassis \
8830 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8831 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8833 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8834 type=router options:router-port=outside \
8835 -- lsp-set-addresses rp-outside router
8837 # Create localnet port in outside
8838 ovn-nbctl lsp-add outside ln-outside
8839 ovn-nbctl lsp-set-addresses ln-outside unknown
8840 ovn-nbctl lsp-set-type ln-outside localnet
8841 ovn-nbctl lsp-set-options ln-outside network_name=phys
8843 # Allow some time for ovn-northd and ovn-controller to catch up.
8844 ovn-nbctl --wait=hv --timeout=3 sync
8846 # currently when ovn-controller is restarted, the old entry is deleted
8847 # and a new one is created, which leaves the Gateway_Chassis with
8848 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
8849 # doesn't have the same effect because "name" is conserved, and the
8850 # Chassis entry is not replaced.
8852 > gw1/ovn-controller.log
8854 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8855 ovn-sbctl destroy Chassis $gw2_chassis
8857 # Ensure ovn-controller has processed latest sbdb update
8858 # ovn-nbctl --wait=hv sync
8860 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
8862 OVN_CLEANUP([gw1],[gw2],[hv1])
8866 AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
8867 AT_KEYWORDS([ovn-nd_ns for unknown mac])
8868 AT_SKIP_IF([test $HAVE_PYTHON = no])
8871 ovn-nbctl ls-add sw0_ip6
8872 ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
8873 ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
8874 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
8876 ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
8877 "50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
8879 ovn-nbctl lr-add lr0_ip6
8880 ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
8881 ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
8882 ovn-nbctl lsp-set-type lrp0_ip6-attachment router
8883 ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
8884 ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
8885 ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
8887 ovn-nbctl ls-add public
8888 ovn-nbctl lsp-add public ln-public
8889 ovn-nbctl lsp-set-addresses ln-public unknown
8890 ovn-nbctl lsp-set-type ln-public localnet
8891 ovn-nbctl lsp-set-options ln-public network_name=phys
8893 ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
8894 2001:db8:1:0:200:02ff:fe01:0204/64 \
8895 -- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
8898 ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
8899 rp-ip6_public type=router options:router-port=ip6_public \
8900 -- lsp-set-addresses rp-ip6_public router
8905 ovs-vsctl add-br br-phys
8906 ovn_attach n1 br-phys 192.168.0.2
8908 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8909 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
8910 options:tx_pcap=hv1/vif1-tx.pcap \
8911 options:rxq_pcap=hv1/vif1-rx.pcap \
8913 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8915 # Allow some time for ovn-northd and ovn-controller to catch up.
8916 # XXX This should be more systematic.
8920 sed 's/\(00\)\{1,\}$//'
8923 # Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
8924 # addresses. ovn-controller should generate an IPv6 NS request for IPv6
8925 # packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
8926 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
8927 # This function sends ipv6 packet
8929 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
8930 dst_ip=20010db800010000020002fffe010205
8932 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
8933 packet=${packet}8000000000000000
8934 shift; shift; shift; shift
8936 dst_mac=3333ff010205
8937 src_mac=000002010204
8938 mcast_node_ip=ff0200000000000000000001ff010205
8939 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
8940 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
8941 expected_packet=${expected_packet}0101${src_mac}
8943 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
8944 echo $expected_packet >> ipv6_ns.expected
8947 src_mac=506400000002
8948 dst_mac=00000000af01
8949 src_ip=aef0000000000000526400fffe000002
8950 # Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
8951 # should be received by the ports attached to br-phys.
8952 test_ipv6 1 $src_mac $dst_mac $src_ip 2
8954 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
8955 trim_zeros > 1.packets
8956 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
8957 trim_zeros > 2.packets
8959 cat ipv6_ns.expected | cut -c -112 > expout
8960 AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8961 AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8963 # Skipping the ICMPv6 checksum
8964 cat ipv6_ns.expected | cut -c 117- > expout
8965 AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8966 AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8972 AT_SETUP([ovn -- options:requested-chassis for logical port])
8977 ovn-nbctl ls-add ls0
8978 ovn-nbctl lsp-add ls0 lsp0
8980 # create two hypervisors, each with one vif port
8983 ovs-vsctl add-br br-phys
8984 ovn_attach n1 br-phys 192.168.0.11
8985 ovs-vsctl -- add-port br-int hv1-vif0
8989 ovs-vsctl add-br br-phys
8990 ovn_attach n1 br-phys 192.168.0.12
8991 ovs-vsctl -- add-port br-int hv2-vif0
8993 # Allow only chassis hv1 to bind logical port lsp0.
8994 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
8996 # Allow some time for ovn-northd and ovn-controller to catch up.
8997 ovn-nbctl --wait=hv --timeout=3 sync
8999 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
9000 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9001 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9003 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9004 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9006 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9008 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9009 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9011 # (2) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
9012 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9014 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9016 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9017 AT_CHECK([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv1_uuid"], [0], [])
9019 # (3) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
9020 # the requested chassis for lsp0 is changed from hv1 to hv2.
9021 echo "verifying that lsp0 binding moves when requested-chassis is changed"
9023 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9024 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9025 OVS_WAIT_UNTIL([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv2_uuid"])
9027 OVN_CLEANUP([hv1],[hv2])
9031 AT_SETUP([ovn -- options:requested-chassis with hostname])
9035 ovn-nbctl ls-add ls0
9036 ovn-nbctl lsp-add ls0 lsp0
9041 ovs-vsctl add-br br-phys
9042 ovn_attach n1 br-phys 192.168.0.11
9043 ovs-vsctl -- add-port br-int hv1-vif0
9045 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9046 echo "hv1_hostname=${hv1_hostname}"
9047 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9048 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9050 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9051 echo "hv1_uuid=${hv1_uuid}"
9052 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9053 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
9055 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9056 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9057 ovn-nbctl --wait=hv --timeout=3 sync
9058 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])