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);
830 Syntax error at `)' expecting port number.
831 ct_lb(192.168.1.2:123456);
832 Syntax error at `123456' expecting port number.
834 Syntax error at `foo' expecting IPv4 address.
838 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
843 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
846 formats as ct_commit;
847 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
849 ct_commit(ct_mark=1);
850 formats as ct_commit(ct_mark=0x1);
851 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
853 ct_commit(ct_mark=1/1);
854 formats as ct_commit(ct_mark=0x1/0x1);
855 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
857 ct_commit(ct_label=1);
858 formats as ct_commit(ct_label=0x1);
859 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
861 ct_commit(ct_label=1/1);
862 formats as ct_commit(ct_label=0x1/0x1);
863 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
865 ct_commit(ct_mark=1, ct_label=2);
866 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
867 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
870 ct_commit(ct_label=0x01020304050607080910111213141516);
871 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
872 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
874 ct_commit(ct_label=0x181716151413121110090807060504030201);
875 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
876 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
878 ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
879 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
881 ct_commit(ct_label=18446744073709551615);
882 formats as ct_commit(ct_label=0xffffffffffffffff);
883 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
885 ct_commit(ct_label=18446744073709551616);
886 Decimal constants must be less than 2**64.
890 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
892 ct_dnat(192.168.1.2);
893 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
896 ct_dnat(192.168.1.2, 192.168.1.3);
897 Syntax error at `,' expecting `)'.
899 Syntax error at `foo' expecting IPv4 address.
901 Syntax error at `foo' expecting IPv4 address.
903 Syntax error at `)' expecting IPv4 address.
907 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
909 ct_snat(192.168.1.2);
910 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
913 ct_snat(192.168.1.2, 192.168.1.3);
914 Syntax error at `,' expecting `)'.
916 Syntax error at `foo' expecting IPv4 address.
918 Syntax error at `foo' expecting IPv4 address.
920 Syntax error at `)' expecting IPv4 address.
927 clone { ip4.dst = 255.255.255.255; output; }; next;
928 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
929 has prereqs eth.type == 0x800
932 arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
933 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)
936 formats as arp { drop; };
937 encodes as controller(userdata=00.00.00.00.00.00.00.00)
941 get_arp(outport, ip4.dst);
942 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[]
943 has prereqs eth.type == 0x800
944 get_arp(inport, reg0);
945 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[]
948 Syntax error at `;' expecting `('.
950 Syntax error at `)' expecting field name.
952 Syntax error at `)' expecting `,'.
953 get_arp(inport ip4.dst);
954 Syntax error at `ip4.dst' expecting `,'.
955 get_arp(inport, ip4.dst;
956 Syntax error at `;' expecting `)'.
957 get_arp(inport, eth.dst);
958 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
959 get_arp(inport, outport);
960 Cannot use string field outport where numeric field is required.
961 get_arp(reg0, ip4.dst);
962 Cannot use numeric field reg0 where string field is required.
965 put_arp(inport, arp.spa, arp.sha);
966 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[]
967 has prereqs eth.type == 0x806 && eth.type == 0x806
970 reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
971 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)
972 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");
973 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");
974 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)
975 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);
976 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);
977 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)
979 reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
980 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
981 reg1[0] = put_dhcp_opts();
982 put_dhcp_opts requires offerip to be specified.
983 reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
984 Syntax error at `x' expecting DHCPv4 option name.
985 reg1[0] = put_dhcp_opts(router = 10.0.0.1);
986 put_dhcp_opts requires offerip to be specified.
987 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
988 Syntax error at `"hi"'.
989 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
990 Syntax error at `xyzzy' expecting DHCPv4 option name.
991 reg1[0] = put_dhcp_opts(offerip="xyzzy");
992 DHCPv4 option offerip requires numeric value.
993 reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
994 DHCPv4 option domain requires string value.
997 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; };
998 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
999 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)
1003 get_nd(outport, ip6.dst);
1004 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[]
1005 has prereqs eth.type == 0x86dd
1006 get_nd(inport, xxreg0);
1007 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[]
1009 Syntax error at `;' expecting `('.
1011 Syntax error at `)' expecting field name.
1013 Syntax error at `)' expecting `,'.
1014 get_nd(inport ip6.dst);
1015 Syntax error at `ip6.dst' expecting `,'.
1016 get_nd(inport, ip6.dst;
1017 Syntax error at `;' expecting `)'.
1018 get_nd(inport, eth.dst);
1019 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1020 get_nd(inport, outport);
1021 Cannot use string field outport where numeric field is required.
1022 get_nd(xxreg0, ip6.dst);
1023 Cannot use numeric field xxreg0 where string field is required.
1026 put_nd(inport, nd.target, nd.sll);
1027 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[]
1028 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)
1031 reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
1032 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)
1033 reg1[0] = put_dhcpv6_opts();
1034 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1035 reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1036 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
1037 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)
1038 reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1039 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
1040 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)
1041 reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
1042 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)
1043 reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1044 Syntax error at `x' expecting DHCPv6 option name.
1045 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1046 Syntax error at `"hi"'.
1047 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1048 Syntax error at `xyzzy' expecting DHCPv6 option name.
1049 reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1050 DHCPv6 option ia_addr requires numeric value.
1051 reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1052 DHCPv6 option domain_search requires string value.
1056 encodes as set_queue:0
1058 encodes as set_queue:61440
1060 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1063 reg1[0] = dns_lookup();
1064 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1066 reg1[0] = dns_lookup("foo");
1067 dns_lookup doesn't take any parameters
1069 # Contradictionary prerequisites (allowed but not useful):
1070 ip4.src = ip6.src[0..31];
1071 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1072 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1073 ip4.src <-> ip6.src[0..31];
1074 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[]
1075 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1077 # Miscellaneous negative tests.
1079 Syntax error at `;'.
1081 Syntax error at `xyzzy' expecting action.
1083 Syntax error at `123'.
1085 Syntax error at `xyzzy' expecting action.
1087 Syntax error at end of input expecting `;'.
1089 sed '/^[[ ]]/d' test-cases.txt > input.txt
1090 cp test-cases.txt expout
1091 AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1094 AT_BANNER([OVN end-to-end tests])
1096 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1097 AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
1098 AT_KEYWORDS([ovnarp])
1099 AT_SKIP_IF([test $HAVE_PYTHON = no])
1102 # Create hypervisors hv[123].
1103 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1104 # Add all of the vifs to a single logical switch lsw0.
1105 # Turn on port security on all the vifs except vif[123]1.
1106 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1107 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1108 ovn-nbctl ls-add lsw0
1113 ovs-vsctl add-br br-phys
1114 ovn_attach n1 br-phys 192.168.0.$i
1117 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
1118 ovn-nbctl lsp-add lsw0 lp$i$j
1119 if test $j = 1; then
1120 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
1122 if test $j = 3; then
1123 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1125 ip_addrs="192.168.0.$i$j"
1127 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1128 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
1132 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1133 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1134 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
1135 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\"
1136 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
1138 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1139 # packets for ARP resolution (native tunneling doesn't queue packets
1140 # for ARP resolution).
1143 # Allow some time for ovn-northd and ovn-controller to catch up.
1144 # XXX This should be more systematic.
1147 # Make sure there is no attempt to adding duplicated flows by ovn-controller
1148 AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1149 AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1150 AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1152 # Given the name of a logical port, prints the name of the hypervisor
1153 # on which it is located.
1158 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1160 # This shell function causes a packet to be received on INPORT. The packet's
1161 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1162 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1163 # more) list the VIFs on which the packet should be received. INPORT and the
1164 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1171 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1172 hv=`vif_to_hv $inport`
1174 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1176 echo $packet >> $outport.expected
1180 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1182 # Causes a packet to be received on INPORT. The packet is an ARP
1183 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1184 # it should be the hardware address of the target to expect to receive in an
1185 # ARP reply; otherwise no reply is expected.
1187 # INPORT is an logical switch port number, e.g. 11 for vif11.
1188 # SHA and REPLY_HA are each 12 hex digits.
1189 # SPA and TPA are each 8 hex digits.
1191 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1192 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1193 hv=`vif_to_hv $inport`
1194 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1196 if test X$reply_ha = X; then
1197 # Expect to receive the broadcast ARP on the other logical switch ports
1198 # if no reply is expected.
1202 if test $i$j != $inport; then
1203 echo $request >> $i$j.expected
1208 # Expect to receive the reply, if any.
1209 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1210 echo $reply >> $inport.expected
1215 printf "%02x%02x%02x%02x" "$@"
1218 # Send packets between all pairs of source and destination ports:
1220 # 1. Unicast packets are delivered to exactly one logical switch port
1221 # (except that packets destined to their input ports are dropped).
1223 # 2. Broadcast and multicast are delivered to all logical switch ports
1224 # except the input port.
1226 # 3. When port security is turned on, the switch drops packets from the wrong
1229 # 4. The switch drops all packets with a VLAN tag.
1231 # 5. The switch drops all packets with a multicast source address. (This only
1232 # affects behavior when port security is turned off, since otherwise port
1233 # security would drop the packet anyway.)
1235 # 6. The switch delivers packets with an unknown destination to logical
1236 # switch ports with "unknown" among their MAC addresses (and port
1237 # security disabled).
1239 # 7. The switch drops unicast packets that violate an ACL.
1241 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1243 # 9. OVN generates responses to ARP requests for known IPs, except for
1244 # requests from a port for the port's own IP.
1246 # 10. No response to ARP requests for unknown IPs.
1259 if test $d != $s; then unicast=$d; else unicast=; fi
1260 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1262 if test $d != $s && test $js = 1; then
1267 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1269 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1270 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
1271 if test $d = $s || (test $js = 1 && test $d = 33); then
1272 # Source of 11, 21, or 31 and dest of 33 should be dropped
1273 # due to the 4th ACL that uses address_set(set1).
1278 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1279 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1280 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
1281 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
1283 test_packet $s f000000000$d f00000000055 810000091234 #4
1284 test_packet $s f000000000$d 0100000000$s $s$d #5
1286 if test $d != $s && test $jd = 1; then
1287 unknown="$unknown $d"
1289 bcast="$bcast $unicast"
1290 bacl2="$bacl2 $acl2"
1291 bacl3="$bacl3 $acl3"
1293 sip=`ip_to_hex 192 168 0 $i$j`
1294 tip=`ip_to_hex 192 168 0 $id$jd`
1295 tip_unknown=`ip_to_hex 11 11 11 11`
1296 if test $d != $s; then
1297 reply_ha=f000000000$d
1301 test_arp $s f000000000$s $sip $tip $reply_ha #9
1302 test_arp $s f000000000$s $sip $tip_unknown #10
1304 if test $jd = 3; then
1305 # lsp[123]3 has an additional ip 192.169.0.[123]3.
1306 tip=`ip_to_hex 192 169 0 $id$jd`
1307 test_arp $s f000000000$s $sip $tip $reply_ha #9
1312 # Broadcast and multicast.
1313 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1314 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
1315 if test $js = 1; then
1316 bcast_impersonate=$bcast
1320 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1322 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1324 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1325 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1326 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1327 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1328 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1329 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1333 # set address for lp13 with invalid characters.
1334 # lp13 should be configured with only 192.168.0.13.
1335 ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
1337 # Allow some time for ovn-northd and ovn-controller to catch up.
1338 # XXX This should be more systematic.
1341 sip=`ip_to_hex 192 168 0 11`
1342 tip=`ip_to_hex 192 168 0 13`
1343 test_arp 11 f00000000011 $sip $tip f00000000013
1345 tip=`ip_to_hex 192 169 0 13`
1346 #arp request for 192.169.0.13 should be flooded
1347 test_arp 11 f00000000011 $sip $tip
1349 # dump information and flows with counters
1350 ovn-sbctl dump-flows -- list multicast_group
1352 echo "------ hv1 dump ------"
1353 as hv1 ovs-vsctl show
1354 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1356 echo "------ hv2 dump ------"
1357 as hv2 ovs-vsctl show
1358 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1360 echo "------ hv3 dump ------"
1361 as hv3 ovs-vsctl show
1362 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
1364 # Now check the packets actually received against the ones expected.
1367 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1371 OVN_CLEANUP([hv1],[hv2],[hv3])
1375 AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1376 AT_SKIP_IF([test $HAVE_PYTHON = no])
1379 # Create a logical switch and some logical ports.
1380 # Turn on port security on all lports except ls1.
1381 # Make ls1 a destination for unknown MACs.
1382 # Add some ACLs for Ethertypes 1234, 1235, 1236.
1383 ovn-nbctl ls-add lsw0
1384 ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1386 ovn-nbctl lsp-add lsw0 lp$i
1388 ovn-nbctl --wait=sb sync
1390 ovn-sbctl lsp-bind lp$i hv0
1391 if test $i = 1; then
1392 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
1394 if test $i = 3; then
1395 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1397 ip_addrs="192.168.0.$i"
1399 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1400 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
1403 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1404 ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1405 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1406 ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1407 ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1409 ovn-nbctl --wait=sb sync
1410 on_exit 'kill `cat ovn-trace.pid`'
1411 ovn-trace --detach --pidfile --no-chdir
1413 # test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1415 # This shell function causes a packet to be received on INPORT. The packet's
1416 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1417 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1418 # more) list the VIFs on which the packet should be received. INPORT and the
1419 # OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1421 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1422 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1425 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1426 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1431 echo "output(\"lp$outport\");"
1434 AT_CAPTURE_FILE([trace])
1435 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1438 # test_arp INPORT SHA SPA TPA [REPLY_HA]
1440 # Causes a packet to be received on INPORT. The packet is an ARP
1441 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1442 # it should be the hardware address of the target to expect to receive in an
1443 # ARP reply; otherwise no reply is expected.
1445 # INPORT is an logical switch port number, e.g. 11 for vif11.
1446 # SHA and REPLY_HA are each 12 hex digits.
1447 # SPA and TPA are each 8 hex digits.
1449 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1451 local request="inport == \"lp$inport\"
1452 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1453 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
1454 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
1456 if test -z "$reply_ha"; then
1460 if test $i != $inport; then
1461 reply="${reply}output(\"lp$i\");
1468 eth.src = $reply_ha;
1471 arp.sha = $reply_ha;
1474 output(\"lp$inport\");
1478 AT_CAPTURE_FILE([trace])
1479 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1482 # Send packets between all pairs of source and destination ports:
1484 # 1. Unicast packets are delivered to exactly one logical switch port
1485 # (except that packets destined to their input ports are dropped).
1487 # 2. Broadcast and multicast are delivered to all logical switch ports
1488 # except the input port.
1490 # 3. When port security is turned on, the switch drops packets from the wrong
1493 # 4. The switch drops all packets with a VLAN tag.
1495 # 5. The switch drops all packets with a multicast source address. (This only
1496 # affects behavior when port security is turned off, since otherwise port
1497 # security would drop the packet anyway.)
1499 # 6. The switch delivers packets with an unknown destination to logical
1500 # switch ports with "unknown" among their MAC addresses (and port
1501 # security disabled).
1503 # 7. The switch drops unicast packets that violate an ACL.
1505 # 8. The switch drops multicast and broadcast packets that violate an ACL.
1507 # 9. OVN generates responses to ARP requests for known IPs, except for
1508 # requests from a port for the port's own IP.
1510 # 10. No response to ARP requests for unknown IPs.
1520 if test $d != $s; then unicast=$d; else unicast=; fi
1521 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1523 if test $d != $s && test $s = 1; then
1528 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1530 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1531 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1532 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1533 # Source of 1 or 2 and dest of 3 should be dropped
1534 # due to the 4th ACL that uses address_set(set1).
1541 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1542 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1543 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1544 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1546 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1547 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1549 if test $d != $s && test $d = 1; then
1550 unknown="$unknown $d"
1552 bcast="$bcast $unicast"
1553 bacl2="$bacl2 $acl2"
1554 bacl3="$bacl3 $acl3"
1558 tip_unknown=11.11.11.11
1559 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1560 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1561 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1563 if test $d = 3; then
1564 # lp3 has an additional ip 192.169.0.[123]3.
1566 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
1570 # Broadcast and multicast.
1571 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1572 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1573 if test $s = 1; then
1574 bcast_impersonate=$bcast
1578 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1580 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1583 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1584 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1585 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1588 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1589 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1590 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1595 # 2 hypervisors, 4 logical ports per HV
1596 # 2 locally attached networks (one flat, one vlan tagged over same device)
1597 # 2 ports per HV on each network
1598 AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
1599 AT_SKIP_IF([test $HAVE_PYTHON = no])
1602 # In this test cases we create 3 switches, all connected to same
1603 # physical network (through br-phys on each HV). Each switch has
1604 # VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1605 # of VIF port name indicates the hypervisor it is bound to, e.g.
1606 # lp23 means VIF 3 on hv2.
1608 # Each switch's VLAN tag and their logical switch ports are:
1611 # - ports: lp11, lp12, lp21, lp22
1614 # - tagged with VLAN 101
1615 # - ports: lp13, lp14, lp23, lp24
1618 # - ports: lp15, lp25
1620 # Note: a localnet port is created for each switch to connect to
1625 ovn-nbctl ls-add $ls_name
1627 if test $i -eq 2; then
1628 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
1630 ovn-nbctl lsp-add $ls_name $ln_port_name
1632 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1633 ovn-nbctl lsp-set-type $ln_port_name localnet
1634 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
1639 # Prints the name of the logical switch that contains LSP.
1642 lp?[[12]]) echo ls1 ;; dnl (
1643 lp?[[34]]) echo ls2 ;; dnl (
1644 lp?5) echo ls3 ;; dnl (
1645 *) AT_FAIL_IF([:]) ;;
1653 ovs-vsctl add-br br-phys
1654 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1655 ovn_attach n1 br-phys 192.168.0.$i
1657 for j in 1 2 3 4 5; do
1658 ovs-vsctl add-port br-int vif$i$j -- \
1659 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1660 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1661 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1665 ls_name=$(lsp_to_ls $lsp_name)
1667 ovn-nbctl lsp-add $ls_name $lsp_name
1668 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1669 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
1671 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
1674 ovn-nbctl --wait=sb sync
1675 ovn-sbctl dump-flows
1679 # XXX This is now the 3rd copy of these functions in this file ...
1681 # Given the name of a logical port, prints the name of the hypervisor
1682 # on which it is located.
1687 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT
1689 # This shell function causes a packet to be received on INPORT. The packet's
1690 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1691 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1692 # logical switch port numbers, e.g. 11 for vif11.
1694 # EOUT is the end-to-end output port, that is, where the packet will end up
1695 # after possibly bouncing through one or more localnet ports. LOUT is the
1696 # logical output port, which might be a localnet port, as seen by ovn-trace
1697 # (which doesn't know what localnet ports are connected to and therefore can't
1698 # figure out the end-to-end answer).
1700 for j in 1 2 3 4 5; do
1705 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1708 # First try tracing the packet.
1709 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1710 if test $lout != drop; then
1711 echo "output(\"$lout\");"
1713 AT_CAPTURE_FILE([trace])
1714 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1716 # Then actually send a packet, for an end-to-end test.
1717 local packet=$(echo $dst$src | sed 's/://g')${eth}
1718 hv=`vif_to_hv $inport`
1720 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1721 if test $eout != drop; then
1722 echo $packet >> ${eout#lp}.expected
1726 # lp11 and lp21 are on the same network (phys, untagged)
1727 # and on different hypervisors
1728 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1729 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
1731 # lp11 and lp12 are on the same network (phys, untagged)
1732 # and on the same hypervisor
1733 test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1734 test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
1736 # lp13 and lp23 are on the same network (phys, VLAN 101)
1737 # and on different hypervisors
1738 test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1739 test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
1741 # lp13 and lp14 are on the same network (phys, VLAN 101)
1742 # and on the same hypervisor
1743 test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1744 test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
1746 # lp11 and lp15 are on the same network (phys, untagged),
1747 # same hypervisor, and on different switches
1748 test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1749 test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
1751 # lp11 and lp25 are on the same network (phys, untagged),
1752 # different hypervisors, and on different switches
1753 test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1754 test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
1756 # Ports that should not be able to communicate
1757 test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1758 test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1759 test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1760 test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1761 test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1762 test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1763 test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1764 test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
1766 # Dump a bunch of info helpful for debugging if there's a failure.
1768 echo "------ OVN dump ------"
1772 echo "------ hv1 dump ------"
1773 as hv1 ovs-vsctl show
1774 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1776 echo "------ hv2 dump ------"
1777 as hv2 ovs-vsctl show
1778 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1780 # Now check the packets actually received against the ones expected.
1782 for j in 1 2 3 4 5; do
1783 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
1787 OVN_CLEANUP([hv1],[hv2])
1791 AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1793 AT_SKIP_IF([test $HAVE_PYTHON = no])
1796 # Configure the Northbound database
1797 ovn-nbctl ls-add lsw0
1799 ovn-nbctl lsp-add lsw0 lp1
1800 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1802 ovn-nbctl lsp-add lsw0 lp2
1803 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1805 ovn-nbctl lsp-add lsw0 lp-vtep
1806 ovn-nbctl lsp-set-type lp-vtep vtep
1807 ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1808 ovn-nbctl lsp-set-addresses lp-vtep unknown
1810 # lpr, lr and lrp1 are used for the ARP request handling test only.
1811 ovn-nbctl lsp-add lsw0 lpr
1813 ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
1814 ovn-nbctl set Logical_Switch_Port lpr type=router \
1815 options:router-port=lrp1 \
1816 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
1819 net_add n1 # Network to connect hv1, hv2, and vtep
1820 net_add n2 # Network to connect vtep and hv3
1822 # Create hypervisor hv1 connected to n1
1825 ovs-vsctl add-br br-phys
1826 ovn_attach n1 br-phys 192.168.0.1
1827 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
1829 # Create hypervisor hv2 connected to n1
1832 ovs-vsctl add-br br-phys
1833 ovn_attach n1 br-phys 192.168.0.2
1834 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
1837 # Start the vtep emulator with a leg in both networks
1841 ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1842 ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1844 ovs-vsctl add-br br-phys
1845 net_attach n1 br-phys
1847 mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1848 arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1849 ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1850 ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1852 ovs-vsctl add-br br-vtep
1853 net_attach n2 br-vtep
1855 vtep-ctl add-ps br-vtep
1856 vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1857 vtep-ctl add-ls lsw0
1859 start_daemon ovs-vtep br-vtep
1860 start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1862 OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
1864 OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1866 # It takes more time for the update to be processed by ovs-vtep.
1869 # Add hv3 on the other side of the vtep
1872 ovs-vsctl add-br br-phys
1873 net_attach n2 br-phys
1875 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
1877 # Pre-populate the hypervisors' ARP tables so that we don't lose any
1878 # packets for ARP resolution (native tunneling doesn't queue packets
1879 # for ARP resolution).
1882 # Allow some time for ovn-northd and ovn-controller to catch up.
1883 # XXX This should be more systematic.
1886 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
1888 # This shell function causes a packet to be received on INPORT. The packet's
1889 # content has Ethernet destination DST and source SRC (each exactly 12 hex
1890 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1891 # more) list the VIFs on which the packet should be received. INPORT and the
1892 # OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
1897 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1898 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1901 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1903 echo $packet >> $outport.expected
1907 # Send packets between all pairs of source and destination ports:
1909 # 1. Unicast packets are delivered to exactly one logical switch port
1910 # (except that packets destined to their input ports are dropped).
1912 # 2. Broadcast and multicast are delivered to all logical switch ports
1913 # except the input port.
1915 # 3. The switch delivers packets with an unknown destination to logical
1916 # switch ports with "unknown" among their MAC addresses (and port
1917 # security disabled).
1922 if test $d != $s; then unicast=$d; else unicast=; fi
1923 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1925 # The vtep (vif3) is the only one configured for "unknown"
1926 if test $d != $s && test $d = 3; then
1927 unknown="$unknown $d"
1929 bcast="$bcast $unicast"
1932 # Broadcast and multicast.
1933 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1934 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
1936 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1939 # ARP request should not be responded to by logical switch router
1940 # type arp responder on HV1 and HV2 and should reach directly to
1943 printf "%02x%02x%02x%02x" "$@"
1946 spa=`ip_to_hex 192 168 1 2`
1947 tpa=`ip_to_hex 192 168 1 1`
1948 request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1949 as hv3 ovs-appctl netdev-dummy/receive vif3 $request
1950 echo $request >> 1.expected
1951 echo $request >> 2.expected
1953 # dump information with counters
1954 echo "------ OVN dump ------"
1958 echo "---------SB dump-----"
1959 ovn-sbctl list datapath_binding
1960 echo "---------------------"
1961 ovn-sbctl list port_binding
1962 echo "---------------------"
1963 ovn-sbctl dump-flows
1965 echo "------ hv1 dump ------"
1966 as hv1 ovs-vsctl show
1967 as hv1 ovs-ofctl -O OpenFlow13 show br-int
1968 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1970 echo "------ hv2 dump ------"
1971 as hv2 ovs-vsctl show
1972 as hv2 ovs-ofctl -O OpenFlow13 show br-int
1973 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1975 echo "------ hv3 dump ------"
1976 as hv3 ovs-vsctl show
1977 # note: hv3 has no logical port bind, thus it should not have br-int
1978 AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1979 [ovs-ofctl: br-int is not a bridge or a socket
1982 # Now check the packets actually received against the ones expected.
1984 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
1987 # Gracefully terminate daemons
1988 OVN_CLEANUP([hv1],[hv2],[vtep])
1989 OVN_CLEANUP_VSWITCH([hv3])
1993 # Similar test to "hardware GW"
1994 AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1995 AT_SKIP_IF([test $HAVE_PYTHON = no])
1998 # Configure the Northbound database
1999 ovn-nbctl ls-add lsw0
2001 ovn-nbctl lsp-add lsw0 lp1
2002 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2004 ovn-nbctl lsp-add lsw0 lp2
2005 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2007 ovn-nbctl lsp-add lsw0 lp-gw
2008 ovn-nbctl lsp-set-type lp-gw l2gateway
2009 ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
2010 ovn-nbctl lsp-set-addresses lp-gw unknown
2012 net_add n1 # Network to connect hv1, hv2, and gw
2013 net_add n2 # Network to connect gw and hv3
2015 # Create hypervisor hv1 connected to n1
2018 ovs-vsctl add-br br-phys
2019 ovn_attach n1 br-phys 192.168.0.1
2020 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
2022 # Create hypervisor hv2 connected to n1
2025 ovs-vsctl add-br br-phys
2026 ovn_attach n1 br-phys 192.168.0.2
2027 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
2029 # Create hypervisor hv_gw connected to n1 and n2
2030 # connect br-phys bridge to n1; connect hv-gw bridge to n2
2033 ovs-vsctl add-br br-phys
2034 ovn_attach n1 br-phys 192.168.0.3
2035 ovs-vsctl add-br br-phys2
2036 net_attach n2 br-phys2
2037 ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2039 # Add hv3 on the other side of the GW
2042 ovs-vsctl add-br br-phys
2043 net_attach n2 br-phys
2044 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
2047 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2048 # packets for ARP resolution (native tunneling doesn't queue packets
2049 # for ARP resolution).
2052 # Allow some time for ovn-northd and ovn-controller to catch up.
2053 # XXX This should be more systematic.
2056 # test_packet INPORT DST SRC ETHTYPE OUTPORT...
2058 # This shell function causes a packet to be received on INPORT. The packet's
2059 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2060 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2061 # more) list the VIFs on which the packet should be received. INPORT and the
2062 # OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
2067 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2068 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2071 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2073 echo $packet >> $outport.expected
2077 # Send packets between all pairs of source and destination ports:
2079 # 1. Unicast packets are delivered to exactly one lport (except that packets
2080 # destined to their input ports are dropped).
2082 # 2. Broadcast and multicast are delivered to all lports except the input port.
2084 # 3. The lswitch delivers packets with an unknown destination to lports with
2085 # "unknown" among their MAC addresses (and port security disabled).
2090 if test $d != $s; then unicast=$d; else unicast=; fi
2091 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2093 # The vtep (vif3) is the only one configured for "unknown"
2094 if test $d != $s && test $d = 3; then
2095 unknown="$unknown $d"
2097 bcast="$bcast $unicast"
2100 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2101 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2102 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2105 echo "------ ovn-nbctl show ------"
2107 echo "------ ovn-sbctl show ------"
2110 echo "------ hv1 ------"
2111 as hv1 ovs-vsctl show
2112 echo "------ hv1 br-int ------"
2113 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2114 echo "------ hv1 br-phys ------"
2115 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2117 echo "------ hv2 ------"
2118 as hv2 ovs-vsctl show
2119 echo "------ hv2 br-int ------"
2120 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2121 echo "------ hv2 br-phys ------"
2122 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2124 echo "------ hv_gw ------"
2125 as hv_gw ovs-vsctl show
2126 echo "------ hv_gw br-phys ------"
2127 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2128 echo "------ hv_gw br-phys2 ------"
2129 as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2131 echo "------ hv3 ------"
2132 as hv3 ovs-vsctl show
2133 echo "------ hv3 br-phys ------"
2134 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2136 # Now check the packets actually received against the ones expected.
2138 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
2142 # 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2143 AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2144 AT_SKIP_IF([test $HAVE_PYTHON = no])
2149 # Three logical switches ls1, ls2, ls3.
2150 # One logical router lr0 connected to ls[123],
2151 # with nine subnets, three per logical switch:
2153 # lrp11 on ls1 for subnet 192.168.11.0/24
2154 # lrp12 on ls1 for subnet 192.168.12.0/24
2155 # lrp13 on ls1 for subnet 192.168.13.0/24
2157 # lrp33 on ls3 for subnet 192.168.33.0/24
2159 # 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2160 # digits are the subnet and the last digit distinguishes the VIF.
2162 ovn-nbctl ls-add ls$i
2165 # Add "unknown" to MAC addresses for lp?11, so packets for
2166 # MAC-IP bindings discovered via ARP later have somewhere to go.
2167 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2170 -- lsp-add ls$i lp$i$j$k \
2171 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2172 192.168.$i$j.$k" $unknown
2177 ovn-nbctl lr-add lr0
2180 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
2182 -- lsp-add ls$i lrp$i$j-attachment \
2183 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
2184 options:router-port=lrp$i$j \
2185 addresses='"00:00:00:00:ff:'$i$j'"'
2189 ovn-nbctl set Logical_Switch_Port lrp33-attachment \
2190 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2194 # Three hypervisors hv[123].
2195 # lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2196 # lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2197 # lp?3[123] all on hv3.
2200 # Given the name of a logical port, prints the name of the hypervisor
2201 # on which it is located.
2204 ?11) echo 1 ;; dnl (
2205 ?12 | ?21 | ?22) echo 2 ;; dnl (
2206 ?13 | ?23 | ?3?) echo 3 ;;
2210 # Given the name of a logical port, prints the name of its logical router
2211 # port, e.g. "vif_to_lrp 123" yields 12.
2216 # Given the name of a logical port, prints the name of its logical
2217 # switch, e.g. "vif_to_ls 123" yields 1.
2226 ovs-vsctl add-br br-phys
2227 ovn_attach n1 br-phys 192.168.0.$i
2232 hv=`vif_to_hv $i$j$k`
2233 as hv$hv ovs-vsctl \
2234 -- add-port br-int vif$i$j$k \
2235 -- set Interface vif$i$j$k \
2236 external-ids:iface-id=lp$i$j$k \
2237 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2238 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2239 ofport-request=$i$j$k
2244 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2245 # packets for ARP resolution (native tunneling doesn't queue packets
2246 # for ARP resolution).
2249 # Allow some time for ovn-northd and ovn-controller to catch up.
2250 # XXX This should be more systematic.
2253 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2255 # This shell function causes a packet to be received on INPORT. The packet's
2256 # content has Ethernet destination DST and source SRC (each exactly 12 hex
2257 # digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2258 # more) list the VIFs on which the packet should be received. INPORT and the
2259 # OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
2268 # This packet has bad checksums but logical L3 routing doesn't check.
2269 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2270 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2271 shift; shift; shift; shift; shift
2272 hv=hv`vif_to_hv $inport`
2273 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2274 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2275 in_ls=`vif_to_ls $inport`
2276 in_lrp=`vif_to_lrp $inport`
2278 out_ls=`vif_to_ls $outport`
2279 if test $in_ls = $out_ls; then
2280 # Ports on the same logical switch receive exactly the same packet.
2283 # Routing decrements TTL and updates source and dest MAC
2285 out_lrp=`vif_to_lrp $outport`
2286 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2287 fi >> $outport.expected
2291 as hv1 ovs-vsctl --columns=name,ofport list interface
2292 as hv1 ovn-sbctl list port_binding
2293 as hv1 ovn-sbctl list datapath_binding
2294 as hv1 ovn-sbctl dump-flows
2295 as hv1 ovs-ofctl dump-flows br-int
2297 # Send IP packets between all pairs of source and destination ports:
2299 # 1. Unicast IP packets are delivered to exactly one logical switch port
2300 # (except that packets destined to their input ports are dropped).
2302 # 2. Broadcast IP packets are delivered to all logical switch ports
2303 # except the input port.
2305 printf "%02x%02x%02x%02x" "$@"
2313 sip=`ip_to_hex 192 168 $is$js $ks`
2318 dip=`ip_to_hex 192 168 $id$jd $kd`
2319 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2320 if test $d != $s; then unicast=$d; else unicast=; fi
2322 test_ip $s $smac $dmac $sip $dip $unicast #1
2324 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2328 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2333 # 3. Send an IP packet from every logical port to every other subnet,
2334 # to an IP address that does not have a static IP-MAC binding.
2335 # This should generate a broadcast ARP request for the destination
2336 # IP address in the destination subnet.
2342 sip=`ip_to_hex 192 168 $is$js $ks`
2345 if test $is$js = $id$jd; then
2350 dmac=00000000ff$is$js
2351 # Calculate a 4th octet for the destination that is
2352 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2353 # that have static MAC bindings, and fits in the range
2355 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2356 dip=`ip_to_hex 192 168 $id$jd $o4`
2357 test_ip $s $smac $dmac $sip $dip
2359 # Every LP on the destination subnet's lswitch should
2360 # receive the ARP request.
2361 lrmac=00000000ff$id$jd
2362 lrip=`ip_to_hex 192 168 $id$jd 254`
2363 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2364 for jd2 in 1 2 3; do
2366 echo $arp >> $id$jd2$kd.expected
2375 # test_arp INPORT SHA SPA TPA [REPLY_HA]
2377 # Causes a packet to be received on INPORT. The packet is an ARP
2378 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2379 # it should be the hardware address of the target to expect to receive in an
2380 # ARP reply; otherwise no reply is expected.
2382 # INPORT is an logical switch port number, e.g. 11 for vif11.
2383 # SHA and REPLY_HA are each 12 hex digits.
2384 # SPA and TPA are each 8 hex digits.
2386 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2387 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2388 hv=hv`vif_to_hv $inport`
2389 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2390 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2392 # Expect to receive the broadcast ARP on the other logical switch ports if
2393 # IP address is not configured to the switch patch port.
2394 local i=`vif_to_ls $inport`
2398 # 192.168.33.254 is configured to the switch patch port for lrp33,
2399 # so no ARP flooding expected for it.
2400 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
2401 echo $request >> $i$j$k.expected
2406 # Expect to receive the reply, if any.
2407 if test X$reply_ha != X; then
2408 lrp=`vif_to_lrp $inport`
2409 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2410 echo $reply >> $inport.expected
2414 # Test router replies to ARP requests from all source ports:
2416 # 4. Router replies to query for its MAC address from port's own IP address.
2418 # 5. Router replies to query for its MAC address from any random IP address
2421 # 6. Router replies to query for its MAC address from another subnet.
2423 # 7. No reply to query for IP address other than router IP.
2427 smac=f00000000$i$j$k # Source MAC
2428 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2429 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2430 rmac=00000000ff$i$j # Router MAC
2431 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2432 test_arp $i$j$k $smac $sip $rip $rmac #4
2433 test_arp $i$j$k $smac $otherip $rip $rmac #5
2434 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2435 test_arp $i$j$k $smac $sip $otherip #7
2440 # Allow some time for packet forwarding.
2441 # XXX This can be improved.
2444 # 8. Generate an ARP reply for each of the IP addresses ARPed for
2447 # Here, the $s is the VIF that originated the ARP request and $d is
2448 # the VIF that sends the ARP reply, which is somewhat backward but
2449 # it means that $s and $d are the same as #3.
2450 : > mac_bindings.expected
2457 if test $is$js = $id$jd; then
2464 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2465 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2466 host_mac=8000000000$o4
2468 lrmac=00000000ff$id$jd
2469 lrip=`ip_to_hex 192 168 $id$jd 254`
2471 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2477 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2478 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2479 #as $hv ovs-ofctl dump-flows br-int table=19
2481 host_ip_pretty=192.168.$id$jd.$o4
2482 host_mac_pretty=80:00:00:00:00:$o4
2483 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2490 # Allow some time for packet forwarding.
2491 # XXX This can be improved.
2494 # 9. Send an IP packet from every logical port to every other subnet. These
2495 # are the same packets already sent as #3, but now the destinations' IP-MAC
2496 # bindings have been discovered via ARP, so instead of provoking an ARP
2497 # request, these packets now get routed to their destinations (which don't
2498 # have static MAC bindings, so they go to the port we've designated as
2499 # accepting "unknown" MACs.)
2505 sip=`ip_to_hex 192 168 $is$js $ks`
2508 if test $is$js = $id$jd; then
2513 dmac=00000000ff$is$js
2514 # Calculate a 4th octet for the destination that is
2515 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2516 # that have static MAC bindings, and fits in the range
2518 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2519 dip=`ip_to_hex 192 168 $id$jd $o4`
2520 test_ip $s $smac $dmac $sip $dip
2522 # Expect the packet egress.
2523 host_mac=8000000000$o4
2526 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
2533 ovn-sbctl -f csv -d bare --no-heading \
2534 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2536 # Now check the packets actually received against the ones expected.
2540 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2546 # Check the MAC bindings against those expected.
2547 AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2550 # Gracefully terminate daemons
2551 OVN_CLEANUP([hv1], [hv2], [hv3])
2555 # 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2556 AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
2557 AT_SKIP_IF([test $HAVE_PYTHON = no])
2560 # Create hypervisors hv[123].
2561 # Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2562 # Add all of the vifs to a single logical switch lsw0.
2563 # Turn off port security on vifs vif[123]1
2564 # Turn on l2 port security on vifs vif[123]2
2565 # Turn of l2 and l3 port security on vifs vif[123]3
2566 # Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
2567 ovn-nbctl ls-add lsw0
2572 ovs-vsctl add-br br-phys
2573 ovn_attach n1 br-phys 192.168.0.$i
2576 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
2577 ovn-nbctl lsp-add lsw0 lp$i$j
2578 if test $j = 1; then
2579 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
2580 elif test $j = 2; then
2581 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2582 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
2584 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
2585 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2586 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2591 # Pre-populate the hypervisors' ARP tables so that we don't lose any
2592 # packets for ARP resolution (native tunneling doesn't queue packets
2593 # for ARP resolution).
2596 # Allow some time for ovn-northd and ovn-controller to catch up.
2597 # XXX This should be more systematic.
2600 # Given the name of a logical port, prints the name of the hypervisor
2601 # on which it is located.
2612 # test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2614 # This shell function causes an ip packet to be received on INPORT.
2615 # The packet's content has Ethernet destination DST and source SRC
2616 # (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2617 # The OUTPORTs (zero or more) list the VIFs on which the packet should
2618 # be received. INPORT and the OUTPORTs are specified as logical switch
2619 # port numbers, e.g. 11 for vif11.
2621 # This packet has bad checksums but logical L3 routing doesn't check.
2622 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2623 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2624 shift; shift; shift; shift; shift
2625 hv=`vif_to_hv $inport`
2626 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2627 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2629 echo $packet >> $outport.expected
2633 # test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2635 # Causes a packet to be received on INPORT. The packet is an ARP
2636 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2637 # it should be the hardware address of the target to expect to receive in an
2638 # ARP reply; otherwise no reply is expected.
2640 # INPORT is an logical switch port number, e.g. 11 for vif11.
2641 # SHA and REPLY_HA are each 12 hex digits.
2642 # SPA and TPA are each 8 hex digits.
2644 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2645 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2646 hv=`vif_to_hv $inport`
2647 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2648 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2649 if test $drop != 1; then
2650 if test X$reply_ha = X; then
2651 # Expect to receive the broadcast ARP on the other logical switch ports
2652 # if no reply is expected.
2656 if test $i$j != $inport; then
2657 echo $request >> $i$j.expected
2662 # Expect to receive the reply, if any.
2663 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2664 echo $reply >> $inport.expected
2669 # test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2670 # This function is similar to test_ip() except that it sends
2673 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2674 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2675 shift; shift; shift; shift; shift
2676 hv=`vif_to_hv $inport`
2677 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2678 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2680 echo $packet >> $outport.expected
2684 # test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2685 # This function is similar to test_ipv6() except it specifies the ICMPv6 type
2686 # of the test packet
2688 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2689 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2690 shift; shift; shift; shift; shift; shift
2691 hv=`vif_to_hv $inport`
2692 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2693 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2695 echo $packet >> $outport.expected
2700 printf "%02x%02x%02x%02x" "$@"
2704 sip=`ip_to_hex 192 168 0 12`
2705 tip=`ip_to_hex 192 168 0 13`
2706 # the arp packet should be allowed even if lp[123]1 is
2707 # not configured with mac f00000000023 and ip 192.168.0.12
2709 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2711 if test $i != $j; then
2712 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2718 sip=`ip_to_hex 192 168 0 12`
2719 tip=`ip_to_hex 192 168 0 13`
2721 # arp packet should be allowed since lp22 is configured with
2723 test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2725 # arp packet should not be allowed since lp32 is not configured with
2727 test_arp 32 f00000000021 f00000000021 $sip $tip 1
2729 # arp packet with sha set to f00000000021 should not be allowed
2731 test_arp 12 f00000000012 f00000000021 $sip $tip 1
2733 # ip packets should be allowed and received since lp[123]2 do not
2734 # have l3 port security
2735 sip=`ip_to_hex 192 168 0 55`
2736 tip=`ip_to_hex 192 168 0 66`
2739 if test $i != $j; then
2740 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2745 # ipv6 packets should be received by lp[123]2
2746 # lp[123]1 can send ipv6 traffic as there is no port security
2747 sip=fe800000000000000000000000000000
2748 tip=ff020000000000000000000000000000
2751 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2755 # l2 and l3 port security
2756 sip=`ip_to_hex 192 168 0 13`
2757 tip=`ip_to_hex 192 168 0 22`
2758 # arp packet should be allowed since lp13 is configured with
2759 # f00000000013 and 192.168.0.13
2760 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2762 # the arp packet should be dropped because lp23 is not configured
2763 # with mac f00000000022
2764 sip=`ip_to_hex 192 168 0 13`
2765 tip=`ip_to_hex 192 168 0 22`
2766 test_arp 23 f00000000022 f00000000022 $sip $tip 1
2768 # the arp packet should be dropped because lp33 is not configured
2769 # with ip 192.168.0.55
2770 spa=`ip_to_hex 192 168 0 55`
2771 tpa=`ip_to_hex 192 168 0 22`
2772 test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2774 # ip packets should not be received by lp[123]3 since
2775 # l3 port security is enabled
2776 sip=`ip_to_hex 192 168 0 55`
2777 tip=`ip_to_hex 192 168 0 66`
2780 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2784 # ipv6 packets should be dropped for lp[123]3 since
2785 # it is configured with only ipv4 address
2786 sip=fe800000000000000000000000000000
2787 tip=ff020000000000000000000000000000
2790 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2793 # ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2794 # lp[123]1 can send ipv6 traffic as there is no port security
2796 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2799 # lp13 has extra port security with mac f0000000113 and ipv6 addr
2800 # fe80::ea2a:eaff:fe28:0012
2802 # ipv4 packet should be dropped for lp13 with mac f0000000113
2803 sip=`ip_to_hex 192 168 0 13`
2804 tip=`ip_to_hex 192 168 0 23`
2805 test_ip 13 f00000000113 f00000000023 $sip $tip
2807 # ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2808 # and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
2809 # lp11 can send ipv6 traffic as there is no port security
2810 sip=ee800000000000000000000000000000
2812 tip=fe80000000000000ea2aeafffe2800${i}3
2813 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
2817 # ipv6 packet should not be received by lp33 with mac f0000000333
2818 # and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2819 # configured with fe80::ea2a:eaff:fe28:0033
2820 # lp11 can send ipv6 traffic as there is no port security
2822 sip=ee800000000000000000000000000000
2823 tip=fe80000000000000ea2aeafffe280023
2824 test_ipv6 11 f00000000011 f00000000333 $sip $tip
2826 # ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2827 # and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
2828 # and should be dropped for any other ip6.src
2829 # lp21 can receive ipv6 traffic as there is no port security
2831 tip=ee800000000000000000000000000000
2833 sip=fe80000000000000ea2aeafffe2800${i}3
2834 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2836 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
2837 sip=00000000000000000000000000000000
2838 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2839 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2840 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2841 # Traffic to non-multicast traffic should be dropped
2842 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2843 # Traffic of other ICMPv6 types should be dropped
2844 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
2847 sip=ae80000000000000ea2aeafffe2800aa
2848 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2851 # configure lsp13 to send and received IPv4 packets with an address range
2852 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"
2856 sip=`ip_to_hex 10 0 0 13`
2857 tip=`ip_to_hex 192 168 0 22`
2858 # arp packet with inner ip 10.0.0.13 should be allowed for lsp13
2859 test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2861 sip=`ip_to_hex 10 0 0 14`
2862 tip=`ip_to_hex 192 168 0 23`
2863 # IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
2864 # with dst ip 192.168.0.23 should be allowed
2865 test_ip 13 f00000000013 f00000000023 $sip $tip 23
2867 sip=`ip_to_hex 192 168 0 33`
2868 tip=`ip_to_hex 10 0 0 15`
2869 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2870 # with dst ip 10.0.0.15 should be received by lsp13
2871 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2873 sip=`ip_to_hex 192 168 0 33`
2874 tip=`ip_to_hex 20 0 0 4`
2875 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2876 # with dst ip 20.0.0.4 should be received by lsp13
2877 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2879 sip=`ip_to_hex 192 168 0 33`
2880 tip=`ip_to_hex 20 0 0 5`
2881 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2882 # with dst ip 20.0.0.5 should not be received by lsp13
2883 test_ip 33 f00000000033 f00000000013 $sip $tip
2885 sip=`ip_to_hex 192 168 0 33`
2886 tip=`ip_to_hex 20 0 0 255`
2887 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2888 # with dst ip 20.0.0.255 should be received by lsp13
2889 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2891 sip=`ip_to_hex 192 168 0 33`
2892 tip=`ip_to_hex 192 168 0 255`
2893 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2894 # with dst ip 192.168.0.255 should not be received by lsp13
2895 test_ip 33 f00000000033 f00000000013 $sip $tip
2897 sip=`ip_to_hex 192 168 0 33`
2898 tip=`ip_to_hex 224 0 0 4`
2899 # IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2900 # with dst ip 224.0.0.4 should be received by lsp13
2901 test_ip 33 f00000000033 f00000000013 $sip $tip 13
2903 #dump information including flow counters
2905 ovn-sbctl dump-flows -- list multicast_group
2907 echo "------ hv1 dump ------"
2908 as hv1 ovs-vsctl show
2909 as hv1 ovs-ofctl -O OpenFlow13 show br-int
2910 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2912 echo "------ hv2 dump ------"
2913 as hv2 ovs-vsctl show
2914 as hv2 ovs-ofctl -O OpenFlow13 show br-int
2915 as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2917 echo "------ hv3 dump ------"
2918 as hv3 ovs-vsctl show
2919 as hv3 ovs-ofctl -O OpenFlow13 show br-int
2920 as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2922 # Now check the packets actually received against the ones expected.
2925 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
2929 OVN_CLEANUP([hv1],[hv2],[hv3])
2933 AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2934 AT_SKIP_IF([test $HAVE_PYTHON = no])
2938 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2939 # network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2940 # R2 has ls2 (172.16.1.0/24) connected to it.
2942 ls1_lp1_mac="f0:00:00:01:02:03"
2943 rp_ls1_mac="00:00:00:01:02:03"
2944 rp_ls2_mac="00:00:00:01:02:04"
2945 ls2_lp1_mac="f0:00:00:01:02:04"
2947 ls1_lp1_ip="192.168.1.2"
2948 ls2_lp1_ip="172.16.1.2"
2953 ovn-nbctl ls-add ls1
2954 ovn-nbctl ls-add ls2
2957 ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
2959 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2960 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
2963 ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
2965 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
2966 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
2969 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
2970 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
2972 ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
2973 ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
2975 # Create logical port ls1-lp1 in ls1
2976 ovn-nbctl lsp-add ls1 ls1-lp1 \
2977 -- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
2979 # Create logical port ls2-lp1 in ls2
2980 ovn-nbctl lsp-add ls2 ls2-lp1 \
2981 -- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
2983 # Create two hypervisor and create OVS ports corresponding to logical ports.
2988 ovs-vsctl add-br br-phys
2989 ovn_attach n1 br-phys 192.168.0.1
2990 ovs-vsctl -- add-port br-int hv1-vif1 -- \
2991 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2992 options:tx_pcap=hv1/vif1-tx.pcap \
2993 options:rxq_pcap=hv1/vif1-rx.pcap \
2998 ovs-vsctl add-br br-phys
2999 ovn_attach n1 br-phys 192.168.0.2
3000 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3001 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3002 options:tx_pcap=hv2/vif1-tx.pcap \
3003 options:rxq_pcap=hv2/vif1-rx.pcap \
3007 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3008 # packets for ARP resolution (native tunneling doesn't queue packets
3009 # for ARP resolution).
3012 # Allow some time for ovn-northd and ovn-controller to catch up.
3013 # XXX This should be more systematic.
3017 packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3018 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3019 udp && udp.src==53 && udp.dst==4369"
3020 as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3023 echo "---------NB dump-----"
3025 echo "---------------------"
3026 ovn-nbctl list logical_router
3027 echo "---------------------"
3028 ovn-nbctl list logical_router_port
3029 echo "---------------------"
3031 echo "---------SB dump-----"
3032 ovn-sbctl list datapath_binding
3033 echo "---------------------"
3034 ovn-sbctl list port_binding
3035 echo "---------------------"
3037 echo "------ hv1 dump ----------"
3038 as hv1 ovs-ofctl show br-int
3039 as hv1 ovs-ofctl dump-flows br-int
3040 echo "------ hv2 dump ----------"
3041 as hv2 ovs-ofctl show br-int
3042 as hv2 ovs-ofctl dump-flows br-int
3045 # The TTL should be decremented by 2.
3046 packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3047 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3048 udp && udp.src==53 && udp.dst==4369"
3049 echo $packet | ovstest test-ovn expr-to-packets > expected
3051 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3053 OVN_CLEANUP([hv1],[hv2])
3058 AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3059 AT_KEYWORDS([router-admin-state])
3060 AT_SKIP_IF([test $HAVE_PYTHON = no])
3064 # One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3065 # and 172.16.1.0/24) connected to it.
3069 ovn-nbctl ls-add ls1
3072 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
3073 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3074 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3076 # Create logical port ls1-lp1 in ls1
3077 ovn-nbctl lsp-add ls1 ls1-lp1 \
3078 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3080 # Create logical port ls1-lp2 in ls1
3081 ovn-nbctl lsp-add ls1 ls1-lp2 \
3082 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3084 # Create one hypervisor and create OVS ports corresponding to logical ports.
3089 ovs-vsctl add-br br-phys
3090 ovn_attach n1 br-phys 192.168.0.1
3091 ovs-vsctl -- add-port br-int vif1 -- \
3092 set interface vif1 external-ids:iface-id=ls1-lp1 \
3093 options:tx_pcap=hv1/vif1-tx.pcap \
3094 options:rxq_pcap=hv1/vif1-rx.pcap \
3097 ovs-vsctl -- add-port br-int vif2 -- \
3098 set interface vif2 external-ids:iface-id=ls1-lp2 \
3099 options:tx_pcap=hv1/vif2-tx.pcap \
3100 options:rxq_pcap=hv1/vif2-rx.pcap \
3104 # Allow some time for ovn-northd and ovn-controller to catch up.
3105 # XXX This should be more systematic.
3108 # Send ip packets between the two ports.
3110 printf "%02x%02x%02x%02x" "$@"
3114 src_mac="f00000010203"
3115 dst_mac="000000010203"
3116 src_ip=`ip_to_hex 192 168 1 2`
3117 dst_ip=`ip_to_hex 172 16 1 2`
3118 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3119 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3122 echo "---------NB dump-----"
3124 echo "---------------------"
3125 ovn-nbctl list logical_router
3126 echo "---------------------"
3127 ovn-nbctl list logical_router_port
3128 echo "---------------------"
3130 echo "---------SB dump-----"
3131 ovn-sbctl list datapath_binding
3132 echo "---------------------"
3133 ovn-sbctl list logical_flow
3134 echo "---------------------"
3136 echo "------ hv1 dump ----------"
3137 as hv1 ovs-ofctl dump-flows br-int
3141 ovn-nbctl set Logical_Router R1 enabled=false
3143 # Allow some time for ovn-northd and ovn-controller to catch up.
3144 # XXX This should be more systematic.
3147 echo "---------SB dump-----"
3148 ovn-sbctl list datapath_binding
3149 echo "---------------------"
3150 ovn-sbctl list logical_flow
3151 echo "---------------------"
3153 echo "------ hv1 dump ----------"
3154 as hv1 ovs-ofctl dump-flows br-int
3156 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3159 expect_src_mac="000000010203"
3160 expect_dst_mac="f00000010204"
3161 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3163 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3167 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3168 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3169 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3172 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3175 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3178 OVS_APP_EXIT_AND_WAIT([ovn-northd])
3181 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3182 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3187 AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
3188 AT_KEYWORDS([router-admin-state])
3189 AT_SKIP_IF([test $HAVE_PYTHON = no])
3193 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3194 # and has switch ls2 (172.16.1.0/24) connected to it.
3198 ovn-nbctl ls-add ls1
3199 ovn-nbctl ls-add ls2
3202 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
3203 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3204 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3207 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
3208 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3209 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
3211 # Create logical port ls1-lp1 in ls1
3212 ovn-nbctl lsp-add ls1 ls1-lp1 \
3213 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3215 # Create logical port ls2-lp1 in ls2
3216 ovn-nbctl lsp-add ls2 ls2-lp1 \
3217 -- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
3219 # Create one hypervisor and create OVS ports corresponding to logical ports.
3224 ovs-vsctl add-br br-phys
3225 ovn_attach n1 br-phys 192.168.0.1
3226 ovs-vsctl -- add-port br-int vif1 -- \
3227 set interface vif1 external-ids:iface-id=ls1-lp1 \
3228 options:tx_pcap=hv1/vif1-tx.pcap \
3229 options:rxq_pcap=hv1/vif1-rx.pcap \
3232 ovs-vsctl -- add-port br-int vif2 -- \
3233 set interface vif2 external-ids:iface-id=ls2-lp1 \
3234 options:tx_pcap=hv1/vif2-tx.pcap \
3235 options:rxq_pcap=hv1/vif2-rx.pcap \
3239 # Allow some time for ovn-northd and ovn-controller to catch up.
3240 # XXX This should be more systematic.
3243 # Send ip packets between the two ports.
3245 printf "%02x%02x%02x%02x" "$@"
3249 src_mac="f00000010203"
3250 dst_mac="000000010203"
3251 src_ip=`ip_to_hex 192 168 1 2`
3252 dst_ip=`ip_to_hex 172 16 1 2`
3253 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3254 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3257 echo "---------NB dump-----"
3259 echo "---------------------"
3260 ovn-nbctl list logical_router
3261 echo "---------------------"
3262 ovn-nbctl list logical_router_port
3263 echo "---------------------"
3265 echo "---------SB dump-----"
3266 ovn-sbctl list datapath_binding
3267 echo "---------------------"
3268 ovn-sbctl list logical_flow
3269 echo "---------------------"
3271 echo "------ hv1 dump ----------"
3272 as hv1 ovs-ofctl dump-flows br-int
3275 ovn-nbctl set Logical_Router R1 enabled=false
3277 echo "---------SB dump-----"
3278 ovn-sbctl list datapath_binding
3279 echo "---------------------"
3280 ovn-sbctl list logical_flow
3281 echo "---------------------"
3283 echo "------ hv1 dump ----------"
3284 as hv1 ovs-ofctl dump-flows br-int
3286 # Allow some time for the disabling of logical router R1 to propagate.
3287 # XXX This should be more systematic.
3290 as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3293 expect_src_mac="000000010204"
3294 expect_dst_mac="f00000010204"
3295 echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
3297 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3303 AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
3304 AT_SKIP_IF([test $HAVE_PYTHON = no])
3308 # Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3309 # network. R1 has switchess foo (192.168.1.0/24)
3311 # R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3316 ovn-nbctl ls-add foo
3317 ovn-nbctl ls-add alice
3318 ovn-nbctl ls-add bob
3321 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
3322 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3323 options:router-port=foo addresses=\"00:00:00:01:02:03\"
3325 # Connect alice to R2
3326 ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
3327 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3328 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
3331 ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
3332 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
3333 options:router-port=bob addresses=\"00:00:00:01:02:05\"
3336 ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3337 ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
3339 #install static routes
3340 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3341 ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3342 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3344 # Create logical port foo1 in foo
3345 ovn-nbctl lsp-add foo foo1 \
3346 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3348 # Create logical port alice1 in alice
3349 ovn-nbctl lsp-add alice alice1 \
3350 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3352 # Create logical port bob1 in bob
3353 ovn-nbctl lsp-add bob bob1 \
3354 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
3356 # Create two hypervisor and create OVS ports corresponding to logical ports.
3361 ovs-vsctl add-br br-phys
3362 ovn_attach n1 br-phys 192.168.0.1
3363 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3364 set interface hv1-vif1 external-ids:iface-id=foo1 \
3365 options:tx_pcap=hv1/vif1-tx.pcap \
3366 options:rxq_pcap=hv1/vif1-rx.pcap \
3369 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3370 set interface hv1-vif2 external-ids:iface-id=alice1 \
3371 options:tx_pcap=hv1/vif2-tx.pcap \
3372 options:rxq_pcap=hv1/vif2-rx.pcap \
3377 ovs-vsctl add-br br-phys
3378 ovn_attach n1 br-phys 192.168.0.2
3379 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3380 set interface hv2-vif1 external-ids:iface-id=bob1 \
3381 options:tx_pcap=hv2/vif1-tx.pcap \
3382 options:rxq_pcap=hv2/vif1-rx.pcap \
3386 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3387 # packets for ARP resolution (native tunneling doesn't queue packets
3388 # for ARP resolution).
3391 # Allow some time for ovn-northd and ovn-controller to catch up.
3392 # XXX This should be more systematic.
3396 printf "%02x%02x%02x%02x" "$@"
3399 # Send ip packets between foo1 and alice1
3400 src_mac="f00000010203"
3401 dst_mac="000000010203"
3402 src_ip=`ip_to_hex 192 168 1 2`
3403 dst_ip=`ip_to_hex 172 16 1 2`
3404 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3405 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3407 # Send ip packets between foo1 and bob1
3408 src_mac="f00000010203"
3409 dst_mac="000000010203"
3410 src_ip=`ip_to_hex 192 168 1 2`
3411 dst_ip=`ip_to_hex 172 16 2 2`
3412 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3413 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3415 echo "---------NB dump-----"
3417 echo "---------------------"
3418 ovn-nbctl list logical_router
3419 echo "---------------------"
3420 ovn-nbctl list logical_router_port
3421 echo "---------------------"
3423 echo "---------SB dump-----"
3424 ovn-sbctl list datapath_binding
3425 echo "---------------------"
3426 ovn-sbctl list port_binding
3427 echo "---------------------"
3429 echo "------ hv1 dump ----------"
3430 as hv1 ovs-ofctl dump-flows br-int
3431 echo "------ hv2 dump ----------"
3432 as hv2 ovs-ofctl dump-flows br-int
3434 # Packet to Expect at bob1
3435 src_mac="000000010205"
3436 dst_mac="f00000010205"
3437 src_ip=`ip_to_hex 192 168 1 2`
3438 dst_ip=`ip_to_hex 172 16 2 2`
3439 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3441 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3443 # Packet to Expect at alice1
3444 src_mac="000000010204"
3445 dst_mac="f00000010204"
3446 src_ip=`ip_to_hex 192 168 1 2`
3447 dst_ip=`ip_to_hex 172 16 1 2`
3448 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3450 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3452 OVN_CLEANUP([hv1],[hv2])
3456 AT_SETUP([ovn -- send gratuitous arp on localnet])
3457 AT_SKIP_IF([test $HAVE_PYTHON = no])
3459 ovn-nbctl ls-add lsw0
3467 ovn_attach n1 br-phys 192.168.0.1
3469 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3470 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])
3473 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3474 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3475 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
3477 # Create a localnet port.
3478 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3479 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3480 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3481 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
3483 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3485 # Wait for packet to be received.
3486 echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3487 OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3489 # Delete the localnet ports.
3490 AT_CHECK([ovs-vsctl del-port localvif1])
3491 AT_CHECK([ovn-nbctl lsp-del ln_port])
3497 AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
3498 AT_SKIP_IF([test $HAVE_PYTHON = no])
3502 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3503 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3504 # connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3511 ovn-nbctl ls-add foo
3512 ovn-nbctl ls-add alice
3513 ovn-nbctl ls-add bob
3514 ovn-nbctl ls-add join
3517 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
3518 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
3519 options:router-port=foo addresses=\"00:00:01:01:02:03\"
3521 # Connect alice to R2
3522 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
3523 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
3524 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
3527 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
3528 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
3529 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
3531 # Connect R1 to join
3532 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
3533 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
3534 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
3536 # Connect R2 to join
3537 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
3538 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
3539 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
3541 # Connect R3 to join
3542 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
3543 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
3544 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
3546 #install static routes
3547 ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3548 ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
3550 ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3551 ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
3553 ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3554 ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
3556 # Create logical port foo1 in foo
3557 ovn-nbctl lsp-add foo foo1 \
3558 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
3560 # Create logical port alice1 in alice
3561 ovn-nbctl lsp-add alice alice1 \
3562 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
3564 # Create logical port bob1 in bob
3565 ovn-nbctl lsp-add bob bob1 \
3566 -- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
3568 # Create two hypervisor and create OVS ports corresponding to logical ports.
3573 ovs-vsctl add-br br-phys
3574 ovn_attach n1 br-phys 192.168.0.1
3575 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3576 set interface hv1-vif1 external-ids:iface-id=foo1 \
3577 options:tx_pcap=hv1/vif1-tx.pcap \
3578 options:rxq_pcap=hv1/vif1-rx.pcap \
3581 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3582 set interface hv1-vif2 external-ids:iface-id=alice1 \
3583 options:tx_pcap=hv1/vif2-tx.pcap \
3584 options:rxq_pcap=hv1/vif2-rx.pcap \
3589 ovs-vsctl add-br br-phys
3590 ovn_attach n1 br-phys 192.168.0.2
3591 ovs-vsctl -- add-port br-int hv2-vif1 -- \
3592 set interface hv2-vif1 external-ids:iface-id=bob1 \
3593 options:tx_pcap=hv2/vif1-tx.pcap \
3594 options:rxq_pcap=hv2/vif1-rx.pcap \
3598 # Pre-populate the hypervisors' ARP tables so that we don't lose any
3599 # packets for ARP resolution (native tunneling doesn't queue packets
3600 # for ARP resolution).
3603 # Allow some time for ovn-northd and ovn-controller to catch up.
3604 # XXX This should be more systematic.
3608 printf "%02x%02x%02x%02x" "$@"
3611 # Send ip packets between foo1 and alice1
3612 src_mac="f00000010203"
3613 dst_mac="000001010203"
3614 src_ip=`ip_to_hex 192 168 1 2`
3615 dst_ip=`ip_to_hex 172 16 1 2`
3616 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3617 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3618 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3620 # Send ip packets between foo1 and bob1
3621 src_mac="f00000010203"
3622 dst_mac="000001010203"
3623 src_ip=`ip_to_hex 192 168 1 2`
3624 dst_ip=`ip_to_hex 10 32 1 2`
3625 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3626 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3628 echo "---------NB dump-----"
3630 echo "---------------------"
3631 ovn-nbctl list logical_router
3632 echo "---------------------"
3633 ovn-nbctl list logical_router_port
3634 echo "---------------------"
3636 echo "---------SB dump-----"
3637 ovn-sbctl list datapath_binding
3638 echo "---------------------"
3639 ovn-sbctl list port_binding
3640 echo "---------------------"
3641 ovn-sbctl dump-flows
3642 echo "---------------------"
3644 echo "------ hv1 dump ----------"
3645 as hv1 ovs-ofctl show br-int
3646 as hv1 ovs-ofctl dump-flows br-int
3647 echo "------ hv2 dump ----------"
3648 as hv2 ovs-ofctl show br-int
3649 as hv2 ovs-ofctl dump-flows br-int
3650 echo "----------------------------"
3652 # Packet to Expect at bob1
3653 src_mac="000003010203"
3654 dst_mac="f00000010205"
3655 src_ip=`ip_to_hex 192 168 1 2`
3656 dst_ip=`ip_to_hex 10 32 1 2`
3657 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3659 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3661 # Packet to Expect at alice1
3662 src_mac="000002010203"
3663 dst_mac="f00000010204"
3664 src_ip=`ip_to_hex 192 168 1 2`
3665 dst_ip=`ip_to_hex 172 16 1 2`
3666 echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
3668 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
3670 OVN_CLEANUP([hv1],[hv2])
3674 AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
3675 AT_SKIP_IF([test $HAVE_PYTHON = no])
3678 ovn-nbctl ls-add ls1
3680 ovn-nbctl lsp-add ls1 ls1-lp1 \
3681 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3683 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3685 ovn-nbctl lsp-add ls1 ls1-lp2 \
3686 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3688 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3690 ovn-nbctl ls-add ls2
3691 ovn-nbctl lsp-add ls2 ls2-lp1 \
3692 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3693 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3694 ovn-nbctl lsp-add ls2 ls2-lp2 \
3695 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3696 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3698 d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
3699 options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3700 \"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
3702 ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3703 ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3705 d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
3706 options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3707 \"lease_time\"=\"3600\"")"
3709 ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
3715 ovs-vsctl add-br br-phys
3716 ovn_attach n1 br-phys 192.168.0.1
3717 ovs-vsctl -- add-port br-int hv1-vif1 -- \
3718 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3719 options:tx_pcap=hv1/vif1-tx.pcap \
3720 options:rxq_pcap=hv1/vif1-rx.pcap \
3723 ovs-vsctl -- add-port br-int hv1-vif2 -- \
3724 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3725 options:tx_pcap=hv1/vif2-tx.pcap \
3726 options:rxq_pcap=hv1/vif2-rx.pcap \
3729 ovs-vsctl -- add-port br-int hv1-vif3 -- \
3730 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3731 options:tx_pcap=hv1/vif3-tx.pcap \
3732 options:rxq_pcap=hv1/vif3-rx.pcap \
3735 ovs-vsctl -- add-port br-int hv1-vif4 -- \
3736 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3737 options:tx_pcap=hv1/vif4-tx.pcap \
3738 options:rxq_pcap=hv1/vif4-rx.pcap \
3745 as hv1 ovs-vsctl show
3747 # This shell function sends a DHCP request packet
3748 # test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3750 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
3751 shift; shift; shift; shift; shift;
3752 if test $use_ip != 0; then
3757 src_ip=`ip_to_hex 0 0 0 0`
3758 dst_ip=`ip_to_hex 255 255 255 255`
3760 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
3761 # udp header and dhcp header
3762 request=${request}0044004300fc0000
3763 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
3764 # client hardware padding
3765 request=${request}00000000000000000000
3767 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3768 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3770 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3771 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3772 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3773 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3775 request=${request}63825363
3777 request=${request}3501${dhcp_type}ff
3779 if test $offer_ip != 0; then
3780 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
3781 # total IP length will be the IP length of the request packet
3782 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3783 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3784 udp_len=`expr $ip_len - 20`
3785 ip_len=$(printf "%x" $ip_len)
3786 udp_len=$(printf "%x" $udp_len)
3787 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3788 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3789 # udp header and dhcp header.
3790 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
3791 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
3793 reply=${reply}${offer_ip}
3794 # next server ip address, relay agent ip address, client mac address
3795 reply=${reply}0000000000000000${src_mac}
3796 # client hardware padding
3797 reply=${reply}00000000000000000000
3799 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3800 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3802 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3803 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3804 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3805 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3807 reply=${reply}63825363
3809 local dhcp_reply_type=02
3810 if test $dhcp_type = 03; then
3813 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
3814 echo $reply >> $inport.expected
3817 echo $request >> $outport.expected
3820 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3826 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3827 options:rxq_pcap=dummy-rx.pcap
3828 rm -f ${pcap_file}*.pcap
3829 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3830 options:rxq_pcap=${pcap_file}-rx.pcap
3834 printf "%02x%02x%02x%02x" "$@"
3837 AT_CAPTURE_FILE([ofctl_monitor0.log])
3838 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3839 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3841 echo "---------NB dump-----"
3843 echo "---------------------"
3844 echo "---------SB dump-----"
3845 ovn-sbctl list datapath_binding
3846 echo "---------------------"
3847 ovn-sbctl list logical_flow
3848 echo "---------------------"
3850 echo "---------------------"
3851 ovn-sbctl dump-flows
3852 echo "---------------------"
3854 echo "------ hv1 dump ----------"
3855 as hv1 ovs-ofctl dump-flows br-int
3857 # Send DHCPDISCOVER.
3858 offer_ip=`ip_to_hex 10 0 0 4`
3859 server_ip=`ip_to_hex 10 0 0 1`
3860 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3861 test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3863 # NXT_RESUMEs should be 1.
3864 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3866 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3867 cat 1.expected | cut -c -48 > expout
3868 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3869 # Skipping the IPv4 checksum.
3870 cat 1.expected | cut -c 53- > expout
3871 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3873 # ovs-ofctl also resumes the packets and this causes other ports to receive
3874 # the DHCP request packet. So reset the pcap files so that its easier to test.
3875 reset_pcap_file hv1-vif1 hv1/vif1
3876 reset_pcap_file hv1-vif2 hv1/vif2
3881 offer_ip=`ip_to_hex 10 0 0 6`
3882 server_ip=`ip_to_hex 10 0 0 1`
3883 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3884 test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
3886 # NXT_RESUMEs should be 2.
3887 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3889 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3890 cat 2.expected | cut -c -48 > expout
3891 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3892 # Skipping the IPv4 checksum.
3893 cat 2.expected | cut -c 53- > expout
3894 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3896 reset_pcap_file hv1-vif1 hv1/vif1
3897 reset_pcap_file hv1-vif2 hv1/vif2
3901 # Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3902 # but should be resumed without the reply.
3903 # ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3904 # one from ovn-controller and the other from "ovs-ofctl resume."
3906 test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
3908 # NXT_RESUMEs should be 3.
3909 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3911 # vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
3912 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3914 reset_pcap_file hv1-vif1 hv1/vif1
3915 reset_pcap_file hv1-vif2 hv1/vif2
3919 # Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3920 # ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3922 test_dhcp 3 f00000000003 01 0 4 0
3924 # Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3926 test_dhcp 4 f00000000004 01 0 3 0
3928 # NXT_RESUMEs should be 3.
3929 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3931 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3932 OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
3934 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
3935 offer_ip=`ip_to_hex 10 0 0 6`
3936 server_ip=`ip_to_hex 10 0 0 1`
3937 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3940 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
3942 # NXT_RESUMEs should be 4.
3943 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3945 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3946 cat 2.expected | cut -c -48 > expout
3947 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3948 # Skipping the IPv4 checksum.
3949 cat 2.expected | cut -c 53- > expout
3950 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3952 reset_pcap_file hv1-vif1 hv1/vif1
3953 reset_pcap_file hv1-vif2 hv1/vif2
3957 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
3958 offer_ip=`ip_to_hex 10 0 0 6`
3959 server_ip=`ip_to_hex 10 0 0 1`
3960 expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
3962 dst_ip=`ip_to_hex 255 255 255 255`
3963 test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
3965 # NXT_RESUMEs should be 5.
3966 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3968 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3969 cat 2.expected | cut -c -48 > expout
3970 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3971 # Skipping the IPv4 checksum.
3972 cat 2.expected | cut -c 53- > expout
3973 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3975 reset_pcap_file hv1-vif1 hv1/vif1
3976 reset_pcap_file hv1-vif2 hv1/vif2
3980 # Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
3981 # The packet should not be received by ovn-controller.
3982 src_ip=`ip_to_hex 10 0 0 6`
3983 dst_ip=`ip_to_hex 10 0 0 4`
3984 test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
3986 # NXT_RESUMEs should be 5.
3987 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3989 # vif1-tx.pcap should have received the DHCPv4 request packet
3990 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
3993 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3994 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3995 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3998 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4001 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4004 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4007 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4008 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4012 AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
4013 AT_SKIP_IF([test $HAVE_PYTHON = no])
4016 ovn-nbctl ls-add ls1
4017 ovn-nbctl lsp-add ls1 ls1-lp1 \
4018 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4020 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4022 ovn-nbctl lsp-add ls1 ls1-lp2 \
4023 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4025 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4027 ovn-nbctl lsp-add ls1 ls1-lp3 \
4028 -- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4030 ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4032 d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4033 options="\"server_id\"=\"00:00:00:10:00:01\"")"
4035 ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4036 ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4038 d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4039 options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
4041 ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
4043 ovn-nbctl ls-add ls2
4044 ovn-nbctl lsp-add ls2 ls2-lp1 \
4045 -- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4046 ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4047 ovn-nbctl lsp-add ls2 ls2-lp2 \
4048 -- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4049 ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4055 ovs-vsctl add-br br-phys
4056 ovn_attach n1 br-phys 192.168.0.1
4057 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4058 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4059 options:tx_pcap=hv1/vif1-tx.pcap \
4060 options:rxq_pcap=hv1/vif1-rx.pcap \
4063 ovs-vsctl -- add-port br-int hv1-vif2 -- \
4064 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4065 options:tx_pcap=hv1/vif2-tx.pcap \
4066 options:rxq_pcap=hv1/vif2-rx.pcap \
4069 ovs-vsctl -- add-port br-int hv1-vif3 -- \
4070 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4071 options:tx_pcap=hv1/vif3-tx.pcap \
4072 options:rxq_pcap=hv1/vif3-rx.pcap \
4075 ovs-vsctl -- add-port br-int hv1-vif4 -- \
4076 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4077 options:tx_pcap=hv1/vif4-tx.pcap \
4078 options:rxq_pcap=hv1/vif4-rx.pcap \
4081 ovs-vsctl -- add-port br-int hv1-vif5 -- \
4082 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4083 options:tx_pcap=hv1/vif5-tx.pcap \
4084 options:rxq_pcap=hv1/vif5-rx.pcap \
4092 sed 's/\(00\)\{1,\}$//'
4095 # This shell function sends a DHCPv6 request packet
4096 # test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4097 # The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
4098 # packet should be received twice (one from ovn-controller and the other
4099 # from the "ovs-ofctl monitor br-int resume"
4101 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4102 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4104 request=${request}ff020000000000000000000000010002
4105 # udp header and dhcpv6 header
4106 request=${request}02220223002affff${msg_code}010203
4108 request=${request}0001000a00030001${src_mac}
4109 # IA-NA (Identity Association for Non Temporary Address)
4110 request=${request}0003000c0102030400000e1000001518
4111 shift; shift; shift; shift; shift;
4112 if test $offer_ip != 0; then
4113 local server_mac=000000100001
4114 local server_lla=fe80000000000000020000fffe100001
4116 if test $msg_code = 01; then
4120 if test $offer_ip = 1; then
4123 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
4124 # udp header and dhcpv6 header
4125 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
4127 reply=${reply}0001000a00030001${src_mac}
4129 if test $offer_ip != 1; then
4130 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
4133 reply=${reply}0002000a00030001${server_mac}
4134 echo $reply | trim_zeros >> $inport.expected
4137 echo $request | trim_zeros >> $outport.expected
4141 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4147 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4148 options:rxq_pcap=dummy-rx.pcap
4149 rm -f ${pcap_file}*.pcap
4150 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4151 options:rxq_pcap=${pcap_file}-rx.pcap
4154 AT_CAPTURE_FILE([ofctl_monitor0.log])
4155 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4156 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4158 echo "---------NB dump-----"
4160 echo "---------------------"
4161 echo "---------SB dump-----"
4162 ovn-sbctl list datapath_binding
4163 echo "---------------------"
4164 ovn-sbctl list logical_flow
4165 echo "---------------------"
4167 echo "---------------------"
4168 ovn-sbctl dump-flows
4169 echo "---------------------"
4171 echo "------ hv1 dump ----------"
4172 as hv1 ovs-ofctl dump-flows br-int
4174 src_mac=f00000000001
4175 src_lla=fe80000000000000f20000fffe000001
4176 offer_ip=ae700000000000000000000000000004
4177 test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4179 # NXT_RESUMEs should be 1.
4180 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4182 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4183 # cat 1.expected | trim_zeros > expout
4184 cat 1.expected | cut -c -120 > expout
4185 AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4186 # Skipping the UDP checksum
4187 cat 1.expected | cut -c 125- > expout
4188 AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4192 # Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4193 # without any modifications and the packet should be received by ls1-lp1.
4194 # ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4195 # resume and the other from ovs-ofctl monitor resume.
4197 reset_pcap_file hv1-vif1 hv1/vif1
4198 reset_pcap_file hv1-vif2 hv1/vif2
4200 src_mac=f00000000002
4201 src_lla=fe80000000000000f20000fffe000002
4202 offer_ip=ae700000000000000000000000000005
4203 # Set invalid msg_type
4205 test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4207 # NXT_RESUMEs should be 2.
4208 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4210 # vif2-tx.pcap should not have received the DHCPv6 reply packet
4212 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4213 AT_CHECK([cat 2.packets], [0], [])
4215 # vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4216 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4217 cat 1.expected > expout
4218 AT_CHECK([cat 1.packets], [0], [expout])
4220 # Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4221 # There should be no DHCPv6 reply from ovn-controller and the request packet
4222 # should be received by ls2-lp2.
4224 src_mac=f00000000003
4225 src_lla=fe80000000000000f20000fffe000003
4226 test_dhcpv6 3 $src_mac $src_lla 01 0 4
4228 # NXT_RESUMEs should be 2 only.
4229 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4231 # vif3-tx.pcap should not have received the DHCPv6 reply packet
4232 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4233 AT_CHECK([cat 3.packets], [0], [])
4235 # vif4-tx.pcap should have received the DHCPv6 request packet
4236 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4237 cat 4.expected > expout
4238 AT_CHECK([cat 4.packets], [0], [expout])
4240 # Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4241 # The DHCPv6 reply should doesn't contian offer_ip.
4242 src_mac=f00000000022
4243 src_lla=fe80000000000000f20000fffe000022
4244 reset_pcap_file hv1-vif5 hv1/vif5
4245 test_dhcpv6 5 $src_mac $src_lla 01 1 5
4247 # NXT_RESUMEs should be 3.
4248 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4250 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4251 # Skipping the UDP checksum
4252 cat 5.expected | cut -c 1-120,125- > expout
4253 AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4256 OVS_APP_EXIT_AND_WAIT([ovn-controller])
4257 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4258 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4261 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4264 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4267 OVS_APP_EXIT_AND_WAIT([ovn-northd])
4270 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4271 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4275 AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
4276 AT_SKIP_IF([test $HAVE_PYTHON = no])
4280 # Two LRs - R1 and R2 that are connected to each other via LS "join"
4281 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4282 # connected to it. R2 has alice (172.16.1.0/24) connected to it.
4283 # R2 is a gateway router.
4287 # Create two hypervisor and create OVS ports corresponding to logical ports.
4292 ovs-vsctl add-br br-phys
4293 ovn_attach n1 br-phys 192.168.0.1
4294 ovs-vsctl -- add-port br-int hv1-vif1 -- \
4295 set interface hv1-vif1 external-ids:iface-id=foo1 \
4296 options:tx_pcap=hv1/vif1-tx.pcap \
4297 options:rxq_pcap=hv1/vif1-rx.pcap \
4303 ovs-vsctl add-br br-phys
4304 ovn_attach n1 br-phys 192.168.0.2
4305 ovs-vsctl -- add-port br-int hv2-vif1 -- \
4306 set interface hv2-vif1 external-ids:iface-id=alice1 \
4307 options:tx_pcap=hv2/vif1-tx.pcap \
4308 options:rxq_pcap=hv2/vif1-rx.pcap \
4311 # Pre-populate the hypervisors' ARP tables so that we don't lose any
4312 # packets for ARP resolution (native tunneling doesn't queue packets
4313 # for ARP resolution).
4316 ovn-nbctl create Logical_Router name=R1
4317 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4319 ovn-nbctl ls-add foo
4320 ovn-nbctl ls-add alice
4321 ovn-nbctl ls-add join
4324 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
4325 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
4326 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
4328 # Connect alice to R2
4329 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4330 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
4331 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
4333 # Connect R1 to join
4334 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
4335 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
4336 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
4338 # Connect R2 to join
4339 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4340 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
4341 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
4344 #install static routes
4345 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4346 ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4347 R1 static_routes @lrt
4349 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4350 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4351 R2 static_routes @lrt
4353 # Create logical port foo1 in foo
4354 ovn-nbctl lsp-add foo foo1 \
4355 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
4357 # Create logical port alice1 in alice
4358 ovn-nbctl lsp-add alice alice1 \
4359 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
4362 # Allow some time for ovn-northd and ovn-controller to catch up.
4363 # XXX This should be more systematic.
4367 printf "%02x%02x%02x%02x" "$@"
4370 # Send ip packets between foo1 and alice1
4371 src_mac="f00000010203"
4372 dst_mac="000001010203"
4373 src_ip=`ip_to_hex 192 168 1 2`
4374 dst_ip=`ip_to_hex 172 16 1 2`
4375 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4377 echo "---------NB dump-----"
4379 echo "---------------------"
4380 ovn-nbctl list logical_router
4381 echo "---------------------"
4382 ovn-nbctl list logical_router_port
4383 echo "---------------------"
4385 echo "---------SB dump-----"
4386 ovn-sbctl list datapath_binding
4387 echo "---------------------"
4388 ovn-sbctl list port_binding
4389 echo "---------------------"
4390 ovn-sbctl dump-flows
4391 echo "---------------------"
4392 ovn-sbctl list chassis
4393 ovn-sbctl list encap
4394 echo "---------------------"
4396 # Packet to Expect at alice1
4397 src_mac="000002010203"
4398 dst_mac="f00000010204"
4399 src_ip=`ip_to_hex 192 168 1 2`
4400 dst_ip=`ip_to_hex 172 16 1 2`
4401 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4404 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4405 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4407 echo "------ hv1 dump after packet 1 ----------"
4408 as hv1 ovs-ofctl show br-int
4409 as hv1 ovs-ofctl dump-flows br-int
4410 echo "------ hv2 dump after packet 1 ----------"
4411 as hv2 ovs-ofctl show br-int
4412 as hv2 ovs-ofctl dump-flows br-int
4413 echo "----------------------------"
4415 echo $expected > expected
4416 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4418 # Delete the router and re-create it. Things should work as before.
4420 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4421 # Connect alice to R2
4422 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4423 # Connect R2 to join
4424 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4426 ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4427 ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4428 R2 static_routes @lrt
4430 # Wait for ovn-controller to catch up.
4433 # Send the packet again.
4434 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4436 echo "------ hv1 dump after packet 2 ----------"
4437 as hv1 ovs-ofctl show br-int
4438 as hv1 ovs-ofctl dump-flows br-int
4439 echo "------ hv2 dump after packet 2 ----------"
4440 as hv2 ovs-ofctl show br-int
4441 as hv2 ovs-ofctl dump-flows br-int
4442 echo "----------------------------"
4444 echo $expected >> expected
4445 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
4447 OVN_CLEANUP([hv1],[hv2])
4451 AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4452 AT_KEYWORDS([router-icmp-reply])
4453 AT_SKIP_IF([test $HAVE_PYTHON = no])
4457 # One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4458 # and has switch ls2 (172.16.1.0/24) connected to it.
4462 ovn-nbctl ls-add ls1
4463 ovn-nbctl ls-add ls2
4466 ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
4467 ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
4468 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
4471 ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
4472 ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
4473 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
4475 # Create logical port ls1-lp1 in ls1
4476 ovn-nbctl lsp-add ls1 ls1-lp1 \
4477 -- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
4479 # Create logical port ls2-lp1 in ls2
4480 ovn-nbctl lsp-add ls2 ls2-lp1 \
4481 -- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
4483 # Create one hypervisor and create OVS ports corresponding to logical ports.
4488 ovs-vsctl add-br br-phys
4489 ovn_attach n1 br-phys 192.168.0.1
4490 ovs-vsctl -- add-port br-int vif1 -- \
4491 set interface vif1 external-ids:iface-id=ls1-lp1 \
4492 options:tx_pcap=hv1/vif1-tx.pcap \
4493 options:rxq_pcap=hv1/vif1-rx.pcap \
4496 ovs-vsctl -- add-port br-int vif2 -- \
4497 set interface vif2 external-ids:iface-id=ls2-lp1 \
4498 options:tx_pcap=hv1/vif2-tx.pcap \
4499 options:rxq_pcap=hv1/vif2-rx.pcap \
4503 # Allow some time for ovn-northd and ovn-controller to catch up.
4504 # XXX This should be more systematic.
4509 printf "%02x%02x%02x%02x" "$@"
4514 # test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4516 # Causes a packet to be received on INPORT. The packet is an ICMPv4
4517 # request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4518 # ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4519 # provided, then it should be the ip and icmp checksums of the packet
4520 # responded; otherwise, no reply is expected.
4521 # In the absence of an ip checksum calculation helpers, this relies
4522 # on the caller to provide the checksums for the ip and icmp headers.
4523 # XXX This should be more systematic.
4525 # INPORT is an lport number, e.g. 11 for vif11.
4526 # ETH_SRC and ETH_DST are each 12 hex digits.
4527 # IPV4_SRC and IPV4_DST are each 8 hex digits.
4528 # IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4529 # EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4530 test_ipv4_icmp_request() {
4531 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4532 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4533 shift; shift; shift; shift; shift; shift; shift
4536 # Use ttl to exercise section 4.2.2.9 of RFC1812
4540 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4541 local icmp_type_code_request=0800
4542 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4543 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4545 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4546 if test X$exp_icmp_chksum != X; then
4547 # Expect to receive the reply, if any. In same port where packet was sent.
4548 # Note: src and dst fields are expected to be reversed.
4549 local icmp_type_code_response=0000
4550 local reply_icmp_ttl=fe
4551 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4552 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4553 echo $reply >> vif$inport.expected
4557 # Send ping packet to router's ip addresses, from each of the 2 logical ports.
4558 rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4559 rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4560 l1_ip=$(ip_to_hex 192 168 1 2)
4561 l2_ip=$(ip_to_hex 172 16 1 2)
4563 # Ping router ip address that is on same subnet as the logical port
4564 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4565 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4567 # Ping router ip address that is on the other side of the logical ports
4568 test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4569 test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4571 echo "---------NB dump-----"
4573 echo "---------------------"
4574 ovn-nbctl list logical_router
4575 echo "---------------------"
4576 ovn-nbctl list logical_router_port
4577 echo "---------------------"
4579 echo "---------SB dump-----"
4580 ovn-sbctl list datapath_binding
4581 echo "---------------------"
4582 ovn-sbctl list logical_flow
4583 echo "---------------------"
4585 echo "------ hv1 dump ----------"
4586 as hv1 ovs-ofctl dump-flows br-int
4588 # Now check the packets actually received against the ones expected.
4589 for inport in 1 2; do
4590 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
4597 # 1 hypervisor, 1 port
4598 # make sure that the port state is properly set to up and back down
4599 # when created and deleted.
4600 AT_SETUP([ovn -- port state up and down])
4603 ovn-nbctl ls-add ls1
4604 ovn-nbctl lsp-add ls1 lp1
4605 ovn-nbctl lsp-set-addresses lp1 unknown
4609 as hv1 ovs-vsctl add-br br-phys
4610 as hv1 ovn_attach n1 br-phys 192.168.0.1
4612 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4613 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4615 as hv1 ovs-vsctl del-port br-int vif1
4616 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4622 # 1 hypervisor, 1 port
4623 # make sure that the OF rules created to support a datapath are added/cleared
4624 # when logical switch is created and removed.
4625 AT_SETUP([ovn -- datapath rules added/removed])
4626 AT_KEYWORDS([cleanup])
4631 as hv1 ovs-vsctl add-br br-phys
4632 as hv1 ovn_attach n1 br-phys 192.168.0.1
4634 # This shell function checks if OF rules in br-int have clauses
4635 # related to OVN datapaths. The caller determines if it should find
4636 # a match in the output, or not.
4638 # EXPECT_DATAPATH param determines whether flows that refer to
4639 # datapath to should be present or not. 0 means
4640 # they should not be.
4641 # STAGE_INFO param is a simple string to help identify the stage
4642 # in the test when this function was invoked.
4643 test_datapath_in_of_rules() {
4644 local expect_datapath=$1 stage_info=$2
4645 echo "------ ovn-nbctl show ${stage_info} ------"
4647 echo "------ ovn-sbctl show ${stage_info} ------"
4649 echo "------ OF rules ${stage_info} ------"
4650 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4651 # if there is a datapath mentioned in the output, check for the
4652 # magic keyword that represents one, based on the exit status of
4654 if test $expect_datapath != 0; then
4655 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
4657 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
4661 test_datapath_in_of_rules 0 "before ls+port create"
4663 ovn-nbctl ls-add ls1
4664 ovn-nbctl lsp-add ls1 lp1
4665 ovn-nbctl lsp-set-addresses lp1 unknown
4667 as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4668 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4670 test_datapath_in_of_rules 1 "after port is bound"
4672 as hv1 ovs-vsctl del-port br-int vif1
4673 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4675 ovn-nbctl lsp-set-addresses lp1
4676 ovn-nbctl lsp-del lp1
4677 ovn-nbctl ls-del ls1
4679 # wait for earlier changes to take effect
4680 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4682 # ensure OF rules are no longer present. There used to be a bug here.
4683 test_datapath_in_of_rules 0 "after lport+ls removal"
4689 AT_SETUP([ovn -- nd_na ])
4690 AT_SKIP_IF([test $HAVE_PYTHON = no])
4693 #TODO: since patch port for IPv6 logical router port is not ready not,
4694 # so we are not going to test vifs on different lswitches cases. Try
4695 # to update for that once relevant stuff implemented.
4697 # In this test cases we create 1 lswitch, it has 2 VIF ports attached
4698 # with. NS packet we test, from one VIF for another VIF, will be replied
4699 # by local ovn-controller, but not by target VIF.
4701 # Create hypervisors and logical switch lsw0.
4702 ovn-nbctl ls-add lsw0
4706 ovs-vsctl add-br br-phys
4707 ovn_attach n1 br-phys 192.168.0.2
4709 # Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4710 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
4711 ovn-nbctl lsp-add lsw0 lp1
4712 ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4713 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"
4715 # Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4716 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
4717 ovn-nbctl lsp-add lsw0 lp2
4718 ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4719 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"
4721 # Add ACL rule for ICMPv6 on lsw0
4722 ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4723 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4724 ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4726 # Allow some time for ovn-northd and ovn-controller to catch up.
4727 # XXX This should be more systematic.
4730 # Given the name of a logical port, prints the name of the hypervisor
4731 # on which it is located.
4739 # Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4740 # vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4741 # vif2 will not receive NS packet, since ovn-controller will reply for it.
4742 ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4743 na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4745 as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
4746 echo $na_packet >> 1.expected
4748 echo "------ hv1 dump ------"
4749 as hv1 ovs-vsctl show
4750 as hv1 ovs-ofctl -O OpenFlow13 show br-int
4751 as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4754 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
4761 AT_SETUP([ovn -- address sets modification/removal smoke test])
4768 ovs-vsctl add-br br-phys
4769 ovn_attach n1 br-phys 192.168.0.1
4771 row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4772 ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4773 ovn-nbctl destroy Address_Set $row
4777 # A bug previously existed in the address set support code
4778 # that caused ovn-controller to crash after an address set
4779 # was updated and then removed. This test case ensures
4780 # that ovn-controller is at least still running after
4781 # creating, updating, and deleting an address set.
4782 AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4788 AT_SETUP([ovn -- ipam])
4789 AT_SKIP_IF([test $HAVE_PYTHON = no])
4792 # Add a port to a switch that does not have a subnet set, then set the
4793 # subnet which should result in an address being allocated for the port.
4794 ovn-nbctl ls-add sw0
4795 ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
4796 ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
4797 AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4798 ["0a:00:00:00:00:01 192.168.1.2"
4801 # Add 9 more ports to sw0, addresses should all be unique.
4802 for n in `seq 1 9`; do
4803 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
4805 AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4806 ["0a:00:00:00:00:02 192.168.1.3"
4808 AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4809 ["0a:00:00:00:00:03 192.168.1.4"
4811 AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4812 ["0a:00:00:00:00:04 192.168.1.5"
4814 AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4815 ["0a:00:00:00:00:05 192.168.1.6"
4817 AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4818 ["0a:00:00:00:00:06 192.168.1.7"
4820 AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4821 ["0a:00:00:00:00:07 192.168.1.8"
4823 AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4824 ["0a:00:00:00:00:08 192.168.1.9"
4826 AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4827 ["0a:00:00:00:00:09 192.168.1.10"
4829 AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4830 ["0a:00:00:00:00:0a 192.168.1.11"
4833 # Trying similar tests with a second switch. MAC addresses should be unique
4834 # across both switches but IP's only need to be unique within the same switch.
4835 ovn-nbctl ls-add sw1
4836 ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
4837 ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
4838 AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4839 ["0a:00:00:00:00:0b 192.168.1.2"
4842 for n in `seq 11 19`; do
4843 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
4845 AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4846 ["0a:00:00:00:00:0c 192.168.1.3"
4848 AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4849 ["0a:00:00:00:00:0d 192.168.1.4"
4851 AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4852 ["0a:00:00:00:00:0e 192.168.1.5"
4854 AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4855 ["0a:00:00:00:00:0f 192.168.1.6"
4857 AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4858 ["0a:00:00:00:00:10 192.168.1.7"
4860 AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4861 ["0a:00:00:00:00:11 192.168.1.8"
4863 AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4864 ["0a:00:00:00:00:12 192.168.1.9"
4866 AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4867 ["0a:00:00:00:00:13 192.168.1.10"
4869 AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4870 ["0a:00:00:00:00:14 192.168.1.11"
4873 # Change a port's address to test for multiple ip's for a single address entry
4874 # and addresses set by the user.
4875 ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
4876 ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
4877 AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4878 ["0a:00:00:00:00:16 192.168.1.13"
4881 # Test for logical router port address management.
4882 ovn-nbctl create Logical_Router name=R1
4883 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4884 network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4885 -- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4886 -- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
4887 ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
4888 AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4889 ["0a:00:00:00:00:18 192.168.1.15"
4892 # Test for address reuse after logical port is deleted.
4893 ovn-nbctl lsp-del p0
4894 ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
4895 AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4896 ["0a:00:00:00:00:19 192.168.1.2"
4899 # Test for multiple addresses to one logical port.
4900 ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4901 "0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
4902 ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
4903 AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4904 ["0a:00:00:00:00:1c 192.168.1.16"
4907 # Test for exhausting subnet address space.
4908 ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
4909 ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
4910 AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4911 ["0a:00:00:00:00:1d 172.16.1.2"
4914 ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
4915 AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4916 ["0a:00:00:00:00:1e"
4919 # Test that address management does not add duplicate MAC for lsp/lrp peers.
4920 ovn-nbctl create Logical_Router name=R2
4921 ovn-nbctl ls-add sw3
4922 ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4924 ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4925 network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4926 -- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4927 -- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
4928 ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
4929 AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4930 ["0a:00:00:00:00:20 192.168.1.17"
4933 # Test static MAC address with dynamically allocated IP
4934 ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
4935 "fe:dc:ba:98:76:54 dynamic"
4936 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4937 ["fe:dc:ba:98:76:54 192.168.1.18"
4940 # Update the static MAC address with dynamically allocated IP and check
4941 # if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
4942 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
4943 ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
4945 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4946 ["fe:dc:ba:98:76:55 192.168.1.18"
4949 ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
4950 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4951 ["fe:dc:ba:98:76:55 192.168.1.18"
4954 ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
4955 AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4956 ["fe:dc:ba:98:76:56 192.168.1.18"
4960 # Test the exclude_ips from the IPAM list
4961 ovn-nbctl --wait=sb set logical_switch sw0 \
4962 other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
4964 ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
4966 # 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
4967 AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
4968 ["0a:00:00:00:00:21 192.168.1.20"
4971 ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
4973 # 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
4974 AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
4975 ["0a:00:00:00:00:22 192.168.1.22"
4978 ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
4980 # 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
4981 AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
4982 ["0a:00:00:00:00:23 192.168.1.51"
4985 # Now clear the exclude_ips list. 192.168.1.19 should be assigned.
4986 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
4987 ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
4989 AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
4990 ["0a:00:00:00:00:24 192.168.1.19"
4993 # Set invalid data in exclude_ips list. It should be ignored.
4994 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
4995 ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
4997 # 192.168.1.21 should be assigned as that's the next free one.
4998 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
4999 ["0a:00:00:00:00:25 192.168.1.21"
5002 # Clear the dynamic addresses assignment request.
5003 ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5004 AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5009 ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5010 ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5013 # With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5014 # - aef0::800:ff:fe00:26 (EUI64)
5015 AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5016 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5019 ovn-nbctl --wait=sb ls-add sw4
5020 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5021 ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5024 AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5025 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5028 ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5029 "f0:00:00:00:10:12 dynamic"
5031 AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5032 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5035 # Clear the other_config for sw4. No dynamic ip should be assigned.
5036 ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5037 ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5040 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5044 # Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5045 ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5046 -- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5048 # Now p40 should be assigned with dynamic addresses.
5049 AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5050 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5053 ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5055 # p41 should not have IPv4 address (as the pool is exhausted).
5056 AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5057 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5061 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5064 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5067 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5071 AT_SETUP([ovn -- ipam connectivity])
5072 AT_SKIP_IF([test $HAVE_PYTHON = no])
5077 # Test for a ping using dynamically allocated addresses.
5078 ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5079 ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5082 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5083 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
5084 options:router-port=foo \
5085 -- lsp-set-addresses rp-foo router
5087 # Connect alice to R1
5088 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5089 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5090 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5092 # Create logical port foo1 in foo
5093 ovn-nbctl --wait=sb lsp-add foo foo1 \
5094 -- lsp-set-addresses foo1 "dynamic"
5095 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])
5097 # Create logical port alice1 in alice
5098 ovn-nbctl --wait=sb lsp-add alice alice1 \
5099 -- lsp-set-addresses alice1 "dynamic"
5100 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
5102 # Create logical port foo2 in foo
5103 ovn-nbctl --wait=sb lsp-add foo foo2 \
5104 -- lsp-set-addresses foo2 "dynamic"
5105 AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
5107 # Create a hypervisor and create OVS ports corresponding to logical ports.
5112 ovs-vsctl add-br br-phys
5113 ovn_attach n1 br-phys 192.168.0.1
5114 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5115 set interface hv1-vif1 external-ids:iface-id=foo1 \
5116 options:tx_pcap=hv1/vif1-tx.pcap \
5117 options:rxq_pcap=hv1/vif1-rx.pcap \
5120 ovs-vsctl -- add-port br-int hv1-vif2 -- \
5121 set interface hv1-vif2 external-ids:iface-id=foo2 \
5122 options:tx_pcap=hv1/vif2-tx.pcap \
5123 options:rxq_pcap=hv1/vif2-rx.pcap \
5126 ovs-vsctl -- add-port br-int hv1-vif3 -- \
5127 set interface hv1-vif3 external-ids:iface-id=alice1 \
5128 options:tx_pcap=hv1/vif3-tx.pcap \
5129 options:rxq_pcap=hv1/vif3-rx.pcap \
5132 # Allow some time for ovn-northd and ovn-controller to catch up.
5133 # XXX This should be more systematic.
5137 printf "%02x%02x%02x%02x" "$@"
5140 # Send ip packets between foo1 and foo2
5141 src_mac="0a0000000001"
5142 dst_mac="0a0000000003"
5143 src_ip=`ip_to_hex 192 168 1 2`
5144 dst_ip=`ip_to_hex 192 168 1 3`
5145 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5146 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5148 # Send ip packets between foo1 and alice1
5149 src_mac="0a0000000001"
5150 dst_mac="000000010203"
5151 src_ip=`ip_to_hex 192 168 1 2`
5152 dst_ip=`ip_to_hex 192 168 2 2`
5153 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5154 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5156 echo "---------NB dump-----"
5158 echo "---------------------"
5159 ovn-nbctl list logical_router
5160 echo "---------------------"
5161 ovn-nbctl list logical_router_port
5162 echo "---------------------"
5164 echo "---------SB dump-----"
5165 ovn-sbctl list datapath_binding
5166 echo "---------------------"
5167 ovn-sbctl list port_binding
5168 echo "---------------------"
5170 echo "------ hv1 dump ----------"
5171 as hv1 ovs-ofctl dump-flows br-int
5173 # Packet to Expect at foo2
5174 src_mac="0a0000000001"
5175 dst_mac="0a0000000003"
5176 src_ip=`ip_to_hex 192 168 1 2`
5177 dst_ip=`ip_to_hex 192 168 1 3`
5178 expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5180 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5181 echo $expected > expout
5182 AT_CHECK([cat received1.packets], [0], [expout])
5184 # Packet to Expect at alice1
5185 src_mac="000000010204"
5186 dst_mac="0a0000000002"
5187 src_ip=`ip_to_hex 192 168 1 2`
5188 dst_ip=`ip_to_hex 192 168 2 2`
5189 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5191 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5192 echo $expected > expout
5193 AT_CHECK([cat received2.packets], [0], [expout])
5199 AT_SETUP([ovn -- ovs-vswitchd restart])
5200 AT_KEYWORDS([vswitchd])
5201 AT_SKIP_IF([test $HAVE_PYTHON = no])
5204 ovn-nbctl ls-add ls1
5206 ovn-nbctl lsp-add ls1 ls1-lp1 \
5207 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5209 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5215 ovs-vsctl add-br br-phys
5216 ovn_attach n1 br-phys 192.168.0.1
5217 ovs-vsctl -- add-port br-int hv1-vif1 -- \
5218 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5219 options:tx_pcap=hv1/vif1-tx.pcap \
5220 options:rxq_pcap=hv1/vif1-rx.pcap \
5226 as hv1 ovs-vsctl show
5228 echo "---------------------"
5229 ovn-sbctl dump-flows
5230 echo "---------------------"
5232 echo "------ hv1 dump ----------"
5233 as hv1 ovs-ofctl dump-flows br-int
5234 total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5236 echo "Total flows before vswitchd restart = " $total_flows
5238 # Code taken from ovs-save utility
5240 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5241 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5242 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5243 echo "EOF" >> restore_flows.sh
5246 restart_vswitchd () {
5249 if test $restore_flows = true; then
5254 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5256 if test $restore_flows = true; then
5258 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5262 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5263 ovs-ofctl dump-flows br-int
5265 if test $restore_flows = true; then
5266 sh ./restore_flows.sh
5267 echo "Flows after restore"
5269 ovs-ofctl dump-flows br-int
5270 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5271 flow-restore-wait="true"
5275 # Save the flows, restart vswitchd and restore the flows
5276 restart_vswitchd true
5278 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5279 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5280 test "${total_flows}" = "${total_flows_after_restart}"
5283 # Restart vswitchd without restoring
5284 restart_vswitchd false
5286 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5287 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5288 test "${total_flows}" = "${total_flows_after_restart}"
5294 AT_SETUP([ovn -- send arp for nexthop])
5295 AT_SKIP_IF([test $HAVE_PYTHON = no])
5298 # Topology: Two LSs - ls1 and ls2 are connected via router r0
5300 # Create logical switches
5301 ovn-nbctl ls-add ls1
5302 ovn-nbctl ls-add ls2
5305 ovn-nbctl create Logical_Router name=lr0
5307 # Add router ls1p1 port to gateway router
5308 ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5309 ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5310 type=router options:router-port=lrp-ls1lp1 \
5311 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5313 # Add router ls2p2 port to gateway router
5314 ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5315 ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5316 type=router options:router-port=lrp-ls2lp1 \
5317 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5319 # Set default gateway (nexthop) to 192.168.1.254
5320 ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5322 # Create logical port ls1lp2 in ls1
5323 ovn-nbctl lsp-add ls1 ls1lp2 \
5324 -- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5326 # Create logical port ls2lp2 in ls2
5327 ovn-nbctl lsp-add ls2 ls2lp2 \
5328 -- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5333 ovs-vsctl add-br br-phys
5334 ovn_attach n1 br-phys 192.168.0.1
5335 ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5336 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5337 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5338 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5340 ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5341 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5342 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5343 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5346 # Allow some time for ovn-northd and ovn-controller to catch up.
5347 # XXX This should be more systematic.
5350 echo "---------NB dump-----"
5352 echo "---------------------"
5353 ovn-nbctl list logical_router
5354 echo "---------------------"
5355 ovn-nbctl list logical_router_port
5356 echo "---------------------"
5358 echo "---------SB dump-----"
5359 ovn-sbctl list datapath_binding
5360 echo "---------------------"
5361 ovn-sbctl list port_binding
5362 echo "---------------------"
5363 ovn-sbctl dump-flows
5364 echo "---------------------"
5365 ovn-sbctl list chassis
5366 ovn-sbctl list encap
5367 echo "---------------------"
5369 echo "------Flows dump-----"
5371 ovs-ofctl dump-flows
5372 echo "---------------------"
5375 printf "%02x%02x%02x%02x" "$@"
5378 src_mac="f00000000003"
5379 dst_mac="f00000000001"
5380 src_ip=`ip_to_hex 192 168 0 2`
5381 dst_ip=`ip_to_hex 8 8 8 8`
5382 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5384 # Send IP packet destined to 8.8.8.8 from lsp1lp2
5385 as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5388 sed 's/\(00\)\{1,\}$//'
5391 # ARP packet should be received with Target IP Address set to 192.168.1.254 and
5394 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5395 expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5396 echo $expected > expout
5397 AT_CHECK([cat packets], [0], [expout])
5404 AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
5405 AT_SKIP_IF([test $HAVE_PYTHON = no])
5407 # Create logical switch
5408 ovn-nbctl ls-add ls0
5409 # Create gateway router
5410 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5411 # Add router port to gateway router
5412 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5413 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5414 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5415 # Add nat-address option
5416 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5425 ovn_attach n1 br-phys 192.168.0.1
5427 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5428 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])
5430 # Create a localnet port.
5431 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5432 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5433 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5434 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5437 # Wait for packet to be received.
5438 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5440 sed 's/\(00\)\{1,\}$//'
5442 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5443 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5444 echo $expected > expout
5445 AT_CHECK([sort packets], [0], [expout])
5452 AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5453 AT_SKIP_IF([test $HAVE_PYTHON = no])
5455 # Create logical switch
5456 ovn-nbctl ls-add ls0
5457 # Create gateway router
5458 ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5459 # Add router port to gateway router
5460 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5461 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5462 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
5463 # Add nat-address option
5464 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5466 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5467 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5468 # Add load balancers
5469 AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5470 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5471 AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5472 AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5481 ovn_attach n1 br-phys 192.168.0.1
5483 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5484 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])
5486 # Create a localnet port.
5487 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5488 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5489 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5490 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5493 # Wait for packet to be received.
5494 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5496 sed 's/\(00\)\{1,\}$//'
5498 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5499 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5500 echo $expected > expout
5501 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5502 echo $expected >> expout
5503 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5504 echo $expected >> expout
5505 AT_CHECK([sort packets], [0], [expout])
5512 AT_SETUP([ovn -- delete mac bindings])
5517 ovs-vsctl -- add-br br-phys
5518 ovn_attach n1 br-phys 192.168.0.1
5519 # Create logical switch ls0
5520 ovn-nbctl ls-add ls0
5521 # Create ports lp0, lp1 in ls0
5522 ovn-nbctl lsp-add ls0 lp0
5523 ovn-nbctl lsp-add ls0 lp1
5524 ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5525 ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5526 dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5527 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5528 ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5529 ovn-sbctl find MAC_Binding
5530 # Delete port lp0 and check that its MAC_Binding is deleted.
5531 ovn-nbctl lsp-del lp0
5532 ovn-sbctl find MAC_Binding
5533 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5534 # Delete logical switch ls0 and check that its MAC_Binding is deleted.
5535 ovn-nbctl ls-del ls0
5536 ovn-sbctl find MAC_Binding
5537 OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
5543 AT_SETUP([ovn -- conntrack zone allocation])
5544 AT_SKIP_IF([test $HAVE_PYTHON = no])
5548 # 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5549 # connected to a router R1.
5550 # foo has foo1 to act as a client.
5551 # bar has bar1, bar2, bar3 to act as servers.
5557 ovs-vsctl add-br br-phys
5558 ovn_attach n1 br-phys 192.168.0.1
5559 for i in foo1 bar1 bar2 bar3; do
5560 ovs-vsctl -- add-port br-int $i -- \
5561 set interface $i external-ids:iface-id=$i \
5562 options:tx_pcap=hv1/$i-tx.pcap \
5563 options:rxq_pcap=hv1/$i-rx.pcap
5566 ovn-nbctl create Logical_Router name=R1
5567 ovn-nbctl ls-add foo
5568 ovn-nbctl ls-add bar
5571 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5572 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5573 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5576 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5577 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5578 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5580 # Create logical port foo1 in foo
5581 ovn-nbctl lsp-add foo foo1 \
5582 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5584 # Create logical port bar1, bar2 and bar3 in bar
5585 for i in `seq 1 3`; do
5587 ovn-nbctl lsp-add bar bar$i \
5588 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5591 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5597 AT_SETUP([ovn -- tag allocation])
5600 AT_CHECK([ovn-nbctl ls-add ls0])
5601 AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5602 AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5603 AT_CHECK([ovn-nbctl ls-add ls1])
5605 dnl When a tag is provided, no allocation is done
5606 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5607 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5609 dnl The same 'tag' gets created in southbound database.
5610 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5611 logical_port="c0"], [0], [3
5614 dnl Allocate tags and see it getting created in both NB and SB
5615 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5616 AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5618 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5619 logical_port="c1"], [0], [1
5622 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5623 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5625 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5626 logical_port="c2"], [0], [2
5628 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5629 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5631 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5632 logical_port="c3"], [0], [4
5635 dnl A different parent.
5636 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5637 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5639 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5640 logical_port="c4"], [0], [1
5643 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5644 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5646 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5647 logical_port="c5"], [0], [2
5650 dnl Delete a logical port and create a new one.
5651 AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5652 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5653 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5655 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5656 logical_port="c6"], [0], [1
5659 dnl Restart northd to see that the same allocation remains.
5661 OVS_APP_EXIT_AND_WAIT([ovn-northd])
5662 start_daemon ovn-northd \
5663 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5664 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5666 dnl Create a switch to make sure that ovn-northd has run through the main loop.
5667 AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5668 AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5670 AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5672 AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5674 AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5676 AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5678 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5681 dnl Create a switch port with a tag that has already been allocated.
5682 dnl It should go through fine with a duplicate tag.
5683 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5684 AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5686 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5687 logical_port="c7"], [0], [2
5689 AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5692 AT_CHECK([ovn-nbctl ls-add ls2])
5693 dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5694 dnl gets copied to 'tag'
5695 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5696 AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5698 dnl The same 'tag' gets created in southbound database.
5699 AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5700 logical_port="local0"], [0], [25
5702 dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5703 AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5704 AT_CHECK([ovn-nbctl lsp-get-tag local1])
5705 dnl change the tag_request.
5706 AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5707 AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5712 AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
5714 ovn-nbctl ls-add lsw0
5719 ovs-vsctl add-br br-phys
5720 ovn_attach n1 br-phys 192.168.0.$i
5721 ovs-vsctl add-br br-eth0
5722 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5725 # Create a localnet port.
5726 AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5727 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5728 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5729 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5733 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5734 AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5735 AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5736 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5737 AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5738 AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5739 AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5740 AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5741 AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5743 # Bind the localvif1 to hv1.
5745 AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5747 # On hv1, check that there are no flows outputting bcast to tunnel
5748 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5750 # On hv2, check that no flow outputs bcast to tunnel to hv1.
5752 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5754 # Now bind vif2 on hv2.
5755 AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5757 # At this point, the broadcast flow on vif2 should be deleted.
5758 # because, there is now a localnet vif bound (table=32 programming logic)
5759 OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5761 # Verify that the local net patch port exists on hv2.
5762 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5764 # Now bind vif3 on hv2.
5765 AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5767 # Verify that the local net patch port still exists on hv2
5768 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5771 AT_CHECK([ovn-nbctl lsp-del localvif2])
5773 # Verify that the local net patch port still exists on hv2,
5774 # because, localvif3 is still bound.
5775 OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5777 OVN_CLEANUP([hv1],[hv2])
5782 AT_SETUP([ovn -- ACL logging])
5790 ovs-vsctl add-br br-phys
5791 ovn_attach n1 br-phys 192.168.0.1
5792 for i in lp1 lp2; do
5793 ovs-vsctl -- add-port br-int $i -- \
5794 set interface $i external-ids:iface-id=$i \
5795 options:tx_pcap=hv/$i-tx.pcap \
5796 options:rxq_pcap=hv/$i-rx.pcap
5799 lp1_mac="f0:00:00:00:00:01"
5800 lp1_ip="192.168.1.2"
5802 lp2_mac="f0:00:00:00:00:02"
5803 lp2_ip="192.168.1.3"
5805 ovn-nbctl ls-add lsw0
5806 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5807 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5808 ovn-nbctl lsp-set-addresses lp1 $lp1_mac
5809 ovn-nbctl lsp-set-addresses lp2 $lp2_mac
5810 ovn-nbctl --wait=sb sync
5812 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
5813 ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
5815 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
5816 ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
5818 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
5819 ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
5821 ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
5822 ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
5824 ovn-sbctl dump-flows
5827 # Send packet that should be dropped without logging.
5828 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5829 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5830 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
5831 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5833 # Send packet that should be dropped with logging.
5834 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5835 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5836 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
5837 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5839 # Send packet that should be allowed without logging.
5840 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5841 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5842 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
5843 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5845 # Send packet that should be allowed with logging.
5846 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5847 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5848 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
5849 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5851 # Send packet that should allow related flows without logging.
5852 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5853 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5854 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
5855 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5857 # Send packet that should allow related flows with logging.
5858 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5859 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5860 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
5861 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5863 # Send packet that should be rejected without logging.
5864 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5865 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5866 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
5867 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5869 # Send packet that should be rejected with logging.
5870 packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
5871 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
5872 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
5873 as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
5875 OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
5877 AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
5878 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
5879 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
5880 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
5881 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
5888 AT_SETUP([ovn -- DSCP marking check])
5892 ovn-nbctl ls-add lsw0
5893 ovn-nbctl --wait=sb lsp-add lsw0 lp1
5894 ovn-nbctl --wait=sb lsp-add lsw0 lp2
5895 ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5896 ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5897 ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5898 ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5899 ovn-nbctl --wait=sb sync
5903 ovs-vsctl add-br br-phys
5904 ovn_attach n1 br-phys 192.168.0.1
5905 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
5906 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
5908 AT_CAPTURE_FILE([trace])
5910 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5913 # Extracts nw_tos from the final flow from ofproto/trace output and prints
5914 # it on stdout. Prints "none" if no nw_tos was included.
5915 get_final_nw_tos() {
5916 if flow=$(grep '^Final flow:' stdout); then :; else
5917 # The output didn't have a final flow.
5921 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5930 # Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5932 # First check with ovn-trace for logical flows.
5933 echo "checking for tos $1"
5934 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
5935 echo 'output("lp2");') > expout
5936 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])
5938 # Then re-check with ofproto/trace for a physical packet.
5939 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])
5940 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
5945 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");
5947 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])
5948 AT_CHECK([get_final_nw_tos], [0], [none
5951 # check at L3 without dscp marking
5954 # Mark DSCP with a valid value
5955 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)
5958 # Update the DSCP marking
5959 ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
5962 ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
5965 # Disable DSCP marking
5966 ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
5972 AT_SETUP([ovn -- read-only sb db:ptcp access])
5973 AT_SKIP_IF([test $HAVE_PYTHON = no])
5976 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
5978 # Add read-only remote to sb ovsdb-server
5980 [ovsdb-tool transact ovn-sb.db \
5981 ['["OVN_Southbound",
5983 "table": "SB_Global",
5985 "connections": ["set", [["named-uuid", "xyz"]]]}},
5987 "table": "Connection",
5989 "row": {"target": "ptcp:0:127.0.0.1",
5990 "read_only": true}}]']], [0], [ignore], [ignore])
5992 start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
5994 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
5996 # read-only accesses should succeed
5997 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
5998 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6000 # write access should fail
6001 AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6002 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6005 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6008 AT_SETUP([ovn -- read-only sb db:pssl access])
6009 AT_SKIP_IF([test $HAVE_PYTHON = no])
6010 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6011 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6012 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6016 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6018 # Add read-only remote to sb ovsdb-server
6020 [ovsdb-tool transact ovn-sb.db \
6021 ['["OVN_Southbound",
6023 "table": "SB_Global",
6025 "connections": ["set", [["named-uuid", "xyz"]]]}},
6027 "table": "Connection",
6029 "row": {"target": "pssl:0:127.0.0.1",
6030 "read_only": true}}]']], [0], [ignore], [ignore])
6032 start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6033 --remote=db:OVN_Southbound,SB_Global,connections \
6034 --private-key="$PKIDIR/testpki-privkey2.pem" \
6035 --certificate="$PKIDIR/testpki-cert2.pem" \
6036 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6039 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6041 # read-only accesses should succeed
6042 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6043 --private-key=$PKIDIR/testpki-privkey.pem \
6044 --certificate=$PKIDIR/testpki-cert.pem \
6045 --ca-cert=$PKIDIR/testpki-cacert.pem \
6046 list SB_Global], [0], [stdout], [ignore])
6047 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6048 --private-key=$PKIDIR/testpki-privkey.pem \
6049 --certificate=$PKIDIR/testpki-cert.pem \
6050 --ca-cert=$PKIDIR/testpki-cacert.pem \
6051 list Connection], [0], [stdout], [ignore])
6053 # write access should fail
6054 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6055 --private-key=$PKIDIR/testpki-privkey.pem \
6056 --certificate=$PKIDIR/testpki-cert.pem \
6057 --ca-cert=$PKIDIR/testpki-cacert.pem \
6058 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6059 [ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6062 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6065 AT_SETUP([ovn -- nb connection/ssl commands])
6066 AT_SKIP_IF([test $HAVE_PYTHON = no])
6067 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6068 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6069 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6073 ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6075 # Start nb db server using db connection/ssl entries (unpopulated initially)
6076 start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6077 --remote=db:OVN_Northbound,NB_Global,connections \
6078 --private-key=db:OVN_Northbound,SSL,private_key \
6079 --certificate=db:OVN_Northbound,SSL,certificate \
6080 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6083 # Populate SSL configuration entries in nb db
6085 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6086 $PKIDIR/testpki-cert.pem \
6087 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6089 # Populate a passive SSL connection in nb db
6090 AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6092 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6094 # Verify SSL connetivity to nb db server
6095 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6096 --private-key=$PKIDIR/testpki-privkey.pem \
6097 --certificate=$PKIDIR/testpki-cert.pem \
6098 --ca-cert=$PKIDIR/testpki-cacert.pem \
6100 [0], [stdout], [ignore])
6101 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6102 --private-key=$PKIDIR/testpki-privkey.pem \
6103 --certificate=$PKIDIR/testpki-cert.pem \
6104 --ca-cert=$PKIDIR/testpki-cacert.pem \
6106 [0], [stdout], [ignore])
6107 AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6108 --private-key=$PKIDIR/testpki-privkey.pem \
6109 --certificate=$PKIDIR/testpki-cert.pem \
6110 --ca-cert=$PKIDIR/testpki-cacert.pem \
6112 [0], [stdout], [ignore])
6114 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6117 AT_SETUP([ovn -- sb connection/ssl commands])
6118 AT_SKIP_IF([test $HAVE_PYTHON = no])
6119 AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6120 PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6121 AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6125 ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6127 # Start sb db server using db connection/ssl entries (unpopulated initially)
6128 start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6129 --remote=db:OVN_Southbound,SB_Global,connections \
6130 --private-key=db:OVN_Southbound,SSL,private_key \
6131 --certificate=db:OVN_Southbound,SSL,certificate \
6132 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6135 # Populate SSL configuration entries in sb db
6137 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6138 $PKIDIR/testpki-cert.pem \
6139 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6141 # Populate a passive SSL connection in sb db
6142 AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6144 PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6146 # Verify SSL connetivity to sb db server
6147 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6148 --private-key=$PKIDIR/testpki-privkey.pem \
6149 --certificate=$PKIDIR/testpki-cert.pem \
6150 --ca-cert=$PKIDIR/testpki-cacert.pem \
6152 [0], [stdout], [ignore])
6153 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6154 --private-key=$PKIDIR/testpki-privkey.pem \
6155 --certificate=$PKIDIR/testpki-cert.pem \
6156 --ca-cert=$PKIDIR/testpki-cacert.pem \
6158 [0], [stdout], [ignore])
6159 AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6160 --private-key=$PKIDIR/testpki-privkey.pem \
6161 --certificate=$PKIDIR/testpki-cert.pem \
6162 --ca-cert=$PKIDIR/testpki-cacert.pem \
6164 [0], [stdout], [ignore])
6166 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6169 AT_SETUP([ovn -- nested containers])
6173 # 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6176 # 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6177 # and "bar" (192.168.2.0/24). They are all connected to router R1.
6180 ovn-nbctl ls-add mgmt
6181 ovn-nbctl ls-add foo
6182 ovn-nbctl ls-add bar
6184 # Connect mgmt to R1
6185 ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6186 ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6187 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6190 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6191 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6192 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6195 ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6196 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6197 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6199 # "mgmt" has VM1 and VM2 connected
6200 ovn-nbctl lsp-add mgmt vm1 \
6201 -- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6203 ovn-nbctl lsp-add mgmt vm2 \
6204 -- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6206 # "foo1" and "foo2" are containers belonging to switch "foo"
6207 # "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6208 ovn-nbctl lsp-add foo foo1 vm1 1 \
6209 -- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6211 ovn-nbctl lsp-add foo foo2 vm2 2 \
6212 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6214 # "bar1" and "bar2" are containers belonging to switch "bar"
6215 # "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6216 ovn-nbctl lsp-add bar bar1 vm1 2 \
6217 -- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6219 ovn-nbctl lsp-add bar bar2 vm2 1 \
6220 -- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6222 # bar3 is a standalone VM belonging to switch "bar"
6223 ovn-nbctl lsp-add bar bar3 \
6224 -- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6226 # Create two hypervisor and create OVS ports corresponding to logical ports.
6231 ovs-vsctl add-br br-phys
6232 ovn_attach n1 br-phys 192.168.0.1
6233 ovs-vsctl -- add-port br-int vm1 -- \
6234 set interface vm1 external-ids:iface-id=vm1 \
6235 options:tx_pcap=hv1/vm1-tx.pcap \
6236 options:rxq_pcap=hv1/vm1-rx.pcap \
6239 ovs-vsctl -- add-port br-int bar3 -- \
6240 set interface bar3 external-ids:iface-id=bar3 \
6241 options:tx_pcap=hv1/bar3-tx.pcap \
6242 options:rxq_pcap=hv1/bar3-rx.pcap \
6247 ovs-vsctl add-br br-phys
6248 ovn_attach n1 br-phys 192.168.0.2
6249 ovs-vsctl -- add-port br-int vm2 -- \
6250 set interface vm2 external-ids:iface-id=vm2 \
6251 options:tx_pcap=hv2/vm2-tx.pcap \
6252 options:rxq_pcap=hv2/vm2-rx.pcap \
6255 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6256 # packets for ARP resolution (native tunneling doesn't queue packets
6257 # for ARP resolution).
6260 # Allow some time for ovn-northd and ovn-controller to catch up.
6261 # XXX This should be more systematic.
6265 printf "%02x%02x%02x%02x" "$@"
6268 # Send ip packets between foo1 and foo2 (same switch, different HVs and
6269 # different VLAN tags).
6270 src_mac="f00000010205"
6271 dst_mac="f00000010206"
6272 src_ip=`ip_to_hex 192 168 1 2`
6273 dst_ip=`ip_to_hex 192 168 1 3`
6274 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6275 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6277 # expected packet at foo2
6278 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6279 echo $packet > expected
6280 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6282 # Send ip packets between foo1 and bar2 (different switch, different HV)
6283 src_mac="f00000010205"
6284 dst_mac="000000010203"
6285 src_ip=`ip_to_hex 192 168 1 2`
6286 dst_ip=`ip_to_hex 192 168 2 3`
6287 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6288 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6290 # expected packet at bar2
6291 src_mac="000000010204"
6292 dst_mac="f00000010208"
6293 packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6294 echo $packet >> expected
6295 OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6297 # Send ip packets between foo1 and bar1
6298 # (different switch, loopback to same vm but different tag)
6299 src_mac="f00000010205"
6300 dst_mac="000000010203"
6301 src_ip=`ip_to_hex 192 168 1 2`
6302 dst_ip=`ip_to_hex 192 168 2 2`
6303 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6304 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6306 # expected packet at bar1
6307 src_mac="000000010204"
6308 dst_mac="f00000010207"
6309 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6310 echo $packet > expected1
6311 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6313 # Send ip packets between bar1 and bar3
6314 # (same switch. But one is container and another is a standalone VM)
6315 src_mac="f00000010207"
6316 dst_mac="f00000010209"
6317 src_ip=`ip_to_hex 192 168 2 2`
6318 dst_ip=`ip_to_hex 192 168 2 3`
6319 packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6320 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6322 # expected packet at bar3
6323 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6324 echo $packet > expected
6325 OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6327 # Send ip packets between foo1 and vm1.
6328 (different switch, container to the VM hosting it.)
6329 src_mac="f00000010205"
6330 dst_mac="000000010203"
6331 src_ip=`ip_to_hex 192 168 1 2`
6332 dst_ip=`ip_to_hex 172 16 1 2`
6333 packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6334 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6336 # expected packet at vm1
6337 src_mac="000000010202"
6338 dst_mac="f00000010203"
6339 packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6340 echo $packet >> expected1
6341 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6343 # Send packets from vm1 to bar1.
6344 (different switch, A hosting VM to a container inside it)
6345 src_mac="f00000010203"
6346 dst_mac="000000010202"
6347 src_ip=`ip_to_hex 172 16 1 2`
6348 dst_ip=`ip_to_hex 192 168 2 2`
6349 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6350 as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6352 # expected packet at vm1
6353 src_mac="000000010204"
6354 dst_mac="f00000010207"
6355 packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6356 echo $packet >> expected1
6357 OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6359 OVN_CLEANUP([hv1],[hv2])
6363 AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6364 AT_SKIP_IF([test $HAVE_PYTHON = no])
6368 # Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6369 # in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6370 # (192.168.2.0/24) connected to it.
6372 # R2 and R3 are gateway routers.
6373 # R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6374 # connected to it. Note how both alice and bob have the same subnet behind it.
6375 # We are trying to simulate external network via those 2 switches. In real
6376 # world the switch ports of these switches will have addresses set as "unknown"
6377 # to make them learning switches. Or those switches will be "localnet" ones.
6379 # Create three hypervisors and create OVS ports corresponding to logical ports.
6384 ovs-vsctl add-br br-phys
6385 ovn_attach n1 br-phys 192.168.0.1
6386 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6387 set interface hv1-vif1 external-ids:iface-id=foo1 \
6388 options:tx_pcap=hv1/vif1-tx.pcap \
6389 options:rxq_pcap=hv1/vif1-rx.pcap \
6392 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6393 set interface hv1-vif2 external-ids:iface-id=bar1 \
6394 options:tx_pcap=hv1/vif2-tx.pcap \
6395 options:rxq_pcap=hv1/vif2-rx.pcap \
6400 ovs-vsctl add-br br-phys
6401 ovn_attach n1 br-phys 192.168.0.2
6402 ovs-vsctl -- add-port br-int hv2-vif1 -- \
6403 set interface hv2-vif1 external-ids:iface-id=alice1 \
6404 options:tx_pcap=hv2/vif1-tx.pcap \
6405 options:rxq_pcap=hv2/vif1-rx.pcap \
6410 ovs-vsctl add-br br-phys
6411 ovn_attach n1 br-phys 192.168.0.3
6412 ovs-vsctl -- add-port br-int hv3-vif1 -- \
6413 set interface hv3-vif1 external-ids:iface-id=bob1 \
6414 options:tx_pcap=hv3/vif1-tx.pcap \
6415 options:rxq_pcap=hv3/vif1-rx.pcap \
6419 ovn-nbctl create Logical_Router name=R1
6420 ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6421 ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6423 ovn-nbctl ls-add foo
6424 ovn-nbctl ls-add bar
6425 ovn-nbctl ls-add alice
6426 ovn-nbctl ls-add bob
6427 ovn-nbctl ls-add join
6430 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6431 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6432 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6435 ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6436 ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6437 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6439 # Connect alice to R2
6440 ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6441 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6442 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6445 ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6446 ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6447 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6449 # Connect R1 to join
6450 ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6451 ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6452 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6454 # Connect R2 to join
6455 ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6456 ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6457 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6459 # Connect R3 to join
6460 ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6461 ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6462 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6464 # Install static routes with source ip address as the policy for routing.
6465 # We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6466 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6467 ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6469 # Install static routes with destination ip address as the policy for routing.
6470 ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6472 ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6474 # Create logical port foo1 in foo
6475 ovn-nbctl lsp-add foo foo1 \
6476 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6478 # Create logical port bar1 in bar
6479 ovn-nbctl lsp-add bar bar1 \
6480 -- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6482 # Create logical port alice1 in alice
6483 ovn-nbctl lsp-add alice alice1 \
6484 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6486 # Create logical port bob1 in bob
6487 ovn-nbctl lsp-add bob bob1 \
6488 -- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6490 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6491 # packets for ARP resolution (native tunneling doesn't queue packets
6492 # for ARP resolution).
6495 # Allow some time for ovn-northd and ovn-controller to catch up.
6496 # XXX This should be more systematic.
6500 printf "%02x%02x%02x%02x" "$@"
6503 sed 's/\(00\)\{1,\}$//'
6506 # Send ip packets between foo1 and bar1
6507 # (East-west traffic should flow normally)
6508 src_mac="f00000010203"
6509 dst_mac="000001010203"
6510 src_ip=`ip_to_hex 192 168 1 2`
6511 dst_ip=`ip_to_hex 192 168 2 2`
6512 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6513 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6515 # Send ip packets between foo1 and alice1
6516 src_mac="f00000010203"
6517 dst_mac="000001010203"
6518 src_ip=`ip_to_hex 192 168 1 2`
6519 dst_ip=`ip_to_hex 172 16 1 3`
6520 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6521 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6522 as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
6524 # Send ip packets between bar1 and bob1
6525 src_mac="f00000010204"
6526 dst_mac="000001010204"
6527 src_ip=`ip_to_hex 192 168 2 2`
6528 dst_ip=`ip_to_hex 172 16 1 4`
6529 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6530 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6531 #as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6533 # Packet to expect at bar1
6534 src_mac="000001010204"
6535 dst_mac="f00000010204"
6536 src_ip=`ip_to_hex 192 168 1 2`
6537 dst_ip=`ip_to_hex 192 168 2 2`
6538 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6539 echo $expected > expected
6540 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6542 # Packet to Expect at alice1
6543 src_mac="000002010203"
6544 dst_mac="f00000010205"
6545 src_ip=`ip_to_hex 192 168 1 2`
6546 dst_ip=`ip_to_hex 172 16 1 3`
6547 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6548 echo $expected > expected
6549 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6551 # Packet to Expect at bob1
6552 src_mac="000003010203"
6553 dst_mac="f00000010206"
6554 src_ip=`ip_to_hex 192 168 2 2`
6555 dst_ip=`ip_to_hex 172 16 1 4`
6556 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6557 echo $expected > expected
6558 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6560 for sim in hv1 hv2 hv3; do
6562 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6563 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6564 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6568 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6571 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6574 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6577 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6578 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6582 AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6583 AT_SKIP_IF([test $HAVE_PYTHON = no])
6586 ovn-nbctl ls-add ls1
6588 ovn-nbctl lsp-add ls1 ls1-lp1 \
6589 -- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6591 ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6593 ovn-nbctl lsp-add ls1 ls1-lp2 \
6594 -- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6596 ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6598 DNS1=`ovn-nbctl create DNS records={}`
6599 DNS2=`ovn-nbctl create DNS records={}`
6601 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6602 ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6603 ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6605 ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6611 ovs-vsctl add-br br-phys
6612 ovn_attach n1 br-phys 192.168.0.1
6613 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6614 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6615 options:tx_pcap=hv1/vif1-tx.pcap \
6616 options:rxq_pcap=hv1/vif1-rx.pcap \
6619 ovs-vsctl -- add-port br-int hv1-vif2 -- \
6620 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
6621 options:tx_pcap=hv1/vif2-tx.pcap \
6622 options:rxq_pcap=hv1/vif2-rx.pcap \
6627 as hv1 ovs-vsctl show
6629 echo "*************************"
6631 echo "*************************"
6634 printf "%02x%02x%02x%02x" "$@"
6640 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
6641 options:rxq_pcap=dummy-rx.pcap
6642 rm -f ${pcap_file}*.pcap
6643 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
6644 options:rxq_pcap=${pcap_file}-rx.pcap
6647 # set_dns_params host_name
6648 # Sets the dns_req_data and dns_resp_data
6657 query_name=03766d31036f766e036f726700
6658 # IPv4 address - 10.0.0.4
6659 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6663 query_name=03766d32036f766e036f726700
6664 # IPv4 address - 10.0.0.6
6665 expected_dns_answer=${query_name}00010001${ttl}00040a000006
6666 # IPv4 address - 20.0.0.4
6667 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
6672 query_name=03766d33036f766e036f726700
6673 # IPv4 address - 40.0.0.4
6674 expected_dns_answer=${query_name}00010001${ttl}000428000004
6678 query_name=03766d31036f766e036f726700
6679 # IPv6 address - aef0::4
6681 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
6685 query_name=03766d31036f766e036f726700
6688 # IPv4 address - 10.0.0.4
6689 # IPv6 address - aef0::4
6690 expected_dns_answer=${query_name}00010001${ttl}00040a000004
6691 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
6692 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
6696 query_name=03766d31036f766e036f726700
6697 # IPv6 address - aef0::4
6705 local dns_req_header=010201200001000000000000
6706 local dns_resp_header=010281200001${an_count}00000000
6707 dns_req_data=${dns_req_header}${query_name}${type}0001
6708 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
6711 # This shell function sends a DNS request packet
6712 # test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
6714 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
6715 local dns_query_data=$7
6716 shift; shift; shift; shift; shift; shift; shift;
6717 # Packet size => IPv4 header (20) + UDP header (8) +
6718 # DNS data (header + query)
6719 ip_len=`expr 28 + ${#dns_query_data} / 2`
6720 udp_len=`expr $ip_len - 20`
6721 ip_len=$(printf "%x" $ip_len)
6722 udp_len=$(printf "%x" $udp_len)
6723 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
6724 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
6726 request=${request}${dns_query_data}
6728 if test $dns_reply != 0; then
6730 ip_len=`expr 28 + ${#dns_reply} / 2`
6731 udp_len=`expr $ip_len - 20`
6732 ip_len=$(printf "%x" $ip_len)
6733 udp_len=$(printf "%x" $udp_len)
6734 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
6735 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
6736 echo $reply >> $inport.expected
6739 echo $request >> $outport.expected
6742 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
6745 AT_CAPTURE_FILE([ofctl_monitor0.log])
6746 as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
6747 --pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
6750 src_ip=`ip_to_hex 10 0 0 4`
6751 dst_ip=`ip_to_hex 10 0 0 1`
6753 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6755 # NXT_RESUMEs should be 1.
6756 OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6758 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6759 cat 1.expected | cut -c -48 > expout
6760 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6761 # Skipping the IPv4 checksum.
6762 cat 1.expected | cut -c 53- > expout
6763 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6765 reset_pcap_file hv1-vif1 hv1/vif1
6766 reset_pcap_file hv1-vif2 hv1/vif2
6771 src_ip=`ip_to_hex 10 0 0 6`
6772 dst_ip=`ip_to_hex 10 0 0 1`
6774 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6776 # NXT_RESUMEs should be 2.
6777 OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6779 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6780 cat 2.expected | cut -c -48 > expout
6781 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6782 # Skipping the IPv4 checksum.
6783 cat 2.expected | cut -c 53- > expout
6784 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6786 reset_pcap_file hv1-vif1 hv1/vif1
6787 reset_pcap_file hv1-vif2 hv1/vif2
6791 # Clear the query name options for ls1-lp2
6792 ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
6795 src_ip=`ip_to_hex 10 0 0 4`
6796 dst_ip=`ip_to_hex 10 0 0 1`
6798 test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
6800 # NXT_RESUMEs should be 3.
6801 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6803 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6804 AT_CHECK([cat 1.packets], [0], [])
6806 reset_pcap_file hv1-vif1 hv1/vif1
6807 reset_pcap_file hv1-vif2 hv1/vif2
6811 # Clear the query name for ls1-lp1
6812 # Since ls1 has no query names configued,
6813 # ovn-northd should not add the DNS flows.
6814 ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
6817 src_ip=`ip_to_hex 10 0 0 6`
6818 dst_ip=`ip_to_hex 10 0 0 1`
6820 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6822 # NXT_RESUMEs should be 3 only.
6823 OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6825 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6826 AT_CHECK([cat 2.packets], [0], [])
6828 reset_pcap_file hv1-vif1 hv1/vif1
6829 reset_pcap_file hv1-vif2 hv1/vif2
6833 # Test IPv6 (AAAA records) using IPv4 packet.
6834 # Add back the DNS options for ls1-lp1.
6835 ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6837 set_dns_params vm1_ipv6_only
6838 src_ip=`ip_to_hex 10 0 0 6`
6839 dst_ip=`ip_to_hex 10 0 0 1`
6841 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6843 # NXT_RESUMEs should be 4.
6844 OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6846 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6847 cat 2.expected | cut -c -48 > expout
6848 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6849 # Skipping the IPv4 checksum.
6850 cat 2.expected | cut -c 53- > expout
6851 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6853 reset_pcap_file hv1-vif1 hv1/vif1
6854 reset_pcap_file hv1-vif2 hv1/vif2
6858 # Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
6859 set_dns_params vm1_ipv4_v6
6860 src_ip=`ip_to_hex 10 0 0 6`
6861 dst_ip=`ip_to_hex 10 0 0 1`
6863 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6865 # NXT_RESUMEs should be 5.
6866 OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6868 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6869 cat 2.expected | cut -c -48 > expout
6870 AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
6871 # Skipping the IPv4 checksum.
6872 cat 2.expected | cut -c 53- > expout
6873 AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
6875 reset_pcap_file hv1-vif1 hv1/vif1
6876 reset_pcap_file hv1-vif2 hv1/vif2
6881 set_dns_params vm1_invalid_type
6882 src_ip=`ip_to_hex 10 0 0 6`
6883 dst_ip=`ip_to_hex 10 0 0 1`
6885 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6887 # NXT_RESUMEs should be 6.
6888 OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6890 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6891 AT_CHECK([cat 2.packets], [0], [])
6893 reset_pcap_file hv1-vif1 hv1/vif1
6894 reset_pcap_file hv1-vif2 hv1/vif2
6898 # Incomplete DNS packet.
6899 set_dns_params vm1_incomplete
6900 src_ip=`ip_to_hex 10 0 0 6`
6901 dst_ip=`ip_to_hex 10 0 0 1`
6903 test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
6905 # NXT_RESUMEs should be 7.
6906 OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6908 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
6909 AT_CHECK([cat 2.packets], [0], [])
6911 reset_pcap_file hv1-vif1 hv1/vif1
6912 reset_pcap_file hv1-vif2 hv1/vif2
6916 # Add one more DNS record to the ls1.
6917 ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
6920 src_ip=`ip_to_hex 10 0 0 4`
6921 dst_ip=`ip_to_hex 10 0 0 1`
6923 test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
6925 # NXT_RESUMEs should be 8.
6926 OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
6928 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
6929 cat 1.expected | cut -c -48 > expout
6930 AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
6931 # Skipping the IPv4 checksum.
6932 cat 1.expected | cut -c 53- > expout
6933 AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
6935 reset_pcap_file hv1-vif1 hv1/vif1
6936 reset_pcap_file hv1-vif2 hv1/vif2
6941 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6942 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6943 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6946 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6949 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6952 OVS_APP_EXIT_AND_WAIT([ovn-northd])
6955 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6956 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6959 AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
6960 AT_SKIP_IF([test $HAVE_PYTHON = no])
6967 ovs-vsctl add-br br-phys
6968 ovn_attach n1 br-phys 192.168.0.1
6969 ovs-vsctl -- add-port br-int hv1-vif1 -- \
6970 set interface hv1-vif1 external-ids:iface-id=foo1 \
6971 options:tx_pcap=hv1/vif1-tx.pcap \
6972 options:rxq_pcap=hv1/vif1-rx.pcap \
6977 ovs-vsctl add-br br-phys
6978 ovn_attach n1 br-phys 192.168.0.2
6982 ovs-vsctl add-br br-phys
6983 ovn_attach n1 br-phys 192.168.0.4
6987 ovs-vsctl add-br br-phys
6988 ovn_attach n1 br-phys 192.168.0.3
6989 ovs-vsctl -- add-port br-int ext1-vif1 -- \
6990 set interface ext1-vif1 external-ids:iface-id=outside1 \
6991 options:tx_pcap=ext1/vif1-tx.pcap \
6992 options:rxq_pcap=ext1/vif1-rx.pcap \
6995 # Pre-populate the hypervisors' ARP tables so that we don't lose any
6996 # packets for ARP resolution (native tunneling doesn't queue packets
6997 # for ARP resolution).
7000 ovn-nbctl create Logical_Router name=R1
7002 ovn-nbctl ls-add foo
7003 ovn-nbctl ls-add alice
7004 ovn-nbctl ls-add outside
7007 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7008 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7009 type=router options:router-port=foo \
7010 -- lsp-set-addresses rp-foo router
7012 # Connect alice to R1 as distributed router gateway port on gw1
7013 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7016 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7019 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7022 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7024 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7025 type=router options:router-port=alice \
7026 -- lsp-set-addresses rp-alice router
7028 # Create logical port foo1 in foo
7029 ovn-nbctl lsp-add foo foo1 \
7030 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7032 # Create logical port outside1 in outside
7033 ovn-nbctl lsp-add outside outside1 \
7034 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7036 # Create localnet port in alice
7037 ovn-nbctl lsp-add alice ln-alice
7038 ovn-nbctl lsp-set-addresses ln-alice unknown
7039 ovn-nbctl lsp-set-type ln-alice localnet
7040 ovn-nbctl lsp-set-options ln-alice network_name=phys
7042 # Create localnet port in outside
7043 ovn-nbctl lsp-add outside ln-outside
7044 ovn-nbctl lsp-set-addresses ln-outside unknown
7045 ovn-nbctl lsp-set-type ln-outside localnet
7046 ovn-nbctl lsp-set-options ln-outside network_name=phys
7048 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7049 # mapping to the external network, is the one generating packets
7050 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7051 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7052 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7054 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7056 # Allow some time for ovn-northd and ovn-controller to catch up.
7057 # XXX This should be more systematic.
7061 printf "%02x%02x%02x%02x" "$@"
7067 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7068 options:rxq_pcap=dummy-rx.pcap
7069 rm -f ${pcap_file}*.pcap
7070 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7071 options:rxq_pcap=${pcap_file}-rx.pcap
7079 # Send ip packet between foo1 and outside1
7080 src_mac="f00000010203" # foo1 mac
7081 dst_mac="000001010203" # rp-foo mac (internal router leg)
7082 src_ip=`ip_to_hex 192 168 1 2`
7083 dst_ip=`ip_to_hex 172 16 1 3`
7084 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7086 # ARP request packet to expect at outside1
7087 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7089 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7091 # Send ARP reply from outside1 back to the router
7092 # XXX: note, we could avoid this if we plug this port into a netns
7093 # and setup the IP address into the port, so the kernel would simply reply
7094 src_mac="000002010203"
7095 reply_mac="f00000010204"
7096 dst_ip=`ip_to_hex 172 16 1 3`
7097 src_ip=`ip_to_hex 172 16 1 1`
7098 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7100 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7102 # Packet to Expect at ext1 chassis, outside1 port
7103 src_mac="000002010203"
7104 dst_mac="f00000010204"
7105 src_ip=`ip_to_hex 192 168 1 2`
7106 dst_ip=`ip_to_hex 172 16 1 3`
7107 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7108 echo $expected > ext1-vif1.expected
7110 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7111 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7112 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7114 # Resend packet from foo1 to outside1
7115 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7119 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7120 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7121 AT_CHECK([grep $expected packets | sort], [0], [expout])
7122 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7123 AT_CHECK([grep $expected packets | sort], [0], [])
7126 test_ip_packet gw1 gw2
7128 ovn-nbctl --timeout=3 --wait=hv \
7129 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7132 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7135 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7137 test_ip_packet gw2 gw1
7139 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7142 AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7143 AT_SKIP_IF([test $HAVE_PYTHON = no])
7150 ovs-vsctl add-br br-phys
7151 ovn_attach n1 br-phys 192.168.0.1
7152 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7153 set interface hv1-vif1 external-ids:iface-id=foo1 \
7154 options:tx_pcap=hv1/vif1-tx.pcap \
7155 options:rxq_pcap=hv1/vif1-rx.pcap \
7160 ovs-vsctl add-br br-phys
7161 ovn_attach n1 br-phys 192.168.0.2
7165 ovs-vsctl add-br br-phys
7166 ovn_attach n1 br-phys 192.168.0.4
7170 ovs-vsctl add-br br-phys
7171 ovn_attach n1 br-phys 192.168.0.3
7172 ovs-vsctl -- add-port br-int ext1-vif1 -- \
7173 set interface ext1-vif1 external-ids:iface-id=outside1 \
7174 options:tx_pcap=ext1/vif1-tx.pcap \
7175 options:rxq_pcap=ext1/vif1-rx.pcap \
7178 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7179 # packets for ARP resolution (native tunneling doesn't queue packets
7180 # for ARP resolution).
7183 ovn-nbctl create Logical_Router name=R0
7184 ovn-nbctl create Logical_Router name=R1
7186 ovn-nbctl ls-add foo
7187 ovn-nbctl ls-add join
7188 ovn-nbctl ls-add alice
7189 ovn-nbctl ls-add outside
7192 ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7193 ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7194 type=router options:router-port=R0-foo \
7195 -- lsp-set-addresses foo-R0 router
7198 ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7199 ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7200 type=router options:router-port=R0-join \
7201 -- lsp-set-addresses join-R0 router
7204 ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7205 ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7206 type=router options:router-port=R1-join \
7207 -- lsp-set-addresses join-R1 router
7210 ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7211 ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7213 # Connect alice to R1 as distributed router gateway port on gw1
7214 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7217 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7220 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7223 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7225 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7226 type=router options:router-port=alice \
7227 -- lsp-set-addresses rp-alice router
7229 # Create logical port foo1 in foo
7230 ovn-nbctl lsp-add foo foo1 \
7231 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7233 # Create logical port outside1 in outside
7234 ovn-nbctl lsp-add outside outside1 \
7235 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7237 # Create localnet port in alice
7238 ovn-nbctl lsp-add alice ln-alice
7239 ovn-nbctl lsp-set-addresses ln-alice unknown
7240 ovn-nbctl lsp-set-type ln-alice localnet
7241 ovn-nbctl lsp-set-options ln-alice network_name=phys
7243 # Create localnet port in outside
7244 ovn-nbctl lsp-add outside ln-outside
7245 ovn-nbctl lsp-set-addresses ln-outside unknown
7246 ovn-nbctl lsp-set-type ln-outside localnet
7247 ovn-nbctl lsp-set-options ln-outside network_name=phys
7249 # Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7250 # mapping to the external network, is the one generating packets
7251 as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7252 as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7253 as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7255 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7257 # Allow some time for ovn-northd and ovn-controller to catch up.
7258 # XXX This should be more systematic.
7262 printf "%02x%02x%02x%02x" "$@"
7268 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7269 options:rxq_pcap=dummy-rx.pcap
7270 rm -f ${pcap_file}*.pcap
7271 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7272 options:rxq_pcap=${pcap_file}-rx.pcap
7280 # Send ip packet between foo1 and outside1
7281 src_mac="f00000010203" # foo1 mac
7282 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7283 src_ip=`ip_to_hex 192 168 1 2`
7284 dst_ip=`ip_to_hex 172 16 1 3`
7285 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7287 # ARP request packet to expect at outside1
7288 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7290 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7292 # Send ARP reply from outside1 back to the router
7293 # XXX: note, we could avoid this if we plug this port into a netns
7294 # and setup the IP address into the port, so the kernel would simply reply
7295 src_mac="000002010203"
7296 reply_mac="f00000010204"
7297 dst_ip=`ip_to_hex 172 16 1 3`
7298 src_ip=`ip_to_hex 172 16 1 1`
7299 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7301 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7303 # Packet to Expect at ext1 chassis, outside1 port
7304 src_mac="000002010203"
7305 dst_mac="f00000010204"
7306 src_ip=`ip_to_hex 192 168 1 2`
7307 dst_ip=`ip_to_hex 172 16 1 3`
7308 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7309 echo $expected > ext1-vif1.expected
7311 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7312 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7313 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7315 # Resend packet from foo1 to outside1
7316 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7320 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7321 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7322 AT_CHECK([grep $expected packets | sort], [0], [expout])
7323 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7324 AT_CHECK([grep $expected packets | sort], [0], [])
7327 test_ip_packet gw1 gw2
7329 ovn-nbctl --timeout=3 --wait=hv \
7330 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7333 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7336 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7338 test_ip_packet gw2 gw1
7340 OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7343 AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7344 AT_SKIP_IF([test $HAVE_PYTHON = no])
7348 # One LR R1 that has switches foo (192.168.1.0/24) and
7349 # alice (172.16.1.0/24) connected to it. The logical port
7350 # between R1 and alice has a "redirect-chassis" specified,
7351 # i.e. it is the distributed router gateway port.
7352 # Switch alice also has a localnet port defined.
7353 # An additional switch outside has a localnet port and the
7354 # same subnet as alice (172.16.1.0/24).
7357 # Three hypervisors hv[123].
7358 # hv1 hosts vif foo1.
7359 # hv2 is the "redirect-chassis" that hosts the distributed
7360 # router gateway port.
7361 # hv3 hosts vif outside1.
7362 # In order to show that connectivity works only through hv2,
7363 # an initial round of tests is run without any bridge-mapping
7364 # defined for the localnet on hv2. These tests are expected
7366 # Subsequent tests are run after defining the bridge-mapping
7367 # for the localnet on hv2. These tests are expected to succeed.
7369 # Create three hypervisors and create OVS ports corresponding
7375 ovs-vsctl add-br br-phys
7376 ovn_attach n1 br-phys 192.168.0.1
7377 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7378 set interface hv1-vif1 external-ids:iface-id=foo1 \
7379 options:tx_pcap=hv1/vif1-tx.pcap \
7380 options:rxq_pcap=hv1/vif1-rx.pcap \
7385 ovs-vsctl add-br br-phys
7386 ovn_attach n1 br-phys 192.168.0.2
7390 ovs-vsctl add-br br-phys
7391 ovn_attach n1 br-phys 192.168.0.3
7392 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7393 set interface hv3-vif1 external-ids:iface-id=outside1 \
7394 options:tx_pcap=hv3/vif1-tx.pcap \
7395 options:rxq_pcap=hv3/vif1-rx.pcap \
7398 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7399 # packets for ARP resolution (native tunneling doesn't queue packets
7400 # for ARP resolution).
7403 ovn-nbctl create Logical_Router name=R1
7405 ovn-nbctl ls-add foo
7406 ovn-nbctl ls-add alice
7407 ovn-nbctl ls-add outside
7410 ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7411 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7412 type=router options:router-port=foo \
7413 -- lsp-set-addresses rp-foo router
7415 # Connect alice to R1 as distributed router gateway port on hv2
7416 ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7417 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7418 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7419 type=router options:router-port=alice \
7420 -- lsp-set-addresses rp-alice router
7422 # Create logical port foo1 in foo
7423 ovn-nbctl lsp-add foo foo1 \
7424 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7426 # Create logical port outside1 in outside
7427 ovn-nbctl lsp-add outside outside1 \
7428 -- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7430 # Create localnet port in alice
7431 ovn-nbctl lsp-add alice ln-alice
7432 ovn-nbctl lsp-set-addresses ln-alice unknown
7433 ovn-nbctl lsp-set-type ln-alice localnet
7434 ovn-nbctl lsp-set-options ln-alice network_name=phys
7436 # Create localnet port in outside
7437 ovn-nbctl lsp-add outside ln-outside
7438 ovn-nbctl lsp-set-addresses ln-outside unknown
7439 ovn-nbctl lsp-set-type ln-outside localnet
7440 ovn-nbctl lsp-set-options ln-outside network_name=phys
7442 # Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7443 as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7444 as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7447 # Allow some time for ovn-northd and ovn-controller to catch up.
7448 # XXX This should be more systematic.
7451 echo "---------NB dump-----"
7453 echo "---------------------"
7454 ovn-nbctl list logical_router
7455 echo "---------------------"
7456 ovn-nbctl list logical_router_port
7457 echo "---------------------"
7459 echo "---------SB dump-----"
7460 ovn-sbctl list datapath_binding
7461 echo "---------------------"
7462 ovn-sbctl list port_binding
7463 echo "---------------------"
7464 ovn-sbctl dump-flows
7465 echo "---------------------"
7466 ovn-sbctl list chassis
7467 ovn-sbctl list encap
7468 echo "------ Gateway_Chassis dump (SBDB) -------"
7469 ovn-sbctl list Gateway_Chassis
7470 echo "------ Port_Binding chassisredirect -------"
7471 ovn-sbctl find Port_Binding type=chassisredirect
7472 echo "-------------------------------------------"
7474 echo "------ hv1 dump ----------"
7475 as hv1 ovs-ofctl show br-int
7476 as hv1 ovs-ofctl dump-flows br-int
7477 echo "------ hv2 dump ----------"
7478 as hv2 ovs-ofctl show br-int
7479 as hv2 ovs-ofctl dump-flows br-int
7480 echo "------ hv3 dump ----------"
7481 as hv3 ovs-ofctl show br-int
7482 as hv3 ovs-ofctl dump-flows br-int
7483 echo "--------------------------"
7486 # Check that redirect mapping is programmed only on hv2
7487 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7489 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7491 # Check that hv1 sends chassisredirect port traffic to hv2
7492 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7494 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7496 # Check that arp reply on distributed gateway port is only programmed on hv2
7497 AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7499 AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7504 printf "%02x%02x%02x%02x" "$@"
7508 : > hv2-vif1.expected
7509 : > hv3-vif1.expected
7511 # test_arp INPORT SHA SPA TPA [REPLY_HA]
7513 # Causes a packet to be received on INPORT. The packet is an ARP
7514 # request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7515 # it should be the hardware address of the target to expect to receive in an
7516 # ARP reply; otherwise no reply is expected.
7518 # INPORT is an logical switch port number, e.g. 11 for vif11.
7519 # SHA and REPLY_HA are each 12 hex digits.
7520 # SPA and TPA are each 8 hex digits.
7522 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7523 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7524 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7526 if test X$reply_ha != X; then
7527 # Expect to receive the reply, if any.
7528 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7529 echo $reply >> hv${hv}-vif$inport.expected
7533 rtr_ip=$(ip_to_hex 172 16 1 1)
7534 foo_ip=$(ip_to_hex 192 168 1 2)
7535 outside_ip=$(ip_to_hex 172 16 1 3)
7541 # ARP for router IP address from outside1, no response expected
7542 test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7544 # Now check the packets actually received against the ones expected.
7545 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7547 # Send ip packet between foo1 and outside1
7548 src_mac="f00000010203"
7549 dst_mac="000001010203"
7550 src_ip=`ip_to_hex 192 168 1 2`
7551 dst_ip=`ip_to_hex 172 16 1 3`
7552 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7554 # Now check the packets actually received against the ones expected.
7555 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7557 # Now add bridge-mappings on hv2, which should make everything work
7558 as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7560 # Allow some time for ovn-northd and ovn-controller to catch up.
7561 # XXX This should be more systematic.
7564 # ARP for router IP address from outside1
7565 test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
7567 # Now check the packets actually received against the ones expected.
7568 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7570 # Send ip packet between foo1 and outside1
7571 src_mac="f00000010203"
7572 dst_mac="000001010203"
7573 src_ip=`ip_to_hex 192 168 1 2`
7574 dst_ip=`ip_to_hex 172 16 1 3`
7575 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7577 # ARP request packet to expect at outside1
7578 src_mac="000002010203"
7579 src_ip=`ip_to_hex 172 16 1 1`
7580 arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7582 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7584 echo $arp_request >> hv3-vif1.expected
7585 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7587 # Send ARP reply from outside1 back to the router
7588 reply_mac="f00000010204"
7589 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7591 as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
7593 # Allow some time for ovn-northd and ovn-controller to catch up.
7594 # XXX This should be more systematic.
7597 # Packet to Expect at outside1
7598 src_mac="000002010203"
7599 dst_mac="f00000010204"
7600 src_ip=`ip_to_hex 192 168 1 2`
7601 dst_ip=`ip_to_hex 172 16 1 3`
7602 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7604 # Resend packet from foo1 to outside1
7605 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7607 echo "------ hv1 dump ----------"
7608 as hv1 ovs-ofctl show br-int
7609 as hv1 ovs-ofctl dump-flows br-int
7610 echo "------ hv2 dump ----------"
7611 as hv2 ovs-ofctl show br-int
7612 as hv2 ovs-ofctl dump-flows br-int
7613 echo "------ hv3 dump ----------"
7614 as hv3 ovs-ofctl show br-int
7615 as hv3 ovs-ofctl dump-flows br-int
7616 echo "----------------------------"
7618 echo $expected >> hv3-vif1.expected
7619 OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7621 #Check ovn-trace over "chassisredirect" port
7622 AT_CAPTURE_FILE([trace])
7624 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
7627 echo 'ip.ttl--;' > expout
7628 echo 'eth.src = 00:00:02:01:02:03;' >> expout
7629 echo 'eth.dst = f0:00:00:01:02:04;' >> expout
7630 echo 'output("ln-alice");' >> expout
7631 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])
7633 # Create logical port alice1 in alice on hv1
7634 as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
7635 set interface hv1-vif2 external-ids:iface-id=alice1 \
7636 options:tx_pcap=hv1/vif2-tx.pcap \
7637 options:rxq_pcap=hv1/vif2-rx.pcap \
7640 ovn-nbctl lsp-add alice alice1 \
7641 -- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
7643 # Create logical port foo2 in foo on hv2
7644 as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7645 set interface hv2-vif1 external-ids:iface-id=foo2 \
7646 options:tx_pcap=hv2/vif1-tx.pcap \
7647 options:rxq_pcap=hv2/vif1-rx.pcap \
7650 ovn-nbctl lsp-add foo foo2 \
7651 -- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
7653 # Allow some time for ovn-northd and ovn-controller to catch up.
7654 # XXX This should be more systematic.
7657 : > hv1-vif2.expected
7659 # Send ip packet between alice1 and foo2
7660 src_mac="f00000010205"
7661 dst_mac="000002010203"
7662 src_ip=`ip_to_hex 172 16 1 4`
7663 dst_ip=`ip_to_hex 192 168 1 3`
7664 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7666 as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7668 # Packet to Expect at foo2
7669 src_mac="000001010203"
7670 dst_mac="f00000010206"
7671 src_ip=`ip_to_hex 172 16 1 4`
7672 dst_ip=`ip_to_hex 192 168 1 3`
7673 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7675 echo $expected >> hv2-vif1.expected
7676 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
7678 AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
7681 ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
7683 AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
7686 OVN_CLEANUP([hv1],[hv2],[hv3])
7690 AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
7691 AT_SKIP_IF([test $HAVE_PYTHON = no])
7693 # Create logical switches
7694 ovn-nbctl ls-add ls0
7695 ovn-nbctl ls-add ls1
7696 # Create distributed router
7697 ovn-nbctl create Logical_Router name=lr0
7698 # Add distributed gateway port to distributed router
7699 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
7700 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
7701 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
7702 type=router options:router-port=lrp0 addresses="router"
7703 # Add router port to ls1
7704 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
7705 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
7706 type=router options:router-port=lrp1 addresses="router"
7707 # Add logical ports for NAT rules
7708 ovn-nbctl lsp-add ls1 foo1 \
7709 -- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
7710 ovn-nbctl lsp-add ls1 foo2 \
7711 -- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
7712 # Add nat-addresses option
7713 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7715 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
7716 AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
7717 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])
7718 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])
7723 ovs-vsctl add-br br-phys
7724 ovn_attach n1 br-phys 192.168.0.1
7726 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7727 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])
7731 ovs-vsctl add-br br-phys
7732 ovn_attach n1 br-phys 192.168.0.2
7733 # Initially test with no bridge-mapping on hv2, expect to receive no packets
7737 ovs-vsctl add-br br-phys
7738 ovn_attach n1 br-phys 192.168.0.3
7739 # Initially test with no bridge-mapping on hv3
7741 # Create a localnet port.
7742 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
7743 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
7744 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
7745 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
7747 # Allow some time for ovn-northd and ovn-controller to catch up.
7748 # XXX This should be more systematic.
7751 # Expect no packets when hv2 bridge-mapping is not present
7753 OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
7755 # Add bridge-mapping on hv2
7756 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7758 # Wait for packets to be received.
7759 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
7761 sed 's/\(00\)\{1,\}$//'
7763 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7764 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
7765 echo $expected > expout
7766 expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
7767 echo $expected >> expout
7768 AT_CHECK([sort packets], [0], [expout])
7771 # Temporarily remove nat-addresses option to avoid race conditions
7772 # due to GARP backoff
7773 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
7778 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7779 options:rxq_pcap=dummy-rx.pcap
7780 rm -f ${pcap_file}*.pcap
7781 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7782 options:rxq_pcap=${pcap_file}-rx.pcap
7785 as hv1 reset_pcap_file snoopvif hv1/snoopvif
7787 # Add OVS ports for foo1 and foo2 on hv3
7788 ovs-vsctl -- add-port br-int hv3-vif1 -- \
7789 set interface hv3-vif1 external-ids:iface-id=foo1 \
7791 ovs-vsctl -- add-port br-int hv3-vif2 -- \
7792 set interface hv3-vif2 external-ids:iface-id=foo2 \
7795 # Add bridge-mapping on hv3
7796 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
7798 # Re-add nat-addresses option
7799 ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
7801 # Wait for packets to be received.
7802 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
7804 sed 's/\(00\)\{1,\}$//'
7807 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
7808 expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
7809 echo $expected >> expout
7810 expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
7811 echo $expected >> expout
7812 AT_CHECK([sort packets], [0], [expout])
7815 OVN_CLEANUP([hv1],[hv2],[hv3])
7819 AT_SETUP([ovn -- /32 router IP address])
7820 AT_SKIP_IF([test $HAVE_PYTHON = no])
7824 # 2 LS 'foo' and 'alice' connected via router R1.
7825 # R1 connects to 'alice' with a /32 IP address. We use static routes and
7826 # nexthop to push traffic to a logical port in switch 'alice'
7830 ovn-nbctl ls-add foo
7831 ovn-nbctl ls-add alice
7834 ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
7835 ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7836 options:router-port=foo addresses=\"00:00:00:01:02:03\"
7838 # Connect alice to R1.
7839 ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
7840 ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7841 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
7843 # Create logical port foo1 in foo
7844 ovn-nbctl lsp-add foo foo1 \
7845 -- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7847 # Create logical port alice1 in alice
7848 ovn-nbctl lsp-add alice alice1 \
7849 -- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
7851 #install default route in R1 to use alice1's IP address as nexthop
7852 ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
7854 # Create two hypervisor and create OVS ports corresponding to logical ports.
7859 ovs-vsctl add-br br-phys
7860 ovn_attach n1 br-phys 192.168.0.1
7861 ovs-vsctl -- add-port br-int hv1-vif1 -- \
7862 set interface hv1-vif1 external-ids:iface-id=foo1 \
7863 options:tx_pcap=hv1/vif1-tx.pcap \
7864 options:rxq_pcap=hv1/vif1-rx.pcap \
7869 ovs-vsctl add-br br-phys
7870 ovn_attach n1 br-phys 192.168.0.2
7871 ovs-vsctl -- add-port br-int hv2-vif1 -- \
7872 set interface hv2-vif1 external-ids:iface-id=alice1 \
7873 options:tx_pcap=hv2/vif1-tx.pcap \
7874 options:rxq_pcap=hv2/vif1-rx.pcap \
7878 # Pre-populate the hypervisors' ARP tables so that we don't lose any
7879 # packets for ARP resolution (native tunneling doesn't queue packets
7880 # for ARP resolution).
7883 # Allow some time for ovn-northd and ovn-controller to catch up.
7884 # XXX This should be more systematic.
7888 printf "%02x%02x%02x%02x" "$@"
7891 # Send ip packets between foo1 and alice1
7892 src_mac="f00000010203"
7893 dst_mac="000000010203"
7894 src_ip=`ip_to_hex 192 168 1 2`
7895 dst_ip=`ip_to_hex 10 0 0 2`
7896 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7898 # Send the first packet to trigger a ARP response and population of
7899 # mac_bindings table.
7900 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7901 OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
7903 # Send the second packet to reach the destination.
7904 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7906 # Packet to Expect at 'alice1'
7907 src_mac="000000010204"
7908 dst_mac="f00000010204"
7909 src_ip=`ip_to_hex 192 168 1 2`
7910 dst_ip=`ip_to_hex 10 0 0 2`
7911 echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
7913 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7915 OVN_CLEANUP([hv1],[hv2])
7919 AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
7920 AT_SKIP_IF([test $HAVE_PYTHON = no])
7923 ovn-nbctl ls-add ls1
7925 # Add localport to the switch
7926 ovn-nbctl lsp-add ls1 lp01
7927 ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
7928 ovn-nbctl lsp-set-type lp01 localport
7935 ovs-vsctl add-br br-phys
7936 ovn_attach n1 br-phys 192.168.0.$i
7937 ovs-vsctl add-port br-int vif01 -- \
7938 set Interface vif01 external-ids:iface-id=lp01 \
7939 options:tx_pcap=hv${i}/vif01-tx.pcap \
7940 options:rxq_pcap=hv${i}/vif01-rx.pcap \
7941 ofport-request=${i}0
7943 ovs-vsctl add-port br-int vif${i}1 -- \
7944 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
7945 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
7946 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
7947 ofport-request=${i}1
7949 ovn-nbctl lsp-add ls1 lp${i}1
7950 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
7951 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
7953 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
7956 ovn-nbctl --wait=sb sync
7957 ovn-sbctl dump-flows
7961 # Given the name of a logical port, prints the name of the hypervisor
7962 # on which it is located.
7967 # test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
7969 # This shell function causes a packet to be received on INPORT. The packet's
7970 # content has Ethernet destination DST and source SRC (each exactly 12 hex
7971 # digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
7972 # logical switch port numbers, e.g. 11 for vif11.
7974 # EOUT is the end-to-end output port, that is, where the packet will end up
7975 # after possibly bouncing through one or more localnet ports. LOUT is the
7976 # logical output port, which might be a localnet port, as seen by ovn-trace
7977 # (which doesn't know what localnet ports are connected to and therefore can't
7978 # figure out the end-to-end answer).
7980 # DEFHV is the default hypervisor from where the packet is going to be sent
7981 # if the source port is a localport.
7988 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
7991 # First try tracing the packet.
7992 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
7993 if test $lout != drop; then
7994 echo "output(\"$lout\");"
7996 AT_CAPTURE_FILE([trace])
7997 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
7999 # Then actually send a packet, for an end-to-end test.
8000 local packet=$(echo $dst$src | sed 's/://g')${eth}
8001 hv=`vif_to_hv $inport`
8002 # If hypervisor 0 (localport) use the defhv parameter
8003 if test $hv = hv0; then
8007 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8008 if test $eout != drop; then
8009 echo $packet >> ${eout#lp}.expected
8014 # lp11 and lp21 are on different hypervisors
8015 test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8016 test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8018 # Both VIFs should be able to reach the localport on their own HV
8019 test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8020 test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8022 # Packet sent from localport on same hv should reach the vif
8023 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8024 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8026 # Packet sent from localport on different hv should be dropped
8027 test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8028 test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8030 # Now check the packets actually received against the ones expected.
8033 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8037 OVN_CLEANUP([hv1],[hv2])
8041 AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8042 AT_SKIP_IF([test $HAVE_PYTHON = no])
8047 # create gateways with external network connectivity
8052 ovs-vsctl add-br br-phys
8053 ovn_attach n1 br-phys 192.168.0.$i
8054 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8057 ovn-nbctl ls-add inside
8058 ovn-nbctl ls-add outside
8060 # create hypervisors with a vif port each to an internal network
8065 ovs-vsctl add-br br-phys
8066 ovn_attach n1 br-phys 192.168.0.1$i
8067 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8068 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8069 options:tx_pcap=hv$i/vif1-tx.pcap \
8070 options:rxq_pcap=hv$i/vif1-rx.pcap \
8073 ovn-nbctl lsp-add inside inside$i \
8074 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8080 ovn-nbctl create Logical_Router name=R1
8082 # Connect inside to R1
8083 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8084 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8085 type=router options:router-port=inside \
8086 -- lsp-set-addresses rp-inside router
8088 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8089 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8091 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8092 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8093 --id=@gc1 create Gateway_Chassis \
8094 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8095 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8097 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8098 type=router options:router-port=outside \
8099 -- lsp-set-addresses rp-outside router
8101 # Create localnet port in outside
8102 ovn-nbctl lsp-add outside ln-outside
8103 ovn-nbctl lsp-set-addresses ln-outside unknown
8104 ovn-nbctl lsp-set-type ln-outside localnet
8105 ovn-nbctl lsp-set-options ln-outside network_name=phys
8107 # Allow some time for ovn-northd and ovn-controller to catch up.
8108 # XXX This should be more systematic.
8109 ovn-nbctl --wait=hv --timeout=3 sync
8111 echo "---------NB dump-----"
8113 echo "---------------------"
8114 ovn-nbctl list logical_router
8115 echo "---------------------"
8116 ovn-nbctl list logical_router_port
8117 echo "---------------------"
8119 echo "---------SB dump-----"
8120 ovn-sbctl list datapath_binding
8121 echo "---------------------"
8122 ovn-sbctl list port_binding
8123 echo "---------------------"
8124 ovn-sbctl dump-flows
8125 echo "---------------------"
8126 ovn-sbctl list chassis
8127 ovn-sbctl list encap
8128 echo "---------------------"
8129 echo "------ Gateway_Chassis dump (SBDB) -------"
8130 ovn-sbctl list Gateway_Chassis
8131 echo "------ Port_Binding chassisredirect -------"
8132 ovn-sbctl find Port_Binding type=chassisredirect
8133 echo "-------------------------------------------"
8135 for chassis in gw1 gw2 hv1 hv2; do
8137 echo "------ $chassis dump ----------"
8138 ovs-ofctl show br-int
8139 ovs-ofctl dump-flows br-int
8140 echo "--------------------------"
8142 function bfd_dump() {
8143 for chassis in gw1 gw2 hv1 hv2; do
8145 echo "------ $chassis dump (BFD)----"
8146 echo "BFD (from $chassis):"
8147 # dump BFD config and status to the other chassis
8148 for chassis2 in gw1 gw2 hv1 hv2; do
8149 if [[ "$chassis" != "$chassis2" ]]; then
8150 echo " -> $chassis2:"
8151 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8154 echo "--------------------------"
8160 hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8161 hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8162 hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8163 hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8165 echo $hv1_gw1_ofport
8166 echo $hv1_gw2_ofport
8167 echo $hv2_gw1_ofport
8168 echo $hv2_gw2_ofport
8171 as hv1 ovs-ofctl dump-flows br-int table=32
8174 as hv2 ovs-ofctl dump-flows br-int table=32
8176 gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8177 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8179 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
8182 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
8185 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8187 # make sure that flows for handling the outside router port reside on gw1
8188 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8190 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8193 # make sure ARP responder flows for outside router port reside on gw1 too
8194 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8196 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8201 # check that the chassis redirect port has been claimed by the gw1 chassis
8202 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8207 # at this point, we invert the priority of the gw chassis between gw1 and gw2
8209 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8210 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8211 --id=@gc1 create Gateway_Chassis \
8212 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8213 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8216 # XXX: Let the change propagate down to the ovn-controllers
8217 ovn-nbctl --wait=hv --timeout=3 sync
8219 # we make sure that the hypervisors noticed, and inverted the slave ports
8220 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
8223 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
8226 # check that the chassis redirect port has been reclaimed by the gw2 chassis
8227 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8231 # check BFD enablement on tunnel ports from gw1 #########
8233 for chassis in gw2 hv1 hv2; do
8234 echo "checking gw1 -> $chassis"
8235 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8241 # check BFD enablement on tunnel ports from gw2 ##########
8243 for chassis in gw1 hv1 hv2; do
8244 echo "checking gw2 -> $chassis"
8245 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8250 # check BFD enablement on tunnel ports from hv1 ###########
8252 for chassis in gw1 gw2; do
8253 echo "checking hv1 -> $chassis"
8254 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8258 # make sure BFD is not enabled to hv2, we don't need it
8259 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8264 # check BFD enablement on tunnel ports from hv2 ##########
8266 for chassis in gw1 gw2; do
8267 echo "checking hv2 -> $chassis"
8268 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8272 # make sure BFD is not enabled to hv1, we don't need it
8273 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8277 sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8279 # make sure that flows for handling the outside router port reside on gw2 now
8280 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8282 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8285 # disconnect GW2 from the network, GW1 should take over
8287 port=${sandbox}_br-phys
8288 as main ovs-vsctl del-port n1 $port
8293 # make sure that flows for handling the outside router port reside on gw2 now
8294 AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
8296 AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=23 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
8299 # check that the chassis redirect port has been reclaimed by the gw1 chassis
8300 AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8304 OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
8308 AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
8309 AT_SKIP_IF([test $HAVE_PYTHON = no])
8311 ovn-nbctl ls-add ls0
8312 ovn-nbctl ls-add ls1
8313 ovn-nbctl create Logical_Router name=lr0
8314 ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
8316 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8317 name=outside_gw1 chassis_name=hv2 priority=10 -- \
8318 --id=@gc1 create Gateway_Chassis \
8319 name=outside_gw2 chassis_name=hv3 priority=1 -- \
8320 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8322 ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8323 type=router options:router-port=lrp0 addresses="router"
8324 ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8325 ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8326 type=router options:router-port=lrp1 addresses="router"
8329 AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
8334 ovs-vsctl add-br br-phys
8335 ovn_attach n1 br-phys 192.168.0.1
8336 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8337 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])
8341 ovs-vsctl add-br br-phys
8342 ovn_attach n1 br-phys 192.168.0.2
8343 AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8347 ovs-vsctl add-br br-phys
8348 ovn_attach n1 br-phys 192.168.0.3
8349 AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8351 # Create a localnet port.
8352 AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8353 AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8354 AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8355 AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8357 # wait for earlier changes to take effect
8358 AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
8363 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8364 options:rxq_pcap=dummy-rx.pcap
8365 rm -f ${pcap_file}*.pcap
8366 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8367 options:rxq_pcap=${pcap_file}-rx.pcap
8370 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8371 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8372 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8373 # add nat-addresses option
8374 ovn-nbctl --wait=sb lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8376 # Wait for packets to be received through hv2.
8377 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8379 sed 's/\(00\)\{1,\}$//'
8382 only_broadcast_from_lrp1() {
8383 grep "fffffffffffff00000000001"
8386 garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
8389 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
8390 echo "packets on hv1-snoopvif:"
8392 AT_CHECK([sort hv1_snoop_tx], [0], [expout])
8393 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8394 echo "packets on hv2 br-phys tx"
8396 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
8397 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8398 echo "packets on hv3 br-phys tx"
8400 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
8403 # at this point, we invert the priority of the gw chassis between hv2 and hv3
8405 ovn-nbctl --wait=hv \
8406 --id=@gc0 create Gateway_Chassis \
8407 name=outside_gw1 chassis_name=hv2 priority=1 -- \
8408 --id=@gc1 create Gateway_Chassis \
8409 name=outside_gw2 chassis_name=hv3 priority=10 -- \
8410 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
8413 as hv1 reset_pcap_file snoopvif hv1/snoopvif
8414 as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
8415 as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
8417 # Wait for packets to be received.
8418 OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8420 sed 's/\(00\)\{1,\}$//'
8423 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
8424 AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
8425 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
8426 AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
8427 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
8428 AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
8429 OVN_CLEANUP([hv1],[hv2],[hv3])
8433 AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
8434 AT_SKIP_IF([test $HAVE_PYTHON = no])
8439 # create two gateways with external network connectivity
8443 ovs-vsctl add-br br-phys
8444 ovn_attach n1 br-phys 192.168.0.$i
8445 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8448 ovn-nbctl ls-add inside
8449 ovn-nbctl ls-add outside
8451 # create one hypervisors with a vif port the internal network
8454 ovs-vsctl add-br br-phys
8455 ovn_attach n1 br-phys 192.168.0.11
8456 ovs-vsctl -- add-port br-int hv1-vif1 -- \
8457 set interface hv1-vif1 external-ids:iface-id=inside1 \
8458 options:tx_pcap=hv1/vif1-tx.pcap \
8459 options:rxq_pcap=hv1/vif1-rx.pcap \
8462 ovn-nbctl lsp-add inside inside1 \
8463 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
8468 ovn-nbctl create Logical_Router name=R1
8470 # Connect inside to R1
8471 ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8472 ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8473 type=router options:router-port=inside \
8474 -- lsp-set-addresses rp-inside router
8476 # Connect outside to R1 as distributed router gateway port on gw1+gw2
8477 ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8479 ovn-nbctl --id=@gc0 create Gateway_Chassis \
8480 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8481 --id=@gc1 create Gateway_Chassis \
8482 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8483 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8485 ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8486 type=router options:router-port=outside \
8487 -- lsp-set-addresses rp-outside router
8489 # Create localnet port in outside
8490 ovn-nbctl lsp-add outside ln-outside
8491 ovn-nbctl lsp-set-addresses ln-outside unknown
8492 ovn-nbctl lsp-set-type ln-outside localnet
8493 ovn-nbctl lsp-set-options ln-outside network_name=phys
8495 # Allow some time for ovn-northd and ovn-controller to catch up.
8496 ovn-nbctl --wait=hv --timeout=3 sync
8498 # currently when ovn-controller is restarted, the old entry is deleted
8499 # and a new one is created, which leaves the Gateway_Chassis with
8500 # an empty chassis for a while. NOTE: restarting ovn-controller in tests
8501 # doesn't have the same effect because "name" is conserved, and the
8502 # Chassis entry is not replaced.
8504 > gw1/ovn-controller.log
8506 gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8507 ovn-sbctl destroy Chassis $gw2_chassis
8509 # Ensure ovn-controller has processed latest sbdb update
8510 # ovn-nbctl --wait=hv sync
8512 AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
8514 OVN_CLEANUP([gw1],[gw2],[hv1])
8518 AT_SETUP([ovn -- options:requested-chassis for logical port])
8523 ovn-nbctl ls-add ls0
8524 ovn-nbctl lsp-add ls0 lsp0
8526 # create two hypervisors, each with one vif port
8529 ovs-vsctl add-br br-phys
8530 ovn_attach n1 br-phys 192.168.0.11
8531 ovs-vsctl -- add-port br-int hv1-vif0
8535 ovs-vsctl add-br br-phys
8536 ovn_attach n1 br-phys 192.168.0.12
8537 ovs-vsctl -- add-port br-int hv2-vif0
8539 # Allow only chassis hv1 to bind logical port lsp0.
8540 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
8542 # Allow some time for ovn-northd and ovn-controller to catch up.
8543 ovn-nbctl --wait=hv --timeout=3 sync
8545 # Retrieve hv1 and hv2 chassis UUIDs from southbound database
8546 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
8547 hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
8549 # (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
8550 echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
8552 ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
8554 OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
8555 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
8557 # (2) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
8558 echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
8560 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
8562 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
8563 AT_CHECK([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv1_uuid"], [0], [])
8565 # (3) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
8566 # the requested chassis for lsp0 is changed from hv1 to hv2.
8567 echo "verifying that lsp0 binding moves when requested-chassis is changed"
8569 ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
8570 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
8571 OVS_WAIT_UNTIL([test $(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = "$hv2_uuid"])
8573 OVN_CLEANUP([hv1],[hv2])
8577 AT_SETUP([ovn -- options:requested-chassis with hostname])
8581 ovn-nbctl ls-add ls0
8582 ovn-nbctl lsp-add ls0 lsp0
8587 ovs-vsctl add-br br-phys
8588 ovn_attach n1 br-phys 192.168.0.11
8589 ovs-vsctl -- add-port br-int hv1-vif0
8591 hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
8592 echo "hv1_hostname=${hv1_hostname}"
8593 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
8594 as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
8596 hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
8597 echo "hv1_uuid=${hv1_uuid}"
8598 OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
8599 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
8601 ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
8602 OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
8603 ovn-nbctl --wait=hv --timeout=3 sync
8604 AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])