]> git.proxmox.com Git - mirror_ovs.git/blame - tests/ovn.at
expr: Fix abort when simplifying "x != 0/0".
[mirror_ovs.git] / tests / ovn.at
CommitLineData
49d7c759
BP
1# OVN_CHECK_PACKETS([PCAP], [EXPECTED])
2#
3# This compares packets read from PCAP, in pcap format, to those read
4# from EXPECTED, which is a text file containing packets as hex
5# strings, one per line. If PCAP contains fewer packets than
6# EXPECTED, it waits up to 10 seconds for more packets to appear.
7#
8# The implementation is an m4 macro that is mostly implemented in
9# terms of a shell function. This reduces the size of the generated
10# testsuite file since the shell function is only emitted once even
11# when this macro is invoked many times.
12m4_divert_text([PREPARE_TESTS],
13 [ovn_check_packets__ () {
14 echo
15 echo "checking packets in $1 against $2:"
16 rcv_pcap=$1
17 rcv_text=`echo "$rcv_pcap.packets" | sed 's/\.pcap//'`
18 exp_text=$2
19 exp_n=`wc -l < "$exp_text"`
20 ovs_wait_cond () {
abb37b6b
FF
21 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $rcv_pcap > $rcv_text
22 rcv_n=`wc -l < "$rcv_text"`
23 test $rcv_n -ge $exp_n
49d7c759
BP
24 }
25 ovs_wait || echo "expected $exp_n packets, only received $rcv_n"
26
e4543cfe 27 sort $exp_text > expout
49d7c759
BP
28 }
29])
30m4_define([OVN_CHECK_PACKETS],
31 [ovn_check_packets__ "$1" "$2"
32 AT_CHECK([sort $rcv_text], [0], [expout])])
33
f295c17b 34AT_BANNER([OVN components])
10b1662b
BP
35
36AT_SETUP([ovn -- lexer])
37dnl For lines without =>, input and expected output are identical.
38dnl For lines with =>, input precedes => and expected output follows =>.
39AT_DATA([test-cases.txt], [dnl
40foo bar baz quuxquuxquux _abcd_ a.b.c.d a123_.456
41"abc\u0020def" => "abc def"
42" => error("Input ends inside quoted string.")dnl "
43
2c5cbb15
RB
44$foo $bar $baz $quuxquuxquux $_abcd_ $a.b.c.d $a123_.456
45$1 => error("`$' must be followed by a valid identifier.") 1
46
10b1662b
BP
47a/*b*/c => a c
48a//b c => a
49a/**/b => a b
50a/*/b => a error("`/*' without matching `*/'.")
51a/*/**/b => a b
52a/b => a error("`/' is only valid as part of `//' or `/*'.") b
53
540 1 12345 18446744073709551615
5518446744073709551616 => error("Decimal constants must be less than 2**64.")
569999999999999999999999 => error("Decimal constants must be less than 2**64.")
5701 => error("Decimal constants must not have leading zeros.")
58
590/0
600/1
611/0 => error("Value contains unmasked 1-bits.")
621/1
63128/384
641/3
651/ => error("Integer constant expected.")
66
671/0x123 => error("Value and mask have incompatible formats.")
68
690x1234
700x01234 => 0x1234
710x0 => 0
720x000 => 0
730xfedcba9876543210
740XFEDCBA9876543210 => 0xfedcba9876543210
750xfedcba9876543210fedcba9876543210
10b1662b
BP
760x0000fedcba9876543210fedcba9876543210 => 0xfedcba9876543210fedcba9876543210
770x => error("Hex digits expected following 0x.")
780X => error("Hex digits expected following 0X.")
790x0/0x0 => 0/0
800x0/0x1 => 0/0x1
810x1/0x0 => error("Value contains unmasked 1-bits.")
820xffff/0x1ffff
830x. => error("Invalid syntax in hexadecimal constant.")
84
85192.168.128.1 1.2.3.4 255.255.255.255 0.0.0.0
86256.1.2.3 => error("Invalid numeric constant.")
87192.168.0.0/16
88192.168.0.0/255.255.0.0 => 192.168.0.0/16
89192.168.0.0/255.255.255.0 => 192.168.0.0/24
90192.168.0.0/255.255.0.255
91192.168.0.0/255.0.0.0 => error("Value contains unmasked 1-bits.")
92192.168.0.0/32
93192.168.0.0/255.255.255.255 => 192.168.0.0/32
52c0fc39 941.2.3.4:5 => 1.2.3.4 : 5
10b1662b
BP
95
96::
97::1
98ff00::1234 => ff00::1234
992001:db8:85a3::8a2e:370:7334
1002001:db8:85a3:0:0:8a2e:370:7334 => 2001:db8:85a3::8a2e:370:7334
1012001:0db8:85a3:0000:0000:8a2e:0370:7334 => 2001:db8:85a3::8a2e:370:7334
102::ffff:192.0.2.128
103::ffff:c000:0280 => ::ffff:192.0.2.128
104::1/::1
105::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff => ::1/128
106::1/128
107ff00::/8
108ff00::/ff00:: => ff00::/8
109
11001:23:45:67:ab:cd
11101:23:45:67:AB:CD => 01:23:45:67:ab:cd
112fe:dc:ba:98:76:54
113FE:DC:ba:98:76:54 => fe:dc:ba:98:76:54
11401:00:00:00:00:00/01:00:00:00:00:00
115ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
116fe:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff
117ff:ff:ff:ff:ff:ff/fe:ff:ff:ff:ff:ff => error("Value contains unmasked 1-bits.")
118fe:x => error("Invalid numeric constant.")
11900:01:02:03:04:x => error("Invalid numeric constant.")
120
a20c96c6 121# Test that operators are tokenized as expected, even without white space.
52c0fc39 122(){}[[]]==!=<<=>>=!&&||..,;=<->--: => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> -- :
10b1662b
BP
123& => error("`&' is only valid as part of `&&'.")
124| => error("`|' is only valid as part of `||'.")
56091efe 125- => error("`-' is only valid as part of `--'.")
10b1662b
BP
126
127^ => error("Invalid character `^' in input.")
128])
129AT_CAPTURE_FILE([input.txt])
130sed 's/ =>.*//' test-cases.txt > input.txt
131sed 's/.* => //' test-cases.txt > expout
132AT_CHECK([ovstest test-ovn lex < input.txt], [0], [expout])
133AT_CLEANUP
e0840f11 134
7700eea0
BP
135dnl The OVN expression parser needs to know what fields overlap with one
136dnl another. This test therefore verifies that all the smaller registers
137dnl are defined as terms of subfields of the larger ones.
138dnl
139dnl When we add or remove registers this test needs to be updated, of course.
140AT_SETUP([ovn -- registers])
141AT_CHECK([ovstest test-ovn dump-symtab | grep reg | sort], [0],
142[[reg0 = xxreg0[96..127]
143reg1 = xxreg0[64..95]
144reg2 = xxreg0[32..63]
145reg3 = xxreg0[0..31]
146reg4 = xxreg1[96..127]
147reg5 = xxreg1[64..95]
148reg6 = xxreg1[32..63]
149reg7 = xxreg1[0..31]
150reg8 = xreg4[32..63]
151reg9 = xreg4[0..31]
152xreg0 = xxreg0[64..127]
153xreg1 = xxreg0[0..63]
154xreg2 = xxreg1[64..127]
155xreg3 = xxreg1[0..63]
156xreg4 = OXM_OF_PKT_REG4
157xxreg0 = NXM_NX_XXREG0
158xxreg1 = NXM_NX_XXREG1
159]])
160AT_CLEANUP
161
2277b860
BP
162dnl Check that the OVN conntrack field definitions are correct.
163AT_SETUP([ovn -- conntrack fields])
164AT_CHECK([ovstest test-ovn dump-symtab | grep ^ct | sort], [0],
165[[ct.est = ct_state[1]
166ct.inv = ct_state[4]
167ct.new = ct_state[0]
168ct.rel = ct_state[2]
169ct.rpl = ct_state[3]
170ct.trk = ct_state[5]
171ct_label = NXM_NX_CT_LABEL
b73db61d 172ct_label.blocked = ct_label[0]
2277b860
BP
173ct_mark = NXM_NX_CT_MARK
174ct_state = NXM_NX_CT_STATE
175]])
176AT_CLEANUP
177
e0840f11
BP
178AT_SETUP([ovn -- expression parser])
179dnl For lines without =>, input and expected output are identical.
180dnl For lines with =>, input precedes => and expected output follows =>.
181AT_DATA([test-cases.txt], [[
182eth.type == 0x800
183eth.type==0x800 => eth.type == 0x800
184eth.type[0..15] == 0x800 => eth.type == 0x800
185
186vlan.present
187vlan.present == 1 => vlan.present
188!(vlan.present == 0) => vlan.present
189!(vlan.present != 1) => vlan.present
190!vlan.present
191vlan.present == 0 => !vlan.present
192vlan.present != 1 => !vlan.present
193!(vlan.present == 1) => !vlan.present
194!(vlan.present != 0) => !vlan.present
195
196eth.dst[0]
197eth.dst[0] == 1 => eth.dst[0]
198eth.dst[0] != 0 => eth.dst[0]
199!(eth.dst[0] == 0) => eth.dst[0]
200!(eth.dst[0] != 1) => eth.dst[0]
201
202!eth.dst[0]
203eth.dst[0] == 0 => !eth.dst[0]
204eth.dst[0] != 1 => !eth.dst[0]
205!(eth.dst[0] == 1) => !eth.dst[0]
206!(eth.dst[0] != 0) => !eth.dst[0]
207
208vlan.tci[12..15] == 0x3
209vlan.tci == 0x3000/0xf000 => vlan.tci[12..15] == 0x3
210vlan.tci[12..15] != 0x3
211vlan.tci != 0x3000/0xf000 => vlan.tci[12..15] != 0x3
212
213!vlan.pcp => vlan.pcp == 0
214!(vlan.pcp) => vlan.pcp == 0
215vlan.pcp == 0x4
216vlan.pcp != 0x4
217vlan.pcp > 0x4
218vlan.pcp >= 0x4
219vlan.pcp < 0x4
220vlan.pcp <= 0x4
221!(vlan.pcp != 0x4) => vlan.pcp == 0x4
222!(vlan.pcp == 0x4) => vlan.pcp != 0x4
223!(vlan.pcp <= 0x4) => vlan.pcp > 0x4
224!(vlan.pcp < 0x4) => vlan.pcp >= 0x4
225!(vlan.pcp >= 0x4) => vlan.pcp < 0x4
226!(vlan.pcp > 0x4) => vlan.pcp <= 0x4
2270x4 == vlan.pcp => vlan.pcp == 0x4
2280x4 != vlan.pcp => vlan.pcp != 0x4
2290x4 < vlan.pcp => vlan.pcp > 0x4
2300x4 <= vlan.pcp => vlan.pcp >= 0x4
2310x4 > vlan.pcp => vlan.pcp < 0x4
2320x4 >= vlan.pcp => vlan.pcp <= 0x4
233!(0x4 != vlan.pcp) => vlan.pcp == 0x4
234!(0x4 == vlan.pcp) => vlan.pcp != 0x4
235!(0x4 >= vlan.pcp) => vlan.pcp > 0x4
236!(0x4 > vlan.pcp) => vlan.pcp >= 0x4
237!(0x4 <= vlan.pcp) => vlan.pcp < 0x4
238!(0x4 < vlan.pcp) => vlan.pcp <= 0x4
239
2401 < vlan.pcp < 4 => vlan.pcp > 0x1 && vlan.pcp < 0x4
2411 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2421 < vlan.pcp <= 4 => vlan.pcp > 0x1 && vlan.pcp <= 0x4
2431 <= vlan.pcp < 4 => vlan.pcp >= 0x1 && vlan.pcp < 0x4
2441 <= vlan.pcp <= 4 => vlan.pcp >= 0x1 && vlan.pcp <= 0x4
2454 > vlan.pcp > 1 => vlan.pcp < 0x4 && vlan.pcp > 0x1
2464 >= vlan.pcp > 1 => vlan.pcp <= 0x4 && vlan.pcp > 0x1
2474 > vlan.pcp >= 1 => vlan.pcp < 0x4 && vlan.pcp >= 0x1
2484 >= vlan.pcp >= 1 => vlan.pcp <= 0x4 && vlan.pcp >= 0x1
249!(1 < vlan.pcp < 4) => vlan.pcp <= 0x1 || vlan.pcp >= 0x4
250!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
251!(1 < vlan.pcp <= 4) => vlan.pcp <= 0x1 || vlan.pcp > 0x4
252!(1 <= vlan.pcp < 4) => vlan.pcp < 0x1 || vlan.pcp >= 0x4
253!(1 <= vlan.pcp <= 4) => vlan.pcp < 0x1 || vlan.pcp > 0x4
254!(4 > vlan.pcp > 1) => vlan.pcp >= 0x4 || vlan.pcp <= 0x1
255!(4 >= vlan.pcp > 1) => vlan.pcp > 0x4 || vlan.pcp <= 0x1
256!(4 > vlan.pcp >= 1) => vlan.pcp >= 0x4 || vlan.pcp < 0x1
257!(4 >= vlan.pcp >= 1) => vlan.pcp > 0x4 || vlan.pcp < 0x1
258
259vlan.pcp == {1, 2, 3, 4} => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
260vlan.pcp == 1 || ((vlan.pcp == 2 || vlan.pcp == 3) || vlan.pcp == 4) => vlan.pcp == 0x1 || vlan.pcp == 0x2 || vlan.pcp == 0x3 || vlan.pcp == 0x4
261
262vlan.pcp != {1, 2, 3, 4} => vlan.pcp != 0x1 && vlan.pcp != 0x2 && vlan.pcp != 0x3 && vlan.pcp != 0x4
263vlan.pcp == 1 && ((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && vlan.pcp == 0x2 && vlan.pcp == 0x3 && vlan.pcp == 0x4
264
265vlan.pcp == 1 && !((vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3 || vlan.pcp != 0x4)
266vlan.pcp == 1 && (!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && (vlan.pcp != 0x2 || vlan.pcp != 0x3) && vlan.pcp == 0x4
267vlan.pcp == 1 && !(!(vlan.pcp == 2 && vlan.pcp == 3) && vlan.pcp == 4) => vlan.pcp == 0x1 && ((vlan.pcp == 0x2 && vlan.pcp == 0x3) || vlan.pcp != 0x4)
268
269ip4.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
270ip6.src == ::1 => ip6.src == 0x1
271
272ip4.src == 1.2.3.4 => ip4.src == 0x1020304
273ip4.src == ::1.2.3.4/::ffff:ffff => ip4.src == 0x1020304
274ip6.src == ::1 => ip6.src == 0x1
275
2761
2770
278!1 => 0
279!0 => 1
280
281inport == "eth0"
282!(inport != "eth0") => inport == "eth0"
283
3b7cb7e1
BP
284ip4.src == "eth0" => Integer field ip4.src is not compatible with string constant.
285inport == 1 => String field inport is not compatible with integer constant.
76da94b5 286ip4.src = 1.2.3.4 => Syntax error at `=' expecting relational operator.
e0840f11
BP
287
288ip4.src > {1, 2, 3} => Only == and != operators may be used with value sets.
289eth.type > 0x800 => Only == and != operators may be used with nominal field eth.type.
290vlan.present > 0 => Only == and != operators may be used with Boolean field vlan.present.
291
292inport != "eth0" => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
293!(inport == "eth0") => Nominal field inport may only be tested for equality (taking enclosing `!' operators into account).
294eth.type != 0x800 => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
295!(eth.type == 0x800) => Nominal field eth.type may only be tested for equality (taking enclosing `!' operators into account).
76da94b5 296inport = "eth0" => Syntax error at `=' expecting relational operator.
e0840f11
BP
297
298123 == 123 => Syntax error at `123' expecting field name.
299
2c5cbb15
RB
300$name => Syntax error at `$name' expecting address set name.
301
e0840f11
BP
302123 == xyzzy => Syntax error at `xyzzy' expecting field name.
303xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
304
305inport[1] == 1 => Cannot select subfield of string field inport.
306
307eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
308eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
309eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
310
311eth.type[5!] => Syntax error at `!' expecting `@:>@'.
312
313eth.type[5..1] => Invalid bit range 5 to 1.
314
315eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
316
317eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
318
319eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
320
321!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
322
323123 => Syntax error at end of input expecting relational operator.
324
325123 x => Syntax error at `x' expecting relational operator.
326
327{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
328
329eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
330
331(1 x) => Syntax error at `x' expecting `)'.
332
333!0x800 != eth.type => Missing parentheses around operand of !.
334
335eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
336
337eth.dst == {} => Syntax error at `}' expecting constant.
338
339eth.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).
340
3b7cb7e1 341ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
342
3431 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 344
9aef3c1b 345eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
346
347ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
348eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
e0840f11
BP
349]])
350sed 's/ =>.*//' test-cases.txt > input.txt
351sed 's/.* => //' test-cases.txt > expout
352AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
353AT_CLEANUP
354
355AT_SETUP([ovn -- expression annotation])
356dnl Input precedes =>, expected output follows =>.
357AT_DATA([test-cases.txt], [[
358ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
359ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
360ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
361ip.proto == {123, 234} => (ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)) || (ip.proto == 0xea && (eth.type == 0x800 || eth.type == 0x86dd))
362ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
363
364ip => eth.type == 0x800 || eth.type == 0x86dd
365ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
366ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
367ip > 0 => Only == and != operators may be used with nominal field ip.
368!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
369ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
370
371vlan.present => vlan.tci[12]
372!vlan.present => !vlan.tci[12]
373
374!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
375vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 376!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
377
378ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
379!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
380ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
381
382bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
383self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
384mutual_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'.
385mutual_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'.
386]])
387sed 's/ =>.*//' test-cases.txt > input.txt
388sed 's/.* => //' test-cases.txt > expout
389AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
390AT_CLEANUP
391
9d4aecca 392AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 393AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 394 [Tested converting all 1-terminal expressions with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
395])
396AT_CLEANUP
397
9d4aecca 398AT_SETUP([ovn -- 2-term expression conversion])
e0840f11 399AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
9d4aecca 400 [Tested converting 570 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
401])
402AT_CLEANUP
403
9d4aecca 404AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 405AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
9d4aecca 406 [Tested converting 62418 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
407])
408AT_CLEANUP
409
9d4aecca
BP
410AT_SETUP([ovn -- 3-term numeric expression simplification])
411AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
412 [Tested simplifying 477138 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
413])
414AT_CLEANUP
415
9d4aecca
BP
416AT_SETUP([ovn -- 4-term string expression simplification])
417AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
418 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
419])
420AT_CLEANUP
421
9d4aecca
BP
422AT_SETUP([ovn -- 3-term mixed expression simplification])
423AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
424 [Tested simplifying 124410 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
425])
426AT_CLEANUP
427
97ba1d55
BP
428AT_SETUP([ovn -- simplification special cases])
429simplify() {
430 echo "$1" | ovstest test-ovn simplify-expr
431}
432AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
433])
a3d79068
BP
434AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
435])
97ba1d55
BP
436AT_CLEANUP
437
9d4aecca
BP
438AT_SETUP([ovn -- 4-term numeric expression normalization])
439AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
440 [Tested normalizing 1207162 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
441])
442AT_CLEANUP
443
9d4aecca
BP
444AT_SETUP([ovn -- 4-term string expression normalization])
445AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
446 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
447])
448AT_CLEANUP
449
450AT_SETUP([ovn -- 4-term mixed expression normalization])
451AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
452 [Tested normalizing 128282 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
453])
454AT_CLEANUP
455
456AT_SETUP([ovn -- 5-term numeric expression normalization])
457AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
458 [Tested normalizing 368550 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
459])
460AT_CLEANUP
461
462AT_SETUP([ovn -- 5-term string expression normalization])
463AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
464 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
465])
466AT_CLEANUP
467
468AT_SETUP([ovn -- 5-term mixed expression normalization])
469AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
470 [Tested normalizing 116550 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
471])
472AT_CLEANUP
473
474AT_SETUP([ovn -- 4-term numeric expressions to flows])
475AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
476 [Tested converting to flows 128282 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
477])
478AT_CLEANUP
479
480AT_SETUP([ovn -- 4-term string expressions to flows])
481AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
482 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
483])
484AT_CLEANUP
485
486AT_SETUP([ovn -- 4-term mixed expressions to flows])
487AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
488 [Tested converting to flows 37994 expressions of 4 terminals with 1 numeric vars (each 2 bits) in terms of operators == and 1 string vars.
489])
490AT_CLEANUP
491
492AT_SETUP([ovn -- 3-term numeric expressions to flows])
493AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
494 [Tested converting to flows 38394 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
495])
496AT_CLEANUP
f386a8a7
BP
497
498AT_SETUP([ovn -- converting expressions to flows -- string fields])
499expr_to_flow () {
500 echo "$1" | ovstest test-ovn expr-to-flows | sort
501}
cc5e28d8 502AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 503])
cc5e28d8 504AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
505])
506AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
507])
508AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
509ip,reg14=0x5
510ipv6,reg14=0x5
f386a8a7
BP
511])
512AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
513ip,reg14=0x6
514ipv6,reg14=0x6
f386a8a7
BP
515])
516AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
517])
518AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
519[reg14=0x5
520reg14=0x6
521reg14=0xfffe
f386a8a7
BP
522])
523AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
524ip,reg14=0x5
525ip,reg14=0x6
526ipv6,reg14=0x5
527ipv6,reg14=0x6
f386a8a7 528])
9d4aecca
BP
529AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
530(no flows)
531])
f386a8a7 532AT_CLEANUP
3b7cb7e1 533
2c5cbb15
RB
534AT_SETUP([ovn -- converting expressions to flows -- address sets])
535expr_to_flow () {
536 echo "$1" | ovstest test-ovn expr-to-flows | sort
537}
538AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
539ip,nw_src=10.0.0.1
540ip,nw_src=10.0.0.2
541ip,nw_src=10.0.0.3
542])
543AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
544ip,nw_src=10.0.0.1
545ip,nw_src=10.0.0.2
546ip,nw_src=10.0.0.3
547])
548AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set1}'], [0], [dnl
549ip,nw_src=1.2.3.4
550ip,nw_src=10.0.0.1
551ip,nw_src=10.0.0.2
552ip,nw_src=10.0.0.3
553])
554AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
555ip,nw_src=1.2.0.0/20
556ip,nw_src=10.0.0.1
557ip,nw_src=10.0.0.2
558ip,nw_src=10.0.0.3
559ip,nw_src=5.5.5.0/24
560])
561AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
562ipv6,ipv6_src=::1
563ipv6,ipv6_src=::2
564ipv6,ipv6_src=::3
565])
566AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
567ipv6,ipv6_src=::1
568ipv6,ipv6_src=::2
569ipv6,ipv6_src=::3
570ipv6,ipv6_src=::4
571])
572AT_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
573dl_src=00:00:00:00:00:01
574dl_src=00:00:00:00:00:02
575dl_src=00:00:00:00:00:03
576])
577AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
578dl_src=00:00:00:00:00:01
579dl_src=00:00:00:00:00:02
580dl_src=00:00:00:00:00:03
581])
ea382567
RB
582AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
583dl_src=00:00:00:00:00:01
584dl_src=00:00:00:00:00:02
585dl_src=00:00:00:00:00:03
586dl_src=ba:be:be:ef:de:ad
587])
2c5cbb15
RB
588AT_CLEANUP
589
3b7cb7e1 590AT_SETUP([ovn -- action parsing])
d5a76da4
BP
591dnl Unindented text is input (a set of OVN logical actions).
592dnl Indented text is expected output.
593AT_DATA([test-cases.txt],
594[[# drop
595drop;
596 encodes as drop
597drop; next;
598 Syntax error at `next' expecting end of input.
599next; drop;
600 Syntax error at `drop' expecting action.
5f822129
BP
601
602# output
d5a76da4
BP
603output;
604 encodes as resubmit(,64)
5f822129
BP
605
606# next
d5a76da4
BP
607next;
608 formats as next(11);
609 encodes as resubmit(,27)
610next(11);
611 encodes as resubmit(,27)
612next(0);
613 encodes as resubmit(,16)
614next(15);
615 encodes as resubmit(,31)
616
617next();
618 Syntax error at `)' expecting small integer.
619next(10;
620 Syntax error at `;' expecting `)'.
621next(16);
622 "next" argument must be in range 0 to 15.
5f822129
BP
623
624# Loading a constant value.
d5a76da4
BP
625tcp.dst=80;
626 formats as tcp.dst = 80;
627 encodes as set_field:80->tcp_dst
628 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
629eth.dst[40] = 1;
630 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
631vlan.pcp = 2;
632 encodes as set_field:0x4000/0xe000->vlan_tci
633 has prereqs vlan.tci[12]
634vlan.tci[13..15] = 2;
635 encodes as set_field:0x4000/0xe000->vlan_tci
636inport = "";
637 encodes as set_field:0->reg14
638ip.ttl=4;
639 formats as ip.ttl = 4;
640 encodes as set_field:4->nw_ttl
641 has prereqs eth.type == 0x800 || eth.type == 0x86dd
642outport="eth0"; next; outport="LOCAL"; next;
643 formats as outport = "eth0"; next(11); outport = "LOCAL"; next(11);
644 encodes as set_field:0x5->reg15,resubmit(,27),set_field:0xfffe->reg15,resubmit(,27)
645
646inport[1] = 1;
647 Cannot select subfield of string field inport.
648ip.proto[1] = 1;
649 Cannot select subfield of nominal field ip.proto.
650eth.dst[40] == 1;
651 Syntax error at `==' expecting `=' or `<->'.
652ip = 1;
653 Predicate symbol ip used where lvalue required.
654ip.proto = 6;
655 Field ip.proto is not modifiable.
656inport = {"a", "b"};
657 Syntax error at `{' expecting constant.
658inport = {};
659 Syntax error at `{' expecting constant.
660bad_prereq = 123;
661 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
662self_recurse = 123;
663 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'.
664vlan.present = 0;
665 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
666
667# Moving one field into another.
d5a76da4
BP
668reg0=reg1;
669 formats as reg0 = reg1;
670 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
671vlan.pcp = reg0[0..2];
672 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
673 has prereqs vlan.tci[12]
674reg0[10] = vlan.pcp[1];
675 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
676 has prereqs vlan.tci[12]
677outport = inport;
678 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
679
680reg0[0] = vlan.present;
681 Predicate symbol vlan.present used where lvalue required.
682reg0 = reg1[0..10];
683 Can't assign 11-bit value to 32-bit destination.
684inport = reg0;
685 Can't assign integer field (reg0) to string field (inport).
686inport = big_string;
687 String fields inport and big_string are incompatible for assignment.
688ip.proto = reg0[0..7];
689 Field ip.proto is not modifiable.
5f822129
BP
690
691# Exchanging fields.
d5a76da4
BP
692reg0 <-> reg1;
693 encodes as push:NXM_NX_XXREG0[64..95],push:NXM_NX_XXREG0[96..127],pop:NXM_NX_XXREG0[64..95],pop:NXM_NX_XXREG0[96..127]
694vlan.pcp <-> reg0[0..2];
695 encodes as push:NXM_NX_XXREG0[96..98],push:NXM_OF_VLAN_TCI[13..15],pop:NXM_NX_XXREG0[96..98],pop:NXM_OF_VLAN_TCI[13..15]
696 has prereqs vlan.tci[12]
697reg0[10] <-> vlan.pcp[1];
698 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
699 has prereqs vlan.tci[12]
700outport <-> inport;
701 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
702
703reg0[0] <-> vlan.present;
704 Predicate symbol vlan.present used where lvalue required.
705reg0 <-> reg1[0..10];
706 Can't exchange 32-bit field with 11-bit field.
707inport <-> reg0;
708 Can't exchange string field (inport) with integer field (reg0).
709inport <-> big_string;
710 String fields inport and big_string are incompatible for exchange.
711ip.proto <-> reg0[0..7];
712 Field ip.proto is not modifiable.
713reg0[0..7] <-> ip.proto;
714 Field ip.proto is not modifiable.
5f822129
BP
715
716# TTL decrement.
d5a76da4
BP
717ip.ttl--;
718 encodes as dec_ttl
719 has prereqs ip
720ip.ttl
721 Syntax error at end of input expecting `--'.
5f822129 722
467085fd 723# load balancing.
d5a76da4
BP
724ct_lb;
725 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
726 has prereqs ip
727ct_lb();
728 formats as ct_lb;
729 encodes as ct(table=27,zone=NXM_NX_REG13[0..15],nat)
730 has prereqs ip
731ct_lb(192.168.1.2:80, 192.168.1.3:80);
732 encodes as group:1
733 has prereqs ip
734ct_lb(192.168.1.2, 192.168.1.3, );
735 formats as ct_lb(192.168.1.2, 192.168.1.3);
736 encodes as group:2
737 has prereqs ip
738
739ct_lb(192.168.1.2:);
740 Syntax error at `)' expecting port number.
741ct_lb(192.168.1.2:123456);
742 Syntax error at `123456' expecting port number.
743ct_lb(foo);
744 Syntax error at `foo' expecting IPv4 address.
745
746# ct_next
747ct_next;
748 encodes as ct(table=27,zone=NXM_NX_REG13[0..15])
749 has prereqs ip
750
751# ct_commit
752ct_commit;
753 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
754 has prereqs ip
755ct_commit();
756 formats as ct_commit;
757 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
758 has prereqs ip
759ct_commit(ct_mark=1);
760 formats as ct_commit(ct_mark=0x1);
761 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
762 has prereqs ip
763ct_commit(ct_mark=1/1);
764 formats as ct_commit(ct_mark=0x1/0x1);
765 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
766 has prereqs ip
767ct_commit(ct_label=1);
768 formats as ct_commit(ct_label=0x1);
769 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
770 has prereqs ip
771ct_commit(ct_label=1/1);
772 formats as ct_commit(ct_label=0x1/0x1);
773 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
774 has prereqs ip
775ct_commit(ct_mark=1, ct_label=2);
776 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
777 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
778 has prereqs ip
779
780ct_commit(ct_label=0x01020304050607080910111213141516);
781 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
782 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
783 has prereqs ip
784ct_commit(ct_label=0x181716151413121110090807060504030201);
785 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
786 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
787 has prereqs ip
788ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
789 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
790 has prereqs ip
791ct_commit(ct_label=18446744073709551615);
792 formats as ct_commit(ct_label=0xffffffffffffffff);
793 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
794 has prereqs ip
795ct_commit(ct_label=18446744073709551616);
796 Decimal constants must be less than 2**64.
797
798# ct_dnat
799ct_dnat;
800 encodes as ct(table=27,zone=NXM_NX_REG11[0..15],nat)
801 has prereqs ip
802ct_dnat(192.168.1.2);
803 encodes as ct(commit,table=27,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
804 has prereqs ip
805
806ct_dnat(192.168.1.2, 192.168.1.3);
807 Syntax error at `,' expecting `)'.
808ct_dnat(foo);
809 Syntax error at `foo' expecting IPv4 address.
810ct_dnat(foo, bar);
811 Syntax error at `foo' expecting IPv4 address.
812ct_dnat();
813 Syntax error at `)' expecting IPv4 address.
814
815# ct_snat
816ct_snat;
817 encodes as ct(zone=NXM_NX_REG12[0..15],nat)
818 has prereqs ip
819ct_snat(192.168.1.2);
820 encodes as ct(commit,table=27,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
821 has prereqs ip
822
823ct_snat(192.168.1.2, 192.168.1.3);
824 Syntax error at `,' expecting `)'.
825ct_snat(foo);
826 Syntax error at `foo' expecting IPv4 address.
827ct_snat(foo, bar);
828 Syntax error at `foo' expecting IPv4 address.
829ct_snat();
830 Syntax error at `)' expecting IPv4 address.
de297547 831
6335d074 832# arp
d5a76da4
BP
833arp { eth.dst = ff:ff:ff:ff:ff:ff; output; };
834 encodes as controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
835 has prereqs ip4
6335d074 836
0bac7164 837# get_arp
d5a76da4
BP
838get_arp(outport, ip4.dst);
839 encodes as push:NXM_NX_REG0[],push:NXM_OF_IP_DST[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[]
840 has prereqs eth.type == 0x800
841get_arp(inport, reg0);
842 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG0[],push:NXM_NX_XXREG0[96..127],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],pop:NXM_NX_REG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG0[],pop:NXM_NX_REG15[]
843
844get_arp;
845 Syntax error at `;' expecting `('.
846get_arp();
847 Syntax error at `)' expecting field name.
848get_arp(inport);
849 Syntax error at `)' expecting `,'.
850get_arp(inport ip4.dst);
851 Syntax error at `ip4.dst' expecting `,'.
852get_arp(inport, ip4.dst;
853 Syntax error at `;' expecting `)'.
854get_arp(inport, eth.dst);
855 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
856get_arp(inport, outport);
857 Cannot use string field outport where numeric field is required.
858get_arp(reg0, ip4.dst);
859 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
860
861# put_arp
d5a76da4
BP
862put_arp(inport, arp.spa, arp.sha);
863 encodes as push:NXM_NX_REG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ARP_SHA[],push:NXM_OF_ARP_SPA[],pop:NXM_NX_REG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.01.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_REG0[]
864 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 865
42814145 866# put_dhcp_opts
d5a76da4
BP
867reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
868 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.40.01.02.03.04.03.04.0a.00.00.01,pause)
869reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
870 formats as reg2[5] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.254.0, mtu = 1400, domain = "ovn.org");
871 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.25.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.fe.00.1a.02.05.78.0f.07.6f.76.6e.2e.6f.72.67,pause)
872reg0[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);
873 formats as reg0[15] = put_dhcp_opts(offerip = 10.0.0.4, router = 10.0.0.1, netmask = 255.255.255.0, mtu = 1400, ip_forward_enable = 1, default_ttl = 121, dns_server = {8.8.8.8, 7.7.7.7}, classless_static_route = {30.0.0.0/24, 10.0.0.4, 40.0.0.0/16, 10.0.0.6, 0.0.0.0/0, 10.0.0.1}, ethernet_encap = 1, router_discovery = 0);
874 encodes as controller(userdata=00.00.00.02.00.00.00.00.00.01.de.10.00.00.00.6f.0a.00.00.04.03.04.0a.00.00.01.01.04.ff.ff.ff.00.1a.02.05.78.13.01.01.17.01.79.06.08.08.08.08.08.07.07.07.07.79.14.18.1e.00.00.0a.00.00.04.10.28.00.0a.00.00.06.00.0a.00.00.01.24.01.01.1f.01.00,pause)
875
876reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
877 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
878reg1[0] = put_dhcp_opts();
879 put_dhcp_opts requires offerip to be specified.
880reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
881 Syntax error at `x' expecting DHCPv4 option name.
882reg1[0] = put_dhcp_opts(router = 10.0.0.1);
883 put_dhcp_opts requires offerip to be specified.
884reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
885 Syntax error at `"hi"'.
886reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
887 Syntax error at `xyzzy' expecting DHCPv4 option name.
888reg1[0] = put_dhcp_opts(offerip="xyzzy");
889 DHCPv4 option offerip requires numeric value.
890reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
891 DHCPv4 option domain requires string value.
42814145 892
f8a8db39 893# nd_na
d5a76da4
BP
894nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
895 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
896 encodes as controller(userdata=00.00.00.03.00.00.00.00.00.19.00.10.80.00.08.06.12.34.56.78.9a.bc.00.00.00.19.00.10.80.00.42.06.12.34.56.78.9a.bc.00.00.ff.ff.00.18.00.00.23.20.00.06.00.20.00.00.00.00.00.01.1c.04.00.01.1e.04.00.19.00.10.00.01.1c.04.00.00.00.00.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
897 has prereqs nd_ns
e75451fe 898
c34a87b6 899# get_nd
d5a76da4
BP
900get_nd(outport, ip6.dst);
901 encodes as push:NXM_NX_XXREG0[],push:NXM_NX_IPV6_DST[],pop:NXM_NX_XXREG0[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_XXREG0[]
902 has prereqs eth.type == 0x86dd
903get_nd(inport, xxreg0);
904 encodes as push:NXM_NX_REG15[],push:NXM_NX_REG14[],pop:NXM_NX_REG15[],set_field:00:00:00:00:00:00->eth_dst,resubmit(,65),pop:NXM_NX_REG15[]
905get_nd;
906 Syntax error at `;' expecting `('.
907get_nd();
908 Syntax error at `)' expecting field name.
909get_nd(inport);
910 Syntax error at `)' expecting `,'.
911get_nd(inport ip6.dst);
912 Syntax error at `ip6.dst' expecting `,'.
913get_nd(inport, ip6.dst;
914 Syntax error at `;' expecting `)'.
915get_nd(inport, eth.dst);
916 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
917get_nd(inport, outport);
918 Cannot use string field outport where numeric field is required.
919get_nd(xxreg0, ip6.dst);
920 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
921
922# put_nd
d5a76da4
BP
923put_nd(inport, nd.target, nd.sll);
924 encodes as push:NXM_NX_XXREG0[],push:NXM_OF_ETH_SRC[],push:NXM_NX_ND_SLL[],push:NXM_NX_ND_TARGET[],pop:NXM_NX_XXREG0[],pop:NXM_OF_ETH_SRC[],controller(userdata=00.00.00.04.00.00.00.00),pop:NXM_OF_ETH_SRC[],pop:NXM_NX_XXREG0[]
925 has prereqs ((icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd)) || (icmp6.type == 0x88 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd))) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.type == 0x87 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && icmp6.code == 0 && eth.type == 0x86dd && ip.proto == 0x3a && (eth.type == 0x800 || eth.type == 0x86dd) && ip.ttl == 0xff && (eth.type == 0x800 || eth.type == 0x86dd)
c34a87b6 926
01cfdb2f 927# put_dhcpv6_opts
d5a76da4
BP
928reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
929 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.05.00.10.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.04.02.00.06.00.00.00.00.00.10.02,pause)
930reg1[0] = put_dhcpv6_opts();
931 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
932reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
933 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
934 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.17.00.20.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
40df4566
ZKL
935reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
936 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
937 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.02.00.06.00.12.34.56.78.9a.bc.17.00.20.00.ae.70.00.00.00.00.00.00.00.00.00.00.00.00.00.01.ae.89.00.00.00.00.00.00.00.00.00.00.00.00.00.02,pause)
d5a76da4
BP
938reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
939 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40.18.00.07.00.6f.76.6e.2e.6f.72.67,pause)
940reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
941 Syntax error at `x' expecting DHCPv6 option name.
942reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
943 Syntax error at `"hi"'.
944reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
945 Syntax error at `xyzzy' expecting DHCPv6 option name.
946reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
947 DHCPv6 option ia_addr requires numeric value.
948reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
949 DHCPv6 option domain_search requires string value.
01cfdb2f 950
a6095f81
BS
951# set_queue
952set_queue(0);
953 encodes as set_queue:0
954set_queue(61440);
955 encodes as set_queue:61440
956set_queue(65535);
957 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
958
5f822129 959# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
960ip4.src = ip6.src[0..31];
961 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
962 has prereqs eth.type == 0x800 && eth.type == 0x86dd
963ip4.src <-> ip6.src[0..31];
964 encodes as push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[]
965 has prereqs eth.type == 0x800 && eth.type == 0x86dd
966
967# Miscellaneous negative tests.
968;
969 Syntax error at `;'.
970xyzzy;
971 Syntax error at `xyzzy' expecting action.
972next; 123;
973 Syntax error at `123'.
974next; xyzzy;
975 Syntax error at `xyzzy' expecting action.
976next
9aef3c1b 977 Syntax error at end of input expecting `;'.
3b7cb7e1 978]])
d5a76da4
BP
979sed '/^[[ ]]/d' test-cases.txt > input.txt
980cp test-cases.txt expout
3b7cb7e1
BP
981AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
982AT_CLEANUP
f295c17b
BP
983
984AT_BANNER([OVN end-to-end tests])
985
9975d7be
BP
986# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
987AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 988AT_KEYWORDS([ovnarp])
f295c17b
BP
989AT_SKIP_IF([test $HAVE_PYTHON = no])
990ovn_start
991
992# Create hypervisors hv[123].
9975d7be 993# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
994# Add all of the vifs to a single logical switch lsw0.
995# Turn on port security on all the vifs except vif[123]1.
996# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
997# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 998ovn-nbctl ls-add lsw0
f295c17b
BP
999net_add n1
1000for i in 1 2 3; do
1001 sim_add hv$i
1002 as hv$i
1003 ovs-vsctl add-br br-phys
1004 ovn_attach n1 br-phys 192.168.0.$i
1005
1006 for j in 1 2 3; do
1007 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 1008 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1009 if test $j = 1; then
31ed1192 1010 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1011 else
7dc88496
NS
1012 if test $j = 3; then
1013 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1014 else
1015 ip_addrs="192.168.0.$i$j"
1016 fi
31ed1192
JP
1017 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1018 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1019 fi
1020 done
1021done
1022ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1023ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1024ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1025ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:11\",\"f0:00:00:00:00:21\",\"f0:00:00:00:00:31\"
1026ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b
BP
1027
1028# Pre-populate the hypervisors' ARP tables so that we don't lose any
1029# packets for ARP resolution (native tunneling doesn't queue packets
1030# for ARP resolution).
1031ovn_populate_arp
1032
1033# Allow some time for ovn-northd and ovn-controller to catch up.
1034# XXX This should be more systematic.
1035sleep 1
611099dc 1036
57d143eb
HZ
1037# Given the name of a logical port, prints the name of the hypervisor
1038# on which it is located.
1039vif_to_hv() {
1040 echo hv${1%?}
1041}
1042
f295c17b
BP
1043# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1044#
1045# This shell function causes a packet to be received on INPORT. The packet's
1046# content has Ethernet destination DST and source SRC (each exactly 12 hex
1047# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1048# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1049# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1050for i in 1 2 3; do
1051 for j in 1 2 3; do
1052 : > $i$j.expected
1053 done
1054done
1055test_packet() {
1056 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1057 hv=`vif_to_hv $inport`
f295c17b
BP
1058 vif=vif$inport
1059 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1060 for outport; do
e4543cfe 1061 echo $packet >> $outport.expected
f295c17b
BP
1062 done
1063}
1064
57d143eb
HZ
1065# test_arp INPORT SHA SPA TPA [REPLY_HA]
1066#
1067# Causes a packet to be received on INPORT. The packet is an ARP
1068# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1069# it should be the hardware address of the target to expect to receive in an
1070# ARP reply; otherwise no reply is expected.
1071#
31ed1192 1072# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1073# SHA and REPLY_HA are each 12 hex digits.
1074# SPA and TPA are each 8 hex digits.
1075test_arp() {
1076 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1077 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1078 hv=`vif_to_hv $inport`
1079 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1080
92f9822b 1081 if test X$reply_ha = X; then
57d143eb
HZ
1082 # Expect to receive the broadcast ARP on the other logical switch ports
1083 # if no reply is expected.
1084 local i j
1085 for i in 1 2 3; do
1086 for j in 1 2 3; do
1087 if test $i$j != $inport; then
1088 echo $request >> $i$j.expected
1089 fi
1090 done
1091 done
1092 else
1093 # Expect to receive the reply, if any.
1094 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1095 echo $reply >> $inport.expected
1096 fi
1097}
1098
1099ip_to_hex() {
1100 printf "%02x%02x%02x%02x" "$@"
1101}
1102
f295c17b
BP
1103# Send packets between all pairs of source and destination ports:
1104#
31ed1192
JP
1105# 1. Unicast packets are delivered to exactly one logical switch port
1106# (except that packets destined to their input ports are dropped).
f295c17b 1107#
31ed1192
JP
1108# 2. Broadcast and multicast are delivered to all logical switch ports
1109# except the input port.
f295c17b 1110#
ea46a4e9 1111# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1112# MAC address.
1113#
ea46a4e9 1114# 4. The switch drops all packets with a VLAN tag.
f295c17b 1115#
ea46a4e9 1116# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1117# affects behavior when port security is turned off, since otherwise port
1118# security would drop the packet anyway.)
1119#
ea46a4e9 1120# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1121# switch ports with "unknown" among their MAC addresses (and port
1122# security disabled).
f295c17b 1123#
ea46a4e9 1124# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1125#
ea46a4e9 1126# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1127#
9fcb6a18
BP
1128# 9. OVN generates responses to ARP requests for known IPs, except for
1129# requests from a port for the port's own IP.
57d143eb
HZ
1130#
1131# 10. No response to ARP requests for unknown IPs.
4acd1e87 1132
f295c17b
BP
1133for is in 1 2 3; do
1134 for js in 1 2 3; do
1135 s=$is$js
1136 bcast=
4d5c43d5
JP
1137 unknown=
1138 bacl2=
1139 bacl3=
f295c17b
BP
1140 for id in 1 2 3; do
1141 for jd in 1 2 3; do
1142 d=$id$jd
1143
1144 if test $d != $s; then unicast=$d; else unicast=; fi
1145 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1146
1147 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1148 impersonate=$d
1149 else
1150 impersonate=
1151 fi
f295c17b
BP
1152 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1153
4d5c43d5
JP
1154 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1155 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1156 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1157 # Source of 11, 21, or 31 and dest of 33 should be dropped
1158 # due to the 4th ACL that uses address_set(set1).
1159 acl4=
1160 else
1161 acl4=$d
1162 fi
f295c17b
BP
1163 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1164 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1165 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1166 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
f295c17b
BP
1167
1168 test_packet $s f000000000$d f00000000055 810000091234 #4
1169 test_packet $s f000000000$d 0100000000$s $s$d #5
1170
4d5c43d5
JP
1171 if test $d != $s && test $jd = 1; then
1172 unknown="$unknown $d"
1173 fi
f295c17b
BP
1174 bcast="$bcast $unicast"
1175 bacl2="$bacl2 $acl2"
1176 bacl3="$bacl3 $acl3"
57d143eb
HZ
1177
1178 sip=`ip_to_hex 192 168 0 $i$j`
1179 tip=`ip_to_hex 192 168 0 $id$jd`
1180 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1181 if test $d != $s; then
1182 reply_ha=f000000000$d
1183 else
1184 reply_ha=
1185 fi
1186 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1187 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1188
1189 if test $jd = 3; then
31ed1192 1190 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1191 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1192 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1193 fi
f295c17b
BP
1194 done
1195 done
1196
4d5c43d5 1197 # Broadcast and multicast.
f295c17b
BP
1198 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1199 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1200 if test $js = 1; then
f295c17b
BP
1201 bcast_impersonate=$bcast
1202 else
4d5c43d5
JP
1203 bcast_impersonate=
1204 fi
f295c17b
BP
1205 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1206
1207 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1208
1209 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1210 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1211 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1212 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1213 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1214 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1215 done
1216done
1217
7dc88496
NS
1218# set address for lp13 with invalid characters.
1219# lp13 should be configured with only 192.168.0.13.
31ed1192 1220ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1221
1222# Allow some time for ovn-northd and ovn-controller to catch up.
1223# XXX This should be more systematic.
1224sleep 1
1225
7dc88496
NS
1226sip=`ip_to_hex 192 168 0 11`
1227tip=`ip_to_hex 192 168 0 13`
1228test_arp 11 f00000000011 $sip $tip f00000000013
1229
1230tip=`ip_to_hex 192 169 0 13`
1231#arp request for 192.169.0.13 should be flooded
1232test_arp 11 f00000000011 $sip $tip
1233
91125642 1234# dump information and flows with counters
bb0c41d3
RM
1235ovn-sbctl dump-flows -- list multicast_group
1236
1237echo "------ hv1 dump ------"
1238as hv1 ovs-vsctl show
1239as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1240
1241echo "------ hv2 dump ------"
1242as hv2 ovs-vsctl show
1243as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1244
1245echo "------ hv3 dump ------"
1246as hv3 ovs-vsctl show
1247as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1248
f295c17b
BP
1249# Now check the packets actually received against the ones expected.
1250for i in 1 2 3; do
1251 for j in 1 2 3; do
49d7c759 1252 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1253 done
1254done
fcde56f5 1255
7a8f15e0 1256OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1257
f295c17b 1258AT_CLEANUP
eb6b08eb 1259
4acd1e87
BP
1260AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1261AT_SKIP_IF([test $HAVE_PYTHON = no])
1262ovn_start
1263
1264# Create a logical switch and some logical ports.
1265# Turn on port security on all lports except ls1.
1266# Make ls1 a destination for unknown MACs.
1267# Add some ACLs for Ethertypes 1234, 1235, 1236.
1268ovn-nbctl ls-add lsw0
1269ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1270for i in 1 2 3; do
1271 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1272done
1273ovn-nbctl --wait=sb sync
1274for i in 1 2 3; do
4acd1e87
BP
1275 ovn-sbctl lsp-bind lp$i hv0
1276 if test $i = 1; then
abb37b6b 1277 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1278 else
abb37b6b
FF
1279 if test $i = 3; then
1280 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1281 else
1282 ip_addrs="192.168.0.$i"
1283 fi
1284 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:$i $ip_addrs"
1285 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:$i
4acd1e87
BP
1286 fi
1287done
1288ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1289ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1290ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1291ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1292ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1293
1294ovn-nbctl --wait=sb sync
1295on_exit 'kill `cat ovn-trace.pid`'
1296ovn-trace --detach --pidfile --no-chdir
1297
1298# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1299#
1300# This shell function causes a packet to be received on INPORT. The packet's
1301# content has Ethernet destination DST and source SRC (each exactly 12 hex
1302# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1303# more) list the VIFs on which the packet should be received. INPORT and the
1304# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1305test_packet() {
1306 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1307 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1308 while :; do
abb37b6b
FF
1309 case $1 in # (
1310 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1311 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1312 *) break ;;
1313 esac
4acd1e87
BP
1314 done
1315 for outport; do
abb37b6b 1316 echo "output(\"lp$outport\");"
4acd1e87
BP
1317 done > expout
1318
1319 AT_CAPTURE_FILE([trace])
1320 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1321}
1322
1323# test_arp INPORT SHA SPA TPA [REPLY_HA]
1324#
1325# Causes a packet to be received on INPORT. The packet is an ARP
1326# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1327# it should be the hardware address of the target to expect to receive in an
1328# ARP reply; otherwise no reply is expected.
1329#
1330# INPORT is an logical switch port number, e.g. 11 for vif11.
1331# SHA and REPLY_HA are each 12 hex digits.
1332# SPA and TPA are each 8 hex digits.
1333test_arp() {
1334 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1335
1336 local request="inport == \"lp$inport\"
1337 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1338 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1339 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1340
1341 if test -z "$reply_ha"; then
1342 reply=
abb37b6b
FF
1343 local i
1344 for i in 1 2 3; do
1345 if test $i != $inport; then
1346 reply="${reply}output(\"lp$i\");
4acd1e87 1347"
abb37b6b
FF
1348 fi
1349 done
4acd1e87
BP
1350 else
1351 reply="\
1352eth.dst = $sha;
1353eth.src = $reply_ha;
1354arp.op = 2;
1355arp.tha = $sha;
1356arp.sha = $reply_ha;
1357arp.tpa = $spa;
1358arp.spa = $tpa;
1359output(\"lp$inport\");
1360"
1361 fi
1362
1363 AT_CAPTURE_FILE([trace])
1364 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1365}
1366
1367# Send packets between all pairs of source and destination ports:
1368#
1369# 1. Unicast packets are delivered to exactly one logical switch port
1370# (except that packets destined to their input ports are dropped).
1371#
1372# 2. Broadcast and multicast are delivered to all logical switch ports
1373# except the input port.
1374#
1375# 3. When port security is turned on, the switch drops packets from the wrong
1376# MAC address.
1377#
1378# 4. The switch drops all packets with a VLAN tag.
1379#
1380# 5. The switch drops all packets with a multicast source address. (This only
1381# affects behavior when port security is turned off, since otherwise port
1382# security would drop the packet anyway.)
1383#
1384# 6. The switch delivers packets with an unknown destination to logical
1385# switch ports with "unknown" among their MAC addresses (and port
1386# security disabled).
1387#
1388# 7. The switch drops unicast packets that violate an ACL.
1389#
1390# 8. The switch drops multicast and broadcast packets that violate an ACL.
1391#
9fcb6a18
BP
1392# 9. OVN generates responses to ARP requests for known IPs, except for
1393# requests from a port for the port's own IP.
4acd1e87
BP
1394#
1395# 10. No response to ARP requests for unknown IPs.
1396
1397for s in 1 2 3; do
1398 bcast=
1399 unknown=
1400 bacl2=
1401 bacl3=
1402 for d in 1 2 3; do
abb37b6b
FF
1403 echo
1404 echo "lp$s -> lp$d"
1405 if test $d != $s; then unicast=$d; else unicast=; fi
1406 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1407
1408 if test $d != $s && test $s = 1; then
1409 impersonate=$d
1410 else
1411 impersonate=
1412 fi
1413 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1414
1415 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1416 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1417 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1418 # Source of 1 or 2 and dest of 3 should be dropped
1419 # due to the 4th ACL that uses address_set(set1).
1420 acl4=
1421 else
1422 acl4=$d
1423 fi
1424
1425 #7, acl1 to acl4:
1426 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1427 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1428 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1429 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1430
1431 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1432 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1433
1434 if test $d != $s && test $d = 1; then
1435 unknown="$unknown $d"
1436 fi
1437 bcast="$bcast $unicast"
1438 bacl2="$bacl2 $acl2"
1439 bacl3="$bacl3 $acl3"
1440
1441 sip=192.168.0.$s
1442 tip=192.168.0.$d
1443 tip_unknown=11.11.11.11
9fcb6a18
BP
1444 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1445 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1446 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1447
1448 if test $d = 3; then
1449 # lp3 has an additional ip 192.169.0.[123]3.
1450 tip=192.169.0.$d
9fcb6a18 1451 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1452 fi
4acd1e87
BP
1453 done
1454
1455 # Broadcast and multicast.
1456 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1457 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1458 if test $s = 1; then
abb37b6b 1459 bcast_impersonate=$bcast
4acd1e87 1460 else
abb37b6b 1461 bcast_impersonate=
4acd1e87
BP
1462 fi
1463 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1464
1465 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1466
1467 #8, acl1 to acl3:
1468 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1469 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1470 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1471
1472 #8, acl1 to acl3:
1473 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1474 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1475 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1476done
1477
1478AT_CLEANUP
1479
7277bc83
RB
1480# 2 hypervisors, 4 logical ports per HV
1481# 2 locally attached networks (one flat, one vlan tagged over same device)
1482# 2 ports per HV on each network
e90aeb57 1483AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1484AT_SKIP_IF([test $HAVE_PYTHON = no])
1485ovn_start
1486
ea46a4e9
JP
1487# In this test cases we create 3 switches, all connected to same
1488# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1489# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1490# of VIF port name indicates the hypervisor it is bound to, e.g.
1491# lp23 means VIF 3 on hv2.
1492#
ea46a4e9 1493# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1494# - ls1:
1495# - untagged
ea46a4e9 1496# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1497#
1498# - ls2:
1499# - tagged with VLAN 101
ea46a4e9 1500# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1501# - ls3:
1502# - untagged
ea46a4e9 1503# - ports: lp15, lp25
0ee7f7f1 1504#
ea46a4e9 1505# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1506# physical network.
1507
1508for i in 1 2 3; do
ea46a4e9
JP
1509 ls_name=ls$i
1510 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1511 ln_port_name=ln$i
1512 if test $i -eq 2; then
ea46a4e9 1513 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1514 else
ea46a4e9 1515 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1516 fi
31ed1192
JP
1517 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1518 ovn-nbctl lsp-set-type $ln_port_name localnet
1519 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1520done
d79fc5f4
RB
1521
1522net_add n1
1523for i in 1 2; do
1524 sim_add hv$i
1525 as hv$i
1526 ovs-vsctl add-br br-phys
1527 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1528 ovn_attach n1 br-phys 192.168.0.$i
1529
0ee7f7f1 1530 for j in 1 2 3 4 5; do
d79fc5f4
RB
1531 ovs-vsctl add-port br-int vif$i$j -- \
1532 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1533 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1534 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1535 ofport-request=$i$j
1536
31ed1192 1537 lsp_name=lp$i$j
7277bc83 1538 if test $j -le 2; then
ea46a4e9 1539 ls_name=ls1
0ee7f7f1 1540 elif test $j -le 4; then
ea46a4e9 1541 ls_name=ls2
d79fc5f4 1542 else
ea46a4e9 1543 ls_name=ls3
d79fc5f4 1544 fi
d79fc5f4 1545
ea46a4e9 1546 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1547 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1548 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1549
31ed1192 1550 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1551 done
1552done
1553
1554ovn_populate_arp
1555
1556# XXX This is now the 3rd copy of these functions in this file ...
1557
1558# Given the name of a logical port, prints the name of the hypervisor
1559# on which it is located.
1560vif_to_hv() {
1561 echo hv${1%?}
1562}
1563#
1564# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1565#
1566# This shell function causes a packet to be received on INPORT. The packet's
1567# content has Ethernet destination DST and source SRC (each exactly 12 hex
1568# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1569# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1570# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
d79fc5f4 1571for i in 1 2; do
0ee7f7f1 1572 for j in 1 2 3 4 5; do
d79fc5f4
RB
1573 : > $i$j.expected
1574 done
1575done
1576test_packet() {
1577 local inport=$1 src=$2 dst=$3 eth=$4; shift; shift; shift; shift
1578 local packet=${src}${dst}${eth}
1579 hv=`vif_to_hv $inport`
1580 vif=vif$inport
1581 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1582 for outport; do
e4543cfe 1583 echo $packet >> $outport.expected
d79fc5f4
RB
1584 done
1585}
1586
7277bc83
RB
1587# lp11 and lp21 are on the same network (phys, untagged)
1588# and on different hypervisors
d79fc5f4
RB
1589test_packet 11 f00000000021 f00000000011 1121 21
1590test_packet 21 f00000000011 f00000000021 2111 11
1591
7277bc83
RB
1592# lp11 and lp12 are on the same network (phys, untagged)
1593# and on the same hypervisor
e90aeb57
RB
1594test_packet 11 f00000000012 f00000000011 1112 12
1595test_packet 12 f00000000011 f00000000012 1211 11
7277bc83
RB
1596
1597# lp13 and lp23 are on the same network (phys, VLAN 101)
1598# and on different hypervisors
1599test_packet 13 f00000000023 f00000000013 1323 23
1600test_packet 23 f00000000013 f00000000023 2313 13
1601
1602# lp13 and lp14 are on the same network (phys, VLAN 101)
1603# and on the same hypervisor
e90aeb57
RB
1604test_packet 13 f00000000014 f00000000013 1314 14
1605test_packet 14 f00000000013 f00000000014 1413 13
d79fc5f4 1606
0ee7f7f1 1607# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1608# same hypervisor, and on different switches
0ee7f7f1
HZ
1609test_packet 11 f00000000015 f00000000011 1115 15
1610test_packet 15 f00000000011 f00000000015 1511 11
1611
1612# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1613# different hypervisors, and on different switches
0ee7f7f1
HZ
1614test_packet 11 f00000000025 f00000000011 1125 25
1615test_packet 25 f00000000011 f00000000025 2511 11
1616
d79fc5f4 1617# Ports that should not be able to communicate
7277bc83
RB
1618test_packet 11 f00000000013 f00000000011 1113
1619test_packet 11 f00000000023 f00000000011 1123
1620test_packet 21 f00000000013 f00000000021 2113
1621test_packet 21 f00000000023 f00000000021 2123
1622test_packet 13 f00000000011 f00000000013 1311
1623test_packet 13 f00000000021 f00000000013 1321
1624test_packet 23 f00000000011 f00000000023 2311
1625test_packet 23 f00000000021 f00000000023 2321
d79fc5f4 1626
d79fc5f4
RB
1627# Dump a bunch of info helpful for debugging if there's a failure.
1628
1629echo "------ OVN dump ------"
1630ovn-nbctl show
1631ovn-sbctl show
1632
1633echo "------ hv1 dump ------"
1634as hv1 ovs-vsctl show
1635as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1636
1637echo "------ hv2 dump ------"
1638as hv2 ovs-vsctl show
1639as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1640
1641# Now check the packets actually received against the ones expected.
1642for i in 1 2; do
0ee7f7f1 1643 for j in 1 2 3 4 5; do
49d7c759 1644 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
1645 done
1646done
1647
7a8f15e0 1648OVN_CLEANUP([hv1],[hv2])
d9c8c57c 1649
d79fc5f4
RB
1650AT_CLEANUP
1651
91125642
FF
1652AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
1653AT_KEYWORDS([vtep])
eb6b08eb
JP
1654AT_SKIP_IF([test $HAVE_PYTHON = no])
1655ovn_start
1656
1657# Configure the Northbound database
ea46a4e9 1658ovn-nbctl ls-add lsw0
eb6b08eb 1659
31ed1192
JP
1660ovn-nbctl lsp-add lsw0 lp1
1661ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 1662
31ed1192
JP
1663ovn-nbctl lsp-add lsw0 lp2
1664ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 1665
31ed1192
JP
1666ovn-nbctl lsp-add lsw0 lp-vtep
1667ovn-nbctl lsp-set-type lp-vtep vtep
1668ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
1669ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb
JP
1670
1671net_add n1 # Network to connect hv1, hv2, and vtep
1672net_add n2 # Network to connect vtep and hv3
1673
1674# Create hypervisor hv1 connected to n1
1675sim_add hv1
1676as hv1
1677ovs-vsctl add-br br-phys
1678ovn_attach n1 br-phys 192.168.0.1
1679ovs-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
1680
1681# Create hypervisor hv2 connected to n1
1682sim_add hv2
1683as hv2
1684ovs-vsctl add-br br-phys
1685ovn_attach n1 br-phys 192.168.0.2
1686ovs-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
1687
1688
1689# Start the vtep emulator with a leg in both networks
1690sim_add vtep
1691as vtep
1692
1693ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
1694ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
1695
1696ovs-vsctl add-br br-phys
1697net_attach n1 br-phys
1698
1699mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
1700arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
1701ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
1702ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
1703
1704ovs-vsctl add-br br-vtep
1705net_attach n2 br-vtep
1706
1707vtep-ctl add-ps br-vtep
1708vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
1709vtep-ctl add-ls lsw0
1710
1711start_daemon ovs-vtep br-vtep
1712start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
1713
1714sleep 1
1715
1716vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0
1717
475f0a2c
DB
1718OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
1719 grep -- source`"])
1720# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
1721sleep 1
1722
1723# Add hv3 on the other side of the vtep
1724sim_add hv3
1725as hv3
1726ovs-vsctl add-br br-phys
1727net_attach n2 br-phys
1728
1729ovs-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
1730
1731# Pre-populate the hypervisors' ARP tables so that we don't lose any
1732# packets for ARP resolution (native tunneling doesn't queue packets
1733# for ARP resolution).
1734ovn_populate_arp
1735
1736# Allow some time for ovn-northd and ovn-controller to catch up.
1737# XXX This should be more systematic.
1738sleep 1
6977df72 1739
eb6b08eb
JP
1740# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1741#
1742# This shell function causes a packet to be received on INPORT. The packet's
1743# content has Ethernet destination DST and source SRC (each exactly 12 hex
1744# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1745# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1746# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
1747for i in 1 2 3; do
1748 : > $i.expected
1749done
1750test_packet() {
1751 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1752 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1753 hv=hv$inport
1754 vif=vif$inport
1755 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1756 for outport; do
e4543cfe 1757 echo $packet >> $outport.expected
eb6b08eb
JP
1758 done
1759}
1760
1761# Send packets between all pairs of source and destination ports:
1762#
31ed1192
JP
1763# 1. Unicast packets are delivered to exactly one logical switch port
1764# (except that packets destined to their input ports are dropped).
eb6b08eb 1765#
31ed1192
JP
1766# 2. Broadcast and multicast are delivered to all logical switch ports
1767# except the input port.
eb6b08eb 1768#
ea46a4e9 1769# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1770# switch ports with "unknown" among their MAC addresses (and port
1771# security disabled).
eb6b08eb
JP
1772for s in 1 2 3; do
1773 bcast=
1774 unknown=
1775 for d in 1 2 3; do
1776 if test $d != $s; then unicast=$d; else unicast=; fi
1777 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1778
1779 # The vtep (vif3) is the only one configured for "unknown"
1780 if test $d != $s && test $d = 3; then
1781 unknown="$unknown $d"
1782 fi
1783 bcast="$bcast $unicast"
1784 done
1785
1786 # Broadcast and multicast.
46ed1382
DB
1787 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1788 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
1789
1790 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
1791done
1792
bb0c41d3
RM
1793# dump information with counters
1794echo "------ OVN dump ------"
1795ovn-nbctl show
1796ovn-sbctl show
1797
1798echo "------ hv1 dump ------"
1799as hv1 ovs-vsctl show
6195e2e7 1800as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1801as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1802
1803echo "------ hv2 dump ------"
1804as hv2 ovs-vsctl show
6195e2e7 1805as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
1806as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1807
1808echo "------ hv3 dump ------"
1809as hv3 ovs-vsctl show
6754e92d
FF
1810# note: hv3 has no logical port bind, thus it should not have br-int
1811AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
1812[ovs-ofctl: br-int is not a bridge or a socket
1813])
bb0c41d3 1814
eb6b08eb
JP
1815# Now check the packets actually received against the ones expected.
1816for i in 1 2 3; do
49d7c759 1817 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 1818done
fcde56f5
LR
1819
1820# Gracefully terminate daemons
7a8f15e0
LR
1821OVN_CLEANUP([hv1],[hv2],[vtep])
1822OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 1823
eb6b08eb 1824AT_CLEANUP
9975d7be 1825
184bc3ca
RB
1826# Similar test to "hardware GW"
1827AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
1828AT_SKIP_IF([test $HAVE_PYTHON = no])
1829ovn_start
1830
1831# Configure the Northbound database
1832ovn-nbctl ls-add lsw0
1833
1834ovn-nbctl lsp-add lsw0 lp1
1835ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
1836
1837ovn-nbctl lsp-add lsw0 lp2
1838ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
1839
1840ovn-nbctl lsp-add lsw0 lp-gw
1841ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 1842ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
1843ovn-nbctl lsp-set-addresses lp-gw unknown
1844
1845net_add n1 # Network to connect hv1, hv2, and gw
1846net_add n2 # Network to connect gw and hv3
1847
1848# Create hypervisor hv1 connected to n1
1849sim_add hv1
1850as hv1
1851ovs-vsctl add-br br-phys
1852ovn_attach n1 br-phys 192.168.0.1
1853ovs-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
1854
1855# Create hypervisor hv2 connected to n1
1856sim_add hv2
1857as hv2
1858ovs-vsctl add-br br-phys
1859ovn_attach n1 br-phys 192.168.0.2
1860ovs-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
1861
1862# Create hypervisor hv_gw connected to n1 and n2
1863# connect br-phys bridge to n1; connect hv-gw bridge to n2
1864sim_add hv_gw
1865as hv_gw
1866ovs-vsctl add-br br-phys
1867ovn_attach n1 br-phys 192.168.0.3
1868ovs-vsctl add-br br-phys2
1869net_attach n2 br-phys2
1870ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
1871
184bc3ca
RB
1872# Add hv3 on the other side of the GW
1873sim_add hv3
1874as hv3
1875ovs-vsctl add-br br-phys
1876net_attach n2 br-phys
1877ovs-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
1878
1879
1880# Pre-populate the hypervisors' ARP tables so that we don't lose any
1881# packets for ARP resolution (native tunneling doesn't queue packets
1882# for ARP resolution).
1883ovn_populate_arp
1884
1885# Allow some time for ovn-northd and ovn-controller to catch up.
1886# XXX This should be more systematic.
1887sleep 1
1888
1889# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1890#
1891# This shell function causes a packet to be received on INPORT. The packet's
1892# content has Ethernet destination DST and source SRC (each exactly 12 hex
1893# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1894# more) list the VIFs on which the packet should be received. INPORT and the
1895# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
1896for i in 1 2 3; do
1897 : > $i.expected
1898done
1899test_packet() {
1900 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
1901 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
1902 hv=hv$inport
1903 vif=vif$inport
1904 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1905 for outport; do
e4543cfe 1906 echo $packet >> $outport.expected
184bc3ca
RB
1907 done
1908}
1909
1910# Send packets between all pairs of source and destination ports:
1911#
1912# 1. Unicast packets are delivered to exactly one lport (except that packets
1913# destined to their input ports are dropped).
1914#
1915# 2. Broadcast and multicast are delivered to all lports except the input port.
1916#
1917# 3. The lswitch delivers packets with an unknown destination to lports with
1918# "unknown" among their MAC addresses (and port security disabled).
1919for s in 1 2 3 ; do
1920 bcast=
1921 unknown=
1922 for d in 1 2 3 ; do
1923 if test $d != $s; then unicast=$d; else unicast=; fi
1924 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
1925
1926 # The vtep (vif3) is the only one configured for "unknown"
1927 if test $d != $s && test $d = 3; then
1928 unknown="$unknown $d"
1929 fi
1930 bcast="$bcast $unicast"
1931 done
1932
1933 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
1934 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
1935 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
1936done
1937
184bc3ca
RB
1938echo "------ ovn-nbctl show ------"
1939ovn-nbctl show
1940echo "------ ovn-sbctl show ------"
1941ovn-sbctl show
1942
1943echo "------ hv1 ------"
1944as hv1 ovs-vsctl show
1945echo "------ hv1 br-int ------"
1946as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1947echo "------ hv1 br-phys ------"
1948as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1949
1950echo "------ hv2 ------"
1951as hv2 ovs-vsctl show
1952echo "------ hv2 br-int ------"
1953as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1954echo "------ hv2 br-phys ------"
1955as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1956
1957echo "------ hv_gw ------"
1958as hv_gw ovs-vsctl show
1959echo "------ hv_gw br-phys ------"
1960as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
1961echo "------ hv_gw br-phys2 ------"
1962as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
1963
1964echo "------ hv3 ------"
1965as hv3 ovs-vsctl show
1966echo "------ hv3 br-phys ------"
1967as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
1968
1969# Now check the packets actually received against the ones expected.
1970for i in 1 2 3; do
49d7c759 1971 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
1972done
1973AT_CLEANUP
1974
9975d7be
BP
1975# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
1976AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
1977AT_SKIP_IF([test $HAVE_PYTHON = no])
1978ovn_start
1979
1980# Logical network:
1981#
1982# Three logical switches ls1, ls2, ls3.
86e98048
BP
1983# One logical router lr0 connected to ls[123],
1984# with nine subnets, three per logical switch:
1985#
1986# lrp11 on ls1 for subnet 192.168.11.0/24
1987# lrp12 on ls1 for subnet 192.168.12.0/24
1988# lrp13 on ls1 for subnet 192.168.13.0/24
1989# ...
1990# lrp33 on ls3 for subnet 192.168.33.0/24
1991#
1992# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
1993# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 1994for i in 1 2 3; do
ea46a4e9 1995 ovn-nbctl ls-add ls$i
9975d7be 1996 for j in 1 2 3; do
86e98048 1997 for k in 1 2 3; do
31ed1192
JP
1998 # Add "unknown" to MAC addresses for lp?11, so packets for
1999 # MAC-IP bindings discovered via ARP later have somewhere to go.
2000 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2001
2002 ovn-nbctl \
2003 -- lsp-add ls$i lp$i$j$k \
2004 -- lsp-set-addresses lp$i$j$k "f0:00:00:00:0$i:$j$k \
2005 192.168.$i$j.$k" $unknown
86e98048
BP
2006 done
2007 done
2008done
2009
fa2a27b2 2010ovn-nbctl lr-add lr0
86e98048
BP
2011for i in 1 2 3; do
2012 for j in 1 2 3; do
bf44c2cd 2013 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2014 ovn-nbctl \
31ed1192 2015 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2016 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2017 options:router-port=lrp$i$j \
86e98048 2018 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2019 done
2020done
2021
80f408f4 2022ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2023 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2024
9975d7be
BP
2025# Physical network:
2026#
2027# Three hypervisors hv[123].
86e98048
BP
2028# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2029# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2030# lp?3[123] all on hv3.
2031
9975d7be
BP
2032
2033# Given the name of a logical port, prints the name of the hypervisor
2034# on which it is located.
2035vif_to_hv() {
2036 case $1 in dnl (
86e98048
BP
2037 ?11) echo 1 ;; dnl (
2038 ?12 | ?21 | ?22) echo 2 ;; dnl (
2039 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2040 esac
2041}
2042
86e98048
BP
2043# Given the name of a logical port, prints the name of its logical router
2044# port, e.g. "vif_to_lrp 123" yields 12.
2045vif_to_lrp() {
2046 echo ${1%?}
2047}
2048
2049# Given the name of a logical port, prints the name of its logical
2050# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2051vif_to_ls() {
86e98048 2052 echo ${1%??}
e3393e3f
BP
2053}
2054
9975d7be
BP
2055net_add n1
2056for i in 1 2 3; do
2057 sim_add hv$i
2058 as hv$i
2059 ovs-vsctl add-br br-phys
2060 ovn_attach n1 br-phys 192.168.0.$i
2061done
2062for i in 1 2 3; do
2063 for j in 1 2 3; do
86e98048 2064 for k in 1 2 3; do
269ecccc
JP
2065 hv=`vif_to_hv $i$j$k`
2066 as hv$hv ovs-vsctl \
2067 -- add-port br-int vif$i$j$k \
2068 -- set Interface vif$i$j$k \
2069 external-ids:iface-id=lp$i$j$k \
2070 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2071 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2072 ofport-request=$i$j$k
86e98048 2073 done
9975d7be
BP
2074 done
2075done
2076
2077# Pre-populate the hypervisors' ARP tables so that we don't lose any
2078# packets for ARP resolution (native tunneling doesn't queue packets
2079# for ARP resolution).
2080ovn_populate_arp
2081
2082# Allow some time for ovn-northd and ovn-controller to catch up.
2083# XXX This should be more systematic.
2084sleep 1
2085
e3393e3f 2086# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2087#
2088# This shell function causes a packet to be received on INPORT. The packet's
2089# content has Ethernet destination DST and source SRC (each exactly 12 hex
2090# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2091# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2092# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2093for i in 1 2 3; do
2094 for j in 1 2 3; do
86e98048
BP
2095 for k in 1 2 3; do
2096 : > $i$j$k.expected
269ecccc 2097 done
9975d7be
BP
2098 done
2099done
e3393e3f 2100test_ip() {
9975d7be
BP
2101 # This packet has bad checksums but logical L3 routing doesn't check.
2102 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2103 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2104 shift; shift; shift; shift; shift
2105 hv=hv`vif_to_hv $inport`
2106 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2107 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2108 in_ls=`vif_to_ls $inport`
2109 in_lrp=`vif_to_lrp $inport`
9975d7be 2110 for outport; do
269ecccc 2111 out_ls=`vif_to_ls $outport`
86e98048 2112 if test $in_ls = $out_ls; then
9975d7be
BP
2113 # Ports on the same logical switch receive exactly the same packet.
2114 echo $packet
2115 else
2116 # Routing decrements TTL and updates source and dest MAC
2117 # (and checksum).
269ecccc 2118 out_lrp=`vif_to_lrp $outport`
86e98048 2119 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2120 fi >> $outport.expected
9975d7be
BP
2121 done
2122}
2123
e3393e3f 2124as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2125as hv1 ovn-sbctl list port_binding
2126as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2127as hv1 ovn-sbctl dump-flows
2128as hv1 ovs-ofctl dump-flows br-int
2129
e3393e3f 2130# Send IP packets between all pairs of source and destination ports:
9975d7be 2131#
31ed1192
JP
2132# 1. Unicast IP packets are delivered to exactly one logical switch port
2133# (except that packets destined to their input ports are dropped).
9975d7be 2134#
31ed1192
JP
2135# 2. Broadcast IP packets are delivered to all logical switch ports
2136# except the input port.
86e98048
BP
2137ip_to_hex() {
2138 printf "%02x%02x%02x%02x" "$@"
2139}
9975d7be 2140for is in 1 2 3; do
269ecccc
JP
2141 for js in 1 2 3; do
2142 for ks in 1 2 3; do
2143 bcast=
2144 s=$is$js$ks
2145 smac=f00000000$s
2146 sip=`ip_to_hex 192 168 $is$js $ks`
2147 for id in 1 2 3; do
2148 for jd in 1 2 3; do
2149 for kd in 1 2 3; do
2150 d=$id$jd$kd
2151 dip=`ip_to_hex 192 168 $id$jd $kd`
2152 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2153 if test $d != $s; then unicast=$d; else unicast=; fi
2154
2155 test_ip $s $smac $dmac $sip $dip $unicast #1
2156
2157 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2158 done
2159 done
9975d7be 2160 done
269ecccc
JP
2161 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2162 done
2163 done
e3393e3f
BP
2164done
2165
0bac7164
BP
2166# 3. Send an IP packet from every logical port to every other subnet,
2167# to an IP address that does not have a static IP-MAC binding.
2168# This should generate a broadcast ARP request for the destination
2169# IP address in the destination subnet.
2170for is in 1 2 3; do
269ecccc
JP
2171 for js in 1 2 3; do
2172 for ks in 1 2 3; do
2173 s=$is$js$ks
2174 smac=f00000000$s
2175 sip=`ip_to_hex 192 168 $is$js $ks`
2176 for id in 1 2 3; do
2177 for jd in 1 2 3; do
2178 if test $is$js = $id$jd; then
2179 continue
2180 fi
2181
2182 # Send the packet.
2183 dmac=00000000ff$is$js
2184 # Calculate a 4th octet for the destination that is
2185 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2186 # that have static MAC bindings, and fits in the range
2187 # 0-255.
2188 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2189 dip=`ip_to_hex 192 168 $id$jd $o4`
2190 test_ip $s $smac $dmac $sip $dip
2191
2192 # Every LP on the destination subnet's lswitch should
2193 # receive the ARP request.
2194 lrmac=00000000ff$id$jd
2195 lrip=`ip_to_hex 192 168 $id$jd 254`
2196 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2197 for jd2 in 1 2 3; do
2198 for kd in 1 2 3; do
e4543cfe 2199 echo $arp >> $id$jd2$kd.expected
0bac7164 2200 done
269ecccc 2201 done
0bac7164 2202 done
269ecccc 2203 done
0bac7164 2204 done
269ecccc 2205 done
0bac7164
BP
2206done
2207
e3393e3f
BP
2208# test_arp INPORT SHA SPA TPA [REPLY_HA]
2209#
2210# Causes a packet to be received on INPORT. The packet is an ARP
2211# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2212# it should be the hardware address of the target to expect to receive in an
2213# ARP reply; otherwise no reply is expected.
2214#
31ed1192 2215# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2216# SHA and REPLY_HA are each 12 hex digits.
2217# SPA and TPA are each 8 hex digits.
2218test_arp() {
2219 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2220 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2221 hv=hv`vif_to_hv $inport`
2222 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2223 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2224
57d143eb 2225 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2226 # IP address is not configured to the switch patch port.
e3393e3f 2227 local i=`vif_to_ls $inport`
86e98048 2228 local j k
e3393e3f 2229 for j in 1 2 3; do
86e98048 2230 for k in 1 2 3; do
ea46a4e9 2231 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2232 # so no ARP flooding expected for it.
2233 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2234 echo $request >> $i$j$k.expected
2235 fi
2236 done
e3393e3f
BP
2237 done
2238
2239 # Expect to receive the reply, if any.
2240 if test X$reply_ha != X; then
86e98048
BP
2241 lrp=`vif_to_lrp $inport`
2242 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2243 echo $reply >> $inport.expected
2244 fi
2245}
2246
2247# Test router replies to ARP requests from all source ports:
2248#
0bac7164 2249# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2250#
0bac7164 2251# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2252# in its subnet.
2253#
0bac7164 2254# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2255#
0bac7164 2256# 7. No reply to query for IP address other than router IP.
e3393e3f 2257for i in 1 2 3; do
269ecccc
JP
2258 for j in 1 2 3; do
2259 for k in 1 2 3; do
2260 smac=f00000000$i$j$k # Source MAC
2261 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2262 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2263 rmac=00000000ff$i$j # Router MAC
2264 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2265 test_arp $i$j$k $smac $sip $rip $rmac #4
2266 test_arp $i$j$k $smac $otherip $rip $rmac #5
2267 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2268 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2269 done
269ecccc 2270 done
0bac7164
BP
2271done
2272
2273# Allow some time for packet forwarding.
2274# XXX This can be improved.
2275sleep 1
2276
2277# 8. Generate an ARP reply for each of the IP addresses ARPed for
2278# earlier as #3.
2279#
2280# Here, the $s is the VIF that originated the ARP request and $d is
2281# the VIF that sends the ARP reply, which is somewhat backward but
2282# it means that $s and $d are the same as #3.
2283: > mac_bindings.expected
2284for is in 1 2 3; do
269ecccc
JP
2285 for js in 1 2 3; do
2286 for ks in 1 2 3; do
2287 s=$is$js$ks
2288 for id in 1 2 3; do
2289 for jd in 1 2 3; do
2290 if test $is$js = $id$jd; then
2291 continue
2292 fi
2293
2294 kd=1
2295 d=$id$jd$kd
2296
2297 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2298 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2299 host_mac=8000000000$o4
2300
2301 lrmac=00000000ff$id$jd
2302 lrip=`ip_to_hex 192 168 $id$jd 254`
2303
2304 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2305
2306 echo
2307 echo
2308 echo
2309 hv=hv`vif_to_hv $d`
2310 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2311 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2312 #as $hv ovs-ofctl dump-flows br-int table=19
2313
2314 host_ip_pretty=192.168.$id$jd.$o4
2315 host_mac_pretty=80:00:00:00:00:$o4
2316 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2317 done
269ecccc 2318 done
9975d7be 2319 done
269ecccc 2320 done
9975d7be 2321done
0bac7164 2322
9975d7be
BP
2323# Allow some time for packet forwarding.
2324# XXX This can be improved.
2325sleep 1
2326
0bac7164
BP
2327# 9. Send an IP packet from every logical port to every other subnet. These
2328# are the same packets already sent as #3, but now the destinations' IP-MAC
2329# bindings have been discovered via ARP, so instead of provoking an ARP
2330# request, these packets now get routed to their destinations (which don't
2331# have static MAC bindings, so they go to the port we've designated as
2332# accepting "unknown" MACs.)
2333for is in 1 2 3; do
269ecccc
JP
2334 for js in 1 2 3; do
2335 for ks in 1 2 3; do
2336 s=$is$js$ks
2337 smac=f00000000$s
2338 sip=`ip_to_hex 192 168 $is$js $ks`
2339 for id in 1 2 3; do
2340 for jd in 1 2 3; do
2341 if test $is$js = $id$jd; then
2342 continue
2343 fi
2344
2345 # Send the packet.
2346 dmac=00000000ff$is$js
2347 # Calculate a 4th octet for the destination that is
2348 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2349 # that have static MAC bindings, and fits in the range
2350 # 0-255.
2351 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2352 dip=`ip_to_hex 192 168 $id$jd $o4`
2353 test_ip $s $smac $dmac $sip $dip
2354
2355 # Expect the packet egress.
2356 host_mac=8000000000$o4
2357 outport=${id}11
2358 out_lrp=$id$jd
e4543cfe 2359 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2360 done
269ecccc 2361 done
0bac7164 2362 done
269ecccc 2363 done
0bac7164
BP
2364done
2365
0bac7164
BP
2366ovn-sbctl -f csv -d bare --no-heading \
2367 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2368
9975d7be
BP
2369# Now check the packets actually received against the ones expected.
2370for i in 1 2 3; do
2371 for j in 1 2 3; do
86e98048 2372 for k in 1 2 3; do
abb37b6b
FF
2373 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2374 [$i$j$k.expected])
86e98048 2375 done
9975d7be
BP
2376 done
2377done
fcde56f5 2378
0bac7164
BP
2379# Check the MAC bindings against those expected.
2380AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2381])
2382
fcde56f5 2383# Gracefully terminate daemons
7a8f15e0 2384OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2385
9975d7be 2386AT_CLEANUP
685f4dfe
NS
2387
2388# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2389AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2390AT_SKIP_IF([test $HAVE_PYTHON = no])
2391ovn_start
2392
2393# Create hypervisors hv[123].
2394# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2395# Add all of the vifs to a single logical switch lsw0.
2396# Turn off port security on vifs vif[123]1
2397# Turn on l2 port security on vifs vif[123]2
2398# Turn of l2 and l3 port security on vifs vif[123]3
2399# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2400ovn-nbctl ls-add lsw0
685f4dfe
NS
2401net_add n1
2402for i in 1 2 3; do
2403 sim_add hv$i
2404 as hv$i
2405 ovs-vsctl add-br br-phys
2406 ovn_attach n1 br-phys 192.168.0.$i
2407
2408 for j in 1 2 3; do
2409 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 2410 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2411 if test $j = 1; then
31ed1192 2412 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2413 elif test $j = 2; then
31ed1192
JP
2414 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2415 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2416 else
2417 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2418 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2419 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
2420 fi
2421 done
2422done
2423
685f4dfe
NS
2424# Pre-populate the hypervisors' ARP tables so that we don't lose any
2425# packets for ARP resolution (native tunneling doesn't queue packets
2426# for ARP resolution).
2427ovn_populate_arp
2428
2429# Allow some time for ovn-northd and ovn-controller to catch up.
2430# XXX This should be more systematic.
2431sleep 1
685f4dfe
NS
2432
2433# Given the name of a logical port, prints the name of the hypervisor
2434# on which it is located.
2435vif_to_hv() {
2436 echo hv${1%?}
2437}
2438
685f4dfe
NS
2439for i in 1 2 3; do
2440 for j in 1 2 3; do
2441 : > $i$j.expected
2442 done
2443done
2444
2445# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2446#
2447# This shell function causes an ip packet to be received on INPORT.
2448# The packet's content has Ethernet destination DST and source SRC
2449# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2450# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2451# be received. INPORT and the OUTPORTs are specified as logical switch
2452# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2453test_ip() {
2454 # This packet has bad checksums but logical L3 routing doesn't check.
2455 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2456 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2457 shift; shift; shift; shift; shift
2458 hv=`vif_to_hv $inport`
2459 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2460 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2461 for outport; do
e4543cfe 2462 echo $packet >> $outport.expected
685f4dfe
NS
2463 done
2464}
2465
2466# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2467#
2468# Causes a packet to be received on INPORT. The packet is an ARP
2469# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2470# it should be the hardware address of the target to expect to receive in an
2471# ARP reply; otherwise no reply is expected.
2472#
31ed1192 2473# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2474# SHA and REPLY_HA are each 12 hex digits.
2475# SPA and TPA are each 8 hex digits.
2476test_arp() {
2477 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2478 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2479 hv=`vif_to_hv $inport`
2480 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2481 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2482 if test $drop != 1; then
e137131a 2483 if test X$reply_ha = X; then
685f4dfe
NS
2484 # Expect to receive the broadcast ARP on the other logical switch ports
2485 # if no reply is expected.
2486 local i j
2487 for i in 1 2 3; do
2488 for j in 1 2 3; do
2489 if test $i$j != $inport; then
2490 echo $request >> $i$j.expected
2491 fi
2492 done
2493 done
2494 else
2495 # Expect to receive the reply, if any.
2496 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2497 echo $reply >> $inport.expected
2498 fi
2499 fi
2500}
2501
2502# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2503# This function is similar to test_ip() except that it sends
2504# ipv6 packet
2505test_ipv6() {
2506 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2507 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2508 shift; shift; shift; shift; shift
2509 hv=`vif_to_hv $inport`
2510 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2511 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2512 for outport; do
e4543cfe 2513 echo $packet >> $outport.expected
685f4dfe
NS
2514 done
2515}
2516
9e687b23
DL
2517# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2518# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2519# of the test packet
2520test_icmpv6() {
2521 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2522 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2523 shift; shift; shift; shift; shift; shift
2524 hv=`vif_to_hv $inport`
2525 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2526 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2527 for outport; do
e4543cfe 2528 echo $packet >> $outport.expected
9e687b23
DL
2529 done
2530}
2531
685f4dfe
NS
2532ip_to_hex() {
2533 printf "%02x%02x%02x%02x" "$@"
2534}
2535
2536# no port security
2537sip=`ip_to_hex 192 168 0 12`
2538tip=`ip_to_hex 192 168 0 13`
2539# the arp packet should be allowed even if lp[123]1 is
2540# not configured with mac f00000000023 and ip 192.168.0.12
2541for i in 1 2 3; do
2542 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2543 for j in 1 2 3; do
2544 if test $i != $j; then
2545 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2546 fi
2547 done
2548done
2549
2550# l2 port security
2551sip=`ip_to_hex 192 168 0 12`
2552tip=`ip_to_hex 192 168 0 13`
2553
2554# arp packet should be allowed since lp22 is configured with
2555# mac f00000000022
2556test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2557
2558# arp packet should not be allowed since lp32 is not configured with
2559# mac f00000000021
2560test_arp 32 f00000000021 f00000000021 $sip $tip 1
2561
2562# arp packet with sha set to f00000000021 should not be allowed
2563# for lp12
2564test_arp 12 f00000000012 f00000000021 $sip $tip 1
2565
2566# ip packets should be allowed and received since lp[123]2 do not
2567# have l3 port security
2568sip=`ip_to_hex 192 168 0 55`
2569tip=`ip_to_hex 192 168 0 66`
2570for i in 1 2 3; do
2571 for j in 1 2 3; do
2572 if test $i != $j; then
2573 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2574 fi
2575 done
2576done
2577
2578# ipv6 packets should be received by lp[123]2
2579# lp[123]1 can send ipv6 traffic as there is no port security
2580sip=fe800000000000000000000000000000
2581tip=ff020000000000000000000000000000
2582
2583for i in 1 2 3; do
2584 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2585done
2586
2587
2588# l2 and l3 port security
2589sip=`ip_to_hex 192 168 0 13`
2590tip=`ip_to_hex 192 168 0 22`
2591# arp packet should be allowed since lp13 is configured with
2592# f00000000013 and 192.168.0.13
2593test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2594
2595# the arp packet should be dropped because lp23 is not configured
2596# with mac f00000000022
2597sip=`ip_to_hex 192 168 0 13`
2598tip=`ip_to_hex 192 168 0 22`
2599test_arp 23 f00000000022 f00000000022 $sip $tip 1
2600
2601# the arp packet should be dropped because lp33 is not configured
2602# with ip 192.168.0.55
2603spa=`ip_to_hex 192 168 0 55`
2604tpa=`ip_to_hex 192 168 0 22`
2605test_arp 33 f00000000031 f00000000031 $spa $tpa 1
2606
2607# ip packets should not be received by lp[123]3 since
2608# l3 port security is enabled
2609sip=`ip_to_hex 192 168 0 55`
2610tip=`ip_to_hex 192 168 0 66`
2611for i in 1 2 3; do
2612 for j in 1 2 3; do
2613 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
2614 done
2615done
2616
2617# ipv6 packets should be dropped for lp[123]3 since
2618# it is configured with only ipv4 address
2619sip=fe800000000000000000000000000000
2620tip=ff020000000000000000000000000000
2621
2622for i in 1 2 3; do
2623 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
2624done
2625
2626# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
2627# lp[123]1 can send ipv6 traffic as there is no port security
2628for i in 1 2 3; do
2629 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
2630done
2631
2632# lp13 has extra port security with mac f0000000113 and ipv6 addr
2633# fe80::ea2a:eaff:fe28:0012
2634
2635# ipv4 packet should be dropped for lp13 with mac f0000000113
2636sip=`ip_to_hex 192 168 0 13`
2637tip=`ip_to_hex 192 168 0 23`
2638test_ip 13 f00000000113 f00000000023 $sip $tip
2639
6d53e8a9
BP
2640# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
2641# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
2642# lp11 can send ipv6 traffic as there is no port security
2643sip=ee800000000000000000000000000000
2644for i in 1 2 3; do
6d53e8a9
BP
2645 tip=fe80000000000000ea2aeafffe2800${i}3
2646 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
2647done
2648
2649
2650# ipv6 packet should not be received by lp33 with mac f0000000333
2651# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
2652# configured with fe80::ea2a:eaff:fe28:0033
2653# lp11 can send ipv6 traffic as there is no port security
2654
2655sip=ee800000000000000000000000000000
2656tip=fe80000000000000ea2aeafffe280023
2657test_ipv6 11 f00000000011 f00000000333 $sip $tip
2658
6d53e8a9
BP
2659# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
2660# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
2661# and should be dropped for any other ip6.src
2662# lp21 can receive ipv6 traffic as there is no port security
2663
2664tip=ee800000000000000000000000000000
2665for i in 1 2 3; do
2666 sip=fe80000000000000ea2aeafffe2800${i}3
2667 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
2668
9e687b23 2669 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 2670 sip=00000000000000000000000000000000
9e687b23
DL
2671 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
2672 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
2673 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
2674 # Traffic to non-multicast traffic should be dropped
2675 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
2676 # Traffic of other ICMPv6 types should be dropped
2677 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
2678
2679 # should be dropped
2680 sip=ae80000000000000ea2aeafffe2800aa
2681 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
2682done
2683
31ed1192
JP
2684# configure lsp13 to send and received IPv4 packets with an address range
2685ovn-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 2686
8ff5a966
NS
2687sleep 2
2688
7d9d86ad
NS
2689sip=`ip_to_hex 10 0 0 13`
2690tip=`ip_to_hex 192 168 0 22`
31ed1192 2691# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
2692test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2693
2694sip=`ip_to_hex 10 0 0 14`
2695tip=`ip_to_hex 192 168 0 23`
31ed1192 2696# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
2697# with dst ip 192.168.0.23 should be allowed
2698test_ip 13 f00000000013 f00000000023 $sip $tip 23
2699
2700sip=`ip_to_hex 192 168 0 33`
2701tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
2702# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2703# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
2704test_ip 33 f00000000033 f00000000013 $sip $tip 13
2705
2706sip=`ip_to_hex 192 168 0 33`
2707tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
2708# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2709# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
2710test_ip 33 f00000000033 f00000000013 $sip $tip 13
2711
2712sip=`ip_to_hex 192 168 0 33`
2713tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
2714# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2715# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
2716test_ip 33 f00000000033 f00000000013 $sip $tip
2717
2718sip=`ip_to_hex 192 168 0 33`
2719tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
2720# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2721# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
2722test_ip 33 f00000000033 f00000000013 $sip $tip 13
2723
2724sip=`ip_to_hex 192 168 0 33`
2725tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
2726# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2727# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
2728test_ip 33 f00000000033 f00000000013 $sip $tip
2729
2730sip=`ip_to_hex 192 168 0 33`
2731tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
2732# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
2733# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 2734test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 2735
bb0c41d3
RM
2736#dump information including flow counters
2737ovn-nbctl show
2738ovn-sbctl dump-flows -- list multicast_group
2739
2740echo "------ hv1 dump ------"
2741as hv1 ovs-vsctl show
6195e2e7 2742as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2743as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2744
2745echo "------ hv2 dump ------"
2746as hv2 ovs-vsctl show
6195e2e7 2747as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2748as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2749
2750echo "------ hv3 dump ------"
2751as hv3 ovs-vsctl show
6195e2e7 2752as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2753as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
2754
685f4dfe
NS
2755# Now check the packets actually received against the ones expected.
2756for i in 1 2 3; do
2757 for j in 1 2 3; do
49d7c759 2758 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
2759 done
2760done
2761
7a8f15e0 2762OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 2763
685f4dfe 2764AT_CLEANUP
509afdc3
GS
2765
2766AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
2767AT_SKIP_IF([test $HAVE_PYTHON = no])
2768ovn_start
2769
2770# Logical network:
2771# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
2772# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
2773# R2 has ls2 (172.16.1.0/24) connected to it.
2774
fa2a27b2
JP
2775ovn-nbctl lr-add R1
2776ovn-nbctl lr-add R2
509afdc3 2777
ea46a4e9
JP
2778ovn-nbctl ls-add ls1
2779ovn-nbctl ls-add ls2
509afdc3
GS
2780
2781# Connect ls1 to R1
bf44c2cd 2782ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
509afdc3 2783
31ed1192 2784ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 2785 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
509afdc3
GS
2786
2787# Connect ls2 to R2
bf44c2cd 2788ovn-nbctl lrp-add R2 ls2 00:00:00:01:02:04 172.16.1.1/24
509afdc3 2789
31ed1192 2790ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 2791 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
509afdc3
GS
2792
2793# Connect R1 to R2
4685e523
JP
2794ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
2795ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 2796
6d9ecfa9
JP
2797ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
2798ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
2799
2800# Create logical port ls1-lp1 in ls1
31ed1192
JP
2801ovn-nbctl lsp-add ls1 ls1-lp1 \
2802-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
509afdc3
GS
2803
2804# Create logical port ls2-lp1 in ls2
31ed1192
JP
2805ovn-nbctl lsp-add ls2 ls2-lp1 \
2806-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
509afdc3
GS
2807
2808# Create two hypervisor and create OVS ports corresponding to logical ports.
2809net_add n1
2810
2811sim_add hv1
2812as hv1
2813ovs-vsctl add-br br-phys
2814ovn_attach n1 br-phys 192.168.0.1
2815ovs-vsctl -- add-port br-int hv1-vif1 -- \
2816 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
2817 options:tx_pcap=hv1/vif1-tx.pcap \
2818 options:rxq_pcap=hv1/vif1-rx.pcap \
2819 ofport-request=1
2820
2821sim_add hv2
2822as hv2
2823ovs-vsctl add-br br-phys
2824ovn_attach n1 br-phys 192.168.0.2
2825ovs-vsctl -- add-port br-int hv2-vif1 -- \
2826 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
2827 options:tx_pcap=hv2/vif1-tx.pcap \
2828 options:rxq_pcap=hv2/vif1-rx.pcap \
2829 ofport-request=1
2830
2831
2832# Pre-populate the hypervisors' ARP tables so that we don't lose any
2833# packets for ARP resolution (native tunneling doesn't queue packets
2834# for ARP resolution).
2835ovn_populate_arp
2836
2837# Allow some time for ovn-northd and ovn-controller to catch up.
2838# XXX This should be more systematic.
2839sleep 1
2840
2841# Send ip packets between the two ports.
2842ip_to_hex() {
2843 printf "%02x%02x%02x%02x" "$@"
2844}
509afdc3
GS
2845
2846# Packet to send.
2847src_mac="f00000010203"
2848dst_mac="000000010203"
2849src_ip=`ip_to_hex 192 168 1 2`
2850dst_ip=`ip_to_hex 172 16 1 2`
2851packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2852as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2853
2854
2855echo "---------NB dump-----"
2856ovn-nbctl show
2857echo "---------------------"
2858ovn-nbctl list logical_router
2859echo "---------------------"
2860ovn-nbctl list logical_router_port
2861echo "---------------------"
2862
2863echo "---------SB dump-----"
2864ovn-sbctl list datapath_binding
2865echo "---------------------"
2866ovn-sbctl list port_binding
2867echo "---------------------"
2868
2869echo "------ hv1 dump ----------"
8dab1022 2870as hv1 ovs-ofctl show br-int
509afdc3
GS
2871as hv1 ovs-ofctl dump-flows br-int
2872echo "------ hv2 dump ----------"
8dab1022 2873as hv2 ovs-ofctl show br-int
509afdc3
GS
2874as hv2 ovs-ofctl dump-flows br-int
2875
2876# Packet to Expect
2877src_mac="000000010204"
2878dst_mac="f00000010204"
49d7c759 2879echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
509afdc3 2880
49d7c759 2881OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 2882
7a8f15e0 2883OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
2884
2885AT_CLEANUP
5412db30
J
2886
2887
4685e523
JP
2888AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
2889AT_KEYWORDS([router-admin-state])
2890AT_SKIP_IF([test $HAVE_PYTHON = no])
2891ovn_start
2892
2893# Logical network:
2894# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
2895# and 172.16.1.0/24) connected to it.
2896
2897ovn-nbctl lr-add R1
2898
2899ovn-nbctl ls-add ls1
2900
2901# Connect ls1 to R1
bf44c2cd 2902ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
2903ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
2904 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
2905
2906# Create logical port ls1-lp1 in ls1
2907ovn-nbctl lsp-add ls1 ls1-lp1 \
2908 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
2909
2910# Create logical port ls1-lp2 in ls1
2911ovn-nbctl lsp-add ls1 ls1-lp2 \
2912 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
2913
2914# Create one hypervisor and create OVS ports corresponding to logical ports.
2915net_add n1
2916
2917sim_add hv1
2918as hv1
2919ovs-vsctl add-br br-phys
2920ovn_attach n1 br-phys 192.168.0.1
2921ovs-vsctl -- add-port br-int vif1 -- \
2922 set interface vif1 external-ids:iface-id=ls1-lp1 \
2923 options:tx_pcap=hv1/vif1-tx.pcap \
2924 options:rxq_pcap=hv1/vif1-rx.pcap \
2925 ofport-request=1
2926
2927ovs-vsctl -- add-port br-int vif2 -- \
2928 set interface vif2 external-ids:iface-id=ls1-lp2 \
2929 options:tx_pcap=hv1/vif2-tx.pcap \
2930 options:rxq_pcap=hv1/vif2-rx.pcap \
2931 ofport-request=1
2932
2933
2934# Allow some time for ovn-northd and ovn-controller to catch up.
2935# XXX This should be more systematic.
2936sleep 1
2937
2938# Send ip packets between the two ports.
2939ip_to_hex() {
2940 printf "%02x%02x%02x%02x" "$@"
2941}
4685e523
JP
2942
2943# Packet to send.
2944src_mac="f00000010203"
2945dst_mac="000000010203"
2946src_ip=`ip_to_hex 192 168 1 2`
2947dst_ip=`ip_to_hex 172 16 1 2`
2948packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2949as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
2950
2951
2952echo "---------NB dump-----"
2953ovn-nbctl show
2954echo "---------------------"
2955ovn-nbctl list logical_router
2956echo "---------------------"
2957ovn-nbctl list logical_router_port
2958echo "---------------------"
2959
2960echo "---------SB dump-----"
2961ovn-sbctl list datapath_binding
2962echo "---------------------"
2963ovn-sbctl list logical_flow
2964echo "---------------------"
2965
2966echo "------ hv1 dump ----------"
2967as hv1 ovs-ofctl dump-flows br-int
2968
2969
2970#Disable router R1
2971ovn-nbctl set Logical_Router R1 enabled=false
2972
3b8cd0ea
BP
2973# Allow some time for ovn-northd and ovn-controller to catch up.
2974# XXX This should be more systematic.
2975sleep 1
2976
4685e523
JP
2977echo "---------SB dump-----"
2978ovn-sbctl list datapath_binding
2979echo "---------------------"
2980ovn-sbctl list logical_flow
2981echo "---------------------"
2982
2983echo "------ hv1 dump ----------"
2984as hv1 ovs-ofctl dump-flows br-int
2985
2986as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
2987
2988# Packet to Expect
2989expect_src_mac="000000010203"
2990expect_dst_mac="f00000010204"
49d7c759 2991echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 2992
49d7c759 2993OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
2994
2995
2996as hv1
2997OVS_APP_EXIT_AND_WAIT([ovn-controller])
2998OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
2999OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3000
3001as ovn-sb
3002OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3003
3004as ovn-nb
3005OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3006
3007as northd
3008OVS_APP_EXIT_AND_WAIT([ovn-northd])
3009
3010as main
3011OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3012OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3013
3014AT_CLEANUP
3015
3016
3017AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3018AT_KEYWORDS([router-admin-state])
3019AT_SKIP_IF([test $HAVE_PYTHON = no])
3020ovn_start
3021
3022# Logical network:
3023# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3024# and has switch ls2 (172.16.1.0/24) connected to it.
3025
fa2a27b2 3026ovn-nbctl lr-add R1
5412db30 3027
ea46a4e9
JP
3028ovn-nbctl ls-add ls1
3029ovn-nbctl ls-add ls2
5412db30
J
3030
3031# Connect ls1 to R1
bf44c2cd 3032ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3033ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3034 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3035
3036# Connect ls2 to R1
bf44c2cd 3037ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3038ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3039 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3040
3041# Create logical port ls1-lp1 in ls1
31ed1192
JP
3042ovn-nbctl lsp-add ls1 ls1-lp1 \
3043-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3044
3045# Create logical port ls2-lp1 in ls2
31ed1192
JP
3046ovn-nbctl lsp-add ls2 ls2-lp1 \
3047-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3048
3049# Create one hypervisor and create OVS ports corresponding to logical ports.
3050net_add n1
3051
3052sim_add hv1
3053as hv1
3054ovs-vsctl add-br br-phys
3055ovn_attach n1 br-phys 192.168.0.1
3056ovs-vsctl -- add-port br-int vif1 -- \
3057 set interface vif1 external-ids:iface-id=ls1-lp1 \
3058 options:tx_pcap=hv1/vif1-tx.pcap \
3059 options:rxq_pcap=hv1/vif1-rx.pcap \
3060 ofport-request=1
3061
3062ovs-vsctl -- add-port br-int vif2 -- \
3063 set interface vif2 external-ids:iface-id=ls2-lp1 \
3064 options:tx_pcap=hv1/vif2-tx.pcap \
3065 options:rxq_pcap=hv1/vif2-rx.pcap \
3066 ofport-request=1
3067
3068
3069# Allow some time for ovn-northd and ovn-controller to catch up.
3070# XXX This should be more systematic.
3071sleep 1
3072
3073# Send ip packets between the two ports.
3074ip_to_hex() {
3075 printf "%02x%02x%02x%02x" "$@"
3076}
5412db30
J
3077
3078# Packet to send.
3079src_mac="f00000010203"
3080dst_mac="000000010203"
3081src_ip=`ip_to_hex 192 168 1 2`
3082dst_ip=`ip_to_hex 172 16 1 2`
3083packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3084as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3085
3086
3087echo "---------NB dump-----"
3088ovn-nbctl show
3089echo "---------------------"
3090ovn-nbctl list logical_router
3091echo "---------------------"
3092ovn-nbctl list logical_router_port
3093echo "---------------------"
3094
3095echo "---------SB dump-----"
3096ovn-sbctl list datapath_binding
3097echo "---------------------"
3098ovn-sbctl list logical_flow
3099echo "---------------------"
3100
3101echo "------ hv1 dump ----------"
3102as hv1 ovs-ofctl dump-flows br-int
3103
5412db30
J
3104#Disable router R1
3105ovn-nbctl set Logical_Router R1 enabled=false
3106
3107echo "---------SB dump-----"
3108ovn-sbctl list datapath_binding
3109echo "---------------------"
3110ovn-sbctl list logical_flow
3111echo "---------------------"
3112
3113echo "------ hv1 dump ----------"
3114as hv1 ovs-ofctl dump-flows br-int
3115
a1361a6e
LR
3116# Allow some time for the disabling of logical router R1 to propagate.
3117# XXX This should be more systematic.
3118sleep 1
3119
5412db30
J
3120as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3121
3122# Packet to Expect
3123expect_src_mac="000000010204"
3124expect_dst_mac="f00000010204"
49d7c759 3125echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3126
49d7c759 3127OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3128
7a8f15e0 3129OVN_CLEANUP([hv1])
5412db30
J
3130
3131AT_CLEANUP
3132
28dc3fe9 3133AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3134AT_SKIP_IF([test $HAVE_PYTHON = no])
3135ovn_start
3136
3137# Logical network:
3138# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3139# network. R1 has switchess foo (192.168.1.0/24)
3140# connected to it.
3141# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3142
fa2a27b2
JP
3143ovn-nbctl lr-add R1
3144ovn-nbctl lr-add R2
28dc3fe9 3145
ea46a4e9
JP
3146ovn-nbctl ls-add foo
3147ovn-nbctl ls-add alice
3148ovn-nbctl ls-add bob
28dc3fe9
SR
3149
3150# Connect foo to R1
bf44c2cd 3151ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3152ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3153 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3154
3155# Connect alice to R2
bf44c2cd 3156ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3157ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3158 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3159
3160# Connect bob to R2
bf44c2cd 3161ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3162ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3163 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3164
3165# Connect R1 to R2
4685e523
JP
3166ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3167ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3168
3169#install static routes
e48ccf3c
JP
3170ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3171ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3172ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3173
3174# Create logical port foo1 in foo
31ed1192
JP
3175ovn-nbctl lsp-add foo foo1 \
3176-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3177
3178# Create logical port alice1 in alice
31ed1192
JP
3179ovn-nbctl lsp-add alice alice1 \
3180-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3181
3182# Create logical port bob1 in bob
31ed1192
JP
3183ovn-nbctl lsp-add bob bob1 \
3184-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3185
3186# Create two hypervisor and create OVS ports corresponding to logical ports.
3187net_add n1
3188
3189sim_add hv1
3190as hv1
3191ovs-vsctl add-br br-phys
3192ovn_attach n1 br-phys 192.168.0.1
3193ovs-vsctl -- add-port br-int hv1-vif1 -- \
3194 set interface hv1-vif1 external-ids:iface-id=foo1 \
3195 options:tx_pcap=hv1/vif1-tx.pcap \
3196 options:rxq_pcap=hv1/vif1-rx.pcap \
3197 ofport-request=1
3198
3199ovs-vsctl -- add-port br-int hv1-vif2 -- \
3200 set interface hv1-vif2 external-ids:iface-id=alice1 \
3201 options:tx_pcap=hv1/vif2-tx.pcap \
3202 options:rxq_pcap=hv1/vif2-rx.pcap \
3203 ofport-request=2
3204
3205sim_add hv2
3206as hv2
3207ovs-vsctl add-br br-phys
3208ovn_attach n1 br-phys 192.168.0.2
3209ovs-vsctl -- add-port br-int hv2-vif1 -- \
3210 set interface hv2-vif1 external-ids:iface-id=bob1 \
3211 options:tx_pcap=hv2/vif1-tx.pcap \
3212 options:rxq_pcap=hv2/vif1-rx.pcap \
3213 ofport-request=1
3214
3215
3216# Pre-populate the hypervisors' ARP tables so that we don't lose any
3217# packets for ARP resolution (native tunneling doesn't queue packets
3218# for ARP resolution).
3219ovn_populate_arp
3220
3221# Allow some time for ovn-northd and ovn-controller to catch up.
3222# XXX This should be more systematic.
3223sleep 1
3224
3225ip_to_hex() {
3226 printf "%02x%02x%02x%02x" "$@"
3227}
28dc3fe9
SR
3228
3229# Send ip packets between foo1 and alice1
3230src_mac="f00000010203"
3231dst_mac="000000010203"
3232src_ip=`ip_to_hex 192 168 1 2`
3233dst_ip=`ip_to_hex 172 16 1 2`
3234packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3235as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3236
3237# Send ip packets between foo1 and bob1
3238src_mac="f00000010203"
3239dst_mac="000000010203"
3240src_ip=`ip_to_hex 192 168 1 2`
3241dst_ip=`ip_to_hex 172 16 2 2`
3242packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3243as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3244
3245echo "---------NB dump-----"
3246ovn-nbctl show
3247echo "---------------------"
3248ovn-nbctl list logical_router
3249echo "---------------------"
3250ovn-nbctl list logical_router_port
3251echo "---------------------"
3252
3253echo "---------SB dump-----"
3254ovn-sbctl list datapath_binding
3255echo "---------------------"
3256ovn-sbctl list port_binding
3257echo "---------------------"
3258
3259echo "------ hv1 dump ----------"
3260as hv1 ovs-ofctl dump-flows br-int
3261echo "------ hv2 dump ----------"
3262as hv2 ovs-ofctl dump-flows br-int
3263
3264# Packet to Expect at bob1
3265src_mac="000000010205"
3266dst_mac="f00000010205"
3267src_ip=`ip_to_hex 192 168 1 2`
3268dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3269echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3270
49d7c759 3271OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3272
3273# Packet to Expect at alice1
3274src_mac="000000010204"
3275dst_mac="f00000010204"
3276src_ip=`ip_to_hex 192 168 1 2`
3277dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3278echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3279
49d7c759 3280OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3281
7a8f15e0 3282OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3283
3284AT_CLEANUP
5412db30 3285
0ee8aaf6 3286AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3287AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3288ovn_start
ea46a4e9 3289ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3290net_add n1
3291sim_add hv
3292as hv
3293ovs-vsctl \
3294 -- add-br br-phys \
3295 -- add-br br-eth0
3296
3297ovn_attach n1 br-phys 192.168.0.1
3298
3299AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3300AT_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])
3301
3302# Create a vif.
31ed1192
JP
3303AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3304AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3305AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3306
3307# Create a localnet port.
31ed1192
JP
3308AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3309AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3310AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3311AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3312
3313AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3314
3315# Wait for packet to be received.
49d7c759
BP
3316echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3317OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6
RR
3318
3319# Delete the localnet ports.
3320AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3321AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3322
7a8f15e0 3323OVN_CLEANUP([hv])
0ee8aaf6
RR
3324
3325AT_CLEANUP
75cf9d2b
GS
3326
3327AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3328AT_SKIP_IF([test $HAVE_PYTHON = no])
3329ovn_start
3330
3331# Logical network:
3332# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3333# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3334# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3335# connected to it.
3336
fa2a27b2
JP
3337ovn-nbctl lr-add R1
3338ovn-nbctl lr-add R2
3339ovn-nbctl lr-add R3
75cf9d2b 3340
ea46a4e9
JP
3341ovn-nbctl ls-add foo
3342ovn-nbctl ls-add alice
3343ovn-nbctl ls-add bob
3344ovn-nbctl ls-add join
75cf9d2b
GS
3345
3346# Connect foo to R1
31114af7 3347ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3348ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3349 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3350
3351# Connect alice to R2
31114af7 3352ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3353ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3354 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3355
3356# Connect bob to R3
31114af7 3357ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3358ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3359 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3360
3361# Connect R1 to join
31114af7 3362ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3363ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3364 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3365
3366# Connect R2 to join
31114af7 3367ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3368ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3369 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3370
3371# Connect R3 to join
31114af7 3372ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3373ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3374 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3375
3376#install static routes
e48ccf3c
JP
3377ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3378ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3379
e48ccf3c
JP
3380ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3381ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3382
e48ccf3c
JP
3383ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3384ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3385
3386# Create logical port foo1 in foo
31ed1192
JP
3387ovn-nbctl lsp-add foo foo1 \
3388-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3389
3390# Create logical port alice1 in alice
31ed1192
JP
3391ovn-nbctl lsp-add alice alice1 \
3392-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3393
3394# Create logical port bob1 in bob
31ed1192
JP
3395ovn-nbctl lsp-add bob bob1 \
3396-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3397
3398# Create two hypervisor and create OVS ports corresponding to logical ports.
3399net_add n1
3400
3401sim_add hv1
3402as hv1
3403ovs-vsctl add-br br-phys
3404ovn_attach n1 br-phys 192.168.0.1
3405ovs-vsctl -- add-port br-int hv1-vif1 -- \
3406 set interface hv1-vif1 external-ids:iface-id=foo1 \
3407 options:tx_pcap=hv1/vif1-tx.pcap \
3408 options:rxq_pcap=hv1/vif1-rx.pcap \
3409 ofport-request=1
3410
3411ovs-vsctl -- add-port br-int hv1-vif2 -- \
3412 set interface hv1-vif2 external-ids:iface-id=alice1 \
3413 options:tx_pcap=hv1/vif2-tx.pcap \
3414 options:rxq_pcap=hv1/vif2-rx.pcap \
3415 ofport-request=2
3416
3417sim_add hv2
3418as hv2
3419ovs-vsctl add-br br-phys
3420ovn_attach n1 br-phys 192.168.0.2
3421ovs-vsctl -- add-port br-int hv2-vif1 -- \
3422 set interface hv2-vif1 external-ids:iface-id=bob1 \
3423 options:tx_pcap=hv2/vif1-tx.pcap \
3424 options:rxq_pcap=hv2/vif1-rx.pcap \
3425 ofport-request=1
3426
3427
3428# Pre-populate the hypervisors' ARP tables so that we don't lose any
3429# packets for ARP resolution (native tunneling doesn't queue packets
3430# for ARP resolution).
3431ovn_populate_arp
3432
3433# Allow some time for ovn-northd and ovn-controller to catch up.
3434# XXX This should be more systematic.
3435sleep 1
3436
3437ip_to_hex() {
3438 printf "%02x%02x%02x%02x" "$@"
3439}
75cf9d2b
GS
3440
3441# Send ip packets between foo1 and alice1
3442src_mac="f00000010203"
3443dst_mac="000001010203"
3444src_ip=`ip_to_hex 192 168 1 2`
3445dst_ip=`ip_to_hex 172 16 1 2`
3446packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3447as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3448as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3449
3450# Send ip packets between foo1 and bob1
3451src_mac="f00000010203"
3452dst_mac="000001010203"
3453src_ip=`ip_to_hex 192 168 1 2`
3454dst_ip=`ip_to_hex 10 32 1 2`
3455packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3456as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3457
3458echo "---------NB dump-----"
3459ovn-nbctl show
3460echo "---------------------"
3461ovn-nbctl list logical_router
3462echo "---------------------"
3463ovn-nbctl list logical_router_port
3464echo "---------------------"
3465
3466echo "---------SB dump-----"
3467ovn-sbctl list datapath_binding
3468echo "---------------------"
3469ovn-sbctl list port_binding
3470echo "---------------------"
3471ovn-sbctl dump-flows
3472echo "---------------------"
3473
3474echo "------ hv1 dump ----------"
3475as hv1 ovs-ofctl show br-int
3476as hv1 ovs-ofctl dump-flows br-int
3477echo "------ hv2 dump ----------"
3478as hv2 ovs-ofctl show br-int
3479as hv2 ovs-ofctl dump-flows br-int
3480echo "----------------------------"
3481
3482# Packet to Expect at bob1
3483src_mac="000003010203"
3484dst_mac="f00000010205"
3485src_ip=`ip_to_hex 192 168 1 2`
3486dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3487echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3488
49d7c759 3489OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3490
3491# Packet to Expect at alice1
3492src_mac="000002010203"
3493dst_mac="f00000010204"
3494src_ip=`ip_to_hex 192 168 1 2`
3495dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3496echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3497
49d7c759 3498OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3499
7a8f15e0 3500OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3501
3502AT_CLEANUP
c1645003 3503
281977f7 3504AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3505AT_SKIP_IF([test $HAVE_PYTHON = no])
3506ovn_start
3507
3508ovn-nbctl ls-add ls1
3509
3510ovn-nbctl lsp-add ls1 ls1-lp1 \
3511-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3512
3513ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3514
3515ovn-nbctl lsp-add ls1 ls1-lp2 \
3516-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3517
3518ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3519
3520ovn-nbctl ls-add ls2
3521ovn-nbctl lsp-add ls2 ls2-lp1 \
3522-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3523ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3524ovn-nbctl lsp-add ls2 ls2-lp2 \
3525-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3526ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3527
3528ovn-nbctl -- --id=@d1 create DHCP_Options cidr=10.0.0.0/24 \
3529options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
3530\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"" \
3531-- add Logical_Switch_Port ls1-lp1 dhcpv4_options @d1 \
3532-- add Logical_Switch_Port ls1-lp2 dhcpv4_options @d1
3533
3534ovn-nbctl -- --id=@d2 create DHCP_Options cidr=30.0.0.0/24 \
3535options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
3536\"lease_time\"=\"3600\"" -- add Logical_Switch_Port ls2-lp2 dhcpv4_options @d2
3537
3538net_add n1
3539sim_add hv1
3540
3541as hv1
3542ovs-vsctl add-br br-phys
3543ovn_attach n1 br-phys 192.168.0.1
3544ovs-vsctl -- add-port br-int hv1-vif1 -- \
3545 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3546 options:tx_pcap=hv1/vif1-tx.pcap \
3547 options:rxq_pcap=hv1/vif1-rx.pcap \
3548 ofport-request=1
3549
3550ovs-vsctl -- add-port br-int hv1-vif2 -- \
3551 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3552 options:tx_pcap=hv1/vif2-tx.pcap \
3553 options:rxq_pcap=hv1/vif2-rx.pcap \
3554 ofport-request=2
3555
3556ovs-vsctl -- add-port br-int hv1-vif3 -- \
3557 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3558 options:tx_pcap=hv1/vif3-tx.pcap \
3559 options:rxq_pcap=hv1/vif3-rx.pcap \
3560 ofport-request=3
3561
3562ovs-vsctl -- add-port br-int hv1-vif4 -- \
3563 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3564 options:tx_pcap=hv1/vif4-tx.pcap \
3565 options:rxq_pcap=hv1/vif4-rx.pcap \
3566 ofport-request=4
3567
3568ovn_populate_arp
3569
3570sleep 2
3571
3572as hv1 ovs-vsctl show
3573
281977f7
NS
3574# This shell function sends a DHCP request packet
3575# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
3576test_dhcp() {
3577 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4
3578 local request=ffffffffffff${src_mac}080045100110000000008011000000000000ffffffff
3579 # udp header and dhcp header
ab187e7e
BP
3580 request=${request}0044004300fc0000
3581 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 3582 # client hardware padding
ab187e7e 3583 request=${request}00000000000000000000
281977f7 3584 # server hostname
ab187e7e
BP
3585 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3586 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3587 # boot file name
ab187e7e
BP
3588 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3589 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3590 request=${request}0000000000000000000000000000000000000000000000000000000000000000
3591 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3592 # dhcp magic cookie
ab187e7e 3593 request=${request}63825363
281977f7 3594 # dhcp message type
ab187e7e 3595 request=${request}3501${dhcp_type}ff
281977f7
NS
3596
3597 if test $offer_ip != 0; then
3598 local srv_mac=$5 srv_ip=$6 expected_dhcp_opts=$7
3599 # total IP length will be the IP length of the request packet
3600 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
3601 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
3602 udp_len=`expr $ip_len - 20`
3603 printf -v ip_len "%x" $ip_len
3604 printf -v udp_len "%x" $udp_len
3605 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
3606 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
3607 # udp header and dhcp header.
3608 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 3609 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 3610 # your ip address
ab187e7e 3611 reply=${reply}${offer_ip}
281977f7 3612 # next server ip address, relay agent ip address, client mac address
ab187e7e 3613 reply=${reply}0000000000000000${src_mac}
281977f7 3614 # client hardware padding
ab187e7e 3615 reply=${reply}00000000000000000000
281977f7 3616 # server hostname
ab187e7e
BP
3617 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3618 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3619 # boot file name
ab187e7e
BP
3620 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3621 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3622 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
3623 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 3624 # dhcp magic cookie
ab187e7e 3625 reply=${reply}63825363
281977f7
NS
3626 # dhcp message type
3627 local dhcp_reply_type=02
3628 if test $dhcp_type = 03; then
3629 dhcp_reply_type=05
3630 fi
ab187e7e 3631 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
3632 echo $reply >> $inport.expected
3633 else
3634 shift; shift; shift; shift;
3635 for outport; do
e4543cfe 3636 echo $request >> $outport.expected
281977f7
NS
3637 done
3638 fi
3639 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3640}
3641
3642reset_pcap_file() {
3643 local iface=$1
3644 local pcap_file=$2
3645 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3646options:rxq_pcap=dummy-rx.pcap
3647 rm -f ${pcap_file}*.pcap
3648 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3649options:rxq_pcap=${pcap_file}-rx.pcap
3650}
3651
3652ip_to_hex() {
3653 printf "%02x%02x%02x%02x" "$@"
3654}
3655
3656AT_CAPTURE_FILE([ofctl_monitor0.log])
3657as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3658--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3659
3660echo "---------NB dump-----"
3661ovn-nbctl show
3662echo "---------------------"
3663echo "---------SB dump-----"
3664ovn-sbctl list datapath_binding
3665echo "---------------------"
3666ovn-sbctl list logical_flow
3667echo "---------------------"
3668
3669echo "---------------------"
3670ovn-sbctl dump-flows
3671echo "---------------------"
3672
3673echo "------ hv1 dump ----------"
3674as hv1 ovs-ofctl dump-flows br-int
3675
3676# Send DHCPDISCOVER.
3677offer_ip=`ip_to_hex 10 0 0 4`
3678server_ip=`ip_to_hex 10 0 0 1`
3679expected_dhcp_opts=0104ffffff0003040a00000136040a000001330400000e10
3680test_dhcp 1 f00000000001 01 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3681
3682# NXT_RESUMEs should be 1.
3683OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3684
3685$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
3686cat 1.expected | cut -c -48 > expout
3687AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
3688# Skipping the IPv4 checksum.
3689cat 1.expected | cut -c 53- > expout
3690AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
3691
3692# ovs-ofctl also resumes the packets and this causes other ports to receive
3693# the DHCP request packet. So reset the pcap files so that its easier to test.
3694reset_pcap_file hv1-vif1 hv1/vif1
3695reset_pcap_file hv1-vif2 hv1/vif2
3696rm -f 1.expected
3697rm -f 2.expected
3698
3699# Send DHCPREQUEST.
3700offer_ip=`ip_to_hex 10 0 0 6`
3701server_ip=`ip_to_hex 10 0 0 1`
3702expected_dhcp_opts=0104ffffff0003040a00000136040a000001330400000e10
3703test_dhcp 2 f00000000002 03 $offer_ip ff1000000001 $server_ip $expected_dhcp_opts
3704
3705# NXT_RESUMEs should be 2.
3706OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3707
3708$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
3709cat 2.expected | cut -c -48 > expout
3710AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
3711# Skipping the IPv4 checksum.
3712cat 2.expected | cut -c 53- > expout
3713AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
3714
3715reset_pcap_file hv1-vif1 hv1/vif1
3716reset_pcap_file hv1-vif2 hv1/vif2
3717rm -f 1.expected
3718rm -f 2.expected
3719
3720# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
3721# but should be resumed without the reply.
3722# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
3723# one from ovn-controller and the other from "ovs-ofctl resume."
3724offer_ip=0
3725test_dhcp 2 f00000000002 08 $offer_ip 1 1
3726
3727# NXT_RESUMEs should be 3.
3728OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3729
3730# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 3731OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
3732
3733reset_pcap_file hv1-vif1 hv1/vif1
3734reset_pcap_file hv1-vif2 hv1/vif2
3735rm -f 1.expected
3736rm -f 2.expected
3737
3738# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
3739# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
3740
3741test_dhcp 3 f00000000003 01 0 4
3742
3743# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
3744# this lport.
3745test_dhcp 4 f00000000004 01 0 3
3746
3747# NXT_RESUMEs should be 3.
3748OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3749
49d7c759
BP
3750OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
3751OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7
NS
3752
3753as hv1
33ac3c83
NS
3754OVS_APP_EXIT_AND_WAIT([ovn-controller])
3755OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3756OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3757
3758as ovn-sb
3759OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3760
3761as ovn-nb
3762OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3763
3764as northd
3765OVS_APP_EXIT_AND_WAIT([ovn-northd])
3766
3767as main
3768OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3769OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3770
3771AT_CLEANUP
3772
40df4566 3773AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
3774AT_SKIP_IF([test $HAVE_PYTHON = no])
3775ovn_start
3776
3777ovn-nbctl ls-add ls1
3778ovn-nbctl lsp-add ls1 ls1-lp1 \
3779-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3780
3781ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
3782
3783ovn-nbctl lsp-add ls1 ls1-lp2 \
3784-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3785
3786ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
3787
40df4566
ZKL
3788ovn-nbctl lsp-add ls1 ls1-lp3 \
3789-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3790
3791ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
3792
33ac3c83
NS
3793ovn-nbctl -- --id=@d1 create DHCP_Options cidr="ae70\:\:/64" \
3794options="\"server_id\"=\"00:00:00:10:00:01\"" \
3795-- add Logical_Switch_Port ls1-lp1 dhcpv6_options @d1 \
3796-- add Logical_Switch_Port ls1-lp2 dhcpv6_options @d1
3797
40df4566
ZKL
3798ovn-nbctl -- --id=@d2 create DHCP_Options cidr="ae70\:\:/64" \
3799options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"" \
3800-- add Logical_Switch_Port ls1-lp3 dhcpv6_options @d2
3801
33ac3c83
NS
3802ovn-nbctl ls-add ls2
3803ovn-nbctl lsp-add ls2 ls2-lp1 \
3804-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
3805ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
3806ovn-nbctl lsp-add ls2 ls2-lp2 \
3807-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
3808ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
3809
3810net_add n1
3811sim_add hv1
3812
3813as hv1
3814ovs-vsctl add-br br-phys
3815ovn_attach n1 br-phys 192.168.0.1
3816ovs-vsctl -- add-port br-int hv1-vif1 -- \
3817 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3818 options:tx_pcap=hv1/vif1-tx.pcap \
3819 options:rxq_pcap=hv1/vif1-rx.pcap \
3820 ofport-request=1
3821
3822ovs-vsctl -- add-port br-int hv1-vif2 -- \
3823 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3824 options:tx_pcap=hv1/vif2-tx.pcap \
3825 options:rxq_pcap=hv1/vif2-rx.pcap \
3826 ofport-request=2
3827
3828ovs-vsctl -- add-port br-int hv1-vif3 -- \
3829 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3830 options:tx_pcap=hv1/vif3-tx.pcap \
3831 options:rxq_pcap=hv1/vif3-rx.pcap \
3832 ofport-request=3
3833
3834ovs-vsctl -- add-port br-int hv1-vif4 -- \
3835 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
3836 options:tx_pcap=hv1/vif4-tx.pcap \
3837 options:rxq_pcap=hv1/vif4-rx.pcap \
3838 ofport-request=4
3839
40df4566
ZKL
3840ovs-vsctl -- add-port br-int hv1-vif5 -- \
3841 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
3842 options:tx_pcap=hv1/vif5-tx.pcap \
3843 options:rxq_pcap=hv1/vif5-rx.pcap \
3844 ofport-request=5
3845
33ac3c83
NS
3846ovn_populate_arp
3847
3848sleep 2
3849
3850trim_zeros() {
3851 sed 's/\(00\)\{1,\}$//'
3852}
3853
3854# This shell function sends a DHCPv6 request packet
40df4566
ZKL
3855# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
3856# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
3857# packet should be received twice (one from ovn-controller and the other
3858# from the "ovs-ofctl monitor br-int resume"
3859test_dhcpv6() {
3860 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
3861 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
3862 # dst ip ff02::1:2
ab187e7e 3863 request=${request}ff020000000000000000000000010002
33ac3c83 3864 # udp header and dhcpv6 header
ab187e7e 3865 request=${request}02220223002affff${msg_code}010203
33ac3c83 3866 # Client identifier
ab187e7e 3867 request=${request}0001000a00030001${src_mac}
33ac3c83 3868 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 3869 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
3870 shift; shift; shift; shift; shift;
3871 if test $offer_ip != 0; then
3872 local server_mac=000000100001
3873 local server_lla=fe80000000000000020000fffe100001
3874 local reply_code=07
3875 if test $msg_code = 01; then
3876 reply_code=02
3877 fi
40df4566
ZKL
3878 local msg_len=54
3879 if test $offer_ip = 1; then
3880 msg_len=28
3881 fi
3882 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 3883 # udp header and dhcpv6 header
ab187e7e 3884 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 3885 # Client identifier
ab187e7e 3886 reply=${reply}0001000a00030001${src_mac}
33ac3c83 3887 # IA-NA
40df4566 3888 if test $offer_ip != 1; then
ab187e7e 3889 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 3890 fi
33ac3c83 3891 # Server identifier
ab187e7e 3892 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
3893 echo $reply | trim_zeros >> $inport.expected
3894 else
3895 for outport; do
3896 echo $request | trim_zeros >> $outport.expected
3897 done
3898 fi
3899
3900 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
3901}
3902
3903reset_pcap_file() {
3904 local iface=$1
3905 local pcap_file=$2
3906 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
3907options:rxq_pcap=dummy-rx.pcap
3908 rm -f ${pcap_file}*.pcap
3909 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
3910options:rxq_pcap=${pcap_file}-rx.pcap
3911}
3912
3913AT_CAPTURE_FILE([ofctl_monitor0.log])
3914as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
3915--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
3916
3917echo "---------NB dump-----"
3918ovn-nbctl show
3919echo "---------------------"
3920echo "---------SB dump-----"
3921ovn-sbctl list datapath_binding
3922echo "---------------------"
3923ovn-sbctl list logical_flow
3924echo "---------------------"
3925
3926echo "---------------------"
3927ovn-sbctl dump-flows
3928echo "---------------------"
3929
3930echo "------ hv1 dump ----------"
3931as hv1 ovs-ofctl dump-flows br-int
3932
3933src_mac=f00000000001
3934src_lla=fe80000000000000f20000fffe000001
3935offer_ip=ae700000000000000000000000000004
3936test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
3937
3938# NXT_RESUMEs should be 1.
3939OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3940
3941$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
3942# cat 1.expected | trim_zeros > expout
3943cat 1.expected | cut -c -120 > expout
3944AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
3945# Skipping the UDP checksum
3946cat 1.expected | cut -c 125- > expout
3947AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
3948
3949rm 1.expected
3950
3951# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
3952# without any modifications and the packet should be received by ls1-lp1.
3953# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
3954# resume and the other from ovs-ofctl monitor resume.
3955
3956reset_pcap_file hv1-vif1 hv1/vif1
3957reset_pcap_file hv1-vif2 hv1/vif2
3958
3959src_mac=f00000000002
3960src_lla=fe80000000000000f20000fffe000002
3961offer_ip=ae700000000000000000000000000005
3962# Set invalid msg_type
3963
3964test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
3965
3966# NXT_RESUMEs should be 2.
3967OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3968
3969# vif2-tx.pcap should not have received the DHCPv6 reply packet
3970rm 2.packets
3971$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
3972AT_CHECK([cat 2.packets], [0], [])
3973
3974# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
3975$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
3976cat 1.expected > expout
3977AT_CHECK([cat 1.packets], [0], [expout])
3978
3979# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
3980# There should be no DHCPv6 reply from ovn-controller and the request packet
3981# should be received by ls2-lp2.
3982
3983src_mac=f00000000003
3984src_lla=fe80000000000000f20000fffe000003
3985test_dhcpv6 3 $src_mac $src_lla 01 0 4
3986
3987# NXT_RESUMEs should be 2 only.
3988OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
3989
3990# vif3-tx.pcap should not have received the DHCPv6 reply packet
3991$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
3992AT_CHECK([cat 3.packets], [0], [])
3993
3994# vif4-tx.pcap should have received the DHCPv6 request packet
3995$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
3996cat 4.expected > expout
3997AT_CHECK([cat 4.packets], [0], [expout])
3998
40df4566
ZKL
3999# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4000# The DHCPv6 reply should doesn't contian offer_ip.
4001src_mac=f00000000022
4002src_lla=fe80000000000000f20000fffe000022
4003reset_pcap_file hv1-vif5 hv1/vif5
4004test_dhcpv6 5 $src_mac $src_lla 01 1 5
4005
4006# NXT_RESUMEs should be 3.
4007OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4008
4009$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4010# Skipping the UDP checksum
4011cat 5.expected | cut -c 1-120,125- > expout
4012AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4013
33ac3c83 4014as hv1
281977f7
NS
4015OVS_APP_EXIT_AND_WAIT([ovn-controller])
4016OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4017OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4018
4019as ovn-sb
4020OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4021
4022as ovn-nb
4023OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4024
4025as northd
4026OVS_APP_EXIT_AND_WAIT([ovn-northd])
4027
4028as main
4029OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4030OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4031
4032AT_CLEANUP
4033
c1645003 4034AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4035AT_SKIP_IF([test $HAVE_PYTHON = no])
4036ovn_start
4037
4038# Logical network:
4039# Two LRs - R1 and R2 that are connected to each other via LS "join"
4040# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4041# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4042# R2 is a gateway router.
4043
4044
4045
4046# Create two hypervisor and create OVS ports corresponding to logical ports.
4047net_add n1
4048
4049sim_add hv1
4050as hv1
4051ovs-vsctl add-br br-phys
4052ovn_attach n1 br-phys 192.168.0.1
4053ovs-vsctl -- add-port br-int hv1-vif1 -- \
4054 set interface hv1-vif1 external-ids:iface-id=foo1 \
4055 options:tx_pcap=hv1/vif1-tx.pcap \
4056 options:rxq_pcap=hv1/vif1-rx.pcap \
4057 ofport-request=1
4058
4059
4060sim_add hv2
4061as hv2
4062ovs-vsctl add-br br-phys
4063ovn_attach n1 br-phys 192.168.0.2
4064ovs-vsctl -- add-port br-int hv2-vif1 -- \
4065 set interface hv2-vif1 external-ids:iface-id=alice1 \
4066 options:tx_pcap=hv2/vif1-tx.pcap \
4067 options:rxq_pcap=hv2/vif1-rx.pcap \
4068 ofport-request=1
4069
4070# Pre-populate the hypervisors' ARP tables so that we don't lose any
4071# packets for ARP resolution (native tunneling doesn't queue packets
4072# for ARP resolution).
4073ovn_populate_arp
4074
4075ovn-nbctl create Logical_Router name=R1
4076ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4077
ea46a4e9
JP
4078ovn-nbctl ls-add foo
4079ovn-nbctl ls-add alice
4080ovn-nbctl ls-add join
c1645003
GS
4081
4082# Connect foo to R1
31114af7 4083ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4084ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4085 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4086
4087# Connect alice to R2
31114af7 4088ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4089ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4090 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4091
4092# Connect R1 to join
31114af7 4093ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4094ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4095 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4096
4097# Connect R2 to join
31114af7 4098ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4099ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4100 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4101
4102
4103#install static routes
4104ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4105ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4106R1 static_routes @lrt
4107
4108ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4109ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4110R2 static_routes @lrt
4111
4112# Create logical port foo1 in foo
31ed1192
JP
4113ovn-nbctl lsp-add foo foo1 \
4114-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4115
4116# Create logical port alice1 in alice
31ed1192
JP
4117ovn-nbctl lsp-add alice alice1 \
4118-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4119
4120
4121# Allow some time for ovn-northd and ovn-controller to catch up.
4122# XXX This should be more systematic.
4123sleep 2
4124
4125ip_to_hex() {
4126 printf "%02x%02x%02x%02x" "$@"
4127}
c1645003
GS
4128
4129# Send ip packets between foo1 and alice1
4130src_mac="f00000010203"
4131dst_mac="000001010203"
4132src_ip=`ip_to_hex 192 168 1 2`
4133dst_ip=`ip_to_hex 172 16 1 2`
4134packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4135
4136echo "---------NB dump-----"
4137ovn-nbctl show
4138echo "---------------------"
4139ovn-nbctl list logical_router
4140echo "---------------------"
4141ovn-nbctl list logical_router_port
4142echo "---------------------"
4143
4144echo "---------SB dump-----"
4145ovn-sbctl list datapath_binding
4146echo "---------------------"
4147ovn-sbctl list port_binding
4148echo "---------------------"
4149ovn-sbctl dump-flows
4150echo "---------------------"
4151ovn-sbctl list chassis
4152ovn-sbctl list encap
4153echo "---------------------"
4154
c1645003
GS
4155# Packet to Expect at alice1
4156src_mac="000002010203"
4157dst_mac="f00000010204"
4158src_ip=`ip_to_hex 192 168 1 2`
4159dst_ip=`ip_to_hex 172 16 1 2`
4160expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4161
4162
4163as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4164as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4165
ab39371d
RM
4166echo "------ hv1 dump after packet 1 ----------"
4167as hv1 ovs-ofctl show br-int
4168as hv1 ovs-ofctl dump-flows br-int
4169echo "------ hv2 dump after packet 1 ----------"
4170as hv2 ovs-ofctl show br-int
4171as hv2 ovs-ofctl dump-flows br-int
4172echo "----------------------------"
4173
49d7c759
BP
4174echo $expected > expected
4175OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4176
34114cf8
GS
4177# Delete the router and re-create it. Things should work as before.
4178ovn-nbctl lr-del R2
4179ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4180# Connect alice to R2
4181ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4182# Connect R2 to join
4183ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4184
4185ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4186ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4187R2 static_routes @lrt
4188
4189# Wait for ovn-controller to catch up.
4190sleep 1
4191
4192# Send the packet again.
4193as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4194
4195echo "------ hv1 dump after packet 2 ----------"
4196as hv1 ovs-ofctl show br-int
4197as hv1 ovs-ofctl dump-flows br-int
4198echo "------ hv2 dump after packet 2 ----------"
4199as hv2 ovs-ofctl show br-int
4200as hv2 ovs-ofctl dump-flows br-int
4201echo "----------------------------"
4202
49d7c759
BP
4203echo $expected >> expected
4204OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4205
7a8f15e0 4206OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4207
4208AT_CLEANUP
bb3c4568
FF
4209
4210AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4211AT_KEYWORDS([router-icmp-reply])
4212AT_SKIP_IF([test $HAVE_PYTHON = no])
4213ovn_start
4214
4215# Logical network:
4216# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4217# and has switch ls2 (172.16.1.0/24) connected to it.
4218
fa2a27b2 4219ovn-nbctl lr-add R1
bb3c4568 4220
ea46a4e9
JP
4221ovn-nbctl ls-add ls1
4222ovn-nbctl ls-add ls2
bb3c4568
FF
4223
4224# Connect ls1 to R1
31114af7 4225ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4226ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4227 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4228
4229# Connect ls2 to R1
31114af7 4230ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4231ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4232 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4233
4234# Create logical port ls1-lp1 in ls1
31ed1192
JP
4235ovn-nbctl lsp-add ls1 ls1-lp1 \
4236-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4237
4238# Create logical port ls2-lp1 in ls2
31ed1192
JP
4239ovn-nbctl lsp-add ls2 ls2-lp1 \
4240-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4241
4242# Create one hypervisor and create OVS ports corresponding to logical ports.
4243net_add n1
4244
4245sim_add hv1
4246as hv1
4247ovs-vsctl add-br br-phys
4248ovn_attach n1 br-phys 192.168.0.1
4249ovs-vsctl -- add-port br-int vif1 -- \
4250 set interface vif1 external-ids:iface-id=ls1-lp1 \
4251 options:tx_pcap=hv1/vif1-tx.pcap \
4252 options:rxq_pcap=hv1/vif1-rx.pcap \
4253 ofport-request=1
4254
4255ovs-vsctl -- add-port br-int vif2 -- \
4256 set interface vif2 external-ids:iface-id=ls2-lp1 \
4257 options:tx_pcap=hv1/vif2-tx.pcap \
4258 options:rxq_pcap=hv1/vif2-rx.pcap \
4259 ofport-request=1
4260
4261
4262# Allow some time for ovn-northd and ovn-controller to catch up.
4263# XXX This should be more systematic.
4264sleep 1
4265
4266
4267ip_to_hex() {
4268 printf "%02x%02x%02x%02x" "$@"
4269}
bb3c4568
FF
4270for i in 1 2; do
4271 : > vif$i.expected
4272done
4273# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4274#
4275# Causes a packet to be received on INPORT. The packet is an ICMPv4
4276# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4277# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4278# provided, then it should be the ip and icmp checksums of the packet
4279# responded; otherwise, no reply is expected.
4280# In the absence of an ip checksum calculation helpers, this relies
4281# on the caller to provide the checksums for the ip and icmp headers.
4282# XXX This should be more systematic.
4283#
4284# INPORT is an lport number, e.g. 11 for vif11.
4285# ETH_SRC and ETH_DST are each 12 hex digits.
4286# IPV4_SRC and IPV4_DST are each 8 hex digits.
4287# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4288# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4289test_ipv4_icmp_request() {
4290 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4291 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4292 shift; shift; shift; shift; shift; shift; shift
4293 shift; shift
4294
4295 # Use ttl to exercise section 4.2.2.9 of RFC1812
4296 local ip_ttl=01
4297 local icmp_id=5fbf
4298 local icmp_seq=0001
4299 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4300 local icmp_type_code_request=0800
4301 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4302 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4303
4304 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4305 if test X$exp_icmp_chksum != X; then
4306 # Expect to receive the reply, if any. In same port where packet was sent.
4307 # Note: src and dst fields are expected to be reversed.
4308 local icmp_type_code_response=0000
4309 local reply_icmp_ttl=fe
4310 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4311 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4312 echo $reply >> vif$inport.expected
4313 fi
4314}
4315
4316# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4317rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4318rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4319l1_ip=$(ip_to_hex 192 168 1 2)
4320l2_ip=$(ip_to_hex 172 16 1 2)
4321
4322# Ping router ip address that is on same subnet as the logical port
4323test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4324test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4325
4326# Ping router ip address that is on the other side of the logical ports
4327test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4328test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4329
4330echo "---------NB dump-----"
4331ovn-nbctl show
4332echo "---------------------"
4333ovn-nbctl list logical_router
4334echo "---------------------"
4335ovn-nbctl list logical_router_port
4336echo "---------------------"
4337
4338echo "---------SB dump-----"
4339ovn-sbctl list datapath_binding
4340echo "---------------------"
4341ovn-sbctl list logical_flow
4342echo "---------------------"
4343
4344echo "------ hv1 dump ----------"
4345as hv1 ovs-ofctl dump-flows br-int
4346
4347# Now check the packets actually received against the ones expected.
4348for inport in 1 2; do
49d7c759 4349 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4350done
4351
7a8f15e0 4352OVN_CLEANUP([hv1])
bb3c4568
FF
4353
4354AT_CLEANUP
94f79fcb
RB
4355
4356# 1 hypervisor, 1 port
4357# make sure that the port state is properly set to up and back down
4358# when created and deleted.
4359AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4360ovn_start
4361
4362ovn-nbctl ls-add ls1
4363ovn-nbctl lsp-add ls1 lp1
4364ovn-nbctl lsp-set-addresses lp1 unknown
4365
4366net_add n1
4367sim_add hv1
4368as hv1 ovs-vsctl add-br br-phys
4369as hv1 ovn_attach n1 br-phys 192.168.0.1
4370
4371as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4372OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4373
4374as hv1 ovs-vsctl del-port br-int vif1
4375OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4376
7a8f15e0 4377OVN_CLEANUP([hv1])
94f79fcb 4378
94f79fcb 4379AT_CLEANUP
e75451fe 4380
ccc6e1db
FF
4381# 1 hypervisor, 1 port
4382# make sure that the OF rules created to support a datapath are added/cleared
4383# when logical switch is created and removed.
4384AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4385AT_KEYWORDS([cleanup])
ccc6e1db
FF
4386ovn_start
4387
4388net_add n1
4389sim_add hv1
4390as hv1 ovs-vsctl add-br br-phys
4391as hv1 ovn_attach n1 br-phys 192.168.0.1
4392
4393# This shell function checks if OF rules in br-int have clauses
4394# related to OVN datapaths. The caller determines if it should find
4395# a match in the output, or not.
4396#
4397# EXPECT_DATAPATH param determines whether flows that refer to
4398# datapath to should be present or not. 0 means
4399# they should not be.
4400# STAGE_INFO param is a simple string to help identify the stage
4401# in the test when this function was invoked.
4402test_datapath_in_of_rules() {
4403 local expect_datapath=$1 stage_info=$2
4404 echo "------ ovn-nbctl show ${stage_info} ------"
4405 ovn-nbctl show
4406 echo "------ ovn-sbctl show ${stage_info} ------"
4407 ovn-sbctl show
4408 echo "------ OF rules ${stage_info} ------"
4409 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4410 # if there is a datapath mentioned in the output, check for the
4411 # magic keyword that represents one, based on the exit status of
4412 # a quiet grep
4413 if test $expect_datapath != 0; then
4618b102 4414 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4415 else
4618b102 4416 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4417 fi
4418}
4419
4420test_datapath_in_of_rules 0 "before ls+port create"
4421
4422ovn-nbctl ls-add ls1
4423ovn-nbctl lsp-add ls1 lp1
4424ovn-nbctl lsp-set-addresses lp1 unknown
4425
4426as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4427OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4428
4429test_datapath_in_of_rules 1 "after port is bound"
4430
4431as hv1 ovs-vsctl del-port br-int vif1
4432OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4433
4434ovn-nbctl lsp-set-addresses lp1
4435ovn-nbctl lsp-del lp1
4436ovn-nbctl ls-del ls1
4437
4438# wait for earlier changes to take effect
4439AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4440
4441# ensure OF rules are no longer present. There used to be a bug here.
4442test_datapath_in_of_rules 0 "after lport+ls removal"
4443
4444OVN_CLEANUP([hv1])
4445
4446AT_CLEANUP
4447
f8a8db39 4448AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4449AT_SKIP_IF([test $HAVE_PYTHON = no])
4450ovn_start
4451
4452#TODO: since patch port for IPv6 logical router port is not ready not,
4453# so we are not going to test vifs on different lswitches cases. Try
4454# to update for that once relevant stuff implemented.
4455
4456# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4457# with. NS packet we test, from one VIF for another VIF, will be replied
4458# by local ovn-controller, but not by target VIF.
4459
4460# Create hypervisors and logical switch lsw0.
4461ovn-nbctl ls-add lsw0
4462net_add n1
4463sim_add hv1
4464as hv1
4465ovs-vsctl add-br br-phys
4466ovn_attach n1 br-phys 192.168.0.2
4467
4468# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4469ovs-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
4470ovn-nbctl lsp-add lsw0 lp1
4471ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4472ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4473
4474# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4475ovs-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
4476ovn-nbctl lsp-add lsw0 lp2
4477ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4478ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4479
4480# Add ACL rule for ICMPv6 on lsw0
4481ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4482ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4483ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4484
4485# Allow some time for ovn-northd and ovn-controller to catch up.
4486# XXX This should be more systematic.
4487sleep 1
4488
4489# Given the name of a logical port, prints the name of the hypervisor
4490# on which it is located.
4491vif_to_hv() {
4492 echo hv1${1%?}
4493}
e75451fe
ZKL
4494for i in 1 2; do
4495 : > $i.expected
4496done
4497
4498# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
4499# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
4500# vif2 will not receive NS packet, since ovn-controller will reply for it.
4501ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
4502na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
4503
4504as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 4505echo $na_packet >> 1.expected
e75451fe 4506
e75451fe
ZKL
4507echo "------ hv1 dump ------"
4508as hv1 ovs-vsctl show
4509as hv1 ovs-ofctl -O OpenFlow13 show br-int
4510as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
4511
4512for i in 1 2; do
49d7c759 4513 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
4514done
4515
7a8f15e0 4516OVN_CLEANUP([hv1])
e75451fe
ZKL
4517
4518AT_CLEANUP
7417d147
RM
4519
4520AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
4521ovn_start
4522
4523net_add n1
4524
4525sim_add hv1
4526as hv1
4527ovs-vsctl add-br br-phys
4528ovn_attach n1 br-phys 192.168.0.1
4529
4530row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
4531ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
4532ovn-nbctl destroy Address_Set $row
4533
4534sleep 1
4535
4536# A bug previously existed in the address set support code
4537# that caused ovn-controller to crash after an address set
4538# was updated and then removed. This test case ensures
4539# that ovn-controller is at least still running after
4540# creating, updating, and deleting an address set.
4541AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
4542
4543OVN_CLEANUP([hv1])
4544
4545AT_CLEANUP
8639f9be
ND
4546
4547AT_SETUP([ovn -- ipam])
8639f9be
ND
4548AT_SKIP_IF([test $HAVE_PYTHON = no])
4549ovn_start
4550
4551# Add a port to a switch that does not have a subnet set, then set the
4552# subnet which should result in an address being allocated for the port.
4553ovn-nbctl ls-add sw0
4554ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 4555ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
4556AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
4557 ["0a:00:00:00:00:01 192.168.1.2"
4558])
4559
4560# Add 9 more ports to sw0, addresses should all be unique.
4561for n in `seq 1 9`; do
11547f85 4562 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4563done
4564AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
4565 ["0a:00:00:00:00:02 192.168.1.3"
4566])
4567AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
4568 ["0a:00:00:00:00:03 192.168.1.4"
4569])
4570AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
4571 ["0a:00:00:00:00:04 192.168.1.5"
4572])
4573AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
4574 ["0a:00:00:00:00:05 192.168.1.6"
4575])
4576AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
4577 ["0a:00:00:00:00:06 192.168.1.7"
4578])
4579AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
4580 ["0a:00:00:00:00:07 192.168.1.8"
4581])
4582AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
4583 ["0a:00:00:00:00:08 192.168.1.9"
4584])
4585AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
4586 ["0a:00:00:00:00:09 192.168.1.10"
4587])
4588AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
4589 ["0a:00:00:00:00:0a 192.168.1.11"
4590])
4591
4592# Trying similar tests with a second switch. MAC addresses should be unique
4593# across both switches but IP's only need to be unique within the same switch.
4594ovn-nbctl ls-add sw1
4595ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 4596ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
4597AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
4598 ["0a:00:00:00:00:0b 192.168.1.2"
4599])
4600
4601for n in `seq 11 19`; do
11547f85 4602 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
4603done
4604AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
4605 ["0a:00:00:00:00:0c 192.168.1.3"
4606])
4607AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
4608 ["0a:00:00:00:00:0d 192.168.1.4"
4609])
4610AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
4611 ["0a:00:00:00:00:0e 192.168.1.5"
4612])
4613AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
4614 ["0a:00:00:00:00:0f 192.168.1.6"
4615])
4616AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
4617 ["0a:00:00:00:00:10 192.168.1.7"
4618])
4619AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
4620 ["0a:00:00:00:00:11 192.168.1.8"
4621])
4622AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
4623 ["0a:00:00:00:00:12 192.168.1.9"
4624])
4625AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
4626 ["0a:00:00:00:00:13 192.168.1.10"
4627])
4628AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
4629 ["0a:00:00:00:00:14 192.168.1.11"
4630])
4631
4632# Change a port's address to test for multiple ip's for a single address entry
4633# and addresses set by the user.
4634ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 4635ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
4636AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
4637 ["0a:00:00:00:00:16 192.168.1.13"
4638])
4639
4640# Test for logical router port address management.
4641ovn-nbctl create Logical_Router name=R1
4642ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
4643network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
4644-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
4645-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 4646ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
4647AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
4648 ["0a:00:00:00:00:18 192.168.1.15"
4649])
4650
4651# Test for address reuse after logical port is deleted.
4652ovn-nbctl lsp-del p0
11547f85 4653ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
4654AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
4655 ["0a:00:00:00:00:19 192.168.1.2"
4656])
4657
4658# Test for multiple addresses to one logical port.
4659ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
4660"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 4661ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
4662AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
4663 ["0a:00:00:00:00:1c 192.168.1.16"
4664])
4665
4666# Test for exhausting subnet address space.
4667ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 4668ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
4669AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
4670 ["0a:00:00:00:00:1d 172.16.1.2"
4671])
4672
11547f85 4673ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be
ND
4674AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
4675 [[[]]
4676])
4677
4678# Test that address management does not add duplicate MAC for lsp/lrp peers.
4679ovn-nbctl create Logical_Router name=R2
4680ovn-nbctl ls-add sw3
4681ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
4682"0a:00:00:00:00:1e"
4683ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
4684network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
4685-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
4686-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 4687ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
4688AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
4689 ["0a:00:00:00:00:20 192.168.1.17"
4690])
4691
6374d518
LR
4692# Test static MAC address with dynamically allocated IP
4693ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
4694"fe:dc:ba:98:76:54 dynamic"
4695AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
4696 ["fe:dc:ba:98:76:54 192.168.1.18"
4697])
4698
8639f9be
ND
4699as ovn-sb
4700OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4701
4702as ovn-nb
4703OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4704
4705as northd
4706OVS_APP_EXIT_AND_WAIT([ovn-northd])
4707
4708AT_CLEANUP
4709
4710AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
4711AT_SKIP_IF([test $HAVE_PYTHON = no])
4712ovn_start
4713
4714ovn-nbctl lr-add R1
4715
4716# Test for a ping using dynamically allocated addresses.
4717ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
4718ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
4719
4720# Connect foo to R1
4721ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
4722ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
4723 options:router-port=foo addresses=\"00:00:00:01:02:03\"
4724
4725# Connect alice to R1
4726ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
4727ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
4728 options:router-port=alice addresses=\"00:00:00:01:02:04\"
4729
4730# Create logical port foo1 in foo
fd3b31e9 4731ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 4732-- lsp-set-addresses foo1 "dynamic"
8bc2c143 4733AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo1 dynamic_addresses='"0a:00:00:00:00:01 192.168.1.2"'], [0])
8639f9be
ND
4734
4735# Create logical port alice1 in alice
fd3b31e9 4736ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 4737-- lsp-set-addresses alice1 "dynamic"
8bc2c143 4738AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port alice1 dynamic_addresses='"0a:00:00:00:00:02 192.168.2.2"'])
8639f9be
ND
4739
4740# Create logical port foo2 in foo
fd3b31e9 4741ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 4742-- lsp-set-addresses foo2 "dynamic"
8bc2c143 4743AT_CHECK([ovn-nbctl --timeout=10 wait-until Logical-Switch-Port foo2 dynamic_addresses='"0a:00:00:00:00:03 192.168.1.3"'])
8639f9be
ND
4744
4745# Create a hypervisor and create OVS ports corresponding to logical ports.
4746net_add n1
4747
4748sim_add hv1
4749as hv1
4750ovs-vsctl add-br br-phys
4751ovn_attach n1 br-phys 192.168.0.1
4752ovs-vsctl -- add-port br-int hv1-vif1 -- \
4753 set interface hv1-vif1 external-ids:iface-id=foo1 \
4754 options:tx_pcap=hv1/vif1-tx.pcap \
4755 options:rxq_pcap=hv1/vif1-rx.pcap \
4756 ofport-request=1
4757
4758ovs-vsctl -- add-port br-int hv1-vif2 -- \
4759 set interface hv1-vif2 external-ids:iface-id=foo2 \
4760 options:tx_pcap=hv1/vif2-tx.pcap \
4761 options:rxq_pcap=hv1/vif2-rx.pcap \
4762 ofport-request=2
4763
4764ovs-vsctl -- add-port br-int hv1-vif3 -- \
4765 set interface hv1-vif3 external-ids:iface-id=alice1 \
4766 options:tx_pcap=hv1/vif3-tx.pcap \
4767 options:rxq_pcap=hv1/vif3-rx.pcap \
4768 ofport-request=3
4769
4770# Allow some time for ovn-northd and ovn-controller to catch up.
4771# XXX This should be more systematic.
4772sleep 1
4773
4774ip_to_hex() {
4775 printf "%02x%02x%02x%02x" "$@"
4776}
8639f9be
ND
4777
4778# Send ip packets between foo1 and foo2
4779src_mac="0a0000000001"
4780dst_mac="0a0000000003"
4781src_ip=`ip_to_hex 192 168 1 2`
4782dst_ip=`ip_to_hex 192 168 1 3`
4783packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4784as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4785
4786# Send ip packets between foo1 and alice1
4787src_mac="0a0000000001"
4788dst_mac="000000010203"
4789src_ip=`ip_to_hex 192 168 1 2`
4790dst_ip=`ip_to_hex 192 168 2 2`
4791packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4792as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4793
4794echo "---------NB dump-----"
4795ovn-nbctl show
4796echo "---------------------"
4797ovn-nbctl list logical_router
4798echo "---------------------"
4799ovn-nbctl list logical_router_port
4800echo "---------------------"
4801
4802echo "---------SB dump-----"
4803ovn-sbctl list datapath_binding
4804echo "---------------------"
4805ovn-sbctl list port_binding
4806echo "---------------------"
4807
4808echo "------ hv1 dump ----------"
4809as hv1 ovs-ofctl dump-flows br-int
4810
4811# Packet to Expect at foo2
4812src_mac="0a0000000001"
4813dst_mac="0a0000000003"
4814src_ip=`ip_to_hex 192 168 1 2`
4815dst_ip=`ip_to_hex 192 168 1 3`
4816expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4817
e4543cfe
DDP
4818$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
4819echo $expected > expout
8639f9be
ND
4820AT_CHECK([cat received1.packets], [0], [expout])
4821
4822# Packet to Expect at alice1
4823src_mac="000000010204"
4824dst_mac="0a0000000002"
4825src_ip=`ip_to_hex 192 168 1 2`
4826dst_ip=`ip_to_hex 192 168 2 2`
4827expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
4828
e4543cfe
DDP
4829$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
4830echo $expected > expout
8639f9be
ND
4831AT_CHECK([cat received2.packets], [0], [expout])
4832
4833OVN_CLEANUP([hv1])
4834
4835AT_CLEANUP
f5792c3f
NS
4836
4837AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 4838AT_KEYWORDS([vswitchd])
f5792c3f
NS
4839AT_SKIP_IF([test $HAVE_PYTHON = no])
4840ovn_start
4841
4842ovn-nbctl ls-add ls1
4843
4844ovn-nbctl lsp-add ls1 ls1-lp1 \
4845-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4846
4847ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4848
4849net_add n1
4850sim_add hv1
4851
4852as hv1
4853ovs-vsctl add-br br-phys
4854ovn_attach n1 br-phys 192.168.0.1
4855ovs-vsctl -- add-port br-int hv1-vif1 -- \
4856 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4857 options:tx_pcap=hv1/vif1-tx.pcap \
4858 options:rxq_pcap=hv1/vif1-rx.pcap \
4859 ofport-request=1
4860
4861ovn_populate_arp
4862sleep 2
4863
4864as hv1 ovs-vsctl show
4865
4866echo "---------------------"
4867ovn-sbctl dump-flows
4868echo "---------------------"
4869
4870echo "------ hv1 dump ----------"
4871as hv1 ovs-ofctl dump-flows br-int
4872total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4873
4874echo "Total flows before vswitchd restart = " $total_flows
4875
4876# Code taken from ovs-save utility
4877save_flows () {
4878 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
4879 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
4880 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
4881 echo "EOF" >> restore_flows.sh
4882}
4883
4884restart_vswitchd () {
4885 restore_flows=$1
4886
4887 if test $restore_flows = true; then
4888 save_flows
4889 fi
4890
4891 as hv1
4892 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4893
4894 if test $restore_flows = true; then
4895 as hv1
4896 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
4897 fi
4898
4899 as hv1
4900 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
4901 ovs-ofctl dump-flows br-int
4902
4903 if test $restore_flows = true; then
4904 sh ./restore_flows.sh
4905 echo "Flows after restore"
4906 as hv1
4907 ovs-ofctl dump-flows br-int
4908 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
4909 flow-restore-wait="true"
4910 fi
4911}
4912
4913# Save the flows, restart vswitchd and restore the flows
4914restart_vswitchd true
4915OVS_WAIT_UNTIL([
4916 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4917 echo "Total flows after vswitchd restart = " $total_flows_after_restart
4918 test "${total_flows}" = "${total_flows_after_restart}"
4919])
4920
4921# Restart vswitchd without restoring
4922restart_vswitchd false
4923OVS_WAIT_UNTIL([
4924 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
4925 echo "Total flows after vswitchd restart = " $total_flows_after_restart
4926 test "${total_flows}" = "${total_flows_after_restart}"
4927])
4928
4929OVN_CLEANUP([hv1])
4930AT_CLEANUP
47021598
CSV
4931
4932AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
4933AT_SKIP_IF([test $HAVE_PYTHON = no])
4934ovn_start
4935
4936# Topology: Two LSs - ls1 and ls2 are connected via router r0
4937
4938# Create logical switches
4939ovn-nbctl ls-add ls1
4940ovn-nbctl ls-add ls2
4941
4942# Create router
4943ovn-nbctl create Logical_Router name=lr0
4944
4945# Add router ls1p1 port to gateway router
4946ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
4947ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
4948 type=router options:router-port=lrp-ls1lp1 \
4949 addresses='"f0:00:00:00:00:01 192.168.0.1"'
4950
4951# Add router ls2p2 port to gateway router
4952ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
4953ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
4954 type=router options:router-port=lrp-ls2lp1 \
4955 addresses='"f0:00:00:00:00:02 192.168.1.1"'
4956
4957# Set default gateway (nexthop) to 192.168.1.254
4958ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
4959
4960# Create logical port ls1lp2 in ls1
4961ovn-nbctl lsp-add ls1 ls1lp2 \
4962-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
4963
4964# Create logical port ls2lp2 in ls2
4965ovn-nbctl lsp-add ls2 ls2lp2 \
4966-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
4967
4968net_add n1
4969sim_add hv1
4970as hv1
4971ovs-vsctl add-br br-phys
4972ovn_attach n1 br-phys 192.168.0.1
4973ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
4974 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
4975 options:tx_pcap=hv1/ls1lp2-tx.pcap \
4976 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
4977 ofport-request=1
4978ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
4979 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
4980 options:tx_pcap=hv1/ls2lp2-tx.pcap \
4981 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
4982 ofport-request=2
4983
4984# Allow some time for ovn-northd and ovn-controller to catch up.
4985# XXX This should be more systematic.
4986sleep 1
4987
4988echo "---------NB dump-----"
4989ovn-nbctl show
4990echo "---------------------"
4991ovn-nbctl list logical_router
4992echo "---------------------"
4993ovn-nbctl list logical_router_port
4994echo "---------------------"
4995
4996echo "---------SB dump-----"
4997ovn-sbctl list datapath_binding
4998echo "---------------------"
4999ovn-sbctl list port_binding
5000echo "---------------------"
5001ovn-sbctl dump-flows
5002echo "---------------------"
5003ovn-sbctl list chassis
5004ovn-sbctl list encap
5005echo "---------------------"
5006
5007echo "------Flows dump-----"
5008as hv1
5009ovs-ofctl dump-flows
5010echo "---------------------"
5011
5012ip_to_hex() {
5013 printf "%02x%02x%02x%02x" "$@"
5014}
5015
5016src_mac="f00000000003"
5017dst_mac="f00000000001"
5018src_ip=`ip_to_hex 192 168 0 2`
5019dst_ip=`ip_to_hex 8 8 8 8`
5020packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5021
5022# Send IP packet destined to 8.8.8.8 from lsp1lp2
5023as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5024
5025trim_zeros() {
5026 sed 's/\(00\)\{1,\}$//'
5027}
5028
5029# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5030# not 8.8.8.8
5031
5032$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5033expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5034echo $expected > expout
5035AT_CHECK([cat packets], [0], [expout])
5036cat packets
5037
5038OVN_CLEANUP([hv1])
5039
5040AT_CLEANUP
8439c2eb
CSV
5041
5042AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5043AT_SKIP_IF([test $HAVE_PYTHON = no])
5044ovn_start
5045# Create logical switch
5046ovn-nbctl ls-add ls0
5047# Create gateway router
5048ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5049# Add router port to gateway router
5050ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5051ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
5052 type=router options:router-port=lrp0-rp addresses='"f0:00:00:00:00:01"'
5053# Add nat-address option
5054ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5055
5056net_add n1
5057sim_add hv1
5058as hv1
5059ovs-vsctl \
5060 -- add-br br-phys \
5061 -- add-br br-eth0
5062
5063ovn_attach n1 br-phys 192.168.0.1
5064
5065AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5066AT_CHECK([ovs-vsctl add-port br-eth0 snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
5067
5068# Create a localnet port.
5069AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5070AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5071AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5072AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5073
5074
5075# Wait for packet to be received.
5076OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5077trim_zeros() {
5078 sed 's/\(00\)\{1,\}$//'
5079}
5080$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5081expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5082echo $expected > expout
5083AT_CHECK([sort packets], [0], [expout])
5084cat packets
5085
5086OVN_CLEANUP([hv1])
5087
5088AT_CLEANUP
6e31816f
CSV
5089
5090AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5091ovn_start
5092net_add n1
5093sim_add hv1
5094as hv1
5095ovs-vsctl -- add-br br-phys
5096ovn_attach n1 br-phys 192.168.0.1
5097# Create logical switch ls0
5098ovn-nbctl ls-add ls0
5099# Create ports lp0, lp1 in ls0
5100ovn-nbctl lsp-add ls0 lp0
5101ovn-nbctl lsp-add ls0 lp1
5102ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5103ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5104dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5105ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5106ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5107ovn-sbctl find MAC_Binding
093aa761 5108# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5109ovn-nbctl lsp-del lp0
5110ovn-sbctl find MAC_Binding
093aa761
BP
5111OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5112# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5113ovn-nbctl ls-del ls0
5114ovn-sbctl find MAC_Binding
093aa761 5115OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5116
5117OVN_CLEANUP([hv1])
5118
5119AT_CLEANUP
926c34fd
RM
5120
5121AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5122AT_SKIP_IF([test $HAVE_PYTHON = no])
5123ovn_start
5124
5125# Logical network:
5126# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5127# connected to a router R1.
5128# foo has foo1 to act as a client.
5129# bar has bar1, bar2, bar3 to act as servers.
5130
5131net_add n1
5132
5133sim_add hv1
5134as hv1
5135ovs-vsctl add-br br-phys
5136ovn_attach n1 br-phys 192.168.0.1
5137for i in foo1 bar1 bar2 bar3; do
5138 ovs-vsctl -- add-port br-int $i -- \
5139 set interface $i external-ids:iface-id=$i \
5140 options:tx_pcap=hv1/$i-tx.pcap \
5141 options:rxq_pcap=hv1/$i-rx.pcap
5142done
5143
5144ovn-nbctl create Logical_Router name=R1
5145ovn-nbctl ls-add foo
5146ovn-nbctl ls-add bar
5147
5148# Connect foo to R1
5149ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5150ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5151 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5152
5153# Connect bar to R1
5154ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5155ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5156 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5157
5158# Create logical port foo1 in foo
5159ovn-nbctl lsp-add foo foo1 \
5160-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5161
5162# Create logical port bar1, bar2 and bar3 in bar
5163for i in `seq 1 3`; do
5164 ip=`expr $i + 1`
5165 ovn-nbctl lsp-add bar bar$i \
5166 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5167done
5168
5169OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5170
5171OVN_CLEANUP([hv1])
5172
5173AT_CLEANUP
b511690b
GS
5174
5175AT_SETUP([ovn -- tag allocation])
b511690b
GS
5176ovn_start
5177
5178AT_CHECK([ovn-nbctl ls-add ls0])
5179AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5180AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5181AT_CHECK([ovn-nbctl ls-add ls1])
5182
5183dnl When a tag is provided, no allocation is done
5184AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5185AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5186])
5187dnl The same 'tag' gets created in southbound database.
5188AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5189logical_port="c0"], [0], [3
5190])
5191
5192dnl Allocate tags and see it getting created in both NB and SB
5193AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5194AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5195])
5196AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5197logical_port="c1"], [0], [1
5198])
5199
5200AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5201AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5202])
5203AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5204logical_port="c2"], [0], [2
5205])
5206AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5207AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5208])
5209AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5210logical_port="c3"], [0], [4
5211])
5212
5213dnl A different parent.
5214AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5215AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5216])
5217AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5218logical_port="c4"], [0], [1
5219])
5220
5221AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5222AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5223])
5224AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5225logical_port="c5"], [0], [2
5226])
5227
5228dnl Delete a logical port and create a new one.
5229AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5230AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5231AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5232])
5233AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5234logical_port="c6"], [0], [1
5235])
5236
5237dnl Restart northd to see that the same allocation remains.
5238as northd
5239OVS_APP_EXIT_AND_WAIT([ovn-northd])
5240start_daemon ovn-northd \
5241 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5242 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5243
5244dnl Create a switch to make sure that ovn-northd has run through the main loop.
5245AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5246AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5247])
5248AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5249])
5250AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5251])
5252AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5253])
5254AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5255])
5256AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5257])
5258
5259dnl Create a switch port with a tag that has already been allocated.
5260dnl It should go through fine with a duplicate tag.
5261AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5262AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5263])
5264AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5265logical_port="c7"], [0], [2
5266])
5267AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5268])
5269
5270AT_CHECK([ovn-nbctl ls-add ls2])
5271dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5272dnl gets copied to 'tag'
5273AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5274AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5275])
5276dnl The same 'tag' gets created in southbound database.
5277AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5278logical_port="local0"], [0], [25
5279])
5280dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5281AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5282AT_CHECK([ovn-nbctl lsp-get-tag local1])
5283dnl change the tag_request.
5284AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5285AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5286])
5287
5288AT_CLEANUP
57afd0c0
RR
5289
5290AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5291ovn_start
5292ovn-nbctl ls-add lsw0
5293net_add n1
5294for i in 1 2; do
5295 sim_add hv$i
5296 as hv$i
5297 ovs-vsctl add-br br-phys
5298 ovn_attach n1 br-phys 192.168.0.$i
5299 ovs-vsctl add-br br-eth0
5300 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5301done
5302
5303# Create a localnet port.
5304AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5305AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5306AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5307AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5308
5309
5310# Create 3 vifs.
5311AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
5312AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
5313AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
5314AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
5315AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
5316AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
5317AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
5318AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
5319AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
5320
5321# Bind the localvif1 to hv1.
5322as hv1
5323AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
5324
5325# On hv1, check that there are no flows outputting bcast to tunnel
5326OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5327
5328# On hv2, check that there is 1 flow outputting bcast to tunnel to hv1.
5329as hv2
5330OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 1])
5331
5332# Now bind vif2 on hv2.
5333AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
5334
5335# At this point, the broadcast flow on vif2 should be deleted.
5336# because, there is now a localnet vif bound (table=32 programming logic)
5337OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
5338
5339# Verify that the local net patch port exists on hv2.
5340OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5341
5342# Now bind vif3 on hv2.
5343AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
5344
5345# Verify that the local net patch port still exists on hv2
5346OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5347
5348# Delete localvif2
5349AT_CHECK([ovn-nbctl lsp-del localvif2])
5350
5351# Verify that the local net patch port still exists on hv2,
5352# because, localvif3 is still bound.
5353OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
5354
57afd0c0 5355OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
5356
5357AT_CLEANUP
5358
5359AT_SETUP([ovn -- DSCP marking check])
5360AT_KEYWORDS([ovn])
5361ovn_start
5362
5363ovn-nbctl ls-add lsw0
5364ovn-nbctl --wait=sb lsp-add lsw0 lp1
5365ovn-nbctl --wait=sb lsp-add lsw0 lp2
5366ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
5367ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
5368ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
5369ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
5370ovn-nbctl --wait=sb sync
5371net_add n1
5372sim_add hv
5373as hv
5374ovs-vsctl add-br br-phys
5375ovn_attach n1 br-phys 192.168.0.1
5376ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1 options:tx_pcap=vif1-tx.pcap options:rxq_pcap=vif1-rx.pcap ofport-request=1
5377ovs-vsctl add-port br-int vif2 -- set Interface vif2 external-ids:iface-id=lp2 options:tx_pcap=vif2-tx.pcap options:rxq_pcap=vif2-rx.pcap ofport-request=2
5378
5379AT_CAPTURE_FILE([trace])
5380ovn_trace () {
5381 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
5382}
5383
5384# Extracts nw_tos from the final flow from ofproto/trace output and prints
5385# it on stdout. Prints "none" if no nw_tos was included.
5386get_final_nw_tos() {
5387 if flow=$(grep '^Final flow:' stdout); then :; else
5388 # The output didn't have a final flow.
5389 return 99
5390 fi
5391
5392 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
5393 case $tos in
5394 '') echo none ;;
5395 *) echo $tos ;;
5396 esac
5397}
5398
5399# check_tos TOS
5400#
5401# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
5402check_tos() {
5403 # First check with ovn-trace for logical flows.
5404 echo "checking for tos $1"
5405 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
5406 echo 'output("lp2");') > expout
5407 AT_CHECK_UNQUOTED([ovn_trace lsw0 'inport == "lp1" && eth.src == f0:00:00:00:00:01 && eth.dst == f0:00:00:00:00:02 && ip4.src == 1.1.1.1 && ip4.dst == 1.1.1.2'], [0], [expout])
5408
5409 # Then re-check with ofproto/trace for a physical packet.
5410 AT_CHECK([ovs-appctl ofproto/trace br-int 'in_port=1,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,dl_type=0x800,nw_src=1.1.1.1,nw_dst=1.1.1.2'], [0], [stdout-nolog])
5411 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
5412])
5413}
5414
5415# check at L2
5416AT_CHECK([ovn_trace lsw0 'inport == "lp1" && eth.src == f0:00:00:00:00:01 && eth.dst == f0:00:00:00:00:02'], [0], [output("lp2");
5417])
5418AT_CHECK([ovs-appctl ofproto/trace br-int 'in_port=1,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02'], [0], [stdout-nolog])
5419AT_CHECK([get_final_nw_tos], [0], [none
5420])
5421
5422# check at L3 without dscp marking
5423check_tos 0
5424
5425# Mark DSCP with a valid value
5426qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
5427check_tos 48
5428
5429# Update the DSCP marking
5430ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
5431check_tos 63
5432
5433ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
5434check_tos 63
5435
5436# Disable DSCP marking
5437ovn-nbctl --wait=hv clear Logical_Switch lsw0 qos_rules
5438check_tos 0
5439
5440OVN_CLEANUP([hv])
57afd0c0 5441AT_CLEANUP