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