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