]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
ovn: Add rate-limiting for ACL logs.
[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
fb8635c5 180AT_SETUP([ovn -- composition])
42d36b58
AZ
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 306$name => Syntax error at `$name' expecting address set name.
3d2848ba 307@name => Syntax error at `@name' expecting port group name.
2c5cbb15 308
e0840f11
BP
309123 == xyzzy => Syntax error at `xyzzy' expecting field name.
310xyzzy == 1 => Syntax error at `xyzzy' expecting field name.
311
312inport[1] == 1 => Cannot select subfield of string field inport.
313
314eth.type[] == 1 => Syntax error at `@:>@' expecting small integer.
315eth.type[::1] == 1 => Syntax error at `::1' expecting small integer.
316eth.type[18446744073709551615] == 1 => Syntax error at `18446744073709551615' expecting small integer.
317
318eth.type[5!] => Syntax error at `!' expecting `@:>@'.
319
320eth.type[5..1] => Invalid bit range 5 to 1.
321
322eth.type[12..16] => Cannot select bits 12 to 16 of 16-bit field eth.type.
323
324eth.type[10] == 1 => Cannot select subfield of nominal field eth.type.
325
326eth.type => Explicit `!= 0' is required for inequality test of multibit field against 0.
327
328!(!(vlan.pcp)) => Explicit `!= 0' is required for inequality test of multibit field against 0.
329
330123 => Syntax error at end of input expecting relational operator.
331
332123 x => Syntax error at `x' expecting relational operator.
333
334{1, "eth0"} => Syntax error at `"eth0"' expecting integer.
335
336eth.type == xyzzy => Syntax error at `xyzzy' expecting constant.
337
338(1 x) => Syntax error at `x' expecting `)'.
339
340!0x800 != eth.type => Missing parentheses around operand of !.
341
342eth.type == 0x800 || eth.type == 0x86dd && ip.proto == 17 => && and || must be parenthesized when used together.
343
344eth.dst == {} => Syntax error at `}' expecting constant.
345
346eth.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).
347
3b7cb7e1 348ip4.src == ::1 => 128-bit constant is not compatible with 32-bit field ip4.src.
e0840f11
BP
349
3501 == eth.type == 2 => Range expressions must have the form `x < field < y' or `x > field > y', with each `<' optionally replaced by `<=' or `>' by `>=').
8b34ccda 351
9aef3c1b 352eth.dst[40] x => Syntax error at `x' expecting end of input.
ea382567
RB
353
354ip4.src == {1.2.3.4, $set1, $unknownset} => Syntax error at `$unknownset' expecting address set name.
355eth.src == {$set3, badmac, 00:00:00:00:00:01} => Syntax error at `badmac' expecting constant.
e0840f11
BP
356]])
357sed 's/ =>.*//' test-cases.txt > input.txt
358sed 's/.* => //' test-cases.txt > expout
359AT_CHECK([ovstest test-ovn parse-expr < input.txt], [0], [expout])
360AT_CLEANUP
361
362AT_SETUP([ovn -- expression annotation])
363dnl Input precedes =>, expected output follows =>.
32157c87 364dnl Empty lines and lines starting with # are ignored.
e0840f11
BP
365AT_DATA([test-cases.txt], [[
366ip4.src == 1.2.3.4 => ip4.src == 0x1020304 && eth.type == 0x800
367ip4.src != 1.2.3.4 => ip4.src != 0x1020304 && eth.type == 0x800
368ip.proto == 123 => ip.proto == 0x7b && (eth.type == 0x800 || eth.type == 0x86dd)
32157c87 369ip.proto == {123, 234} => (ip.proto == 0x7b || ip.proto == 0xea) && (eth.type == 0x800 || eth.type == 0x86dd)
e0840f11
BP
370ip4.src == 1.2.3.4 && ip4.dst == 5.6.7.8 => ip4.src == 0x1020304 && eth.type == 0x800 && ip4.dst == 0x5060708 && eth.type == 0x800
371
32157c87
JS
372# Nested expressions over a single symbol should be annotated with symbol's
373# prerequisites only once, at the top level.
374tcp.dst == 1 || (tcp.dst >= 2 && tcp.dst <= 3) => (tcp.dst == 0x1 || (tcp.dst >= 0x2 && tcp.dst <= 0x3)) && ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
375
e0840f11
BP
376ip => eth.type == 0x800 || eth.type == 0x86dd
377ip == 1 => eth.type == 0x800 || eth.type == 0x86dd
378ip[0] == 1 => eth.type == 0x800 || eth.type == 0x86dd
379ip > 0 => Only == and != operators may be used with nominal field ip.
380!ip => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
381ip == 0 => Nominal predicate ip may only be tested positively, e.g. `ip' or `ip == 1' but not `!ip' or `ip == 0'.
382
383vlan.present => vlan.tci[12]
384!vlan.present => !vlan.tci[12]
385
386!vlan.pcp => vlan.tci[13..15] == 0 && vlan.tci[12]
387vlan.pcp == 1 && vlan.vid == 2 => vlan.tci[13..15] == 0x1 && vlan.tci[12] && vlan.tci[0..11] == 0x2 && vlan.tci[12]
7700eea0 388!reg0 && !reg1 && !reg2 && !reg3 => xxreg0[96..127] == 0 && xxreg0[64..95] == 0 && xxreg0[32..63] == 0 && xxreg0[0..31] == 0
e0840f11
BP
389
390ip.first_frag => ip.frag[0] && (eth.type == 0x800 || eth.type == 0x86dd) && (!ip.frag[1] || (eth.type != 0x800 && eth.type != 0x86dd))
391!ip.first_frag => !ip.frag[0] || (eth.type != 0x800 && eth.type != 0x86dd) || (ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd))
392ip.later_frag => ip.frag[1] && (eth.type == 0x800 || eth.type == 0x86dd)
393
394bad_prereq != 0 => Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
395self_recurse != 0 => Error parsing expression `self_recurse != 0' encountered as prerequisite or predicate of initial expression: Recursive expansion of symbol `self_recurse'.
396mutual_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'.
397mutual_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'.
398]])
399sed 's/ =>.*//' test-cases.txt > input.txt
400sed 's/.* => //' test-cases.txt > expout
401AT_CHECK([ovstest test-ovn annotate-expr < input.txt], [0], [expout])
402AT_CLEANUP
403
9d4aecca 404AT_SETUP([ovn -- 1-term expression conversion])
e0840f11 405AT_CHECK([ovstest test-ovn exhaustive --operation=convert 1], [0],
9d4aecca 406 [Tested converting all 1-terminal expressions 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 -- 2-term expression conversion])
e0840f11 411AT_CHECK([ovstest test-ovn exhaustive --operation=convert 2], [0],
8c3caa2c 412 [Tested converting 578 expressions of 2 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
413])
414AT_CLEANUP
415
9d4aecca 416AT_SETUP([ovn -- 3-term expression conversion])
e0840f11 417AT_CHECK([ovstest test-ovn exhaustive --operation=convert --bits=2 3], [0],
8c3caa2c 418 [Tested converting 67410 expressions of 3 terminals with 2 numeric vars (each 2 bits) in terms of operators == != < <= > >= and 2 string vars.
e0840f11
BP
419])
420AT_CLEANUP
421
9d4aecca
BP
422AT_SETUP([ovn -- 3-term numeric expression simplification])
423AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=2 --svars=0 3], [0],
8c3caa2c 424 [Tested simplifying 490770 expressions of 3 terminals with 2 numeric vars (each 3 bits) in terms of operators == != < <= > >=.
e0840f11
BP
425])
426AT_CLEANUP
427
9d4aecca
BP
428AT_SETUP([ovn -- 4-term string expression simplification])
429AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=0 --svars=4 4], [0],
430 [Tested simplifying 21978 expressions of 4 terminals with 4 string vars.
e0840f11
BP
431])
432AT_CLEANUP
433
9d4aecca
BP
434AT_SETUP([ovn -- 3-term mixed expression simplification])
435AT_CHECK([ovstest test-ovn exhaustive --operation=simplify --nvars=1 --svars=1 3], [0],
8c3caa2c 436 [Tested simplifying 127890 expressions of 3 terminals with 1 numeric vars (each 3 bits) in terms of operators == != < <= > >= and 1 string vars.
e0840f11
BP
437])
438AT_CLEANUP
439
97ba1d55
BP
440AT_SETUP([ovn -- simplification special cases])
441simplify() {
442 echo "$1" | ovstest test-ovn simplify-expr
443}
444AT_CHECK([simplify 'eth.dst == 0/0'], [0], [1
445])
a3d79068
BP
446AT_CHECK([simplify 'eth.dst != 0/0'], [0], [0
447])
33f15d17
BP
448AT_CHECK([simplify 'tcp.dst >= 0'], [0],
449 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
450])
451AT_CHECK([simplify 'tcp.dst <= 65535'], [0],
452 [ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
453])
454AT_CHECK([simplify 'tcp.dst > 0'], [0],
455 [[(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)
456]])
457AT_CHECK([simplify 'tcp.dst < 65535'], [0],
458 [[(!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)
459]])
97ba1d55
BP
460AT_CLEANUP
461
ba8d3816
MS
462AT_SETUP([ovn -- is_chassis_resident simplification])
463simplify() {
464 echo "$1" | ovstest test-ovn simplify-expr
465}
466AT_CHECK([simplify 'is_chassis_resident("eth1")'], [0], [1
467])
468AT_CHECK([simplify 'is_chassis_resident("eth2")'], [0], [0
469])
470AT_CHECK([simplify '!is_chassis_resident("eth1")'], [0], [0
471])
472AT_CHECK([simplify '!is_chassis_resident("eth2")'], [0], [1
473])
474AT_CLEANUP
475
9d4aecca
BP
476AT_SETUP([ovn -- 4-term numeric expression normalization])
477AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 4], [0],
8c3caa2c 478 [Tested normalizing 1874026 expressions of 4 terminals with 3 numeric vars (each 1 bits) in terms of operators == != < <= > >=.
e0840f11
BP
479])
480AT_CLEANUP
481
9d4aecca
BP
482AT_SETUP([ovn -- 4-term string expression normalization])
483AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 4], [0],
484 [Tested normalizing 11242 expressions of 4 terminals with 3 string vars.
485])
486AT_CLEANUP
487
488AT_SETUP([ovn -- 4-term mixed expression normalization])
489AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --bits=1 --svars=2 4], [0],
8c3caa2c 490 [Tested normalizing 175978 expressions of 4 terminals with 1 numeric vars (each 1 bits) in terms of operators == != < <= > >= and 2 string vars.
9d4aecca
BP
491])
492AT_CLEANUP
493
494AT_SETUP([ovn -- 5-term numeric expression normalization])
495AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=3 --svars=0 --bits=1 --relops='==' 5], [0],
8c3caa2c 496 [Tested normalizing 1317600 expressions of 5 terminals with 3 numeric vars (each 1 bits) in terms of operators ==.
9d4aecca
BP
497])
498AT_CLEANUP
499
500AT_SETUP([ovn -- 5-term string expression normalization])
501AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=0 --svars=3 --bits=1 --relops='==' 5], [0],
502 [Tested normalizing 368550 expressions of 5 terminals with 3 string vars.
503])
504AT_CLEANUP
505
506AT_SETUP([ovn -- 5-term mixed expression normalization])
507AT_CHECK([ovstest test-ovn exhaustive --operation=normalize --nvars=1 --svars=1 --bits=1 --relops='==' 5], [0],
8c3caa2c 508 [Tested normalizing 216000 expressions of 5 terminals with 1 numeric vars (each 1 bits) in terms of operators == and 1 string vars.
9d4aecca
BP
509])
510AT_CLEANUP
511
512AT_SETUP([ovn -- 4-term numeric expressions to flows])
8c3caa2c 513AT_KEYWORDS([expression])
9d4aecca 514AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=2 --svars=0 --bits=2 --relops='==' 4], [0],
8c3caa2c 515 [Tested converting to flows 175978 expressions of 4 terminals with 2 numeric vars (each 2 bits) in terms of operators ==.
9d4aecca
BP
516])
517AT_CLEANUP
518
519AT_SETUP([ovn -- 4-term string expressions to flows])
8c3caa2c 520AT_KEYWORDS([expression])
9d4aecca
BP
521AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=0 --svars=4 4], [0],
522 [Tested converting to flows 21978 expressions of 4 terminals with 4 string vars.
523])
524AT_CLEANUP
525
526AT_SETUP([ovn -- 4-term mixed expressions to flows])
8c3caa2c 527AT_KEYWORDS([expression])
9d4aecca 528AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=1 --bits=2 --svars=1 --relops='==' 4], [0],
8c3caa2c 529 [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
530])
531AT_CLEANUP
532
533AT_SETUP([ovn -- 3-term numeric expressions to flows])
8c3caa2c 534AT_KEYWORDS([expression])
9d4aecca 535AT_CHECK([ovstest test-ovn exhaustive --operation=flow --nvars=3 --svars=0 --bits=3 --relops='==' 3], [0],
8c3caa2c 536 [Tested converting to flows 41328 expressions of 3 terminals with 3 numeric vars (each 3 bits) in terms of operators ==.
e0840f11
BP
537])
538AT_CLEANUP
f386a8a7
BP
539
540AT_SETUP([ovn -- converting expressions to flows -- string fields])
8c3caa2c 541AT_KEYWORDS([expression])
f386a8a7
BP
542expr_to_flow () {
543 echo "$1" | ovstest test-ovn expr-to-flows | sort
544}
cc5e28d8 545AT_CHECK([expr_to_flow 'inport == "eth0"'], [0], [reg14=0x5
f386a8a7 546])
cc5e28d8 547AT_CHECK([expr_to_flow 'inport == "eth1"'], [0], [reg14=0x6
f386a8a7
BP
548])
549AT_CHECK([expr_to_flow 'inport == "eth2"'], [0], [(no flows)
550])
551AT_CHECK([expr_to_flow 'inport == "eth0" && ip'], [0], [dnl
cc5e28d8
JP
552ip,reg14=0x5
553ipv6,reg14=0x5
f386a8a7
BP
554])
555AT_CHECK([expr_to_flow 'inport == "eth1" && ip'], [0], [dnl
cc5e28d8
JP
556ip,reg14=0x6
557ipv6,reg14=0x6
f386a8a7
BP
558])
559AT_CHECK([expr_to_flow 'inport == "eth2" && ip'], [0], [(no flows)
560])
561AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2", "LOCAL"}'], [0],
cc5e28d8
JP
562[reg14=0x5
563reg14=0x6
564reg14=0xfffe
f386a8a7
BP
565])
566AT_CHECK([expr_to_flow 'inport == {"eth0", "eth1", "eth2"} && ip'], [0], [dnl
cc5e28d8
JP
567ip,reg14=0x5
568ip,reg14=0x6
569ipv6,reg14=0x5
570ipv6,reg14=0x6
f386a8a7 571])
9d4aecca
BP
572AT_CHECK([expr_to_flow 'inport == "eth0" && inport == "eth1"'], [0], [dnl
573(no flows)
574])
f386a8a7 575AT_CLEANUP
3b7cb7e1 576
2c5cbb15 577AT_SETUP([ovn -- converting expressions to flows -- address sets])
8c3caa2c 578AT_KEYWORDS([expression])
2c5cbb15
RB
579expr_to_flow () {
580 echo "$1" | ovstest test-ovn expr-to-flows | sort
581}
582AT_CHECK([expr_to_flow 'ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3}'], [0], [dnl
583ip,nw_src=10.0.0.1
584ip,nw_src=10.0.0.2
585ip,nw_src=10.0.0.3
586])
587AT_CHECK([expr_to_flow 'ip4.src == $set1'], [0], [dnl
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.3.4, $set1}'], [0], [dnl
593ip,nw_src=1.2.3.4
594ip,nw_src=10.0.0.1
595ip,nw_src=10.0.0.2
596ip,nw_src=10.0.0.3
597])
598AT_CHECK([expr_to_flow 'ip4.src == {1.2.0.0/20, 5.5.5.0/24, $set1}'], [0], [dnl
599ip,nw_src=1.2.0.0/20
600ip,nw_src=10.0.0.1
601ip,nw_src=10.0.0.2
602ip,nw_src=10.0.0.3
603ip,nw_src=5.5.5.0/24
604])
605AT_CHECK([expr_to_flow 'ip6.src == {::1, ::2, ::3}'], [0], [dnl
606ipv6,ipv6_src=::1
607ipv6,ipv6_src=::2
608ipv6,ipv6_src=::3
609])
610AT_CHECK([expr_to_flow 'ip6.src == {::1, $set2, ::4}'], [0], [dnl
611ipv6,ipv6_src=::1
612ipv6,ipv6_src=::2
613ipv6,ipv6_src=::3
614ipv6,ipv6_src=::4
615])
616AT_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
617dl_src=00:00:00:00:00:01
618dl_src=00:00:00:00:00:02
619dl_src=00:00:00:00:00:03
620])
621AT_CHECK([expr_to_flow 'eth.src == {$set3}'], [0], [dnl
622dl_src=00:00:00:00:00:01
623dl_src=00:00:00:00:00:02
624dl_src=00:00:00:00:00:03
625])
ea382567
RB
626AT_CHECK([expr_to_flow 'eth.src == {00:00:00:00:00:01, $set3, ba:be:be:ef:de:ad, $set3}'], [0], [dnl
627dl_src=00:00:00:00:00:01
628dl_src=00:00:00:00:00:02
629dl_src=00:00:00:00:00:03
630dl_src=ba:be:be:ef:de:ad
631])
f3a4e992
HZ
632AT_CHECK([expr_to_flow 'ip4.src == {$set4}'], [0], [dnl
633(no flows)
634])
635AT_CHECK([expr_to_flow 'ip4.src == {1.2.3.4, $set4}'], [0], [dnl
636ip,nw_src=1.2.3.4
637])
638AT_CHECK([expr_to_flow 'ip4.src == 1.2.3.4 || ip4.src == {$set4}'], [0], [dnl
639ip,nw_src=1.2.3.4
640])
641AT_CHECK([expr_to_flow 'ip4.src != {$set4}'], [0], [dnl
642
643])
644AT_CHECK([expr_to_flow 'ip4.src != {1.0.0.0/8, $set4}'], [0], [dnl
645ip,nw_src=0.0.0.0/1.0.0.0
646ip,nw_src=128.0.0.0/1
647ip,nw_src=16.0.0.0/16.0.0.0
648ip,nw_src=2.0.0.0/2.0.0.0
649ip,nw_src=32.0.0.0/32.0.0.0
650ip,nw_src=4.0.0.0/4.0.0.0
651ip,nw_src=64.0.0.0/64.0.0.0
652ip,nw_src=8.0.0.0/8.0.0.0
653])
654AT_CHECK([expr_to_flow 'ip4.src != 1.0.0.0/8 && ip4.src != {$set4}'], [0], [dnl
655ip,nw_src=0.0.0.0/1.0.0.0
656ip,nw_src=128.0.0.0/1
657ip,nw_src=16.0.0.0/16.0.0.0
658ip,nw_src=2.0.0.0/2.0.0.0
659ip,nw_src=32.0.0.0/32.0.0.0
660ip,nw_src=4.0.0.0/4.0.0.0
661ip,nw_src=64.0.0.0/64.0.0.0
662ip,nw_src=8.0.0.0/8.0.0.0
663])
2c5cbb15
RB
664AT_CLEANUP
665
3d2848ba
HZ
666AT_SETUP([ovn -- converting expressions to flows -- port groups])
667AT_KEYWORDS([expression])
668expr_to_flow () {
669 echo "$1" | ovstest test-ovn expr-to-flows | sort
670}
671AT_CHECK([expr_to_flow 'outport == @pg1'], [0], [dnl
672reg15=0x11
673reg15=0x12
674reg15=0x13
675])
676AT_CHECK([expr_to_flow 'outport == {@pg_empty}'], [0], [dnl
677(no flows)
678])
679AT_CHECK([expr_to_flow 'outport == {"lsp1", @pg_empty}'], [0], [dnl
680reg15=0x11
681])
682AT_CLEANUP
683
55b25947
NS
684AT_SETUP([ovn -- converting expressions to flows -- conjunction])
685AT_KEYWORDS([conjunction])
686expr_to_flow () {
687 echo "$1" | ovstest test-ovn expr-to-flows | sort
688}
689
690lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
691ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3}"
692AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
693conj_id=1,ip
694ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
695ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
696ip,nw_dst=20.0.0.3: conjunction(1, 0/2)
697ip,nw_src=10.0.0.1: conjunction(1, 1/2)
698ip,nw_src=10.0.0.2: conjunction(1, 1/2)
699ip,nw_src=10.0.0.3: conjunction(1, 1/2)
700])
701
702lflow="ip && (!ct.est || (ct.est && ct_label.blocked == 1))"
703AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
704ct_state=+est+trk,ct_label=0x1/0x1,ip
705ct_state=+est+trk,ct_label=0x1/0x1,ipv6
706ct_state=-est+trk,ip
707ct_state=-est+trk,ipv6
708])
709
710lflow="ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
711ip4.dst == {20.0.0.1, 20.0.0.2}"
712AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
713conj_id=1,ip
714ip,nw_dst=20.0.0.1: conjunction(1, 0/2)
715ip,nw_dst=20.0.0.2: conjunction(1, 0/2)
716ip,nw_src=10.0.0.1: conjunction(1, 1/2)
717ip,nw_src=10.0.0.2: conjunction(1, 1/2)
718ip,nw_src=10.0.0.3: conjunction(1, 1/2)
719])
720
721lflow="ip4 && ip4.src == {10.0.0.1, 10.0.0.2, 10.0.0.3} && \
722ip4.dst == {20.0.0.1, 20.0.0.2, 20.0.0.3} && \
723tcp.dst >= 1000 && tcp.dst <= 1010"
724
725AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
726conj_id=1,tcp
727tcp,nw_dst=20.0.0.1: conjunction(1, 0/3)
728tcp,nw_dst=20.0.0.2: conjunction(1, 0/3)
729tcp,nw_dst=20.0.0.3: conjunction(1, 0/3)
730tcp,nw_src=10.0.0.1: conjunction(1, 1/3)
731tcp,nw_src=10.0.0.2: conjunction(1, 1/3)
732tcp,nw_src=10.0.0.3: conjunction(1, 1/3)
733tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/3)
734tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/3)
735tcp,tp_dst=0x3f0/0xfffe: conjunction(1, 2/3)
736tcp,tp_dst=1000: conjunction(1, 2/3)
737tcp,tp_dst=1001: conjunction(1, 2/3)
738tcp,tp_dst=1010: conjunction(1, 2/3)
739])
740
741lflow="ip4 && ip4.src == {10.0.0.4, 10.0.0.5, 10.0.0.6} && \
742((ip4.dst == {20.0.0.4, 20.0.0.7, 20.0.0.8} && tcp.dst >= 1000 && \
743tcp.dst <= 2000 && tcp.src >=1000 && tcp.src <= 2000) \
744|| ip4.dst == 20.0.0.5 || ip4.dst == 20.0.0.6)"
745
746AT_CHECK([expr_to_flow "$lflow"], [0], [dnl
747conj_id=1,tcp
748ip,nw_src=10.0.0.4,nw_dst=20.0.0.5
749ip,nw_src=10.0.0.4,nw_dst=20.0.0.6
750ip,nw_src=10.0.0.5,nw_dst=20.0.0.5
751ip,nw_src=10.0.0.5,nw_dst=20.0.0.6
752ip,nw_src=10.0.0.6,nw_dst=20.0.0.5
753ip,nw_src=10.0.0.6,nw_dst=20.0.0.6
754tcp,nw_dst=20.0.0.4: conjunction(1, 0/4)
755tcp,nw_dst=20.0.0.7: conjunction(1, 0/4)
756tcp,nw_dst=20.0.0.8: conjunction(1, 0/4)
757tcp,nw_src=10.0.0.4: conjunction(1, 1/4)
758tcp,nw_src=10.0.0.5: conjunction(1, 1/4)
759tcp,nw_src=10.0.0.6: conjunction(1, 1/4)
760tcp,tp_dst=0x3ea/0xfffe: conjunction(1, 2/4)
761tcp,tp_dst=0x3ec/0xfffc: conjunction(1, 2/4)
762tcp,tp_dst=0x3f0/0xfff0: conjunction(1, 2/4)
763tcp,tp_dst=0x400/0xfe00: conjunction(1, 2/4)
764tcp,tp_dst=0x600/0xff00: conjunction(1, 2/4)
765tcp,tp_dst=0x700/0xff80: conjunction(1, 2/4)
766tcp,tp_dst=0x780/0xffc0: conjunction(1, 2/4)
767tcp,tp_dst=0x7c0/0xfff0: conjunction(1, 2/4)
768tcp,tp_dst=1000: conjunction(1, 2/4)
769tcp,tp_dst=1001: conjunction(1, 2/4)
770tcp,tp_dst=2000: conjunction(1, 2/4)
771tcp,tp_src=0x3ea/0xfffe: conjunction(1, 3/4)
772tcp,tp_src=0x3ec/0xfffc: conjunction(1, 3/4)
773tcp,tp_src=0x3f0/0xfff0: conjunction(1, 3/4)
774tcp,tp_src=0x400/0xfe00: conjunction(1, 3/4)
775tcp,tp_src=0x600/0xff00: conjunction(1, 3/4)
776tcp,tp_src=0x700/0xff80: conjunction(1, 3/4)
777tcp,tp_src=0x780/0xffc0: conjunction(1, 3/4)
778tcp,tp_src=0x7c0/0xfff0: conjunction(1, 3/4)
779tcp,tp_src=1000: conjunction(1, 3/4)
780tcp,tp_src=1001: conjunction(1, 3/4)
781tcp,tp_src=2000: conjunction(1, 3/4)
782])
783AT_CLEANUP
784
3b7cb7e1 785AT_SETUP([ovn -- action parsing])
d5a76da4
BP
786dnl Unindented text is input (a set of OVN logical actions).
787dnl Indented text is expected output.
788AT_DATA([test-cases.txt],
789[[# drop
790drop;
791 encodes as drop
792drop; next;
793 Syntax error at `next' expecting end of input.
794next; drop;
795 Syntax error at `drop' expecting action.
5f822129
BP
796
797# output
d5a76da4
BP
798output;
799 encodes as resubmit(,64)
5f822129
BP
800
801# next
d5a76da4 802next;
00c875d0 803 encodes as resubmit(,19)
d5a76da4 804next(11);
8f5de083 805 formats as next;
00c875d0 806 encodes as resubmit(,19)
d5a76da4 807next(0);
00c875d0
MS
808 encodes as resubmit(,8)
809next(23);
d5a76da4
BP
810 encodes as resubmit(,31)
811
812next();
4c99cb18 813 Syntax error at `)' expecting "pipeline" or "table".
d5a76da4
BP
814next(10;
815 Syntax error at `;' expecting `)'.
00c875d0
MS
816next(24);
817 "next" action cannot advance beyond table 23.
5f822129 818
4c99cb18
BP
819next(table=11);
820 formats as next;
00c875d0 821 encodes as resubmit(,19)
4c99cb18
BP
822next(pipeline=ingress);
823 formats as next;
00c875d0 824 encodes as resubmit(,19)
4c99cb18
BP
825next(table=11, pipeline=ingress);
826 formats as next;
00c875d0 827 encodes as resubmit(,19)
4c99cb18
BP
828next(pipeline=ingress, table=11);
829 formats as next;
00c875d0 830 encodes as resubmit(,19)
4c99cb18
BP
831
832next(pipeline=egress);
833 "next" action cannot advance from ingress to egress pipeline (use "output" action instead)
834
835next(table=10);
836 formats as next(10);
00c875d0 837 encodes as resubmit(,18)
4c99cb18 838
5f822129 839# Loading a constant value.
d5a76da4
BP
840tcp.dst=80;
841 formats as tcp.dst = 80;
842 encodes as set_field:80->tcp_dst
843 has prereqs ip.proto == 0x6 && (eth.type == 0x800 || eth.type == 0x86dd)
844eth.dst[40] = 1;
845 encodes as set_field:01:00:00:00:00:00/01:00:00:00:00:00->eth_dst
846vlan.pcp = 2;
847 encodes as set_field:0x4000/0xe000->vlan_tci
848 has prereqs vlan.tci[12]
849vlan.tci[13..15] = 2;
850 encodes as set_field:0x4000/0xe000->vlan_tci
851inport = "";
852 encodes as set_field:0->reg14
853ip.ttl=4;
854 formats as ip.ttl = 4;
855 encodes as set_field:4->nw_ttl
856 has prereqs eth.type == 0x800 || eth.type == 0x86dd
857outport="eth0"; next; outport="LOCAL"; next;
8f5de083 858 formats as outport = "eth0"; next; outport = "LOCAL"; next;
00c875d0 859 encodes as set_field:0x5->reg15,resubmit(,19),set_field:0xfffe->reg15,resubmit(,19)
d5a76da4
BP
860
861inport[1] = 1;
862 Cannot select subfield of string field inport.
863ip.proto[1] = 1;
864 Cannot select subfield of nominal field ip.proto.
865eth.dst[40] == 1;
866 Syntax error at `==' expecting `=' or `<->'.
867ip = 1;
868 Predicate symbol ip used where lvalue required.
869ip.proto = 6;
870 Field ip.proto is not modifiable.
871inport = {"a", "b"};
872 Syntax error at `{' expecting constant.
873inport = {};
874 Syntax error at `{' expecting constant.
875bad_prereq = 123;
876 Error parsing expression `xyzzy' encountered as prerequisite or predicate of initial expression: Syntax error at `xyzzy' expecting field name.
877self_recurse = 123;
878 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'.
879vlan.present = 0;
880 Predicate symbol vlan.present used where lvalue required.
5f822129
BP
881
882# Moving one field into another.
d5a76da4
BP
883reg0=reg1;
884 formats as reg0 = reg1;
885 encodes as move:NXM_NX_XXREG0[64..95]->NXM_NX_XXREG0[96..127]
886vlan.pcp = reg0[0..2];
887 encodes as move:NXM_NX_XXREG0[96..98]->NXM_OF_VLAN_TCI[13..15]
888 has prereqs vlan.tci[12]
889reg0[10] = vlan.pcp[1];
890 encodes as move:NXM_OF_VLAN_TCI[14]->NXM_NX_XXREG0[106]
891 has prereqs vlan.tci[12]
892outport = inport;
893 encodes as move:NXM_NX_REG14[]->NXM_NX_REG15[]
894
895reg0[0] = vlan.present;
896 Predicate symbol vlan.present used where lvalue required.
897reg0 = reg1[0..10];
898 Can't assign 11-bit value to 32-bit destination.
899inport = reg0;
900 Can't assign integer field (reg0) to string field (inport).
901inport = big_string;
902 String fields inport and big_string are incompatible for assignment.
903ip.proto = reg0[0..7];
904 Field ip.proto is not modifiable.
5f822129
BP
905
906# Exchanging fields.
d5a76da4
BP
907reg0 <-> reg1;
908 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]
909vlan.pcp <-> reg0[0..2];
910 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]
911 has prereqs vlan.tci[12]
912reg0[10] <-> vlan.pcp[1];
913 encodes as push:NXM_OF_VLAN_TCI[14],push:NXM_NX_XXREG0[106],pop:NXM_OF_VLAN_TCI[14],pop:NXM_NX_XXREG0[106]
914 has prereqs vlan.tci[12]
915outport <-> inport;
916 encodes as push:NXM_NX_REG14[],push:NXM_NX_REG15[],pop:NXM_NX_REG14[],pop:NXM_NX_REG15[]
917
918reg0[0] <-> vlan.present;
919 Predicate symbol vlan.present used where lvalue required.
920reg0 <-> reg1[0..10];
921 Can't exchange 32-bit field with 11-bit field.
922inport <-> reg0;
923 Can't exchange string field (inport) with integer field (reg0).
924inport <-> big_string;
925 String fields inport and big_string are incompatible for exchange.
926ip.proto <-> reg0[0..7];
927 Field ip.proto is not modifiable.
928reg0[0..7] <-> ip.proto;
929 Field ip.proto is not modifiable.
5f822129
BP
930
931# TTL decrement.
d5a76da4
BP
932ip.ttl--;
933 encodes as dec_ttl
934 has prereqs ip
935ip.ttl
936 Syntax error at end of input expecting `--'.
5f822129 937
467085fd 938# load balancing.
d5a76da4 939ct_lb;
00c875d0 940 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
941 has prereqs ip
942ct_lb();
943 formats as ct_lb;
00c875d0 944 encodes as ct(table=19,zone=NXM_NX_REG13[0..15],nat)
d5a76da4
BP
945 has prereqs ip
946ct_lb(192.168.1.2:80, 192.168.1.3:80);
947 encodes as group:1
948 has prereqs ip
949ct_lb(192.168.1.2, 192.168.1.3, );
950 formats as ct_lb(192.168.1.2, 192.168.1.3);
951 encodes as group:2
952 has prereqs ip
9d236afa
MM
953ct_lb(fd0f::2, fd0f::3, );
954 formats as ct_lb(fd0f::2, fd0f::3);
955 encodes as group:3
956 has prereqs ip
d5a76da4
BP
957
958ct_lb(192.168.1.2:);
959 Syntax error at `)' expecting port number.
960ct_lb(192.168.1.2:123456);
961 Syntax error at `123456' expecting port number.
962ct_lb(foo);
9d236afa
MM
963 Syntax error at `foo' expecting IP address.
964ct_lb([192.168.1.2]);
965 Syntax error at `192.168.1.2' expecting IPv6 address.
d5a76da4
BP
966
967# ct_next
968ct_next;
00c875d0 969 encodes as ct(table=19,zone=NXM_NX_REG13[0..15])
d5a76da4
BP
970 has prereqs ip
971
972# ct_commit
973ct_commit;
974 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
975 has prereqs ip
976ct_commit();
977 formats as ct_commit;
978 encodes as ct(commit,zone=NXM_NX_REG13[0..15])
979 has prereqs ip
980ct_commit(ct_mark=1);
981 formats as ct_commit(ct_mark=0x1);
982 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark))
983 has prereqs ip
984ct_commit(ct_mark=1/1);
985 formats as ct_commit(ct_mark=0x1/0x1);
986 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_mark))
987 has prereqs ip
988ct_commit(ct_label=1);
989 formats as ct_commit(ct_label=0x1);
990 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_label))
991 has prereqs ip
992ct_commit(ct_label=1/1);
993 formats as ct_commit(ct_label=0x1/0x1);
994 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1/0x1->ct_label))
995 has prereqs ip
996ct_commit(ct_mark=1, ct_label=2);
997 formats as ct_commit(ct_mark=0x1, ct_label=0x2);
998 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1->ct_mark,set_field:0x2->ct_label))
999 has prereqs ip
1000
1001ct_commit(ct_label=0x01020304050607080910111213141516);
1002 formats as ct_commit(ct_label=0x1020304050607080910111213141516);
1003 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1020304050607080910111213141516->ct_label))
1004 has prereqs ip
1005ct_commit(ct_label=0x181716151413121110090807060504030201);
1006 formats as ct_commit(ct_label=0x16151413121110090807060504030201);
1007 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x16151413121110090807060504030201->ct_label))
1008 has prereqs ip
1009ct_commit(ct_label=0x1000000000000000000000000000000/0x1000000000000000000000000000000);
1010 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0x1000000000000000000000000000000/0x1000000000000000000000000000000->ct_label))
1011 has prereqs ip
1012ct_commit(ct_label=18446744073709551615);
1013 formats as ct_commit(ct_label=0xffffffffffffffff);
1014 encodes as ct(commit,zone=NXM_NX_REG13[0..15],exec(set_field:0xffffffffffffffff->ct_label))
1015 has prereqs ip
1016ct_commit(ct_label=18446744073709551616);
1017 Decimal constants must be less than 2**64.
1018
1019# ct_dnat
1020ct_dnat;
00c875d0 1021 encodes as ct(table=19,zone=NXM_NX_REG11[0..15],nat)
d5a76da4
BP
1022 has prereqs ip
1023ct_dnat(192.168.1.2);
00c875d0 1024 encodes as ct(commit,table=19,zone=NXM_NX_REG11[0..15],nat(dst=192.168.1.2))
d5a76da4
BP
1025 has prereqs ip
1026
1027ct_dnat(192.168.1.2, 192.168.1.3);
1028 Syntax error at `,' expecting `)'.
1029ct_dnat(foo);
1030 Syntax error at `foo' expecting IPv4 address.
1031ct_dnat(foo, bar);
1032 Syntax error at `foo' expecting IPv4 address.
1033ct_dnat();
1034 Syntax error at `)' expecting IPv4 address.
1035
1036# ct_snat
1037ct_snat;
00c875d0 1038 encodes as ct(table=19,zone=NXM_NX_REG12[0..15],nat)
d5a76da4
BP
1039 has prereqs ip
1040ct_snat(192.168.1.2);
00c875d0 1041 encodes as ct(commit,table=19,zone=NXM_NX_REG12[0..15],nat(src=192.168.1.2))
d5a76da4
BP
1042 has prereqs ip
1043
1044ct_snat(192.168.1.2, 192.168.1.3);
1045 Syntax error at `,' expecting `)'.
1046ct_snat(foo);
1047 Syntax error at `foo' expecting IPv4 address.
1048ct_snat(foo, bar);
1049 Syntax error at `foo' expecting IPv4 address.
1050ct_snat();
1051 Syntax error at `)' expecting IPv4 address.
de297547 1052
db0e819b
BP
1053# ct_clear
1054ct_clear;
1055 encodes as ct_clear
1056
b3bd2c33 1057# clone
8f5de083 1058clone { ip4.dst = 255.255.255.255; output; }; next;
00c875d0 1059 encodes as clone(set_field:255.255.255.255->ip_dst,resubmit(,64)),resubmit(,19)
b3bd2c33
BP
1060 has prereqs eth.type == 0x800
1061
6335d074 1062# arp
8a41ad8e
BP
1063arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1064 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 1065 has prereqs ip4
bac29564
BP
1066arp { };
1067 formats as arp { drop; };
1068 encodes as controller(userdata=00.00.00.00.00.00.00.00)
1069 has prereqs ip4
6335d074 1070
0bac7164 1071# get_arp
d5a76da4
BP
1072get_arp(outport, ip4.dst);
1073 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[]
1074 has prereqs eth.type == 0x800
1075get_arp(inport, reg0);
1076 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[]
1077
1078get_arp;
1079 Syntax error at `;' expecting `('.
1080get_arp();
1081 Syntax error at `)' expecting field name.
1082get_arp(inport);
1083 Syntax error at `)' expecting `,'.
1084get_arp(inport ip4.dst);
1085 Syntax error at `ip4.dst' expecting `,'.
1086get_arp(inport, ip4.dst;
1087 Syntax error at `;' expecting `)'.
1088get_arp(inport, eth.dst);
1089 Cannot use 48-bit field eth.dst[0..47] where 32-bit field is required.
1090get_arp(inport, outport);
1091 Cannot use string field outport where numeric field is required.
1092get_arp(reg0, ip4.dst);
1093 Cannot use numeric field reg0 where string field is required.
0bac7164
BP
1094
1095# put_arp
d5a76da4
BP
1096put_arp(inport, arp.spa, arp.sha);
1097 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[]
1098 has prereqs eth.type == 0x806 && eth.type == 0x806
0bac7164 1099
42814145 1100# put_dhcp_opts
d5a76da4
BP
1101reg1[0] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1102 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)
1103reg2[5] = put_dhcp_opts(offerip=10.0.0.4,router=10.0.0.1,netmask=255.255.254.0,mtu=1400,domain="ovn.org");
1104 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");
1105 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)
1106reg0[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);
1107 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);
1108 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)
1109
1110reg1[0..1] = put_dhcp_opts(offerip = 1.2.3.4, router = 10.0.0.1);
1111 Cannot use 2-bit field reg1[0..1] where 1-bit field is required.
1112reg1[0] = put_dhcp_opts();
1113 put_dhcp_opts requires offerip to be specified.
1114reg1[0] = put_dhcp_opts(x = 1.2.3.4, router = 10.0.0.1);
1115 Syntax error at `x' expecting DHCPv4 option name.
1116reg1[0] = put_dhcp_opts(router = 10.0.0.1);
1117 put_dhcp_opts requires offerip to be specified.
1118reg1[0] = put_dhcp_opts(offerip=1.2.3.4, "hi");
1119 Syntax error at `"hi"'.
1120reg1[0] = put_dhcp_opts(offerip=1.2.3.4, xyzzy);
1121 Syntax error at `xyzzy' expecting DHCPv4 option name.
1122reg1[0] = put_dhcp_opts(offerip="xyzzy");
1123 DHCPv4 option offerip requires numeric value.
1124reg1[0] = put_dhcp_opts(offerip=1.2.3.4, domain=1.2.3.4);
1125 DHCPv4 option domain requires string value.
42814145 1126
b1a3a6a4
NS
1127# nd_ns
1128nd_ns { nd.target = xxreg0; output; };
1129 encodes as controller(userdata=00.00.00.09.00.00.00.00.ff.ff.00.18.00.00.23.20.00.06.00.80.00.00.00.00.00.01.de.10.00.01.2e.10.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.40.00.00.00)
1130 has prereqs ip6
1131
1132nd_ns { };
1133 formats as nd_ns { drop; };
1134 encodes as controller(userdata=00.00.00.09.00.00.00.00)
1135 has prereqs ip6
1136
f8a8db39 1137# nd_na
d5a76da4
BP
1138nd_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; };
1139 formats as nd_na { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1140 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)
1141 has prereqs nd_ns
c9756229
NS
1142# nd_na_router
1143nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; /* Allow sending out inport. */ output; };
1144 formats as nd_na_router { eth.src = 12:34:56:78:9a:bc; nd.tll = 12:34:56:78:9a:bc; outport = inport; inport = ""; output; };
1145 encodes as controller(userdata=00.00.00.0c.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)
1146 has prereqs nd_ns
e75451fe 1147
c34a87b6 1148# get_nd
d5a76da4
BP
1149get_nd(outport, ip6.dst);
1150 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[]
1151 has prereqs eth.type == 0x86dd
1152get_nd(inport, xxreg0);
1153 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[]
1154get_nd;
1155 Syntax error at `;' expecting `('.
1156get_nd();
1157 Syntax error at `)' expecting field name.
1158get_nd(inport);
1159 Syntax error at `)' expecting `,'.
1160get_nd(inport ip6.dst);
1161 Syntax error at `ip6.dst' expecting `,'.
1162get_nd(inport, ip6.dst;
1163 Syntax error at `;' expecting `)'.
1164get_nd(inport, eth.dst);
1165 Cannot use 48-bit field eth.dst[0..47] where 128-bit field is required.
1166get_nd(inport, outport);
1167 Cannot use string field outport where numeric field is required.
1168get_nd(xxreg0, ip6.dst);
1169 Cannot use numeric field xxreg0 where string field is required.
c34a87b6
JP
1170
1171# put_nd
d5a76da4
BP
1172put_nd(inport, nd.target, nd.sll);
1173 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[]
32157c87 1174 has prereqs (icmp6.type == 0x87 || 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 1175
01cfdb2f 1176# put_dhcpv6_opts
d5a76da4 1177reg1[0] = put_dhcpv6_opts(ia_addr = ae70::4, server_id = 00:00:00:00:10:02);
a55dacac 1178 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
1179reg1[0] = put_dhcpv6_opts();
1180 encodes as controller(userdata=00.00.00.05.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1181reg1[0] = put_dhcpv6_opts(dns_server={ae70::1,ae70::2});
1182 formats as reg1[0] = put_dhcpv6_opts(dns_server = {ae70::1, ae70::2});
a55dacac 1183 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
1184reg1[0] = put_dhcpv6_opts(server_id=12:34:56:78:9a:bc, dns_server={ae70::1,ae89::2});
1185 formats as reg1[0] = put_dhcpv6_opts(server_id = 12:34:56:78:9a:bc, dns_server = {ae70::1, ae89::2});
a55dacac 1186 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 1187reg1[0] = put_dhcpv6_opts(domain_search = "ovn.org");
a55dacac 1188 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
1189reg1[0] = put_dhcpv6_opts(x = 1.2.3.4);
1190 Syntax error at `x' expecting DHCPv6 option name.
1191reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, "hi");
1192 Syntax error at `"hi"'.
1193reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, xyzzy);
1194 Syntax error at `xyzzy' expecting DHCPv6 option name.
1195reg1[0] = put_dhcpv6_opts(ia_addr="ae70::4");
1196 DHCPv6 option ia_addr requires numeric value.
1197reg1[0] = put_dhcpv6_opts(ia_addr=ae70::4, domain_search=ae70::1);
1198 DHCPv6 option domain_search requires string value.
01cfdb2f 1199
a6095f81
BS
1200# set_queue
1201set_queue(0);
1202 encodes as set_queue:0
1203set_queue(61440);
1204 encodes as set_queue:61440
1205set_queue(65535);
1206 Queue ID 65535 for set_queue is not in valid range 0 to 61440.
1207
ea991ad2
NS
1208# dns_lookup
1209reg1[0] = dns_lookup();
1210 encodes as controller(userdata=00.00.00.06.00.00.00.00.00.01.de.10.00.00.00.40,pause)
1211 has prereqs udp
1212reg1[0] = dns_lookup("foo");
1213 dns_lookup doesn't take any parameters
1214
66d89287
GL
1215# set_meter
1216set_meter(0);
1217 Rate 0 for set_meter is not in valid.
1218set_meter(1);
1219 encodes as meter:1
1220set_meter(100, 1000);
1221 encodes as meter:2
1222set_meter(100, 1000, );
1223 Syntax error at `,' expecting `)'.
1224set_meter(4294967295, 4294967295);
1225 encodes as meter:3
1226
52ed5fcc
NS
1227# put_nd_ra_opts
1228reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1229 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.00.ff.ff.00.00.00.00.00.00.00.00.05.01.00.00.00.00.05.dc.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.05,pause)
1230 has prereqs ip6
1231reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1232 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.80.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.10.05.01.00.00.00.00.05.aa,pause)
1233 has prereqs ip6
1234reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1235 encodes as controller(userdata=00.00.00.08.00.00.00.00.00.01.de.10.00.00.00.40.86.00.00.00.ff.40.ff.ff.00.00.00.00.00.00.00.00.01.01.ae.01.02.03.04.06.03.04.40.c0.ff.ff.ff.ff.ff.ff.ff.ff.00.00.00.00.ae.f0.00.00.00.00.00.00.00.00.00.00.00.00.00.00,pause)
1236 has prereqs ip6
1237reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1238 slla option not present
1239reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1240 prefix option can't be set when address mode is dhcpv6_stateful.
1241reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1242 prefix option can't be set when address mode is dhcpv6_stateful.
1243reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1244 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1245reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1246 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1247reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1248 Syntax error at `dhcpv6_stateless' expecting constant.
1249reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1250 Invalid value for "prefix" option
1251reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1252 Invalid value for "addr_mode" option
1253reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1254 IPv6 ND RA option mtu requires numeric value.
1255reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1256 Invalid value for "mtu" option
1257
bc3d6a63
LB
1258# icmp4
1259icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1260 encodes as controller(userdata=00.00.00.0a.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)
1261 has prereqs ip4
1262
1263icmp4 { };
1264 formats as icmp4 { drop; };
1265 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1266 has prereqs ip4
1267
3e7fa1e3
LB
1268# icmp6
1269icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1270 encodes as controller(userdata=00.00.00.0a.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)
1271 has prereqs ip6
1272
1273icmp6 { };
1274 formats as icmp6 { drop; };
1275 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1276 has prereqs ip6
1277
22b65e4d
LB
1278# tcp_reset
1279tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1280 encodes as controller(userdata=00.00.00.0b.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)
1281 has prereqs tcp
1282
1283tcp_reset { };
1284 formats as tcp_reset { drop; };
1285 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1286 has prereqs tcp
1287
5f822129 1288# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1289ip4.src = ip6.src[0..31];
1290 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1291 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1292ip4.src <-> ip6.src[0..31];
1293 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[]
1294 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1295
1296# Miscellaneous negative tests.
1297;
1298 Syntax error at `;'.
1299xyzzy;
1300 Syntax error at `xyzzy' expecting action.
1301next; 123;
1302 Syntax error at `123'.
1303next; xyzzy;
1304 Syntax error at `xyzzy' expecting action.
1305next
9aef3c1b 1306 Syntax error at end of input expecting `;'.
3b7cb7e1 1307]])
d5a76da4
BP
1308sed '/^[[ ]]/d' test-cases.txt > input.txt
1309cp test-cases.txt expout
3b7cb7e1
BP
1310AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1311AT_CLEANUP
f295c17b
BP
1312
1313AT_BANNER([OVN end-to-end tests])
1314
9975d7be
BP
1315# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1316AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1317AT_KEYWORDS([ovnarp])
f295c17b
BP
1318AT_SKIP_IF([test $HAVE_PYTHON = no])
1319ovn_start
1320
1321# Create hypervisors hv[123].
9975d7be 1322# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1323# Add all of the vifs to a single logical switch lsw0.
1324# Turn on port security on all the vifs except vif[123]1.
1325# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1326# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1327ovn-nbctl ls-add lsw0
f295c17b
BP
1328net_add n1
1329for i in 1 2 3; do
1330 sim_add hv$i
1331 as hv$i
1332 ovs-vsctl add-br br-phys
1333 ovn_attach n1 br-phys 192.168.0.$i
1334
1335 for j in 1 2 3; do
1336 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 1337 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1338 if test $j = 1; then
31ed1192 1339 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1340 else
7dc88496
NS
1341 if test $j = 3; then
1342 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1343 else
1344 ip_addrs="192.168.0.$i$j"
1345 fi
31ed1192
JP
1346 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1347 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1348 fi
1349 done
1350done
1351ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1352ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1353ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1354ovn-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\"
1355ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1356
3d2848ba
HZ
1357get_lsp_uuid () {
1358 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1359}
1360
1361ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1362ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1363
f295c17b
BP
1364# Pre-populate the hypervisors' ARP tables so that we don't lose any
1365# packets for ARP resolution (native tunneling doesn't queue packets
1366# for ARP resolution).
74868f2c 1367OVN_POPULATE_ARP
f295c17b
BP
1368
1369# Allow some time for ovn-northd and ovn-controller to catch up.
1370# XXX This should be more systematic.
1371sleep 1
611099dc 1372
fc6f9978
HZ
1373# Make sure there is no attempt to adding duplicated flows by ovn-controller
1374AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1375AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1376AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1377
57d143eb
HZ
1378# Given the name of a logical port, prints the name of the hypervisor
1379# on which it is located.
1380vif_to_hv() {
1381 echo hv${1%?}
1382}
1383
f295c17b
BP
1384# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1385#
1386# This shell function causes a packet to be received on INPORT. The packet's
1387# content has Ethernet destination DST and source SRC (each exactly 12 hex
1388# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1389# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1390# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1391for i in 1 2 3; do
1392 for j in 1 2 3; do
1393 : > $i$j.expected
1394 done
1395done
1396test_packet() {
1397 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1398 hv=`vif_to_hv $inport`
f295c17b
BP
1399 vif=vif$inport
1400 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1401 for outport; do
e4543cfe 1402 echo $packet >> $outport.expected
f295c17b
BP
1403 done
1404}
1405
57d143eb
HZ
1406# test_arp INPORT SHA SPA TPA [REPLY_HA]
1407#
1408# Causes a packet to be received on INPORT. The packet is an ARP
1409# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1410# it should be the hardware address of the target to expect to receive in an
1411# ARP reply; otherwise no reply is expected.
1412#
31ed1192 1413# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1414# SHA and REPLY_HA are each 12 hex digits.
1415# SPA and TPA are each 8 hex digits.
1416test_arp() {
1417 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1418 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1419 hv=`vif_to_hv $inport`
1420 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1421
92f9822b 1422 if test X$reply_ha = X; then
57d143eb
HZ
1423 # Expect to receive the broadcast ARP on the other logical switch ports
1424 # if no reply is expected.
1425 local i j
1426 for i in 1 2 3; do
1427 for j in 1 2 3; do
1428 if test $i$j != $inport; then
1429 echo $request >> $i$j.expected
1430 fi
1431 done
1432 done
1433 else
1434 # Expect to receive the reply, if any.
1435 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1436 echo $reply >> $inport.expected
1437 fi
1438}
1439
1440ip_to_hex() {
1441 printf "%02x%02x%02x%02x" "$@"
1442}
1443
f295c17b
BP
1444# Send packets between all pairs of source and destination ports:
1445#
31ed1192
JP
1446# 1. Unicast packets are delivered to exactly one logical switch port
1447# (except that packets destined to their input ports are dropped).
f295c17b 1448#
31ed1192
JP
1449# 2. Broadcast and multicast are delivered to all logical switch ports
1450# except the input port.
f295c17b 1451#
ea46a4e9 1452# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1453# MAC address.
1454#
ea46a4e9 1455# 4. The switch drops all packets with a VLAN tag.
f295c17b 1456#
ea46a4e9 1457# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1458# affects behavior when port security is turned off, since otherwise port
1459# security would drop the packet anyway.)
1460#
ea46a4e9 1461# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1462# switch ports with "unknown" among their MAC addresses (and port
1463# security disabled).
f295c17b 1464#
ea46a4e9 1465# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1466#
ea46a4e9 1467# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1468#
9fcb6a18
BP
1469# 9. OVN generates responses to ARP requests for known IPs, except for
1470# requests from a port for the port's own IP.
57d143eb
HZ
1471#
1472# 10. No response to ARP requests for unknown IPs.
4acd1e87 1473
f295c17b
BP
1474for is in 1 2 3; do
1475 for js in 1 2 3; do
1476 s=$is$js
1477 bcast=
4d5c43d5
JP
1478 unknown=
1479 bacl2=
1480 bacl3=
f295c17b
BP
1481 for id in 1 2 3; do
1482 for jd in 1 2 3; do
1483 d=$id$jd
1484
1485 if test $d != $s; then unicast=$d; else unicast=; fi
1486 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1487
1488 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1489 impersonate=$d
1490 else
1491 impersonate=
1492 fi
f295c17b
BP
1493 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1494
4d5c43d5
JP
1495 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1496 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1497 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1498 # Source of 11, 21, or 31 and dest of 33 should be dropped
1499 # due to the 4th ACL that uses address_set(set1).
1500 acl4=
1501 else
1502 acl4=$d
1503 fi
3d2848ba
HZ
1504 if test $d = $s || test $d = 22 || test $d = 33; then
1505 # dest of 22 and 33 should be dropped
1506 # due to the 5th ACL that uses port_group(pg1).
1507 acl5=
1508 else
1509 acl5=$d
1510 fi
f295c17b
BP
1511 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1512 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1513 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1514 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1515 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1516
1517 test_packet $s f000000000$d f00000000055 810000091234 #4
1518 test_packet $s f000000000$d 0100000000$s $s$d #5
1519
4d5c43d5
JP
1520 if test $d != $s && test $jd = 1; then
1521 unknown="$unknown $d"
1522 fi
f295c17b
BP
1523 bcast="$bcast $unicast"
1524 bacl2="$bacl2 $acl2"
1525 bacl3="$bacl3 $acl3"
57d143eb 1526
db02f370 1527 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1528 tip=`ip_to_hex 192 168 0 $id$jd`
1529 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1530 if test $d != $s; then
1531 reply_ha=f000000000$d
1532 else
1533 reply_ha=
1534 fi
1535 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1536 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1537
1538 if test $jd = 3; then
31ed1192 1539 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1540 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1541 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1542 fi
f295c17b
BP
1543 done
1544 done
1545
4d5c43d5 1546 # Broadcast and multicast.
f295c17b
BP
1547 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1548 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1549 if test $js = 1; then
f295c17b
BP
1550 bcast_impersonate=$bcast
1551 else
4d5c43d5
JP
1552 bcast_impersonate=
1553 fi
f295c17b
BP
1554 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1555
1556 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1557
1558 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1559 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1560 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1561 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1562 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1563 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1564 done
1565done
1566
7dc88496
NS
1567# set address for lp13 with invalid characters.
1568# lp13 should be configured with only 192.168.0.13.
31ed1192 1569ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1570
1571# Allow some time for ovn-northd and ovn-controller to catch up.
1572# XXX This should be more systematic.
1573sleep 1
1574
7dc88496
NS
1575sip=`ip_to_hex 192 168 0 11`
1576tip=`ip_to_hex 192 168 0 13`
1577test_arp 11 f00000000011 $sip $tip f00000000013
1578
1579tip=`ip_to_hex 192 169 0 13`
1580#arp request for 192.169.0.13 should be flooded
1581test_arp 11 f00000000011 $sip $tip
1582
91125642 1583# dump information and flows with counters
bb0c41d3
RM
1584ovn-sbctl dump-flows -- list multicast_group
1585
1586echo "------ hv1 dump ------"
1587as hv1 ovs-vsctl show
1588as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1589
1590echo "------ hv2 dump ------"
1591as hv2 ovs-vsctl show
1592as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1593
1594echo "------ hv3 dump ------"
1595as hv3 ovs-vsctl show
1596as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1597
f295c17b
BP
1598# Now check the packets actually received against the ones expected.
1599for i in 1 2 3; do
1600 for j in 1 2 3; do
49d7c759 1601 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1602 done
1603done
fcde56f5 1604
7a8f15e0 1605OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1606
f295c17b 1607AT_CLEANUP
eb6b08eb 1608
4acd1e87
BP
1609AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1610AT_SKIP_IF([test $HAVE_PYTHON = no])
1611ovn_start
1612
1613# Create a logical switch and some logical ports.
1614# Turn on port security on all lports except ls1.
1615# Make ls1 a destination for unknown MACs.
1616# Add some ACLs for Ethertypes 1234, 1235, 1236.
1617ovn-nbctl ls-add lsw0
1618ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1619for i in 1 2 3; do
1620 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1621done
1622ovn-nbctl --wait=sb sync
1623for i in 1 2 3; do
4acd1e87
BP
1624 ovn-sbctl lsp-bind lp$i hv0
1625 if test $i = 1; then
abb37b6b 1626 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1627 else
abb37b6b
FF
1628 if test $i = 3; then
1629 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1630 else
1631 ip_addrs="192.168.0.$i"
1632 fi
a8e2addc
LR
1633 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1634 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1635 fi
1636done
1637ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1638ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1639ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1640ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1641ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1642
1643ovn-nbctl --wait=sb sync
1644on_exit 'kill `cat ovn-trace.pid`'
1645ovn-trace --detach --pidfile --no-chdir
1646
1647# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1648#
1649# This shell function causes a packet to be received on INPORT. The packet's
1650# content has Ethernet destination DST and source SRC (each exactly 12 hex
1651# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1652# more) list the VIFs on which the packet should be received. INPORT and the
1653# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1654test_packet() {
1655 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1656 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1657 while :; do
abb37b6b
FF
1658 case $1 in # (
1659 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1660 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1661 *) break ;;
1662 esac
4acd1e87
BP
1663 done
1664 for outport; do
abb37b6b 1665 echo "output(\"lp$outport\");"
4acd1e87
BP
1666 done > expout
1667
1668 AT_CAPTURE_FILE([trace])
1669 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1670}
1671
1672# test_arp INPORT SHA SPA TPA [REPLY_HA]
1673#
1674# Causes a packet to be received on INPORT. The packet is an ARP
1675# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1676# it should be the hardware address of the target to expect to receive in an
1677# ARP reply; otherwise no reply is expected.
1678#
1679# INPORT is an logical switch port number, e.g. 11 for vif11.
1680# SHA and REPLY_HA are each 12 hex digits.
1681# SPA and TPA are each 8 hex digits.
1682test_arp() {
1683 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1684
1685 local request="inport == \"lp$inport\"
1686 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1687 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1688 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1689
1690 if test -z "$reply_ha"; then
1691 reply=
abb37b6b
FF
1692 local i
1693 for i in 1 2 3; do
1694 if test $i != $inport; then
1695 reply="${reply}output(\"lp$i\");
4acd1e87 1696"
abb37b6b
FF
1697 fi
1698 done
4acd1e87
BP
1699 else
1700 reply="\
1701eth.dst = $sha;
1702eth.src = $reply_ha;
1703arp.op = 2;
1704arp.tha = $sha;
1705arp.sha = $reply_ha;
1706arp.tpa = $spa;
1707arp.spa = $tpa;
1708output(\"lp$inport\");
1709"
1710 fi
1711
1712 AT_CAPTURE_FILE([trace])
1713 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1714}
1715
1716# Send packets between all pairs of source and destination ports:
1717#
1718# 1. Unicast packets are delivered to exactly one logical switch port
1719# (except that packets destined to their input ports are dropped).
1720#
1721# 2. Broadcast and multicast are delivered to all logical switch ports
1722# except the input port.
1723#
1724# 3. When port security is turned on, the switch drops packets from the wrong
1725# MAC address.
1726#
1727# 4. The switch drops all packets with a VLAN tag.
1728#
1729# 5. The switch drops all packets with a multicast source address. (This only
1730# affects behavior when port security is turned off, since otherwise port
1731# security would drop the packet anyway.)
1732#
1733# 6. The switch delivers packets with an unknown destination to logical
1734# switch ports with "unknown" among their MAC addresses (and port
1735# security disabled).
1736#
1737# 7. The switch drops unicast packets that violate an ACL.
1738#
1739# 8. The switch drops multicast and broadcast packets that violate an ACL.
1740#
9fcb6a18
BP
1741# 9. OVN generates responses to ARP requests for known IPs, except for
1742# requests from a port for the port's own IP.
4acd1e87
BP
1743#
1744# 10. No response to ARP requests for unknown IPs.
1745
1746for s in 1 2 3; do
1747 bcast=
1748 unknown=
1749 bacl2=
1750 bacl3=
1751 for d in 1 2 3; do
abb37b6b
FF
1752 echo
1753 echo "lp$s -> lp$d"
1754 if test $d != $s; then unicast=$d; else unicast=; fi
1755 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1756
1757 if test $d != $s && test $s = 1; then
1758 impersonate=$d
1759 else
1760 impersonate=
1761 fi
1762 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1763
1764 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1765 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1766 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1767 # Source of 1 or 2 and dest of 3 should be dropped
1768 # due to the 4th ACL that uses address_set(set1).
1769 acl4=
1770 else
1771 acl4=$d
1772 fi
1773
1774 #7, acl1 to acl4:
1775 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1776 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1777 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1778 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1779
1780 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1781 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1782
1783 if test $d != $s && test $d = 1; then
1784 unknown="$unknown $d"
1785 fi
1786 bcast="$bcast $unicast"
1787 bacl2="$bacl2 $acl2"
1788 bacl3="$bacl3 $acl3"
1789
1790 sip=192.168.0.$s
1791 tip=192.168.0.$d
1792 tip_unknown=11.11.11.11
9fcb6a18
BP
1793 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1794 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1795 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1796
1797 if test $d = 3; then
1798 # lp3 has an additional ip 192.169.0.[123]3.
1799 tip=192.169.0.$d
9fcb6a18 1800 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1801 fi
4acd1e87
BP
1802 done
1803
1804 # Broadcast and multicast.
1805 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1806 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1807 if test $s = 1; then
abb37b6b 1808 bcast_impersonate=$bcast
4acd1e87 1809 else
abb37b6b 1810 bcast_impersonate=
4acd1e87
BP
1811 fi
1812 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1813
1814 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1815
1816 #8, acl1 to acl3:
1817 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1818 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1819 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1820
1821 #8, acl1 to acl3:
1822 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1823 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1824 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1825done
1826
1827AT_CLEANUP
1828
7277bc83
RB
1829# 2 hypervisors, 4 logical ports per HV
1830# 2 locally attached networks (one flat, one vlan tagged over same device)
1831# 2 ports per HV on each network
e90aeb57 1832AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1833AT_SKIP_IF([test $HAVE_PYTHON = no])
1834ovn_start
1835
ea46a4e9
JP
1836# In this test cases we create 3 switches, all connected to same
1837# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1838# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1839# of VIF port name indicates the hypervisor it is bound to, e.g.
1840# lp23 means VIF 3 on hv2.
1841#
ea46a4e9 1842# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1843# - ls1:
1844# - untagged
ea46a4e9 1845# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1846#
1847# - ls2:
1848# - tagged with VLAN 101
ea46a4e9 1849# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1850# - ls3:
1851# - untagged
ea46a4e9 1852# - ports: lp15, lp25
0ee7f7f1 1853#
ea46a4e9 1854# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1855# physical network.
1856
1857for i in 1 2 3; do
ea46a4e9
JP
1858 ls_name=ls$i
1859 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1860 ln_port_name=ln$i
1861 if test $i -eq 2; then
ea46a4e9 1862 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1863 else
ea46a4e9 1864 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1865 fi
31ed1192
JP
1866 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1867 ovn-nbctl lsp-set-type $ln_port_name localnet
1868 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1869done
d79fc5f4 1870
69b72264
BP
1871# lsp_to_ls LSP
1872#
1873# Prints the name of the logical switch that contains LSP.
1874lsp_to_ls () {
1875 case $1 in dnl (
5a0e4aec
BP
1876 lp?[[12]]) echo ls1 ;; dnl (
1877 lp?[[34]]) echo ls2 ;; dnl (
1878 lp?5) echo ls3 ;; dnl (
1879 *) AT_FAIL_IF([:]) ;;
69b72264
BP
1880 esac
1881}
1882
d79fc5f4
RB
1883net_add n1
1884for i in 1 2; do
1885 sim_add hv$i
1886 as hv$i
1887 ovs-vsctl add-br br-phys
1888 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1889 ovn_attach n1 br-phys 192.168.0.$i
1890
0ee7f7f1 1891 for j in 1 2 3 4 5; do
d79fc5f4
RB
1892 ovs-vsctl add-port br-int vif$i$j -- \
1893 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1894 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1895 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1896 ofport-request=$i$j
1897
31ed1192 1898 lsp_name=lp$i$j
5a0e4aec 1899 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1900
ea46a4e9 1901 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1902 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1903 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1904
31ed1192 1905 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1906 done
1907done
69b72264
BP
1908ovn-nbctl --wait=sb sync
1909ovn-sbctl dump-flows
d79fc5f4 1910
74868f2c 1911OVN_POPULATE_ARP
d79fc5f4
RB
1912
1913# XXX This is now the 3rd copy of these functions in this file ...
1914
1915# Given the name of a logical port, prints the name of the hypervisor
1916# on which it is located.
1917vif_to_hv() {
1918 echo hv${1%?}
1919}
1920#
69b72264 1921# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1922#
1923# This shell function causes a packet to be received on INPORT. The packet's
1924# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1925# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1926# logical switch port numbers, e.g. 11 for vif11.
1927#
1928# EOUT is the end-to-end output port, that is, where the packet will end up
1929# after possibly bouncing through one or more localnet ports. LOUT is the
1930# logical output port, which might be a localnet port, as seen by ovn-trace
1931# (which doesn't know what localnet ports are connected to and therefore can't
1932# figure out the end-to-end answer).
d79fc5f4 1933for i in 1 2; do
0ee7f7f1 1934 for j in 1 2 3 4 5; do
d79fc5f4
RB
1935 : > $i$j.expected
1936 done
1937done
1938test_packet() {
69b72264
BP
1939 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1940 echo "$@"
1941
1942 # First try tracing the packet.
1943 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1944 if test $lout != drop; then
1945 echo "output(\"$lout\");"
1946 fi > expout
1947 AT_CAPTURE_FILE([trace])
1948 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1949
1950 # Then actually send a packet, for an end-to-end test.
1951 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1952 hv=`vif_to_hv $inport`
1953 vif=vif$inport
1954 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1955 if test $eout != drop; then
1956 echo $packet >> ${eout#lp}.expected
1957 fi
d79fc5f4
RB
1958}
1959
7277bc83
RB
1960# lp11 and lp21 are on the same network (phys, untagged)
1961# and on different hypervisors
69b72264
BP
1962test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1963test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1964
7277bc83
RB
1965# lp11 and lp12 are on the same network (phys, untagged)
1966# and on the same hypervisor
69b72264
BP
1967test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1968test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1969
1970# lp13 and lp23 are on the same network (phys, VLAN 101)
1971# and on different hypervisors
69b72264
BP
1972test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1973test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1974
1975# lp13 and lp14 are on the same network (phys, VLAN 101)
1976# and on the same hypervisor
69b72264
BP
1977test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1978test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1979
0ee7f7f1 1980# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 1981# same hypervisor, and on different switches
69b72264
BP
1982test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
1983test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
1984
1985# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 1986# different hypervisors, and on different switches
69b72264
BP
1987test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
1988test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 1989
d79fc5f4 1990# Ports that should not be able to communicate
69b72264
BP
1991test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
1992test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
1993test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
1994test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
1995test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
1996test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
1997test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
1998test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 1999
d79fc5f4
RB
2000# Dump a bunch of info helpful for debugging if there's a failure.
2001
2002echo "------ OVN dump ------"
2003ovn-nbctl show
2004ovn-sbctl show
2005
2006echo "------ hv1 dump ------"
2007as hv1 ovs-vsctl show
2008as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2009
2010echo "------ hv2 dump ------"
2011as hv2 ovs-vsctl show
2012as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2013
2014# Now check the packets actually received against the ones expected.
2015for i in 1 2; do
0ee7f7f1 2016 for j in 1 2 3 4 5; do
49d7c759 2017 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
2018 done
2019done
2020
7a8f15e0 2021OVN_CLEANUP([hv1],[hv2])
d9c8c57c 2022
d79fc5f4
RB
2023AT_CLEANUP
2024
91125642
FF
2025AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2026AT_KEYWORDS([vtep])
eb6b08eb
JP
2027AT_SKIP_IF([test $HAVE_PYTHON = no])
2028ovn_start
2029
2030# Configure the Northbound database
ea46a4e9 2031ovn-nbctl ls-add lsw0
eb6b08eb 2032
31ed1192
JP
2033ovn-nbctl lsp-add lsw0 lp1
2034ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 2035
31ed1192
JP
2036ovn-nbctl lsp-add lsw0 lp2
2037ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 2038
31ed1192
JP
2039ovn-nbctl lsp-add lsw0 lp-vtep
2040ovn-nbctl lsp-set-type lp-vtep vtep
2041ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2042ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 2043
77adbb62
DB
2044# lpr, lr and lrp1 are used for the ARP request handling test only.
2045ovn-nbctl lsp-add lsw0 lpr
2046ovn-nbctl lr-add lr
2047ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2048ovn-nbctl set Logical_Switch_Port lpr type=router \
2049 options:router-port=lrp1 \
2050 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2051
2052
eb6b08eb
JP
2053net_add n1 # Network to connect hv1, hv2, and vtep
2054net_add n2 # Network to connect vtep and hv3
2055
2056# Create hypervisor hv1 connected to n1
2057sim_add hv1
2058as hv1
2059ovs-vsctl add-br br-phys
2060ovn_attach n1 br-phys 192.168.0.1
2061ovs-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
2062
2063# Create hypervisor hv2 connected to n1
2064sim_add hv2
2065as hv2
2066ovs-vsctl add-br br-phys
2067ovn_attach n1 br-phys 192.168.0.2
2068ovs-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
2069
2070
2071# Start the vtep emulator with a leg in both networks
2072sim_add vtep
2073as vtep
2074
2075ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2076ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2077
2078ovs-vsctl add-br br-phys
2079net_attach n1 br-phys
2080
2081mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2082arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2083ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2084ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2085
2086ovs-vsctl add-br br-vtep
2087net_attach n2 br-vtep
2088
2089vtep-ctl add-ps br-vtep
2090vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2091vtep-ctl add-ls lsw0
2092
2093start_daemon ovs-vtep br-vtep
2094start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2095
8cdc4312 2096OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 2097
475f0a2c
DB
2098OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2099 grep -- source`"])
2100# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
2101sleep 1
2102
2103# Add hv3 on the other side of the vtep
2104sim_add hv3
2105as hv3
2106ovs-vsctl add-br br-phys
2107net_attach n2 br-phys
2108
2109ovs-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
2110
2111# Pre-populate the hypervisors' ARP tables so that we don't lose any
2112# packets for ARP resolution (native tunneling doesn't queue packets
2113# for ARP resolution).
74868f2c 2114OVN_POPULATE_ARP
eb6b08eb
JP
2115
2116# Allow some time for ovn-northd and ovn-controller to catch up.
2117# XXX This should be more systematic.
2118sleep 1
6977df72 2119
eb6b08eb
JP
2120# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2121#
2122# This shell function causes a packet to be received on INPORT. The packet's
2123# content has Ethernet destination DST and source SRC (each exactly 12 hex
2124# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2125# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2126# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2127for i in 1 2 3; do
2128 : > $i.expected
2129done
2130test_packet() {
2131 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2132 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2133 hv=hv$inport
2134 vif=vif$inport
2135 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2136 for outport; do
e4543cfe 2137 echo $packet >> $outport.expected
eb6b08eb
JP
2138 done
2139}
2140
2141# Send packets between all pairs of source and destination ports:
2142#
31ed1192
JP
2143# 1. Unicast packets are delivered to exactly one logical switch port
2144# (except that packets destined to their input ports are dropped).
eb6b08eb 2145#
31ed1192
JP
2146# 2. Broadcast and multicast are delivered to all logical switch ports
2147# except the input port.
eb6b08eb 2148#
ea46a4e9 2149# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2150# switch ports with "unknown" among their MAC addresses (and port
2151# security disabled).
eb6b08eb
JP
2152for s in 1 2 3; do
2153 bcast=
2154 unknown=
2155 for d in 1 2 3; do
2156 if test $d != $s; then unicast=$d; else unicast=; fi
2157 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2158
2159 # The vtep (vif3) is the only one configured for "unknown"
2160 if test $d != $s && test $d = 3; then
2161 unknown="$unknown $d"
2162 fi
2163 bcast="$bcast $unicast"
2164 done
2165
2166 # Broadcast and multicast.
46ed1382
DB
2167 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2168 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2169
2170 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2171done
2172
77adbb62
DB
2173# ARP request should not be responded to by logical switch router
2174# type arp responder on HV1 and HV2 and should reach directly to
2175# vif1 and vif2
2176ip_to_hex() {
2177 printf "%02x%02x%02x%02x" "$@"
2178}
2179sha=f00000000003
2180spa=`ip_to_hex 192 168 1 2`
2181tpa=`ip_to_hex 192 168 1 1`
2182request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2183as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2184echo $request >> 1.expected
2185echo $request >> 2.expected
2186
bb0c41d3
RM
2187# dump information with counters
2188echo "------ OVN dump ------"
2189ovn-nbctl show
2190ovn-sbctl show
2191
77adbb62
DB
2192echo "---------SB dump-----"
2193ovn-sbctl list datapath_binding
2194echo "---------------------"
2195ovn-sbctl list port_binding
2196echo "---------------------"
2197ovn-sbctl dump-flows
2198
bb0c41d3
RM
2199echo "------ hv1 dump ------"
2200as hv1 ovs-vsctl show
6195e2e7 2201as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2202as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2203
2204echo "------ hv2 dump ------"
2205as hv2 ovs-vsctl show
6195e2e7 2206as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2207as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2208
2209echo "------ hv3 dump ------"
2210as hv3 ovs-vsctl show
6754e92d
FF
2211# note: hv3 has no logical port bind, thus it should not have br-int
2212AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2213[ovs-ofctl: br-int is not a bridge or a socket
2214])
bb0c41d3 2215
eb6b08eb
JP
2216# Now check the packets actually received against the ones expected.
2217for i in 1 2 3; do
49d7c759 2218 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2219done
fcde56f5
LR
2220
2221# Gracefully terminate daemons
7a8f15e0
LR
2222OVN_CLEANUP([hv1],[hv2],[vtep])
2223OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2224
eb6b08eb 2225AT_CLEANUP
9975d7be 2226
184bc3ca
RB
2227# Similar test to "hardware GW"
2228AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2229AT_SKIP_IF([test $HAVE_PYTHON = no])
2230ovn_start
2231
2232# Configure the Northbound database
2233ovn-nbctl ls-add lsw0
2234
2235ovn-nbctl lsp-add lsw0 lp1
2236ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2237
2238ovn-nbctl lsp-add lsw0 lp2
2239ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2240
2241ovn-nbctl lsp-add lsw0 lp-gw
2242ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2243ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2244ovn-nbctl lsp-set-addresses lp-gw unknown
2245
2246net_add n1 # Network to connect hv1, hv2, and gw
2247net_add n2 # Network to connect gw and hv3
2248
2249# Create hypervisor hv1 connected to n1
2250sim_add hv1
2251as hv1
2252ovs-vsctl add-br br-phys
2253ovn_attach n1 br-phys 192.168.0.1
2254ovs-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
2255
2256# Create hypervisor hv2 connected to n1
2257sim_add hv2
2258as hv2
2259ovs-vsctl add-br br-phys
2260ovn_attach n1 br-phys 192.168.0.2
2261ovs-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
2262
2263# Create hypervisor hv_gw connected to n1 and n2
2264# connect br-phys bridge to n1; connect hv-gw bridge to n2
2265sim_add hv_gw
2266as hv_gw
2267ovs-vsctl add-br br-phys
2268ovn_attach n1 br-phys 192.168.0.3
2269ovs-vsctl add-br br-phys2
2270net_attach n2 br-phys2
2271ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2272
184bc3ca
RB
2273# Add hv3 on the other side of the GW
2274sim_add hv3
2275as hv3
2276ovs-vsctl add-br br-phys
2277net_attach n2 br-phys
2278ovs-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
2279
2280
2281# Pre-populate the hypervisors' ARP tables so that we don't lose any
2282# packets for ARP resolution (native tunneling doesn't queue packets
2283# for ARP resolution).
74868f2c 2284OVN_POPULATE_ARP
184bc3ca
RB
2285
2286# Allow some time for ovn-northd and ovn-controller to catch up.
2287# XXX This should be more systematic.
2288sleep 1
2289
2290# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2291#
2292# This shell function causes a packet to be received on INPORT. The packet's
2293# content has Ethernet destination DST and source SRC (each exactly 12 hex
2294# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2295# more) list the VIFs on which the packet should be received. INPORT and the
2296# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2297for i in 1 2 3; do
2298 : > $i.expected
2299done
2300test_packet() {
2301 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2302 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2303 hv=hv$inport
2304 vif=vif$inport
2305 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2306 for outport; do
e4543cfe 2307 echo $packet >> $outport.expected
184bc3ca
RB
2308 done
2309}
2310
2311# Send packets between all pairs of source and destination ports:
2312#
2313# 1. Unicast packets are delivered to exactly one lport (except that packets
2314# destined to their input ports are dropped).
2315#
2316# 2. Broadcast and multicast are delivered to all lports except the input port.
2317#
2318# 3. The lswitch delivers packets with an unknown destination to lports with
2319# "unknown" among their MAC addresses (and port security disabled).
2320for s in 1 2 3 ; do
2321 bcast=
2322 unknown=
2323 for d in 1 2 3 ; do
2324 if test $d != $s; then unicast=$d; else unicast=; fi
2325 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2326
2327 # The vtep (vif3) is the only one configured for "unknown"
2328 if test $d != $s && test $d = 3; then
2329 unknown="$unknown $d"
2330 fi
2331 bcast="$bcast $unicast"
2332 done
2333
2334 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2335 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2336 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2337done
2338
184bc3ca
RB
2339echo "------ ovn-nbctl show ------"
2340ovn-nbctl show
2341echo "------ ovn-sbctl show ------"
2342ovn-sbctl show
2343
2344echo "------ hv1 ------"
2345as hv1 ovs-vsctl show
2346echo "------ hv1 br-int ------"
2347as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2348echo "------ hv1 br-phys ------"
2349as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2350
2351echo "------ hv2 ------"
2352as hv2 ovs-vsctl show
2353echo "------ hv2 br-int ------"
2354as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2355echo "------ hv2 br-phys ------"
2356as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2357
2358echo "------ hv_gw ------"
2359as hv_gw ovs-vsctl show
2360echo "------ hv_gw br-phys ------"
2361as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2362echo "------ hv_gw br-phys2 ------"
2363as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2364
2365echo "------ hv3 ------"
2366as hv3 ovs-vsctl show
2367echo "------ hv3 br-phys ------"
2368as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2369
2370# Now check the packets actually received against the ones expected.
2371for i in 1 2 3; do
49d7c759 2372 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2373done
2374AT_CLEANUP
2375
9975d7be
BP
2376# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2377AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2378AT_SKIP_IF([test $HAVE_PYTHON = no])
2379ovn_start
2380
2381# Logical network:
2382#
2383# Three logical switches ls1, ls2, ls3.
86e98048
BP
2384# One logical router lr0 connected to ls[123],
2385# with nine subnets, three per logical switch:
2386#
2387# lrp11 on ls1 for subnet 192.168.11.0/24
2388# lrp12 on ls1 for subnet 192.168.12.0/24
2389# lrp13 on ls1 for subnet 192.168.13.0/24
2390# ...
2391# lrp33 on ls3 for subnet 192.168.33.0/24
2392#
2393# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2394# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2395for i in 1 2 3; do
ea46a4e9 2396 ovn-nbctl ls-add ls$i
9975d7be 2397 for j in 1 2 3; do
86e98048 2398 for k in 1 2 3; do
31ed1192
JP
2399 # Add "unknown" to MAC addresses for lp?11, so packets for
2400 # MAC-IP bindings discovered via ARP later have somewhere to go.
2401 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2402
2403 ovn-nbctl \
2404 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
2405 -- lsp-set-addresses lp$i$j$k \
2406 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
86e98048
BP
2407 done
2408 done
2409done
2410
fa2a27b2 2411ovn-nbctl lr-add lr0
86e98048
BP
2412for i in 1 2 3; do
2413 for j in 1 2 3; do
bf44c2cd 2414 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2415 ovn-nbctl \
31ed1192 2416 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2417 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2418 options:router-port=lrp$i$j \
86e98048 2419 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2420 done
2421done
2422
80f408f4 2423ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2424 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2425
9975d7be
BP
2426# Physical network:
2427#
2428# Three hypervisors hv[123].
86e98048
BP
2429# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2430# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2431# lp?3[123] all on hv3.
2432
9975d7be
BP
2433
2434# Given the name of a logical port, prints the name of the hypervisor
2435# on which it is located.
2436vif_to_hv() {
2437 case $1 in dnl (
86e98048
BP
2438 ?11) echo 1 ;; dnl (
2439 ?12 | ?21 | ?22) echo 2 ;; dnl (
2440 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2441 esac
2442}
2443
86e98048
BP
2444# Given the name of a logical port, prints the name of its logical router
2445# port, e.g. "vif_to_lrp 123" yields 12.
2446vif_to_lrp() {
2447 echo ${1%?}
2448}
2449
2450# Given the name of a logical port, prints the name of its logical
2451# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2452vif_to_ls() {
86e98048 2453 echo ${1%??}
e3393e3f
BP
2454}
2455
9975d7be
BP
2456net_add n1
2457for i in 1 2 3; do
2458 sim_add hv$i
2459 as hv$i
2460 ovs-vsctl add-br br-phys
2461 ovn_attach n1 br-phys 192.168.0.$i
2462done
2463for i in 1 2 3; do
2464 for j in 1 2 3; do
86e98048 2465 for k in 1 2 3; do
269ecccc
JP
2466 hv=`vif_to_hv $i$j$k`
2467 as hv$hv ovs-vsctl \
2468 -- add-port br-int vif$i$j$k \
2469 -- set Interface vif$i$j$k \
2470 external-ids:iface-id=lp$i$j$k \
2471 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2472 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2473 ofport-request=$i$j$k
86e98048 2474 done
9975d7be
BP
2475 done
2476done
2477
2478# Pre-populate the hypervisors' ARP tables so that we don't lose any
2479# packets for ARP resolution (native tunneling doesn't queue packets
2480# for ARP resolution).
74868f2c 2481OVN_POPULATE_ARP
9975d7be
BP
2482
2483# Allow some time for ovn-northd and ovn-controller to catch up.
2484# XXX This should be more systematic.
2485sleep 1
2486
e3393e3f 2487# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2488#
2489# This shell function causes a packet to be received on INPORT. The packet's
2490# content has Ethernet destination DST and source SRC (each exactly 12 hex
2491# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2492# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2493# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2494for i in 1 2 3; do
2495 for j in 1 2 3; do
86e98048
BP
2496 for k in 1 2 3; do
2497 : > $i$j$k.expected
269ecccc 2498 done
9975d7be
BP
2499 done
2500done
e3393e3f 2501test_ip() {
9975d7be
BP
2502 # This packet has bad checksums but logical L3 routing doesn't check.
2503 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2504 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2505 shift; shift; shift; shift; shift
2506 hv=hv`vif_to_hv $inport`
2507 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2508 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2509 in_ls=`vif_to_ls $inport`
2510 in_lrp=`vif_to_lrp $inport`
9975d7be 2511 for outport; do
269ecccc 2512 out_ls=`vif_to_ls $outport`
86e98048 2513 if test $in_ls = $out_ls; then
9975d7be
BP
2514 # Ports on the same logical switch receive exactly the same packet.
2515 echo $packet
2516 else
2517 # Routing decrements TTL and updates source and dest MAC
2518 # (and checksum).
269ecccc 2519 out_lrp=`vif_to_lrp $outport`
86e98048 2520 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2521 fi >> $outport.expected
9975d7be
BP
2522 done
2523}
2524
e3393e3f 2525as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2526as hv1 ovn-sbctl list port_binding
2527as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2528as hv1 ovn-sbctl dump-flows
2529as hv1 ovs-ofctl dump-flows br-int
2530
e3393e3f 2531# Send IP packets between all pairs of source and destination ports:
9975d7be 2532#
31ed1192
JP
2533# 1. Unicast IP packets are delivered to exactly one logical switch port
2534# (except that packets destined to their input ports are dropped).
9975d7be 2535#
31ed1192
JP
2536# 2. Broadcast IP packets are delivered to all logical switch ports
2537# except the input port.
86e98048
BP
2538ip_to_hex() {
2539 printf "%02x%02x%02x%02x" "$@"
2540}
9975d7be 2541for is in 1 2 3; do
269ecccc
JP
2542 for js in 1 2 3; do
2543 for ks in 1 2 3; do
2544 bcast=
2545 s=$is$js$ks
2546 smac=f00000000$s
2547 sip=`ip_to_hex 192 168 $is$js $ks`
2548 for id in 1 2 3; do
2549 for jd in 1 2 3; do
2550 for kd in 1 2 3; do
2551 d=$id$jd$kd
2552 dip=`ip_to_hex 192 168 $id$jd $kd`
2553 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2554 if test $d != $s; then unicast=$d; else unicast=; fi
2555
2556 test_ip $s $smac $dmac $sip $dip $unicast #1
2557
2558 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2559 done
2560 done
9975d7be 2561 done
269ecccc
JP
2562 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2563 done
2564 done
e3393e3f
BP
2565done
2566
0bac7164
BP
2567# 3. Send an IP packet from every logical port to every other subnet,
2568# to an IP address that does not have a static IP-MAC binding.
2569# This should generate a broadcast ARP request for the destination
2570# IP address in the destination subnet.
2571for is in 1 2 3; do
269ecccc
JP
2572 for js in 1 2 3; do
2573 for ks in 1 2 3; do
2574 s=$is$js$ks
2575 smac=f00000000$s
2576 sip=`ip_to_hex 192 168 $is$js $ks`
2577 for id in 1 2 3; do
2578 for jd in 1 2 3; do
2579 if test $is$js = $id$jd; then
2580 continue
2581 fi
2582
2583 # Send the packet.
2584 dmac=00000000ff$is$js
2585 # Calculate a 4th octet for the destination that is
2586 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2587 # that have static MAC bindings, and fits in the range
2588 # 0-255.
2589 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2590 dip=`ip_to_hex 192 168 $id$jd $o4`
2591 test_ip $s $smac $dmac $sip $dip
2592
2593 # Every LP on the destination subnet's lswitch should
2594 # receive the ARP request.
2595 lrmac=00000000ff$id$jd
2596 lrip=`ip_to_hex 192 168 $id$jd 254`
2597 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2598 for jd2 in 1 2 3; do
2599 for kd in 1 2 3; do
e4543cfe 2600 echo $arp >> $id$jd2$kd.expected
0bac7164 2601 done
269ecccc 2602 done
0bac7164 2603 done
269ecccc 2604 done
0bac7164 2605 done
269ecccc 2606 done
0bac7164
BP
2607done
2608
e3393e3f
BP
2609# test_arp INPORT SHA SPA TPA [REPLY_HA]
2610#
2611# Causes a packet to be received on INPORT. The packet is an ARP
2612# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2613# it should be the hardware address of the target to expect to receive in an
2614# ARP reply; otherwise no reply is expected.
2615#
31ed1192 2616# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2617# SHA and REPLY_HA are each 12 hex digits.
2618# SPA and TPA are each 8 hex digits.
2619test_arp() {
2620 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2621 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2622 hv=hv`vif_to_hv $inport`
2623 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2d9b49dd 2624 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
e3393e3f 2625
57d143eb 2626 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2627 # IP address is not configured to the switch patch port.
e3393e3f 2628 local i=`vif_to_ls $inport`
86e98048 2629 local j k
e3393e3f 2630 for j in 1 2 3; do
86e98048 2631 for k in 1 2 3; do
ea46a4e9 2632 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2633 # so no ARP flooding expected for it.
2634 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2635 echo $request >> $i$j$k.expected
2636 fi
2637 done
e3393e3f
BP
2638 done
2639
2640 # Expect to receive the reply, if any.
2641 if test X$reply_ha != X; then
86e98048
BP
2642 lrp=`vif_to_lrp $inport`
2643 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2644 echo $reply >> $inport.expected
2645 fi
2646}
2647
2648# Test router replies to ARP requests from all source ports:
2649#
0bac7164 2650# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2651#
0bac7164 2652# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2653# in its subnet.
2654#
0bac7164 2655# 6. Router replies to query for its MAC address from another subnet.
e3393e3f 2656#
0bac7164 2657# 7. No reply to query for IP address other than router IP.
e3393e3f 2658for i in 1 2 3; do
269ecccc
JP
2659 for j in 1 2 3; do
2660 for k in 1 2 3; do
2661 smac=f00000000$i$j$k # Source MAC
2662 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2663 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2664 rmac=00000000ff$i$j # Router MAC
2665 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
2666 test_arp $i$j$k $smac $sip $rip $rmac #4
2667 test_arp $i$j$k $smac $otherip $rip $rmac #5
2668 test_arp $i$j$k $smac 0a123456 $rip $rmac #6
2669 test_arp $i$j$k $smac $sip $otherip #7
0bac7164 2670 done
269ecccc 2671 done
0bac7164
BP
2672done
2673
2674# Allow some time for packet forwarding.
2675# XXX This can be improved.
2676sleep 1
2677
2678# 8. Generate an ARP reply for each of the IP addresses ARPed for
2679# earlier as #3.
2680#
2681# Here, the $s is the VIF that originated the ARP request and $d is
2682# the VIF that sends the ARP reply, which is somewhat backward but
2683# it means that $s and $d are the same as #3.
2684: > mac_bindings.expected
2685for is in 1 2 3; do
269ecccc
JP
2686 for js in 1 2 3; do
2687 for ks in 1 2 3; do
2688 s=$is$js$ks
2689 for id in 1 2 3; do
2690 for jd in 1 2 3; do
2691 if test $is$js = $id$jd; then
2692 continue
2693 fi
2694
2695 kd=1
2696 d=$id$jd$kd
2697
2698 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2699 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2700 host_mac=8000000000$o4
2701
2702 lrmac=00000000ff$id$jd
2703 lrip=`ip_to_hex 192 168 $id$jd 254`
2704
2705 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2706
2707 echo
2708 echo
2709 echo
2710 hv=hv`vif_to_hv $d`
2711 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2712 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2713 #as $hv ovs-ofctl dump-flows br-int table=19
2714
2715 host_ip_pretty=192.168.$id$jd.$o4
2716 host_mac_pretty=80:00:00:00:00:$o4
2717 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2718 done
269ecccc 2719 done
9975d7be 2720 done
269ecccc 2721 done
9975d7be 2722done
0bac7164 2723
9975d7be
BP
2724# Allow some time for packet forwarding.
2725# XXX This can be improved.
2726sleep 1
2727
0bac7164
BP
2728# 9. Send an IP packet from every logical port to every other subnet. These
2729# are the same packets already sent as #3, but now the destinations' IP-MAC
2730# bindings have been discovered via ARP, so instead of provoking an ARP
2731# request, these packets now get routed to their destinations (which don't
2732# have static MAC bindings, so they go to the port we've designated as
2733# accepting "unknown" MACs.)
2734for is in 1 2 3; do
269ecccc
JP
2735 for js in 1 2 3; do
2736 for ks in 1 2 3; do
2737 s=$is$js$ks
2738 smac=f00000000$s
2739 sip=`ip_to_hex 192 168 $is$js $ks`
2740 for id in 1 2 3; do
2741 for jd in 1 2 3; do
2742 if test $is$js = $id$jd; then
2743 continue
2744 fi
2745
2746 # Send the packet.
2747 dmac=00000000ff$is$js
2748 # Calculate a 4th octet for the destination that is
2749 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2750 # that have static MAC bindings, and fits in the range
2751 # 0-255.
2752 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2753 dip=`ip_to_hex 192 168 $id$jd $o4`
2754 test_ip $s $smac $dmac $sip $dip
2755
2756 # Expect the packet egress.
2757 host_mac=8000000000$o4
2758 outport=${id}11
2759 out_lrp=$id$jd
e4543cfe 2760 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2761 done
269ecccc 2762 done
0bac7164 2763 done
269ecccc 2764 done
0bac7164
BP
2765done
2766
0bac7164
BP
2767ovn-sbctl -f csv -d bare --no-heading \
2768 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2769
9975d7be
BP
2770# Now check the packets actually received against the ones expected.
2771for i in 1 2 3; do
2772 for j in 1 2 3; do
86e98048 2773 for k in 1 2 3; do
abb37b6b
FF
2774 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2775 [$i$j$k.expected])
86e98048 2776 done
9975d7be
BP
2777 done
2778done
fcde56f5 2779
0bac7164
BP
2780# Check the MAC bindings against those expected.
2781AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2782])
2783
fcde56f5 2784# Gracefully terminate daemons
7a8f15e0 2785OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2786
9975d7be 2787AT_CLEANUP
685f4dfe
NS
2788
2789# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
2790AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
2791AT_SKIP_IF([test $HAVE_PYTHON = no])
2792ovn_start
2793
2794# Create hypervisors hv[123].
2795# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
2796# Add all of the vifs to a single logical switch lsw0.
2797# Turn off port security on vifs vif[123]1
2798# Turn on l2 port security on vifs vif[123]2
2799# Turn of l2 and l3 port security on vifs vif[123]3
2800# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 2801ovn-nbctl ls-add lsw0
685f4dfe
NS
2802net_add n1
2803for i in 1 2 3; do
2804 sim_add hv$i
2805 as hv$i
2806 ovs-vsctl add-br br-phys
2807 ovn_attach n1 br-phys 192.168.0.$i
2808
2809 for j in 1 2 3; do
2810 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 2811 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 2812 if test $j = 1; then
31ed1192 2813 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 2814 elif test $j = 2; then
31ed1192
JP
2815 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
2816 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
2817 else
2818 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
2819 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
2820 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
2821 fi
2822 done
2823done
2824
685f4dfe
NS
2825# Pre-populate the hypervisors' ARP tables so that we don't lose any
2826# packets for ARP resolution (native tunneling doesn't queue packets
2827# for ARP resolution).
74868f2c 2828OVN_POPULATE_ARP
685f4dfe
NS
2829
2830# Allow some time for ovn-northd and ovn-controller to catch up.
2831# XXX This should be more systematic.
2832sleep 1
685f4dfe
NS
2833
2834# Given the name of a logical port, prints the name of the hypervisor
2835# on which it is located.
2836vif_to_hv() {
2837 echo hv${1%?}
2838}
2839
685f4dfe
NS
2840for i in 1 2 3; do
2841 for j in 1 2 3; do
2842 : > $i$j.expected
2843 done
2844done
2845
2846# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2847#
2848# This shell function causes an ip packet to be received on INPORT.
2849# The packet's content has Ethernet destination DST and source SRC
2850# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
2851# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
2852# be received. INPORT and the OUTPORTs are specified as logical switch
2853# port numbers, e.g. 11 for vif11.
685f4dfe
NS
2854test_ip() {
2855 # This packet has bad checksums but logical L3 routing doesn't check.
2856 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 2857 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
2858 shift; shift; shift; shift; shift
2859 hv=`vif_to_hv $inport`
2860 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2861 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2862 for outport; do
e4543cfe 2863 echo $packet >> $outport.expected
685f4dfe
NS
2864 done
2865}
2866
2867# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
2868#
2869# Causes a packet to be received on INPORT. The packet is an ARP
2870# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2871# it should be the hardware address of the target to expect to receive in an
2872# ARP reply; otherwise no reply is expected.
2873#
31ed1192 2874# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
2875# SHA and REPLY_HA are each 12 hex digits.
2876# SPA and TPA are each 8 hex digits.
2877test_arp() {
2878 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
2879 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2880 hv=`vif_to_hv $inport`
2881 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2882 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
2883 if test $drop != 1; then
e137131a 2884 if test X$reply_ha = X; then
685f4dfe
NS
2885 # Expect to receive the broadcast ARP on the other logical switch ports
2886 # if no reply is expected.
2887 local i j
2888 for i in 1 2 3; do
2889 for j in 1 2 3; do
2890 if test $i$j != $inport; then
2891 echo $request >> $i$j.expected
2892 fi
2893 done
2894 done
2895 else
2896 # Expect to receive the reply, if any.
2897 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2898 echo $reply >> $inport.expected
2899 fi
2900 fi
2901}
2902
2903# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2904# This function is similar to test_ip() except that it sends
2905# ipv6 packet
2906test_ipv6() {
2907 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2908 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
2909 shift; shift; shift; shift; shift
2910 hv=`vif_to_hv $inport`
2911 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2912 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2913 for outport; do
e4543cfe 2914 echo $packet >> $outport.expected
685f4dfe
NS
2915 done
2916}
2917
9e687b23
DL
2918# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
2919# This function is similar to test_ipv6() except it specifies the ICMPv6 type
2920# of the test packet
2921test_icmpv6() {
2922 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
2923 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
2924 shift; shift; shift; shift; shift; shift
2925 hv=`vif_to_hv $inport`
2926 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2927 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
2928 for outport; do
e4543cfe 2929 echo $packet >> $outport.expected
9e687b23
DL
2930 done
2931}
2932
685f4dfe
NS
2933ip_to_hex() {
2934 printf "%02x%02x%02x%02x" "$@"
2935}
2936
2937# no port security
2938sip=`ip_to_hex 192 168 0 12`
2939tip=`ip_to_hex 192 168 0 13`
2940# the arp packet should be allowed even if lp[123]1 is
2941# not configured with mac f00000000023 and ip 192.168.0.12
2942for i in 1 2 3; do
2943 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
2944 for j in 1 2 3; do
2945 if test $i != $j; then
2946 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
2947 fi
2948 done
2949done
2950
2951# l2 port security
2952sip=`ip_to_hex 192 168 0 12`
2953tip=`ip_to_hex 192 168 0 13`
2954
2955# arp packet should be allowed since lp22 is configured with
2956# mac f00000000022
2957test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
2958
2959# arp packet should not be allowed since lp32 is not configured with
2960# mac f00000000021
2961test_arp 32 f00000000021 f00000000021 $sip $tip 1
2962
2963# arp packet with sha set to f00000000021 should not be allowed
2964# for lp12
2965test_arp 12 f00000000012 f00000000021 $sip $tip 1
2966
2967# ip packets should be allowed and received since lp[123]2 do not
2968# have l3 port security
2969sip=`ip_to_hex 192 168 0 55`
2970tip=`ip_to_hex 192 168 0 66`
2971for i in 1 2 3; do
2972 for j in 1 2 3; do
2973 if test $i != $j; then
2974 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
2975 fi
2976 done
2977done
2978
2979# ipv6 packets should be received by lp[123]2
2980# lp[123]1 can send ipv6 traffic as there is no port security
2981sip=fe800000000000000000000000000000
2982tip=ff020000000000000000000000000000
2983
2984for i in 1 2 3; do
2985 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
2986done
2987
2988
2989# l2 and l3 port security
2990sip=`ip_to_hex 192 168 0 13`
2991tip=`ip_to_hex 192 168 0 22`
2992# arp packet should be allowed since lp13 is configured with
2993# f00000000013 and 192.168.0.13
2994test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
2995
2996# the arp packet should be dropped because lp23 is not configured
2997# with mac f00000000022
2998sip=`ip_to_hex 192 168 0 13`
2999tip=`ip_to_hex 192 168 0 22`
3000test_arp 23 f00000000022 f00000000022 $sip $tip 1
3001
3002# the arp packet should be dropped because lp33 is not configured
3003# with ip 192.168.0.55
3004spa=`ip_to_hex 192 168 0 55`
3005tpa=`ip_to_hex 192 168 0 22`
3006test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3007
3008# ip packets should not be received by lp[123]3 since
3009# l3 port security is enabled
3010sip=`ip_to_hex 192 168 0 55`
3011tip=`ip_to_hex 192 168 0 66`
3012for i in 1 2 3; do
3013 for j in 1 2 3; do
3014 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3015 done
3016done
3017
3018# ipv6 packets should be dropped for lp[123]3 since
3019# it is configured with only ipv4 address
3020sip=fe800000000000000000000000000000
3021tip=ff020000000000000000000000000000
3022
3023for i in 1 2 3; do
3024 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3025done
3026
3027# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3028# lp[123]1 can send ipv6 traffic as there is no port security
3029for i in 1 2 3; do
3030 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3031done
3032
3033# lp13 has extra port security with mac f0000000113 and ipv6 addr
3034# fe80::ea2a:eaff:fe28:0012
3035
3036# ipv4 packet should be dropped for lp13 with mac f0000000113
3037sip=`ip_to_hex 192 168 0 13`
3038tip=`ip_to_hex 192 168 0 23`
3039test_ip 13 f00000000113 f00000000023 $sip $tip
3040
6d53e8a9
BP
3041# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3042# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
3043# lp11 can send ipv6 traffic as there is no port security
3044sip=ee800000000000000000000000000000
3045for i in 1 2 3; do
6d53e8a9
BP
3046 tip=fe80000000000000ea2aeafffe2800${i}3
3047 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
3048done
3049
3050
3051# ipv6 packet should not be received by lp33 with mac f0000000333
3052# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3053# configured with fe80::ea2a:eaff:fe28:0033
3054# lp11 can send ipv6 traffic as there is no port security
3055
3056sip=ee800000000000000000000000000000
3057tip=fe80000000000000ea2aeafffe280023
3058test_ipv6 11 f00000000011 f00000000333 $sip $tip
3059
6d53e8a9
BP
3060# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3061# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
3062# and should be dropped for any other ip6.src
3063# lp21 can receive ipv6 traffic as there is no port security
3064
3065tip=ee800000000000000000000000000000
3066for i in 1 2 3; do
3067 sip=fe80000000000000ea2aeafffe2800${i}3
3068 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3069
9e687b23 3070 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 3071 sip=00000000000000000000000000000000
9e687b23
DL
3072 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3073 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3074 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3075 # Traffic to non-multicast traffic should be dropped
3076 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3077 # Traffic of other ICMPv6 types should be dropped
3078 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
3079
3080 # should be dropped
3081 sip=ae80000000000000ea2aeafffe2800aa
3082 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3083done
3084
31ed1192
JP
3085# configure lsp13 to send and received IPv4 packets with an address range
3086ovn-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 3087
8ff5a966
NS
3088sleep 2
3089
7d9d86ad
NS
3090sip=`ip_to_hex 10 0 0 13`
3091tip=`ip_to_hex 192 168 0 22`
31ed1192 3092# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
3093test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3094
3095sip=`ip_to_hex 10 0 0 14`
3096tip=`ip_to_hex 192 168 0 23`
31ed1192 3097# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
3098# with dst ip 192.168.0.23 should be allowed
3099test_ip 13 f00000000013 f00000000023 $sip $tip 23
3100
3101sip=`ip_to_hex 192 168 0 33`
3102tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
3103# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3104# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
3105test_ip 33 f00000000033 f00000000013 $sip $tip 13
3106
3107sip=`ip_to_hex 192 168 0 33`
3108tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
3109# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3110# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3111test_ip 33 f00000000033 f00000000013 $sip $tip 13
3112
3113sip=`ip_to_hex 192 168 0 33`
3114tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3115# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3116# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3117test_ip 33 f00000000033 f00000000013 $sip $tip
3118
3119sip=`ip_to_hex 192 168 0 33`
3120tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3121# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3122# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3123test_ip 33 f00000000033 f00000000013 $sip $tip 13
3124
3125sip=`ip_to_hex 192 168 0 33`
3126tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3127# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3128# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3129test_ip 33 f00000000033 f00000000013 $sip $tip
3130
3131sip=`ip_to_hex 192 168 0 33`
3132tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3133# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3134# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3135test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3136
bb0c41d3
RM
3137#dump information including flow counters
3138ovn-nbctl show
3139ovn-sbctl dump-flows -- list multicast_group
3140
3141echo "------ hv1 dump ------"
3142as hv1 ovs-vsctl show
6195e2e7 3143as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3144as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3145
3146echo "------ hv2 dump ------"
3147as hv2 ovs-vsctl show
6195e2e7 3148as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3149as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3150
3151echo "------ hv3 dump ------"
3152as hv3 ovs-vsctl show
6195e2e7 3153as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3154as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3155
685f4dfe
NS
3156# Now check the packets actually received against the ones expected.
3157for i in 1 2 3; do
3158 for j in 1 2 3; do
49d7c759 3159 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3160 done
3161done
3162
7a8f15e0 3163OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3164
685f4dfe 3165AT_CLEANUP
509afdc3
GS
3166
3167AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3168AT_SKIP_IF([test $HAVE_PYTHON = no])
3169ovn_start
3170
3171# Logical network:
3172# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3173# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3174# R2 has ls2 (172.16.1.0/24) connected to it.
3175
3c1ae70a
JP
3176ls1_lp1_mac="f0:00:00:01:02:03"
3177rp_ls1_mac="00:00:00:01:02:03"
3178rp_ls2_mac="00:00:00:01:02:04"
3179ls2_lp1_mac="f0:00:00:01:02:04"
3180
3181ls1_lp1_ip="192.168.1.2"
3182ls2_lp1_ip="172.16.1.2"
3183
fa2a27b2
JP
3184ovn-nbctl lr-add R1
3185ovn-nbctl lr-add R2
509afdc3 3186
ea46a4e9
JP
3187ovn-nbctl ls-add ls1
3188ovn-nbctl ls-add ls2
509afdc3
GS
3189
3190# Connect ls1 to R1
3c1ae70a 3191ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3192
31ed1192 3193ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3194 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3195
3196# Connect ls2 to R2
3c1ae70a 3197ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3198
31ed1192 3199ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3200 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3201
3202# Connect R1 to R2
4685e523
JP
3203ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3204ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3205
6d9ecfa9
JP
3206ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3207ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3208
3209# Create logical port ls1-lp1 in ls1
31ed1192 3210ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3211-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3212
3213# Create logical port ls2-lp1 in ls2
31ed1192 3214ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3215-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3216
3217# Create two hypervisor and create OVS ports corresponding to logical ports.
3218net_add n1
3219
3220sim_add hv1
3221as hv1
3222ovs-vsctl add-br br-phys
3223ovn_attach n1 br-phys 192.168.0.1
3224ovs-vsctl -- add-port br-int hv1-vif1 -- \
3225 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3226 options:tx_pcap=hv1/vif1-tx.pcap \
3227 options:rxq_pcap=hv1/vif1-rx.pcap \
3228 ofport-request=1
3229
3230sim_add hv2
3231as hv2
3232ovs-vsctl add-br br-phys
3233ovn_attach n1 br-phys 192.168.0.2
3234ovs-vsctl -- add-port br-int hv2-vif1 -- \
3235 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3236 options:tx_pcap=hv2/vif1-tx.pcap \
3237 options:rxq_pcap=hv2/vif1-rx.pcap \
3238 ofport-request=1
3239
3240
3241# Pre-populate the hypervisors' ARP tables so that we don't lose any
3242# packets for ARP resolution (native tunneling doesn't queue packets
3243# for ARP resolution).
74868f2c 3244OVN_POPULATE_ARP
509afdc3
GS
3245
3246# Allow some time for ovn-northd and ovn-controller to catch up.
3247# XXX This should be more systematic.
3248sleep 1
3249
509afdc3 3250# Packet to send.
3c1ae70a
JP
3251packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3252 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3253 udp && udp.src==53 && udp.dst==4369"
3254as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3255
3256
3257echo "---------NB dump-----"
3258ovn-nbctl show
3259echo "---------------------"
3260ovn-nbctl list logical_router
3261echo "---------------------"
3262ovn-nbctl list logical_router_port
3263echo "---------------------"
3264
3265echo "---------SB dump-----"
3266ovn-sbctl list datapath_binding
3267echo "---------------------"
3268ovn-sbctl list port_binding
3269echo "---------------------"
3270
3271echo "------ hv1 dump ----------"
8dab1022 3272as hv1 ovs-ofctl show br-int
509afdc3
GS
3273as hv1 ovs-ofctl dump-flows br-int
3274echo "------ hv2 dump ----------"
8dab1022 3275as hv2 ovs-ofctl show br-int
509afdc3
GS
3276as hv2 ovs-ofctl dump-flows br-int
3277
3278# Packet to Expect
3c1ae70a
JP
3279# The TTL should be decremented by 2.
3280packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3281 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3282 udp && udp.src==53 && udp.dst==4369"
3283echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3284
49d7c759 3285OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3286
7ebfcd3d
NS
3287AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3288grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3289])
3290
3291# Disable the ls2-lp1 port.
3292ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3293
3294AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3295grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3296])
3297
3298# Generate the packet destined for ls2-lp1 and it should not be delivered.
3299# Packet to send.
3300packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3301 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3302 udp && udp.src==53 && udp.dst==4369"
3303
3304as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3305# The 2nd packet sent shound not be received.
3306OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3307
7a8f15e0 3308OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3309
3310AT_CLEANUP
5412db30
J
3311
3312
4685e523
JP
3313AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3314AT_KEYWORDS([router-admin-state])
3315AT_SKIP_IF([test $HAVE_PYTHON = no])
3316ovn_start
3317
3318# Logical network:
3319# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3320# and 172.16.1.0/24) connected to it.
3321
3322ovn-nbctl lr-add R1
3323
3324ovn-nbctl ls-add ls1
3325
3326# Connect ls1 to R1
bf44c2cd 3327ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3328ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3329 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3330
3331# Create logical port ls1-lp1 in ls1
3332ovn-nbctl lsp-add ls1 ls1-lp1 \
3333 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3334
3335# Create logical port ls1-lp2 in ls1
3336ovn-nbctl lsp-add ls1 ls1-lp2 \
3337 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3338
3339# Create one hypervisor and create OVS ports corresponding to logical ports.
3340net_add n1
3341
3342sim_add hv1
3343as hv1
3344ovs-vsctl add-br br-phys
3345ovn_attach n1 br-phys 192.168.0.1
3346ovs-vsctl -- add-port br-int vif1 -- \
3347 set interface vif1 external-ids:iface-id=ls1-lp1 \
3348 options:tx_pcap=hv1/vif1-tx.pcap \
3349 options:rxq_pcap=hv1/vif1-rx.pcap \
3350 ofport-request=1
3351
3352ovs-vsctl -- add-port br-int vif2 -- \
3353 set interface vif2 external-ids:iface-id=ls1-lp2 \
3354 options:tx_pcap=hv1/vif2-tx.pcap \
3355 options:rxq_pcap=hv1/vif2-rx.pcap \
3356 ofport-request=1
3357
3358
3359# Allow some time for ovn-northd and ovn-controller to catch up.
3360# XXX This should be more systematic.
3361sleep 1
3362
3363# Send ip packets between the two ports.
3364ip_to_hex() {
3365 printf "%02x%02x%02x%02x" "$@"
3366}
4685e523
JP
3367
3368# Packet to send.
3369src_mac="f00000010203"
3370dst_mac="000000010203"
3371src_ip=`ip_to_hex 192 168 1 2`
3372dst_ip=`ip_to_hex 172 16 1 2`
3373packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3374as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3375
3376
3377echo "---------NB dump-----"
3378ovn-nbctl show
3379echo "---------------------"
3380ovn-nbctl list logical_router
3381echo "---------------------"
3382ovn-nbctl list logical_router_port
3383echo "---------------------"
3384
3385echo "---------SB dump-----"
3386ovn-sbctl list datapath_binding
3387echo "---------------------"
3388ovn-sbctl list logical_flow
3389echo "---------------------"
3390
3391echo "------ hv1 dump ----------"
3392as hv1 ovs-ofctl dump-flows br-int
3393
3394
3395#Disable router R1
3396ovn-nbctl set Logical_Router R1 enabled=false
3397
3b8cd0ea
BP
3398# Allow some time for ovn-northd and ovn-controller to catch up.
3399# XXX This should be more systematic.
3400sleep 1
3401
4685e523
JP
3402echo "---------SB dump-----"
3403ovn-sbctl list datapath_binding
3404echo "---------------------"
3405ovn-sbctl list logical_flow
3406echo "---------------------"
3407
3408echo "------ hv1 dump ----------"
3409as hv1 ovs-ofctl dump-flows br-int
3410
3411as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3412
3413# Packet to Expect
3414expect_src_mac="000000010203"
3415expect_dst_mac="f00000010204"
49d7c759 3416echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3417
49d7c759 3418OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3419
3420
3421as hv1
3422OVS_APP_EXIT_AND_WAIT([ovn-controller])
3423OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3424OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3425
3426as ovn-sb
3427OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3428
3429as ovn-nb
3430OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3431
3432as northd
3433OVS_APP_EXIT_AND_WAIT([ovn-northd])
3434
3435as main
3436OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3437OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3438
3439AT_CLEANUP
3440
3441
3442AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3443AT_KEYWORDS([router-admin-state])
3444AT_SKIP_IF([test $HAVE_PYTHON = no])
3445ovn_start
3446
3447# Logical network:
3448# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3449# and has switch ls2 (172.16.1.0/24) connected to it.
3450
fa2a27b2 3451ovn-nbctl lr-add R1
5412db30 3452
ea46a4e9
JP
3453ovn-nbctl ls-add ls1
3454ovn-nbctl ls-add ls2
5412db30
J
3455
3456# Connect ls1 to R1
bf44c2cd 3457ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3458ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3459 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3460
3461# Connect ls2 to R1
bf44c2cd 3462ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3463ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3464 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3465
3466# Create logical port ls1-lp1 in ls1
31ed1192
JP
3467ovn-nbctl lsp-add ls1 ls1-lp1 \
3468-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3469
3470# Create logical port ls2-lp1 in ls2
31ed1192
JP
3471ovn-nbctl lsp-add ls2 ls2-lp1 \
3472-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3473
3474# Create one hypervisor and create OVS ports corresponding to logical ports.
3475net_add n1
3476
3477sim_add hv1
3478as hv1
3479ovs-vsctl add-br br-phys
3480ovn_attach n1 br-phys 192.168.0.1
3481ovs-vsctl -- add-port br-int vif1 -- \
3482 set interface vif1 external-ids:iface-id=ls1-lp1 \
3483 options:tx_pcap=hv1/vif1-tx.pcap \
3484 options:rxq_pcap=hv1/vif1-rx.pcap \
3485 ofport-request=1
3486
3487ovs-vsctl -- add-port br-int vif2 -- \
3488 set interface vif2 external-ids:iface-id=ls2-lp1 \
3489 options:tx_pcap=hv1/vif2-tx.pcap \
3490 options:rxq_pcap=hv1/vif2-rx.pcap \
3491 ofport-request=1
3492
3493
3494# Allow some time for ovn-northd and ovn-controller to catch up.
3495# XXX This should be more systematic.
3496sleep 1
3497
3498# Send ip packets between the two ports.
3499ip_to_hex() {
3500 printf "%02x%02x%02x%02x" "$@"
3501}
5412db30
J
3502
3503# Packet to send.
3504src_mac="f00000010203"
3505dst_mac="000000010203"
3506src_ip=`ip_to_hex 192 168 1 2`
3507dst_ip=`ip_to_hex 172 16 1 2`
3508packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3509as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3510
3511
3512echo "---------NB dump-----"
3513ovn-nbctl show
3514echo "---------------------"
3515ovn-nbctl list logical_router
3516echo "---------------------"
3517ovn-nbctl list logical_router_port
3518echo "---------------------"
3519
3520echo "---------SB dump-----"
3521ovn-sbctl list datapath_binding
3522echo "---------------------"
3523ovn-sbctl list logical_flow
3524echo "---------------------"
3525
3526echo "------ hv1 dump ----------"
3527as hv1 ovs-ofctl dump-flows br-int
3528
5412db30
J
3529#Disable router R1
3530ovn-nbctl set Logical_Router R1 enabled=false
3531
3532echo "---------SB dump-----"
3533ovn-sbctl list datapath_binding
3534echo "---------------------"
3535ovn-sbctl list logical_flow
3536echo "---------------------"
3537
3538echo "------ hv1 dump ----------"
3539as hv1 ovs-ofctl dump-flows br-int
3540
a1361a6e
LR
3541# Allow some time for the disabling of logical router R1 to propagate.
3542# XXX This should be more systematic.
3543sleep 1
3544
5412db30
J
3545as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3546
3547# Packet to Expect
3548expect_src_mac="000000010204"
3549expect_dst_mac="f00000010204"
49d7c759 3550echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3551
49d7c759 3552OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3553
7a8f15e0 3554OVN_CLEANUP([hv1])
5412db30
J
3555
3556AT_CLEANUP
3557
28dc3fe9 3558AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3559AT_SKIP_IF([test $HAVE_PYTHON = no])
3560ovn_start
3561
3562# Logical network:
3563# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3564# network. R1 has switchess foo (192.168.1.0/24)
3565# connected to it.
3566# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3567
fa2a27b2
JP
3568ovn-nbctl lr-add R1
3569ovn-nbctl lr-add R2
28dc3fe9 3570
ea46a4e9
JP
3571ovn-nbctl ls-add foo
3572ovn-nbctl ls-add alice
3573ovn-nbctl ls-add bob
28dc3fe9
SR
3574
3575# Connect foo to R1
bf44c2cd 3576ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3577ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3578 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3579
3580# Connect alice to R2
bf44c2cd 3581ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3582ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3583 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3584
3585# Connect bob to R2
bf44c2cd 3586ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3587ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3588 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3589
3590# Connect R1 to R2
4685e523
JP
3591ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3592ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3593
3594#install static routes
e48ccf3c
JP
3595ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3596ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3597ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3598
3599# Create logical port foo1 in foo
31ed1192
JP
3600ovn-nbctl lsp-add foo foo1 \
3601-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3602
3603# Create logical port alice1 in alice
31ed1192
JP
3604ovn-nbctl lsp-add alice alice1 \
3605-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3606
3607# Create logical port bob1 in bob
31ed1192
JP
3608ovn-nbctl lsp-add bob bob1 \
3609-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3610
3611# Create two hypervisor and create OVS ports corresponding to logical ports.
3612net_add n1
3613
3614sim_add hv1
3615as hv1
3616ovs-vsctl add-br br-phys
3617ovn_attach n1 br-phys 192.168.0.1
3618ovs-vsctl -- add-port br-int hv1-vif1 -- \
3619 set interface hv1-vif1 external-ids:iface-id=foo1 \
3620 options:tx_pcap=hv1/vif1-tx.pcap \
3621 options:rxq_pcap=hv1/vif1-rx.pcap \
3622 ofport-request=1
3623
3624ovs-vsctl -- add-port br-int hv1-vif2 -- \
3625 set interface hv1-vif2 external-ids:iface-id=alice1 \
3626 options:tx_pcap=hv1/vif2-tx.pcap \
3627 options:rxq_pcap=hv1/vif2-rx.pcap \
3628 ofport-request=2
3629
3630sim_add hv2
3631as hv2
3632ovs-vsctl add-br br-phys
3633ovn_attach n1 br-phys 192.168.0.2
3634ovs-vsctl -- add-port br-int hv2-vif1 -- \
3635 set interface hv2-vif1 external-ids:iface-id=bob1 \
3636 options:tx_pcap=hv2/vif1-tx.pcap \
3637 options:rxq_pcap=hv2/vif1-rx.pcap \
3638 ofport-request=1
3639
3640
3641# Pre-populate the hypervisors' ARP tables so that we don't lose any
3642# packets for ARP resolution (native tunneling doesn't queue packets
3643# for ARP resolution).
74868f2c 3644OVN_POPULATE_ARP
28dc3fe9
SR
3645
3646# Allow some time for ovn-northd and ovn-controller to catch up.
3647# XXX This should be more systematic.
3648sleep 1
3649
3650ip_to_hex() {
3651 printf "%02x%02x%02x%02x" "$@"
3652}
28dc3fe9
SR
3653
3654# Send ip packets between foo1 and alice1
3655src_mac="f00000010203"
3656dst_mac="000000010203"
3657src_ip=`ip_to_hex 192 168 1 2`
3658dst_ip=`ip_to_hex 172 16 1 2`
3659packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3660as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3661
3662# Send ip packets between foo1 and bob1
3663src_mac="f00000010203"
3664dst_mac="000000010203"
3665src_ip=`ip_to_hex 192 168 1 2`
3666dst_ip=`ip_to_hex 172 16 2 2`
3667packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3668as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3669
3670echo "---------NB dump-----"
3671ovn-nbctl show
3672echo "---------------------"
3673ovn-nbctl list logical_router
3674echo "---------------------"
3675ovn-nbctl list logical_router_port
3676echo "---------------------"
3677
3678echo "---------SB dump-----"
3679ovn-sbctl list datapath_binding
3680echo "---------------------"
3681ovn-sbctl list port_binding
3682echo "---------------------"
3683
3684echo "------ hv1 dump ----------"
3685as hv1 ovs-ofctl dump-flows br-int
3686echo "------ hv2 dump ----------"
3687as hv2 ovs-ofctl dump-flows br-int
3688
3689# Packet to Expect at bob1
3690src_mac="000000010205"
3691dst_mac="f00000010205"
3692src_ip=`ip_to_hex 192 168 1 2`
3693dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3694echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3695
49d7c759 3696OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3697
3698# Packet to Expect at alice1
3699src_mac="000000010204"
3700dst_mac="f00000010204"
3701src_ip=`ip_to_hex 192 168 1 2`
3702dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3703echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3704
49d7c759 3705OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3706
7a8f15e0 3707OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3708
3709AT_CLEANUP
5412db30 3710
0ee8aaf6 3711AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3712AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3713ovn_start
ea46a4e9 3714ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3715net_add n1
3716sim_add hv
3717as hv
3718ovs-vsctl \
3719 -- add-br br-phys \
3720 -- add-br br-eth0
3721
3722ovn_attach n1 br-phys 192.168.0.1
3723
3724AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3725AT_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])
3726
3727# Create a vif.
31ed1192
JP
3728AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3729AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3730AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3731
3732# Create a localnet port.
31ed1192
JP
3733AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3734AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3735AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3736AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3737
3738AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3739
3740# Wait for packet to be received.
49d7c759
BP
3741echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3742OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 3743
5b57e12a
GL
3744# Check GARP packet when restart openflow connection.
3745as hv
3746OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3747
3748OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3749
3750as hv
3751start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3752
3753# Wait for packet to be received.
3754echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3755OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
3756
0ee8aaf6
RR
3757# Delete the localnet ports.
3758AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 3759AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 3760
7a8f15e0 3761OVN_CLEANUP([hv])
0ee8aaf6
RR
3762
3763AT_CLEANUP
75cf9d2b
GS
3764
3765AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
3766AT_SKIP_IF([test $HAVE_PYTHON = no])
3767ovn_start
3768
3769# Logical network:
3770# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
3771# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
3772# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
3773# connected to it.
3774
fa2a27b2
JP
3775ovn-nbctl lr-add R1
3776ovn-nbctl lr-add R2
3777ovn-nbctl lr-add R3
75cf9d2b 3778
ea46a4e9
JP
3779ovn-nbctl ls-add foo
3780ovn-nbctl ls-add alice
3781ovn-nbctl ls-add bob
3782ovn-nbctl ls-add join
75cf9d2b
GS
3783
3784# Connect foo to R1
31114af7 3785ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 3786ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3787 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
3788
3789# Connect alice to R2
31114af7 3790ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 3791ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3792 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
3793
3794# Connect bob to R3
31114af7 3795ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 3796ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 3797 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
3798
3799# Connect R1 to join
31114af7 3800ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 3801ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 3802 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
3803
3804# Connect R2 to join
31114af7 3805ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 3806ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 3807 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
3808
3809# Connect R3 to join
31114af7 3810ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 3811ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 3812 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
3813
3814#install static routes
e48ccf3c
JP
3815ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3816ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 3817
e48ccf3c
JP
3818ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
3819ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 3820
e48ccf3c
JP
3821ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
3822ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
3823
3824# Create logical port foo1 in foo
31ed1192
JP
3825ovn-nbctl lsp-add foo foo1 \
3826-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
3827
3828# Create logical port alice1 in alice
31ed1192
JP
3829ovn-nbctl lsp-add alice alice1 \
3830-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
3831
3832# Create logical port bob1 in bob
31ed1192
JP
3833ovn-nbctl lsp-add bob bob1 \
3834-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
3835
3836# Create two hypervisor and create OVS ports corresponding to logical ports.
3837net_add n1
3838
3839sim_add hv1
3840as hv1
3841ovs-vsctl add-br br-phys
3842ovn_attach n1 br-phys 192.168.0.1
3843ovs-vsctl -- add-port br-int hv1-vif1 -- \
3844 set interface hv1-vif1 external-ids:iface-id=foo1 \
3845 options:tx_pcap=hv1/vif1-tx.pcap \
3846 options:rxq_pcap=hv1/vif1-rx.pcap \
3847 ofport-request=1
3848
3849ovs-vsctl -- add-port br-int hv1-vif2 -- \
3850 set interface hv1-vif2 external-ids:iface-id=alice1 \
3851 options:tx_pcap=hv1/vif2-tx.pcap \
3852 options:rxq_pcap=hv1/vif2-rx.pcap \
3853 ofport-request=2
3854
3855sim_add hv2
3856as hv2
3857ovs-vsctl add-br br-phys
3858ovn_attach n1 br-phys 192.168.0.2
3859ovs-vsctl -- add-port br-int hv2-vif1 -- \
3860 set interface hv2-vif1 external-ids:iface-id=bob1 \
3861 options:tx_pcap=hv2/vif1-tx.pcap \
3862 options:rxq_pcap=hv2/vif1-rx.pcap \
3863 ofport-request=1
3864
3865
3866# Pre-populate the hypervisors' ARP tables so that we don't lose any
3867# packets for ARP resolution (native tunneling doesn't queue packets
3868# for ARP resolution).
74868f2c 3869OVN_POPULATE_ARP
75cf9d2b
GS
3870
3871# Allow some time for ovn-northd and ovn-controller to catch up.
3872# XXX This should be more systematic.
3873sleep 1
3874
3875ip_to_hex() {
3876 printf "%02x%02x%02x%02x" "$@"
3877}
75cf9d2b
GS
3878
3879# Send ip packets between foo1 and alice1
3880src_mac="f00000010203"
3881dst_mac="000001010203"
3882src_ip=`ip_to_hex 192 168 1 2`
3883dst_ip=`ip_to_hex 172 16 1 2`
3884packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3885as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3886as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
3887
3888# Send ip packets between foo1 and bob1
3889src_mac="f00000010203"
3890dst_mac="000001010203"
3891src_ip=`ip_to_hex 192 168 1 2`
3892dst_ip=`ip_to_hex 10 32 1 2`
3893packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3894as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3895
3896echo "---------NB dump-----"
3897ovn-nbctl show
3898echo "---------------------"
3899ovn-nbctl list logical_router
3900echo "---------------------"
3901ovn-nbctl list logical_router_port
3902echo "---------------------"
3903
3904echo "---------SB dump-----"
3905ovn-sbctl list datapath_binding
3906echo "---------------------"
3907ovn-sbctl list port_binding
3908echo "---------------------"
3909ovn-sbctl dump-flows
3910echo "---------------------"
3911
3912echo "------ hv1 dump ----------"
3913as hv1 ovs-ofctl show br-int
3914as hv1 ovs-ofctl dump-flows br-int
3915echo "------ hv2 dump ----------"
3916as hv2 ovs-ofctl show br-int
3917as hv2 ovs-ofctl dump-flows br-int
3918echo "----------------------------"
3919
3920# Packet to Expect at bob1
3921src_mac="000003010203"
3922dst_mac="f00000010205"
3923src_ip=`ip_to_hex 192 168 1 2`
3924dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 3925echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3926
49d7c759 3927OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
3928
3929# Packet to Expect at alice1
3930src_mac="000002010203"
3931dst_mac="f00000010204"
3932src_ip=`ip_to_hex 192 168 1 2`
3933dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3934echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 3935
49d7c759 3936OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 3937
7a8f15e0 3938OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
3939
3940AT_CLEANUP
c1645003 3941
281977f7 3942AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
3943AT_SKIP_IF([test $HAVE_PYTHON = no])
3944ovn_start
3945
3946ovn-nbctl ls-add ls1
3947
3948ovn-nbctl lsp-add ls1 ls1-lp1 \
3949-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3950
3951ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
3952
3953ovn-nbctl lsp-add ls1 ls1-lp2 \
3954-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3955
3956ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
3957
3958ovn-nbctl ls-add ls2
3959ovn-nbctl lsp-add ls2 ls2-lp1 \
3960-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3961ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
3962ovn-nbctl lsp-add ls2 ls2-lp2 \
3963-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3964ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
3965
9060fc9a 3966d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 3967options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 3968\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 3969
9060fc9a
MM
3970ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
3971ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
3972
3973d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 3974options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
3975\"lease_time\"=\"3600\"")"
3976
3977ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
3978
3979net_add n1
3980sim_add hv1
3981
3982as hv1
3983ovs-vsctl add-br br-phys
3984ovn_attach n1 br-phys 192.168.0.1
3985ovs-vsctl -- add-port br-int hv1-vif1 -- \
3986 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3987 options:tx_pcap=hv1/vif1-tx.pcap \
3988 options:rxq_pcap=hv1/vif1-rx.pcap \
3989 ofport-request=1
3990
3991ovs-vsctl -- add-port br-int hv1-vif2 -- \
3992 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
3993 options:tx_pcap=hv1/vif2-tx.pcap \
3994 options:rxq_pcap=hv1/vif2-rx.pcap \
3995 ofport-request=2
3996
3997ovs-vsctl -- add-port br-int hv1-vif3 -- \
3998 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
3999 options:tx_pcap=hv1/vif3-tx.pcap \
4000 options:rxq_pcap=hv1/vif3-rx.pcap \
4001 ofport-request=3
4002
4003ovs-vsctl -- add-port br-int hv1-vif4 -- \
4004 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4005 options:tx_pcap=hv1/vif4-tx.pcap \
4006 options:rxq_pcap=hv1/vif4-rx.pcap \
4007 ofport-request=4
4008
74868f2c 4009OVN_POPULATE_ARP
281977f7
NS
4010
4011sleep 2
4012
4013as hv1 ovs-vsctl show
4014
281977f7
NS
4015# This shell function sends a DHCP request packet
4016# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4017test_dhcp() {
213615b3
NS
4018 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4019 shift; shift; shift; shift; shift;
4020 if test $use_ip != 0; then
4021 src_ip=$1
4022 dst_ip=$2
4023 shift; shift;
4024 else
4025 src_ip=`ip_to_hex 0 0 0 0`
4026 dst_ip=`ip_to_hex 255 255 255 255`
4027 fi
4028 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 4029 # udp header and dhcp header
ab187e7e
BP
4030 request=${request}0044004300fc0000
4031 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 4032 # client hardware padding
ab187e7e 4033 request=${request}00000000000000000000
281977f7 4034 # server hostname
ab187e7e
BP
4035 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4036 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4037 # boot file name
ab187e7e
BP
4038 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4039 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4040 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4041 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4042 # dhcp magic cookie
ab187e7e 4043 request=${request}63825363
281977f7 4044 # dhcp message type
ab187e7e 4045 request=${request}3501${dhcp_type}ff
281977f7
NS
4046
4047 if test $offer_ip != 0; then
213615b3 4048 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
4049 # total IP length will be the IP length of the request packet
4050 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4051 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4052 udp_len=`expr $ip_len - 20`
04d60f6e
YT
4053 ip_len=$(printf "%x" $ip_len)
4054 udp_len=$(printf "%x" $udp_len)
281977f7
NS
4055 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4056 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4057 # udp header and dhcp header.
4058 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 4059 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 4060 # your ip address
ab187e7e 4061 reply=${reply}${offer_ip}
281977f7 4062 # next server ip address, relay agent ip address, client mac address
ab187e7e 4063 reply=${reply}0000000000000000${src_mac}
281977f7 4064 # client hardware padding
ab187e7e 4065 reply=${reply}00000000000000000000
281977f7 4066 # server hostname
ab187e7e
BP
4067 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4068 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4069 # boot file name
ab187e7e
BP
4070 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4071 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4072 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4073 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4074 # dhcp magic cookie
ab187e7e 4075 reply=${reply}63825363
281977f7
NS
4076 # dhcp message type
4077 local dhcp_reply_type=02
4078 if test $dhcp_type = 03; then
4079 dhcp_reply_type=05
4080 fi
ab187e7e 4081 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
4082 echo $reply >> $inport.expected
4083 else
281977f7 4084 for outport; do
e4543cfe 4085 echo $request >> $outport.expected
281977f7
NS
4086 done
4087 fi
4088 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4089}
4090
4091reset_pcap_file() {
4092 local iface=$1
4093 local pcap_file=$2
4094 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4095options:rxq_pcap=dummy-rx.pcap
4096 rm -f ${pcap_file}*.pcap
4097 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4098options:rxq_pcap=${pcap_file}-rx.pcap
4099}
4100
4101ip_to_hex() {
4102 printf "%02x%02x%02x%02x" "$@"
4103}
4104
4105AT_CAPTURE_FILE([ofctl_monitor0.log])
4106as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4107--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4108
4109echo "---------NB dump-----"
4110ovn-nbctl show
4111echo "---------------------"
4112echo "---------SB dump-----"
4113ovn-sbctl list datapath_binding
4114echo "---------------------"
4115ovn-sbctl list logical_flow
4116echo "---------------------"
4117
4118echo "---------------------"
4119ovn-sbctl dump-flows
4120echo "---------------------"
4121
4122echo "------ hv1 dump ----------"
4123as hv1 ovs-ofctl dump-flows br-int
4124
4125# Send DHCPDISCOVER.
4126offer_ip=`ip_to_hex 10 0 0 4`
4127server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4128expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4129test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4130
4131# NXT_RESUMEs should be 1.
4132OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4133
4134$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4135cat 1.expected | cut -c -48 > expout
4136AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4137# Skipping the IPv4 checksum.
4138cat 1.expected | cut -c 53- > expout
4139AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4140
4141# ovs-ofctl also resumes the packets and this causes other ports to receive
4142# the DHCP request packet. So reset the pcap files so that its easier to test.
4143reset_pcap_file hv1-vif1 hv1/vif1
4144reset_pcap_file hv1-vif2 hv1/vif2
4145rm -f 1.expected
4146rm -f 2.expected
4147
4148# Send DHCPREQUEST.
4149offer_ip=`ip_to_hex 10 0 0 6`
4150server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4151expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4152test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4153
4154# NXT_RESUMEs should be 2.
4155OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4156
4157$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4158cat 2.expected | cut -c -48 > expout
4159AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4160# Skipping the IPv4 checksum.
4161cat 2.expected | cut -c 53- > expout
4162AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4163
4164reset_pcap_file hv1-vif1 hv1/vif1
4165reset_pcap_file hv1-vif2 hv1/vif2
4166rm -f 1.expected
4167rm -f 2.expected
4168
4169# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4170# but should be resumed without the reply.
4171# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4172# one from ovn-controller and the other from "ovs-ofctl resume."
4173offer_ip=0
213615b3 4174test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
4175
4176# NXT_RESUMEs should be 3.
4177OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4178
4179# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4180OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4181
4182reset_pcap_file hv1-vif1 hv1/vif1
4183reset_pcap_file hv1-vif2 hv1/vif2
4184rm -f 1.expected
4185rm -f 2.expected
4186
4187# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4188# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4189
213615b3 4190test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
4191
4192# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4193# this lport.
213615b3 4194test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
4195
4196# NXT_RESUMEs should be 3.
4197OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4198
49d7c759
BP
4199OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4200OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4201
213615b3
NS
4202# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4203offer_ip=`ip_to_hex 10 0 0 6`
4204server_ip=`ip_to_hex 10 0 0 1`
4205expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4206src_ip=$offer_ip
4207dst_ip=$server_ip
4208test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4209
4210# NXT_RESUMEs should be 4.
4211OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4212
4213$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4214cat 2.expected | cut -c -48 > expout
4215AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4216# Skipping the IPv4 checksum.
4217cat 2.expected | cut -c 53- > expout
4218AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4219
4220reset_pcap_file hv1-vif1 hv1/vif1
4221reset_pcap_file hv1-vif2 hv1/vif2
4222rm -f 1.expected
4223rm -f 2.expected
4224
4225# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4226offer_ip=`ip_to_hex 10 0 0 6`
4227server_ip=`ip_to_hex 10 0 0 1`
4228expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4229src_ip=$offer_ip
4230dst_ip=`ip_to_hex 255 255 255 255`
4231test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4232
4233# NXT_RESUMEs should be 5.
4234OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4235
4236$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4237cat 2.expected | cut -c -48 > expout
4238AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4239# Skipping the IPv4 checksum.
4240cat 2.expected | cut -c 53- > expout
4241AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4242
4243reset_pcap_file hv1-vif1 hv1/vif1
4244reset_pcap_file hv1-vif2 hv1/vif2
4245rm -f 1.expected
4246rm -f 2.expected
4247
4248# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4249# The packet should not be received by ovn-controller.
4250src_ip=`ip_to_hex 10 0 0 6`
4251dst_ip=`ip_to_hex 10 0 0 4`
4252test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4253
4254# NXT_RESUMEs should be 5.
4255OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4256
4257# vif1-tx.pcap should have received the DHCPv4 request packet
4258OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4259
281977f7 4260as hv1
33ac3c83
NS
4261OVS_APP_EXIT_AND_WAIT([ovn-controller])
4262OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4263OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4264
4265as ovn-sb
4266OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4267
4268as ovn-nb
4269OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4270
4271as northd
4272OVS_APP_EXIT_AND_WAIT([ovn-northd])
4273
4274as main
4275OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4276OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4277
4278AT_CLEANUP
4279
40df4566 4280AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4281AT_SKIP_IF([test $HAVE_PYTHON = no])
4282ovn_start
4283
4284ovn-nbctl ls-add ls1
4285ovn-nbctl lsp-add ls1 ls1-lp1 \
4286-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4287
4288ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4289
4290ovn-nbctl lsp-add ls1 ls1-lp2 \
4291-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4292
4293ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4294
40df4566
ZKL
4295ovn-nbctl lsp-add ls1 ls1-lp3 \
4296-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4297
4298ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4299
9060fc9a
MM
4300d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4301options="\"server_id\"=\"00:00:00:10:00:01\"")"
4302
4303ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4304ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4305
4306d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4307options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4308
9060fc9a 4309ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4310
33ac3c83
NS
4311ovn-nbctl ls-add ls2
4312ovn-nbctl lsp-add ls2 ls2-lp1 \
4313-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4314ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4315ovn-nbctl lsp-add ls2 ls2-lp2 \
4316-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4317ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4318
4319net_add n1
4320sim_add hv1
4321
4322as hv1
4323ovs-vsctl add-br br-phys
4324ovn_attach n1 br-phys 192.168.0.1
4325ovs-vsctl -- add-port br-int hv1-vif1 -- \
4326 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4327 options:tx_pcap=hv1/vif1-tx.pcap \
4328 options:rxq_pcap=hv1/vif1-rx.pcap \
4329 ofport-request=1
4330
4331ovs-vsctl -- add-port br-int hv1-vif2 -- \
4332 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4333 options:tx_pcap=hv1/vif2-tx.pcap \
4334 options:rxq_pcap=hv1/vif2-rx.pcap \
4335 ofport-request=2
4336
4337ovs-vsctl -- add-port br-int hv1-vif3 -- \
4338 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4339 options:tx_pcap=hv1/vif3-tx.pcap \
4340 options:rxq_pcap=hv1/vif3-rx.pcap \
4341 ofport-request=3
4342
4343ovs-vsctl -- add-port br-int hv1-vif4 -- \
4344 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4345 options:tx_pcap=hv1/vif4-tx.pcap \
4346 options:rxq_pcap=hv1/vif4-rx.pcap \
4347 ofport-request=4
4348
40df4566
ZKL
4349ovs-vsctl -- add-port br-int hv1-vif5 -- \
4350 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4351 options:tx_pcap=hv1/vif5-tx.pcap \
4352 options:rxq_pcap=hv1/vif5-rx.pcap \
4353 ofport-request=5
4354
74868f2c 4355OVN_POPULATE_ARP
33ac3c83
NS
4356
4357sleep 2
4358
4359trim_zeros() {
4360 sed 's/\(00\)\{1,\}$//'
4361}
4362
4363# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4364# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4365# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4366# packet should be received twice (one from ovn-controller and the other
4367# from the "ovs-ofctl monitor br-int resume"
4368test_dhcpv6() {
4369 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4370 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4371 # dst ip ff02::1:2
ab187e7e 4372 request=${request}ff020000000000000000000000010002
33ac3c83 4373 # udp header and dhcpv6 header
ab187e7e 4374 request=${request}02220223002affff${msg_code}010203
33ac3c83 4375 # Client identifier
ab187e7e 4376 request=${request}0001000a00030001${src_mac}
33ac3c83 4377 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4378 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4379 shift; shift; shift; shift; shift;
4380 if test $offer_ip != 0; then
4381 local server_mac=000000100001
4382 local server_lla=fe80000000000000020000fffe100001
4383 local reply_code=07
4384 if test $msg_code = 01; then
4385 reply_code=02
4386 fi
40df4566
ZKL
4387 local msg_len=54
4388 if test $offer_ip = 1; then
4389 msg_len=28
4390 fi
4391 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4392 # udp header and dhcpv6 header
ab187e7e 4393 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4394 # Client identifier
ab187e7e 4395 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4396 # IA-NA
40df4566 4397 if test $offer_ip != 1; then
ab187e7e 4398 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4399 fi
33ac3c83 4400 # Server identifier
ab187e7e 4401 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4402 echo $reply | trim_zeros >> $inport.expected
4403 else
4404 for outport; do
4405 echo $request | trim_zeros >> $outport.expected
4406 done
4407 fi
4408
4409 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4410}
4411
4412reset_pcap_file() {
4413 local iface=$1
4414 local pcap_file=$2
4415 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4416options:rxq_pcap=dummy-rx.pcap
4417 rm -f ${pcap_file}*.pcap
4418 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4419options:rxq_pcap=${pcap_file}-rx.pcap
4420}
4421
4422AT_CAPTURE_FILE([ofctl_monitor0.log])
4423as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4424--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4425
4426echo "---------NB dump-----"
4427ovn-nbctl show
4428echo "---------------------"
4429echo "---------SB dump-----"
4430ovn-sbctl list datapath_binding
4431echo "---------------------"
4432ovn-sbctl list logical_flow
4433echo "---------------------"
4434
4435echo "---------------------"
4436ovn-sbctl dump-flows
4437echo "---------------------"
4438
4439echo "------ hv1 dump ----------"
4440as hv1 ovs-ofctl dump-flows br-int
4441
4442src_mac=f00000000001
4443src_lla=fe80000000000000f20000fffe000001
4444offer_ip=ae700000000000000000000000000004
4445test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4446
4447# NXT_RESUMEs should be 1.
4448OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4449
4450$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4451# cat 1.expected | trim_zeros > expout
4452cat 1.expected | cut -c -120 > expout
4453AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4454# Skipping the UDP checksum
4455cat 1.expected | cut -c 125- > expout
4456AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4457
4458rm 1.expected
4459
4460# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4461# without any modifications and the packet should be received by ls1-lp1.
4462# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4463# resume and the other from ovs-ofctl monitor resume.
4464
4465reset_pcap_file hv1-vif1 hv1/vif1
4466reset_pcap_file hv1-vif2 hv1/vif2
4467
4468src_mac=f00000000002
4469src_lla=fe80000000000000f20000fffe000002
4470offer_ip=ae700000000000000000000000000005
4471# Set invalid msg_type
4472
4473test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4474
4475# NXT_RESUMEs should be 2.
4476OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4477
4478# vif2-tx.pcap should not have received the DHCPv6 reply packet
4479rm 2.packets
4480$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4481AT_CHECK([cat 2.packets], [0], [])
4482
4483# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4484$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4485cat 1.expected > expout
4486AT_CHECK([cat 1.packets], [0], [expout])
4487
4488# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4489# There should be no DHCPv6 reply from ovn-controller and the request packet
4490# should be received by ls2-lp2.
4491
4492src_mac=f00000000003
4493src_lla=fe80000000000000f20000fffe000003
4494test_dhcpv6 3 $src_mac $src_lla 01 0 4
4495
4496# NXT_RESUMEs should be 2 only.
4497OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4498
4499# vif3-tx.pcap should not have received the DHCPv6 reply packet
4500$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4501AT_CHECK([cat 3.packets], [0], [])
4502
4503# vif4-tx.pcap should have received the DHCPv6 request packet
4504$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4505cat 4.expected > expout
4506AT_CHECK([cat 4.packets], [0], [expout])
4507
40df4566
ZKL
4508# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4509# The DHCPv6 reply should doesn't contian offer_ip.
4510src_mac=f00000000022
4511src_lla=fe80000000000000f20000fffe000022
4512reset_pcap_file hv1-vif5 hv1/vif5
4513test_dhcpv6 5 $src_mac $src_lla 01 1 5
4514
4515# NXT_RESUMEs should be 3.
4516OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4517
4518$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4519# Skipping the UDP checksum
4520cat 5.expected | cut -c 1-120,125- > expout
4521AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4522
33ac3c83 4523as hv1
281977f7
NS
4524OVS_APP_EXIT_AND_WAIT([ovn-controller])
4525OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4526OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4527
4528as ovn-sb
4529OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4530
4531as ovn-nb
4532OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4533
4534as northd
4535OVS_APP_EXIT_AND_WAIT([ovn-northd])
4536
4537as main
4538OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4539OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4540
4541AT_CLEANUP
4542
c1645003 4543AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4544AT_SKIP_IF([test $HAVE_PYTHON = no])
4545ovn_start
4546
4547# Logical network:
4548# Two LRs - R1 and R2 that are connected to each other via LS "join"
4549# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4550# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4551# R2 is a gateway router.
4552
4553
4554
4555# Create two hypervisor and create OVS ports corresponding to logical ports.
4556net_add n1
4557
4558sim_add hv1
4559as hv1
4560ovs-vsctl add-br br-phys
4561ovn_attach n1 br-phys 192.168.0.1
4562ovs-vsctl -- add-port br-int hv1-vif1 -- \
4563 set interface hv1-vif1 external-ids:iface-id=foo1 \
4564 options:tx_pcap=hv1/vif1-tx.pcap \
4565 options:rxq_pcap=hv1/vif1-rx.pcap \
4566 ofport-request=1
4567
4568
4569sim_add hv2
4570as hv2
4571ovs-vsctl add-br br-phys
4572ovn_attach n1 br-phys 192.168.0.2
4573ovs-vsctl -- add-port br-int hv2-vif1 -- \
4574 set interface hv2-vif1 external-ids:iface-id=alice1 \
4575 options:tx_pcap=hv2/vif1-tx.pcap \
4576 options:rxq_pcap=hv2/vif1-rx.pcap \
4577 ofport-request=1
4578
4579# Pre-populate the hypervisors' ARP tables so that we don't lose any
4580# packets for ARP resolution (native tunneling doesn't queue packets
4581# for ARP resolution).
74868f2c 4582OVN_POPULATE_ARP
c1645003
GS
4583
4584ovn-nbctl create Logical_Router name=R1
4585ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4586
ea46a4e9
JP
4587ovn-nbctl ls-add foo
4588ovn-nbctl ls-add alice
4589ovn-nbctl ls-add join
c1645003
GS
4590
4591# Connect foo to R1
31114af7 4592ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4593ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4594 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4595
4596# Connect alice to R2
31114af7 4597ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4598ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4599 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4600
4601# Connect R1 to join
31114af7 4602ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4603ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4604 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4605
4606# Connect R2 to join
31114af7 4607ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4608ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4609 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4610
4611
4612#install static routes
4613ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4614ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4615R1 static_routes @lrt
4616
4617ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4618ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4619R2 static_routes @lrt
4620
4621# Create logical port foo1 in foo
31ed1192
JP
4622ovn-nbctl lsp-add foo foo1 \
4623-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4624
4625# Create logical port alice1 in alice
31ed1192
JP
4626ovn-nbctl lsp-add alice alice1 \
4627-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4628
4629
4630# Allow some time for ovn-northd and ovn-controller to catch up.
4631# XXX This should be more systematic.
4632sleep 2
4633
4634ip_to_hex() {
4635 printf "%02x%02x%02x%02x" "$@"
4636}
c1645003
GS
4637
4638# Send ip packets between foo1 and alice1
4639src_mac="f00000010203"
4640dst_mac="000001010203"
4641src_ip=`ip_to_hex 192 168 1 2`
4642dst_ip=`ip_to_hex 172 16 1 2`
4643packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4644
4645echo "---------NB dump-----"
4646ovn-nbctl show
4647echo "---------------------"
4648ovn-nbctl list logical_router
4649echo "---------------------"
4650ovn-nbctl list logical_router_port
4651echo "---------------------"
4652
4653echo "---------SB dump-----"
4654ovn-sbctl list datapath_binding
4655echo "---------------------"
4656ovn-sbctl list port_binding
4657echo "---------------------"
4658ovn-sbctl dump-flows
4659echo "---------------------"
4660ovn-sbctl list chassis
4661ovn-sbctl list encap
4662echo "---------------------"
4663
c1645003
GS
4664# Packet to Expect at alice1
4665src_mac="000002010203"
4666dst_mac="f00000010204"
4667src_ip=`ip_to_hex 192 168 1 2`
4668dst_ip=`ip_to_hex 172 16 1 2`
4669expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4670
4671
4672as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4673as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4674
ab39371d
RM
4675echo "------ hv1 dump after packet 1 ----------"
4676as hv1 ovs-ofctl show br-int
4677as hv1 ovs-ofctl dump-flows br-int
4678echo "------ hv2 dump after packet 1 ----------"
4679as hv2 ovs-ofctl show br-int
4680as hv2 ovs-ofctl dump-flows br-int
4681echo "----------------------------"
4682
49d7c759
BP
4683echo $expected > expected
4684OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4685
34114cf8
GS
4686# Delete the router and re-create it. Things should work as before.
4687ovn-nbctl lr-del R2
4688ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4689# Connect alice to R2
4690ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4691# Connect R2 to join
4692ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4693
4694ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4695ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4696R2 static_routes @lrt
4697
4698# Wait for ovn-controller to catch up.
4699sleep 1
4700
4701# Send the packet again.
4702as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4703
4704echo "------ hv1 dump after packet 2 ----------"
4705as hv1 ovs-ofctl show br-int
4706as hv1 ovs-ofctl dump-flows br-int
4707echo "------ hv2 dump after packet 2 ----------"
4708as hv2 ovs-ofctl show br-int
4709as hv2 ovs-ofctl dump-flows br-int
4710echo "----------------------------"
4711
49d7c759
BP
4712echo $expected >> expected
4713OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4714
7a8f15e0 4715OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4716
4717AT_CLEANUP
bb3c4568
FF
4718
4719AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4720AT_KEYWORDS([router-icmp-reply])
4721AT_SKIP_IF([test $HAVE_PYTHON = no])
4722ovn_start
4723
4724# Logical network:
4725# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4726# and has switch ls2 (172.16.1.0/24) connected to it.
4727
fa2a27b2 4728ovn-nbctl lr-add R1
bb3c4568 4729
ea46a4e9
JP
4730ovn-nbctl ls-add ls1
4731ovn-nbctl ls-add ls2
bb3c4568
FF
4732
4733# Connect ls1 to R1
31114af7 4734ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4735ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4736 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4737
4738# Connect ls2 to R1
31114af7 4739ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4740ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4741 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4742
4743# Create logical port ls1-lp1 in ls1
31ed1192
JP
4744ovn-nbctl lsp-add ls1 ls1-lp1 \
4745-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4746
4747# Create logical port ls2-lp1 in ls2
31ed1192
JP
4748ovn-nbctl lsp-add ls2 ls2-lp1 \
4749-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4750
4751# Create one hypervisor and create OVS ports corresponding to logical ports.
4752net_add n1
4753
4754sim_add hv1
4755as hv1
4756ovs-vsctl add-br br-phys
4757ovn_attach n1 br-phys 192.168.0.1
4758ovs-vsctl -- add-port br-int vif1 -- \
4759 set interface vif1 external-ids:iface-id=ls1-lp1 \
4760 options:tx_pcap=hv1/vif1-tx.pcap \
4761 options:rxq_pcap=hv1/vif1-rx.pcap \
4762 ofport-request=1
4763
4764ovs-vsctl -- add-port br-int vif2 -- \
4765 set interface vif2 external-ids:iface-id=ls2-lp1 \
4766 options:tx_pcap=hv1/vif2-tx.pcap \
4767 options:rxq_pcap=hv1/vif2-rx.pcap \
4768 ofport-request=1
4769
4770
4771# Allow some time for ovn-northd and ovn-controller to catch up.
4772# XXX This should be more systematic.
4773sleep 1
4774
4775
4776ip_to_hex() {
4777 printf "%02x%02x%02x%02x" "$@"
4778}
bb3c4568
FF
4779for i in 1 2; do
4780 : > vif$i.expected
4781done
4782# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
4783#
4784# Causes a packet to be received on INPORT. The packet is an ICMPv4
4785# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
4786# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
4787# provided, then it should be the ip and icmp checksums of the packet
4788# responded; otherwise, no reply is expected.
4789# In the absence of an ip checksum calculation helpers, this relies
4790# on the caller to provide the checksums for the ip and icmp headers.
4791# XXX This should be more systematic.
4792#
4793# INPORT is an lport number, e.g. 11 for vif11.
4794# ETH_SRC and ETH_DST are each 12 hex digits.
4795# IPV4_SRC and IPV4_DST are each 8 hex digits.
4796# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
4797# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
4798test_ipv4_icmp_request() {
4799 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
4800 local exp_ip_chksum=$8 exp_icmp_chksum=$9
4801 shift; shift; shift; shift; shift; shift; shift
4802 shift; shift
4803
4804 # Use ttl to exercise section 4.2.2.9 of RFC1812
4805 local ip_ttl=01
4806 local icmp_id=5fbf
4807 local icmp_seq=0001
4808 local icmp_data=$(seq 1 56 | xargs printf "%02x")
4809 local icmp_type_code_request=0800
4810 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4811 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
4812
4813 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
4814 if test X$exp_icmp_chksum != X; then
4815 # Expect to receive the reply, if any. In same port where packet was sent.
4816 # Note: src and dst fields are expected to be reversed.
4817 local icmp_type_code_response=0000
4818 local reply_icmp_ttl=fe
4819 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
4820 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
4821 echo $reply >> vif$inport.expected
4822 fi
4823}
4824
4825# Send ping packet to router's ip addresses, from each of the 2 logical ports.
4826rtr_l1_ip=$(ip_to_hex 192 168 1 1)
4827rtr_l2_ip=$(ip_to_hex 172 16 1 1)
4828l1_ip=$(ip_to_hex 192 168 1 2)
4829l2_ip=$(ip_to_hex 172 16 1 2)
4830
4831# Ping router ip address that is on same subnet as the logical port
4832test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
4833test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
4834
4835# Ping router ip address that is on the other side of the logical ports
4836test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
4837test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
4838
4839echo "---------NB dump-----"
4840ovn-nbctl show
4841echo "---------------------"
4842ovn-nbctl list logical_router
4843echo "---------------------"
4844ovn-nbctl list logical_router_port
4845echo "---------------------"
4846
4847echo "---------SB dump-----"
4848ovn-sbctl list datapath_binding
4849echo "---------------------"
4850ovn-sbctl list logical_flow
4851echo "---------------------"
4852
4853echo "------ hv1 dump ----------"
4854as hv1 ovs-ofctl dump-flows br-int
4855
4856# Now check the packets actually received against the ones expected.
4857for inport in 1 2; do
49d7c759 4858 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
4859done
4860
7a8f15e0 4861OVN_CLEANUP([hv1])
bb3c4568
FF
4862
4863AT_CLEANUP
94f79fcb
RB
4864
4865# 1 hypervisor, 1 port
4866# make sure that the port state is properly set to up and back down
4867# when created and deleted.
4868AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
4869ovn_start
4870
4871ovn-nbctl ls-add ls1
4872ovn-nbctl lsp-add ls1 lp1
4873ovn-nbctl lsp-set-addresses lp1 unknown
4874
4875net_add n1
4876sim_add hv1
4877as hv1 ovs-vsctl add-br br-phys
4878as hv1 ovn_attach n1 br-phys 192.168.0.1
4879
4880as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4881OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4882
4883as hv1 ovs-vsctl del-port br-int vif1
4884OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4885
7a8f15e0 4886OVN_CLEANUP([hv1])
94f79fcb 4887
94f79fcb 4888AT_CLEANUP
e75451fe 4889
ccc6e1db
FF
4890# 1 hypervisor, 1 port
4891# make sure that the OF rules created to support a datapath are added/cleared
4892# when logical switch is created and removed.
4893AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 4894AT_KEYWORDS([cleanup])
ccc6e1db
FF
4895ovn_start
4896
4897net_add n1
4898sim_add hv1
4899as hv1 ovs-vsctl add-br br-phys
4900as hv1 ovn_attach n1 br-phys 192.168.0.1
4901
4902# This shell function checks if OF rules in br-int have clauses
4903# related to OVN datapaths. The caller determines if it should find
4904# a match in the output, or not.
4905#
4906# EXPECT_DATAPATH param determines whether flows that refer to
4907# datapath to should be present or not. 0 means
4908# they should not be.
4909# STAGE_INFO param is a simple string to help identify the stage
4910# in the test when this function was invoked.
4911test_datapath_in_of_rules() {
4912 local expect_datapath=$1 stage_info=$2
4913 echo "------ ovn-nbctl show ${stage_info} ------"
4914 ovn-nbctl show
4915 echo "------ ovn-sbctl show ${stage_info} ------"
4916 ovn-sbctl show
4917 echo "------ OF rules ${stage_info} ------"
4918 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
4919 # if there is a datapath mentioned in the output, check for the
4920 # magic keyword that represents one, based on the exit status of
4921 # a quiet grep
4922 if test $expect_datapath != 0; then
4618b102 4923 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 4924 else
4618b102 4925 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
4926 fi
4927}
4928
4929test_datapath_in_of_rules 0 "before ls+port create"
4930
4931ovn-nbctl ls-add ls1
4932ovn-nbctl lsp-add ls1 lp1
4933ovn-nbctl lsp-set-addresses lp1 unknown
4934
4935as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
4936OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
4937
4938test_datapath_in_of_rules 1 "after port is bound"
4939
4940as hv1 ovs-vsctl del-port br-int vif1
4941OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
4942
4943ovn-nbctl lsp-set-addresses lp1
4944ovn-nbctl lsp-del lp1
4945ovn-nbctl ls-del ls1
4946
4947# wait for earlier changes to take effect
4948AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
4949
4950# ensure OF rules are no longer present. There used to be a bug here.
4951test_datapath_in_of_rules 0 "after lport+ls removal"
4952
4953OVN_CLEANUP([hv1])
4954
4955AT_CLEANUP
4956
f8a8db39 4957AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
4958AT_SKIP_IF([test $HAVE_PYTHON = no])
4959ovn_start
4960
4961#TODO: since patch port for IPv6 logical router port is not ready not,
4962# so we are not going to test vifs on different lswitches cases. Try
4963# to update for that once relevant stuff implemented.
4964
4965# In this test cases we create 1 lswitch, it has 2 VIF ports attached
4966# with. NS packet we test, from one VIF for another VIF, will be replied
4967# by local ovn-controller, but not by target VIF.
4968
4969# Create hypervisors and logical switch lsw0.
4970ovn-nbctl ls-add lsw0
4971net_add n1
4972sim_add hv1
4973as hv1
4974ovs-vsctl add-br br-phys
4975ovn_attach n1 br-phys 192.168.0.2
4976
4977# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
4978ovs-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
4979ovn-nbctl lsp-add lsw0 lp1
4980ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4981ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
4982
4983# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
4984ovs-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
4985ovn-nbctl lsp-add lsw0 lp2
4986ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4987ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
4988
4989# Add ACL rule for ICMPv6 on lsw0
4990ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
4991ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
4992ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
4993
4994# Allow some time for ovn-northd and ovn-controller to catch up.
4995# XXX This should be more systematic.
4996sleep 1
4997
4998# Given the name of a logical port, prints the name of the hypervisor
4999# on which it is located.
5000vif_to_hv() {
5001 echo hv1${1%?}
5002}
e75451fe
ZKL
5003for i in 1 2; do
5004 : > $i.expected
5005done
5006
5007# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5008# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5009# vif2 will not receive NS packet, since ovn-controller will reply for it.
5010ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5011na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5012
5013as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 5014echo $na_packet >> 1.expected
e75451fe 5015
e75451fe
ZKL
5016echo "------ hv1 dump ------"
5017as hv1 ovs-vsctl show
5018as hv1 ovs-ofctl -O OpenFlow13 show br-int
5019as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5020
5021for i in 1 2; do
49d7c759 5022 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
5023done
5024
7a8f15e0 5025OVN_CLEANUP([hv1])
e75451fe
ZKL
5026
5027AT_CLEANUP
7417d147
RM
5028
5029AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
5030ovn_start
5031
5032net_add n1
5033
5034sim_add hv1
5035as hv1
5036ovs-vsctl add-br br-phys
5037ovn_attach n1 br-phys 192.168.0.1
5038
5039row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5040ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5041ovn-nbctl destroy Address_Set $row
5042
5043sleep 1
5044
5045# A bug previously existed in the address set support code
5046# that caused ovn-controller to crash after an address set
5047# was updated and then removed. This test case ensures
5048# that ovn-controller is at least still running after
5049# creating, updating, and deleting an address set.
5050AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5051
5052OVN_CLEANUP([hv1])
5053
5054AT_CLEANUP
8639f9be
ND
5055
5056AT_SETUP([ovn -- ipam])
8639f9be
ND
5057AT_SKIP_IF([test $HAVE_PYTHON = no])
5058ovn_start
5059
5060# Add a port to a switch that does not have a subnet set, then set the
5061# subnet which should result in an address being allocated for the port.
5062ovn-nbctl ls-add sw0
5063ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 5064ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
5065AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5066 ["0a:00:00:00:00:01 192.168.1.2"
5067])
5068
5069# Add 9 more ports to sw0, addresses should all be unique.
5070for n in `seq 1 9`; do
11547f85 5071 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5072done
5073AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5074 ["0a:00:00:00:00:02 192.168.1.3"
5075])
5076AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5077 ["0a:00:00:00:00:03 192.168.1.4"
5078])
5079AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5080 ["0a:00:00:00:00:04 192.168.1.5"
5081])
5082AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5083 ["0a:00:00:00:00:05 192.168.1.6"
5084])
5085AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5086 ["0a:00:00:00:00:06 192.168.1.7"
5087])
5088AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5089 ["0a:00:00:00:00:07 192.168.1.8"
5090])
5091AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5092 ["0a:00:00:00:00:08 192.168.1.9"
5093])
5094AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5095 ["0a:00:00:00:00:09 192.168.1.10"
5096])
5097AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5098 ["0a:00:00:00:00:0a 192.168.1.11"
5099])
5100
5101# Trying similar tests with a second switch. MAC addresses should be unique
5102# across both switches but IP's only need to be unique within the same switch.
5103ovn-nbctl ls-add sw1
5104ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 5105ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
5106AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5107 ["0a:00:00:00:00:0b 192.168.1.2"
5108])
5109
5110for n in `seq 11 19`; do
11547f85 5111 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5112done
5113AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5114 ["0a:00:00:00:00:0c 192.168.1.3"
5115])
5116AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5117 ["0a:00:00:00:00:0d 192.168.1.4"
5118])
5119AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5120 ["0a:00:00:00:00:0e 192.168.1.5"
5121])
5122AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5123 ["0a:00:00:00:00:0f 192.168.1.6"
5124])
5125AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5126 ["0a:00:00:00:00:10 192.168.1.7"
5127])
5128AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5129 ["0a:00:00:00:00:11 192.168.1.8"
5130])
5131AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5132 ["0a:00:00:00:00:12 192.168.1.9"
5133])
5134AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5135 ["0a:00:00:00:00:13 192.168.1.10"
5136])
5137AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5138 ["0a:00:00:00:00:14 192.168.1.11"
5139])
5140
5141# Change a port's address to test for multiple ip's for a single address entry
5142# and addresses set by the user.
5143ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.12 192.168.1.14"
11547f85 5144ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
5145AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5146 ["0a:00:00:00:00:16 192.168.1.13"
5147])
5148
5149# Test for logical router port address management.
5150ovn-nbctl create Logical_Router name=R1
5151ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5152network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5153-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5154-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 5155ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
5156AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5157 ["0a:00:00:00:00:18 192.168.1.15"
5158])
5159
5160# Test for address reuse after logical port is deleted.
5161ovn-nbctl lsp-del p0
11547f85 5162ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
5163AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5164 ["0a:00:00:00:00:19 192.168.1.2"
5165])
5166
5167# Test for multiple addresses to one logical port.
5168ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5169"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 5170ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
5171AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5172 ["0a:00:00:00:00:1c 192.168.1.16"
5173])
5174
5175# Test for exhausting subnet address space.
5176ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 5177ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
5178AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5179 ["0a:00:00:00:00:1d 172.16.1.2"
5180])
5181
11547f85 5182ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 5183AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 5184 ["0a:00:00:00:00:1e"
8639f9be
ND
5185])
5186
5187# Test that address management does not add duplicate MAC for lsp/lrp peers.
5188ovn-nbctl create Logical_Router name=R2
5189ovn-nbctl ls-add sw3
5190ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 5191"0a:00:00:00:00:1f"
8639f9be
ND
5192ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5193network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5194-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5195-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 5196ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
5197AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5198 ["0a:00:00:00:00:20 192.168.1.17"
5199])
5200
6374d518
LR
5201# Test static MAC address with dynamically allocated IP
5202ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5203"fe:dc:ba:98:76:54 dynamic"
5204AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5205 ["fe:dc:ba:98:76:54 192.168.1.18"
5206])
5207
6c4f7a8a
NS
5208# Update the static MAC address with dynamically allocated IP and check
5209# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5210ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
5211ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses
5212
5213AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5214 ["fe:dc:ba:98:76:55 192.168.1.18"
5215])
5216
5217ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5218AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5219 ["fe:dc:ba:98:76:55 192.168.1.18"
5220])
5221
5222ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5223AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5224 ["fe:dc:ba:98:76:56 192.168.1.18"
5225])
5226
161ea2c8
NS
5227
5228# Test the exclude_ips from the IPAM list
5229ovn-nbctl --wait=sb set logical_switch sw0 \
5230other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5231
5232ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5233"dynamic"
5234# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5235AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
5236 ["0a:00:00:00:00:21 192.168.1.20"
5237])
5238
5239ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5240"dynamic"
5241# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5242AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
5243 ["0a:00:00:00:00:22 192.168.1.22"
5244])
5245
5246ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5247"dynamic"
5248# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5249AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
5250 ["0a:00:00:00:00:23 192.168.1.51"
5251])
5252
5253# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5254ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5255ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5256"dynamic"
5257AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
5258 ["0a:00:00:00:00:24 192.168.1.19"
5259])
5260
5261# Set invalid data in exclude_ips list. It should be ignored.
5262ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5263ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5264"dynamic"
5265# 192.168.1.21 should be assigned as that's the next free one.
5266AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5267 ["0a:00:00:00:00:25 192.168.1.21"
5268])
5269
5270# Clear the dynamic addresses assignment request.
5271ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5272AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5273 [[[]]
5274])
5275
7cc0741e
NS
5276# Set IPv6 prefix
5277ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5278ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5279"dynamic"
5280
5281# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5282# - aef0::800:ff:fe00:26 (EUI64)
5283AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
5284 ["0a:00:00:00:00:26 192.168.1.21 aef0::800:ff:fe00:26"
5285])
5286
5287ovn-nbctl --wait=sb ls-add sw4
5288ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5289ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5290"dynamic"
5291
5292AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
5293 ["0a:00:00:00:00:27 bef0::800:ff:fe00:27"
5294])
5295
5296ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5297"f0:00:00:00:10:12 dynamic"
5298
5299AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5300 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5301])
5302
5303# Clear the other_config for sw4. No dynamic ip should be assigned.
5304ovn-nbctl --wait=sb clear Logical-switch sw4 other_config
5305ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5306"dynamic"
5307
5308AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5309 [[[]]
5310])
5311
5312# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5313ovn-nbctl --wait=sb set Logical-switch sw4 other_config:subnet=192.168.2.0/30 \
5314-- set Logical-switch sw4 other_config:ipv6_prefix="bef0::"
5315
5316# Now p40 should be assigned with dynamic addresses.
5317AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
5318 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
5319])
5320
5321ovn-nbctl --wait=sb lsp-add sw4 p41 -- lsp-set-addresses p41 \
5322"dynamic"
5323# p41 should not have IPv4 address (as the pool is exhausted).
5324AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5325 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5326])
5327
8639f9be
ND
5328as ovn-sb
5329OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5330
5331as ovn-nb
5332OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5333
5334as northd
5335OVS_APP_EXIT_AND_WAIT([ovn-northd])
5336
5337AT_CLEANUP
5338
5339AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5340AT_SKIP_IF([test $HAVE_PYTHON = no])
5341ovn_start
5342
5343ovn-nbctl lr-add R1
5344
5345# Test for a ping using dynamically allocated addresses.
5346ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5347ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5348
5349# Connect foo to R1
5350ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5351ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5352 options:router-port=foo \
5353 -- lsp-set-addresses rp-foo router
8639f9be
ND
5354
5355# Connect alice to R1
5356ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5357ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5358 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5359
5360# Create logical port foo1 in foo
fd3b31e9 5361ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5362-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5363AT_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
5364
5365# Create logical port alice1 in alice
fd3b31e9 5366ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5367-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5368AT_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
5369
5370# Create logical port foo2 in foo
fd3b31e9 5371ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5372-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5373AT_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
5374
5375# Create a hypervisor and create OVS ports corresponding to logical ports.
5376net_add n1
5377
5378sim_add hv1
5379as hv1
5380ovs-vsctl add-br br-phys
5381ovn_attach n1 br-phys 192.168.0.1
5382ovs-vsctl -- add-port br-int hv1-vif1 -- \
5383 set interface hv1-vif1 external-ids:iface-id=foo1 \
5384 options:tx_pcap=hv1/vif1-tx.pcap \
5385 options:rxq_pcap=hv1/vif1-rx.pcap \
5386 ofport-request=1
5387
5388ovs-vsctl -- add-port br-int hv1-vif2 -- \
5389 set interface hv1-vif2 external-ids:iface-id=foo2 \
5390 options:tx_pcap=hv1/vif2-tx.pcap \
5391 options:rxq_pcap=hv1/vif2-rx.pcap \
5392 ofport-request=2
5393
5394ovs-vsctl -- add-port br-int hv1-vif3 -- \
5395 set interface hv1-vif3 external-ids:iface-id=alice1 \
5396 options:tx_pcap=hv1/vif3-tx.pcap \
5397 options:rxq_pcap=hv1/vif3-rx.pcap \
5398 ofport-request=3
5399
5400# Allow some time for ovn-northd and ovn-controller to catch up.
5401# XXX This should be more systematic.
5402sleep 1
5403
5404ip_to_hex() {
5405 printf "%02x%02x%02x%02x" "$@"
5406}
8639f9be
ND
5407
5408# Send ip packets between foo1 and foo2
5409src_mac="0a0000000001"
5410dst_mac="0a0000000003"
5411src_ip=`ip_to_hex 192 168 1 2`
5412dst_ip=`ip_to_hex 192 168 1 3`
5413packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5414as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5415
5416# Send ip packets between foo1 and alice1
5417src_mac="0a0000000001"
5418dst_mac="000000010203"
5419src_ip=`ip_to_hex 192 168 1 2`
5420dst_ip=`ip_to_hex 192 168 2 2`
5421packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5422as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5423
5424echo "---------NB dump-----"
5425ovn-nbctl show
5426echo "---------------------"
5427ovn-nbctl list logical_router
5428echo "---------------------"
5429ovn-nbctl list logical_router_port
5430echo "---------------------"
5431
5432echo "---------SB dump-----"
5433ovn-sbctl list datapath_binding
5434echo "---------------------"
5435ovn-sbctl list port_binding
5436echo "---------------------"
5437
5438echo "------ hv1 dump ----------"
5439as hv1 ovs-ofctl dump-flows br-int
5440
5441# Packet to Expect at foo2
5442src_mac="0a0000000001"
5443dst_mac="0a0000000003"
5444src_ip=`ip_to_hex 192 168 1 2`
5445dst_ip=`ip_to_hex 192 168 1 3`
5446expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5447
e4543cfe
DDP
5448$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5449echo $expected > expout
8639f9be
ND
5450AT_CHECK([cat received1.packets], [0], [expout])
5451
5452# Packet to Expect at alice1
5453src_mac="000000010204"
5454dst_mac="0a0000000002"
5455src_ip=`ip_to_hex 192 168 1 2`
5456dst_ip=`ip_to_hex 192 168 2 2`
5457expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5458
e4543cfe
DDP
5459$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5460echo $expected > expout
8639f9be
ND
5461AT_CHECK([cat received2.packets], [0], [expout])
5462
5463OVN_CLEANUP([hv1])
5464
5465AT_CLEANUP
f5792c3f
NS
5466
5467AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5468AT_KEYWORDS([vswitchd])
f5792c3f
NS
5469AT_SKIP_IF([test $HAVE_PYTHON = no])
5470ovn_start
5471
5472ovn-nbctl ls-add ls1
5473
5474ovn-nbctl lsp-add ls1 ls1-lp1 \
5475-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5476
5477ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5478
5479net_add n1
5480sim_add hv1
5481
5482as hv1
5483ovs-vsctl add-br br-phys
5484ovn_attach n1 br-phys 192.168.0.1
5485ovs-vsctl -- add-port br-int hv1-vif1 -- \
5486 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5487 options:tx_pcap=hv1/vif1-tx.pcap \
5488 options:rxq_pcap=hv1/vif1-rx.pcap \
5489 ofport-request=1
5490
74868f2c 5491OVN_POPULATE_ARP
f5792c3f
NS
5492sleep 2
5493
5494as hv1 ovs-vsctl show
5495
5496echo "---------------------"
5497ovn-sbctl dump-flows
5498echo "---------------------"
5499
5500echo "------ hv1 dump ----------"
5501as hv1 ovs-ofctl dump-flows br-int
5502total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5503
5504echo "Total flows before vswitchd restart = " $total_flows
5505
5506# Code taken from ovs-save utility
5507save_flows () {
5508 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5509 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5510 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5511 echo "EOF" >> restore_flows.sh
5512}
5513
5514restart_vswitchd () {
5515 restore_flows=$1
5516
5517 if test $restore_flows = true; then
5518 save_flows
5519 fi
5520
5521 as hv1
5522 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5523
5524 if test $restore_flows = true; then
5525 as hv1
5526 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5527 fi
5528
5529 as hv1
5530 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5531 ovs-ofctl dump-flows br-int
5532
5533 if test $restore_flows = true; then
5534 sh ./restore_flows.sh
5535 echo "Flows after restore"
5536 as hv1
5537 ovs-ofctl dump-flows br-int
5538 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5539 flow-restore-wait="true"
5540 fi
5541}
5542
5543# Save the flows, restart vswitchd and restore the flows
5544restart_vswitchd true
5545OVS_WAIT_UNTIL([
5546 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5547 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5548 test "${total_flows}" = "${total_flows_after_restart}"
5549])
5550
5551# Restart vswitchd without restoring
5552restart_vswitchd false
5553OVS_WAIT_UNTIL([
5554 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5555 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5556 test "${total_flows}" = "${total_flows_after_restart}"
5557])
5558
5559OVN_CLEANUP([hv1])
5560AT_CLEANUP
47021598
CSV
5561
5562AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5563AT_SKIP_IF([test $HAVE_PYTHON = no])
5564ovn_start
5565
5566# Topology: Two LSs - ls1 and ls2 are connected via router r0
5567
5568# Create logical switches
5569ovn-nbctl ls-add ls1
5570ovn-nbctl ls-add ls2
5571
5572# Create router
5573ovn-nbctl create Logical_Router name=lr0
5574
5575# Add router ls1p1 port to gateway router
5576ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5577ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5578 type=router options:router-port=lrp-ls1lp1 \
5579 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5580
5581# Add router ls2p2 port to gateway router
5582ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5583ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5584 type=router options:router-port=lrp-ls2lp1 \
5585 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5586
5587# Set default gateway (nexthop) to 192.168.1.254
5588ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5589
5590# Create logical port ls1lp2 in ls1
5591ovn-nbctl lsp-add ls1 ls1lp2 \
5592-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5593
5594# Create logical port ls2lp2 in ls2
5595ovn-nbctl lsp-add ls2 ls2lp2 \
5596-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5597
5598net_add n1
5599sim_add hv1
5600as hv1
5601ovs-vsctl add-br br-phys
5602ovn_attach n1 br-phys 192.168.0.1
5603ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5604 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5605 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5606 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5607 ofport-request=1
5608ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5609 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5610 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5611 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5612 ofport-request=2
5613
5614# Allow some time for ovn-northd and ovn-controller to catch up.
5615# XXX This should be more systematic.
5616sleep 1
5617
5618echo "---------NB dump-----"
5619ovn-nbctl show
5620echo "---------------------"
5621ovn-nbctl list logical_router
5622echo "---------------------"
5623ovn-nbctl list logical_router_port
5624echo "---------------------"
5625
5626echo "---------SB dump-----"
5627ovn-sbctl list datapath_binding
5628echo "---------------------"
5629ovn-sbctl list port_binding
5630echo "---------------------"
5631ovn-sbctl dump-flows
5632echo "---------------------"
5633ovn-sbctl list chassis
5634ovn-sbctl list encap
5635echo "---------------------"
5636
5637echo "------Flows dump-----"
5638as hv1
5639ovs-ofctl dump-flows
5640echo "---------------------"
5641
5642ip_to_hex() {
5643 printf "%02x%02x%02x%02x" "$@"
5644}
5645
5646src_mac="f00000000003"
5647dst_mac="f00000000001"
5648src_ip=`ip_to_hex 192 168 0 2`
5649dst_ip=`ip_to_hex 8 8 8 8`
5650packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5651
5652# Send IP packet destined to 8.8.8.8 from lsp1lp2
5653as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5654
5655trim_zeros() {
5656 sed 's/\(00\)\{1,\}$//'
5657}
5658
5659# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5660# not 8.8.8.8
5661
5662$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5663expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5664echo $expected > expout
5665AT_CHECK([cat packets], [0], [expout])
5666cat packets
5667
5668OVN_CLEANUP([hv1])
5669
5670AT_CLEANUP
8439c2eb
CSV
5671
5672AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5673AT_SKIP_IF([test $HAVE_PYTHON = no])
5674ovn_start
5675# Create logical switch
5676ovn-nbctl ls-add ls0
5677# Create gateway router
5678ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5679# Add router port to gateway router
5680ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5681ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5682 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5683# Add nat-address option
5684ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5685
5686net_add n1
5687sim_add hv1
5688as hv1
5689ovs-vsctl \
5690 -- add-br br-phys \
5691 -- add-br br-eth0
5692
5693ovn_attach n1 br-phys 192.168.0.1
5694
5695AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5696AT_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])
5697
5698# Create a localnet port.
5699AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5700AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5701AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5702AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5703
5704
5705# Wait for packet to be received.
5706OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5707trim_zeros() {
5708 sed 's/\(00\)\{1,\}$//'
5709}
5710$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5711expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5712echo $expected > expout
5713AT_CHECK([sort packets], [0], [expout])
5714cat packets
5715
5716OVN_CLEANUP([hv1])
5717
5718AT_CLEANUP
6e31816f 5719
e914fb54
MS
5720AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
5721AT_SKIP_IF([test $HAVE_PYTHON = no])
5722ovn_start
5723# Create logical switch
5724ovn-nbctl ls-add ls0
5725# Create gateway router
5726ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5727# Add router port to gateway router
5728ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5729ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5730 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
5731# Add nat-address option
5732ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
5733# Add NAT rules
5734AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
5735AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
5736# Add load balancers
5737AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
5738AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
5739AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
5740AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
5741
5742net_add n1
5743sim_add hv1
5744as hv1
5745ovs-vsctl \
5746 -- add-br br-phys \
5747 -- add-br br-eth0
5748
5749ovn_attach n1 br-phys 192.168.0.1
5750
5751AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5752AT_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])
5753
5754# Create a localnet port.
5755AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
5756AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5757AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5758AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5759
5760
5761# Wait for packet to be received.
5762OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
5763trim_zeros() {
5764 sed 's/\(00\)\{1,\}$//'
5765}
5766$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
5767expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
5768echo $expected > expout
5769expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
5770echo $expected >> expout
5771expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
5772echo $expected >> expout
5773AT_CHECK([sort packets], [0], [expout])
5774cat packets
5775
5776OVN_CLEANUP([hv1])
5777
5778AT_CLEANUP
5779
6e31816f 5780AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
5781ovn_start
5782net_add n1
5783sim_add hv1
5784as hv1
5785ovs-vsctl -- add-br br-phys
5786ovn_attach n1 br-phys 192.168.0.1
5787# Create logical switch ls0
5788ovn-nbctl ls-add ls0
5789# Create ports lp0, lp1 in ls0
5790ovn-nbctl lsp-add ls0 lp0
5791ovn-nbctl lsp-add ls0 lp1
5792ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
5793ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
5794dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
5795ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
5796ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
5797ovn-sbctl find MAC_Binding
093aa761 5798# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5799ovn-nbctl lsp-del lp0
5800ovn-sbctl find MAC_Binding
093aa761
BP
5801OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
5802# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
5803ovn-nbctl ls-del ls0
5804ovn-sbctl find MAC_Binding
093aa761 5805OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
5806
5807OVN_CLEANUP([hv1])
5808
5809AT_CLEANUP
926c34fd
RM
5810
5811AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
5812AT_SKIP_IF([test $HAVE_PYTHON = no])
5813ovn_start
5814
5815# Logical network:
5816# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
5817# connected to a router R1.
5818# foo has foo1 to act as a client.
5819# bar has bar1, bar2, bar3 to act as servers.
5820
5821net_add n1
5822
5823sim_add hv1
5824as hv1
5825ovs-vsctl add-br br-phys
5826ovn_attach n1 br-phys 192.168.0.1
5827for i in foo1 bar1 bar2 bar3; do
5828 ovs-vsctl -- add-port br-int $i -- \
5829 set interface $i external-ids:iface-id=$i \
5830 options:tx_pcap=hv1/$i-tx.pcap \
5831 options:rxq_pcap=hv1/$i-rx.pcap
5832done
5833
5834ovn-nbctl create Logical_Router name=R1
5835ovn-nbctl ls-add foo
5836ovn-nbctl ls-add bar
5837
5838# Connect foo to R1
5839ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
5840ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
5841 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
5842
5843# Connect bar to R1
5844ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
5845ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
5846 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
5847
5848# Create logical port foo1 in foo
5849ovn-nbctl lsp-add foo foo1 \
5850-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
5851
5852# Create logical port bar1, bar2 and bar3 in bar
5853for i in `seq 1 3`; do
5854 ip=`expr $i + 1`
5855 ovn-nbctl lsp-add bar bar$i \
5856 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
5857done
5858
5859OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
5860
5861OVN_CLEANUP([hv1])
5862
5863AT_CLEANUP
b511690b
GS
5864
5865AT_SETUP([ovn -- tag allocation])
b511690b
GS
5866ovn_start
5867
5868AT_CHECK([ovn-nbctl ls-add ls0])
5869AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
5870AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
5871AT_CHECK([ovn-nbctl ls-add ls1])
5872
5873dnl When a tag is provided, no allocation is done
5874AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
5875AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5876])
5877dnl The same 'tag' gets created in southbound database.
5878AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5879logical_port="c0"], [0], [3
5880])
5881
5882dnl Allocate tags and see it getting created in both NB and SB
5883AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
5884AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
5885])
5886AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5887logical_port="c1"], [0], [1
5888])
5889
5890AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
5891AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5892])
5893AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5894logical_port="c2"], [0], [2
5895])
5896AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
5897AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5898])
5899AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5900logical_port="c3"], [0], [4
5901])
5902
5903dnl A different parent.
5904AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
5905AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5906])
5907AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5908logical_port="c4"], [0], [1
5909])
5910
5911AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
5912AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5913])
5914AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5915logical_port="c5"], [0], [2
5916])
5917
5918dnl Delete a logical port and create a new one.
5919AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
5920AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
5921AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5922])
5923AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5924logical_port="c6"], [0], [1
5925])
5926
5927dnl Restart northd to see that the same allocation remains.
5928as northd
5929OVS_APP_EXIT_AND_WAIT([ovn-northd])
5930start_daemon ovn-northd \
5931 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
5932 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
5933
5934dnl Create a switch to make sure that ovn-northd has run through the main loop.
5935AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
5936AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
5937])
5938AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
5939])
5940AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
5941])
5942AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
5943])
5944AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
5945])
5946AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5947])
5948
5949dnl Create a switch port with a tag that has already been allocated.
5950dnl It should go through fine with a duplicate tag.
5951AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
5952AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
5953])
5954AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5955logical_port="c7"], [0], [2
5956])
5957AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
5958])
5959
5960AT_CHECK([ovn-nbctl ls-add ls2])
5961dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
5962dnl gets copied to 'tag'
5963AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
5964AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
5965])
5966dnl The same 'tag' gets created in southbound database.
5967AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
5968logical_port="local0"], [0], [25
5969])
5970dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
5971AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
5972AT_CHECK([ovn-nbctl lsp-get-tag local1])
5973dnl change the tag_request.
5974AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
5975AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
5976])
5977
5978AT_CLEANUP
57afd0c0
RR
5979
5980AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
5981ovn_start
5982ovn-nbctl ls-add lsw0
5983net_add n1
5984for i in 1 2; do
5985 sim_add hv$i
5986 as hv$i
5987 ovs-vsctl add-br br-phys
5988 ovn_attach n1 br-phys 192.168.0.$i
5989 ovs-vsctl add-br br-eth0
5990 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5991done
5992
5993# Create a localnet port.
5994AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
5995AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
5996AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
5997AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
5998
5999
6000# Create 3 vifs.
6001AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6002AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6003AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6004AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6005AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
6006AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6007AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6008AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6009AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6010
6011# Bind the localvif1 to hv1.
6012as hv1
6013AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6014
6015# On hv1, check that there are no flows outputting bcast to tunnel
6016OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6017
1ea9b847 6018# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 6019as hv2
1ea9b847 6020OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
6021
6022# Now bind vif2 on hv2.
6023AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6024
6025# At this point, the broadcast flow on vif2 should be deleted.
6026# because, there is now a localnet vif bound (table=32 programming logic)
6027OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6028
6029# Verify that the local net patch port exists on hv2.
6030OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6031
6032# Now bind vif3 on hv2.
6033AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6034
6035# Verify that the local net patch port still exists on hv2
6036OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6037
6038# Delete localvif2
6039AT_CHECK([ovn-nbctl lsp-del localvif2])
6040
6041# Verify that the local net patch port still exists on hv2,
6042# because, localvif3 is still bound.
6043OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6044
57afd0c0 6045OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
6046
6047AT_CLEANUP
6048
d383eed5
JP
6049
6050AT_SETUP([ovn -- ACL logging])
6051AT_KEYWORDS([ovn])
6052ovn_start
6053
6054net_add n1
6055
6056sim_add hv
6057as hv
6058ovs-vsctl add-br br-phys
6059ovn_attach n1 br-phys 192.168.0.1
6060for i in lp1 lp2; do
6061 ovs-vsctl -- add-port br-int $i -- \
6062 set interface $i external-ids:iface-id=$i \
6063 options:tx_pcap=hv/$i-tx.pcap \
6064 options:rxq_pcap=hv/$i-rx.pcap
6065done
6066
6067lp1_mac="f0:00:00:00:00:01"
6068lp1_ip="192.168.1.2"
6069
6070lp2_mac="f0:00:00:00:00:02"
6071lp2_ip="192.168.1.3"
6072
6073ovn-nbctl ls-add lsw0
6074ovn-nbctl --wait=sb lsp-add lsw0 lp1
6075ovn-nbctl --wait=sb lsp-add lsw0 lp2
6076ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6077ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6078ovn-nbctl --wait=sb sync
6079
6080ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6081ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6082
6083ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6084ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6085
6086ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6087ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6088
6089ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6090ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6091
6092ovn-sbctl dump-flows
6093
6094
6095# Send packet that should be dropped without logging.
6096packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6097 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6098 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6099as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6100
6101# Send packet that should be dropped with logging.
6102packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6103 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6104 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6105as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6106
6107# Send packet that should be allowed without logging.
6108packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6109 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6110 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6111as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6112
6113# Send packet that should be allowed with logging.
6114packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6115 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6116 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6117as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6118
6119# Send packet that should allow related flows without logging.
6120packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6121 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6122 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6123as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6124
6125# Send packet that should allow related flows with logging.
6126packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6127 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6128 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6129as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6130
df48cfc7 6131# Send packet that should be rejected without logging.
d383eed5
JP
6132packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6133 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6134 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6135as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6136
df48cfc7 6137# Send packet that should be rejected with logging.
d383eed5
JP
6138packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6139 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6140 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6141as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6142
c1f272f9
NS
6143OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6144
d383eed5
JP
6145AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6146name="drop-flow", verdict=drop, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4361,tp_dst=81,tcp_flags=syn
6147name="allow-flow", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4363,tp_dst=83,tcp_flags=syn
6148name="<unnamed>", verdict=allow, severity=info: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4365,tp_dst=85,tcp_flags=syn
6149name="reject-flow", verdict=reject, severity=alert: tcp,vlan_tci=0x0000,dl_src=f0:00:00:00:00:01,dl_dst=f0:00:00:00:00:02,nw_src=192.168.1.2,nw_dst=192.168.1.3,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4367,tp_dst=87,tcp_flags=syn
6150])
6151
6152OVN_CLEANUP([hv])
6153AT_CLEANUP
6154
6155
23749245
JP
6156AT_SETUP([ovn -- ACL rate-limited logging])
6157AT_KEYWORDS([ovn])
6158ovn_start
6159
6160net_add n1
6161
6162sim_add hv
6163as hv
6164ovs-vsctl add-br br-phys
6165ovn_attach n1 br-phys 192.168.0.1
6166for i in lp1 lp2; do
6167 ovs-vsctl -- add-port br-int $i -- \
6168 set interface $i external-ids:iface-id=$i \
6169 options:tx_pcap=hv/$i-tx.pcap \
6170 options:rxq_pcap=hv/$i-rx.pcap
6171done
6172
6173lp1_mac="f0:00:00:00:00:01"
6174lp1_ip="192.168.1.2"
6175
6176lp2_mac="f0:00:00:00:00:02"
6177lp2_ip="192.168.1.3"
6178
6179ovn-nbctl ls-add lsw0
6180ovn-nbctl --wait=sb lsp-add lsw0 lp1
6181ovn-nbctl --wait=sb lsp-add lsw0 lp2
6182ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6183ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6184ovn-nbctl --wait=sb sync
6185
6186
6187# Add an ACL that rate-limits logs at 10 per second.
6188ovn-nbctl meter-add http-rl1 drop 10 pktps
6189ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6190
6191# Add an ACL that rate-limits logs at 5 per second.
6192ovn-nbctl meter-add http-rl2 drop 5 pktps
6193ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6194
6195# Add an ACL that doesn't rate-limit logs.
6196ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6197
6198
6199# For each ACL, send 100 packets.
6200for i in `seq 1 100`; do
6201 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=80)'
6202
6203 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=81)'
6204
6205 ovs-appctl netdev-dummy/receive lp1 'in_port(1),eth(src=f0:00:00:00:00:01,dst=f0:00:00:00:00:02),eth_type(0x0800),ipv4(src=192.168.1.2,dst=192.168.1.3,proto=6,tos=0,ttl=64,frag=no),tcp(src=7777,dst=82)'
6206done
6207
6208# Print some information that may help debugging.
6209as hv ovs-appctl -t ovn-controller meter-table-list
6210as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6211
6212# The userspace meter implementation doesn't precisely enforce counts,
6213# so we just check that exactly 100 "http-acl3" actions were logged and
6214# that there were more "http-acl1" actions than "http-acl2" ones.
6215OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6216
6217n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6218n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6219n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6220
6221AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6222AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6223
6224
6225OVN_CLEANUP([hv])
6226AT_CLEANUP
6227
6228
66d89287 6229AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6230AT_KEYWORDS([ovn])
6231ovn_start
6232
6233ovn-nbctl ls-add lsw0
6234ovn-nbctl --wait=sb lsp-add lsw0 lp1
6235ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6236ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6237ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6238ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6239ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6240ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6241ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6242ovn-nbctl --wait=sb sync
6243net_add n1
6244sim_add hv
6245as hv
6246ovs-vsctl add-br br-phys
6247ovn_attach n1 br-phys 192.168.0.1
6248ovs-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
6249ovs-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
6250
6251AT_CAPTURE_FILE([trace])
6252ovn_trace () {
6253 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6254}
6255
6256# Extracts nw_tos from the final flow from ofproto/trace output and prints
6257# it on stdout. Prints "none" if no nw_tos was included.
6258get_final_nw_tos() {
6259 if flow=$(grep '^Final flow:' stdout); then :; else
6260 # The output didn't have a final flow.
6261 return 99
6262 fi
6263
6264 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6265 case $tos in
6266 '') echo none ;;
5a0e4aec 6267 *) echo $tos ;;
1a03fc7d
BS
6268 esac
6269}
6270
6271# check_tos TOS
6272#
6273# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6274check_tos() {
6275 # First check with ovn-trace for logical flows.
6276 echo "checking for tos $1"
6277 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6278 echo 'output("lp2");') > expout
6279 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])
6280
6281 # Then re-check with ofproto/trace for a physical packet.
6282 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])
6283 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6284])
6285}
6286
6287# check at L2
6288AT_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");
6289])
6290AT_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])
6291AT_CHECK([get_final_nw_tos], [0], [none
6292])
6293
6294# check at L3 without dscp marking
6295check_tos 0
6296
6297# Mark DSCP with a valid value
e50ed58a 6298qos_id=$(ovn-nbctl --wait=hv -- --id=@lp1-qos create QoS priority=100 action=dscp=48 match="inport\=\=\"lp1\"\ &&\ is_chassis_resident(\"lp1\")" direction="from-lport" -- set Logical_Switch lsw0 qos_rules=@lp1-qos)
5ee33cbd
GL
6299AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6300])
1a03fc7d
BS
6301check_tos 48
6302
66d89287
GL
6303# check at hv without qos meter
6304AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6305])
6306
6307# Update the meter rate
6308ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6309
6310# check at hv with a qos meter table
6311AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6312])
6313AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6314])
6315
1a03fc7d
BS
6316# Update the DSCP marking
6317ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6318check_tos 63
6319
66d89287
GL
6320# Update the meter rate
6321ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6322
6323# check at hv with a qos meter table
6324AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6325])
6326AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6327])
6328
1a03fc7d
BS
6329ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6330check_tos 63
6331
6332# Disable DSCP marking
5ee33cbd
GL
6333ovn-nbctl --wait=hv qos-del lsw0
6334AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6335])
1a03fc7d
BS
6336check_tos 0
6337
66d89287
GL
6338# check at hv without qos meter
6339AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6340])
6341
e50ed58a
GL
6342# check meter with chassis not resident
6343ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6344AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6345])
6346
6347# check no meter table
6348AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6349])
6350AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6351])
6352
1a03fc7d 6353OVN_CLEANUP([hv])
57afd0c0 6354AT_CLEANUP
7fff4eb7
LR
6355
6356AT_SETUP([ovn -- read-only sb db:ptcp access])
6357AT_SKIP_IF([test $HAVE_PYTHON = no])
6358
6359: > .$1.db.~lock~
6360ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6361
6362# Add read-only remote to sb ovsdb-server
6363AT_CHECK(
6364 [ovsdb-tool transact ovn-sb.db \
6365 ['["OVN_Southbound",
6366 {"op": "insert",
6367 "table": "SB_Global",
6368 "row": {
6369 "connections": ["set", [["named-uuid", "xyz"]]]}},
6370 {"op": "insert",
6371 "table": "Connection",
6372 "uuid-name": "xyz",
6373 "row": {"target": "ptcp:0:127.0.0.1",
6374 "read_only": true}}]']], [0], [ignore], [ignore])
6375
6376start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6377
6378PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6379
6380# read-only accesses should succeed
6381AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6382AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6383
6384# write access should fail
6385AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6386[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6387])
6388
6389OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6390AT_CLEANUP
6391
6392AT_SETUP([ovn -- read-only sb db:pssl access])
6393AT_SKIP_IF([test $HAVE_PYTHON = no])
6394AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6395PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6396AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6397\\]"])
6398
6399: > .$1.db.~lock~
6400ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6401
6402# Add read-only remote to sb ovsdb-server
6403AT_CHECK(
6404 [ovsdb-tool transact ovn-sb.db \
6405 ['["OVN_Southbound",
6406 {"op": "insert",
6407 "table": "SB_Global",
6408 "row": {
6409 "connections": ["set", [["named-uuid", "xyz"]]]}},
6410 {"op": "insert",
6411 "table": "Connection",
6412 "uuid-name": "xyz",
6413 "row": {"target": "pssl:0:127.0.0.1",
6414 "read_only": true}}]']], [0], [ignore], [ignore])
6415
6416start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6417 --remote=db:OVN_Southbound,SB_Global,connections \
6418 --private-key="$PKIDIR/testpki-privkey2.pem" \
6419 --certificate="$PKIDIR/testpki-cert2.pem" \
6420 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6421 ovn-sb.db
6422
6423PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6424
6425# read-only accesses should succeed
6426AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6427 --private-key=$PKIDIR/testpki-privkey.pem \
6428 --certificate=$PKIDIR/testpki-cert.pem \
6429 --ca-cert=$PKIDIR/testpki-cacert.pem \
6430 list SB_Global], [0], [stdout], [ignore])
6431AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6432 --private-key=$PKIDIR/testpki-privkey.pem \
6433 --certificate=$PKIDIR/testpki-cert.pem \
6434 --ca-cert=$PKIDIR/testpki-cacert.pem \
6435 list Connection], [0], [stdout], [ignore])
6436
6437# write access should fail
6438AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6439 --private-key=$PKIDIR/testpki-privkey.pem \
6440 --certificate=$PKIDIR/testpki-cert.pem \
6441 --ca-cert=$PKIDIR/testpki-cacert.pem \
6442 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6443[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6444])
6445
6446OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6447AT_CLEANUP
6448
821302cf
LR
6449AT_SETUP([ovn -- nb connection/ssl commands])
6450AT_SKIP_IF([test $HAVE_PYTHON = no])
6451AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6452PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6453AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6454\\]"])
6455
6456: > .$1.db.~lock~
6457ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6458
6459# Start nb db server using db connection/ssl entries (unpopulated initially)
6460start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6461 --remote=db:OVN_Northbound,NB_Global,connections \
6462 --private-key=db:OVN_Northbound,SSL,private_key \
6463 --certificate=db:OVN_Northbound,SSL,certificate \
6464 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6465 ovn-nb.db
6466
6467# Populate SSL configuration entries in nb db
6468AT_CHECK(
6469 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6470 $PKIDIR/testpki-cert.pem \
6471 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6472
6473# Populate a passive SSL connection in nb db
6474AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6475
6476PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6477
6478# Verify SSL connetivity to nb db server
6479AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6480 --private-key=$PKIDIR/testpki-privkey.pem \
6481 --certificate=$PKIDIR/testpki-cert.pem \
6482 --ca-cert=$PKIDIR/testpki-cacert.pem \
6483 list NB_Global],
6484 [0], [stdout], [ignore])
6485AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6486 --private-key=$PKIDIR/testpki-privkey.pem \
6487 --certificate=$PKIDIR/testpki-cert.pem \
6488 --ca-cert=$PKIDIR/testpki-cacert.pem \
6489 list Connection],
6490 [0], [stdout], [ignore])
6491AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6492 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6493 --certificate=$PKIDIR/testpki-cert.pem \
6494 --ca-cert=$PKIDIR/testpki-cacert.pem \
6495 get-connection],
6496 [0], [stdout], [ignore])
6497
6498OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6499AT_CLEANUP
6500
6501AT_SETUP([ovn -- sb connection/ssl commands])
6502AT_SKIP_IF([test $HAVE_PYTHON = no])
6503AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6504PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6505AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6506\\]"])
6507
6508: > .$1.db.~lock~
6509ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6510
6511# Start sb db server using db connection/ssl entries (unpopulated initially)
6512start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6513 --remote=db:OVN_Southbound,SB_Global,connections \
6514 --private-key=db:OVN_Southbound,SSL,private_key \
6515 --certificate=db:OVN_Southbound,SSL,certificate \
6516 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6517 ovn-sb.db
6518
6519# Populate SSL configuration entries in sb db
6520AT_CHECK(
6521 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6522 $PKIDIR/testpki-cert.pem \
6523 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6524
6525# Populate a passive SSL connection in sb db
6526AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6527
6528PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6529
6530# Verify SSL connetivity to sb db server
6531AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6532 --private-key=$PKIDIR/testpki-privkey.pem \
6533 --certificate=$PKIDIR/testpki-cert.pem \
6534 --ca-cert=$PKIDIR/testpki-cacert.pem \
6535 list SB_Global],
6536 [0], [stdout], [ignore])
6537AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6538 --private-key=$PKIDIR/testpki-privkey.pem \
6539 --certificate=$PKIDIR/testpki-cert.pem \
6540 --ca-cert=$PKIDIR/testpki-cacert.pem \
6541 list Connection],
6542 [0], [stdout], [ignore])
6543AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6544 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6545 --certificate=$PKIDIR/testpki-cert.pem \
6546 --ca-cert=$PKIDIR/testpki-cacert.pem \
6547 get-connection],
6548 [0], [stdout], [ignore])
6549
6550OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6551AT_CLEANUP
6552
75fd74f8
GS
6553AT_SETUP([ovn -- nested containers])
6554ovn_start
6555
6556# Physical network:
6557# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6558
6559# Logical network:
6560# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6561# and "bar" (192.168.2.0/24). They are all connected to router R1.
6562
6563ovn-nbctl lr-add R1
6564ovn-nbctl ls-add mgmt
6565ovn-nbctl ls-add foo
6566ovn-nbctl ls-add bar
6567
6568# Connect mgmt to R1
6569ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6570ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6571 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6572
6573# Connect foo to R1
6574ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6575ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6576 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6577
6578# Connect bar to R1
6579ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6580ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6581 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6582
6583# "mgmt" has VM1 and VM2 connected
6584ovn-nbctl lsp-add mgmt vm1 \
6585-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6586
6587ovn-nbctl lsp-add mgmt vm2 \
6588-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6589
6590# "foo1" and "foo2" are containers belonging to switch "foo"
6591# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6592ovn-nbctl lsp-add foo foo1 vm1 1 \
6593-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6594
6595ovn-nbctl lsp-add foo foo2 vm2 2 \
6596-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6597
6598# "bar1" and "bar2" are containers belonging to switch "bar"
6599# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6600ovn-nbctl lsp-add bar bar1 vm1 2 \
6601-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6602
6603ovn-nbctl lsp-add bar bar2 vm2 1 \
6604-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6605
6606# bar3 is a standalone VM belonging to switch "bar"
6607ovn-nbctl lsp-add bar bar3 \
6608-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6609
6610# Create two hypervisor and create OVS ports corresponding to logical ports.
6611net_add n1
6612
6613sim_add hv1
6614as hv1
6615ovs-vsctl add-br br-phys
6616ovn_attach n1 br-phys 192.168.0.1
6617ovs-vsctl -- add-port br-int vm1 -- \
6618 set interface vm1 external-ids:iface-id=vm1 \
6619 options:tx_pcap=hv1/vm1-tx.pcap \
6620 options:rxq_pcap=hv1/vm1-rx.pcap \
6621 ofport-request=1
6622
6623ovs-vsctl -- add-port br-int bar3 -- \
6624 set interface bar3 external-ids:iface-id=bar3 \
6625 options:tx_pcap=hv1/bar3-tx.pcap \
6626 options:rxq_pcap=hv1/bar3-rx.pcap \
6627 ofport-request=2
6628
6629sim_add hv2
6630as hv2
6631ovs-vsctl add-br br-phys
6632ovn_attach n1 br-phys 192.168.0.2
6633ovs-vsctl -- add-port br-int vm2 -- \
6634 set interface vm2 external-ids:iface-id=vm2 \
6635 options:tx_pcap=hv2/vm2-tx.pcap \
6636 options:rxq_pcap=hv2/vm2-rx.pcap \
6637 ofport-request=1
6638
6639# Pre-populate the hypervisors' ARP tables so that we don't lose any
6640# packets for ARP resolution (native tunneling doesn't queue packets
6641# for ARP resolution).
74868f2c 6642OVN_POPULATE_ARP
75fd74f8
GS
6643
6644# Allow some time for ovn-northd and ovn-controller to catch up.
6645# XXX This should be more systematic.
6646sleep 1
6647
6648ip_to_hex() {
6649 printf "%02x%02x%02x%02x" "$@"
6650}
6651
6652# Send ip packets between foo1 and foo2 (same switch, different HVs and
6653# different VLAN tags).
6654src_mac="f00000010205"
6655dst_mac="f00000010206"
6656src_ip=`ip_to_hex 192 168 1 2`
6657dst_ip=`ip_to_hex 192 168 1 3`
6658packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6659as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6660
6661# expected packet at foo2
6662packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6663echo $packet > expected
6664OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6665
6666# Send ip packets between foo1 and bar2 (different switch, different HV)
6667src_mac="f00000010205"
6668dst_mac="000000010203"
6669src_ip=`ip_to_hex 192 168 1 2`
6670dst_ip=`ip_to_hex 192 168 2 3`
6671packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6672as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6673
6674# expected packet at bar2
6675src_mac="000000010204"
6676dst_mac="f00000010208"
6677packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6678echo $packet >> expected
6679OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6680
6681# Send ip packets between foo1 and bar1
6682# (different switch, loopback to same vm but different tag)
6683src_mac="f00000010205"
6684dst_mac="000000010203"
6685src_ip=`ip_to_hex 192 168 1 2`
6686dst_ip=`ip_to_hex 192 168 2 2`
6687packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6688as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6689
6690# expected packet at bar1
6691src_mac="000000010204"
6692dst_mac="f00000010207"
6693packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6694echo $packet > expected1
6695OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6696
6697# Send ip packets between bar1 and bar3
6698# (same switch. But one is container and another is a standalone VM)
6699src_mac="f00000010207"
6700dst_mac="f00000010209"
6701src_ip=`ip_to_hex 192 168 2 2`
6702dst_ip=`ip_to_hex 192 168 2 3`
6703packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6704as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6705
6706# expected packet at bar3
6707packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6708echo $packet > expected
6709OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
6710
6711# Send ip packets between foo1 and vm1.
6712(different switch, container to the VM hosting it.)
6713src_mac="f00000010205"
6714dst_mac="000000010203"
6715src_ip=`ip_to_hex 192 168 1 2`
6716dst_ip=`ip_to_hex 172 16 1 2`
6717packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6718as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6719
6720# expected packet at vm1
6721src_mac="000000010202"
6722dst_mac="f00000010203"
6723packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6724echo $packet >> expected1
6725OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6726
6727# Send packets from vm1 to bar1.
6728(different switch, A hosting VM to a container inside it)
6729src_mac="f00000010203"
6730dst_mac="000000010202"
6731src_ip=`ip_to_hex 172 16 1 2`
6732dst_ip=`ip_to_hex 192 168 2 2`
6733packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6734as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6735
6736# expected packet at vm1
6737src_mac="000000010204"
6738dst_mac="f00000010207"
6739packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6740echo $packet >> expected1
6741OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6742
6743OVN_CLEANUP([hv1],[hv2])
6744
6745AT_CLEANUP
440a9f4b
GS
6746
6747AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
6748AT_SKIP_IF([test $HAVE_PYTHON = no])
6749ovn_start
6750
6751# Logical network:
6752# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
6753# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
6754# (192.168.2.0/24) connected to it.
6755#
6756# R2 and R3 are gateway routers.
6757# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
6758# connected to it. Note how both alice and bob have the same subnet behind it.
6759# We are trying to simulate external network via those 2 switches. In real
6760# world the switch ports of these switches will have addresses set as "unknown"
6761# to make them learning switches. Or those switches will be "localnet" ones.
6762
6763# Create three hypervisors and create OVS ports corresponding to logical ports.
6764net_add n1
6765
6766sim_add hv1
6767as hv1
6768ovs-vsctl add-br br-phys
6769ovn_attach n1 br-phys 192.168.0.1
6770ovs-vsctl -- add-port br-int hv1-vif1 -- \
6771 set interface hv1-vif1 external-ids:iface-id=foo1 \
6772 options:tx_pcap=hv1/vif1-tx.pcap \
6773 options:rxq_pcap=hv1/vif1-rx.pcap \
6774 ofport-request=1
6775
6776ovs-vsctl -- add-port br-int hv1-vif2 -- \
6777 set interface hv1-vif2 external-ids:iface-id=bar1 \
6778 options:tx_pcap=hv1/vif2-tx.pcap \
6779 options:rxq_pcap=hv1/vif2-rx.pcap \
6780 ofport-request=2
6781
6782sim_add hv2
6783as hv2
6784ovs-vsctl add-br br-phys
6785ovn_attach n1 br-phys 192.168.0.2
6786ovs-vsctl -- add-port br-int hv2-vif1 -- \
6787 set interface hv2-vif1 external-ids:iface-id=alice1 \
6788 options:tx_pcap=hv2/vif1-tx.pcap \
6789 options:rxq_pcap=hv2/vif1-rx.pcap \
6790 ofport-request=1
6791
6792sim_add hv3
6793as hv3
6794ovs-vsctl add-br br-phys
6795ovn_attach n1 br-phys 192.168.0.3
6796ovs-vsctl -- add-port br-int hv3-vif1 -- \
6797 set interface hv3-vif1 external-ids:iface-id=bob1 \
6798 options:tx_pcap=hv3/vif1-tx.pcap \
6799 options:rxq_pcap=hv3/vif1-rx.pcap \
6800 ofport-request=1
6801
6802
6803ovn-nbctl create Logical_Router name=R1
6804ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
6805ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
6806
6807ovn-nbctl ls-add foo
6808ovn-nbctl ls-add bar
6809ovn-nbctl ls-add alice
6810ovn-nbctl ls-add bob
6811ovn-nbctl ls-add join
6812
6813# Connect foo to R1
6814ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6815ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6816 options:router-port=foo addresses=\"00:00:01:01:02:03\"
6817
6818# Connect bar to R1
6819ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
6820ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6821 options:router-port=bar addresses=\"00:00:01:01:02:04\"
6822
6823# Connect alice to R2
6824ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
6825ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
6826 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
6827
6828# Connect bob to R3
6829ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
6830ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
6831 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
6832
6833# Connect R1 to join
6834ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
6835ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
6836 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
6837
6838# Connect R2 to join
6839ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
6840ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
6841 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
6842
6843# Connect R3 to join
6844ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
6845ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
6846 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
6847
6848# Install static routes with source ip address as the policy for routing.
6849# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
6850ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
6851ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
6852
6853# Install static routes with destination ip address as the policy for routing.
6854ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
6855
6856ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
6857
6858# Create logical port foo1 in foo
6859ovn-nbctl lsp-add foo foo1 \
6860-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6861
6862# Create logical port bar1 in bar
6863ovn-nbctl lsp-add bar bar1 \
6864-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
6865
6866# Create logical port alice1 in alice
6867ovn-nbctl lsp-add alice alice1 \
6868-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
6869
6870# Create logical port bob1 in bob
6871ovn-nbctl lsp-add bob bob1 \
6872-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
6873
6874# Pre-populate the hypervisors' ARP tables so that we don't lose any
6875# packets for ARP resolution (native tunneling doesn't queue packets
6876# for ARP resolution).
74868f2c 6877OVN_POPULATE_ARP
440a9f4b
GS
6878
6879# Allow some time for ovn-northd and ovn-controller to catch up.
6880# XXX This should be more systematic.
6881sleep 1
6882
6883ip_to_hex() {
6884 printf "%02x%02x%02x%02x" "$@"
6885}
6886trim_zeros() {
6887 sed 's/\(00\)\{1,\}$//'
6888}
6889
6890# Send ip packets between foo1 and bar1
6891# (East-west traffic should flow normally)
6892src_mac="f00000010203"
6893dst_mac="000001010203"
6894src_ip=`ip_to_hex 192 168 1 2`
6895dst_ip=`ip_to_hex 192 168 2 2`
6896packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6897as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
6898
6899# Send ip packets between foo1 and alice1
6900src_mac="f00000010203"
6901dst_mac="000001010203"
6902src_ip=`ip_to_hex 192 168 1 2`
6903dst_ip=`ip_to_hex 172 16 1 3`
6904packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6905as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 6906as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
6907
6908# Send ip packets between bar1 and bob1
6909src_mac="f00000010204"
6910dst_mac="000001010204"
6911src_ip=`ip_to_hex 192 168 2 2`
6912dst_ip=`ip_to_hex 172 16 1 4`
6913packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6914as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
6915#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
6916
6917# Packet to expect at bar1
6918src_mac="000001010204"
6919dst_mac="f00000010204"
6920src_ip=`ip_to_hex 192 168 1 2`
6921dst_ip=`ip_to_hex 192 168 2 2`
6922expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6923echo $expected > expected
6924OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
6925
6926# Packet to Expect at alice1
6927src_mac="000002010203"
6928dst_mac="f00000010205"
6929src_ip=`ip_to_hex 192 168 1 2`
6930dst_ip=`ip_to_hex 172 16 1 3`
6931expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6932echo $expected > expected
6933OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
6934
6935# Packet to Expect at bob1
6936src_mac="000003010203"
6937dst_mac="f00000010206"
6938src_ip=`ip_to_hex 192 168 2 2`
6939dst_ip=`ip_to_hex 172 16 1 4`
6940expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
6941echo $expected > expected
6942OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
6943
6944for sim in hv1 hv2 hv3; do
6945 as $sim
6946 OVS_APP_EXIT_AND_WAIT([ovn-controller])
6947 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6948 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6949done
6950
6951as ovn-sb
6952OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6953
6954as ovn-nb
6955OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6956
6957as northd
6958OVS_APP_EXIT_AND_WAIT([ovn-northd])
6959
6960as main
6961OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
6962OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6963
6964AT_CLEANUP
41a15b71 6965
302eda27
NS
6966AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
6967AT_SKIP_IF([test $HAVE_PYTHON = no])
6968ovn_start
6969
6970ovn-nbctl ls-add ls1
6971
6972ovn-nbctl lsp-add ls1 ls1-lp1 \
6973-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6974
6975ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
6976
6977ovn-nbctl lsp-add ls1 ls1-lp2 \
6978-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6979
6980ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
6981
6982DNS1=`ovn-nbctl create DNS records={}`
6983DNS2=`ovn-nbctl create DNS records={}`
6984
6985ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
6986ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
6987ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
6988
6989ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
6990
6991net_add n1
6992sim_add hv1
6993
6994as hv1
6995ovs-vsctl add-br br-phys
6996ovn_attach n1 br-phys 192.168.0.1
6997ovs-vsctl -- add-port br-int hv1-vif1 -- \
6998 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
6999 options:tx_pcap=hv1/vif1-tx.pcap \
7000 options:rxq_pcap=hv1/vif1-rx.pcap \
7001 ofport-request=1
7002
7003ovs-vsctl -- add-port br-int hv1-vif2 -- \
7004 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7005 options:tx_pcap=hv1/vif2-tx.pcap \
7006 options:rxq_pcap=hv1/vif2-rx.pcap \
7007 ofport-request=2
7008
74868f2c 7009OVN_POPULATE_ARP
302eda27
NS
7010sleep 2
7011as hv1 ovs-vsctl show
7012
7013echo "*************************"
7014ovn-sbctl list DNS
7015echo "*************************"
7016
7017ip_to_hex() {
7018 printf "%02x%02x%02x%02x" "$@"
7019}
7020
7021reset_pcap_file() {
7022 local iface=$1
7023 local pcap_file=$2
7024 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7025options:rxq_pcap=dummy-rx.pcap
7026 rm -f ${pcap_file}*.pcap
7027 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7028options:rxq_pcap=${pcap_file}-rx.pcap
7029}
7030
7031# set_dns_params host_name
7032# Sets the dns_req_data and dns_resp_data
7033set_dns_params() {
7034 local hname=$1
7035 local ttl=00000e10
7036 an_count=0001
7037 type=0001
7038 case $hname in
7039 vm1)
7040 # vm1.ovn.org
7041 query_name=03766d31036f766e036f726700
7042 # IPv4 address - 10.0.0.4
7043 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7044 ;;
7045 vm2)
7046 # vm2.ovn.org
7047 query_name=03766d32036f766e036f726700
7048 # IPv4 address - 10.0.0.6
7049 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7050 # IPv4 address - 20.0.0.4
7051 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7052 an_count=0002
7053 ;;
7054 vm3)
7055 # vm3.ovn.org
7056 query_name=03766d33036f766e036f726700
7057 # IPv4 address - 40.0.0.4
7058 expected_dns_answer=${query_name}00010001${ttl}000428000004
7059 ;;
7060 vm1_ipv6_only)
7061 # vm1.ovn.org
7062 query_name=03766d31036f766e036f726700
7063 # IPv6 address - aef0::4
7064 type=001c
7065 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7066 ;;
7067 vm1_ipv4_v6)
7068 # vm1.ovn.org
7069 query_name=03766d31036f766e036f726700
7070 type=00ff
7071 an_count=0002
7072 # IPv4 address - 10.0.0.4
7073 # IPv6 address - aef0::4
7074 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7075 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7076 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7077 ;;
7078 vm1_invalid_type)
7079 # vm1.ovn.org
7080 query_name=03766d31036f766e036f726700
7081 # IPv6 address - aef0::4
7082 type=0002
7083 ;;
7084 vm1_incomplete)
7085 # set type to none
7086 type=''
7087 esac
7088 # TTL - 3600
7089 local dns_req_header=010201200001000000000000
7090 local dns_resp_header=010281200001${an_count}00000000
7091 dns_req_data=${dns_req_header}${query_name}${type}0001
7092 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7093}
7094
7095# This shell function sends a DNS request packet
7096# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7097test_dns() {
7098 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7099 local dns_query_data=$7
7100 shift; shift; shift; shift; shift; shift; shift;
7101 # Packet size => IPv4 header (20) + UDP header (8) +
7102 # DNS data (header + query)
7103 ip_len=`expr 28 + ${#dns_query_data} / 2`
7104 udp_len=`expr $ip_len - 20`
7105 ip_len=$(printf "%x" $ip_len)
7106 udp_len=$(printf "%x" $udp_len)
7107 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7108 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7109 # dns data
7110 request=${request}${dns_query_data}
7111
7112 if test $dns_reply != 0; then
7113 local dns_reply=$1
7114 ip_len=`expr 28 + ${#dns_reply} / 2`
7115 udp_len=`expr $ip_len - 20`
7116 ip_len=$(printf "%x" $ip_len)
7117 udp_len=$(printf "%x" $udp_len)
7118 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7119 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7120 echo $reply >> $inport.expected
7121 else
7122 for outport; do
7123 echo $request >> $outport.expected
7124 done
7125 fi
7126 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7127}
7128
f8e79d82
MM
7129test_dns6() {
7130 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7131 local dns_query_data=$7
7132 shift; shift; shift; shift; shift; shift; shift;
7133 # Packet size => UDP header (8) +
7134 # DNS data (header + query)
7135 ip_len=`expr 8 + ${#dns_query_data} / 2`
7136 udp_len=$ip_len
7137 ip_len=$(printf "%x" $ip_len)
7138 udp_len=$(printf "%x" $udp_len)
7139 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7140 request=${request}9234003500${udp_len}0000
7141 #dns data
7142 request=${request}${dns_query_data}
7143
7144 if test $dns_reply != 0; then
7145 local dns_reply=$1
7146 ip_len=`expr 8 + ${#dns_reply} / 2`
7147 udp_len=$ip_len
7148 ip_len=$(printf "%x" $ip_len)
7149 udp_len=$(printf "%x" $udp_len)
7150 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7151 reply=${reply}0035923400${udp_len}0000${dns_reply}
7152 echo $reply >> $inport.expected
7153 else
7154 for outport; do
7155 echo $request >> $outport.expected
7156 done
7157 fi
7158 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7159}
7160
302eda27
NS
7161AT_CAPTURE_FILE([ofctl_monitor0.log])
7162as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7163--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7164
7165set_dns_params vm2
7166src_ip=`ip_to_hex 10 0 0 4`
7167dst_ip=`ip_to_hex 10 0 0 1`
7168dns_reply=1
7169test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7170
7171# NXT_RESUMEs should be 1.
7172OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7173
7174$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7175cat 1.expected | cut -c -48 > expout
7176AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7177# Skipping the IPv4 checksum.
7178cat 1.expected | cut -c 53- > expout
7179AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7180
7181reset_pcap_file hv1-vif1 hv1/vif1
7182reset_pcap_file hv1-vif2 hv1/vif2
7183rm -f 1.expected
7184rm -f 2.expected
7185
7186set_dns_params vm1
7187src_ip=`ip_to_hex 10 0 0 6`
7188dst_ip=`ip_to_hex 10 0 0 1`
7189dns_reply=1
7190test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7191
7192# NXT_RESUMEs should be 2.
7193OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7194
7195$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7196cat 2.expected | cut -c -48 > expout
7197AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7198# Skipping the IPv4 checksum.
7199cat 2.expected | cut -c 53- > expout
7200AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7201
7202reset_pcap_file hv1-vif1 hv1/vif1
7203reset_pcap_file hv1-vif2 hv1/vif2
7204rm -f 1.expected
7205rm -f 2.expected
7206
7207# Clear the query name options for ls1-lp2
7208ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7209
7210set_dns_params vm2
7211src_ip=`ip_to_hex 10 0 0 4`
7212dst_ip=`ip_to_hex 10 0 0 1`
7213dns_reply=0
7214test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7215
7216# NXT_RESUMEs should be 3.
7217OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7218
7219$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7220AT_CHECK([cat 1.packets], [0], [])
7221
7222reset_pcap_file hv1-vif1 hv1/vif1
7223reset_pcap_file hv1-vif2 hv1/vif2
7224rm -f 1.expected
7225rm -f 2.expected
7226
7227# Clear the query name for ls1-lp1
7228# Since ls1 has no query names configued,
7229# ovn-northd should not add the DNS flows.
7230ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7231
7232set_dns_params vm1
7233src_ip=`ip_to_hex 10 0 0 6`
7234dst_ip=`ip_to_hex 10 0 0 1`
7235dns_reply=0
7236test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7237
7238# NXT_RESUMEs should be 3 only.
7239OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7240
7241$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7242AT_CHECK([cat 2.packets], [0], [])
7243
7244reset_pcap_file hv1-vif1 hv1/vif1
7245reset_pcap_file hv1-vif2 hv1/vif2
7246rm -f 1.expected
7247rm -f 2.expected
7248
7249# Test IPv6 (AAAA records) using IPv4 packet.
7250# Add back the DNS options for ls1-lp1.
4f4ac4bb 7251ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
7252
7253set_dns_params vm1_ipv6_only
7254src_ip=`ip_to_hex 10 0 0 6`
7255dst_ip=`ip_to_hex 10 0 0 1`
7256dns_reply=1
7257test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7258
7259# NXT_RESUMEs should be 4.
7260OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7261
7262$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7263cat 2.expected | cut -c -48 > expout
7264AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7265# Skipping the IPv4 checksum.
7266cat 2.expected | cut -c 53- > expout
7267AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7268
7269reset_pcap_file hv1-vif1 hv1/vif1
7270reset_pcap_file hv1-vif2 hv1/vif2
7271rm -f 1.expected
7272rm -f 2.expected
7273
7274# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7275set_dns_params vm1_ipv4_v6
7276src_ip=`ip_to_hex 10 0 0 6`
7277dst_ip=`ip_to_hex 10 0 0 1`
7278dns_reply=1
7279test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7280
7281# NXT_RESUMEs should be 5.
7282OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7283
7284$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7285cat 2.expected | cut -c -48 > expout
7286AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7287# Skipping the IPv4 checksum.
7288cat 2.expected | cut -c 53- > expout
7289AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7290
7291reset_pcap_file hv1-vif1 hv1/vif1
7292reset_pcap_file hv1-vif2 hv1/vif2
7293rm -f 1.expected
7294rm -f 2.expected
7295
7296# Invalid type.
7297set_dns_params vm1_invalid_type
7298src_ip=`ip_to_hex 10 0 0 6`
7299dst_ip=`ip_to_hex 10 0 0 1`
7300dns_reply=0
7301test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7302
7303# NXT_RESUMEs should be 6.
7304OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7305
7306$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7307AT_CHECK([cat 2.packets], [0], [])
7308
7309reset_pcap_file hv1-vif1 hv1/vif1
7310reset_pcap_file hv1-vif2 hv1/vif2
7311rm -f 1.expected
7312rm -f 2.expected
7313
7314# Incomplete DNS packet.
7315set_dns_params vm1_incomplete
7316src_ip=`ip_to_hex 10 0 0 6`
7317dst_ip=`ip_to_hex 10 0 0 1`
7318dns_reply=0
7319test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7320
7321# NXT_RESUMEs should be 7.
7322OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7323
7324$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7325AT_CHECK([cat 2.packets], [0], [])
7326
7327reset_pcap_file hv1-vif1 hv1/vif1
7328reset_pcap_file hv1-vif2 hv1/vif2
7329rm -f 1.expected
7330rm -f 2.expected
7331
7332# Add one more DNS record to the ls1.
7333ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7334
7335set_dns_params vm3
7336src_ip=`ip_to_hex 10 0 0 4`
7337dst_ip=`ip_to_hex 10 0 0 1`
7338dns_reply=1
7339test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7340
7341# NXT_RESUMEs should be 8.
7342OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7343
7344$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7345cat 1.expected | cut -c -48 > expout
7346AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7347# Skipping the IPv4 checksum.
7348cat 1.expected | cut -c 53- > expout
7349AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7350
7351reset_pcap_file hv1-vif1 hv1/vif1
7352reset_pcap_file hv1-vif2 hv1/vif2
7353rm -f 1.expected
7354rm -f 2.expected
7355
f8e79d82
MM
7356# Try DNS query over IPv6
7357set_dns_params vm1
7358src_ip=aef00000000000000000000000000004
7359dst_ip=aef00000000000000000000000000001
7360dns_reply=1
7361test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7362
7363# NXT_RESUMEs should be 9.
7364OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7365
7366$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7367# Skipping the UDP checksum.
7368cat 1.expected | cut -c 1-120,125- > expout
7369AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7370
7371reset_pcap_file hv1-vif1 hv1/vif1
7372reset_pcap_file hv1-vif2 hv1/vif2
7373rm -f 1.expected
7374rm -f 2.expected
7375
302eda27
NS
7376as hv1
7377 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7378OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7379OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7380
7381as ovn-sb
7382OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7383
7384as ovn-nb
7385OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7386
7387as northd
7388OVS_APP_EXIT_AND_WAIT([ovn-northd])
7389
7390as main
7391OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7392OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7393AT_CLEANUP
7394
75f9e007 7395AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7396AT_SKIP_IF([test $HAVE_PYTHON = no])
7397ovn_start
7398
7399net_add n1
7400
7401sim_add hv1
7402as hv1
7403ovs-vsctl add-br br-phys
7404ovn_attach n1 br-phys 192.168.0.1
7405ovs-vsctl -- add-port br-int hv1-vif1 -- \
7406 set interface hv1-vif1 external-ids:iface-id=foo1 \
7407 options:tx_pcap=hv1/vif1-tx.pcap \
7408 options:rxq_pcap=hv1/vif1-rx.pcap \
7409 ofport-request=1
7410
7411sim_add gw1
7412as gw1
7413ovs-vsctl add-br br-phys
7414ovn_attach n1 br-phys 192.168.0.2
7415
7416sim_add gw2
7417as gw2
7418ovs-vsctl add-br br-phys
7419ovn_attach n1 br-phys 192.168.0.4
7420
7421sim_add ext1
7422as ext1
7423ovs-vsctl add-br br-phys
7424ovn_attach n1 br-phys 192.168.0.3
7425ovs-vsctl -- add-port br-int ext1-vif1 -- \
7426 set interface ext1-vif1 external-ids:iface-id=outside1 \
7427 options:tx_pcap=ext1/vif1-tx.pcap \
7428 options:rxq_pcap=ext1/vif1-rx.pcap \
7429 ofport-request=1
7430
7431# Pre-populate the hypervisors' ARP tables so that we don't lose any
7432# packets for ARP resolution (native tunneling doesn't queue packets
7433# for ARP resolution).
74868f2c 7434OVN_POPULATE_ARP
1da17a0b 7435
7436ovn-nbctl create Logical_Router name=R1
7437
7438ovn-nbctl ls-add foo
7439ovn-nbctl ls-add alice
7440ovn-nbctl ls-add outside
7441
7442# Connect foo to R1
7443ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7444ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7445 type=router options:router-port=foo \
7446 -- lsp-set-addresses rp-foo router
7447
7448# Connect alice to R1 as distributed router gateway port on gw1
7449ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7450
7451ovn-nbctl \
7452 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7453 chassis_name=gw1 \
7454 priority=20 -- \
7455 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7456 chassis_name=gw2 \
7457 priority=10 -- \
7458 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7459
7460ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7461 type=router options:router-port=alice \
7462 -- lsp-set-addresses rp-alice router
7463
7464# Create logical port foo1 in foo
7465ovn-nbctl lsp-add foo foo1 \
7466-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7467
7468# Create logical port outside1 in outside
7469ovn-nbctl lsp-add outside outside1 \
7470-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7471
7472# Create localnet port in alice
7473ovn-nbctl lsp-add alice ln-alice
7474ovn-nbctl lsp-set-addresses ln-alice unknown
7475ovn-nbctl lsp-set-type ln-alice localnet
7476ovn-nbctl lsp-set-options ln-alice network_name=phys
7477
7478# Create localnet port in outside
7479ovn-nbctl lsp-add outside ln-outside
7480ovn-nbctl lsp-set-addresses ln-outside unknown
7481ovn-nbctl lsp-set-type ln-outside localnet
7482ovn-nbctl lsp-set-options ln-outside network_name=phys
7483
7484# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7485# mapping to the external network, is the one generating packets
7486as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7487as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7488as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7489
7490AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7491
7492# Allow some time for ovn-northd and ovn-controller to catch up.
7493# XXX This should be more systematic.
7494sleep 2
7495
7496ip_to_hex() {
7497 printf "%02x%02x%02x%02x" "$@"
7498}
7499
7500reset_pcap_file() {
7501 local iface=$1
7502 local pcap_file=$2
7503 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7504options:rxq_pcap=dummy-rx.pcap
7505 rm -f ${pcap_file}*.pcap
7506 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7507options:rxq_pcap=${pcap_file}-rx.pcap
7508}
7509
7510test_ip_packet()
7511{
7512 local active_gw=$1
7513 local backup_gw=$2
7514
7515 # Send ip packet between foo1 and outside1
7516 src_mac="f00000010203" # foo1 mac
7517 dst_mac="000001010203" # rp-foo mac (internal router leg)
7518 src_ip=`ip_to_hex 192 168 1 2`
7519 dst_ip=`ip_to_hex 172 16 1 3`
7520 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7521
7522 # ARP request packet to expect at outside1
7523 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7524
7525 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7526
7527 # Send ARP reply from outside1 back to the router
7528 # XXX: note, we could avoid this if we plug this port into a netns
7529 # and setup the IP address into the port, so the kernel would simply reply
7530 src_mac="000002010203"
7531 reply_mac="f00000010204"
7532 dst_ip=`ip_to_hex 172 16 1 3`
7533 src_ip=`ip_to_hex 172 16 1 1`
7534 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7535
7536 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7537
86c9d79a
NS
7538 OVS_WAIT_UNTIL([
7539 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7540grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7541 ])
7542
1da17a0b 7543 # Packet to Expect at ext1 chassis, outside1 port
7544 src_mac="000002010203"
7545 dst_mac="f00000010204"
7546 src_ip=`ip_to_hex 192 168 1 2`
7547 dst_ip=`ip_to_hex 172 16 1 3`
7548 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7549 echo $expected > ext1-vif1.expected
7550
7551 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7552 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7553 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7554
7555 # Resend packet from foo1 to outside1
7556 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7557
7558 sleep 1
7559
7560 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7561 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7562 AT_CHECK([grep $expected packets | sort], [0], [expout])
7563 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7564 AT_CHECK([grep $expected packets | sort], [0], [])
7565}
7566
7567test_ip_packet gw1 gw2
7568
75f9e007
GZ
7569ovn-nbctl --timeout=3 --wait=hv \
7570 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7571 chassis_name=gw1 \
7572 priority=10 -- \
7573 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7574 chassis_name=gw2 \
7575 priority=20 -- \
7576 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7577
7578test_ip_packet gw2 gw1
7579
7580OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7581AT_CLEANUP
7582
7583AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7584AT_SKIP_IF([test $HAVE_PYTHON = no])
7585ovn_start
7586
7587net_add n1
7588
7589sim_add hv1
7590as hv1
7591ovs-vsctl add-br br-phys
7592ovn_attach n1 br-phys 192.168.0.1
7593ovs-vsctl -- add-port br-int hv1-vif1 -- \
7594 set interface hv1-vif1 external-ids:iface-id=foo1 \
7595 options:tx_pcap=hv1/vif1-tx.pcap \
7596 options:rxq_pcap=hv1/vif1-rx.pcap \
7597 ofport-request=1
7598
7599sim_add gw1
7600as gw1
7601ovs-vsctl add-br br-phys
7602ovn_attach n1 br-phys 192.168.0.2
7603
7604sim_add gw2
7605as gw2
7606ovs-vsctl add-br br-phys
7607ovn_attach n1 br-phys 192.168.0.4
7608
7609sim_add ext1
7610as ext1
7611ovs-vsctl add-br br-phys
7612ovn_attach n1 br-phys 192.168.0.3
7613ovs-vsctl -- add-port br-int ext1-vif1 -- \
7614 set interface ext1-vif1 external-ids:iface-id=outside1 \
7615 options:tx_pcap=ext1/vif1-tx.pcap \
7616 options:rxq_pcap=ext1/vif1-rx.pcap \
7617 ofport-request=1
7618
7619# Pre-populate the hypervisors' ARP tables so that we don't lose any
7620# packets for ARP resolution (native tunneling doesn't queue packets
7621# for ARP resolution).
74868f2c 7622OVN_POPULATE_ARP
75f9e007
GZ
7623
7624ovn-nbctl create Logical_Router name=R0
7625ovn-nbctl create Logical_Router name=R1
7626
7627ovn-nbctl ls-add foo
7628ovn-nbctl ls-add join
7629ovn-nbctl ls-add alice
7630ovn-nbctl ls-add outside
7631
7632#Connect foo to R0
7633ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7634ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7635 type=router options:router-port=R0-foo \
7636 -- lsp-set-addresses foo-R0 router
7637
7638#Connect R0 to join
7639ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7640ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7641 type=router options:router-port=R0-join \
7642 -- lsp-set-addresses join-R0 router
7643
7644#Connect join to R1
7645ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7646ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7647 type=router options:router-port=R1-join \
7648 -- lsp-set-addresses join-R1 router
7649
7650#add route rules
7651ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7652ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7653
7654# Connect alice to R1 as distributed router gateway port on gw1
7655ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7656
7657ovn-nbctl \
7658 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7659 chassis_name=gw1 \
7660 priority=20 -- \
7661 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7662 chassis_name=gw2 \
7663 priority=10 -- \
7664 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7665
7666ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7667 type=router options:router-port=alice \
7668 -- lsp-set-addresses rp-alice router
7669
7670# Create logical port foo1 in foo
7671ovn-nbctl lsp-add foo foo1 \
7672-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7673
7674# Create logical port outside1 in outside
7675ovn-nbctl lsp-add outside outside1 \
7676-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7677
7678# Create localnet port in alice
7679ovn-nbctl lsp-add alice ln-alice
7680ovn-nbctl lsp-set-addresses ln-alice unknown
7681ovn-nbctl lsp-set-type ln-alice localnet
7682ovn-nbctl lsp-set-options ln-alice network_name=phys
7683
7684# Create localnet port in outside
7685ovn-nbctl lsp-add outside ln-outside
7686ovn-nbctl lsp-set-addresses ln-outside unknown
7687ovn-nbctl lsp-set-type ln-outside localnet
7688ovn-nbctl lsp-set-options ln-outside network_name=phys
7689
7690# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7691# mapping to the external network, is the one generating packets
7692as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7693as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7694as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7695
7696AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7697
7698# Allow some time for ovn-northd and ovn-controller to catch up.
7699# XXX This should be more systematic.
7700sleep 2
7701
7702ip_to_hex() {
7703 printf "%02x%02x%02x%02x" "$@"
7704}
7705
7706reset_pcap_file() {
7707 local iface=$1
7708 local pcap_file=$2
7709 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7710options:rxq_pcap=dummy-rx.pcap
7711 rm -f ${pcap_file}*.pcap
7712 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7713options:rxq_pcap=${pcap_file}-rx.pcap
7714}
7715
7716test_ip_packet()
7717{
7718 local active_gw=$1
7719 local backup_gw=$2
7720
7721 # Send ip packet between foo1 and outside1
7722 src_mac="f00000010203" # foo1 mac
7723 dst_mac="000001010203" # foo-R0 mac (internal router leg)
7724 src_ip=`ip_to_hex 192 168 1 2`
7725 dst_ip=`ip_to_hex 172 16 1 3`
7726 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7727
7728 # ARP request packet to expect at outside1
7729 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7730
7731 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7732
7733 # Send ARP reply from outside1 back to the router
7734 # XXX: note, we could avoid this if we plug this port into a netns
7735 # and setup the IP address into the port, so the kernel would simply reply
7736 src_mac="000002010203"
7737 reply_mac="f00000010204"
7738 dst_ip=`ip_to_hex 172 16 1 3`
7739 src_ip=`ip_to_hex 172 16 1 1`
7740 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7741
7742 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7743
86c9d79a
NS
7744 OVS_WAIT_UNTIL([
7745 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7746grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7747 ])
7748
75f9e007
GZ
7749 # Packet to Expect at ext1 chassis, outside1 port
7750 src_mac="000002010203"
7751 dst_mac="f00000010204"
7752 src_ip=`ip_to_hex 192 168 1 2`
7753 dst_ip=`ip_to_hex 172 16 1 3`
7754 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7755 echo $expected > ext1-vif1.expected
7756
7757 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7758 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7759 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7760
7761 # Resend packet from foo1 to outside1
7762 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7763
7764 sleep 1
7765
7766 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7767 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7768 AT_CHECK([grep $expected packets | sort], [0], [expout])
7769 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7770 AT_CHECK([grep $expected packets | sort], [0], [])
7771}
7772
7773test_ip_packet gw1 gw2
7774
8e1d9349 7775ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 7776 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7777 chassis_name=gw1 \
7778 priority=10 -- \
7779 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7780 chassis_name=gw2 \
7781 priority=20 -- \
7782 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7783
7784test_ip_packet gw2 gw1
7785
7786OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7787AT_CLEANUP
7788
41a15b71
MS
7789AT_SETUP([ovn -- 1 LR with distributed router gateway port])
7790AT_SKIP_IF([test $HAVE_PYTHON = no])
7791ovn_start
7792
7793# Logical network:
7794# One LR R1 that has switches foo (192.168.1.0/24) and
7795# alice (172.16.1.0/24) connected to it. The logical port
7796# between R1 and alice has a "redirect-chassis" specified,
7797# i.e. it is the distributed router gateway port.
7798# Switch alice also has a localnet port defined.
7799# An additional switch outside has a localnet port and the
7800# same subnet as alice (172.16.1.0/24).
7801
7802# Physical network:
7803# Three hypervisors hv[123].
7804# hv1 hosts vif foo1.
7805# hv2 is the "redirect-chassis" that hosts the distributed
7806# router gateway port.
7807# hv3 hosts vif outside1.
7808# In order to show that connectivity works only through hv2,
7809# an initial round of tests is run without any bridge-mapping
7810# defined for the localnet on hv2. These tests are expected
7811# to fail.
7812# Subsequent tests are run after defining the bridge-mapping
7813# for the localnet on hv2. These tests are expected to succeed.
7814
7815# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 7816# to logical ports.
41a15b71
MS
7817net_add n1
7818
7819sim_add hv1
7820as hv1
7821ovs-vsctl add-br br-phys
7822ovn_attach n1 br-phys 192.168.0.1
7823ovs-vsctl -- add-port br-int hv1-vif1 -- \
7824 set interface hv1-vif1 external-ids:iface-id=foo1 \
7825 options:tx_pcap=hv1/vif1-tx.pcap \
7826 options:rxq_pcap=hv1/vif1-rx.pcap \
7827 ofport-request=1
7828
7829sim_add hv2
7830as hv2
7831ovs-vsctl add-br br-phys
7832ovn_attach n1 br-phys 192.168.0.2
7833
7834sim_add hv3
7835as hv3
7836ovs-vsctl add-br br-phys
7837ovn_attach n1 br-phys 192.168.0.3
7838ovs-vsctl -- add-port br-int hv3-vif1 -- \
7839 set interface hv3-vif1 external-ids:iface-id=outside1 \
7840 options:tx_pcap=hv3/vif1-tx.pcap \
7841 options:rxq_pcap=hv3/vif1-rx.pcap \
7842 ofport-request=1
7843
7844# Pre-populate the hypervisors' ARP tables so that we don't lose any
7845# packets for ARP resolution (native tunneling doesn't queue packets
7846# for ARP resolution).
74868f2c 7847OVN_POPULATE_ARP
41a15b71
MS
7848
7849ovn-nbctl create Logical_Router name=R1
7850
7851ovn-nbctl ls-add foo
7852ovn-nbctl ls-add alice
7853ovn-nbctl ls-add outside
7854
7855# Connect foo to R1
7856ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7857ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7858 type=router options:router-port=foo \
7859 -- lsp-set-addresses rp-foo router
7860
7861# Connect alice to R1 as distributed router gateway port on hv2
7862ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
7863 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
7864ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7865 type=router options:router-port=alice \
7866 -- lsp-set-addresses rp-alice router
7867
7868# Create logical port foo1 in foo
7869ovn-nbctl lsp-add foo foo1 \
7870-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7871
7872# Create logical port outside1 in outside
7873ovn-nbctl lsp-add outside outside1 \
7874-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7875
7876# Create localnet port in alice
7877ovn-nbctl lsp-add alice ln-alice
7878ovn-nbctl lsp-set-addresses ln-alice unknown
7879ovn-nbctl lsp-set-type ln-alice localnet
7880ovn-nbctl lsp-set-options ln-alice network_name=phys
7881
7882# Create localnet port in outside
7883ovn-nbctl lsp-add outside ln-outside
7884ovn-nbctl lsp-set-addresses ln-outside unknown
7885ovn-nbctl lsp-set-type ln-outside localnet
7886ovn-nbctl lsp-set-options ln-outside network_name=phys
7887
7888# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
7889as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7890as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7891
7892
7893# Allow some time for ovn-northd and ovn-controller to catch up.
7894# XXX This should be more systematic.
7895sleep 2
7896
7897echo "---------NB dump-----"
7898ovn-nbctl show
7899echo "---------------------"
7900ovn-nbctl list logical_router
7901echo "---------------------"
7902ovn-nbctl list logical_router_port
7903echo "---------------------"
7904
7905echo "---------SB dump-----"
7906ovn-sbctl list datapath_binding
7907echo "---------------------"
7908ovn-sbctl list port_binding
7909echo "---------------------"
7910ovn-sbctl dump-flows
7911echo "---------------------"
7912ovn-sbctl list chassis
7913ovn-sbctl list encap
1da17a0b 7914echo "------ Gateway_Chassis dump (SBDB) -------"
7915ovn-sbctl list Gateway_Chassis
7916echo "------ Port_Binding chassisredirect -------"
7917ovn-sbctl find Port_Binding type=chassisredirect
7918echo "-------------------------------------------"
41a15b71
MS
7919
7920echo "------ hv1 dump ----------"
7921as hv1 ovs-ofctl show br-int
7922as hv1 ovs-ofctl dump-flows br-int
7923echo "------ hv2 dump ----------"
7924as hv2 ovs-ofctl show br-int
7925as hv2 ovs-ofctl dump-flows br-int
7926echo "------ hv3 dump ----------"
7927as hv3 ovs-ofctl show br-int
7928as hv3 ovs-ofctl dump-flows br-int
7929echo "--------------------------"
7930
1da17a0b 7931
41a15b71
MS
7932# Check that redirect mapping is programmed only on hv2
7933AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7934])
7935AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
7936])
7937# Check that hv1 sends chassisredirect port traffic to hv2
7938AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
7939])
7940AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
7941])
7942# Check that arp reply on distributed gateway port is only programmed on hv2
7943AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [0
7944])
7945AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep =0x2,metadata=0x1 | wc -l], [0], [1
7946])
7947
7948
7949ip_to_hex() {
7950 printf "%02x%02x%02x%02x" "$@"
7951}
7952
7953
7954: > hv2-vif1.expected
7955: > hv3-vif1.expected
7956
7957# test_arp INPORT SHA SPA TPA [REPLY_HA]
7958#
7959# Causes a packet to be received on INPORT. The packet is an ARP
7960# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
7961# it should be the hardware address of the target to expect to receive in an
7962# ARP reply; otherwise no reply is expected.
7963#
7964# INPORT is an logical switch port number, e.g. 11 for vif11.
7965# SHA and REPLY_HA are each 12 hex digits.
7966# SPA and TPA are each 8 hex digits.
7967test_arp() {
7968 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
7969 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
7970 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
7971
7972 if test X$reply_ha != X; then
7973 # Expect to receive the reply, if any.
7974 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
7975 echo $reply >> hv${hv}-vif$inport.expected
7976 fi
7977}
7978
7979rtr_ip=$(ip_to_hex 172 16 1 1)
7980foo_ip=$(ip_to_hex 192 168 1 2)
7981outside_ip=$(ip_to_hex 172 16 1 3)
7982
7983echo $rtr_ip
7984echo $foo_ip
7985echo $outside_ip
7986
7987# ARP for router IP address from outside1, no response expected
7988test_arp 3 1 f00000010204 $outside_ip $rtr_ip
7989
7990# Now check the packets actually received against the ones expected.
7991OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
7992
7993# Send ip packet between foo1 and outside1
7994src_mac="f00000010203"
7995dst_mac="000001010203"
7996src_ip=`ip_to_hex 192 168 1 2`
7997dst_ip=`ip_to_hex 172 16 1 3`
7998packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7999
8000# Now check the packets actually received against the ones expected.
8001OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8002
8003# Now add bridge-mappings on hv2, which should make everything work
8004as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8005
8006# Allow some time for ovn-northd and ovn-controller to catch up.
8007# XXX This should be more systematic.
8008sleep 2
8009
8010# ARP for router IP address from outside1
8011test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8012
8013# Now check the packets actually received against the ones expected.
8014OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8015
8016# Send ip packet between foo1 and outside1
8017src_mac="f00000010203"
8018dst_mac="000001010203"
8019src_ip=`ip_to_hex 192 168 1 2`
8020dst_ip=`ip_to_hex 172 16 1 3`
8021packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8022
8023# ARP request packet to expect at outside1
8024src_mac="000002010203"
8025src_ip=`ip_to_hex 172 16 1 1`
8026arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8027
8028as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8029
8030echo $arp_request >> hv3-vif1.expected
8031OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8032
8033# Send ARP reply from outside1 back to the router
8034reply_mac="f00000010204"
8035arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8036
8037as hv3 ovs-appctl netdev-dummy/receive hv3-vif1 $arp_reply
8038
8039# Allow some time for ovn-northd and ovn-controller to catch up.
8040# XXX This should be more systematic.
8041sleep 1
8042
8043# Packet to Expect at outside1
8044src_mac="000002010203"
8045dst_mac="f00000010204"
8046src_ip=`ip_to_hex 192 168 1 2`
8047dst_ip=`ip_to_hex 172 16 1 3`
8048expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8049
8050# Resend packet from foo1 to outside1
8051as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8052
8053echo "------ hv1 dump ----------"
8054as hv1 ovs-ofctl show br-int
8055as hv1 ovs-ofctl dump-flows br-int
8056echo "------ hv2 dump ----------"
8057as hv2 ovs-ofctl show br-int
8058as hv2 ovs-ofctl dump-flows br-int
8059echo "------ hv3 dump ----------"
8060as hv3 ovs-ofctl show br-int
8061as hv3 ovs-ofctl dump-flows br-int
8062echo "----------------------------"
8063
8064echo $expected >> hv3-vif1.expected
8065OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8066
8067#Check ovn-trace over "chassisredirect" port
8068AT_CAPTURE_FILE([trace])
8069ovn_trace () {
8070 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8071}
8072
8073echo 'ip.ttl--;' > expout
8074echo 'eth.src = 00:00:02:01:02:03;' >> expout
8075echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8076echo 'output("ln-alice");' >> expout
8077AT_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])
8078
8079# Create logical port alice1 in alice on hv1
8080as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8081 set interface hv1-vif2 external-ids:iface-id=alice1 \
8082 options:tx_pcap=hv1/vif2-tx.pcap \
8083 options:rxq_pcap=hv1/vif2-rx.pcap \
8084 ofport-request=1
8085
8086ovn-nbctl lsp-add alice alice1 \
8087-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8088
8089# Create logical port foo2 in foo on hv2
8090as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8091 set interface hv2-vif1 external-ids:iface-id=foo2 \
8092 options:tx_pcap=hv2/vif1-tx.pcap \
8093 options:rxq_pcap=hv2/vif1-rx.pcap \
8094 ofport-request=1
8095
8096ovn-nbctl lsp-add foo foo2 \
8097-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8098
8099# Allow some time for ovn-northd and ovn-controller to catch up.
8100# XXX This should be more systematic.
8101sleep 1
8102
8103: > hv1-vif2.expected
8104
8105# Send ip packet between alice1 and foo2
8106src_mac="f00000010205"
8107dst_mac="000002010203"
8108src_ip=`ip_to_hex 172 16 1 4`
8109dst_ip=`ip_to_hex 192 168 1 3`
8110packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8111
8112as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8113
8114# Packet to Expect at foo2
8115src_mac="000001010203"
8116dst_mac="f00000010206"
8117src_ip=`ip_to_hex 172 16 1 4`
8118dst_ip=`ip_to_hex 192 168 1 3`
8119expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8120
8121echo $expected >> hv2-vif1.expected
f5f64552 8122OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 8123
0d31e5be 8124AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 8125])
8126
8e1d9349 8127ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 8128
0d31e5be 8129AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 8130])
8131
41a15b71
MS
8132OVN_CLEANUP([hv1],[hv2],[hv3])
8133
8134AT_CLEANUP
26b9e08d
MS
8135
8136AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8137AT_SKIP_IF([test $HAVE_PYTHON = no])
8138ovn_start
8139# Create logical switches
8140ovn-nbctl ls-add ls0
8141ovn-nbctl ls-add ls1
8142# Create distributed router
8143ovn-nbctl create Logical_Router name=lr0
8144# Add distributed gateway port to distributed router
8145ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8146 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8147ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8148 type=router options:router-port=lrp0 addresses="router"
8149# Add router port to ls1
8150ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8151ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8152 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
8153# Add logical ports for NAT rules
8154ovn-nbctl lsp-add ls1 foo1 \
8155-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8156ovn-nbctl lsp-add ls1 foo2 \
8157-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
8158# Add nat-addresses option
8159ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8160# Add NAT rules
8161AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8162AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8163AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.3 10.0.0.3 foo1 f0:00:00:00:00:03])
f40c5588 8164AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat_and_snat 192.168.0.4 10.0.0.4 foo2 f0:00:00:00:00:04])
26b9e08d
MS
8165
8166net_add n1
8167sim_add hv1
8168as hv1
8169ovs-vsctl add-br br-phys
8170ovn_attach n1 br-phys 192.168.0.1
8171
8172AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8173AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
8174
8175sim_add hv2
8176as hv2
8177ovs-vsctl add-br br-phys
8178ovn_attach n1 br-phys 192.168.0.2
8179# Initially test with no bridge-mapping on hv2, expect to receive no packets
8180
f40c5588
MS
8181sim_add hv3
8182as hv3
8183ovs-vsctl add-br br-phys
8184ovn_attach n1 br-phys 192.168.0.3
8185# Initially test with no bridge-mapping on hv3
8186
26b9e08d
MS
8187# Create a localnet port.
8188AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8189AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8190AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8191AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8192
8193# Allow some time for ovn-northd and ovn-controller to catch up.
8194# XXX This should be more systematic.
8195sleep 2
8196
8197# Expect no packets when hv2 bridge-mapping is not present
8198: > packets
8199OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8200
8201# Add bridge-mapping on hv2
f40c5588 8202AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8203
8204# Wait for packets to be received.
8205OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8206trim_zeros() {
8207 sed 's/\(00\)\{1,\}$//'
8208}
8209$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8210expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8211echo $expected > expout
8212expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8213echo $expected >> expout
8214AT_CHECK([sort packets], [0], [expout])
f40c5588 8215sort packets | cat
26b9e08d 8216
f40c5588
MS
8217# Temporarily remove nat-addresses option to avoid race conditions
8218# due to GARP backoff
8219ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8220
8221reset_pcap_file() {
8222 local iface=$1
8223 local pcap_file=$2
8224 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8225options:rxq_pcap=dummy-rx.pcap
8226 rm -f ${pcap_file}*.pcap
8227 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8228options:rxq_pcap=${pcap_file}-rx.pcap
8229}
8230
8231as hv1 reset_pcap_file snoopvif hv1/snoopvif
8232
8233# Add OVS ports for foo1 and foo2 on hv3
8234ovs-vsctl -- add-port br-int hv3-vif1 -- \
8235 set interface hv3-vif1 external-ids:iface-id=foo1 \
8236 ofport-request=1
8237ovs-vsctl -- add-port br-int hv3-vif2 -- \
8238 set interface hv3-vif2 external-ids:iface-id=foo2 \
8239 ofport-request=2
8240
8241# Add bridge-mapping on hv3
8242AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8243
8244# Re-add nat-addresses option
8245ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8246
8247# Wait for packets to be received.
8248OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8249trim_zeros() {
8250 sed 's/\(00\)\{1,\}$//'
8251}
8252
8253$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8254expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8255echo $expected >> expout
8256expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8257echo $expected >> expout
8258AT_CHECK([sort packets], [0], [expout])
8259sort packets | cat
8260
8261OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8262
8263AT_CLEANUP
6b785fd8 8264
4364646c
ZKL
8265AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8266AT_KEYWORDS([ovn-nd_ra])
8267AT_SKIP_IF([test $HAVE_PYTHON = no])
8268ovn_start
8269
8270# In this test case we create 1 lswitch with 3 VIF ports attached,
8271# and a lrouter connected to the lswitch.
8272# We generate the Router solicitation packet and verify the Router Advertisement
8273# reply packet from the ovn-controller.
8274
8275# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8276# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8277# 'slaac' to allow lrp0 send RA for SLAAC mode.
8278ovn-nbctl ls-add lsw0
8279ovn-nbctl lr-add lr0
8280ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8281ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8282ovn-nbctl \
8283 -- lsp-add lsw0 lsp0 \
8284 -- set Logical_Switch_Port lsp0 type=router \
8285 options:router-port=lrp0 \
8286 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8287net_add n1
8288sim_add hv1
8289as hv1
8290ovs-vsctl add-br br-phys
8291ovn_attach n1 br-phys 192.168.0.2
8292
8293ovn-nbctl lsp-add lsw0 lp1
8294ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8295ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8296
8297ovn-nbctl lsp-add lsw0 lp2
8298ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8299ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8300
8301ovn-nbctl lsp-add lsw0 lp3
8302ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8303ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8304
8305# Add ACL rule for ICMPv6 on lsw0
8306ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8307ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8308ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8309ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8310
8311ovs-vsctl -- add-port br-int hv1-vif1 -- \
8312 set interface hv1-vif1 external-ids:iface-id=lp1 \
8313 options:tx_pcap=hv1/vif1-tx.pcap \
8314 options:rxq_pcap=hv1/vif1-rx.pcap \
8315 ofport-request=1
8316
8317ovs-vsctl -- add-port br-int hv1-vif2 -- \
8318 set interface hv1-vif2 external-ids:iface-id=lp2 \
8319 options:tx_pcap=hv1/vif2-tx.pcap \
8320 options:rxq_pcap=hv1/vif2-rx.pcap \
8321 ofport-request=2
8322
8323ovs-vsctl -- add-port br-int hv1-vif3 -- \
8324 set interface hv1-vif3 external-ids:iface-id=lp3 \
8325 options:tx_pcap=hv1/vif3-tx.pcap \
8326 options:rxq_pcap=hv1/vif3-rx.pcap \
8327 ofport-request=3
8328
8329# Allow some time for ovn-northd and ovn-controller to catch up.
8330# XXX This should be more systematic.
8331sleep 1
8332
8333reset_pcap_file() {
8334 local iface=$1
8335 local pcap_file=$2
8336 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8337options:rxq_pcap=dummy-rx.pcap
8338 rm -f ${pcap_file}*.pcap
8339 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8340options:rxq_pcap=${pcap_file}-rx.pcap
8341}
8342
8343# Make sure that ovn-controller has installed the corresponding OF Flow.
8344OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8345
8346# This shell function sends a Router Solicitation packet.
8347# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8348test_ipv6_ra() {
8349 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8350 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8351
8352 local len=24
8353 local mtu_opt=""
8354 if test $mtu != 0; then
8355 len=`expr $len + 8`
8356 mtu_opt=05010000${mtu}
8357 fi
8358
8359 if test ${#prefix_opt} != 0; then
8360 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8361 len=`expr $len + ${#prefix_opt} / 2`
8362 fi
8363
8364 len=$(printf "%x" $len)
8365 local lrp_mac=fa163e000001
8366 local lrp_lla=fe80000000000000f8163efffe000001
8367 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8368 echo $reply >> $inport.expected
8369
8370 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8371}
8372
8373AT_CAPTURE_FILE([ofctl_monitor0.log])
8374as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8375--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8376
8377# MTU is not set and the address mode is set to slaac
8378addr_mode=00
8379default_prefix_option_config=030440c0ffffffffffffffff00000000
8380src_mac=fa163e000002
8381src_lla=fe80000000000000f8163efffe000002
8382test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8383
8384# NXT_RESUME should be 1.
8385OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8386
8387$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8388
8389cat 1.expected | cut -c -112 > expout
8390AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8391
8392# Skipping the ICMPv6 checksum.
8393cat 1.expected | cut -c 117- > expout
8394AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8395
8396rm -f *.expected
8397reset_pcap_file hv1-vif1 hv1/vif1
8398reset_pcap_file hv1-vif2 hv1/vif2
8399reset_pcap_file hv1-vif3 hv1/vif3
8400
8401# Set the MTU to 1500
8402ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8403
8404# Make sure that ovn-controller has installed the corresponding OF Flow.
8405OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8406
8407addr_mode=00
8408default_prefix_option_config=030440c0ffffffffffffffff00000000
8409src_mac=fa163e000003
8410src_lla=fe80000000000000f8163efffe000003
8411mtu=000005dc
8412
8413test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8414
8415# NXT_RESUME should be 2.
8416OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8417
8418$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8419
8420cat 2.expected | cut -c -112 > expout
8421AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8422
8423# Skipping the ICMPv6 checksum.
8424cat 2.expected | cut -c 117- > expout
8425AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8426
8427rm -f *.expected
8428reset_pcap_file hv1-vif1 hv1/vif1
8429reset_pcap_file hv1-vif2 hv1/vif2
8430reset_pcap_file hv1-vif3 hv1/vif3
8431
8432# Set the address mode to dhcpv6_stateful
8433ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8434# Make sure that ovn-controller has installed the corresponding OF Flow.
8435OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8436
8437addr_mode=80
8438default_prefix_option_config=""
8439src_mac=fa163e000004
8440src_lla=fe80000000000000f8163efffe000004
8441mtu=000005dc
8442
8443test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8444
8445# NXT_RESUME should be 3.
8446OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8447
8448$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8449
8450cat 3.expected | cut -c -112 > expout
8451AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8452
8453# Skipping the ICMPv6 checksum.
8454cat 3.expected | cut -c 117- > expout
8455AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8456
8457rm -f *.expected
8458reset_pcap_file hv1-vif1 hv1/vif1
8459reset_pcap_file hv1-vif2 hv1/vif2
8460reset_pcap_file hv1-vif3 hv1/vif3
8461
8462# Set the address mode to dhcpv6_stateless
8463ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8464# Make sure that ovn-controller has installed the corresponding OF Flow.
8465OVS_WAIT_UNTIL([test 1 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8466
8467addr_mode=40
8468default_prefix_option_config=030440c0ffffffffffffffff00000000
8469src_mac=fa163e000002
8470src_lla=fe80000000000000f8163efffe000002
8471mtu=000005dc
8472
8473test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8474
8475# NXT_RESUME should be 4.
8476OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8477
8478$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8479
8480cat 1.expected | cut -c -112 > expout
8481AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8482
8483# Skipping the ICMPv6 checksum.
8484cat 1.expected | cut -c 117- > expout
8485AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8486
8487rm -f *.expected
8488reset_pcap_file hv1-vif1 hv1/vif1
8489reset_pcap_file hv1-vif2 hv1/vif2
8490reset_pcap_file hv1-vif3 hv1/vif3
8491
8492# Set the address mode to invalid.
8493ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8494# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8495OVS_WAIT_UNTIL([test 0 = `as hv1 ovs-ofctl dump-flows br-int | grep -c "ipv6_dst=ff02::2,nw_ttl=255,icmp_type=133,icmp_code=0"`])
8496
8497addr_mode=40
8498default_prefix_option_config=""
8499src_mac=fa163e000002
8500src_lla=fe80000000000000f8163efffe000002
8501mtu=000005dc
8502
8503test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8504
8505# NXT_RESUME should be 4 only.
8506OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8507
8508$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8509AT_CHECK([cat 1.packets], [0], [])
8510
8511OVN_CLEANUP([hv1])
8512AT_CLEANUP
8513
6b785fd8
GS
8514AT_SETUP([ovn -- /32 router IP address])
8515AT_SKIP_IF([test $HAVE_PYTHON = no])
8516ovn_start
8517
8518# Logical network:
8519# 2 LS 'foo' and 'alice' connected via router R1.
8520# R1 connects to 'alice' with a /32 IP address. We use static routes and
8521# nexthop to push traffic to a logical port in switch 'alice'
8522
8523ovn-nbctl lr-add R1
8524
8525ovn-nbctl ls-add foo
8526ovn-nbctl ls-add alice
8527
8528# Connect foo to R1
8529ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8530ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8531 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8532
8533# Connect alice to R1.
8534ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8535ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8536 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8537
8538# Create logical port foo1 in foo
8539ovn-nbctl lsp-add foo foo1 \
8540-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8541
8542# Create logical port alice1 in alice
8543ovn-nbctl lsp-add alice alice1 \
8544-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8545
8546#install default route in R1 to use alice1's IP address as nexthop
8547ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8548
8549# Create two hypervisor and create OVS ports corresponding to logical ports.
8550net_add n1
8551
8552sim_add hv1
8553as hv1
8554ovs-vsctl add-br br-phys
8555ovn_attach n1 br-phys 192.168.0.1
8556ovs-vsctl -- add-port br-int hv1-vif1 -- \
8557 set interface hv1-vif1 external-ids:iface-id=foo1 \
8558 options:tx_pcap=hv1/vif1-tx.pcap \
8559 options:rxq_pcap=hv1/vif1-rx.pcap \
8560 ofport-request=1
8561
8562sim_add hv2
8563as hv2
8564ovs-vsctl add-br br-phys
8565ovn_attach n1 br-phys 192.168.0.2
8566ovs-vsctl -- add-port br-int hv2-vif1 -- \
8567 set interface hv2-vif1 external-ids:iface-id=alice1 \
8568 options:tx_pcap=hv2/vif1-tx.pcap \
8569 options:rxq_pcap=hv2/vif1-rx.pcap \
8570 ofport-request=1
8571
8572
8573# Pre-populate the hypervisors' ARP tables so that we don't lose any
8574# packets for ARP resolution (native tunneling doesn't queue packets
8575# for ARP resolution).
74868f2c 8576OVN_POPULATE_ARP
6b785fd8
GS
8577
8578# Allow some time for ovn-northd and ovn-controller to catch up.
8579# XXX This should be more systematic.
8580sleep 1
8581
8582ip_to_hex() {
8583 printf "%02x%02x%02x%02x" "$@"
8584}
8585
8586# Send ip packets between foo1 and alice1
8587src_mac="f00000010203"
8588dst_mac="000000010203"
8589src_ip=`ip_to_hex 192 168 1 2`
8590dst_ip=`ip_to_hex 10 0 0 2`
8591packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8592
8593# Send the first packet to trigger a ARP response and population of
8594# mac_bindings table.
8595as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8596OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 8597ovn-nbctl --wait=hv sync
6b785fd8
GS
8598# Send the second packet to reach the destination.
8599as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8600
8601# Packet to Expect at 'alice1'
8602src_mac="000000010204"
8603dst_mac="f00000010204"
8604src_ip=`ip_to_hex 192 168 1 2`
8605dst_ip=`ip_to_hex 10 0 0 2`
8606echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8607
8608OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8609
8610OVN_CLEANUP([hv1],[hv2])
8611
8612AT_CLEANUP
2a38ef45
DA
8613
8614AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8615AT_SKIP_IF([test $HAVE_PYTHON = no])
8616ovn_start
8617
8618ovn-nbctl ls-add ls1
8619
8620# Add localport to the switch
8621ovn-nbctl lsp-add ls1 lp01
8622ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8623ovn-nbctl lsp-set-type lp01 localport
8624
8625net_add n1
8626
8627for i in 1 2; do
8628 sim_add hv$i
8629 as hv$i
8630 ovs-vsctl add-br br-phys
8631 ovn_attach n1 br-phys 192.168.0.$i
8632 ovs-vsctl add-port br-int vif01 -- \
8633 set Interface vif01 external-ids:iface-id=lp01 \
8634 options:tx_pcap=hv${i}/vif01-tx.pcap \
8635 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8636 ofport-request=${i}0
8637
8638 ovs-vsctl add-port br-int vif${i}1 -- \
8639 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8640 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8641 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8642 ofport-request=${i}1
8643
8644 ovn-nbctl lsp-add ls1 lp${i}1
8645 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8646 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8647
8648 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8649done
8650
8651ovn-nbctl --wait=sb sync
8652ovn-sbctl dump-flows
8653
74868f2c 8654OVN_POPULATE_ARP
2a38ef45
DA
8655
8656# Given the name of a logical port, prints the name of the hypervisor
8657# on which it is located.
8658vif_to_hv() {
8659 echo hv${1%?}
8660}
8661#
8662# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8663#
8664# This shell function causes a packet to be received on INPORT. The packet's
8665# content has Ethernet destination DST and source SRC (each exactly 12 hex
8666# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8667# logical switch port numbers, e.g. 11 for vif11.
8668#
8669# EOUT is the end-to-end output port, that is, where the packet will end up
8670# after possibly bouncing through one or more localnet ports. LOUT is the
8671# logical output port, which might be a localnet port, as seen by ovn-trace
8672# (which doesn't know what localnet ports are connected to and therefore can't
8673# figure out the end-to-end answer).
8674#
8675# DEFHV is the default hypervisor from where the packet is going to be sent
8676# if the source port is a localport.
8677for i in 1 2; do
8678 for j in 0 1; do
8679 : > $i$j.expected
8680 done
8681done
8682test_packet() {
8683 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8684 echo "$@"
8685
8686 # First try tracing the packet.
8687 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8688 if test $lout != drop; then
8689 echo "output(\"$lout\");"
8690 fi > expout
8691 AT_CAPTURE_FILE([trace])
8692 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8693
8694 # Then actually send a packet, for an end-to-end test.
8695 local packet=$(echo $dst$src | sed 's/://g')${eth}
8696 hv=`vif_to_hv $inport`
8697 # If hypervisor 0 (localport) use the defhv parameter
da88b550 8698 if test $hv = hv0; then
2a38ef45
DA
8699 hv=$defhv
8700 fi
8701 vif=vif$inport
8702 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8703 if test $eout != drop; then
8704 echo $packet >> ${eout#lp}.expected
8705 fi
8706}
8707
8708
8709# lp11 and lp21 are on different hypervisors
8710test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8711test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8712
8713# Both VIFs should be able to reach the localport on their own HV
8714test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8715test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8716
8717# Packet sent from localport on same hv should reach the vif
8718test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8719test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8720
8721# Packet sent from localport on different hv should be dropped
8722test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8723test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8724
8725# Now check the packets actually received against the ones expected.
8726for i in 1 2; do
8727 for j in 0 1; do
8728 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
8729 done
8730done
8731
8732OVN_CLEANUP([hv1],[hv2])
8733
8734AT_CLEANUP
1da17a0b 8735
8736AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
8737AT_SKIP_IF([test $HAVE_PYTHON = no])
8738ovn_start
8739
8740net_add n1
8741
8742# create gateways with external network connectivity
8743
8744for i in 1 2; do
8745 sim_add gw$i
8746 as gw$i
8747 ovs-vsctl add-br br-phys
8748 ovn_attach n1 br-phys 192.168.0.$i
8749 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8750done
8751
8752ovn-nbctl ls-add inside
8753ovn-nbctl ls-add outside
8754
8755# create hypervisors with a vif port each to an internal network
8756
8757for i in 1 2; do
8758 sim_add hv$i
8759 as hv$i
8760 ovs-vsctl add-br br-phys
8761 ovn_attach n1 br-phys 192.168.0.1$i
8762 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
8763 set interface hv$i-vif1 external-ids:iface-id=inside$i \
8764 options:tx_pcap=hv$i/vif1-tx.pcap \
8765 options:rxq_pcap=hv$i/vif1-rx.pcap \
8766 ofport-request=1
8767
8768 ovn-nbctl lsp-add inside inside$i \
8769 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
8770
8771done
8772
74868f2c 8773OVN_POPULATE_ARP
1da17a0b 8774
8775ovn-nbctl create Logical_Router name=R1
8776
8777# Connect inside to R1
8778ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
8779ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
8780 type=router options:router-port=inside \
8781 -- lsp-set-addresses rp-inside router
8782
8783# Connect outside to R1 as distributed router gateway port on gw1+gw2
8784ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
8785
8786ovn-nbctl --id=@gc0 create Gateway_Chassis \
8787 name=outside_gw1 chassis_name=gw1 priority=20 -- \
8788 --id=@gc1 create Gateway_Chassis \
8789 name=outside_gw2 chassis_name=gw2 priority=10 -- \
8790 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8791
8792ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
8793 type=router options:router-port=outside \
8794 -- lsp-set-addresses rp-outside router
8795
8796# Create localnet port in outside
8797ovn-nbctl lsp-add outside ln-outside
8798ovn-nbctl lsp-set-addresses ln-outside unknown
8799ovn-nbctl lsp-set-type ln-outside localnet
8800ovn-nbctl lsp-set-options ln-outside network_name=phys
8801
8802# Allow some time for ovn-northd and ovn-controller to catch up.
8803# XXX This should be more systematic.
8e1d9349 8804ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8805
8806echo "---------NB dump-----"
8807ovn-nbctl show
8808echo "---------------------"
8809ovn-nbctl list logical_router
8810echo "---------------------"
8811ovn-nbctl list logical_router_port
8812echo "---------------------"
8813
8814echo "---------SB dump-----"
8815ovn-sbctl list datapath_binding
8816echo "---------------------"
8817ovn-sbctl list port_binding
8818echo "---------------------"
8819ovn-sbctl dump-flows
8820echo "---------------------"
8821ovn-sbctl list chassis
8822ovn-sbctl list encap
8823echo "---------------------"
8824echo "------ Gateway_Chassis dump (SBDB) -------"
8825ovn-sbctl list Gateway_Chassis
8826echo "------ Port_Binding chassisredirect -------"
8827ovn-sbctl find Port_Binding type=chassisredirect
8828echo "-------------------------------------------"
8829
3475695e
VA
8830for chassis in gw1 gw2 hv1 hv2; do
8831 as $chassis
8832 echo "------ $chassis dump ----------"
8833 ovs-ofctl show br-int
8834 ovs-ofctl dump-flows br-int
3475695e
VA
8835 echo "--------------------------"
8836done
508b7f96 8837function bfd_dump() {
8838 for chassis in gw1 gw2 hv1 hv2; do
8839 as $chassis
8840 echo "------ $chassis dump (BFD)----"
8841 echo "BFD (from $chassis):"
8842 # dump BFD config and status to the other chassis
8843 for chassis2 in gw1 gw2 hv1 hv2; do
8844 if [[ "$chassis" != "$chassis2" ]]; then
8845 echo " -> $chassis2:"
8846 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
8847 fi
8848 done
8849 echo "--------------------------"
8850 done
8851}
8852
8853bfd_dump
1da17a0b 8854
8855hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8856hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8857hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
8858hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
8859
8860echo $hv1_gw1_ofport
8861echo $hv1_gw2_ofport
8862echo $hv2_gw1_ofport
8863echo $hv2_gw2_ofport
8864
8865echo "--- hv1 ---"
8866as hv1 ovs-ofctl dump-flows br-int table=32
8867
8868echo "--- hv2 ---"
8869as hv2 ovs-ofctl dump-flows br-int table=32
8870
508b7f96 8871gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
8872gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
8873
1da17a0b 8874AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw1_ofport,$hv1_gw2_ofport | wc -l], [0], [1
8875])
8876
8877AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw1_ofport,$hv2_gw2_ofport | wc -l], [0], [1
8878])
8879
508b7f96 8880sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8881
8882# make sure that flows for handling the outside router port reside on gw1
66d89287 8883AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8884]])
66d89287 8885AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8886]])
8887
8888# make sure ARP responder flows for outside router port reside on gw1 too
8889AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
8890]])
8891AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
8892]])
8893
8894
8895
8896# check that the chassis redirect port has been claimed by the gw1 chassis
8897AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8898 [0],[[1
8899]])
8900
8901
8902# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 8903
8904ovn-nbctl --id=@gc0 create Gateway_Chassis \
8905 name=outside_gw1 chassis_name=gw1 priority=10 -- \
8906 --id=@gc1 create Gateway_Chassis \
8907 name=outside_gw2 chassis_name=gw2 priority=20 -- \
8908 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
8909
508b7f96 8910
1da17a0b 8911# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 8912ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 8913
508b7f96 8914# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 8915AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv1_gw2_ofport,$hv1_gw1_ofport | wc -l], [0], [1
8916])
8917
8918AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep active_backup | grep slaves:$hv2_gw2_ofport,$hv2_gw1_ofport | wc -l], [0], [1
8919])
8920
508b7f96 8921# check that the chassis redirect port has been reclaimed by the gw2 chassis
8922AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
8923 [0],[[1
8924]])
1da17a0b 8925
3475695e
VA
8926# check BFD enablement on tunnel ports from gw1 #########
8927as gw1
8928for chassis in gw2 hv1 hv2; do
8929 echo "checking gw1 -> $chassis"
8930 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8931 [[enable=true
8932]])
8933done
8934
8935
8936# check BFD enablement on tunnel ports from gw2 ##########
8937as gw2
8938for chassis in gw1 hv1 hv2; do
8939 echo "checking gw2 -> $chassis"
8940 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8941 [[enable=true
8942]])
8943done
8944
8945# check BFD enablement on tunnel ports from hv1 ###########
8946as hv1
8947for chassis in gw1 gw2; do
8948 echo "checking hv1 -> $chassis"
8949 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8950 [[enable=true
8951]])
8952done
8953# make sure BFD is not enabled to hv2, we don't need it
8954AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
8955 [[enable=false
8956]])
8957
8958
8959# check BFD enablement on tunnel ports from hv2 ##########
8960as hv2
8961for chassis in gw1 gw2; do
8962 echo "checking hv2 -> $chassis"
8963 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
8964 [[enable=true
8965]])
8966done
8967# make sure BFD is not enabled to hv1, we don't need it
8968AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
8969 [[enable=false
8970]])
8971
508b7f96 8972sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
8973
8974# make sure that flows for handling the outside router port reside on gw2 now
66d89287 8975AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8976]])
66d89287 8977AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8978]])
8979
8980# disconnect GW2 from the network, GW1 should take over
8981as gw2
8982port=${sandbox}_br-phys
8983as main ovs-vsctl del-port n1 $port
8984sleep 4
8985
8986bfd_dump
8987
8988# make sure that flows for handling the outside router port reside on gw2 now
66d89287 8989AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 8990]])
66d89287 8991AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 8992]])
8993
8994# check that the chassis redirect port has been reclaimed by the gw1 chassis
8995AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
8996 [0],[[1
8997]])
8998
1da17a0b 8999OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9000
9001AT_CLEANUP
acfc41ff
VAK
9002
9003AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9004AT_SKIP_IF([test $HAVE_PYTHON = no])
9005ovn_start
9006ovn-nbctl ls-add ls0
9007ovn-nbctl ls-add ls1
9008ovn-nbctl create Logical_Router name=lr0
9009ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9010
9011ovn-nbctl --id=@gc0 create Gateway_Chassis \
9012 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9013 --id=@gc1 create Gateway_Chassis \
9014 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9015 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9016
9017ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9018 type=router options:router-port=lrp0 addresses="router"
9019ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9020ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9021 type=router options:router-port=lrp1 addresses="router"
9022
9023# Add NAT rules
9024AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9025
9026net_add n1
9027sim_add hv1
9028as hv1
9029ovs-vsctl add-br br-phys
9030ovn_attach n1 br-phys 192.168.0.1
9031AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9032AT_CHECK([ovs-vsctl add-port br-phys snoopvif -- set Interface snoopvif options:tx_pcap=hv1/snoopvif-tx.pcap options:rxq_pcap=hv1/snoopvif-rx.pcap])
9033
9034sim_add hv2
9035as hv2
9036ovs-vsctl add-br br-phys
9037ovn_attach n1 br-phys 192.168.0.2
9038AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9039
9040sim_add hv3
9041as hv3
9042ovs-vsctl add-br br-phys
9043ovn_attach n1 br-phys 192.168.0.3
9044AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9045
9046# Create a localnet port.
9047AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9048AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9049AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9050AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9051
9052# wait for earlier changes to take effect
6c8d3d69 9053AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
9054
9055reset_pcap_file() {
9056 local iface=$1
9057 local pcap_file=$2
9058 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9059options:rxq_pcap=dummy-rx.pcap
9060 rm -f ${pcap_file}*.pcap
9061 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9062options:rxq_pcap=${pcap_file}-rx.pcap
9063}
9064
9065as hv1 reset_pcap_file snoopvif hv1/snoopvif
9066as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9067as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9068# add nat-addresses option
6c8d3d69 9069ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
9070
9071# Wait for packets to be received through hv2.
9072OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9073trim_zeros() {
9074 sed 's/\(00\)\{1,\}$//'
9075}
9076
2db7bb2c 9077only_broadcast_from_lrp1() {
9078 grep "fffffffffffff00000000001"
9079}
9080
acfc41ff 9081garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 9082echo $garp > expout
9083
9084$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
9085echo "packets on hv1-snoopvif:"
9086cat hv1_snoop_tx
9087AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 9088$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
acfc41ff
VAK
9089echo "packets on hv2 br-phys tx"
9090cat hv2_br_phys_tx
9091AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 9092$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
acfc41ff
VAK
9093echo "packets on hv3 br-phys tx"
9094cat hv3_br_phys_tx
9095AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9096
9097
9098# at this point, we invert the priority of the gw chassis between hv2 and hv3
9099
9100ovn-nbctl --wait=hv \
9101 --id=@gc0 create Gateway_Chassis \
9102 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9103 --id=@gc1 create Gateway_Chassis \
9104 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9105 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9106
9107
9108as hv1 reset_pcap_file snoopvif hv1/snoopvif
9109as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9110as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9111
9112# Wait for packets to be received.
9113OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9114trim_zeros() {
9115 sed 's/\(00\)\{1,\}$//'
9116}
9117
2db7bb2c 9118$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 9119AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 9120$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
acfc41ff 9121AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 9122$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
acfc41ff 9123AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
9124
9125# change localnet port tag.
9126AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9127
9128# wait for earlier changes to take effect
6c8d3d69 9129AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
9130
9131# update nat-addresses option
6c8d3d69
HZ
9132ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9133ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
9134
9135as hv1 reset_pcap_file snoopvif hv1/snoopvif
9136as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9137as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9138
9139# Wait for packets to be received.
9140OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9141trim_zeros() {
9142 sed 's/\(00\)\{1,\}$//'
9143}
9144
9145garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9146echo $garp > expout
9147
9148$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9149AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9150$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9151AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9152$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9153AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9154
acfc41ff
VAK
9155OVN_CLEANUP([hv1],[hv2],[hv3])
9156
9157AT_CLEANUP
79371ff5 9158
9159AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9160AT_SKIP_IF([test $HAVE_PYTHON = no])
9161ovn_start
9162
9163net_add n1
9164
9165# create two gateways with external network connectivity
9166for i in 1 2; do
9167 sim_add gw$i
9168 as gw$i
9169 ovs-vsctl add-br br-phys
9170 ovn_attach n1 br-phys 192.168.0.$i
9171 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9172done
9173
9174ovn-nbctl ls-add inside
9175ovn-nbctl ls-add outside
9176
9177# create one hypervisors with a vif port the internal network
9178sim_add hv1
9179as hv1
9180ovs-vsctl add-br br-phys
9181ovn_attach n1 br-phys 192.168.0.11
9182ovs-vsctl -- add-port br-int hv1-vif1 -- \
9183 set interface hv1-vif1 external-ids:iface-id=inside1 \
9184 options:tx_pcap=hv1/vif1-tx.pcap \
9185 options:rxq_pcap=hv1/vif1-rx.pcap \
9186 ofport-request=1
9187
9188ovn-nbctl lsp-add inside inside1 \
9189 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9190
9191
74868f2c 9192OVN_POPULATE_ARP
79371ff5 9193
9194ovn-nbctl create Logical_Router name=R1
9195
9196# Connect inside to R1
9197ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9198ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9199 type=router options:router-port=inside \
9200 -- lsp-set-addresses rp-inside router
9201
9202# Connect outside to R1 as distributed router gateway port on gw1+gw2
9203ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9204
9205ovn-nbctl --id=@gc0 create Gateway_Chassis \
9206 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9207 --id=@gc1 create Gateway_Chassis \
9208 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9209 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9210
9211ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9212 type=router options:router-port=outside \
9213 -- lsp-set-addresses rp-outside router
9214
9215# Create localnet port in outside
9216ovn-nbctl lsp-add outside ln-outside
9217ovn-nbctl lsp-set-addresses ln-outside unknown
9218ovn-nbctl lsp-set-type ln-outside localnet
9219ovn-nbctl lsp-set-options ln-outside network_name=phys
9220
9221# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9222ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9223
9224# currently when ovn-controller is restarted, the old entry is deleted
9225# and a new one is created, which leaves the Gateway_Chassis with
9226# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9227# doesn't have the same effect because "name" is conserved, and the
9228# Chassis entry is not replaced.
9229
3a0c5805 9230> gw1/ovn-controller.log
325b2b1a 9231
79371ff5 9232gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9233ovn-sbctl destroy Chassis $gw2_chassis
9234
9235# Ensure ovn-controller has processed latest sbdb update
9236# ovn-nbctl --wait=hv sync
9237
9238AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9239
9240OVN_CLEANUP([gw1],[gw2],[hv1])
9241
9242AT_CLEANUP
63d91afa 9243
b1a3a6a4
NS
9244AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9245AT_KEYWORDS([ovn-nd_ns for unknown mac])
9246AT_SKIP_IF([test $HAVE_PYTHON = no])
9247ovn_start
9248
9249ovn-nbctl ls-add sw0_ip6
9250ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9251ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9252"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9253
9254ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9255"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9256
9257ovn-nbctl lr-add lr0_ip6
847dc1c2 9258ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9259ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9260ovn-nbctl lsp-set-type lrp0_ip6-attachment router
9261ovn-nbctl lsp-set-addresses lrp0_ip6-attachment 00:00:00:00:af:01
9262ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9263ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9264
9265ovn-nbctl ls-add public
9266ovn-nbctl lsp-add public ln-public
9267ovn-nbctl lsp-set-addresses ln-public unknown
9268ovn-nbctl lsp-set-type ln-public localnet
9269ovn-nbctl lsp-set-options ln-public network_name=phys
9270
9271ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
92722001:db8:1:0:200:02ff:fe01:0204/64 \
9273-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9274
9275
9276ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9277rp-ip6_public type=router options:router-port=ip6_public \
9278-- lsp-set-addresses rp-ip6_public router
9279
9280net_add n1
9281sim_add hv1
9282as hv1
9283ovs-vsctl add-br br-phys
9284ovn_attach n1 br-phys 192.168.0.2
9285
9286ovs-vsctl -- add-port br-int hv1-vif1 -- \
9287 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9288 options:tx_pcap=hv1/vif1-tx.pcap \
9289 options:rxq_pcap=hv1/vif1-rx.pcap \
9290 ofport-request=1
9291ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9292
86c9d79a
NS
9293OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
9294cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9295
9296# There is only one chassis.
9297chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9298OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
9299
9300trim_zeros() {
9301 sed 's/\(00\)\{1,\}$//'
9302}
9303
9304# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9305# addresses. ovn-controller should generate an IPv6 NS request for IPv6
9306# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9307# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9308# This function sends ipv6 packet
9309test_ipv6() {
9310 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9311 dst_ip=20010db800010000020002fffe010205
9312
9313 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9314 packet=${packet}8000000000000000
9315 shift; shift; shift; shift
9316
9317 dst_mac=3333ff010205
9318 src_mac=000002010204
9319 mcast_node_ip=ff0200000000000000000001ff010205
9320 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9321 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9322 expected_packet=${expected_packet}0101${src_mac}
9323
9324 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9325 echo $expected_packet >> ipv6_ns.expected
9326}
9327
9328src_mac=506400000002
9329dst_mac=00000000af01
9330src_ip=aef0000000000000526400fffe000002
9331# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9332# should be received by the ports attached to br-phys.
9333test_ipv6 1 $src_mac $dst_mac $src_ip 2
9334
86c9d79a
NS
9335OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9336OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9337
b1a3a6a4
NS
9338$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9339trim_zeros > 1.packets
9340$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9341trim_zeros > 2.packets
9342
9343cat ipv6_ns.expected | cut -c -112 > expout
9344AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9345AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9346
9347# Skipping the ICMPv6 checksum
9348cat ipv6_ns.expected | cut -c 117- > expout
9349AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9350AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9351
9352OVN_CLEANUP([hv1])
9353
9354AT_CLEANUP
9355
63d91afa
LR
9356AT_SETUP([ovn -- options:requested-chassis for logical port])
9357ovn_start
9358
9359net_add n1
9360
9361ovn-nbctl ls-add ls0
9362ovn-nbctl lsp-add ls0 lsp0
9363
9364# create two hypervisors, each with one vif port
9365sim_add hv1
9366as hv1
9367ovs-vsctl add-br br-phys
9368ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
9369ovs-vsctl -- add-port br-int hv1-vif0 -- \
9370set Interface hv1-vif0 ofport-request=1
63d91afa
LR
9371
9372sim_add hv2
9373as hv2
9374ovs-vsctl add-br br-phys
9375ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
9376ovs-vsctl -- add-port br-int hv2-vif0 -- \
9377set Interface hv2-vif0 ofport-request=1
63d91afa
LR
9378
9379# Allow only chassis hv1 to bind logical port lsp0.
9380ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9381
9382# Allow some time for ovn-northd and ovn-controller to catch up.
9383ovn-nbctl --wait=hv --timeout=3 sync
9384
9385# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
9386ovn-sbctl wait-until chassis hv1
9387ovn-sbctl wait-until chassis hv2
63d91afa
LR
9388hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9389hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9390
9391# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9392echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9393as hv2
9394ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9395
9396OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9397AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9398
99cc5c92
NS
9399# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9400AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9401AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9402
9403# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
9404echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9405as hv1
9406ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9407
9408OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 9409AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 9410
99cc5c92
NS
9411# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9412as hv1 ovs-ofctl dump-flows br-int
9413AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9414AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9415
9416# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
9417# the requested chassis for lsp0 is changed from hv1 to hv2.
9418echo "verifying that lsp0 binding moves when requested-chassis is changed"
9419
9420ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9421OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 9422OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 9423
99cc5c92
NS
9424# (6) Chassis hv2 should add flows and hv1 should not.
9425AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9426AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9427
9428AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9429AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9430
63d91afa
LR
9431OVN_CLEANUP([hv1],[hv2])
9432
9433AT_CLEANUP
bd32425f
RB
9434
9435AT_SETUP([ovn -- options:requested-chassis with hostname])
9436
9437ovn_start
9438
9439ovn-nbctl ls-add ls0
9440ovn-nbctl lsp-add ls0 lsp0
9441
9442net_add n1
9443sim_add hv1
9444as hv1
9445ovs-vsctl add-br br-phys
9446ovn_attach n1 br-phys 192.168.0.11
99cc5c92 9447ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 9448
362ab40a 9449ovn-sbctl wait-until chassis hv1
bd32425f
RB
9450hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9451echo "hv1_hostname=${hv1_hostname}"
9452ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9453as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9454
9455hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9456echo "hv1_uuid=${hv1_uuid}"
9457OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9458AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
9459AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9460AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
9461
9462ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9463OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9464ovn-nbctl --wait=hv --timeout=3 sync
9465AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
9466AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9467AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
9468
9469OVN_CLEANUP([hv1])
9470
9471AT_CLEANUP
4446661a
MM
9472
9473AT_SETUP([ovn -- IPv6 periodic RA])
9474ovn_start
9475
9476# This test sets up two hypervisors.
9477# hv1 and hv2 run ovn-controllers, and
9478# each has a VIF connected to the same
9479# logical switch in OVN. The logical
9480# switch is connected to a logical
9481# router port that is configured to send
9482# periodic router advertisements.
9483#
9484# The reason for having two ovn-controller
9485# hypervisors is to ensure that the
9486# periodic RAs being sent by each ovn-controller
9487# are kept to their local hypervisors. If the
9488# packets are not kept local, then each port
9489# will receive too many RAs.
9490
9491net_add n1
9492sim_add hv1
9493sim_add hv2
9494as hv1
9495ovs-vsctl add-br br-phys
9496ovn_attach n1 br-phys 192.168.0.2
9497as hv2
9498ovs-vsctl add-br br-phys
9499ovn_attach n1 br-phys 192.168.0.3
9500
9501ovn-nbctl lr-add ro
1ea1b0d0 9502ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
9503
9504ovn-nbctl ls-add sw
9505ovn-nbctl lsp-add sw sw-ro
9506ovn-nbctl lsp-set-type sw-ro router
9507ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9508ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9509ovn-nbctl lsp-add sw sw-p1
9510ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9511ovn-nbctl lsp-add sw sw-p2
9512ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9513
9514ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9515ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9516ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9517ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9518
86c9d79a
NS
9519for i in 1 2 ; do
9520 as hv$i
9521 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9522 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9523 options:tx_pcap=hv$i/vif1-tx.pcap \
9524 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
9525 ofport-request=1
9526done
9527
86c9d79a
NS
9528OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9529OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
9530
9531reset_pcap_file() {
9532 local iface=$1
9533 local pcap_file=$2
9534 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9535options:rxq_pcap=dummy-rx.pcap
9536 rm -f ${pcap_file}*.pcap
9537 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9538options:rxq_pcap=${pcap_file}-rx.pcap
9539
9540}
9541
9542construct_expected_ra() {
9543 local src_mac=000000000001
9544 local dst_mac=333300000001
9545 local src_addr=fe80000000000000020000fffe000001
9546 local dst_addr=ff020000000000000000000000000001
9547
9548 local mtu=$1
9549 local ra_mo=$2
9550 local ra_prefix_la=$3
9551
9552 local slla=0101${src_mac}
9553 local mtu_opt=""
9554 if test $mtu != 0; then
9555 mtu_opt=05010000${mtu}
9556 fi
9557 shift 3
9558
9559 local prefix=""
9560 while [[ $# -gt 0 ]] ; do
9561 local size=$1
9562 local net=$2
9563 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9564 shift 2
9565 done
9566
895ceaf7 9567 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
9568 local icmp=8600XXXX${ra}
9569
9570 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 9571 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
9572
9573 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9574 local eth=${dst_mac}${src_mac}86dd${ip}
9575 local packet=${eth}
9576 echo $packet >> expected
9577}
9578
9579ra_test() {
9580 construct_expected_ra $@
9581
9582 for i in hv1 hv2 ; do
9583 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9584
9585 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9586
9587 cat expected | cut -c -112 > expout
9588 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9589
9590 # Skip ICMPv6 checksum.
9591 cat expected | cut -c 117- > expout
9592 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9593
9594 rm -f packets
9595 as $i reset_pcap_file $i-vif1 $i/vif1
9596 done
9597
9598 rm -f expected
9599}
9600
9601# Baseline test with no MTU
9602ra_test 0 00 c0 40 aef00000000000000000000000000000
9603
9604# Now make sure an MTU option makes it
9605ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9606ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9607
9608# Now test for multiple network prefixes
9609ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9610ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9611
9612# Test a different address mode now
9613ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9614ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9615
9616# And the other address mode
9617ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9618ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9619
9620OVN_CLEANUP([hv1],[hv2])
9621AT_CLEANUP
4826add0
LB
9622
9623AT_SETUP([ovn -- ACL reject rule test])
9624AT_KEYWORDS([acl-reject])
9625AT_SKIP_IF([test $HAVE_PYTHON = no])
9626ovn_start
9627
9628# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9629#
9630# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9631# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9632# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9633# unreachable frame generated from ACL rule hit
9634#
9635# INPORT is a lport number, e.g. 11 for vif11.
9636# HV is a hypervisor number
9637# ETH_SRC and ETH_DST are each 12 hex digits.
9638# IPV4_SRC and IPV4_DST are each 8 hex digits.
9639# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9640test_ip_packet() {
9641 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9642 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9643 shift 9
9644
9645 local ip_ttl=ff
9646 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9647
9648 local reply_icmp_ttl=ff
9649 local icmp_type_code_response=0301
9650 local icmp_data=00000000
9651 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9652 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9653 echo $reply >> vif$inport.expected
9654
9655 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9656}
9657
c319fabc
LB
9658# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9659#
9660# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9661# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9662# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9663test_ipv6_packet() {
9664 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9665 shift 7
9666
9667 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9668 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9669
9670 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9671 echo $reply >> vif$inport.expected
9672
9673 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9674}
9675
c20ab6aa
LB
9676# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
9677#
9678# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9679# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9680# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9681#
9682# INPORT is an lport number, e.g. 11 for vif11.
9683# HV is an hypervisor number
9684# ETH_SRC and ETH_DST are each 12 hex digits.
9685# IPV4_SRC and IPV4_DST are each 8 hex digits.
9686# TCP_SPORT and TCP_DPORT are 4 hex digits.
9687# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9688test_tcp_syn_packet() {
9689 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9690 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9691 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9692 shift 12
9693
9694 local ip_ttl=ff
9695 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9696
9697 local tcp_rst_ttl=ff
9698 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ipv4_dst}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
9699 echo $reply >> vif$inport.expected
9700
9701 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9702}
9703
4826add0
LB
9704# Create hypervisors hv[123].
9705# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9706# Add all of the vifs to a single logical switch sw0.
9707
9708net_add n1
9709ovn-nbctl ls-add sw0
9710for i in 1 2 3; do
9711 sim_add hv$i
9712 as hv$i
9713 ovs-vsctl add-br br-phys
9714 ovn_attach n1 br-phys 192.168.0.$i
9715
9716 for j in 1 2 3; do
9717 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
9718 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
9719
9720 ovs-vsctl -- add-port br-int vif$i$j -- \
9721 set interface vif$i$j \
9722 external-ids:iface-id=sw0-p$i$j \
9723 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
9724 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
9725 ofport-request=$i$j
9726 done
9727done
9728
9729OVN_POPULATE_ARP
9730# allow some time for ovn-northd and ovn-controller to catch up.
9731sleep 1
9732
9733ip_to_hex() {
9734 printf "%02x%02x%02x%02x" "$@"
9735}
9736
9737for i in 1 2 3; do
9738 : > vif${i}1.expected
9739done
9740
9741ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
9742ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
9743ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
9744
9745# Allow some time for ovn-northd and ovn-controller to catch up.
9746ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
9747
9748test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
9749test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
9750test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
9751
c319fabc
LB
9752test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
9753
c20ab6aa
LB
9754test_tcp_syn_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 8b40 3039 0000 7d8d 4486
9755test_tcp_syn_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 8b40 3039 0000 7d8d 4486
9756test_tcp_syn_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 8b40 3039 0000 7d82 4486
9757
4826add0
LB
9758for i in 1 2 3; do
9759 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
9760done
9761
9762OVN_CLEANUP([hv1], [hv2], [hv3])
9763AT_CLEANUP
689829d5
HZ
9764
9765AT_SETUP([ovn -- Port Groups])
9766AT_KEYWORDS([ovnpg])
9767AT_SKIP_IF([test $HAVE_PYTHON = no])
9768ovn_start
9769
9770# Logical network:
9771#
9772# Three logical switches ls1, ls2, ls3.
9773# One logical router lr0 connected to ls[123],
9774# with nine subnets, three per logical switch:
9775#
9776# lrp11 on ls1 for subnet 192.168.11.0/24
9777# lrp12 on ls1 for subnet 192.168.12.0/24
9778# lrp13 on ls1 for subnet 192.168.13.0/24
9779# ...
9780# lrp33 on ls3 for subnet 192.168.33.0/24
9781#
9782# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
9783# digits are the subnet and the last digit distinguishes the VIF.
9784#
9785# This test will create two port groups and uses them in ACL.
9786
9787get_lsp_uuid () {
9788 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
9789}
9790
9791pg1_ports=
9792pg2_ports=
9793for i in 1 2 3; do
9794 ovn-nbctl ls-add ls$i
9795 for j in 1 2 3; do
9796 for k in 1 2 3; do
9797 ovn-nbctl \
9798 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
9799 -- lsp-set-addresses lp$i$j$k \
9800 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
689829d5
HZ
9801 # logical ports lp[12]?1 belongs to port group pg1
9802 if test $i != 3 && test $k == 1; then
9803 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
9804 fi
9805 # logical ports lp[23]?2 belongs to port group pg2
9806 if test $i != 1 && test $k == 2; then
9807 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
9808 fi
9809 done
9810 done
9811done
9812
9813ovn-nbctl lr-add lr0
9814for i in 1 2 3; do
9815 for j in 1 2 3; do
9816 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
9817 ovn-nbctl \
9818 -- lsp-add ls$i lrp$i$j-attachment \
9819 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
9820 options:router-port=lrp$i$j \
9821 addresses='"00:00:00:00:ff:'$i$j'"'
9822 done
9823done
9824
9825ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
9826ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
9827
9828# create ACLs on all lswitches to drop traffic from pg2 to pg1
9829ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9830ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9831ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
9832
9833# Physical network:
9834#
9835# Three hypervisors hv[123].
9836# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
9837# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
9838# lp?3[123] all on hv3.
9839
9840# Given the name of a logical port, prints the name of the hypervisor
9841# on which it is located.
9842vif_to_hv() {
9843 case $1 in dnl (
9844 ?11) echo 1 ;; dnl (
9845 ?12 | ?21 | ?22) echo 2 ;; dnl (
9846 ?13 | ?23 | ?3?) echo 3 ;;
9847 esac
9848}
9849
9850# Given the name of a logical port, prints the name of its logical router
9851# port, e.g. "vif_to_lrp 123" yields 12.
9852vif_to_lrp() {
9853 echo ${1%?}
9854}
9855
9856# Given the name of a logical port, prints the name of its logical
9857# switch, e.g. "vif_to_ls 123" yields 1.
9858vif_to_ls() {
9859 echo ${1%??}
9860}
9861
9862net_add n1
9863for i in 1 2 3; do
9864 sim_add hv$i
9865 as hv$i
9866 ovs-vsctl add-br br-phys
9867 ovn_attach n1 br-phys 192.168.0.$i
9868done
9869for i in 1 2 3; do
9870 for j in 1 2 3; do
9871 for k in 1 2 3; do
9872 hv=`vif_to_hv $i$j$k`
9873 as hv$hv ovs-vsctl \
9874 -- add-port br-int vif$i$j$k \
9875 -- set Interface vif$i$j$k \
9876 external-ids:iface-id=lp$i$j$k \
9877 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
9878 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
9879 ofport-request=$i$j$k
9880 done
9881 done
9882done
9883
9884# Pre-populate the hypervisors' ARP tables so that we don't lose any
9885# packets for ARP resolution (native tunneling doesn't queue packets
9886# for ARP resolution).
9887OVN_POPULATE_ARP
9888
9889# Allow some time for ovn-northd and ovn-controller to catch up.
9890# XXX This should be more systematic.
9891sleep 1
9892
9893# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9894#
9895# This shell function causes a packet to be received on INPORT. The packet's
9896# content has Ethernet destination DST and source SRC (each exactly 12 hex
9897# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
9898# more) list the VIFs on which the packet should be received. INPORT and the
9899# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9900for i in 1 2 3; do
9901 for j in 1 2 3; do
9902 for k in 1 2 3; do
9903 : > $i$j$k.expected
9904 done
9905 done
9906done
9907test_ip() {
9908 # This packet has bad checksums but logical L3 routing doesn't check.
9909 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
9910 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9911 shift; shift; shift; shift; shift
9912 hv=hv`vif_to_hv $inport`
9913 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
9914 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
9915 in_ls=`vif_to_ls $inport`
9916 in_lrp=`vif_to_lrp $inport`
9917 for outport; do
9918 out_ls=`vif_to_ls $outport`
9919 if test $in_ls = $out_ls; then
9920 # Ports on the same logical switch receive exactly the same packet.
9921 echo $packet
9922 else
9923 # Routing decrements TTL and updates source and dest MAC
9924 # (and checksum).
9925 out_lrp=`vif_to_lrp $outport`
9926 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
9927 fi >> $outport.expected
9928 done
9929}
9930
9931as hv1 ovs-vsctl --columns=name,ofport list interface
9932as hv1 ovn-sbctl list port_binding
9933as hv1 ovn-sbctl list datapath_binding
9934as hv1 ovn-sbctl list port_group
9935as hv1 ovn-sbctl list address_set
9936as hv1 ovn-sbctl dump-flows
9937as hv1 ovs-ofctl dump-flows br-int
9938
9939# Send IP packets between all pairs of source and destination ports,
9940# packets matches ACL (pg2 to pg1) should be dropped
9941ip_to_hex() {
9942 printf "%02x%02x%02x%02x" "$@"
9943}
9944for is in 1 2 3; do
9945 for js in 1 2 3; do
9946 for ks in 1 2 3; do
9947 bcast=
9948 s=$is$js$ks
9949 smac=f00000000$s
9950 sip=`ip_to_hex 192 168 $is$js $ks`
9951 for id in 1 2 3; do
9952 for jd in 1 2 3; do
9953 for kd in 1 2 3; do
9954 d=$id$jd$kd
9955 dip=`ip_to_hex 192 168 $id$jd $kd`
9956 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
9957 if test $d != $s; then unicast=$d; else unicast=; fi
9958
9959 # packets matches ACL should be dropped
9960 if test $id != 3 && test $kd == 1; then
9961 if test $is != 1 && test $ks == 2; then
9962 unicast=
9963 fi
9964 fi
9965 test_ip $s $smac $dmac $sip $dip $unicast #1
9966 done
9967 done
9968 done
9969 done
9970 done
9971done
9972
9973# Allow some time for packet forwarding.
9974# XXX This can be improved.
9975sleep 1
9976
9977# Now check the packets actually received against the ones expected.
9978for i in 1 2 3; do
9979 for j in 1 2 3; do
9980 for k in 1 2 3; do
9981 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
9982 [$i$j$k.expected])
9983 done
9984 done
9985done
9986
9987# Gracefully terminate daemons
9988OVN_CLEANUP([hv1], [hv2], [hv3])
9989AT_CLEANUP
1beb60af
HZ
9990
9991AT_SETUP([ovn -- ACLs on Port Groups])
9992AT_KEYWORDS([ovnpg_acl])
9993AT_SKIP_IF([test $HAVE_PYTHON = no])
9994ovn_start
9995
9996# Logical network:
9997#
9998# Three logical switches ls1, ls2, ls3.
9999# One logical router lr0 connected to ls[123],
10000# with nine subnets, three per logical switch:
10001#
10002# lrp11 on ls1 for subnet 192.168.11.0/24
10003# lrp12 on ls1 for subnet 192.168.12.0/24
10004# lrp13 on ls1 for subnet 192.168.13.0/24
10005# ...
10006# lrp33 on ls3 for subnet 192.168.33.0/24
10007#
10008# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10009# digits are the subnet and the last digit distinguishes the VIF.
10010#
10011# This test will create two port groups and ACLs will be applied on them.
10012
10013get_lsp_uuid () {
10014 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10015}
10016
10017pg1_ports=
10018pg2_ports=
10019for i in 1 2 3; do
10020 ovn-nbctl ls-add ls$i
10021 for j in 1 2 3; do
10022 for k in 1 2 3; do
10023 ovn-nbctl \
10024 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10025 -- lsp-set-addresses lp$i$j$k \
10026 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
1beb60af
HZ
10027 # logical ports lp[12]?1 belongs to port group pg1
10028 if test $i != 3 && test $k == 1; then
10029 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10030 fi
10031 # logical ports lp[23]?2 belongs to port group pg2
10032 if test $i != 1 && test $k == 2; then
10033 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10034 fi
10035 done
10036 done
10037done
10038
10039ovn-nbctl lr-add lr0
10040for i in 1 2 3; do
10041 for j in 1 2 3; do
10042 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10043 ovn-nbctl \
10044 -- lsp-add ls$i lrp$i$j-attachment \
10045 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10046 options:router-port=lrp$i$j \
10047 addresses='"00:00:00:00:ff:'$i$j'"'
10048 done
10049done
10050
d87e0897 10051ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
10052ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10053
10054# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
10055ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10056ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
cdc9a84a 10057 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
10058
10059# Physical network:
10060#
10061# Three hypervisors hv[123].
10062# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10063# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10064# lp?3[123] all on hv3.
10065
10066# Given the name of a logical port, prints the name of the hypervisor
10067# on which it is located.
10068vif_to_hv() {
10069 case $1 in dnl (
10070 ?11) echo 1 ;; dnl (
10071 ?12 | ?21 | ?22) echo 2 ;; dnl (
10072 ?13 | ?23 | ?3?) echo 3 ;;
10073 esac
10074}
10075
10076# Given the name of a logical port, prints the name of its logical router
10077# port, e.g. "vif_to_lrp 123" yields 12.
10078vif_to_lrp() {
10079 echo ${1%?}
10080}
10081
10082# Given the name of a logical port, prints the name of its logical
10083# switch, e.g. "vif_to_ls 123" yields 1.
10084vif_to_ls() {
10085 echo ${1%??}
10086}
10087
10088net_add n1
10089for i in 1 2 3; do
10090 sim_add hv$i
10091 as hv$i
10092 ovs-vsctl add-br br-phys
10093 ovn_attach n1 br-phys 192.168.0.$i
10094done
10095for i in 1 2 3; do
10096 for j in 1 2 3; do
10097 for k in 1 2 3; do
10098 hv=`vif_to_hv $i$j$k`
10099 as hv$hv ovs-vsctl \
10100 -- add-port br-int vif$i$j$k \
10101 -- set Interface vif$i$j$k \
10102 external-ids:iface-id=lp$i$j$k \
10103 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10104 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10105 ofport-request=$i$j$k
10106 done
10107 done
10108done
10109
10110# Pre-populate the hypervisors' ARP tables so that we don't lose any
10111# packets for ARP resolution (native tunneling doesn't queue packets
10112# for ARP resolution).
10113OVN_POPULATE_ARP
10114
10115# Allow some time for ovn-northd and ovn-controller to catch up.
10116# XXX This should be more systematic.
10117sleep 1
10118
cdc9a84a
HZ
10119lsp_to_mac() {
10120 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10121}
10122
10123lrp_to_mac() {
10124 echo 00:00:00:00:ff:$1
10125}
10126
10127# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
1beb60af 10128#
cdc9a84a
HZ
10129# This shell function causes a ICMP packet to be received on INPORT.
10130# The OUTPORTs (zero or more) list the VIFs on which the packet should
10131# be received. INPORT and the OUTPORTs are specified as logical switch
10132# port numbers, e.g. 123 for vif123.
1beb60af
HZ
10133for i in 1 2 3; do
10134 for j in 1 2 3; do
10135 for k in 1 2 3; do
10136 : > $i$j$k.expected
10137 done
10138 done
10139done
cdc9a84a
HZ
10140
10141test_icmp() {
10142 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10143 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10144 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10145 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10146 icmp4.code==0"
10147 shift; shift; shift; shift; shift; shift
1beb60af 10148 hv=hv`vif_to_hv $inport`
cdc9a84a 10149 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
1beb60af
HZ
10150 in_ls=`vif_to_ls $inport`
10151 in_lrp=`vif_to_lrp $inport`
10152 for outport; do
10153 out_ls=`vif_to_ls $outport`
10154 if test $in_ls = $out_ls; then
10155 # Ports on the same logical switch receive exactly the same packet.
cdc9a84a 10156 echo $packet | ovstest test-ovn expr-to-packets
1beb60af
HZ
10157 else
10158 # Routing decrements TTL and updates source and dest MAC
10159 # (and checksum).
10160 out_lrp=`vif_to_lrp $outport`
cdc9a84a
HZ
10161 exp_smac=`lrp_to_mac $out_lrp`
10162 exp_dmac=`lsp_to_mac $outport`
10163 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10164 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10165 icmp4.type==$icmp_type && icmp4.code==0"
10166 echo $exp_packet | ovstest test-ovn expr-to-packets
10167
1beb60af
HZ
10168 fi >> $outport.expected
10169 done
10170}
10171
10172as hv1 ovs-vsctl --columns=name,ofport list interface
10173as hv1 ovn-sbctl list port_binding
10174as hv1 ovn-sbctl list datapath_binding
10175as hv1 ovn-sbctl list port_group
10176as hv1 ovn-sbctl list address_set
10177as hv1 ovn-sbctl dump-flows
10178as hv1 ovs-ofctl dump-flows br-int
10179
10180# Send IP packets between all pairs of source and destination ports,
10181# packets matches ACL1 but not ACL2 should be dropped
10182ip_to_hex() {
10183 printf "%02x%02x%02x%02x" "$@"
10184}
10185for is in 1 2 3; do
10186 for js in 1 2 3; do
10187 for ks in 1 2 3; do
10188 bcast=
10189 s=$is$js$ks
cdc9a84a
HZ
10190 slsp_mac=`lsp_to_mac $s`
10191 slrp_mac=`lrp_to_mac $is$js`
10192 sip=192.168.$is$js.$ks
1beb60af
HZ
10193 for id in 1 2 3; do
10194 for jd in 1 2 3; do
10195 for kd in 1 2 3; do
10196 d=$id$jd$kd
cdc9a84a
HZ
10197 dlsp_mac=`lsp_to_mac $d`
10198 dlrp_mac=`lrp_to_mac $id$jd`
10199 dip=192.168.$id$jd.$kd
10200 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
1beb60af
HZ
10201 if test $d != $s; then unicast=$d; else unicast=; fi
10202
10203 # packets matches ACL1 but not ACL2 should be dropped
10204 if test $id != 3 && test $kd == 1; then
10205 if test $is == 1 || test $ks != 2; then
10206 unicast=
10207 fi
10208 fi
cdc9a84a
HZ
10209 # icmp request (type = 8)
10210 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
10211
10212 # if packets are not dropped, test the return traffic (icmp echo)
10213 # to make sure stateful works, too.
10214 if test x$unicast != x; then
10215 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
10216 # icmp echo (type = 0)
10217 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
10218 fi
1beb60af
HZ
10219 done
10220 done
10221 done
10222 done
10223 done
10224done
10225
10226# Allow some time for packet forwarding.
10227# XXX This can be improved.
10228sleep 1
10229
10230# Now check the packets actually received against the ones expected.
10231for i in 1 2 3; do
10232 for j in 1 2 3; do
10233 for k in 1 2 3; do
10234 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10235 [$i$j$k.expected])
10236 done
10237 done
10238done
10239
10240# Gracefully terminate daemons
10241OVN_CLEANUP([hv1], [hv2], [hv3])
10242AT_CLEANUP
55b25947
NS
10243
10244AT_SETUP([ovn -- ACL conjunction])
10245ovn_start
10246
10247ovn-nbctl ls-add ls1
10248
10249ovn-nbctl lsp-add ls1 ls1-lp1 \
10250-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10251
10252ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10253
10254ovn-nbctl lsp-add ls1 ls1-lp2 \
10255-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10256
10257ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10258
10259net_add n1
10260sim_add hv1
10261
10262as hv1
10263ovs-vsctl add-br br-phys
10264ovn_attach n1 br-phys 192.168.0.1
10265ovs-vsctl -- add-port br-int hv1-vif1 -- \
10266 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10267 options:tx_pcap=hv1/vif1-tx.pcap \
10268 options:rxq_pcap=hv1/vif1-rx.pcap \
10269 ofport-request=1
10270
10271ovs-vsctl -- add-port br-int hv1-vif2 -- \
10272 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10273 options:tx_pcap=hv1/vif2-tx.pcap \
10274 options:rxq_pcap=hv1/vif2-rx.pcap \
10275 ofport-request=2
10276
10277ovn-nbctl create Address_Set name=set1 \
10278addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10279ovn-nbctl create Address_Set name=set2 \
10280addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10281ovn-nbctl acl-add ls1 to-lport 1002 \
10282'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10283ovn-nbctl acl-add ls1 to-lport 1001 \
10284'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10285
10286# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10287#
10288# This shell function causes an ip packet to be received on INPORT.
10289# The packet's content has Ethernet destination DST and source SRC
10290# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10291# The OUTPORTs (zero or more) list the VIFs on which the packet should
10292# be received. INPORT and the OUTPORTs are specified as logical switch
10293# port numbers, e.g. 11 for vif11.
10294test_ip() {
10295 # This packet has bad checksums but logical L3 routing doesn't check.
10296 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10297 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10298${dst_ip}0035111100080000
10299 shift; shift; shift; shift; shift
10300 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10301 for outport; do
10302 echo $packet >> $outport.expected
10303 done
10304}
10305
10306ip_to_hex() {
10307 printf "%02x%02x%02x%02x" "$@"
10308}
10309
10310reset_pcap_file() {
10311 local iface=$1
10312 local pcap_file=$2
10313 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10314options:rxq_pcap=dummy-rx.pcap
10315 rm -f ${pcap_file}*.pcap
10316 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10317options:rxq_pcap=${pcap_file}-rx.pcap
10318}
10319
10320
10321sip=`ip_to_hex 10 0 0 4`
10322dip=`ip_to_hex 10 0 0 6`
10323
10324test_ip 1 f00000000001 f00000000002 $sip $dip 2
10325
10326cat 2.expected > expout
10327$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10328AT_CHECK([cat 2.packets], [0], [expout])
10329
10330# There should be total of 12 flows present with conjunction action and 2 flows
10331# with conj match. Eg.
10332# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10333# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10334# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10335# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10336# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10337# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10338# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10339# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10340# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10341# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10342# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10343# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10344# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10345# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10346
10347OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10348grep conjunction | wc -l`])
10349OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10350grep conj_id | wc -l`])
10351
10352as hv1 ovs-ofctl dump-flows br-int
10353
10354# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10355ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10356ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10357
10358reset_pcap_file hv1-vif2 hv1/vif2
10359
10360rm -f 2.packets
10361
10362sip=`ip_to_hex 10 0 0 4`
10363dip=`ip_to_hex 10 0 0 7`
10364
10365test_ip 1 f00000000001 f00000000002 $sip $dip
10366$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10367AT_CHECK([cat 2.packets], [0], [])
10368
10369AT_CLEANUP
0e2751ed
LB
10370
10371AT_SETUP([ovn -- TTL exceeded])
10372AT_KEYWORDS([ttl-exceeded])
10373AT_SKIP_IF([test $HAVE_PYTHON = no])
10374ovn_start
10375
10376# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10377#
10378# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10379# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
10380# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
10381# generated by OVN logical router
10382#
10383# INPORT is a lport number, e.g. 11 for vif11.
10384# HV is a hypervisor number
10385# ETH_SRC and ETH_DST are each 12 hex digits.
10386# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
10387# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10388test_ip_packet() {
10389 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
10390 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
10391 shift 10
10392
10393 local ip_ttl=01
10394 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10395
10396 local reply_icmp_ttl=fe
10397 local icmp_type_code_response=0b00
10398 local icmp_data=00000000
10399 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10400 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10401 echo $reply >> vif$inport.expected
10402
10403 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10404}
10405
e6a84e1e
LB
10406# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
10407#
10408# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10409# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
10410# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
10411# packet sent by OVN logical router
10412test_ip6_packet() {
10413 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
10414 shift 8
10415
10416 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
10417 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
10418
10419 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
10420 echo $reply >> vif$inport.expected
10421
10422 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10423}
10424
0e2751ed
LB
10425ip_to_hex() {
10426 printf "%02x%02x%02x%02x" "$@"
10427}
10428
10429for i in 1 2; do
10430 net_add n$i
10431 ovn-nbctl ls-add sw$i
10432
10433 sim_add hv$i
10434 as hv$i
10435 ovs-vsctl add-br br-phys
10436 ovn_attach n$i br-phys 192.168.$i.1
10437
10438 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
e6a84e1e 10439 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
0e2751ed
LB
10440
10441 ovs-vsctl -- add-port br-int vif$i -- \
10442 set interface vif$i \
10443 external-ids:iface-id=sw$i-p${i}0 \
10444 options:tx_pcap=hv$i/vif$i-tx.pcap \
10445 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10446 ofport-request=$i
10447done
10448
10449ovn-nbctl lr-add lr0
10450for i in 1 2; do
e6a84e1e 10451 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
0e2751ed
LB
10452 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10453 -- set Logical_Switch_Port lrp$i-attachment type=router \
e6a84e1e 10454 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
0e2751ed
LB
10455done
10456
10457OVN_POPULATE_ARP
10458# allow some time for ovn-northd and ovn-controller to catch up.
10459ovn-nbctl --wait=hv sync
10460
10461test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 1 254) 0000 7dae f4ff
e6a84e1e 10462test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
0e2751ed
LB
10463OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10464
10465OVN_CLEANUP([hv1], [hv2])
10466AT_CLEANUP
86558ac2
LB
10467
10468AT_SETUP([ovn -- router port unreachable])
10469AT_KEYWORDS([router-port-unreachable])
10470AT_SKIP_IF([test $HAVE_PYTHON = no])
10471ovn_start
10472
10473# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER L4_PROTCOL IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM EXP_ICMP_CODE
10474#
10475# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10476# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
10477# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
10478# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
10479#
10480# INPORT is a lport number, e.g. 11 for vif11.
10481# HV is a hypervisor number
10482# ETH_SRC and ETH_DST are each 12 hex digits.
10483# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10484# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10485test_ip_packet() {
10486 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
10487 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
10488 shift 11
10489
10490 local ip_ttl=ff
10491 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
10492
10493 local reply_icmp_ttl=fe
10494 local icmp_data=00000000
10495 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
10496 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10497 echo $reply >> vif$inport.expected
10498
10499 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10500}
10501
159932c9
LB
10502# test_tcp_syn_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_ROUTER IP_CHKSUM TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_IP_CHKSUM EXP_TCP_RST_CHKSUM
10503#
10504# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10505# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10506# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
10507#
10508# INPORT is an lport number, e.g. 11 for vif11.
10509# HV is an hypervisor number
10510# ETH_SRC and ETH_DST are each 12 hex digits.
10511# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10512# TCP_SPORT and TCP_DPORT are 4 hex digits.
10513# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10514test_tcp_syn_packet() {
10515 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
10516 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10517 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10518 shift 12
10519
10520 local ip_ttl=ff
10521 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10522
10523 local tcp_rst_ttl=fe
10524 local reply=${eth_src}${eth_dst}08004500002800004000${tcp_rst_ttl}06${exp_ip_chksum}${ip_router}${ipv4_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10525 echo $reply >> vif$inport.expected
10526
10527 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10528}
10529
98af55fc
LB
10530# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
10531#
10532# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
10533# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
10534# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
10535test_tcp6_packet() {
10536 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
10537 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
10538 local exp_tcp_rst_chksum=${10}
10539 shift 10
10540
10541 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
10542 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10543
10544 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10545 echo $reply >> vif$inport.expected
10546
10547 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10548}
10549
4c25c3b8
LB
10550# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
10551#
10552# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10553# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
10554# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
10555test_ip6_packet() {
10556 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_proto=$7 ipv6_len=$8 data=$9
10557 local exp_icmp_code=${10} exp_icmp_chksum=${11}
10558 shift 11
10559
10560 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
10561 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
10562
10563 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
10564 echo $reply >> vif$inport.expected
10565
10566 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10567}
10568
86558ac2
LB
10569ip_to_hex() {
10570 printf "%02x%02x%02x%02x" "$@"
10571}
10572
10573for i in 1 2; do
10574 net_add n$i
10575 ovn-nbctl ls-add sw$i
10576
10577 sim_add hv$i
10578 as hv$i
10579 ovs-vsctl add-br br-phys
10580 ovn_attach n$i br-phys 192.168.$i.1
10581
10582 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
4c25c3b8 10583 lsp-set-addresses sw$i-p${i}0 "00:00:00:00:00:0$i 192.168.$i.1 2001:db8:$i::11"
86558ac2
LB
10584
10585 ovs-vsctl -- add-port br-int vif$i -- \
10586 set interface vif$i \
10587 external-ids:iface-id=sw$i-p${i}0 \
10588 options:tx_pcap=hv$i/vif$i-tx.pcap \
10589 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10590 ofport-request=$i
10591done
10592
10593ovn-nbctl lr-add lr0
10594for i in 1 2; do
4c25c3b8 10595 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.254/24 2001:db8:$i::1/64
86558ac2
LB
10596 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10597 -- set Logical_Switch_Port lrp$i-attachment type=router \
4c25c3b8 10598 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
86558ac2
LB
10599done
10600
10601OVN_POPULATE_ARP
10602# allow some time for ovn-northd and ovn-controller to catch up.
10603ovn-nbctl --wait=hv sync
10604
10605test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 11 0000 7dae fcfc 0303
0e858e05 10606test_ip_packet 1 1 000000000001 00000000ff01 $(ip_to_hex 192 168 1 1) $(ip_to_hex 192 168 1 254) 84 0000 7dae fcfd 0302
4c25c3b8 10607test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
86558ac2
LB
10608OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10609
159932c9 10610test_tcp_syn_packet 2 2 000000000002 00000000ff02 $(ip_to_hex 192 168 2 1) $(ip_to_hex 192 168 2 254) 0000 8b40 3039 0000 7bae 4486
9c937ec5 10611test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
98af55fc 10612test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
159932c9
LB
10613OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
10614
86558ac2
LB
10615OVN_CLEANUP([hv1], [hv2])
10616AT_CLEANUP