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