]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
ovn-controller: process lport bindings only when transaction is possible
[ovs.git] / tests / ovn.at
CommitLineData
f295c17b 1AT_BANNER([OVN components])
10b1662b
BP
2
3AT_SETUP([ovn -- lexer])
4dnl For lines without =>, input and expected output are identical.
5dnl For lines with =>, input precedes => and expected output follows =>.
6AT_DATA([test-cases.txt], [dnl
7foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
8"abc\u0020def" => "abc def"
9" => error("Input ends inside quoted string.")dnl "
10
2c5cbb15
RB
11$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
12$1 => error("`$' must be followed by a valid identifier.") 1
13
10b1662b
BP
14a/*b*/c => a c
15a//b c => a
16a/**/b => a b
17a/*/b => a error("`/*' without matching `*/'.")
18a/*/**/b => a b
19a/b => a error("`/' is only valid as part of `//' or `/*'.") b
20
210 1 12345 18446744073709551615
2218446744073709551616 => error("Decimal constants must be less than 2**64.")
239999999999999999999999 => error("Decimal constants must be less than 2**64.")
2401 => error("Decimal constants must not have leading zeros.")
25
260/0
270/1
281/0 => error("Value contains unmasked 1-bits.")
291/1
30128/384
311/3
321/ => error("Integer constant expected.")
33
341/0x123 => error("Value and mask have incompatible formats.")
35
360x1234
370x01234 => 0x1234
380x0 => 0
390x000 => 0
400xfedcba9876543210
410XFEDCBA9876543210 => 0xfedcba9876543210
420xfedcba9876543210fedcba9876543210
10b1662b
BP
430x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
440x => error("Hex digits expected following 0x.")
450X => error("Hex digits expected following 0X.")
460x0/0x0 => 0/0
470x0/0x1 => 0/0x1
480x1/0x0 => error("Value contains unmasked 1-bits.")
490xffff/0x1ffff
500x. => error("Invalid syntax in hexadecimal constant.")
51
52192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
53256.1.2.3 => error("Invalid numeric constant.")
54192.168.0.0/16
55192.168.0.0/255.255.0.0 => 192.168.0.0/16
56192.168.0.0/255.255.255.0 => 192.168.0.0/24
57192.168.0.0/255.255.0.255
58192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
59192.168.0.0/32
60192.168.0.0/255.255.255.255 => 192.168.0.0/32
61
62::
63::1
64ff00::1234 => ff00::1234
652001:db8:85a3::8a2e:370:7334
662001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
672001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
68::ffff:192.0.2.128
69::ffff:c000:0280 => ::ffff:192.0.2.128
70::1/::1
71::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
72::1/128
73ff00::/8
74ff00::/ff00:: => ff00::/8
75
7601:23:45:67:ab:cd
7701:23:45:67:AB:CD => 01:23:45:67:ab:cd
78fe:dc:ba:98:76:54
79FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
8001:00:00:00:00:00/01:00:00:00:00:00
81ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
82fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
83ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
84fe:x => error("Invalid numeric constant.")
8500:01:02:03:04:x => error("Invalid numeric constant.")
86
a20c96c6 87# Test that operators are tokenized as expected, even without white space.
56091efe 88(){}[[]]==!=<<=>>=!&&||..,;=<->-- => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> --
10b1662b
BP
89& => error("`&' is only valid as part of `&&'.")
90| => error("`|' is only valid as part of `||'.")
56091efe 91- => error("`-' is only valid as part of `--'.")
10b1662b
BP
92
93^ => error("Invalid character `^' in input.")
94])
95AT_CAPTURE_FILE([input.txt])
96sed 's/ =>.*//' test-cases.txt > input.txt
97sed 's/.* => //' test-cases.txt > expout
98AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
99AT_CLEANUP
e0840f11
BP
100
101AT_SETUP([ovn -- expression parser])
102dnl For lines without =>, input and expected output are identical.
103dnl For lines with =>, input precedes => and expected output follows =>.
104AT_DATA([test-cases.txt], [[
105eth.type == 0x800
106eth.type==0x800 => eth.type == 0x800
107eth.type[0..15] == 0x800 => eth.type == 0x800
108
109vlan.present
110vlan.present == 1 => vlan.present
111!(vlan.present == 0) => vlan.present
112!(vlan.present != 1) => vlan.present
113!vlan.present
114vlan.present == 0 => !vlan.present
115vlan.present != 1 => !vlan.present
116!(vlan.present == 1) => !vlan.present
117!(vlan.present != 0) => !vlan.present
118
119eth.dst[0]
120eth.dst[0] == 1 => eth.dst[0]
121eth.dst[0] != 0 => eth.dst[0]
122!(eth.dst[0] == 0) => eth.dst[0]
123!(eth.dst[0] != 1) => eth.dst[0]
124
125!eth.dst[0]
126eth.dst[0] == 0 => !eth.dst[0]
127eth.dst[0] != 1 => !eth.dst[0]
128!(eth.dst[0] == 1) => !eth.dst[0]
129!(eth.dst[0] != 0) => !eth.dst[0]
130
131vlan.tci[12..15] == 0x3
132vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
133vlan.tci[12..15] != 0x3
134vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
135
136!vlan.pcp => vlan.pcp == 0
137!(vlan.pcp) => vlan.pcp == 0
138vlan.pcp == 0x4
139vlan.pcp != 0x4
140vlan.pcp > 0x4
141vlan.pcp >= 0x4
142vlan.pcp < 0x4
143vlan.pcp <= 0x4
144!(vlan.pcp != 0x4) => vlan.pcp == 0x4
145!(vlan.pcp == 0x4) => vlan.pcp != 0x4
146!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
147!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
148!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
149!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
1500x4 == vlan.pcp => vlan.pcp == 0x4
1510x4 != vlan.pcp => vlan.pcp != 0x4
1520x4 < vlan.pcp => vlan.pcp > 0x4
1530x4 <= vlan.pcp => vlan.pcp >= 0x4
1540x4 > vlan.pcp => vlan.pcp < 0x4
1550x4 >= vlan.pcp => vlan.pcp <= 0x4
156!(0x4 != vlan.pcp) => vlan.pcp == 0x4
157!(0x4 == vlan.pcp) => vlan.pcp != 0x4
158!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
159!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
160!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
161!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
162
1631 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
1641 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
1651 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
1661 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
1671 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
1684 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
1694 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
1704 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
1714 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
172!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
173!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
174!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
175!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
176!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
177!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
178!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
179!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
180!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
181
182vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
183vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
184
185vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
186vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
187
188vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
189vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
190vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
191
192ip4.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
193ip6.src == ::1 => ip6.src == 0x1
194
195ip4.src == 1.2.3.4 => ip4.src == 0x1020304
196ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
197ip6.src == ::1 => ip6.src == 0x1
198
1991
2000
201!1 => 0
202!0 => 1
203
204inport == "eth0"
205!(inport != "eth0") => inport == "eth0"
206
3b7cb7e1
BP
207ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
208inport == 1 => String field inport is not compatible with integer constant.
e0840f11
BP
209
210ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
211eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
212vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
213
214inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
215!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
216eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
217!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
218
219123 == 123 => Syntax error at `123' expecting field name.
220
2c5cbb15
RB
221$name => Syntax error at `$name' expecting address set name.
222
e0840f11
BP
223123 == xyzzy => Syntax error at `xyzzy' expecting field name.
224xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
225
226inport[1] == 1 => Cannot select subfield of string field inport.
227
228eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
229eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
230eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
231
232eth.type[5!] => Syntax error at `!' expecting `@:>@'.
233
234eth.type[5..1] => Invalid bit range 5 to 1.
235
236eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
237
238eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
239
240eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
241
242!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
243
244123 => Syntax error at end of input expecting relational operator.
245
246123 x => Syntax error at `x' expecting relational operator.
247
248{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
249
250eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
251
252(1 x) => Syntax error at `x' expecting `)'.
253
254!0x800 != eth.type => Missing parentheses around operand of !.
255
256eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
257
258eth.dst == {} => Syntax error at `}' expecting constant.
259
260eth.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).
261
3b7cb7e1 262ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
263
2641 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda
JS
265
266eth.dst[40] x => Extra tokens at end of input.
e0840f11
BP
267]])
268sed 's/ =>.*//' test-cases.txt > input.txt
269sed 's/.* => //' test-cases.txt > expout
270AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
271AT_CLEANUP
272
273AT_SETUP([ovn -- expression annotation])
274dnl Input precedes =>, expected output follows =>.
275AT_DATA([test-cases.txt], [[
276ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
277ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
278ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
279ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
280ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
281
282ip => eth.type == 0x800 || eth.type == 0x86dd
283ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
284ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
285ip > 0 => Only == and != operators may be used with nominal field ip.
286!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
287ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
288
289vlan.present => vlan.tci[12]
290!vlan.present => !vlan.tci[12]
291
292!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
293vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
294!reg0 && !reg1 && !reg2 && !reg3 => xreg0[32..63] == 0 && xreg0[0..31] == 0 && xreg1[32..63] == 0 && xreg1[0..31] == 0
295
296ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
297!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
298ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
299
300bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
301self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
302mutual_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'.
303mutual_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'.
304]])
305sed 's/ =>.*//' test-cases.txt > input.txt
306sed 's/.* => //' test-cases.txt > expout
307AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
308AT_CLEANUP
309
9d4aecca 310AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 311AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 312 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
313])
314AT_CLEANUP
315
9d4aecca 316AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 317AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
9d4aecca 318 [Tested converting 570 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
319])
320AT_CLEANUP
321
9d4aecca 322AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 323AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
9d4aecca 324 [Tested converting 62418 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
325])
326AT_CLEANUP
327
9d4aecca
BP
328AT_SETUP([ovn -- 3-term numeric expression simplification])
329AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
330 [Tested simplifying 477138 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
331])
332AT_CLEANUP
333
9d4aecca
BP
334AT_SETUP([ovn -- 4-term string expression simplification])
335AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
336 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
337])
338AT_CLEANUP
339
9d4aecca
BP
340AT_SETUP([ovn -- 3-term mixed expression simplification])
341AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
342 [Tested simplifying 124410 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
343])
344AT_CLEANUP
345
9d4aecca
BP
346AT_SETUP([ovn -- 4-term numeric expression normalization])
347AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
348 [Tested normalizing 1207162 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
349])
350AT_CLEANUP
351
9d4aecca
BP
352AT_SETUP([ovn -- 4-term string expression normalization])
353AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
354 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
355])
356AT_CLEANUP
357
358AT_SETUP([ovn -- 4-term mixed expression normalization])
359AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
360 [Tested normalizing 128282 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
361])
362AT_CLEANUP
363
364AT_SETUP([ovn -- 5-term numeric expression normalization])
365AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
366 [Tested normalizing 368550 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
367])
368AT_CLEANUP
369
370AT_SETUP([ovn -- 5-term string expression normalization])
371AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
372 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
373])
374AT_CLEANUP
375
376AT_SETUP([ovn -- 5-term mixed expression normalization])
377AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
378 [Tested normalizing 116550 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
379])
380AT_CLEANUP
381
382AT_SETUP([ovn -- 4-term numeric expressions to flows])
383AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
384 [Tested converting to flows 128282 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
385])
386AT_CLEANUP
387
388AT_SETUP([ovn -- 4-term string expressions to flows])
389AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
390 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
391])
392AT_CLEANUP
393
394AT_SETUP([ovn -- 4-term mixed expressions to flows])
395AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
396 [Tested converting to flows 37994 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
397])
398AT_CLEANUP
399
400AT_SETUP([ovn -- 3-term numeric expressions to flows])
401AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
402 [Tested converting to flows 38394 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
403])
404AT_CLEANUP
f386a8a7
BP
405
406AT_SETUP([ovn -- converting expressions to flows -- string fields])
407expr_to_flow () {
408 echo "$1" | ovstest test-ovn expr-to-flows | sort
409}
3b7cb7e1 410AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg6=0x5
f386a8a7 411])
3b7cb7e1 412AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg6=0x6
f386a8a7
BP
413])
414AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
415])
416AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
3b7cb7e1
BP
417ip,reg6=0x5
418ipv6,reg6=0x5
f386a8a7
BP
419])
420AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
3b7cb7e1
BP
421ip,reg6=0x6
422ipv6,reg6=0x6
f386a8a7
BP
423])
424AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
425])
426AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
3b7cb7e1
BP
427[reg6=0x5
428reg6=0x6
429reg6=0xfffe
f386a8a7
BP
430])
431AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
3b7cb7e1
BP
432ip,reg6=0x5
433ip,reg6=0x6
434ipv6,reg6=0x5
435ipv6,reg6=0x6
f386a8a7 436])
9d4aecca
BP
437AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
438(no flows)
439])
f386a8a7 440AT_CLEANUP
3b7cb7e1 441
2c5cbb15
RB
442AT_SETUP([ovn -- converting expressions to flows -- address sets])
443expr_to_flow () {
444 echo "$1" | ovstest test-ovn expr-to-flows | sort
445}
446AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
447ip,nw_src=10.0.0.1
448ip,nw_src=10.0.0.2
449ip,nw_src=10.0.0.3
450])
451AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
452ip,nw_src=10.0.0.1
453ip,nw_src=10.0.0.2
454ip,nw_src=10.0.0.3
455])
456AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
457ip,nw_src=1.2.3.4
458ip,nw_src=10.0.0.1
459ip,nw_src=10.0.0.2
460ip,nw_src=10.0.0.3
461])
462AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
463ip,nw_src=1.2.0.0/20
464ip,nw_src=10.0.0.1
465ip,nw_src=10.0.0.2
466ip,nw_src=10.0.0.3
467ip,nw_src=5.5.5.0/24
468])
469AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
470ipv6,ipv6_src=::1
471ipv6,ipv6_src=::2
472ipv6,ipv6_src=::3
473])
474AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
475ipv6,ipv6_src=::1
476ipv6,ipv6_src=::2
477ipv6,ipv6_src=::3
478ipv6,ipv6_src=::4
479])
480AT_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
481dl_src=00:00:00:00:00:01
482dl_src=00:00:00:00:00:02
483dl_src=00:00:00:00:00:03
484])
485AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
486dl_src=00:00:00:00:00:01
487dl_src=00:00:00:00:00:02
488dl_src=00:00:00:00:00:03
489])
490AT_CLEANUP
491
3b7cb7e1
BP
492AT_SETUP([ovn -- action parsing])
493dnl Text before => is input, text after => is expected output.
494AT_DATA([test-cases.txt], [[
5f822129 495# drop
3b7cb7e1 496drop; => actions=drop, prereqs=1
5f822129
BP
497drop; next; => Syntax error at `next' expecting end of input.
498next; drop; => Syntax error at `drop' expecting action.
499
500# output
501output; => actions=resubmit(,64), prereqs=1
502
503# next
558ec83d
BP
504next; => actions=resubmit(,27), prereqs=1
505next(0); => actions=resubmit(,16), prereqs=1
506next(15); => actions=resubmit(,31), prereqs=1
5f822129
BP
507
508next(); => Syntax error at `)' expecting small integer.
509next(10; => Syntax error at `;' expecting `)'.
510next(16); => "next" argument must be in range 0 to 15.
511
512# Loading a constant value.
3b7cb7e1
BP
513tcp.dst=80; => actions=set_field:80->tcp_dst, prereqs=ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
514eth.dst[40] = 1; => actions=set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst, prereqs=1
515vlan.pcp = 2; => actions=set_field:0x4000/0xe000->vlan_tci, prereqs=vlan.tci[12]
516vlan.tci[13..15] = 2; => actions=set_field:0x4000/0xe000->vlan_tci, prereqs=1
b4970837 517inport = ""; => actions=set_field:0->reg6,set_field:0->in_port, prereqs=1
47f3b59b 518ip.ttl = 4; => actions=set_field:4->nw_ttl, prereqs=eth.type == 0x800 || eth.type == 0x86dd
5f822129 519outport="eth0"; next; outport="LOCAL"; next; => actions=set_field:0x5->reg7,resubmit(,27),set_field:0xfffe->reg7,resubmit(,27), prereqs=1
558ec83d 520
3b7cb7e1
BP
521inport[1] = 1; => Cannot select subfield of string field inport.
522ip.proto[1] = 1; => Cannot select subfield of nominal field ip.proto.
8fb72d29 523eth.dst[40] == 1; => Syntax error at `==' expecting `=' or `<->'.
ce57ea75 524ip = 1; => Predicate symbol ip used where lvalue required.
3b7cb7e1
BP
525ip.proto = 6; => Field ip.proto is not modifiable.
526inport = {"a", "b"}; => Assignments require a single value.
527inport = {}; => Syntax error at `}' expecting constant.
528bad_prereq = 123; => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
529self_recurse = 123; => 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'.
ce57ea75 530vlan.present = 0; => Predicate symbol vlan.present used where lvalue required.
5f822129
BP
531
532# Moving one field into another.
533reg0 = reg1; => actions=move:OXM_OF_PKT_REG0[0..31]->OXM_OF_PKT_REG0[32..63], prereqs=1
534vlan.pcp = reg0[0..2]; => actions=move:OXM_OF_PKT_REG0[32..34]->NXM_OF_VLAN_TCI[13..15], prereqs=vlan.tci[12]
535reg0[10] = vlan.pcp[1]; => actions=move:NXM_OF_VLAN_TCI[14]->OXM_OF_PKT_REG0[42], prereqs=vlan.tci[12]
536outport = inport; => actions=move:NXM_NX_REG6[]->NXM_NX_REG7[], prereqs=1
537
ce57ea75 538reg0[0] = vlan.present; => Predicate symbol vlan.present used where lvalue required.
5ee054fb
BP
539reg0 = reg1[0..10]; => Can't assign 11-bit value to 32-bit destination.
540inport = reg0; => Can't assign integer field (reg0) to string field (inport).
541inport = big_string; => String fields inport and big_string are incompatible for assignment.
542ip.proto = reg0[0..7]; => Field ip.proto is not modifiable.
5f822129
BP
543
544# Exchanging fields.
545reg0 <-> reg1; => actions=push:OXM_OF_PKT_REG0[0..31],push:OXM_OF_PKT_REG0[32..63],pop:OXM_OF_PKT_REG0[0..31],pop:OXM_OF_PKT_REG0[32..63], prereqs=1
546vlan.pcp <-> reg0[0..2]; => actions=push:OXM_OF_PKT_REG0[32..34],push:NXM_OF_VLAN_TCI[13..15],pop:OXM_OF_PKT_REG0[32..34],pop:NXM_OF_VLAN_TCI[13..15], prereqs=vlan.tci[12]
547reg0[10] <-> vlan.pcp[1]; => actions=push:NXM_OF_VLAN_TCI[14],push:OXM_OF_PKT_REG0[42],pop:NXM_OF_VLAN_TCI[14],pop:OXM_OF_PKT_REG0[42], prereqs=vlan.tci[12]
548outport <-> inport; => actions=push:NXM_NX_REG6[],push:NXM_NX_REG7[],pop:NXM_NX_REG6[],pop:NXM_NX_REG7[], prereqs=1
549
ce57ea75 550reg0[0] <-> vlan.present; => Predicate symbol vlan.present used where lvalue required.
a20c96c6
BP
551reg0 <-> reg1[0..10]; => Can't exchange 32-bit field with 11-bit field.
552inport <-> reg0; => Can't exchange string field (inport) with integer field (reg0).
553inport <-> big_string; => String fields inport and big_string are incompatible for exchange.
554ip.proto <-> reg0[0..7]; => Field ip.proto is not modifiable.
555reg0[0..7] <-> ip.proto; => Field ip.proto is not modifiable.
5f822129
BP
556
557# TTL decrement.
558ip.ttl--; => actions=dec_ttl, prereqs=ip
47f3b59b 559ip.ttl => Syntax error at end of input expecting `--'.
5f822129
BP
560
561# conntrack
562ct_next; => actions=ct(table=27,zone=NXM_NX_REG5[0..15]), prereqs=ip
563ct_commit; => actions=ct(commit,zone=NXM_NX_REG5[0..15]), prereqs=ip
a9e1b66f
RB
564ct_commit(); => actions=ct(commit,zone=NXM_NX_REG5[0..15]), prereqs=ip
565ct_commit(ct_mark=1); => actions=ct(commit,zone=NXM_NX_REG5[0..15],exec(set_field:0x1->ct_mark)), prereqs=ip
566ct_commit(ct_mark=1/1); => actions=ct(commit,zone=NXM_NX_REG5[0..15],exec(set_field:0x1/0x1->ct_mark)), prereqs=ip
567ct_commit(ct_label=1); => actions=ct(commit,zone=NXM_NX_REG5[0..15],exec(set_field:0x1->ct_label)), prereqs=ip
568ct_commit(ct_label=1/1); => actions=ct(commit,zone=NXM_NX_REG5[0..15],exec(set_field:0x1/0x1->ct_label)), prereqs=ip
569ct_commit(ct_mark=1, ct_label=2); => actions=ct(commit,zone=NXM_NX_REG5[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label)), prereqs=ip
5f822129 570
de297547
GS
571# dnat
572ct_dnat; => actions=ct(table=27,zone=NXM_NX_REG3[0..15],nat), prereqs=ip
573ct_dnat(192.168.1.2); => actions=ct(commit,table=27,zone=NXM_NX_REG3[0..15],nat(dst=192.168.1.2)), prereqs=ip
574ct_dnat(192.168.1.2, 192.168.1.3); => Syntax error at `,' expecting `)'.
575ct_dnat(foo); => Syntax error at `foo' invalid ip.
576ct_dnat(foo, bar); => Syntax error at `foo' invalid ip.
577ct_dnat(); => Syntax error at `)' invalid ip.
578
579# snat
580ct_snat; => actions=ct(zone=NXM_NX_REG4[0..15],nat), prereqs=ip
581ct_snat(192.168.1.2); => actions=ct(commit,table=27,zone=NXM_NX_REG4[0..15],nat(src=192.168.1.2)), prereqs=ip
582ct_snat(192.168.1.2, 192.168.1.3); => Syntax error at `,' expecting `)'.
583ct_snat(foo); => Syntax error at `foo' invalid ip.
584ct_snat(foo, bar); => Syntax error at `foo' invalid ip.
585ct_snat(); => Syntax error at `)' invalid ip.
586
587
6335d074
BP
588# arp
589arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; => actions=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), prereqs=ip4
590
0bac7164
BP
591# get_arp
592get_arp(outport, ip4.dst); => actions=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[], prereqs=eth.type == 0x800
593get_arp(inport, reg0); => actions=push:NXM_NX_REG7[],push:NXM_NX_REG0[],push:OXM_OF_PKT_REG0[32..63],push:NXM_NX_REG6[],pop:NXM_NX_REG7[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG7[], prereqs=1
594get_arp; => Syntax error at `;' expecting `('.
595get_arp(); => Syntax error at `)' expecting field name.
596get_arp(inport); => Syntax error at `)' expecting `,'.
597get_arp(inport ip4.dst); => Syntax error at `ip4.dst' expecting `,'.
598get_arp(inport, ip4.dst; => Syntax error at `;' expecting `)'.
599get_arp(inport, eth.dst); => Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
600get_arp(inport, outport); => Cannot use string field outport where numeric field is required.
601get_arp(reg0, ip4.dst); => Cannot use numeric field reg0 where string field is required.
602
603# put_arp
604put_arp(inport, arp.spa, arp.sha); => actions=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[], prereqs=eth.type == 0x806 && eth.type == 0x806
605
42814145
NS
606# put_dhcp_opts
607reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1); => actions=controller(userdata=00.00.00.02.00.00.00.00.80.01.00.08.00.00.00.00.01.02.03.04.03.04.0a.00.00.01,pause), prereqs=1
608reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org"); => actions=controller(userdata=00.00.00.02.00.00.00.00.80.01.02.08.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), prereqs=1
609# offerip=10.0.0.4 --> 0a.00.00.04
610# router=10.0.0.1 --> 03.04.0a.00.00.01
611# netmask=255.255.255.0 --> 01.04.ff.ff.ff.00
612# mtu=1400 --> 1a.02.05.78
613# ip_forward_enable-1 --> 13.01.01
614# default_ttl=121 --> 17.01.79
615# dns_server={8.8.8.8,7.7.7.7} --> 06.08.08.08.08.08.07.07.07.07
616# classless_static_route= --> 79.14
617# {30.0.0.0/24,10.0.0.4 --> 18.1e.00.00.0a.00.00.04
618# 40.0.0.0/16,10.0.0.6 --> 10.28.00.0a.00.00.06
619# 0.0.0.0/0,10.0.0.1} --> 00.0a.00.00.01
620# ethernet_encap=1 --> 24.01.01
621# router_discovery=0 --> 1f.01.00
622reg0[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); => actions=controller(userdata=00.00.00.02.00.00.00.00.80.01.00.08.00.00.00.2f.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), prereqs=1
623reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1); => Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
624reg1[0] = put_dhcp_opts(); => Syntax error at `)'.
625reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1); => Syntax error at `x' expecting offerip option.
626reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi"); => Syntax error at `"hi"'.
627reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy); => Syntax error at `xyzzy' expecting DHCP option name.
628reg1[0] = put_dhcp_opts(offerip="xyzzy"); => DHCP option offerip requires numeric value.
629reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4); => DHCP option domain requires string value.
630
e75451fe
ZKL
631# na
632na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; }; => actions=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.0c.04.00.01.0e.04.00.19.00.10.00.01.0c.04.00.00.00.00.00.00.00.00.00.19.00.10.00.00.00.02.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00), prereqs=nd
633
5f822129
BP
634# Contradictionary prerequisites (allowed but not useful):
635ip4.src = ip6.src[0..31]; => actions=move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[], prereqs=eth.type == 0x800 && eth.type == 0x86dd
636ip4.src <-> ip6.src[0..31]; => actions=push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[], prereqs=eth.type == 0x800 && eth.type == 0x86dd
637
638## Miscellaneous negative tests.
639; => Syntax error at `;'.
640xyzzy; => Syntax error at `xyzzy' expecting action.
641next; 123; => Syntax error at `123'.
642next; xyzzy; => Syntax error at `xyzzy' expecting action.
643next => Syntax error at end of input expecting ';'.
3b7cb7e1
BP
644]])
645sed 's/ =>.*//' test-cases.txt > input.txt
646sed 's/.* => //' test-cases.txt > expout
647AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
648AT_CLEANUP
f295c17b
BP
649
650AT_BANNER([OVN end-to-end tests])
651
9975d7be
BP
652# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
653AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 654AT_KEYWORDS([ovnarp])
f295c17b
BP
655AT_SKIP_IF([test $HAVE_PYTHON = no])
656ovn_start
657
658# Create hypervisors hv[123].
9975d7be 659# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
660# Add all of the vifs to a single logical switch lsw0.
661# Turn on port security on all the vifs except vif[123]1.
662# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
663# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 664ovn-nbctl ls-add lsw0
f295c17b
BP
665net_add n1
666for i in 1 2 3; do
667 sim_add hv$i
668 as hv$i
669 ovs-vsctl add-br br-phys
670 ovn_attach n1 br-phys 192.168.0.$i
671
672 for j in 1 2 3; do
673 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
31ed1192 674 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 675 if test $j = 1; then
31ed1192 676 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 677 else
7dc88496
NS
678 if test $j = 3; then
679 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
680 else
681 ip_addrs="192.168.0.$i$j"
682 fi
31ed1192
JP
683 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
684 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
685 fi
686 done
687done
688ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
689ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
690ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
691
692# Pre-populate the hypervisors' ARP tables so that we don't lose any
693# packets for ARP resolution (native tunneling doesn't queue packets
694# for ARP resolution).
695ovn_populate_arp
696
697# Allow some time for ovn-northd and ovn-controller to catch up.
698# XXX This should be more systematic.
699sleep 1
611099dc 700
57d143eb
HZ
701# Given the name of a logical port, prints the name of the hypervisor
702# on which it is located.
703vif_to_hv() {
704 echo hv${1%?}
705}
706
f295c17b
BP
707# test_packet INPORT DST SRC ETHTYPE OUTPORT...
708#
709# This shell function causes a packet to be received on INPORT. The packet's
710# content has Ethernet destination DST and source SRC (each exactly 12 hex
711# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
712# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 713# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
714trim_zeros() {
715 sed 's/\(00\)\{1,\}$//'
716}
717for i in 1 2 3; do
718 for j in 1 2 3; do
719 : > $i$j.expected
720 done
721done
722test_packet() {
723 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 724 hv=`vif_to_hv $inport`
f295c17b
BP
725 vif=vif$inport
726 as $hv ovs-appctl netdev-dummy/receive $vif $packet
727 for outport; do
728 echo $packet | trim_zeros >> $outport.expected
729 done
730}
731
57d143eb
HZ
732# test_arp INPORT SHA SPA TPA [REPLY_HA]
733#
734# Causes a packet to be received on INPORT. The packet is an ARP
735# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
736# it should be the hardware address of the target to expect to receive in an
737# ARP reply; otherwise no reply is expected.
738#
31ed1192 739# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
740# SHA and REPLY_HA are each 12 hex digits.
741# SPA and TPA are each 8 hex digits.
742test_arp() {
743 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
744 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
745 hv=`vif_to_hv $inport`
746 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
747
92f9822b 748 if test X$reply_ha = X; then
57d143eb
HZ
749 # Expect to receive the broadcast ARP on the other logical switch ports
750 # if no reply is expected.
751 local i j
752 for i in 1 2 3; do
753 for j in 1 2 3; do
754 if test $i$j != $inport; then
755 echo $request >> $i$j.expected
756 fi
757 done
758 done
759 else
760 # Expect to receive the reply, if any.
761 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
762 echo $reply >> $inport.expected
763 fi
764}
765
766ip_to_hex() {
767 printf "%02x%02x%02x%02x" "$@"
768}
769
f295c17b
BP
770# Send packets between all pairs of source and destination ports:
771#
31ed1192
JP
772# 1. Unicast packets are delivered to exactly one logical switch port
773# (except that packets destined to their input ports are dropped).
f295c17b 774#
31ed1192
JP
775# 2. Broadcast and multicast are delivered to all logical switch ports
776# except the input port.
f295c17b 777#
ea46a4e9 778# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
779# MAC address.
780#
ea46a4e9 781# 4. The switch drops all packets with a VLAN tag.
f295c17b 782#
ea46a4e9 783# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
784# affects behavior when port security is turned off, since otherwise port
785# security would drop the packet anyway.)
786#
ea46a4e9 787# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
788# switch ports with "unknown" among their MAC addresses (and port
789# security disabled).
f295c17b 790#
ea46a4e9 791# 7. The switch drops unicast packets that violate an ACL.
f295c17b 792#
ea46a4e9 793# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb
HZ
794#
795# 9. ARP requests to known IPs are responded directly.
796#
797# 10. No response to ARP requests for unknown IPs.
f295c17b
BP
798for is in 1 2 3; do
799 for js in 1 2 3; do
800 s=$is$js
801 bcast=
4d5c43d5
JP
802 unknown=
803 bacl2=
804 bacl3=
f295c17b
BP
805 for id in 1 2 3; do
806 for jd in 1 2 3; do
807 d=$id$jd
808
809 if test $d != $s; then unicast=$d; else unicast=; fi
810 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
811
812 if test $d != $s && test $js = 1; then
4d5c43d5
JP
813 impersonate=$d
814 else
815 impersonate=
816 fi
f295c17b
BP
817 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
818
4d5c43d5
JP
819 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
820 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
f295c17b
BP
821 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
822 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
823 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
824
825 test_packet $s f000000000$d f00000000055 810000091234 #4
826 test_packet $s f000000000$d 0100000000$s $s$d #5
827
4d5c43d5
JP
828 if test $d != $s && test $jd = 1; then
829 unknown="$unknown $d"
830 fi
f295c17b
BP
831 bcast="$bcast $unicast"
832 bacl2="$bacl2 $acl2"
833 bacl3="$bacl3 $acl3"
57d143eb
HZ
834
835 sip=`ip_to_hex 192 168 0 $i$j`
836 tip=`ip_to_hex 192 168 0 $id$jd`
837 tip_unknown=`ip_to_hex 11 11 11 11`
838 test_arp $s f000000000$s $sip $tip f000000000$d #9
839 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
840
841 if test $jd = 3; then
31ed1192 842 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496
NS
843 tip=`ip_to_hex 192 169 0 $id$jd`
844 test_arp $s f000000000$s $sip $tip f000000000$d #9
845 fi
f295c17b
BP
846 done
847 done
848
4d5c43d5 849 # Broadcast and multicast.
f295c17b
BP
850 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
851 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 852 if test $js = 1; then
f295c17b
BP
853 bcast_impersonate=$bcast
854 else
4d5c43d5
JP
855 bcast_impersonate=
856 fi
f295c17b
BP
857 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
858
859 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
860
861 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
862 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
863 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
864 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
865 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
866 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
867 done
868done
869
7dc88496
NS
870# set address for lp13 with invalid characters.
871# lp13 should be configured with only 192.168.0.13.
31ed1192 872ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
7dc88496
NS
873sip=`ip_to_hex 192 168 0 11`
874tip=`ip_to_hex 192 168 0 13`
875test_arp 11 f00000000011 $sip $tip f00000000013
876
877tip=`ip_to_hex 192 169 0 13`
878#arp request for 192.169.0.13 should be flooded
879test_arp 11 f00000000011 $sip $tip
880
f295c17b
BP
881# Allow some time for packet forwarding.
882# XXX This can be improved.
883sleep 1
884
91125642 885# dump information and flows with counters
bb0c41d3
RM
886ovn-sbctl dump-flows -- list multicast_group
887
888echo "------ hv1 dump ------"
889as hv1 ovs-vsctl show
890as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
891
892echo "------ hv2 dump ------"
893as hv2 ovs-vsctl show
894as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
895
896echo "------ hv3 dump ------"
897as hv3 ovs-vsctl show
898as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
f295c17b
BP
899# Now check the packets actually received against the ones expected.
900for i in 1 2 3; do
901 for j in 1 2 3; do
902 file=hv$i/vif$i$j-tx.pcap
903 echo $file
904 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i$j.packets
2172f32d
YT
905 sort $i$j.expected > expout
906 AT_CHECK([sort $i$j.packets], [0], [expout])
f295c17b
BP
907 echo
908 done
909done
fcde56f5
LR
910
911# Gracefully terminate daemons
d9c8c57c
LR
912for sim in hv1 hv2 hv3; do
913 as $sim
914 OVS_APP_EXIT_AND_WAIT([ovn-controller])
915 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
916 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
fcde56f5 917done
d9c8c57c
LR
918
919as ovn-sb
920OVS_APP_EXIT_AND_WAIT([ovsdb-server])
921
922as ovn-nb
923OVS_APP_EXIT_AND_WAIT([ovsdb-server])
924
925as northd
926OVS_APP_EXIT_AND_WAIT([ovn-northd])
927
928as main
929OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
930OVS_APP_EXIT_AND_WAIT([ovsdb-server])
931
f295c17b 932AT_CLEANUP
eb6b08eb 933
7277bc83
RB
934# 2 hypervisors, 4 logical ports per HV
935# 2 locally attached networks (one flat, one vlan tagged over same device)
936# 2 ports per HV on each network
e90aeb57 937AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
938AT_KEYWORDS([ovn-localnet])
939AT_SKIP_IF([test $HAVE_PYTHON = no])
940ovn_start
941
ea46a4e9
JP
942# In this test cases we create 3 switches, all connected to same
943# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
944# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
945# of VIF port name indicates the hypervisor it is bound to, e.g.
946# lp23 means VIF 3 on hv2.
947#
ea46a4e9 948# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
949# - ls1:
950# - untagged
ea46a4e9 951# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
952#
953# - ls2:
954# - tagged with VLAN 101
ea46a4e9 955# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
956# - ls3:
957# - untagged
ea46a4e9 958# - ports: lp15, lp25
0ee7f7f1 959#
ea46a4e9 960# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
961# physical network.
962
963for i in 1 2 3; do
ea46a4e9
JP
964 ls_name=ls$i
965 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
966 ln_port_name=ln$i
967 if test $i -eq 2; then
ea46a4e9 968 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 969 else
ea46a4e9 970 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 971 fi
31ed1192
JP
972 ovn-nbctl lsp-set-addresses $ln_port_name unknown
973 ovn-nbctl lsp-set-type $ln_port_name localnet
974 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 975done
d79fc5f4
RB
976
977net_add n1
978for i in 1 2; do
979 sim_add hv$i
980 as hv$i
981 ovs-vsctl add-br br-phys
982 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
983 ovn_attach n1 br-phys 192.168.0.$i
984
0ee7f7f1 985 for j in 1 2 3 4 5; do
d79fc5f4
RB
986 ovs-vsctl add-port br-int vif$i$j -- \
987 set Interface vif$i$j external-ids:iface-id=lp$i$j \
988 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
989 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
990 ofport-request=$i$j
991
31ed1192 992 lsp_name=lp$i$j
7277bc83 993 if test $j -le 2; then
ea46a4e9 994 ls_name=ls1
0ee7f7f1 995 elif test $j -le 4; then
ea46a4e9 996 ls_name=ls2
d79fc5f4 997 else
ea46a4e9 998 ls_name=ls3
d79fc5f4 999 fi
d79fc5f4 1000
ea46a4e9 1001 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1002 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1003 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1004
31ed1192 1005 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1006 done
1007done
1008
1009ovn_populate_arp
1010
1011# XXX This is now the 3rd copy of these functions in this file ...
1012
1013# Given the name of a logical port, prints the name of the hypervisor
1014# on which it is located.
1015vif_to_hv() {
1016 echo hv${1%?}
1017}
1018#
1019# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1020#
1021# This shell function causes a packet to be received on INPORT. The packet's
1022# content has Ethernet destination DST and source SRC (each exactly 12 hex
1023# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1024# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1025# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
d79fc5f4
RB
1026trim_zeros() {
1027 sed 's/\(00\)\{1,\}$//'
1028}
1029for i in 1 2; do
0ee7f7f1 1030 for j in 1 2 3 4 5; do
d79fc5f4
RB
1031 : > $i$j.expected
1032 done
1033done
1034test_packet() {
1035 local inport=$1 src=$2 dst=$3 eth=$4; shift; shift; shift; shift
1036 local packet=${src}${dst}${eth}
1037 hv=`vif_to_hv $inport`
1038 vif=vif$inport
1039 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1040 for outport; do
1041 echo $packet | trim_zeros >> $outport.expected
1042 done
1043}
1044
7277bc83
RB
1045# lp11 and lp21 are on the same network (phys, untagged)
1046# and on different hypervisors
d79fc5f4
RB
1047test_packet 11 f00000000021 f00000000011 1121 21
1048test_packet 21 f00000000011 f00000000021 2111 11
1049
7277bc83
RB
1050# lp11 and lp12 are on the same network (phys, untagged)
1051# and on the same hypervisor
e90aeb57
RB
1052test_packet 11 f00000000012 f00000000011 1112 12
1053test_packet 12 f00000000011 f00000000012 1211 11
7277bc83
RB
1054
1055# lp13 and lp23 are on the same network (phys, VLAN 101)
1056# and on different hypervisors
1057test_packet 13 f00000000023 f00000000013 1323 23
1058test_packet 23 f00000000013 f00000000023 2313 13
1059
1060# lp13 and lp14 are on the same network (phys, VLAN 101)
1061# and on the same hypervisor
e90aeb57
RB
1062test_packet 13 f00000000014 f00000000013 1314 14
1063test_packet 14 f00000000013 f00000000014 1413 13
d79fc5f4 1064
0ee7f7f1 1065# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1066# same hypervisor, and on different switches
0ee7f7f1
HZ
1067test_packet 11 f00000000015 f00000000011 1115 15
1068test_packet 15 f00000000011 f00000000015 1511 11
1069
1070# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1071# different hypervisors, and on different switches
0ee7f7f1
HZ
1072test_packet 11 f00000000025 f00000000011 1125 25
1073test_packet 25 f00000000011 f00000000025 2511 11
1074
d79fc5f4 1075# Ports that should not be able to communicate
7277bc83
RB
1076test_packet 11 f00000000013 f00000000011 1113
1077test_packet 11 f00000000023 f00000000011 1123
1078test_packet 21 f00000000013 f00000000021 2113
1079test_packet 21 f00000000023 f00000000021 2123
1080test_packet 13 f00000000011 f00000000013 1311
1081test_packet 13 f00000000021 f00000000013 1321
1082test_packet 23 f00000000011 f00000000023 2311
1083test_packet 23 f00000000021 f00000000023 2321
d79fc5f4
RB
1084
1085# Allow some time for packet forwarding.
1086# XXX This can be improved.
1087sleep 1
1088
1089# Dump a bunch of info helpful for debugging if there's a failure.
1090
1091echo "------ OVN dump ------"
1092ovn-nbctl show
1093ovn-sbctl show
1094
1095echo "------ hv1 dump ------"
1096as hv1 ovs-vsctl show
1097as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1098
1099echo "------ hv2 dump ------"
1100as hv2 ovs-vsctl show
1101as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1102
1103# Now check the packets actually received against the ones expected.
1104for i in 1 2; do
0ee7f7f1 1105 for j in 1 2 3 4 5; do
d79fc5f4
RB
1106 file=hv$i/vif$i$j-tx.pcap
1107 echo $file
1108 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i$j.packets
1109 sort $i$j.expected > expout
1110 AT_CHECK([sort $i$j.packets], [0], [expout])
1111 echo
1112 done
1113done
1114
fcde56f5 1115# Gracefully terminate daemons
d9c8c57c
LR
1116for sim in hv1 hv2; do
1117 as $sim
1118 OVS_APP_EXIT_AND_WAIT([ovn-controller])
1119 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
1120 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
fcde56f5 1121done
d9c8c57c
LR
1122
1123as ovn-sb
1124OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1125
1126as ovn-nb
1127OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1128
1129as northd
1130OVS_APP_EXIT_AND_WAIT([ovn-northd])
1131
1132as main
1133OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
1134OVS_APP_EXIT_AND_WAIT([ovsdb-server])
d79fc5f4
RB
1135AT_CLEANUP
1136
91125642
FF
1137AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1138AT_KEYWORDS([vtep])
eb6b08eb
JP
1139AT_SKIP_IF([test $HAVE_PYTHON = no])
1140ovn_start
1141
1142# Configure the Northbound database
ea46a4e9 1143ovn-nbctl ls-add lsw0
eb6b08eb 1144
31ed1192
JP
1145ovn-nbctl lsp-add lsw0 lp1
1146ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 1147
31ed1192
JP
1148ovn-nbctl lsp-add lsw0 lp2
1149ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 1150
31ed1192
JP
1151ovn-nbctl lsp-add lsw0 lp-vtep
1152ovn-nbctl lsp-set-type lp-vtep vtep
1153ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1154ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb
JP
1155
1156net_add n1 # Network to connect hv1, hv2, and vtep
1157net_add n2 # Network to connect vtep and hv3
1158
1159# Create hypervisor hv1 connected to n1
1160sim_add hv1
1161as hv1
1162ovs-vsctl add-br br-phys
1163ovn_attach n1 br-phys 192.168.0.1
1164ovs-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
1165
1166# Create hypervisor hv2 connected to n1
1167sim_add hv2
1168as hv2
1169ovs-vsctl add-br br-phys
1170ovn_attach n1 br-phys 192.168.0.2
1171ovs-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
1172
1173
1174# Start the vtep emulator with a leg in both networks
1175sim_add vtep
1176as vtep
1177
1178ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1179ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1180
1181ovs-vsctl add-br br-phys
1182net_attach n1 br-phys
1183
1184mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1185arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1186ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1187ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1188
1189ovs-vsctl add-br br-vtep
1190net_attach n2 br-vtep
1191
1192vtep-ctl add-ps br-vtep
1193vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1194vtep-ctl add-ls lsw0
1195
1196start_daemon ovs-vtep br-vtep
1197start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1198
1199sleep 1
1200
1201vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0
1202
1203sleep 1
1204
1205# Add hv3 on the other side of the vtep
1206sim_add hv3
1207as hv3
1208ovs-vsctl add-br br-phys
1209net_attach n2 br-phys
1210
1211ovs-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
1212
1213# Pre-populate the hypervisors' ARP tables so that we don't lose any
1214# packets for ARP resolution (native tunneling doesn't queue packets
1215# for ARP resolution).
1216ovn_populate_arp
1217
1218# Allow some time for ovn-northd and ovn-controller to catch up.
1219# XXX This should be more systematic.
1220sleep 1
6977df72 1221
eb6b08eb
JP
1222# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1223#
1224# This shell function causes a packet to be received on INPORT. The packet's
1225# content has Ethernet destination DST and source SRC (each exactly 12 hex
1226# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1227# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1228# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
1229trim_zeros() {
1230 sed 's/\(00\)\{1,\}$//'
1231}
1232for i in 1 2 3; do
1233 : > $i.expected
1234done
1235test_packet() {
1236 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1237 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1238 hv=hv$inport
1239 vif=vif$inport
1240 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1241 for outport; do
1242 echo $packet | trim_zeros >> $outport.expected
1243 done
1244}
1245
1246# Send packets between all pairs of source and destination ports:
1247#
31ed1192
JP
1248# 1. Unicast packets are delivered to exactly one logical switch port
1249# (except that packets destined to their input ports are dropped).
eb6b08eb 1250#
31ed1192
JP
1251# 2. Broadcast and multicast are delivered to all logical switch ports
1252# except the input port.
eb6b08eb 1253#
ea46a4e9 1254# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1255# switch ports with "unknown" among their MAC addresses (and port
1256# security disabled).
eb6b08eb
JP
1257for s in 1 2 3; do
1258 bcast=
1259 unknown=
1260 for d in 1 2 3; do
1261 if test $d != $s; then unicast=$d; else unicast=; fi
1262 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1263
1264 # The vtep (vif3) is the only one configured for "unknown"
1265 if test $d != $s && test $d = 3; then
1266 unknown="$unknown $d"
1267 fi
1268 bcast="$bcast $unicast"
1269 done
1270
1271 # Broadcast and multicast.
46ed1382
DB
1272 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1273 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
1274
1275 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1276done
1277
1278# Allow some time for packet forwarding.
1279# XXX This can be improved.
1280sleep 1
1281
bb0c41d3
RM
1282# dump information with counters
1283echo "------ OVN dump ------"
1284ovn-nbctl show
1285ovn-sbctl show
1286
1287echo "------ hv1 dump ------"
1288as hv1 ovs-vsctl show
6195e2e7 1289as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1290as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1291
1292echo "------ hv2 dump ------"
1293as hv2 ovs-vsctl show
6195e2e7 1294as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1295as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1296
1297echo "------ hv3 dump ------"
1298as hv3 ovs-vsctl show
6754e92d
FF
1299# note: hv3 has no logical port bind, thus it should not have br-int
1300AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1301[ovs-ofctl: br-int is not a bridge or a socket
1302])
bb0c41d3 1303
eb6b08eb
JP
1304# Now check the packets actually received against the ones expected.
1305for i in 1 2 3; do
1306 file=hv$i/vif$i-tx.pcap
1307 echo $file
1308 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i.packets
2172f32d
YT
1309 sort $i.expected > expout
1310 AT_CHECK([sort $i.packets], [0], [expout])
eb6b08eb
JP
1311 echo
1312done
fcde56f5
LR
1313
1314# Gracefully terminate daemons
d9c8c57c
LR
1315as vtep
1316OVS_APP_EXIT_AND_WAIT([ovn-controller-vtep])
1317OVS_APP_EXIT_AND_WAIT([ovs-vtep])
1318
1319as hv1
1320OVS_APP_EXIT_AND_WAIT([ovn-controller])
1321
1322as hv2
1323OVS_APP_EXIT_AND_WAIT([ovn-controller])
1324
1325as ovn-sb
1326OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1327
1328as ovn-nb
1329OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1330
1331as northd
1332OVS_APP_EXIT_AND_WAIT([ovn-northd])
1333
1334for sim in hv1 hv2 hv3 vtep main; do
1335 as $sim
1336 for daemon in ovs-vswitchd ovsdb-server; do
1337 OVS_APP_EXIT_AND_WAIT([$daemon])
1338 done
fcde56f5 1339done
eb6b08eb 1340AT_CLEANUP
9975d7be 1341
184bc3ca
RB
1342# Similar test to "hardware GW"
1343AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1344AT_SKIP_IF([test $HAVE_PYTHON = no])
1345ovn_start
1346
1347# Configure the Northbound database
1348ovn-nbctl ls-add lsw0
1349
1350ovn-nbctl lsp-add lsw0 lp1
1351ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1352
1353ovn-nbctl lsp-add lsw0 lp2
1354ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1355
1356ovn-nbctl lsp-add lsw0 lp-gw
1357ovn-nbctl lsp-set-type lp-gw l2gateway
1358ovn-nbctl lsp-set-options lp-gw network_name=physnet1
1359ovn-nbctl lsp-set-addresses lp-gw unknown
1360
1361net_add n1 # Network to connect hv1, hv2, and gw
1362net_add n2 # Network to connect gw and hv3
1363
1364# Create hypervisor hv1 connected to n1
1365sim_add hv1
1366as hv1
1367ovs-vsctl add-br br-phys
1368ovn_attach n1 br-phys 192.168.0.1
1369ovs-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
1370
1371# Create hypervisor hv2 connected to n1
1372sim_add hv2
1373as hv2
1374ovs-vsctl add-br br-phys
1375ovn_attach n1 br-phys 192.168.0.2
1376ovs-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
1377
1378# Create hypervisor hv_gw connected to n1 and n2
1379# connect br-phys bridge to n1; connect hv-gw bridge to n2
1380sim_add hv_gw
1381as hv_gw
1382ovs-vsctl add-br br-phys
1383ovn_attach n1 br-phys 192.168.0.3
1384ovs-vsctl add-br br-phys2
1385net_attach n2 br-phys2
1386ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
1387
1388# Bind our gateway port to the hv_gw chassis
1389ovn-sbctl lport-bind lp-gw hv_gw
1390
1391# Add hv3 on the other side of the GW
1392sim_add hv3
1393as hv3
1394ovs-vsctl add-br br-phys
1395net_attach n2 br-phys
1396ovs-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
1397
1398
1399# Pre-populate the hypervisors' ARP tables so that we don't lose any
1400# packets for ARP resolution (native tunneling doesn't queue packets
1401# for ARP resolution).
1402ovn_populate_arp
1403
1404# Allow some time for ovn-northd and ovn-controller to catch up.
1405# XXX This should be more systematic.
1406sleep 1
1407
1408# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1409#
1410# This shell function causes a packet to be received on INPORT. The packet's
1411# content has Ethernet destination DST and source SRC (each exactly 12 hex
1412# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1413# more) list the VIFs on which the packet should be received. INPORT and the
1414# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
1415trim_zeros() {
1416 sed 's/\(00\)\{1,\}$//'
1417}
1418for i in 1 2 3; do
1419 : > $i.expected
1420done
1421test_packet() {
1422 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1423 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1424 hv=hv$inport
1425 vif=vif$inport
1426 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1427 for outport; do
1428 echo $packet | trim_zeros >> $outport.expected
1429 done
1430}
1431
1432# Send packets between all pairs of source and destination ports:
1433#
1434# 1. Unicast packets are delivered to exactly one lport (except that packets
1435# destined to their input ports are dropped).
1436#
1437# 2. Broadcast and multicast are delivered to all lports except the input port.
1438#
1439# 3. The lswitch delivers packets with an unknown destination to lports with
1440# "unknown" among their MAC addresses (and port security disabled).
1441for s in 1 2 3 ; do
1442 bcast=
1443 unknown=
1444 for d in 1 2 3 ; do
1445 if test $d != $s; then unicast=$d; else unicast=; fi
1446 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1447
1448 # The vtep (vif3) is the only one configured for "unknown"
1449 if test $d != $s && test $d = 3; then
1450 unknown="$unknown $d"
1451 fi
1452 bcast="$bcast $unicast"
1453 done
1454
1455 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1456 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
1457 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
1458done
1459
1460# Allow some time for packet forwarding.
1461# XXX This can be improved.
1462sleep 3
1463
1464echo "------ ovn-nbctl show ------"
1465ovn-nbctl show
1466echo "------ ovn-sbctl show ------"
1467ovn-sbctl show
1468
1469echo "------ hv1 ------"
1470as hv1 ovs-vsctl show
1471echo "------ hv1 br-int ------"
1472as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1473echo "------ hv1 br-phys ------"
1474as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1475
1476echo "------ hv2 ------"
1477as hv2 ovs-vsctl show
1478echo "------ hv2 br-int ------"
1479as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1480echo "------ hv2 br-phys ------"
1481as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1482
1483echo "------ hv_gw ------"
1484as hv_gw ovs-vsctl show
1485echo "------ hv_gw br-phys ------"
1486as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
1487echo "------ hv_gw br-phys2 ------"
1488as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
1489
1490echo "------ hv3 ------"
1491as hv3 ovs-vsctl show
1492echo "------ hv3 br-phys ------"
1493as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1494
1495# Now check the packets actually received against the ones expected.
1496for i in 1 2 3; do
1497 file=hv$i/vif$i-tx.pcap
1498 echo $file
1499 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i.packets
1500 sort $i.expected > expout
1501 AT_CHECK([sort $i.packets], [0], [expout])
1502 echo
1503done
1504AT_CLEANUP
1505
9975d7be
BP
1506# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
1507AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
1508AT_SKIP_IF([test $HAVE_PYTHON = no])
1509ovn_start
1510
1511# Logical network:
1512#
1513# Three logical switches ls1, ls2, ls3.
86e98048
BP
1514# One logical router lr0 connected to ls[123],
1515# with nine subnets, three per logical switch:
1516#
1517# lrp11 on ls1 for subnet 192.168.11.0/24
1518# lrp12 on ls1 for subnet 192.168.12.0/24
1519# lrp13 on ls1 for subnet 192.168.13.0/24
1520# ...
1521# lrp33 on ls3 for subnet 192.168.33.0/24
1522#
1523# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
1524# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 1525for i in 1 2 3; do
ea46a4e9 1526 ovn-nbctl ls-add ls$i
9975d7be 1527 for j in 1 2 3; do
86e98048 1528 for k in 1 2 3; do
31ed1192
JP
1529 # Add "unknown" to MAC addresses for lp?11, so packets for
1530 # MAC-IP bindings discovered via ARP later have somewhere to go.
1531 if test $j$k = 11; then unknown=unknown; else unknown=; fi
1532
1533 ovn-nbctl \
1534 -- lsp-add ls$i lp$i$j$k \
1535 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
1536 192.168.$i$j.$k" $unknown
86e98048
BP
1537 done
1538 done
1539done
1540
fa2a27b2 1541ovn-nbctl lr-add lr0
86e98048
BP
1542for i in 1 2 3; do
1543 for j in 1 2 3; do
269ecccc 1544 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j \
31114af7 1545 192.168.$i$j.254/24 lrp$i$j-attachment
269ecccc 1546 ovn-nbctl \
31ed1192 1547 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 1548 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 1549 options:router-port=lrp$i$j \
86e98048 1550 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
1551 done
1552done
1553
80f408f4 1554ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
1555 addresses='"00:00:00:00:ff:33 192.168.33.254"'
1556
9975d7be
BP
1557# Physical network:
1558#
1559# Three hypervisors hv[123].
86e98048
BP
1560# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
1561# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
1562# lp?3[123] all on hv3.
1563
9975d7be
BP
1564
1565# Given the name of a logical port, prints the name of the hypervisor
1566# on which it is located.
1567vif_to_hv() {
1568 case $1 in dnl (
86e98048
BP
1569 ?11) echo 1 ;; dnl (
1570 ?12 | ?21 | ?22) echo 2 ;; dnl (
1571 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
1572 esac
1573}
1574
86e98048
BP
1575# Given the name of a logical port, prints the name of its logical router
1576# port, e.g. "vif_to_lrp 123" yields 12.
1577vif_to_lrp() {
1578 echo ${1%?}
1579}
1580
1581# Given the name of a logical port, prints the name of its logical
1582# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 1583vif_to_ls() {
86e98048 1584 echo ${1%??}
e3393e3f
BP
1585}
1586
9975d7be
BP
1587net_add n1
1588for i in 1 2 3; do
1589 sim_add hv$i
1590 as hv$i
1591 ovs-vsctl add-br br-phys
1592 ovn_attach n1 br-phys 192.168.0.$i
1593done
1594for i in 1 2 3; do
1595 for j in 1 2 3; do
86e98048 1596 for k in 1 2 3; do
269ecccc
JP
1597 hv=`vif_to_hv $i$j$k`
1598 as hv$hv ovs-vsctl \
1599 -- add-port br-int vif$i$j$k \
1600 -- set Interface vif$i$j$k \
1601 external-ids:iface-id=lp$i$j$k \
1602 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
1603 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
1604 ofport-request=$i$j$k
86e98048 1605 done
9975d7be
BP
1606 done
1607done
1608
1609# Pre-populate the hypervisors' ARP tables so that we don't lose any
1610# packets for ARP resolution (native tunneling doesn't queue packets
1611# for ARP resolution).
1612ovn_populate_arp
1613
1614# Allow some time for ovn-northd and ovn-controller to catch up.
1615# XXX This should be more systematic.
1616sleep 1
1617
e3393e3f 1618# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
1619#
1620# This shell function causes a packet to be received on INPORT. The packet's
1621# content has Ethernet destination DST and source SRC (each exactly 12 hex
1622# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1623# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1624# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
1625trim_zeros() {
1626 sed 's/\(00\)\{1,\}$//'
1627}
1628for i in 1 2 3; do
1629 for j in 1 2 3; do
86e98048
BP
1630 for k in 1 2 3; do
1631 : > $i$j$k.expected
269ecccc 1632 done
9975d7be
BP
1633 done
1634done
e3393e3f 1635test_ip() {
9975d7be
BP
1636 # This packet has bad checksums but logical L3 routing doesn't check.
1637 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 1638 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
1639 shift; shift; shift; shift; shift
1640 hv=hv`vif_to_hv $inport`
1641 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
1642 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
1643 in_ls=`vif_to_ls $inport`
1644 in_lrp=`vif_to_lrp $inport`
9975d7be 1645 for outport; do
269ecccc 1646 out_ls=`vif_to_ls $outport`
86e98048 1647 if test $in_ls = $out_ls; then
9975d7be
BP
1648 # Ports on the same logical switch receive exactly the same packet.
1649 echo $packet
1650 else
1651 # Routing decrements TTL and updates source and dest MAC
1652 # (and checksum).
269ecccc 1653 out_lrp=`vif_to_lrp $outport`
86e98048 1654 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9975d7be
BP
1655 fi | trim_zeros >> $outport.expected
1656 done
1657}
1658
e3393e3f 1659as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
1660as hv1 ovn-sbctl list port_binding
1661as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
1662as hv1 ovn-sbctl dump-flows
1663as hv1 ovs-ofctl dump-flows br-int
1664
e3393e3f 1665# Send IP packets between all pairs of source and destination ports:
9975d7be 1666#
31ed1192
JP
1667# 1. Unicast IP packets are delivered to exactly one logical switch port
1668# (except that packets destined to their input ports are dropped).
9975d7be 1669#
31ed1192
JP
1670# 2. Broadcast IP packets are delivered to all logical switch ports
1671# except the input port.
86e98048
BP
1672ip_to_hex() {
1673 printf "%02x%02x%02x%02x" "$@"
1674}
9975d7be 1675for is in 1 2 3; do
269ecccc
JP
1676 for js in 1 2 3; do
1677 for ks in 1 2 3; do
1678 bcast=
1679 s=$is$js$ks
1680 smac=f00000000$s
1681 sip=`ip_to_hex 192 168 $is$js $ks`
1682 for id in 1 2 3; do
1683 for jd in 1 2 3; do
1684 for kd in 1 2 3; do
1685 d=$id$jd$kd
1686 dip=`ip_to_hex 192 168 $id$jd $kd`
1687 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
1688 if test $d != $s; then unicast=$d; else unicast=; fi
1689
1690 test_ip $s $smac $dmac $sip $dip $unicast #1
1691
1692 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
1693 done
1694 done
9975d7be 1695 done
269ecccc
JP
1696 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
1697 done
1698 done
e3393e3f
BP
1699done
1700
0bac7164
BP
1701# 3. Send an IP packet from every logical port to every other subnet,
1702# to an IP address that does not have a static IP-MAC binding.
1703# This should generate a broadcast ARP request for the destination
1704# IP address in the destination subnet.
1705for is in 1 2 3; do
269ecccc
JP
1706 for js in 1 2 3; do
1707 for ks in 1 2 3; do
1708 s=$is$js$ks
1709 smac=f00000000$s
1710 sip=`ip_to_hex 192 168 $is$js $ks`
1711 for id in 1 2 3; do
1712 for jd in 1 2 3; do
1713 if test $is$js = $id$jd; then
1714 continue
1715 fi
1716
1717 # Send the packet.
1718 dmac=00000000ff$is$js
1719 # Calculate a 4th octet for the destination that is
1720 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
1721 # that have static MAC bindings, and fits in the range
1722 # 0-255.
1723 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
1724 dip=`ip_to_hex 192 168 $id$jd $o4`
1725 test_ip $s $smac $dmac $sip $dip
1726
1727 # Every LP on the destination subnet's lswitch should
1728 # receive the ARP request.
1729 lrmac=00000000ff$id$jd
1730 lrip=`ip_to_hex 192 168 $id$jd 254`
1731 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
1732 for jd2 in 1 2 3; do
1733 for kd in 1 2 3; do
1734 echo $arp | trim_zeros >> $id$jd2$kd.expected
0bac7164 1735 done
269ecccc 1736 done
0bac7164 1737 done
269ecccc 1738 done
0bac7164 1739 done
269ecccc 1740 done
0bac7164
BP
1741done
1742
e3393e3f
BP
1743# test_arp INPORT SHA SPA TPA [REPLY_HA]
1744#
1745# Causes a packet to be received on INPORT. The packet is an ARP
1746# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1747# it should be the hardware address of the target to expect to receive in an
1748# ARP reply; otherwise no reply is expected.
1749#
31ed1192 1750# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
1751# SHA and REPLY_HA are each 12 hex digits.
1752# SPA and TPA are each 8 hex digits.
1753test_arp() {
1754 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1755 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1756 hv=hv`vif_to_hv $inport`
1757 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1758 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
1759
57d143eb 1760 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 1761 # IP address is not configured to the switch patch port.
e3393e3f 1762 local i=`vif_to_ls $inport`
86e98048 1763 local j k
e3393e3f 1764 for j in 1 2 3; do
86e98048 1765 for k in 1 2 3; do
ea46a4e9 1766 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
1767 # so no ARP flooding expected for it.
1768 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
1769 echo $request >> $i$j$k.expected
1770 fi
1771 done
e3393e3f
BP
1772 done
1773
1774 # Expect to receive the reply, if any.
1775 if test X$reply_ha != X; then
86e98048
BP
1776 lrp=`vif_to_lrp $inport`
1777 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
1778 echo $reply >> $inport.expected
1779 fi
1780}
1781
1782# Test router replies to ARP requests from all source ports:
1783#
0bac7164 1784# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 1785#
0bac7164 1786# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
1787# in its subnet.
1788#
0bac7164 1789# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 1790#
0bac7164 1791# 7. No reply to query for IP address other than router IP.
e3393e3f 1792for i in 1 2 3; do
269ecccc
JP
1793 for j in 1 2 3; do
1794 for k in 1 2 3; do
1795 smac=f00000000$i$j$k # Source MAC
1796 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
1797 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
1798 rmac=00000000ff$i$j # Router MAC
1799 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
1800 test_arp $i$j$k $smac $sip $rip $rmac #4
1801 test_arp $i$j$k $smac $otherip $rip $rmac #5
1802 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
1803 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 1804 done
269ecccc 1805 done
0bac7164
BP
1806done
1807
1808# Allow some time for packet forwarding.
1809# XXX This can be improved.
1810sleep 1
1811
1812# 8. Generate an ARP reply for each of the IP addresses ARPed for
1813# earlier as #3.
1814#
1815# Here, the $s is the VIF that originated the ARP request and $d is
1816# the VIF that sends the ARP reply, which is somewhat backward but
1817# it means that $s and $d are the same as #3.
1818: > mac_bindings.expected
1819for is in 1 2 3; do
269ecccc
JP
1820 for js in 1 2 3; do
1821 for ks in 1 2 3; do
1822 s=$is$js$ks
1823 for id in 1 2 3; do
1824 for jd in 1 2 3; do
1825 if test $is$js = $id$jd; then
1826 continue
1827 fi
1828
1829 kd=1
1830 d=$id$jd$kd
1831
1832 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
1833 host_ip=`ip_to_hex 192 168 $id$jd $o4`
1834 host_mac=8000000000$o4
1835
1836 lrmac=00000000ff$id$jd
1837 lrip=`ip_to_hex 192 168 $id$jd 254`
1838
1839 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
1840
1841 echo
1842 echo
1843 echo
1844 hv=hv`vif_to_hv $d`
1845 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
1846 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
1847 #as $hv ovs-ofctl dump-flows br-int table=19
1848
1849 host_ip_pretty=192.168.$id$jd.$o4
1850 host_mac_pretty=80:00:00:00:00:$o4
1851 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 1852 done
269ecccc 1853 done
9975d7be 1854 done
269ecccc 1855 done
9975d7be 1856done
0bac7164 1857
9975d7be
BP
1858# Allow some time for packet forwarding.
1859# XXX This can be improved.
1860sleep 1
1861
0bac7164
BP
1862# 9. Send an IP packet from every logical port to every other subnet. These
1863# are the same packets already sent as #3, but now the destinations' IP-MAC
1864# bindings have been discovered via ARP, so instead of provoking an ARP
1865# request, these packets now get routed to their destinations (which don't
1866# have static MAC bindings, so they go to the port we've designated as
1867# accepting "unknown" MACs.)
1868for is in 1 2 3; do
269ecccc
JP
1869 for js in 1 2 3; do
1870 for ks in 1 2 3; do
1871 s=$is$js$ks
1872 smac=f00000000$s
1873 sip=`ip_to_hex 192 168 $is$js $ks`
1874 for id in 1 2 3; do
1875 for jd in 1 2 3; do
1876 if test $is$js = $id$jd; then
1877 continue
1878 fi
1879
1880 # Send the packet.
1881 dmac=00000000ff$is$js
1882 # Calculate a 4th octet for the destination that is
1883 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
1884 # that have static MAC bindings, and fits in the range
1885 # 0-255.
1886 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
1887 dip=`ip_to_hex 192 168 $id$jd $o4`
1888 test_ip $s $smac $dmac $sip $dip
1889
1890 # Expect the packet egress.
1891 host_mac=8000000000$o4
1892 outport=${id}11
1893 out_lrp=$id$jd
1894 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 | trim_zeros >> $outport.expected
0bac7164 1895 done
269ecccc 1896 done
0bac7164 1897 done
269ecccc 1898 done
0bac7164
BP
1899done
1900
1901# Allow some time for packet forwarding.
1902# XXX This can be improved.
1903sleep 1
1904
1905ovn-sbctl -f csv -d bare --no-heading \
1906 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
1907
9975d7be
BP
1908# Now check the packets actually received against the ones expected.
1909for i in 1 2 3; do
1910 for j in 1 2 3; do
86e98048 1911 for k in 1 2 3; do
269ecccc
JP
1912 file=hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap
1913 echo $file
1914 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i$j$k.packets
1915 sort $i$j$k.expected > expout
1916 AT_CHECK([sort $i$j$k.packets], [0], [expout])
1917 echo
86e98048 1918 done
9975d7be
BP
1919 done
1920done
fcde56f5 1921
0bac7164
BP
1922# Check the MAC bindings against those expected.
1923AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
1924])
1925
fcde56f5 1926# Gracefully terminate daemons
eff49a56
LR
1927for sim in hv1 hv2 hv3; do
1928 as $sim
1929 OVS_APP_EXIT_AND_WAIT([ovn-controller])
1930 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
1931 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
fcde56f5 1932done
eff49a56
LR
1933
1934as ovn-sb
1935OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1936
1937as ovn-nb
1938OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1939
1940as northd
1941OVS_APP_EXIT_AND_WAIT([ovn-northd])
1942
1943as main
1944OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
1945OVS_APP_EXIT_AND_WAIT([ovsdb-server])
1946
9975d7be 1947AT_CLEANUP
685f4dfe
NS
1948
1949# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1950AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
1951AT_KEYWORDS([portsecurity])
1952AT_SKIP_IF([test $HAVE_PYTHON = no])
1953ovn_start
1954
1955# Create hypervisors hv[123].
1956# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
1957# Add all of the vifs to a single logical switch lsw0.
1958# Turn off port security on vifs vif[123]1
1959# Turn on l2 port security on vifs vif[123]2
1960# Turn of l2 and l3 port security on vifs vif[123]3
1961# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 1962ovn-nbctl ls-add lsw0
685f4dfe
NS
1963net_add n1
1964for i in 1 2 3; do
1965 sim_add hv$i
1966 as hv$i
1967 ovs-vsctl add-br br-phys
1968 ovn_attach n1 br-phys 192.168.0.$i
1969
1970 for j in 1 2 3; do
1971 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
31ed1192 1972 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 1973 if test $j = 1; then
31ed1192 1974 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 1975 elif test $j = 2; then
31ed1192
JP
1976 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
1977 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
1978 else
1979 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
1980 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
1981 ovn-nbctl lsp-set-port-security lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
685f4dfe
NS
1982 fi
1983 done
1984done
1985
685f4dfe
NS
1986# Pre-populate the hypervisors' ARP tables so that we don't lose any
1987# packets for ARP resolution (native tunneling doesn't queue packets
1988# for ARP resolution).
1989ovn_populate_arp
1990
1991# Allow some time for ovn-northd and ovn-controller to catch up.
1992# XXX This should be more systematic.
1993sleep 1
685f4dfe
NS
1994
1995# Given the name of a logical port, prints the name of the hypervisor
1996# on which it is located.
1997vif_to_hv() {
1998 echo hv${1%?}
1999}
2000
2001
2002trim_zeros() {
2003 sed 's/\(00\)\{1,\}$//'
2004}
2005for i in 1 2 3; do
2006 for j in 1 2 3; do
2007 : > $i$j.expected
2008 done
2009done
2010
2011# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2012#
2013# This shell function causes an ip packet to be received on INPORT.
2014# The packet's content has Ethernet destination DST and source SRC
2015# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2016# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2017# be received. INPORT and the OUTPORTs are specified as logical switch
2018# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2019test_ip() {
2020 # This packet has bad checksums but logical L3 routing doesn't check.
2021 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2022 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}003511110008
2023 shift; shift; shift; shift; shift
2024 hv=`vif_to_hv $inport`
2025 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2026 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2027 for outport; do
2028 echo $packet | trim_zeros >> $outport.expected
2029 done
2030}
2031
2032# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2033#
2034# Causes a packet to be received on INPORT. The packet is an ARP
2035# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2036# it should be the hardware address of the target to expect to receive in an
2037# ARP reply; otherwise no reply is expected.
2038#
31ed1192 2039# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2040# SHA and REPLY_HA are each 12 hex digits.
2041# SPA and TPA are each 8 hex digits.
2042test_arp() {
2043 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2044 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2045 hv=`vif_to_hv $inport`
2046 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2047 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2048 if test $drop != 1; then
2049 if test X$reply_ha == X; then
2050 # Expect to receive the broadcast ARP on the other logical switch ports
2051 # if no reply is expected.
2052 local i j
2053 for i in 1 2 3; do
2054 for j in 1 2 3; do
2055 if test $i$j != $inport; then
2056 echo $request >> $i$j.expected
2057 fi
2058 done
2059 done
2060 else
2061 # Expect to receive the reply, if any.
2062 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2063 echo $reply >> $inport.expected
2064 fi
2065 fi
2066}
2067
2068# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2069# This function is similar to test_ip() except that it sends
2070# ipv6 packet
2071test_ipv6() {
2072 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2073 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2074 shift; shift; shift; shift; shift
2075 hv=`vif_to_hv $inport`
2076 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2077 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2078 for outport; do
2079 echo $packet | trim_zeros >> $outport.expected
2080 done
2081}
2082
9e687b23
DL
2083# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2084# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2085# of the test packet
2086test_icmpv6() {
2087 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2088 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2089 shift; shift; shift; shift; shift; shift
2090 hv=`vif_to_hv $inport`
2091 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2092 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2093 for outport; do
2094 echo $packet | trim_zeros >> $outport.expected
2095 done
2096}
2097
685f4dfe
NS
2098ip_to_hex() {
2099 printf "%02x%02x%02x%02x" "$@"
2100}
2101
2102# no port security
2103sip=`ip_to_hex 192 168 0 12`
2104tip=`ip_to_hex 192 168 0 13`
2105# the arp packet should be allowed even if lp[123]1 is
2106# not configured with mac f00000000023 and ip 192.168.0.12
2107for i in 1 2 3; do
2108 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2109 for j in 1 2 3; do
2110 if test $i != $j; then
2111 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2112 fi
2113 done
2114done
2115
2116# l2 port security
2117sip=`ip_to_hex 192 168 0 12`
2118tip=`ip_to_hex 192 168 0 13`
2119
2120# arp packet should be allowed since lp22 is configured with
2121# mac f00000000022
2122test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2123
2124# arp packet should not be allowed since lp32 is not configured with
2125# mac f00000000021
2126test_arp 32 f00000000021 f00000000021 $sip $tip 1
2127
2128# arp packet with sha set to f00000000021 should not be allowed
2129# for lp12
2130test_arp 12 f00000000012 f00000000021 $sip $tip 1
2131
2132# ip packets should be allowed and received since lp[123]2 do not
2133# have l3 port security
2134sip=`ip_to_hex 192 168 0 55`
2135tip=`ip_to_hex 192 168 0 66`
2136for i in 1 2 3; do
2137 for j in 1 2 3; do
2138 if test $i != $j; then
2139 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2140 fi
2141 done
2142done
2143
2144# ipv6 packets should be received by lp[123]2
2145# lp[123]1 can send ipv6 traffic as there is no port security
2146sip=fe800000000000000000000000000000
2147tip=ff020000000000000000000000000000
2148
2149for i in 1 2 3; do
2150 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2151done
2152
2153
2154# l2 and l3 port security
2155sip=`ip_to_hex 192 168 0 13`
2156tip=`ip_to_hex 192 168 0 22`
2157# arp packet should be allowed since lp13 is configured with
2158# f00000000013 and 192.168.0.13
2159test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2160
2161# the arp packet should be dropped because lp23 is not configured
2162# with mac f00000000022
2163sip=`ip_to_hex 192 168 0 13`
2164tip=`ip_to_hex 192 168 0 22`
2165test_arp 23 f00000000022 f00000000022 $sip $tip 1
2166
2167# the arp packet should be dropped because lp33 is not configured
2168# with ip 192.168.0.55
2169spa=`ip_to_hex 192 168 0 55`
2170tpa=`ip_to_hex 192 168 0 22`
2171test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2172
2173# ip packets should not be received by lp[123]3 since
2174# l3 port security is enabled
2175sip=`ip_to_hex 192 168 0 55`
2176tip=`ip_to_hex 192 168 0 66`
2177for i in 1 2 3; do
2178 for j in 1 2 3; do
2179 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2180 done
2181done
2182
2183# ipv6 packets should be dropped for lp[123]3 since
2184# it is configured with only ipv4 address
2185sip=fe800000000000000000000000000000
2186tip=ff020000000000000000000000000000
2187
2188for i in 1 2 3; do
2189 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2190done
2191
2192# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2193# lp[123]1 can send ipv6 traffic as there is no port security
2194for i in 1 2 3; do
2195 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2196done
2197
2198# lp13 has extra port security with mac f0000000113 and ipv6 addr
2199# fe80::ea2a:eaff:fe28:0012
2200
2201# ipv4 packet should be dropped for lp13 with mac f0000000113
2202sip=`ip_to_hex 192 168 0 13`
2203tip=`ip_to_hex 192 168 0 23`
2204test_ip 13 f00000000113 f00000000023 $sip $tip
2205
2206# ipv6 packet should be received by lp[123]3 with mac f0000000{i}{i}3
2207# and ip6.dst as fe80::ea2a:eaff:fe28:0{i}{i}3.
2208# lp11 can send ipv6 traffic as there is no port security
2209sip=ee800000000000000000000000000000
2210for i in 1 2 3; do
2211 tip=fe80000000000000ea2aeafffe2800{i}3
2212 test_ipv6 11 f00000000011 f000000000{i}${i}3 $sip $tip {i}3
2213done
2214
2215
2216# ipv6 packet should not be received by lp33 with mac f0000000333
2217# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2218# configured with fe80::ea2a:eaff:fe28:0033
2219# lp11 can send ipv6 traffic as there is no port security
2220
2221sip=ee800000000000000000000000000000
2222tip=fe80000000000000ea2aeafffe280023
2223test_ipv6 11 f00000000011 f00000000333 $sip $tip
2224
2225# ipv6 packet should be allowed for lp[123]3 with mac f0000000{i}{i}3
2226# and ip6.src fe80::ea2a:eaff:fe28:0{i}{i}3 and ip6.src ::.
2227# and should be dropped for any other ip6.src
2228# lp21 can receive ipv6 traffic as there is no port security
2229
2230tip=ee800000000000000000000000000000
2231for i in 1 2 3; do
2232 sip=fe80000000000000ea2aeafffe2800${i}3
2233 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2234
9e687b23 2235 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 2236 sip=00000000000000000000000000000000
9e687b23
DL
2237 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2238 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2239 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2240 # Traffic to non-multicast traffic should be dropped
2241 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2242 # Traffic of other ICMPv6 types should be dropped
2243 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
2244
2245 # should be dropped
2246 sip=ae80000000000000ea2aeafffe2800aa
2247 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2248done
2249
31ed1192
JP
2250# configure lsp13 to send and received IPv4 packets with an address range
2251ovn-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"
7d9d86ad 2252
8ff5a966
NS
2253sleep 2
2254
7d9d86ad
NS
2255sip=`ip_to_hex 10 0 0 13`
2256tip=`ip_to_hex 192 168 0 22`
31ed1192 2257# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
2258test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2259
2260sip=`ip_to_hex 10 0 0 14`
2261tip=`ip_to_hex 192 168 0 23`
31ed1192 2262# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
2263# with dst ip 192.168.0.23 should be allowed
2264test_ip 13 f00000000013 f00000000023 $sip $tip 23
2265
2266sip=`ip_to_hex 192 168 0 33`
2267tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
2268# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2269# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
2270test_ip 33 f00000000033 f00000000013 $sip $tip 13
2271
2272sip=`ip_to_hex 192 168 0 33`
2273tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
2274# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2275# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
2276test_ip 33 f00000000033 f00000000013 $sip $tip 13
2277
2278sip=`ip_to_hex 192 168 0 33`
2279tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
2280# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2281# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
2282test_ip 33 f00000000033 f00000000013 $sip $tip
2283
2284sip=`ip_to_hex 192 168 0 33`
2285tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
2286# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2287# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
2288test_ip 33 f00000000033 f00000000013 $sip $tip 13
2289
2290sip=`ip_to_hex 192 168 0 33`
2291tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
2292# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2293# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
2294test_ip 33 f00000000033 f00000000013 $sip $tip
2295
2296sip=`ip_to_hex 192 168 0 33`
2297tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
2298# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2299# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 2300test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe
NS
2301
2302# Allow some time for packet forwarding.
2303
2304# XXX This can be improved.
2305sleep 1
2306
bb0c41d3
RM
2307#dump information including flow counters
2308ovn-nbctl show
2309ovn-sbctl dump-flows -- list multicast_group
2310
2311echo "------ hv1 dump ------"
2312as hv1 ovs-vsctl show
6195e2e7 2313as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2314as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2315
2316echo "------ hv2 dump ------"
2317as hv2 ovs-vsctl show
6195e2e7 2318as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2319as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2320
2321echo "------ hv3 dump ------"
2322as hv3 ovs-vsctl show
6195e2e7 2323as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2324as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2325
685f4dfe
NS
2326# Now check the packets actually received against the ones expected.
2327for i in 1 2 3; do
2328 for j in 1 2 3; do
2329 file=hv$i/vif$i$j-tx.pcap
2330 echo $file
2331 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i$j.packets
2332 sort $i$j.expected > expout
2333 AT_CHECK([sort $i$j.packets], [0], [expout])
2334 echo
2335 done
2336done
2337
2338# Gracefully terminate daemons
d9c8c57c
LR
2339for sim in hv1 hv2 hv3; do
2340 as $sim
2341 OVS_APP_EXIT_AND_WAIT([ovn-controller])
2342 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2343 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
685f4dfe 2344done
d9c8c57c
LR
2345
2346as ovn-sb
2347OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2348
2349as ovn-nb
2350OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2351
2352as northd
2353OVS_APP_EXIT_AND_WAIT([ovn-northd])
2354
2355as main
2356OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2357OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2358
685f4dfe 2359AT_CLEANUP
509afdc3
GS
2360
2361AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
2362AT_KEYWORDS([ovnpeer])
2363AT_SKIP_IF([test $HAVE_PYTHON = no])
2364ovn_start
2365
2366# Logical network:
2367# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2368# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2369# R2 has ls2 (172.16.1.0/24) connected to it.
2370
fa2a27b2
JP
2371ovn-nbctl lr-add R1
2372ovn-nbctl lr-add R2
509afdc3 2373
ea46a4e9
JP
2374ovn-nbctl ls-add ls1
2375ovn-nbctl ls-add ls2
509afdc3
GS
2376
2377# Connect ls1 to R1
31114af7 2378ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 rp-ls1
509afdc3 2379
31ed1192 2380ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 2381 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
509afdc3
GS
2382
2383# Connect ls2 to R2
31114af7 2384ovn-nbctl lrp-add R2 ls2 00:00:00:01:02:04 172.16.1.1/24 rp-ls2
509afdc3 2385
31ed1192 2386ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 2387 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
509afdc3
GS
2388
2389# Connect R1 to R2
31114af7
JP
2390ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 R2_R1
2391ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 R1_R2
509afdc3
GS
2392
2393ovn-nbctl set Logical_Router R1 default_gw="20.0.0.2"
2394ovn-nbctl set Logical_Router R2 default_gw="20.0.0.1"
2395
2396# Create logical port ls1-lp1 in ls1
31ed1192
JP
2397ovn-nbctl lsp-add ls1 ls1-lp1 \
2398-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
509afdc3
GS
2399
2400# Create logical port ls2-lp1 in ls2
31ed1192
JP
2401ovn-nbctl lsp-add ls2 ls2-lp1 \
2402-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
509afdc3
GS
2403
2404# Create two hypervisor and create OVS ports corresponding to logical ports.
2405net_add n1
2406
2407sim_add hv1
2408as hv1
2409ovs-vsctl add-br br-phys
2410ovn_attach n1 br-phys 192.168.0.1
2411ovs-vsctl -- add-port br-int hv1-vif1 -- \
2412 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2413 options:tx_pcap=hv1/vif1-tx.pcap \
2414 options:rxq_pcap=hv1/vif1-rx.pcap \
2415 ofport-request=1
2416
2417sim_add hv2
2418as hv2
2419ovs-vsctl add-br br-phys
2420ovn_attach n1 br-phys 192.168.0.2
2421ovs-vsctl -- add-port br-int hv2-vif1 -- \
2422 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
2423 options:tx_pcap=hv2/vif1-tx.pcap \
2424 options:rxq_pcap=hv2/vif1-rx.pcap \
2425 ofport-request=1
2426
2427
2428# Pre-populate the hypervisors' ARP tables so that we don't lose any
2429# packets for ARP resolution (native tunneling doesn't queue packets
2430# for ARP resolution).
2431ovn_populate_arp
2432
2433# Allow some time for ovn-northd and ovn-controller to catch up.
2434# XXX This should be more systematic.
2435sleep 1
2436
2437# Send ip packets between the two ports.
2438ip_to_hex() {
2439 printf "%02x%02x%02x%02x" "$@"
2440}
2441trim_zeros() {
2442 sed 's/\(00\)\{1,\}$//'
2443}
2444
2445# Packet to send.
2446src_mac="f00000010203"
2447dst_mac="000000010203"
2448src_ip=`ip_to_hex 192 168 1 2`
2449dst_ip=`ip_to_hex 172 16 1 2`
2450packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2451as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2452
2453
2454echo "---------NB dump-----"
2455ovn-nbctl show
2456echo "---------------------"
2457ovn-nbctl list logical_router
2458echo "---------------------"
2459ovn-nbctl list logical_router_port
2460echo "---------------------"
2461
2462echo "---------SB dump-----"
2463ovn-sbctl list datapath_binding
2464echo "---------------------"
2465ovn-sbctl list port_binding
2466echo "---------------------"
2467
2468echo "------ hv1 dump ----------"
8dab1022 2469as hv1 ovs-ofctl show br-int
509afdc3
GS
2470as hv1 ovs-ofctl dump-flows br-int
2471echo "------ hv2 dump ----------"
8dab1022 2472as hv2 ovs-ofctl show br-int
509afdc3
GS
2473as hv2 ovs-ofctl dump-flows br-int
2474
2475# Packet to Expect
2476src_mac="000000010204"
2477dst_mac="f00000010204"
2478expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
2479
2480$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap | trim_zeros > received.packets
2481echo $expected | trim_zeros > expout
2482AT_CHECK([cat received.packets], [0], [expout])
2483
2484for sim in hv1 hv2; do
2485 as $sim
2486 OVS_APP_EXIT_AND_WAIT([ovn-controller])
2487 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2488 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2489done
2490
2491as ovn-sb
2492OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2493
2494as ovn-nb
2495OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2496
2497as northd
2498OVS_APP_EXIT_AND_WAIT([ovn-northd])
2499
2500as main
2501OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2502OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2503
2504AT_CLEANUP
5412db30
J
2505
2506
2507AT_SETUP([ovn -- 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
2508AT_KEYWORDS([router-admin-state])
2509AT_SKIP_IF([test $HAVE_PYTHON = no])
2510ovn_start
2511
2512# Logical network:
2513# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
2514# and has switch ls2 (172.16.1.0/24) connected to it.
2515
fa2a27b2 2516ovn-nbctl lr-add R1
5412db30 2517
ea46a4e9
JP
2518ovn-nbctl ls-add ls1
2519ovn-nbctl ls-add ls2
5412db30
J
2520
2521# Connect ls1 to R1
31114af7 2522ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 rp-ls1
31ed1192 2523ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 2524 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
2525
2526# Connect ls2 to R1
31114af7 2527ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24 rp-ls2
31ed1192 2528ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 2529 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
2530
2531# Create logical port ls1-lp1 in ls1
31ed1192
JP
2532ovn-nbctl lsp-add ls1 ls1-lp1 \
2533-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
2534
2535# Create logical port ls2-lp1 in ls2
31ed1192
JP
2536ovn-nbctl lsp-add ls2 ls2-lp1 \
2537-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
2538
2539# Create one hypervisor and create OVS ports corresponding to logical ports.
2540net_add n1
2541
2542sim_add hv1
2543as hv1
2544ovs-vsctl add-br br-phys
2545ovn_attach n1 br-phys 192.168.0.1
2546ovs-vsctl -- add-port br-int vif1 -- \
2547 set interface vif1 external-ids:iface-id=ls1-lp1 \
2548 options:tx_pcap=hv1/vif1-tx.pcap \
2549 options:rxq_pcap=hv1/vif1-rx.pcap \
2550 ofport-request=1
2551
2552ovs-vsctl -- add-port br-int vif2 -- \
2553 set interface vif2 external-ids:iface-id=ls2-lp1 \
2554 options:tx_pcap=hv1/vif2-tx.pcap \
2555 options:rxq_pcap=hv1/vif2-rx.pcap \
2556 ofport-request=1
2557
2558
2559# Allow some time for ovn-northd and ovn-controller to catch up.
2560# XXX This should be more systematic.
2561sleep 1
2562
2563# Send ip packets between the two ports.
2564ip_to_hex() {
2565 printf "%02x%02x%02x%02x" "$@"
2566}
2567trim_zeros() {
2568 sed 's/\(00\)\{1,\}$//'
2569}
2570
2571# Packet to send.
2572src_mac="f00000010203"
2573dst_mac="000000010203"
2574src_ip=`ip_to_hex 192 168 1 2`
2575dst_ip=`ip_to_hex 172 16 1 2`
2576packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2577as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
2578
2579
2580echo "---------NB dump-----"
2581ovn-nbctl show
2582echo "---------------------"
2583ovn-nbctl list logical_router
2584echo "---------------------"
2585ovn-nbctl list logical_router_port
2586echo "---------------------"
2587
2588echo "---------SB dump-----"
2589ovn-sbctl list datapath_binding
2590echo "---------------------"
2591ovn-sbctl list logical_flow
2592echo "---------------------"
2593
2594echo "------ hv1 dump ----------"
2595as hv1 ovs-ofctl dump-flows br-int
2596
2597
2598#Disable router R1
2599ovn-nbctl set Logical_Router R1 enabled=false
2600
2601echo "---------SB dump-----"
2602ovn-sbctl list datapath_binding
2603echo "---------------------"
2604ovn-sbctl list logical_flow
2605echo "---------------------"
2606
2607echo "------ hv1 dump ----------"
2608as hv1 ovs-ofctl dump-flows br-int
2609
a1361a6e
LR
2610# Allow some time for the disabling of logical router R1 to propagate.
2611# XXX This should be more systematic.
2612sleep 1
2613
5412db30
J
2614as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
2615
2616# Packet to Expect
2617expect_src_mac="000000010204"
2618expect_dst_mac="f00000010204"
2619expected=${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
2620
2621$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > received.packets
2622echo $expected | trim_zeros > expout
2623AT_CHECK([cat received.packets], [0], [expout])
2624
2625
2626as hv1
2627OVS_APP_EXIT_AND_WAIT([ovn-controller])
2628OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2629OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2630
2631as ovn-sb
2632OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2633
2634as ovn-nb
2635OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2636
2637as northd
2638OVS_APP_EXIT_AND_WAIT([ovn-northd])
2639
2640as main
2641OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2642OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2643
2644AT_CLEANUP
2645
28dc3fe9
SR
2646AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
2647AT_KEYWORDS([ovnstaticroutespeer])
2648AT_SKIP_IF([test $HAVE_PYTHON = no])
2649ovn_start
2650
2651# Logical network:
2652# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2653# network. R1 has switchess foo (192.168.1.0/24)
2654# connected to it.
2655# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
2656
fa2a27b2
JP
2657ovn-nbctl lr-add R1
2658ovn-nbctl lr-add R2
28dc3fe9 2659
ea46a4e9
JP
2660ovn-nbctl ls-add foo
2661ovn-nbctl ls-add alice
2662ovn-nbctl ls-add bob
28dc3fe9
SR
2663
2664# Connect foo to R1
31114af7 2665ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24 rp-foo
31ed1192 2666ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 2667 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
2668
2669# Connect alice to R2
31114af7 2670ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24 rp-alice
31ed1192 2671ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 2672 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
2673
2674# Connect bob to R2
31114af7 2675ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24 rp-bob
31ed1192 2676ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 2677 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
2678
2679# Connect R1 to R2
31114af7
JP
2680ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 R2_R1
2681ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 R1_R2
28dc3fe9
SR
2682
2683#install static routes
e48ccf3c
JP
2684ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
2685ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
2686ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
2687
2688# Create logical port foo1 in foo
31ed1192
JP
2689ovn-nbctl lsp-add foo foo1 \
2690-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
2691
2692# Create logical port alice1 in alice
31ed1192
JP
2693ovn-nbctl lsp-add alice alice1 \
2694-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
2695
2696# Create logical port bob1 in bob
31ed1192
JP
2697ovn-nbctl lsp-add bob bob1 \
2698-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
2699
2700# Create two hypervisor and create OVS ports corresponding to logical ports.
2701net_add n1
2702
2703sim_add hv1
2704as hv1
2705ovs-vsctl add-br br-phys
2706ovn_attach n1 br-phys 192.168.0.1
2707ovs-vsctl -- add-port br-int hv1-vif1 -- \
2708 set interface hv1-vif1 external-ids:iface-id=foo1 \
2709 options:tx_pcap=hv1/vif1-tx.pcap \
2710 options:rxq_pcap=hv1/vif1-rx.pcap \
2711 ofport-request=1
2712
2713ovs-vsctl -- add-port br-int hv1-vif2 -- \
2714 set interface hv1-vif2 external-ids:iface-id=alice1 \
2715 options:tx_pcap=hv1/vif2-tx.pcap \
2716 options:rxq_pcap=hv1/vif2-rx.pcap \
2717 ofport-request=2
2718
2719sim_add hv2
2720as hv2
2721ovs-vsctl add-br br-phys
2722ovn_attach n1 br-phys 192.168.0.2
2723ovs-vsctl -- add-port br-int hv2-vif1 -- \
2724 set interface hv2-vif1 external-ids:iface-id=bob1 \
2725 options:tx_pcap=hv2/vif1-tx.pcap \
2726 options:rxq_pcap=hv2/vif1-rx.pcap \
2727 ofport-request=1
2728
2729
2730# Pre-populate the hypervisors' ARP tables so that we don't lose any
2731# packets for ARP resolution (native tunneling doesn't queue packets
2732# for ARP resolution).
2733ovn_populate_arp
2734
2735# Allow some time for ovn-northd and ovn-controller to catch up.
2736# XXX This should be more systematic.
2737sleep 1
2738
2739ip_to_hex() {
2740 printf "%02x%02x%02x%02x" "$@"
2741}
2742trim_zeros() {
2743 sed 's/\(00\)\{1,\}$//'
2744}
2745
2746# Send ip packets between foo1 and alice1
2747src_mac="f00000010203"
2748dst_mac="000000010203"
2749src_ip=`ip_to_hex 192 168 1 2`
2750dst_ip=`ip_to_hex 172 16 1 2`
2751packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2752as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2753
2754# Send ip packets between foo1 and bob1
2755src_mac="f00000010203"
2756dst_mac="000000010203"
2757src_ip=`ip_to_hex 192 168 1 2`
2758dst_ip=`ip_to_hex 172 16 2 2`
2759packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2760as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2761
2762echo "---------NB dump-----"
2763ovn-nbctl show
2764echo "---------------------"
2765ovn-nbctl list logical_router
2766echo "---------------------"
2767ovn-nbctl list logical_router_port
2768echo "---------------------"
2769
2770echo "---------SB dump-----"
2771ovn-sbctl list datapath_binding
2772echo "---------------------"
2773ovn-sbctl list port_binding
2774echo "---------------------"
2775
2776echo "------ hv1 dump ----------"
2777as hv1 ovs-ofctl dump-flows br-int
2778echo "------ hv2 dump ----------"
2779as hv2 ovs-ofctl dump-flows br-int
2780
2781# Packet to Expect at bob1
2782src_mac="000000010205"
2783dst_mac="f00000010205"
2784src_ip=`ip_to_hex 192 168 1 2`
2785dst_ip=`ip_to_hex 172 16 2 2`
2786expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
2787
2788$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap | trim_zeros > received.packets
2789echo $expected | trim_zeros > expout
2790AT_CHECK([cat received.packets], [0], [expout])
2791
2792# Packet to Expect at alice1
2793src_mac="000000010204"
2794dst_mac="f00000010204"
2795src_ip=`ip_to_hex 192 168 1 2`
2796dst_ip=`ip_to_hex 172 16 1 2`
2797expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
2798
2799$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > received1.packets
2800echo $expected | trim_zeros > expout
2801AT_CHECK([cat received1.packets], [0], [expout])
2802
2803for sim in hv1 hv2; do
2804 as $sim
2805 OVS_APP_EXIT_AND_WAIT([ovn-controller])
2806 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2807 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2808done
2809
2810as ovn-sb
2811OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2812
2813as ovn-nb
2814OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2815
2816as northd
2817OVS_APP_EXIT_AND_WAIT([ovn-northd])
2818
2819as main
2820OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2821OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2822
2823AT_CLEANUP
5412db30 2824
0ee8aaf6
RR
2825AT_SETUP([ovn -- send gratuitous arp on localnet])
2826AT_KEYWORDS([ovn])
2827ovn_start
ea46a4e9 2828ovn-nbctl ls-add lsw0
0ee8aaf6
RR
2829net_add n1
2830sim_add hv
2831as hv
2832ovs-vsctl \
2833 -- add-br br-phys \
2834 -- add-br br-eth0
2835
2836ovn_attach n1 br-phys 192.168.0.1
2837
2838AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
2839AT_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])
2840
2841# Create a vif.
31ed1192
JP
2842AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
2843AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
2844AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
2845
2846# Create a localnet port.
31ed1192
JP
2847AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
2848AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
2849AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
2850AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
2851
2852AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
2853
2854# Wait for packet to be received.
2855OVS_WAIT_UNTIL([test `wc -c < "hv/snoopvif-tx.pcap"` -ge 50])
2856trim_zeros() {
2857 sed 's/\(00\)\{1,\}$//'
2858}
2859$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv/snoopvif-tx.pcap | trim_zeros > packets
2860expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102"
2861echo $expected > expout
2862AT_CHECK([sort packets], [0], [expout])
2863cat packets
2864
2865# Delete the localnet ports.
2866AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 2867AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6
RR
2868
2869as hv
2870OVS_APP_EXIT_AND_WAIT([ovn-controller])
2871OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2872OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2873
2874as ovn-sb
2875OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2876
2877as ovn-nb
2878OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2879
2880as northd
2881OVS_APP_EXIT_AND_WAIT([ovn-northd])
2882
2883as main
2884OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2885OVS_APP_EXIT_AND_WAIT([ovsdb-server])
2886
2887AT_CLEANUP
75cf9d2b
GS
2888
2889AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
2890AT_KEYWORDS([ovnstaticroutes])
2891AT_SKIP_IF([test $HAVE_PYTHON = no])
2892ovn_start
2893
2894# Logical network:
2895# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
2896# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
2897# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
2898# connected to it.
2899
fa2a27b2
JP
2900ovn-nbctl lr-add R1
2901ovn-nbctl lr-add R2
2902ovn-nbctl lr-add R3
75cf9d2b 2903
ea46a4e9
JP
2904ovn-nbctl ls-add foo
2905ovn-nbctl ls-add alice
2906ovn-nbctl ls-add bob
2907ovn-nbctl ls-add join
75cf9d2b
GS
2908
2909# Connect foo to R1
31114af7 2910ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 2911ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 2912 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
2913
2914# Connect alice to R2
31114af7 2915ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 2916ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 2917 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
2918
2919# Connect bob to R3
31114af7 2920ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 2921ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 2922 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
2923
2924# Connect R1 to join
31114af7 2925ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 2926ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 2927 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
2928
2929# Connect R2 to join
31114af7 2930ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 2931ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 2932 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
2933
2934# Connect R3 to join
31114af7 2935ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 2936ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 2937 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
2938
2939#install static routes
e48ccf3c
JP
2940ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
2941ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 2942
e48ccf3c
JP
2943ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
2944ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 2945
e48ccf3c
JP
2946ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
2947ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
2948
2949# Create logical port foo1 in foo
31ed1192
JP
2950ovn-nbctl lsp-add foo foo1 \
2951-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
2952
2953# Create logical port alice1 in alice
31ed1192
JP
2954ovn-nbctl lsp-add alice alice1 \
2955-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
2956
2957# Create logical port bob1 in bob
31ed1192
JP
2958ovn-nbctl lsp-add bob bob1 \
2959-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
2960
2961# Create two hypervisor and create OVS ports corresponding to logical ports.
2962net_add n1
2963
2964sim_add hv1
2965as hv1
2966ovs-vsctl add-br br-phys
2967ovn_attach n1 br-phys 192.168.0.1
2968ovs-vsctl -- add-port br-int hv1-vif1 -- \
2969 set interface hv1-vif1 external-ids:iface-id=foo1 \
2970 options:tx_pcap=hv1/vif1-tx.pcap \
2971 options:rxq_pcap=hv1/vif1-rx.pcap \
2972 ofport-request=1
2973
2974ovs-vsctl -- add-port br-int hv1-vif2 -- \
2975 set interface hv1-vif2 external-ids:iface-id=alice1 \
2976 options:tx_pcap=hv1/vif2-tx.pcap \
2977 options:rxq_pcap=hv1/vif2-rx.pcap \
2978 ofport-request=2
2979
2980sim_add hv2
2981as hv2
2982ovs-vsctl add-br br-phys
2983ovn_attach n1 br-phys 192.168.0.2
2984ovs-vsctl -- add-port br-int hv2-vif1 -- \
2985 set interface hv2-vif1 external-ids:iface-id=bob1 \
2986 options:tx_pcap=hv2/vif1-tx.pcap \
2987 options:rxq_pcap=hv2/vif1-rx.pcap \
2988 ofport-request=1
2989
2990
2991# Pre-populate the hypervisors' ARP tables so that we don't lose any
2992# packets for ARP resolution (native tunneling doesn't queue packets
2993# for ARP resolution).
2994ovn_populate_arp
2995
2996# Allow some time for ovn-northd and ovn-controller to catch up.
2997# XXX This should be more systematic.
2998sleep 1
2999
3000ip_to_hex() {
3001 printf "%02x%02x%02x%02x" "$@"
3002}
3003trim_zeros() {
3004 sed 's/\(00\)\{1,\}$//'
3005}
3006
3007# Send ip packets between foo1 and alice1
3008src_mac="f00000010203"
3009dst_mac="000001010203"
3010src_ip=`ip_to_hex 192 168 1 2`
3011dst_ip=`ip_to_hex 172 16 1 2`
3012packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3013as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3014as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3015
3016# Send ip packets between foo1 and bob1
3017src_mac="f00000010203"
3018dst_mac="000001010203"
3019src_ip=`ip_to_hex 192 168 1 2`
3020dst_ip=`ip_to_hex 10 32 1 2`
3021packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3022as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3023
3024echo "---------NB dump-----"
3025ovn-nbctl show
3026echo "---------------------"
3027ovn-nbctl list logical_router
3028echo "---------------------"
3029ovn-nbctl list logical_router_port
3030echo "---------------------"
3031
3032echo "---------SB dump-----"
3033ovn-sbctl list datapath_binding
3034echo "---------------------"
3035ovn-sbctl list port_binding
3036echo "---------------------"
3037ovn-sbctl dump-flows
3038echo "---------------------"
3039
3040echo "------ hv1 dump ----------"
3041as hv1 ovs-ofctl show br-int
3042as hv1 ovs-ofctl dump-flows br-int
3043echo "------ hv2 dump ----------"
3044as hv2 ovs-ofctl show br-int
3045as hv2 ovs-ofctl dump-flows br-int
3046echo "----------------------------"
3047
3048# Packet to Expect at bob1
3049src_mac="000003010203"
3050dst_mac="f00000010205"
3051src_ip=`ip_to_hex 192 168 1 2`
3052dst_ip=`ip_to_hex 10 32 1 2`
3053expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
3054
3055$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap | trim_zeros > received.packets
3056echo $expected | trim_zeros > expout
3057AT_CHECK([cat received.packets], [0], [expout])
3058
3059# Packet to Expect at alice1
3060src_mac="000002010203"
3061dst_mac="f00000010204"
3062src_ip=`ip_to_hex 192 168 1 2`
3063dst_ip=`ip_to_hex 172 16 1 2`
3064expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
3065
3066$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > received1.packets
3067echo $expected | trim_zeros > expout
3068AT_CHECK([cat received1.packets], [0], [expout])
3069
3070for sim in hv1 hv2; do
3071 as $sim
3072 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3073 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3074 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3075done
3076
3077as ovn-sb
3078OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3079
3080as ovn-nb
3081OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3082
3083as northd
3084OVS_APP_EXIT_AND_WAIT([ovn-northd])
3085
3086as main
3087OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3088OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3089
3090AT_CLEANUP
c1645003 3091
c1645003
GS
3092AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
3093AT_KEYWORDS([ovngatewayrouter])
3094AT_SKIP_IF([test $HAVE_PYTHON = no])
3095ovn_start
3096
3097# Logical network:
3098# Two LRs - R1 and R2 that are connected to each other via LS "join"
3099# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3100# connected to it. R2 has alice (172.16.1.0/24) connected to it.
3101# R2 is a gateway router.
3102
3103
3104
3105# Create two hypervisor and create OVS ports corresponding to logical ports.
3106net_add n1
3107
3108sim_add hv1
3109as hv1
3110ovs-vsctl add-br br-phys
3111ovn_attach n1 br-phys 192.168.0.1
3112ovs-vsctl -- add-port br-int hv1-vif1 -- \
3113 set interface hv1-vif1 external-ids:iface-id=foo1 \
3114 options:tx_pcap=hv1/vif1-tx.pcap \
3115 options:rxq_pcap=hv1/vif1-rx.pcap \
3116 ofport-request=1
3117
3118
3119sim_add hv2
3120as hv2
3121ovs-vsctl add-br br-phys
3122ovn_attach n1 br-phys 192.168.0.2
3123ovs-vsctl -- add-port br-int hv2-vif1 -- \
3124 set interface hv2-vif1 external-ids:iface-id=alice1 \
3125 options:tx_pcap=hv2/vif1-tx.pcap \
3126 options:rxq_pcap=hv2/vif1-rx.pcap \
3127 ofport-request=1
3128
3129# Pre-populate the hypervisors' ARP tables so that we don't lose any
3130# packets for ARP resolution (native tunneling doesn't queue packets
3131# for ARP resolution).
3132ovn_populate_arp
3133
3134ovn-nbctl create Logical_Router name=R1
3135ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
3136
ea46a4e9
JP
3137ovn-nbctl ls-add foo
3138ovn-nbctl ls-add alice
3139ovn-nbctl ls-add join
c1645003
GS
3140
3141# Connect foo to R1
31114af7 3142ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3143ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 3144 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
3145
3146# Connect alice to R2
31114af7 3147ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3148ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3149 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
3150
3151# Connect R1 to join
31114af7 3152ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3153ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3154 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
3155
3156# Connect R2 to join
31114af7 3157ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3158ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3159 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
3160
3161
3162#install static routes
3163ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
3164ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
3165R1 static_routes @lrt
3166
3167ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
3168ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
3169R2 static_routes @lrt
3170
3171# Create logical port foo1 in foo
31ed1192
JP
3172ovn-nbctl lsp-add foo foo1 \
3173-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
3174
3175# Create logical port alice1 in alice
31ed1192
JP
3176ovn-nbctl lsp-add alice alice1 \
3177-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
3178
3179
3180# Allow some time for ovn-northd and ovn-controller to catch up.
3181# XXX This should be more systematic.
3182sleep 2
3183
3184ip_to_hex() {
3185 printf "%02x%02x%02x%02x" "$@"
3186}
3187trim_zeros() {
3188 sed 's/\(00\)\{1,\}$//'
3189}
3190
3191# Send ip packets between foo1 and alice1
3192src_mac="f00000010203"
3193dst_mac="000001010203"
3194src_ip=`ip_to_hex 192 168 1 2`
3195dst_ip=`ip_to_hex 172 16 1 2`
3196packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3197
3198echo "---------NB dump-----"
3199ovn-nbctl show
3200echo "---------------------"
3201ovn-nbctl list logical_router
3202echo "---------------------"
3203ovn-nbctl list logical_router_port
3204echo "---------------------"
3205
3206echo "---------SB dump-----"
3207ovn-sbctl list datapath_binding
3208echo "---------------------"
3209ovn-sbctl list port_binding
3210echo "---------------------"
3211ovn-sbctl dump-flows
3212echo "---------------------"
3213ovn-sbctl list chassis
3214ovn-sbctl list encap
3215echo "---------------------"
3216
3217echo "------ hv1 dump ----------"
3218as hv1 ovs-ofctl show br-int
3219as hv1 ovs-ofctl dump-flows br-int
3220echo "------ hv2 dump ----------"
3221as hv2 ovs-ofctl show br-int
3222as hv2 ovs-ofctl dump-flows br-int
3223echo "----------------------------"
3224
3225# Packet to Expect at alice1
3226src_mac="000002010203"
3227dst_mac="f00000010204"
3228src_ip=`ip_to_hex 192 168 1 2`
3229dst_ip=`ip_to_hex 172 16 1 2`
3230expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
3231
3232
3233as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3234as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3235
3236$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/vif1-tx.pcap | trim_zeros > received1.packets
3237echo $expected | trim_zeros > expout
3238AT_CHECK([cat received1.packets], [0], [expout])
3239
3240for sim in hv1 hv2; do
3241 as $sim
3242 OVS_APP_EXIT_AND_WAIT([ovn-controller])
3243 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3244 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3245done
3246
3247as ovn-sb
3248OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3249
3250as ovn-nb
3251OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3252
3253as northd
3254OVS_APP_EXIT_AND_WAIT([ovn-northd])
3255
3256as main
3257OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3258OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3259
3260AT_CLEANUP
bb3c4568
FF
3261
3262AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
3263AT_KEYWORDS([router-icmp-reply])
3264AT_SKIP_IF([test $HAVE_PYTHON = no])
3265ovn_start
3266
3267# Logical network:
3268# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3269# and has switch ls2 (172.16.1.0/24) connected to it.
3270
fa2a27b2 3271ovn-nbctl lr-add R1
bb3c4568 3272
ea46a4e9
JP
3273ovn-nbctl ls-add ls1
3274ovn-nbctl ls-add ls2
bb3c4568
FF
3275
3276# Connect ls1 to R1
31114af7 3277ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 3278ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 3279 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
3280
3281# Connect ls2 to R1
31114af7 3282ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 3283ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 3284 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
3285
3286# Create logical port ls1-lp1 in ls1
31ed1192
JP
3287ovn-nbctl lsp-add ls1 ls1-lp1 \
3288-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
3289
3290# Create logical port ls2-lp1 in ls2
31ed1192
JP
3291ovn-nbctl lsp-add ls2 ls2-lp1 \
3292-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
3293
3294# Create one hypervisor and create OVS ports corresponding to logical ports.
3295net_add n1
3296
3297sim_add hv1
3298as hv1
3299ovs-vsctl add-br br-phys
3300ovn_attach n1 br-phys 192.168.0.1
3301ovs-vsctl -- add-port br-int vif1 -- \
3302 set interface vif1 external-ids:iface-id=ls1-lp1 \
3303 options:tx_pcap=hv1/vif1-tx.pcap \
3304 options:rxq_pcap=hv1/vif1-rx.pcap \
3305 ofport-request=1
3306
3307ovs-vsctl -- add-port br-int vif2 -- \
3308 set interface vif2 external-ids:iface-id=ls2-lp1 \
3309 options:tx_pcap=hv1/vif2-tx.pcap \
3310 options:rxq_pcap=hv1/vif2-rx.pcap \
3311 ofport-request=1
3312
3313
3314# Allow some time for ovn-northd and ovn-controller to catch up.
3315# XXX This should be more systematic.
3316sleep 1
3317
3318
3319ip_to_hex() {
3320 printf "%02x%02x%02x%02x" "$@"
3321}
3322trim_zeros() {
3323 sed 's/\(00\)\{1,\}$//'
3324}
3325for i in 1 2; do
3326 : > vif$i.expected
3327done
3328# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
3329#
3330# Causes a packet to be received on INPORT. The packet is an ICMPv4
3331# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
3332# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
3333# provided, then it should be the ip and icmp checksums of the packet
3334# responded; otherwise, no reply is expected.
3335# In the absence of an ip checksum calculation helpers, this relies
3336# on the caller to provide the checksums for the ip and icmp headers.
3337# XXX This should be more systematic.
3338#
3339# INPORT is an lport number, e.g. 11 for vif11.
3340# ETH_SRC and ETH_DST are each 12 hex digits.
3341# IPV4_SRC and IPV4_DST are each 8 hex digits.
3342# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
3343# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
3344test_ipv4_icmp_request() {
3345 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
3346 local exp_ip_chksum=$8 exp_icmp_chksum=$9
3347 shift; shift; shift; shift; shift; shift; shift
3348 shift; shift
3349
3350 # Use ttl to exercise section 4.2.2.9 of RFC1812
3351 local ip_ttl=01
3352 local icmp_id=5fbf
3353 local icmp_seq=0001
3354 local icmp_data=$(seq 1 56 | xargs printf "%02x")
3355 local icmp_type_code_request=0800
3356 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
3357 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
3358
3359 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
3360 if test X$exp_icmp_chksum != X; then
3361 # Expect to receive the reply, if any. In same port where packet was sent.
3362 # Note: src and dst fields are expected to be reversed.
3363 local icmp_type_code_response=0000
3364 local reply_icmp_ttl=fe
3365 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
3366 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
3367 echo $reply >> vif$inport.expected
3368 fi
3369}
3370
3371# Send ping packet to router's ip addresses, from each of the 2 logical ports.
3372rtr_l1_ip=$(ip_to_hex 192 168 1 1)
3373rtr_l2_ip=$(ip_to_hex 172 16 1 1)
3374l1_ip=$(ip_to_hex 192 168 1 2)
3375l2_ip=$(ip_to_hex 172 16 1 2)
3376
3377# Ping router ip address that is on same subnet as the logical port
3378test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
3379test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
3380
3381# Ping router ip address that is on the other side of the logical ports
3382test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
3383test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
3384
3385echo "---------NB dump-----"
3386ovn-nbctl show
3387echo "---------------------"
3388ovn-nbctl list logical_router
3389echo "---------------------"
3390ovn-nbctl list logical_router_port
3391echo "---------------------"
3392
3393echo "---------SB dump-----"
3394ovn-sbctl list datapath_binding
3395echo "---------------------"
3396ovn-sbctl list logical_flow
3397echo "---------------------"
3398
3399echo "------ hv1 dump ----------"
3400as hv1 ovs-ofctl dump-flows br-int
3401
3402# Now check the packets actually received against the ones expected.
3403for inport in 1 2; do
3404 file=hv1/vif${inport}-tx.pcap
3405 echo $file
3406 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > received.packets
3407 cat vif$inport.expected | trim_zeros > expout
3408 AT_CHECK([cat received.packets], [0], [expout])
3409done
3410
3411as hv1
3412OVS_APP_EXIT_AND_WAIT([ovn-controller])
3413OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3414OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3415
3416as ovn-sb
3417OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3418
3419as ovn-nb
3420OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3421
3422as northd
3423OVS_APP_EXIT_AND_WAIT([ovn-northd])
3424
3425as main
3426OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3427OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3428
3429AT_CLEANUP
94f79fcb
RB
3430
3431# 1 hypervisor, 1 port
3432# make sure that the port state is properly set to up and back down
3433# when created and deleted.
3434AT_SETUP([ovn -- port state up and down])
3435AT_KEYWORDS([ovn])
3436ovn_start
3437
3438ovn-nbctl ls-add ls1
3439ovn-nbctl lsp-add ls1 lp1
3440ovn-nbctl lsp-set-addresses lp1 unknown
3441
3442net_add n1
3443sim_add hv1
3444as hv1 ovs-vsctl add-br br-phys
3445as hv1 ovn_attach n1 br-phys 192.168.0.1
3446
3447as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
3448OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
3449
3450as hv1 ovs-vsctl del-port br-int vif1
3451OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
3452
3453as hv1
3454OVS_APP_EXIT_AND_WAIT([ovn-controller])
3455OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3456OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3457
3458as ovn-sb
3459OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3460
3461as ovn-nb
3462OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3463
3464as northd
3465OVS_APP_EXIT_AND_WAIT([ovn-northd])
3466
3467as main
3468OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3469OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3470AT_CLEANUP
e75451fe
ZKL
3471
3472AT_SETUP([ovn -- nd ])
3473AT_KEYWORDS([ovn-nd])
3474AT_SKIP_IF([test $HAVE_PYTHON = no])
3475ovn_start
3476
3477#TODO: since patch port for IPv6 logical router port is not ready not,
3478# so we are not going to test vifs on different lswitches cases. Try
3479# to update for that once relevant stuff implemented.
3480
3481# In this test cases we create 1 lswitch, it has 2 VIF ports attached
3482# with. NS packet we test, from one VIF for another VIF, will be replied
3483# by local ovn-controller, but not by target VIF.
3484
3485# Create hypervisors and logical switch lsw0.
3486ovn-nbctl ls-add lsw0
3487net_add n1
3488sim_add hv1
3489as hv1
3490ovs-vsctl add-br br-phys
3491ovn_attach n1 br-phys 192.168.0.2
3492
3493# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
3494ovs-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
3495ovn-nbctl lsp-add lsw0 lp1
3496ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
3497ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
3498
3499# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
3500ovs-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
3501ovn-nbctl lsp-add lsw0 lp2
3502ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
3503ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
3504
3505# Add ACL rule for ICMPv6 on lsw0
3506ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
3507ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
3508ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
3509
3510# Allow some time for ovn-northd and ovn-controller to catch up.
3511# XXX This should be more systematic.
3512sleep 1
3513
3514# Given the name of a logical port, prints the name of the hypervisor
3515# on which it is located.
3516vif_to_hv() {
3517 echo hv1${1%?}
3518}
3519trim_zeros() {
3520 sed 's/\(00\)\{1,\}$//'
3521}
3522for i in 1 2; do
3523 : > $i.expected
3524done
3525
3526# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
3527# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
3528# vif2 will not receive NS packet, since ovn-controller will reply for it.
3529ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
3530na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
3531
3532as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
3533echo $na_packet | trim_zeros >> 1.expected
3534
3535sleep 1
3536
3537echo "------ hv1 dump ------"
3538as hv1 ovs-vsctl show
3539as hv1 ovs-ofctl -O OpenFlow13 show br-int
3540as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3541
3542for i in 1 2; do
3543 file=hv1/vif$i-tx.pcap
3544 echo $file
3545 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $file | trim_zeros > $i.packets
3546 cat $i.expected > expout
3547 AT_CHECK([cat $i.packets], [0], [expout])
3548done
3549
3550as hv1
3551OVS_APP_EXIT_AND_WAIT([ovn-controller])
3552OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3553OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3554
3555as ovn-sb
3556OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3557
3558as ovn-nb
3559OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3560
3561as northd
3562OVS_APP_EXIT_AND_WAIT([ovn-northd])
3563
3564as main
3565OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3566OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3567
3568AT_CLEANUP