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