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