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