]> git.proxmox.com Git - ovs.git/blame - tests/ovn.at
rhel: allow passing more flags to configure, fedora
[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)
6f016174
MM
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",wpad="https://example.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", wpad = "https://example.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.fc.13.68.74.74.70.73.3a.2f.2f.65.78.61.6d.70.6c.65.2e.6f.72.67,pause)
d5a76da4
BP
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
977433d8
JP
1227# log
1228log(verdict=allow, severity=warning);
1229 encodes as controller(userdata=00.00.00.07.00.00.00.00.00.04)
1230log(name="test1", verdict=drop, severity=info);
1231 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31)
1232log(verdict=drop, severity=info, meter="meter1");
1233 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06,meter_id=4)
1234log(name="test1", verdict=drop, severity=info, meter="meter1");
1235 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06.74.65.73.74.31,meter_id=4)
1236log(verdict=drop);
1237 formats as log(verdict=drop, severity=info);
1238 encodes as controller(userdata=00.00.00.07.00.00.00.00.01.06)
1239log(verdict=bad_verdict, severity=info);
1240 Syntax error at `bad_verdict' unknown verdict.
1241log(verdict=drop, severity=bad_severity);
1242 Syntax error at `bad_severity' unknown severity.
1243log(severity=notice);
1244 Syntax error at `;' expecting verdict.
1245
52ed5fcc
NS
1246# put_nd_ra_opts
1247reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64, slla = ae:01:02:03:04:05);
1248 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)
1249 has prereqs ip6
1250reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", slla = ae:01:02:03:04:10, mtu = 1450);
1251 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)
1252 has prereqs ip6
1253reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:06, prefix = aef0::/64);
1254 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)
1255 has prereqs ip6
1256reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::/64);
1257 slla option not present
1258reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1259 prefix option can't be set when address mode is dhcpv6_stateful.
1260reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateful", mtu = 1450, prefix = aef0::/64, prefix = bef0::/64, slla = ae:01:02:03:04:10);
1261 prefix option can't be set when address mode is dhcpv6_stateful.
1262reg1[0] = put_nd_ra_opts(addr_mode = "slaac", slla = ae:01:02:03:04:10);
1263 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1264reg1[0] = put_nd_ra_opts(addr_mode = "dhcpv6_stateless", slla = ae:01:02:03:04:10);
1265 prefix option needs to be set when address mode is slaac/dhcpv6_stateless.
1266reg1[0] = put_nd_ra_opts(addr_mode = dhcpv6_stateless, prefix = aef0::/64, slla = ae:01:02:03:04:10);
1267 Syntax error at `dhcpv6_stateless' expecting constant.
1268reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 1500, prefix = aef0::, slla = ae:01:02:03:04:10);
1269 Invalid value for "prefix" option
1270reg1[0] = put_nd_ra_opts(addr_mode = "foo", mtu = 1500, slla = ae:01:02:03:04:10);
1271 Invalid value for "addr_mode" option
1272reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = "1500", slla = ae:01:02:03:04:10);
1273 IPv6 ND RA option mtu requires numeric value.
1274reg1[0] = put_nd_ra_opts(addr_mode = "slaac", mtu = 10.0.0.4, slla = ae:01:02:03:04:10);
1275 Invalid value for "mtu" option
1276
bc3d6a63
LB
1277# icmp4
1278icmp4 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1279 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)
1280 has prereqs ip4
1281
1282icmp4 { };
1283 formats as icmp4 { drop; };
1284 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1285 has prereqs ip4
1286
3e7fa1e3
LB
1287# icmp6
1288icmp6 { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1289 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)
1290 has prereqs ip6
1291
1292icmp6 { };
1293 formats as icmp6 { drop; };
1294 encodes as controller(userdata=00.00.00.0a.00.00.00.00)
1295 has prereqs ip6
1296
22b65e4d
LB
1297# tcp_reset
1298tcp_reset { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output;
1299 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)
1300 has prereqs tcp
1301
1302tcp_reset { };
1303 formats as tcp_reset { drop; };
1304 encodes as controller(userdata=00.00.00.0b.00.00.00.00)
1305 has prereqs tcp
1306
5f822129 1307# Contradictionary prerequisites (allowed but not useful):
d5a76da4
BP
1308ip4.src = ip6.src[0..31];
1309 encodes as move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[]
1310 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1311ip4.src <-> ip6.src[0..31];
1312 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[]
1313 has prereqs eth.type == 0x800 && eth.type == 0x86dd
1314
1315# Miscellaneous negative tests.
1316;
1317 Syntax error at `;'.
1318xyzzy;
1319 Syntax error at `xyzzy' expecting action.
1320next; 123;
1321 Syntax error at `123'.
1322next; xyzzy;
1323 Syntax error at `xyzzy' expecting action.
1324next
9aef3c1b 1325 Syntax error at end of input expecting `;'.
3b7cb7e1 1326]])
d5a76da4
BP
1327sed '/^[[ ]]/d' test-cases.txt > input.txt
1328cp test-cases.txt expout
3b7cb7e1
BP
1329AT_CHECK([ovstest test-ovn parse-actions < input.txt], [0], [expout])
1330AT_CLEANUP
f295c17b
BP
1331
1332AT_BANNER([OVN end-to-end tests])
1333
9975d7be
BP
1334# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
1335AT_SETUP([ovn -- 3 HVs, 1 LS, 3 lports/HV])
57d143eb 1336AT_KEYWORDS([ovnarp])
f295c17b
BP
1337AT_SKIP_IF([test $HAVE_PYTHON = no])
1338ovn_start
1339
1340# Create hypervisors hv[123].
9975d7be 1341# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
f295c17b
BP
1342# Add all of the vifs to a single logical switch lsw0.
1343# Turn on port security on all the vifs except vif[123]1.
1344# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
1345# Add some ACLs for Ethertypes 1234, 1235, 1236.
ea46a4e9 1346ovn-nbctl ls-add lsw0
f295c17b
BP
1347net_add n1
1348for i in 1 2 3; do
1349 sim_add hv$i
1350 as hv$i
1351 ovs-vsctl add-br br-phys
1352 ovn_attach n1 br-phys 192.168.0.$i
1353
1354 for j in 1 2 3; do
1355 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 1356 ovn-nbctl lsp-add lsw0 lp$i$j
4d5c43d5 1357 if test $j = 1; then
31ed1192 1358 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
f295c17b 1359 else
7dc88496
NS
1360 if test $j = 3; then
1361 ip_addrs="192.168.0.$i$j fe80::ea2a:eaff:fe28:$i$j/64 192.169.0.$i$j"
1362 else
1363 ip_addrs="192.168.0.$i$j"
1364 fi
31ed1192
JP
1365 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j $ip_addrs"
1366 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
f295c17b
BP
1367 fi
1368 done
1369done
1370ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1371ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp11"' drop
1372ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp33"' drop
ea382567
RB
1373ovn-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\"
1374ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp33"' drop
f295c17b 1375
3d2848ba
HZ
1376get_lsp_uuid () {
1377 ovn-nbctl lsp-list lsw0 | grep $1 | awk '{ print $1 }'
1378}
1379
1380ovn-nbctl create Port_Group name=pg1 ports=`get_lsp_uuid lp22`,`get_lsp_uuid lp33`
1381ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1238 && outport == @pg1' drop
1382
f295c17b
BP
1383# Pre-populate the hypervisors' ARP tables so that we don't lose any
1384# packets for ARP resolution (native tunneling doesn't queue packets
1385# for ARP resolution).
74868f2c 1386OVN_POPULATE_ARP
f295c17b
BP
1387
1388# Allow some time for ovn-northd and ovn-controller to catch up.
1389# XXX This should be more systematic.
1390sleep 1
611099dc 1391
fc6f9978
HZ
1392# Make sure there is no attempt to adding duplicated flows by ovn-controller
1393AT_FAIL_IF([test -n "`grep duplicate hv1/ovn-controller.log`"])
1394AT_FAIL_IF([test -n "`grep duplicate hv2/ovn-controller.log`"])
1395AT_FAIL_IF([test -n "`grep duplicate hv3/ovn-controller.log`"])
1396
57d143eb
HZ
1397# Given the name of a logical port, prints the name of the hypervisor
1398# on which it is located.
1399vif_to_hv() {
1400 echo hv${1%?}
1401}
1402
f295c17b
BP
1403# test_packet INPORT DST SRC ETHTYPE OUTPORT...
1404#
1405# This shell function causes a packet to be received on INPORT. The packet's
1406# content has Ethernet destination DST and source SRC (each exactly 12 hex
1407# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1408# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 1409# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
f295c17b
BP
1410for i in 1 2 3; do
1411 for j in 1 2 3; do
1412 : > $i$j.expected
1413 done
1414done
1415test_packet() {
1416 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
57d143eb 1417 hv=`vif_to_hv $inport`
f295c17b
BP
1418 vif=vif$inport
1419 as $hv ovs-appctl netdev-dummy/receive $vif $packet
1420 for outport; do
e4543cfe 1421 echo $packet >> $outport.expected
f295c17b
BP
1422 done
1423}
1424
57d143eb
HZ
1425# test_arp INPORT SHA SPA TPA [REPLY_HA]
1426#
1427# Causes a packet to be received on INPORT. The packet is an ARP
1428# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1429# it should be the hardware address of the target to expect to receive in an
1430# ARP reply; otherwise no reply is expected.
1431#
31ed1192 1432# INPORT is an logical switch port number, e.g. 11 for vif11.
57d143eb
HZ
1433# SHA and REPLY_HA are each 12 hex digits.
1434# SPA and TPA are each 8 hex digits.
1435test_arp() {
1436 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1437 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
1438 hv=`vif_to_hv $inport`
1439 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
1440
92f9822b 1441 if test X$reply_ha = X; then
57d143eb
HZ
1442 # Expect to receive the broadcast ARP on the other logical switch ports
1443 # if no reply is expected.
1444 local i j
1445 for i in 1 2 3; do
1446 for j in 1 2 3; do
1447 if test $i$j != $inport; then
1448 echo $request >> $i$j.expected
1449 fi
1450 done
1451 done
1452 else
1453 # Expect to receive the reply, if any.
1454 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
1455 echo $reply >> $inport.expected
1456 fi
1457}
1458
1459ip_to_hex() {
1460 printf "%02x%02x%02x%02x" "$@"
1461}
1462
f295c17b
BP
1463# Send packets between all pairs of source and destination ports:
1464#
31ed1192
JP
1465# 1. Unicast packets are delivered to exactly one logical switch port
1466# (except that packets destined to their input ports are dropped).
f295c17b 1467#
31ed1192
JP
1468# 2. Broadcast and multicast are delivered to all logical switch ports
1469# except the input port.
f295c17b 1470#
ea46a4e9 1471# 3. When port security is turned on, the switch drops packets from the wrong
f295c17b
BP
1472# MAC address.
1473#
ea46a4e9 1474# 4. The switch drops all packets with a VLAN tag.
f295c17b 1475#
ea46a4e9 1476# 5. The switch drops all packets with a multicast source address. (This only
f295c17b
BP
1477# affects behavior when port security is turned off, since otherwise port
1478# security would drop the packet anyway.)
1479#
ea46a4e9 1480# 6. The switch delivers packets with an unknown destination to logical
31ed1192
JP
1481# switch ports with "unknown" among their MAC addresses (and port
1482# security disabled).
f295c17b 1483#
ea46a4e9 1484# 7. The switch drops unicast packets that violate an ACL.
f295c17b 1485#
ea46a4e9 1486# 8. The switch drops multicast and broadcast packets that violate an ACL.
57d143eb 1487#
9fcb6a18
BP
1488# 9. OVN generates responses to ARP requests for known IPs, except for
1489# requests from a port for the port's own IP.
57d143eb
HZ
1490#
1491# 10. No response to ARP requests for unknown IPs.
4acd1e87 1492
f295c17b
BP
1493for is in 1 2 3; do
1494 for js in 1 2 3; do
1495 s=$is$js
1496 bcast=
4d5c43d5
JP
1497 unknown=
1498 bacl2=
1499 bacl3=
f295c17b
BP
1500 for id in 1 2 3; do
1501 for jd in 1 2 3; do
1502 d=$id$jd
1503
1504 if test $d != $s; then unicast=$d; else unicast=; fi
1505 test_packet $s f000000000$d f000000000$s $s$d $unicast #1
1506
1507 if test $d != $s && test $js = 1; then
4d5c43d5
JP
1508 impersonate=$d
1509 else
1510 impersonate=
1511 fi
f295c17b
BP
1512 test_packet $s f000000000$d f00000000055 55$d $impersonate #3
1513
4d5c43d5
JP
1514 if test $d != $s && test $s != 11; then acl2=$d; else acl2=; fi
1515 if test $d != $s && test $d != 33; then acl3=$d; else acl3=; fi
e137131a 1516 if test $d = $s || (test $js = 1 && test $d = 33); then
ea382567
RB
1517 # Source of 11, 21, or 31 and dest of 33 should be dropped
1518 # due to the 4th ACL that uses address_set(set1).
1519 acl4=
1520 else
1521 acl4=$d
1522 fi
3d2848ba
HZ
1523 if test $d = $s || test $d = 22 || test $d = 33; then
1524 # dest of 22 and 33 should be dropped
1525 # due to the 5th ACL that uses port_group(pg1).
1526 acl5=
1527 else
1528 acl5=$d
1529 fi
f295c17b
BP
1530 test_packet $s f000000000$d f000000000$s 1234 #7, acl1
1531 test_packet $s f000000000$d f000000000$s 1235 $acl2 #7, acl2
1532 test_packet $s f000000000$d f000000000$s 1236 $acl3 #7, acl3
ea382567 1533 test_packet $s f000000000$d f000000000$s 1237 $acl4 #7, acl4
3d2848ba 1534 test_packet $s f000000000$d f000000000$s 1238 $acl5 #7, acl5
f295c17b
BP
1535
1536 test_packet $s f000000000$d f00000000055 810000091234 #4
1537 test_packet $s f000000000$d 0100000000$s $s$d #5
1538
4d5c43d5
JP
1539 if test $d != $s && test $jd = 1; then
1540 unknown="$unknown $d"
1541 fi
f295c17b
BP
1542 bcast="$bcast $unicast"
1543 bacl2="$bacl2 $acl2"
1544 bacl3="$bacl3 $acl3"
57d143eb 1545
db02f370 1546 sip=`ip_to_hex 192 168 0 $is$js`
57d143eb
HZ
1547 tip=`ip_to_hex 192 168 0 $id$jd`
1548 tip_unknown=`ip_to_hex 11 11 11 11`
9fcb6a18
BP
1549 if test $d != $s; then
1550 reply_ha=f000000000$d
1551 else
1552 reply_ha=
1553 fi
1554 test_arp $s f000000000$s $sip $tip $reply_ha #9
57d143eb 1555 test_arp $s f000000000$s $sip $tip_unknown #10
7dc88496
NS
1556
1557 if test $jd = 3; then
31ed1192 1558 # lsp[123]3 has an additional ip 192.169.0.[123]3.
7dc88496 1559 tip=`ip_to_hex 192 169 0 $id$jd`
9fcb6a18 1560 test_arp $s f000000000$s $sip $tip $reply_ha #9
7dc88496 1561 fi
f295c17b
BP
1562 done
1563 done
1564
4d5c43d5 1565 # Broadcast and multicast.
f295c17b
BP
1566 test_packet $s ffffffffffff f000000000$s ${s}ff $bcast #2
1567 test_packet $s 010000000000 f000000000$s ${s}ff $bcast #2
4d5c43d5 1568 if test $js = 1; then
f295c17b
BP
1569 bcast_impersonate=$bcast
1570 else
4d5c43d5
JP
1571 bcast_impersonate=
1572 fi
f295c17b
BP
1573 test_packet $s 010000000000 f00000000044 44ff $bcast_impersonate #3
1574
1575 test_packet $s f0000000ffff f000000000$s ${s}66 $unknown #6
1576
1577 test_packet $s ffffffffffff f000000000$s 1234 #8, acl1
1578 test_packet $s ffffffffffff f000000000$s 1235 $bacl2 #8, acl2
1579 test_packet $s ffffffffffff f000000000$s 1236 $bacl3 #8, acl3
1580 test_packet $s 010000000000 f000000000$s 1234 #8, acl1
1581 test_packet $s 010000000000 f000000000$s 1235 $bacl2 #8, acl2
1582 test_packet $s 010000000000 f000000000$s 1236 $bacl3 #8, acl3
1583 done
1584done
1585
7dc88496
NS
1586# set address for lp13 with invalid characters.
1587# lp13 should be configured with only 192.168.0.13.
31ed1192 1588ovn-nbctl lsp-set-addresses lp13 "f0:00:00:00:00:13 192.168.0.13 invalid 192.169.0.13"
3b8cd0ea
BP
1589
1590# Allow some time for ovn-northd and ovn-controller to catch up.
1591# XXX This should be more systematic.
1592sleep 1
1593
7dc88496
NS
1594sip=`ip_to_hex 192 168 0 11`
1595tip=`ip_to_hex 192 168 0 13`
1596test_arp 11 f00000000011 $sip $tip f00000000013
1597
1598tip=`ip_to_hex 192 169 0 13`
1599#arp request for 192.169.0.13 should be flooded
1600test_arp 11 f00000000011 $sip $tip
1601
91125642 1602# dump information and flows with counters
bb0c41d3
RM
1603ovn-sbctl dump-flows -- list multicast_group
1604
1605echo "------ hv1 dump ------"
1606as hv1 ovs-vsctl show
1607as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
1608
1609echo "------ hv2 dump ------"
1610as hv2 ovs-vsctl show
1611as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
1612
1613echo "------ hv3 dump ------"
1614as hv3 ovs-vsctl show
1615as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
49d7c759 1616
f295c17b
BP
1617# Now check the packets actually received against the ones expected.
1618for i in 1 2 3; do
1619 for j in 1 2 3; do
49d7c759 1620 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
f295c17b
BP
1621 done
1622done
fcde56f5 1623
7a8f15e0 1624OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 1625
f295c17b 1626AT_CLEANUP
eb6b08eb 1627
4acd1e87
BP
1628AT_SETUP([ovn -- trace 1 LS, 3 LSPs])
1629AT_SKIP_IF([test $HAVE_PYTHON = no])
1630ovn_start
1631
1632# Create a logical switch and some logical ports.
1633# Turn on port security on all lports except ls1.
1634# Make ls1 a destination for unknown MACs.
1635# Add some ACLs for Ethertypes 1234, 1235, 1236.
1636ovn-nbctl ls-add lsw0
1637ovn-sbctl chassis-add hv0 geneve 127.0.0.1
1638for i in 1 2 3; do
1639 ovn-nbctl lsp-add lsw0 lp$i
7979c444
BP
1640done
1641ovn-nbctl --wait=sb sync
1642for i in 1 2 3; do
4acd1e87
BP
1643 ovn-sbctl lsp-bind lp$i hv0
1644 if test $i = 1; then
abb37b6b 1645 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i 192.168.0.$i" unknown
4acd1e87 1646 else
abb37b6b
FF
1647 if test $i = 3; then
1648 ip_addrs="192.168.0.$i fe80::ea2a:eaff:fe28:$i/64 192.169.0.$i"
1649 else
1650 ip_addrs="192.168.0.$i"
1651 fi
a8e2addc
LR
1652 ovn-nbctl lsp-set-addresses lp$i "f0:00:00:00:00:0$i $ip_addrs"
1653 ovn-nbctl lsp-set-port-security lp$i f0:00:00:00:00:0$i
4acd1e87
BP
1654 fi
1655done
1656ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1234' drop
1657ovn-nbctl acl-add lsw0 from-lport 1000 'eth.type == 0x1235 && inport == "lp1"' drop
1658ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1236 && outport == "lp3"' drop
1659ovn-nbctl create Address_Set name=set1 addresses=\"f0:00:00:00:00:01\",\"f0:00:00:00:00:02\"
1660ovn-nbctl acl-add lsw0 to-lport 1000 'eth.type == 0x1237 && eth.src == $set1 && outport == "lp3"' drop
1661
1662ovn-nbctl --wait=sb sync
1663on_exit 'kill `cat ovn-trace.pid`'
1664ovn-trace --detach --pidfile --no-chdir
1665
1666# test_packet INPORT DST SRC [-vlan] [-eth TYPE] OUTPORT...
1667#
1668# This shell function causes a packet to be received on INPORT. The packet's
1669# content has Ethernet destination DST and source SRC (each exactly 12 hex
1670# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
1671# more) list the VIFs on which the packet should be received. INPORT and the
1672# OUTPORTs are specified as logical switch port numbers, e.g. 11 for vif11.
1673test_packet() {
1674 local inport=$1 eth_dst=$2 eth_src=$3; shift; shift; shift
1675 uflow="inport==\"lp$inport\" && eth.dst==$eth_dst && eth.src==$eth_src"
1676 while :; do
abb37b6b
FF
1677 case $1 in # (
1678 -vlan) uflow="$uflow && vlan.vid == 1234"; shift ;; # (
1679 -eth) uflow="$uflow && eth.type == 0x$2"; shift; shift ;; # (
1680 *) break ;;
1681 esac
4acd1e87
BP
1682 done
1683 for outport; do
abb37b6b 1684 echo "output(\"lp$outport\");"
4acd1e87
BP
1685 done > expout
1686
1687 AT_CAPTURE_FILE([trace])
1688 AT_CHECK([ovs-appctl -t ovn-trace trace --all lsw0 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1689}
1690
1691# test_arp INPORT SHA SPA TPA [REPLY_HA]
1692#
1693# Causes a packet to be received on INPORT. The packet is an ARP
1694# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
1695# it should be the hardware address of the target to expect to receive in an
1696# ARP reply; otherwise no reply is expected.
1697#
1698# INPORT is an logical switch port number, e.g. 11 for vif11.
1699# SHA and REPLY_HA are each 12 hex digits.
1700# SPA and TPA are each 8 hex digits.
1701test_arp() {
1702 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
1703
1704 local request="inport == \"lp$inport\"
1705 && eth.dst == ff:ff:ff:ff:ff:ff && eth.src == $sha
1706 && arp.op == 1 && arp.sha == $sha && arp.spa == $spa
abb37b6b 1707 && arp.tha == ff:ff:ff:ff:ff:ff && arp.tpa == $tpa"
4acd1e87
BP
1708
1709 if test -z "$reply_ha"; then
1710 reply=
abb37b6b
FF
1711 local i
1712 for i in 1 2 3; do
1713 if test $i != $inport; then
1714 reply="${reply}output(\"lp$i\");
4acd1e87 1715"
abb37b6b
FF
1716 fi
1717 done
4acd1e87
BP
1718 else
1719 reply="\
1720eth.dst = $sha;
1721eth.src = $reply_ha;
1722arp.op = 2;
1723arp.tha = $sha;
1724arp.sha = $reply_ha;
1725arp.tpa = $spa;
1726arp.spa = $tpa;
1727output(\"lp$inport\");
1728"
1729 fi
1730
1731 AT_CAPTURE_FILE([trace])
1732 AT_CHECK_UNQUOTED([ovs-appctl -t ovn-trace trace --all lsw0 "$request" | tee trace | sed '1,/Minimal trace/d'], [0], [$reply])
1733}
1734
1735# Send packets between all pairs of source and destination ports:
1736#
1737# 1. Unicast packets are delivered to exactly one logical switch port
1738# (except that packets destined to their input ports are dropped).
1739#
1740# 2. Broadcast and multicast are delivered to all logical switch ports
1741# except the input port.
1742#
1743# 3. When port security is turned on, the switch drops packets from the wrong
1744# MAC address.
1745#
1746# 4. The switch drops all packets with a VLAN tag.
1747#
1748# 5. The switch drops all packets with a multicast source address. (This only
1749# affects behavior when port security is turned off, since otherwise port
1750# security would drop the packet anyway.)
1751#
1752# 6. The switch delivers packets with an unknown destination to logical
1753# switch ports with "unknown" among their MAC addresses (and port
1754# security disabled).
1755#
1756# 7. The switch drops unicast packets that violate an ACL.
1757#
1758# 8. The switch drops multicast and broadcast packets that violate an ACL.
1759#
9fcb6a18
BP
1760# 9. OVN generates responses to ARP requests for known IPs, except for
1761# requests from a port for the port's own IP.
4acd1e87
BP
1762#
1763# 10. No response to ARP requests for unknown IPs.
1764
1765for s in 1 2 3; do
1766 bcast=
1767 unknown=
1768 bacl2=
1769 bacl3=
1770 for d in 1 2 3; do
abb37b6b
FF
1771 echo
1772 echo "lp$s -> lp$d"
1773 if test $d != $s; then unicast=$d; else unicast=; fi
1774 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s $unicast #1
1775
1776 if test $d != $s && test $s = 1; then
1777 impersonate=$d
1778 else
1779 impersonate=
1780 fi
1781 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 $impersonate #3
1782
1783 if test $d != $s && test $s != 1; then acl2=$d; else acl2=; fi
1784 if test $d != $s && test $d != 3; then acl3=$d; else acl3=; fi
1785 if test $d = $s || ( (test $s = 1 || test $s = 2) && test $d = 3); then
1786 # Source of 1 or 2 and dest of 3 should be dropped
1787 # due to the 4th ACL that uses address_set(set1).
1788 acl4=
1789 else
1790 acl4=$d
1791 fi
1792
1793 #7, acl1 to acl4:
1794 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1234
1795 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1235 $acl2
1796 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1236 $acl3
1797 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:0$s -eth 1237 $acl4
1798
1799 test_packet $s f0:00:00:00:00:0$d f0:00:00:00:00:55 -vlan #4
1800 test_packet $s f0:00:00:00:00:0$d 01:00:00:00:00:0$s #5
1801
1802 if test $d != $s && test $d = 1; then
1803 unknown="$unknown $d"
1804 fi
1805 bcast="$bcast $unicast"
1806 bacl2="$bacl2 $acl2"
1807 bacl3="$bacl3 $acl3"
1808
1809 sip=192.168.0.$s
1810 tip=192.168.0.$d
1811 tip_unknown=11.11.11.11
9fcb6a18
BP
1812 if test $d != $s; then reply_ha=f0:00:00:00:00:0$d; else reply_ha=; fi
1813 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b
FF
1814 test_arp $s f0:00:00:00:00:0$s $sip $tip_unknown #10
1815
1816 if test $d = 3; then
1817 # lp3 has an additional ip 192.169.0.[123]3.
1818 tip=192.169.0.$d
9fcb6a18 1819 test_arp $s f0:00:00:00:00:0$s $sip $tip $reply_ha #9
abb37b6b 1820 fi
4acd1e87
BP
1821 done
1822
1823 # Broadcast and multicast.
1824 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s $bcast #2
1825 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s $bcast #2
1826 if test $s = 1; then
abb37b6b 1827 bcast_impersonate=$bcast
4acd1e87 1828 else
abb37b6b 1829 bcast_impersonate=
4acd1e87
BP
1830 fi
1831 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:44 $bcast_impersonate #3
1832
1833 test_packet $s f0:00:00:00:ff:ff f0:00:00:00:00:0$s $unknown #6
1834
1835 #8, acl1 to acl3:
1836 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1234
1837 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1235 $bacl2
1838 test_packet $s ff:ff:ff:ff:ff:ff f0:00:00:00:00:0$s -eth 1236 $bacl3
1839
1840 #8, acl1 to acl3:
1841 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1234
1842 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1235 $bacl2
1843 test_packet $s 01:00:00:00:00:00 f0:00:00:00:00:0$s -eth 1236 $bacl3
1844done
1845
1846AT_CLEANUP
1847
7277bc83
RB
1848# 2 hypervisors, 4 logical ports per HV
1849# 2 locally attached networks (one flat, one vlan tagged over same device)
1850# 2 ports per HV on each network
e90aeb57 1851AT_SETUP([ovn -- 2 HVs, 4 lports/HV, localnet ports])
d79fc5f4
RB
1852AT_SKIP_IF([test $HAVE_PYTHON = no])
1853ovn_start
1854
ea46a4e9
JP
1855# In this test cases we create 3 switches, all connected to same
1856# physical network (through br-phys on each HV). Each switch has
0ee7f7f1
HZ
1857# VIF ports across 2 HVs. Each HV has 5 VIF ports. The first digit
1858# of VIF port name indicates the hypervisor it is bound to, e.g.
1859# lp23 means VIF 3 on hv2.
1860#
ea46a4e9 1861# Each switch's VLAN tag and their logical switch ports are:
0ee7f7f1
HZ
1862# - ls1:
1863# - untagged
ea46a4e9 1864# - ports: lp11, lp12, lp21, lp22
0ee7f7f1
HZ
1865#
1866# - ls2:
1867# - tagged with VLAN 101
ea46a4e9 1868# - ports: lp13, lp14, lp23, lp24
0ee7f7f1
HZ
1869# - ls3:
1870# - untagged
ea46a4e9 1871# - ports: lp15, lp25
0ee7f7f1 1872#
ea46a4e9 1873# Note: a localnet port is created for each switch to connect to
0ee7f7f1
HZ
1874# physical network.
1875
1876for i in 1 2 3; do
ea46a4e9
JP
1877 ls_name=ls$i
1878 ovn-nbctl ls-add $ls_name
0ee7f7f1
HZ
1879 ln_port_name=ln$i
1880 if test $i -eq 2; then
ea46a4e9 1881 ovn-nbctl lsp-add $ls_name $ln_port_name "" 101
0ee7f7f1 1882 else
ea46a4e9 1883 ovn-nbctl lsp-add $ls_name $ln_port_name
0ee7f7f1 1884 fi
31ed1192
JP
1885 ovn-nbctl lsp-set-addresses $ln_port_name unknown
1886 ovn-nbctl lsp-set-type $ln_port_name localnet
1887 ovn-nbctl lsp-set-options $ln_port_name network_name=phys
0ee7f7f1 1888done
d79fc5f4 1889
69b72264
BP
1890# lsp_to_ls LSP
1891#
1892# Prints the name of the logical switch that contains LSP.
1893lsp_to_ls () {
1894 case $1 in dnl (
5a0e4aec
BP
1895 lp?[[12]]) echo ls1 ;; dnl (
1896 lp?[[34]]) echo ls2 ;; dnl (
1897 lp?5) echo ls3 ;; dnl (
1898 *) AT_FAIL_IF([:]) ;;
69b72264
BP
1899 esac
1900}
1901
d79fc5f4
RB
1902net_add n1
1903for i in 1 2; do
1904 sim_add hv$i
1905 as hv$i
1906 ovs-vsctl add-br br-phys
1907 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
1908 ovn_attach n1 br-phys 192.168.0.$i
1909
0ee7f7f1 1910 for j in 1 2 3 4 5; do
d79fc5f4
RB
1911 ovs-vsctl add-port br-int vif$i$j -- \
1912 set Interface vif$i$j external-ids:iface-id=lp$i$j \
1913 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
1914 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
1915 ofport-request=$i$j
1916
31ed1192 1917 lsp_name=lp$i$j
5a0e4aec 1918 ls_name=$(lsp_to_ls $lsp_name)
d79fc5f4 1919
ea46a4e9 1920 ovn-nbctl lsp-add $ls_name $lsp_name
31ed1192
JP
1921 ovn-nbctl lsp-set-addresses $lsp_name f0:00:00:00:00:$i$j
1922 ovn-nbctl lsp-set-port-security $lsp_name f0:00:00:00:00:$i$j
d79fc5f4 1923
31ed1192 1924 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up $lsp_name` = xup])
d79fc5f4
RB
1925 done
1926done
69b72264
BP
1927ovn-nbctl --wait=sb sync
1928ovn-sbctl dump-flows
d79fc5f4 1929
74868f2c 1930OVN_POPULATE_ARP
d79fc5f4
RB
1931
1932# XXX This is now the 3rd copy of these functions in this file ...
1933
1934# Given the name of a logical port, prints the name of the hypervisor
1935# on which it is located.
1936vif_to_hv() {
1937 echo hv${1%?}
1938}
1939#
69b72264 1940# test_packet INPORT DST SRC ETHTYPE EOUT LOUT
d79fc5f4
RB
1941#
1942# This shell function causes a packet to be received on INPORT. The packet's
1943# content has Ethernet destination DST and source SRC (each exactly 12 hex
69b72264
BP
1944# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
1945# logical switch port numbers, e.g. 11 for vif11.
1946#
1947# EOUT is the end-to-end output port, that is, where the packet will end up
1948# after possibly bouncing through one or more localnet ports. LOUT is the
1949# logical output port, which might be a localnet port, as seen by ovn-trace
1950# (which doesn't know what localnet ports are connected to and therefore can't
1951# figure out the end-to-end answer).
d79fc5f4 1952for i in 1 2; do
0ee7f7f1 1953 for j in 1 2 3 4 5; do
d79fc5f4
RB
1954 : > $i$j.expected
1955 done
1956done
1957test_packet() {
69b72264
BP
1958 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6
1959 echo "$@"
1960
1961 # First try tracing the packet.
1962 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
1963 if test $lout != drop; then
1964 echo "output(\"$lout\");"
1965 fi > expout
1966 AT_CAPTURE_FILE([trace])
1967 AT_CHECK([ovn-trace --all $(lsp_to_ls lp$inport) "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
1968
1969 # Then actually send a packet, for an end-to-end test.
1970 local packet=$(echo $dst$src | sed 's/://g')${eth}
d79fc5f4
RB
1971 hv=`vif_to_hv $inport`
1972 vif=vif$inport
1973 as $hv ovs-appctl netdev-dummy/receive $vif $packet
69b72264
BP
1974 if test $eout != drop; then
1975 echo $packet >> ${eout#lp}.expected
1976 fi
d79fc5f4
RB
1977}
1978
7277bc83
RB
1979# lp11 and lp21 are on the same network (phys, untagged)
1980# and on different hypervisors
69b72264
BP
1981test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
1982test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
d79fc5f4 1983
7277bc83
RB
1984# lp11 and lp12 are on the same network (phys, untagged)
1985# and on the same hypervisor
69b72264
BP
1986test_packet 11 f0:00:00:00:00:12 f0:00:00:00:00:11 1112 lp12 lp12
1987test_packet 12 f0:00:00:00:00:11 f0:00:00:00:00:12 1211 lp11 lp11
7277bc83
RB
1988
1989# lp13 and lp23 are on the same network (phys, VLAN 101)
1990# and on different hypervisors
69b72264
BP
1991test_packet 13 f0:00:00:00:00:23 f0:00:00:00:00:13 1323 lp23 lp23
1992test_packet 23 f0:00:00:00:00:13 f0:00:00:00:00:23 2313 lp13 lp13
7277bc83
RB
1993
1994# lp13 and lp14 are on the same network (phys, VLAN 101)
1995# and on the same hypervisor
69b72264
BP
1996test_packet 13 f0:00:00:00:00:14 f0:00:00:00:00:13 1314 lp14 lp14
1997test_packet 14 f0:00:00:00:00:13 f0:00:00:00:00:14 1413 lp13 lp13
d79fc5f4 1998
0ee7f7f1 1999# lp11 and lp15 are on the same network (phys, untagged),
ea46a4e9 2000# same hypervisor, and on different switches
69b72264
BP
2001test_packet 11 f0:00:00:00:00:15 f0:00:00:00:00:11 1115 lp15 ln1
2002test_packet 15 f0:00:00:00:00:11 f0:00:00:00:00:15 1511 lp11 ln3
0ee7f7f1
HZ
2003
2004# lp11 and lp25 are on the same network (phys, untagged),
ea46a4e9 2005# different hypervisors, and on different switches
69b72264
BP
2006test_packet 11 f0:00:00:00:00:25 f0:00:00:00:00:11 1125 lp25 ln1
2007test_packet 25 f0:00:00:00:00:11 f0:00:00:00:00:25 2511 lp11 ln3
0ee7f7f1 2008
d79fc5f4 2009# Ports that should not be able to communicate
69b72264
BP
2010test_packet 11 f0:00:00:00:00:13 f0:00:00:00:00:11 1113 drop ln1
2011test_packet 11 f0:00:00:00:00:23 f0:00:00:00:00:11 1123 drop ln1
2012test_packet 21 f0:00:00:00:00:13 f0:00:00:00:00:21 2113 drop ln1
2013test_packet 21 f0:00:00:00:00:23 f0:00:00:00:00:21 2123 drop ln1
2014test_packet 13 f0:00:00:00:00:11 f0:00:00:00:00:13 1311 drop ln2
2015test_packet 13 f0:00:00:00:00:21 f0:00:00:00:00:13 1321 drop ln2
2016test_packet 23 f0:00:00:00:00:11 f0:00:00:00:00:23 2311 drop ln2
2017test_packet 23 f0:00:00:00:00:21 f0:00:00:00:00:23 2321 drop ln2
d79fc5f4 2018
d79fc5f4
RB
2019# Dump a bunch of info helpful for debugging if there's a failure.
2020
2021echo "------ OVN dump ------"
2022ovn-nbctl show
2023ovn-sbctl show
2024
2025echo "------ hv1 dump ------"
2026as hv1 ovs-vsctl show
2027as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2028
2029echo "------ hv2 dump ------"
2030as hv2 ovs-vsctl show
2031as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2032
2033# Now check the packets actually received against the ones expected.
2034for i in 1 2; do
0ee7f7f1 2035 for j in 1 2 3 4 5; do
49d7c759 2036 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
d79fc5f4
RB
2037 done
2038done
2039
7a8f15e0 2040OVN_CLEANUP([hv1],[hv2])
d9c8c57c 2041
d79fc5f4
RB
2042AT_CLEANUP
2043
91125642
FF
2044AT_SETUP([ovn -- vtep: 3 HVs, 1 VIFs/HV, 1 GW, 1 LS])
2045AT_KEYWORDS([vtep])
eb6b08eb
JP
2046AT_SKIP_IF([test $HAVE_PYTHON = no])
2047ovn_start
2048
2049# Configure the Northbound database
ea46a4e9 2050ovn-nbctl ls-add lsw0
eb6b08eb 2051
31ed1192
JP
2052ovn-nbctl lsp-add lsw0 lp1
2053ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
eb6b08eb 2054
31ed1192
JP
2055ovn-nbctl lsp-add lsw0 lp2
2056ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
eb6b08eb 2057
31ed1192
JP
2058ovn-nbctl lsp-add lsw0 lp-vtep
2059ovn-nbctl lsp-set-type lp-vtep vtep
2060ovn-nbctl lsp-set-options lp-vtep vtep-physical-switch=br-vtep vtep-logical-switch=lsw0
2061ovn-nbctl lsp-set-addresses lp-vtep unknown
eb6b08eb 2062
77adbb62
DB
2063# lpr, lr and lrp1 are used for the ARP request handling test only.
2064ovn-nbctl lsp-add lsw0 lpr
2065ovn-nbctl lr-add lr
2066ovn-nbctl lrp-add lr lrp1 f0:00:00:00:00:f1 192.168.1.1/24
2067ovn-nbctl set Logical_Switch_Port lpr type=router \
2068 options:router-port=lrp1 \
2069 addresses='"f0:00:00:00:00:f1 192.168.1.1"'
2070
2071
eb6b08eb
JP
2072net_add n1 # Network to connect hv1, hv2, and vtep
2073net_add n2 # Network to connect vtep and hv3
2074
2075# Create hypervisor hv1 connected to n1
2076sim_add hv1
2077as hv1
2078ovs-vsctl add-br br-phys
2079ovn_attach n1 br-phys 192.168.0.1
2080ovs-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
2081
2082# Create hypervisor hv2 connected to n1
2083sim_add hv2
2084as hv2
2085ovs-vsctl add-br br-phys
2086ovn_attach n1 br-phys 192.168.0.2
2087ovs-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
2088
2089
2090# Start the vtep emulator with a leg in both networks
2091sim_add vtep
2092as vtep
2093
2094ovsdb-tool create "$ovs_base"/vtep/vtep.db "$abs_top_srcdir"/vtep/vtep.ovsschema || return 1
2095ovs-appctl -t ovsdb-server ovsdb-server/add-db "$ovs_base"/vtep/vtep.db
2096
2097ovs-vsctl add-br br-phys
2098net_attach n1 br-phys
2099
2100mac=`ovs-vsctl get Interface br-phys mac_in_use | sed s/\"//g`
2101arp_table="$arp_table $sandbox,br-phys,192.168.0.3,$mac"
2102ovs-appctl netdev-dummy/ip4addr br-phys 192.168.0.3/24 >/dev/null || return 1
2103ovs-appctl ovs/route/add 192.168.0.3/24 br-phys >/dev/null || return 1
2104
2105ovs-vsctl add-br br-vtep
2106net_attach n2 br-vtep
2107
2108vtep-ctl add-ps br-vtep
2109vtep-ctl set Physical_Switch br-vtep tunnel_ips=192.168.0.3
2110vtep-ctl add-ls lsw0
2111
2112start_daemon ovs-vtep br-vtep
2113start_daemon ovn-controller-vtep --vtep-db=unix:"$ovs_base"/vtep/db.sock --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
2114
8cdc4312 2115OVS_WAIT_UNTIL([vtep-ctl bind-ls br-vtep br-vtep_n2 0 lsw0])
eb6b08eb 2116
475f0a2c
DB
2117OVS_WAIT_UNTIL([test -n "`as vtep vtep-ctl get-replication-mode lsw0 |
2118 grep -- source`"])
2119# It takes more time for the update to be processed by ovs-vtep.
eb6b08eb
JP
2120sleep 1
2121
2122# Add hv3 on the other side of the vtep
2123sim_add hv3
2124as hv3
2125ovs-vsctl add-br br-phys
2126net_attach n2 br-phys
2127
2128ovs-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
2129
2130# Pre-populate the hypervisors' ARP tables so that we don't lose any
2131# packets for ARP resolution (native tunneling doesn't queue packets
2132# for ARP resolution).
74868f2c 2133OVN_POPULATE_ARP
eb6b08eb
JP
2134
2135# Allow some time for ovn-northd and ovn-controller to catch up.
2136# XXX This should be more systematic.
2137sleep 1
6977df72 2138
eb6b08eb
JP
2139# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2140#
2141# This shell function causes a packet to be received on INPORT. The packet's
2142# content has Ethernet destination DST and source SRC (each exactly 12 hex
2143# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2144# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2145# OUTPORTs are specified as logical switch port numbers, e.g. 1 for vif1.
eb6b08eb
JP
2146for i in 1 2 3; do
2147 : > $i.expected
2148done
2149test_packet() {
2150 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2151 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2152 hv=hv$inport
2153 vif=vif$inport
2154 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2155 for outport; do
e4543cfe 2156 echo $packet >> $outport.expected
eb6b08eb
JP
2157 done
2158}
2159
2160# Send packets between all pairs of source and destination ports:
2161#
31ed1192
JP
2162# 1. Unicast packets are delivered to exactly one logical switch port
2163# (except that packets destined to their input ports are dropped).
eb6b08eb 2164#
31ed1192
JP
2165# 2. Broadcast and multicast are delivered to all logical switch ports
2166# except the input port.
eb6b08eb 2167#
ea46a4e9 2168# 3. The switch delivers packets with an unknown destination to logical
31ed1192
JP
2169# switch ports with "unknown" among their MAC addresses (and port
2170# security disabled).
eb6b08eb
JP
2171for s in 1 2 3; do
2172 bcast=
2173 unknown=
2174 for d in 1 2 3; do
2175 if test $d != $s; then unicast=$d; else unicast=; fi
2176 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2177
2178 # The vtep (vif3) is the only one configured for "unknown"
2179 if test $d != $s && test $d = 3; then
2180 unknown="$unknown $d"
2181 fi
2182 bcast="$bcast $unicast"
2183 done
2184
2185 # Broadcast and multicast.
46ed1382
DB
2186 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2187 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #2
eb6b08eb
JP
2188
2189 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #3
2190done
2191
77adbb62
DB
2192# ARP request should not be responded to by logical switch router
2193# type arp responder on HV1 and HV2 and should reach directly to
2194# vif1 and vif2
2195ip_to_hex() {
2196 printf "%02x%02x%02x%02x" "$@"
2197}
2198sha=f00000000003
2199spa=`ip_to_hex 192 168 1 2`
2200tpa=`ip_to_hex 192 168 1 1`
2201request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2202as hv3 ovs-appctl netdev-dummy/receive vif3 $request
2203echo $request >> 1.expected
2204echo $request >> 2.expected
2205
bb0c41d3
RM
2206# dump information with counters
2207echo "------ OVN dump ------"
2208ovn-nbctl show
2209ovn-sbctl show
2210
77adbb62
DB
2211echo "---------SB dump-----"
2212ovn-sbctl list datapath_binding
2213echo "---------------------"
2214ovn-sbctl list port_binding
2215echo "---------------------"
2216ovn-sbctl dump-flows
2217
bb0c41d3
RM
2218echo "------ hv1 dump ------"
2219as hv1 ovs-vsctl show
6195e2e7 2220as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2221as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2222
2223echo "------ hv2 dump ------"
2224as hv2 ovs-vsctl show
6195e2e7 2225as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
2226as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2227
2228echo "------ hv3 dump ------"
2229as hv3 ovs-vsctl show
6754e92d
FF
2230# note: hv3 has no logical port bind, thus it should not have br-int
2231AT_CHECK([as hv3 ovs-ofctl -O OpenFlow13 show br-int], [1], [],
2232[ovs-ofctl: br-int is not a bridge or a socket
2233])
bb0c41d3 2234
eb6b08eb
JP
2235# Now check the packets actually received against the ones expected.
2236for i in 1 2 3; do
49d7c759 2237 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
eb6b08eb 2238done
fcde56f5
LR
2239
2240# Gracefully terminate daemons
7a8f15e0
LR
2241OVN_CLEANUP([hv1],[hv2],[vtep])
2242OVN_CLEANUP_VSWITCH([hv3])
d9c8c57c 2243
eb6b08eb 2244AT_CLEANUP
9975d7be 2245
184bc3ca
RB
2246# Similar test to "hardware GW"
2247AT_SETUP([ovn -- 3 HVs, 1 VIFs/HV, 1 software GW, 1 LS])
2248AT_SKIP_IF([test $HAVE_PYTHON = no])
2249ovn_start
2250
2251# Configure the Northbound database
2252ovn-nbctl ls-add lsw0
2253
2254ovn-nbctl lsp-add lsw0 lp1
2255ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
2256
2257ovn-nbctl lsp-add lsw0 lp2
2258ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
2259
2260ovn-nbctl lsp-add lsw0 lp-gw
2261ovn-nbctl lsp-set-type lp-gw l2gateway
62b87eab 2262ovn-nbctl lsp-set-options lp-gw network_name=physnet1 l2gateway-chassis=hv_gw
184bc3ca
RB
2263ovn-nbctl lsp-set-addresses lp-gw unknown
2264
2265net_add n1 # Network to connect hv1, hv2, and gw
2266net_add n2 # Network to connect gw and hv3
2267
2268# Create hypervisor hv1 connected to n1
2269sim_add hv1
2270as hv1
2271ovs-vsctl add-br br-phys
2272ovn_attach n1 br-phys 192.168.0.1
2273ovs-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
2274
2275# Create hypervisor hv2 connected to n1
2276sim_add hv2
2277as hv2
2278ovs-vsctl add-br br-phys
2279ovn_attach n1 br-phys 192.168.0.2
2280ovs-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
2281
2282# Create hypervisor hv_gw connected to n1 and n2
2283# connect br-phys bridge to n1; connect hv-gw bridge to n2
2284sim_add hv_gw
2285as hv_gw
2286ovs-vsctl add-br br-phys
2287ovn_attach n1 br-phys 192.168.0.3
2288ovs-vsctl add-br br-phys2
2289net_attach n2 br-phys2
2290ovs-vsctl set open . external_ids:ovn-bridge-mappings="physnet1:br-phys2"
2291
184bc3ca
RB
2292# Add hv3 on the other side of the GW
2293sim_add hv3
2294as hv3
2295ovs-vsctl add-br br-phys
2296net_attach n2 br-phys
2297ovs-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
2298
2299
2300# Pre-populate the hypervisors' ARP tables so that we don't lose any
2301# packets for ARP resolution (native tunneling doesn't queue packets
2302# for ARP resolution).
74868f2c 2303OVN_POPULATE_ARP
184bc3ca
RB
2304
2305# Allow some time for ovn-northd and ovn-controller to catch up.
2306# XXX This should be more systematic.
2307sleep 1
2308
2309# test_packet INPORT DST SRC ETHTYPE OUTPORT...
2310#
2311# This shell function causes a packet to be received on INPORT. The packet's
2312# content has Ethernet destination DST and source SRC (each exactly 12 hex
2313# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2314# more) list the VIFs on which the packet should be received. INPORT and the
2315# OUTPORTs are specified as lport numbers, e.g. 1 for vif1.
184bc3ca
RB
2316for i in 1 2 3; do
2317 : > $i.expected
2318done
2319test_packet() {
2320 local inport=$1 packet=$2$3$4; shift; shift; shift; shift
2321 #hv=hv`echo $inport | sed 's/^\(.\).*/\1/'`
2322 hv=hv$inport
2323 vif=vif$inport
2324 as $hv ovs-appctl netdev-dummy/receive $vif $packet
2325 for outport; do
e4543cfe 2326 echo $packet >> $outport.expected
184bc3ca
RB
2327 done
2328}
2329
2330# Send packets between all pairs of source and destination ports:
2331#
2332# 1. Unicast packets are delivered to exactly one lport (except that packets
2333# destined to their input ports are dropped).
2334#
2335# 2. Broadcast and multicast are delivered to all lports except the input port.
2336#
2337# 3. The lswitch delivers packets with an unknown destination to lports with
2338# "unknown" among their MAC addresses (and port security disabled).
2339for s in 1 2 3 ; do
2340 bcast=
2341 unknown=
2342 for d in 1 2 3 ; do
2343 if test $d != $s; then unicast=$d; else unicast=; fi
2344 test_packet $s f0000000000$d f0000000000$s 00$s$d $unicast #1
2345
2346 # The vtep (vif3) is the only one configured for "unknown"
2347 if test $d != $s && test $d = 3; then
2348 unknown="$unknown $d"
2349 fi
2350 bcast="$bcast $unicast"
2351 done
2352
2353 test_packet $s ffffffffffff f0000000000$s 0${s}ff $bcast #2
2354 test_packet $s 010000000000 f0000000000$s 0${s}ff $bcast #3
2355 test_packet $s f0000000ffff f0000000000$s 0${s}66 $unknown #4
2356done
2357
184bc3ca
RB
2358echo "------ ovn-nbctl show ------"
2359ovn-nbctl show
2360echo "------ ovn-sbctl show ------"
2361ovn-sbctl show
2362
2363echo "------ hv1 ------"
2364as hv1 ovs-vsctl show
2365echo "------ hv1 br-int ------"
2366as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
2367echo "------ hv1 br-phys ------"
2368as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2369
2370echo "------ hv2 ------"
2371as hv2 ovs-vsctl show
2372echo "------ hv2 br-int ------"
2373as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
2374echo "------ hv2 br-phys ------"
2375as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2376
2377echo "------ hv_gw ------"
2378as hv_gw ovs-vsctl show
2379echo "------ hv_gw br-phys ------"
2380as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys
2381echo "------ hv_gw br-phys2 ------"
2382as hv_gw ovs-ofctl -O OpenFlow13 dump-flows br-phys2
2383
2384echo "------ hv3 ------"
2385as hv3 ovs-vsctl show
2386echo "------ hv3 br-phys ------"
2387as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-phys
2388
2389# Now check the packets actually received against the ones expected.
2390for i in 1 2 3; do
49d7c759 2391 OVN_CHECK_PACKETS([hv$i/vif$i-tx.pcap], [$i.expected])
184bc3ca
RB
2392done
2393AT_CLEANUP
2394
9975d7be
BP
2395# 3 hypervisors, 3 logical switches with 3 logical ports each, 1 logical router
2396AT_SETUP([ovn -- 3 HVs, 3 LS, 3 lports/LS, 1 LR])
2397AT_SKIP_IF([test $HAVE_PYTHON = no])
2398ovn_start
2399
2400# Logical network:
2401#
2402# Three logical switches ls1, ls2, ls3.
86e98048
BP
2403# One logical router lr0 connected to ls[123],
2404# with nine subnets, three per logical switch:
2405#
2406# lrp11 on ls1 for subnet 192.168.11.0/24
2407# lrp12 on ls1 for subnet 192.168.12.0/24
2408# lrp13 on ls1 for subnet 192.168.13.0/24
2409# ...
2410# lrp33 on ls3 for subnet 192.168.33.0/24
2411#
2412# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
2413# digits are the subnet and the last digit distinguishes the VIF.
9975d7be 2414for i in 1 2 3; do
ea46a4e9 2415 ovn-nbctl ls-add ls$i
9975d7be 2416 for j in 1 2 3; do
86e98048 2417 for k in 1 2 3; do
31ed1192
JP
2418 # Add "unknown" to MAC addresses for lp?11, so packets for
2419 # MAC-IP bindings discovered via ARP later have somewhere to go.
2420 if test $j$k = 11; then unknown=unknown; else unknown=; fi
2421
2422 ovn-nbctl \
2423 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
2424 -- lsp-set-addresses lp$i$j$k \
2425 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k" $unknown
86e98048
BP
2426 done
2427 done
2428done
2429
fa2a27b2 2430ovn-nbctl lr-add lr0
86e98048
BP
2431for i in 1 2 3; do
2432 for j in 1 2 3; do
bf44c2cd 2433 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
269ecccc 2434 ovn-nbctl \
31ed1192 2435 -- lsp-add ls$i lrp$i$j-attachment \
269ecccc 2436 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
00007447 2437 options:router-port=lrp$i$j \
86e98048 2438 addresses='"00:00:00:00:ff:'$i$j'"'
9975d7be
BP
2439 done
2440done
2441
80f408f4 2442ovn-nbctl set Logical_Switch_Port lrp33-attachment \
57d143eb
HZ
2443 addresses='"00:00:00:00:ff:33 192.168.33.254"'
2444
9975d7be
BP
2445# Physical network:
2446#
2447# Three hypervisors hv[123].
86e98048
BP
2448# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
2449# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
2450# lp?3[123] all on hv3.
2451
9975d7be
BP
2452
2453# Given the name of a logical port, prints the name of the hypervisor
2454# on which it is located.
2455vif_to_hv() {
2456 case $1 in dnl (
86e98048
BP
2457 ?11) echo 1 ;; dnl (
2458 ?12 | ?21 | ?22) echo 2 ;; dnl (
2459 ?13 | ?23 | ?3?) echo 3 ;;
9975d7be
BP
2460 esac
2461}
2462
86e98048
BP
2463# Given the name of a logical port, prints the name of its logical router
2464# port, e.g. "vif_to_lrp 123" yields 12.
2465vif_to_lrp() {
2466 echo ${1%?}
2467}
2468
2469# Given the name of a logical port, prints the name of its logical
2470# switch, e.g. "vif_to_ls 123" yields 1.
e3393e3f 2471vif_to_ls() {
86e98048 2472 echo ${1%??}
e3393e3f
BP
2473}
2474
9975d7be
BP
2475net_add n1
2476for i in 1 2 3; do
2477 sim_add hv$i
2478 as hv$i
2479 ovs-vsctl add-br br-phys
2480 ovn_attach n1 br-phys 192.168.0.$i
2481done
2482for i in 1 2 3; do
2483 for j in 1 2 3; do
86e98048 2484 for k in 1 2 3; do
269ecccc
JP
2485 hv=`vif_to_hv $i$j$k`
2486 as hv$hv ovs-vsctl \
2487 -- add-port br-int vif$i$j$k \
2488 -- set Interface vif$i$j$k \
2489 external-ids:iface-id=lp$i$j$k \
2490 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
2491 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
2492 ofport-request=$i$j$k
86e98048 2493 done
9975d7be
BP
2494 done
2495done
2496
2497# Pre-populate the hypervisors' ARP tables so that we don't lose any
2498# packets for ARP resolution (native tunneling doesn't queue packets
2499# for ARP resolution).
74868f2c 2500OVN_POPULATE_ARP
9975d7be
BP
2501
2502# Allow some time for ovn-northd and ovn-controller to catch up.
2503# XXX This should be more systematic.
2504sleep 1
2505
e3393e3f 2506# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9975d7be
BP
2507#
2508# This shell function causes a packet to be received on INPORT. The packet's
2509# content has Ethernet destination DST and source SRC (each exactly 12 hex
2510# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2511# more) list the VIFs on which the packet should be received. INPORT and the
31ed1192 2512# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
9975d7be
BP
2513for i in 1 2 3; do
2514 for j in 1 2 3; do
86e98048
BP
2515 for k in 1 2 3; do
2516 : > $i$j$k.expected
269ecccc 2517 done
9975d7be
BP
2518 done
2519done
e3393e3f 2520test_ip() {
9975d7be
BP
2521 # This packet has bad checksums but logical L3 routing doesn't check.
2522 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
ba43992e 2523 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
9975d7be
BP
2524 shift; shift; shift; shift; shift
2525 hv=hv`vif_to_hv $inport`
2526 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2527 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
86e98048
BP
2528 in_ls=`vif_to_ls $inport`
2529 in_lrp=`vif_to_lrp $inport`
9975d7be 2530 for outport; do
269ecccc 2531 out_ls=`vif_to_ls $outport`
86e98048 2532 if test $in_ls = $out_ls; then
9975d7be
BP
2533 # Ports on the same logical switch receive exactly the same packet.
2534 echo $packet
2535 else
2536 # Routing decrements TTL and updates source and dest MAC
2537 # (and checksum).
269ecccc 2538 out_lrp=`vif_to_lrp $outport`
86e98048 2539 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
e4543cfe 2540 fi >> $outport.expected
9975d7be
BP
2541 done
2542}
2543
e3393e3f 2544as hv1 ovs-vsctl --columns=name,ofport list interface
0bac7164
BP
2545as hv1 ovn-sbctl list port_binding
2546as hv1 ovn-sbctl list datapath_binding
9975d7be
BP
2547as hv1 ovn-sbctl dump-flows
2548as hv1 ovs-ofctl dump-flows br-int
2549
e3393e3f 2550# Send IP packets between all pairs of source and destination ports:
9975d7be 2551#
31ed1192
JP
2552# 1. Unicast IP packets are delivered to exactly one logical switch port
2553# (except that packets destined to their input ports are dropped).
9975d7be 2554#
31ed1192
JP
2555# 2. Broadcast IP packets are delivered to all logical switch ports
2556# except the input port.
86e98048
BP
2557ip_to_hex() {
2558 printf "%02x%02x%02x%02x" "$@"
2559}
9975d7be 2560for is in 1 2 3; do
269ecccc
JP
2561 for js in 1 2 3; do
2562 for ks in 1 2 3; do
2563 bcast=
2564 s=$is$js$ks
2565 smac=f00000000$s
2566 sip=`ip_to_hex 192 168 $is$js $ks`
2567 for id in 1 2 3; do
2568 for jd in 1 2 3; do
2569 for kd in 1 2 3; do
2570 d=$id$jd$kd
2571 dip=`ip_to_hex 192 168 $id$jd $kd`
2572 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
2573 if test $d != $s; then unicast=$d; else unicast=; fi
2574
2575 test_ip $s $smac $dmac $sip $dip $unicast #1
2576
2577 if test $id = $is && test $d != $s; then bcast="$bcast $d"; fi
2578 done
2579 done
9975d7be 2580 done
269ecccc
JP
2581 test_ip $s $smac ffffffffffff $sip ffffffff $bcast #2
2582 done
2583 done
e3393e3f
BP
2584done
2585
0bac7164
BP
2586# 3. Send an IP packet from every logical port to every other subnet,
2587# to an IP address that does not have a static IP-MAC binding.
2588# This should generate a broadcast ARP request for the destination
2589# IP address in the destination subnet.
2590for is in 1 2 3; do
269ecccc
JP
2591 for js in 1 2 3; do
2592 for ks in 1 2 3; do
2593 s=$is$js$ks
2594 smac=f00000000$s
2595 sip=`ip_to_hex 192 168 $is$js $ks`
2596 for id in 1 2 3; do
2597 for jd in 1 2 3; do
2598 if test $is$js = $id$jd; then
2599 continue
2600 fi
2601
2602 # Send the packet.
2603 dmac=00000000ff$is$js
2604 # Calculate a 4th octet for the destination that is
2605 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2606 # that have static MAC bindings, and fits in the range
2607 # 0-255.
2608 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2609 dip=`ip_to_hex 192 168 $id$jd $o4`
2610 test_ip $s $smac $dmac $sip $dip
2611
2612 # Every LP on the destination subnet's lswitch should
2613 # receive the ARP request.
2614 lrmac=00000000ff$id$jd
2615 lrip=`ip_to_hex 192 168 $id$jd 254`
2616 arp=ffffffffffff${lrmac}08060001080006040001${lrmac}${lrip}000000000000${dip}
2617 for jd2 in 1 2 3; do
2618 for kd in 1 2 3; do
e4543cfe 2619 echo $arp >> $id$jd2$kd.expected
0bac7164 2620 done
269ecccc 2621 done
0bac7164 2622 done
269ecccc 2623 done
0bac7164 2624 done
269ecccc 2625 done
0bac7164
BP
2626done
2627
e3393e3f
BP
2628# test_arp INPORT SHA SPA TPA [REPLY_HA]
2629#
2630# Causes a packet to be received on INPORT. The packet is an ARP
2631# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2632# it should be the hardware address of the target to expect to receive in an
2633# ARP reply; otherwise no reply is expected.
2634#
31ed1192 2635# INPORT is an logical switch port number, e.g. 11 for vif11.
e3393e3f
BP
2636# SHA and REPLY_HA are each 12 hex digits.
2637# SPA and TPA are each 8 hex digits.
2638test_arp() {
2639 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2640 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2641 hv=hv`vif_to_hv $inport`
2642 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2d9b49dd 2643 as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
e3393e3f 2644
57d143eb 2645 # Expect to receive the broadcast ARP on the other logical switch ports if
ea46a4e9 2646 # IP address is not configured to the switch patch port.
e3393e3f 2647 local i=`vif_to_ls $inport`
86e98048 2648 local j k
e3393e3f 2649 for j in 1 2 3; do
86e98048 2650 for k in 1 2 3; do
ea46a4e9 2651 # 192.168.33.254 is configured to the switch patch port for lrp33,
57d143eb
HZ
2652 # so no ARP flooding expected for it.
2653 if test $i$j$k != $inport && test $tpa != `ip_to_hex 192 168 33 254`; then
86e98048
BP
2654 echo $request >> $i$j$k.expected
2655 fi
2656 done
e3393e3f
BP
2657 done
2658
2659 # Expect to receive the reply, if any.
2660 if test X$reply_ha != X; then
86e98048
BP
2661 lrp=`vif_to_lrp $inport`
2662 local reply=${sha}00000000ff${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
e3393e3f
BP
2663 echo $reply >> $inport.expected
2664 fi
2665}
2666
2667# Test router replies to ARP requests from all source ports:
2668#
0bac7164 2669# 4. Router replies to query for its MAC address from port's own IP address.
e3393e3f 2670#
0bac7164 2671# 5. Router replies to query for its MAC address from any random IP address
e3393e3f
BP
2672# in its subnet.
2673#
054008ad 2674# 6. No reply to query for IP address other than router IP.
e3393e3f 2675#
054008ad 2676# 7. No reply to query from another subnet.
b0684540 2677: > mac_bindings.expected
e3393e3f 2678for i in 1 2 3; do
269ecccc
JP
2679 for j in 1 2 3; do
2680 for k in 1 2 3; do
2681 smac=f00000000$i$j$k # Source MAC
2682 sip=`ip_to_hex 192 168 $i$j $k` # Source IP
2683 rip=`ip_to_hex 192 168 $i$j 254` # Router IP
2684 rmac=00000000ff$i$j # Router MAC
2685 otherip=`ip_to_hex 192 168 $i$j 55` # Some other IP in subnet
054008ad
HZ
2686 externalip=`ip_to_hex 1 2 3 4` # Some other IP not in subnet
2687
2688 test_arp $i$j$k $smac $sip $rip $rmac #4
2689 test_arp $i$j$k $smac $otherip $rip $rmac #5
2690 test_arp $i$j$k $smac $sip $otherip #6
2691
2692 # When rip is 192.168.33.254, ARP request from externalip won't be
2693 # filtered, because 192.168.33.254 is configured to switch peer port
2694 # for lrp33.
2695 lrp33_rsp=
2696 if test $i = 3 && test $j = 3; then
2697 lrp33_rsp=$rmac
2698 fi
2699 test_arp $i$j$k $smac $externalip $rip $lrp33_rsp #7
2700
b0684540
HZ
2701 # MAC binding should be learned from ARP request.
2702 host_mac_pretty=f0:00:00:00:0$i:$j$k
2703
2704 host_ip_pretty=192.168.$i$j.$k
2705 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2706
2707 # mac_binding is learned and overwritten so only the last one remains.
2708 if test $k = 3; then
2709 # lrp33 will not learn from ARP request, because 192.168.33.254 is
2710 # configured to switch peer port for lrp33.
2711 if test $i != 3 || test $j != 3; then
2712 host_ip_pretty=192.168.$i$j.55
2713 echo lrp$i$j,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
2714 fi
2715 fi
2716
0bac7164 2717 done
269ecccc 2718 done
0bac7164
BP
2719done
2720
2721# Allow some time for packet forwarding.
2722# XXX This can be improved.
2723sleep 1
2724
2725# 8. Generate an ARP reply for each of the IP addresses ARPed for
2726# earlier as #3.
2727#
2728# Here, the $s is the VIF that originated the ARP request and $d is
2729# the VIF that sends the ARP reply, which is somewhat backward but
2730# it means that $s and $d are the same as #3.
0bac7164 2731for is in 1 2 3; do
269ecccc
JP
2732 for js in 1 2 3; do
2733 for ks in 1 2 3; do
2734 s=$is$js$ks
2735 for id in 1 2 3; do
2736 for jd in 1 2 3; do
2737 if test $is$js = $id$jd; then
2738 continue
2739 fi
2740
2741 kd=1
2742 d=$id$jd$kd
2743
2744 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2745 host_ip=`ip_to_hex 192 168 $id$jd $o4`
2746 host_mac=8000000000$o4
2747
2748 lrmac=00000000ff$id$jd
2749 lrip=`ip_to_hex 192 168 $id$jd 254`
2750
2751 arp=${lrmac}${host_mac}08060001080006040002${host_mac}${host_ip}${lrmac}${lrip}
2752
2753 echo
2754 echo
2755 echo
2756 hv=hv`vif_to_hv $d`
2757 as $hv ovs-appctl netdev-dummy/receive vif$d $arp
2758 #as $hv ovs-appctl ofproto/trace br-int in_port=$d $arp
2759 #as $hv ovs-ofctl dump-flows br-int table=19
2760
2761 host_ip_pretty=192.168.$id$jd.$o4
2762 host_mac_pretty=80:00:00:00:00:$o4
2763 echo lrp$id$jd,$host_ip_pretty,$host_mac_pretty >> mac_bindings.expected
86e98048 2764 done
269ecccc 2765 done
9975d7be 2766 done
269ecccc 2767 done
9975d7be 2768done
0bac7164 2769
9975d7be
BP
2770# Allow some time for packet forwarding.
2771# XXX This can be improved.
2772sleep 1
2773
0bac7164
BP
2774# 9. Send an IP packet from every logical port to every other subnet. These
2775# are the same packets already sent as #3, but now the destinations' IP-MAC
2776# bindings have been discovered via ARP, so instead of provoking an ARP
2777# request, these packets now get routed to their destinations (which don't
2778# have static MAC bindings, so they go to the port we've designated as
2779# accepting "unknown" MACs.)
2780for is in 1 2 3; do
269ecccc
JP
2781 for js in 1 2 3; do
2782 for ks in 1 2 3; do
2783 s=$is$js$ks
2784 smac=f00000000$s
2785 sip=`ip_to_hex 192 168 $is$js $ks`
2786 for id in 1 2 3; do
2787 for jd in 1 2 3; do
2788 if test $is$js = $id$jd; then
2789 continue
2790 fi
2791
2792 # Send the packet.
2793 dmac=00000000ff$is$js
2794 # Calculate a 4th octet for the destination that is
2795 # unique per $s, avoids the .1 .2 .3 and .254 IP addresses
2796 # that have static MAC bindings, and fits in the range
2797 # 0-255.
2798 o4=`expr $is '*' 9 + $js '*' 3 + $ks + 10`
2799 dip=`ip_to_hex 192 168 $id$jd $o4`
2800 test_ip $s $smac $dmac $sip $dip
2801
2802 # Expect the packet egress.
2803 host_mac=8000000000$o4
2804 outport=${id}11
2805 out_lrp=$id$jd
e4543cfe 2806 echo ${host_mac}00000000ff${out_lrp}08004500001c00000000"3f1101"00${sip}${dip}0035111100080000 >> $outport.expected
0bac7164 2807 done
269ecccc 2808 done
0bac7164 2809 done
269ecccc 2810 done
0bac7164
BP
2811done
2812
0bac7164
BP
2813ovn-sbctl -f csv -d bare --no-heading \
2814 -- --columns=logical_port,ip,mac list mac_binding > mac_bindings
2815
9975d7be
BP
2816# Now check the packets actually received against the ones expected.
2817for i in 1 2 3; do
2818 for j in 1 2 3; do
86e98048 2819 for k in 1 2 3; do
abb37b6b
FF
2820 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
2821 [$i$j$k.expected])
86e98048 2822 done
9975d7be
BP
2823 done
2824done
fcde56f5 2825
0bac7164
BP
2826# Check the MAC bindings against those expected.
2827AT_CHECK_UNQUOTED([sort < mac_bindings], [0], [`sort < mac_bindings.expected`
2828])
2829
fcde56f5 2830# Gracefully terminate daemons
7a8f15e0 2831OVN_CLEANUP([hv1], [hv2], [hv3])
eff49a56 2832
9975d7be 2833AT_CLEANUP
685f4dfe 2834
b0684540
HZ
2835AT_SETUP([ovn -- IP relocation using GARP request])
2836AT_SKIP_IF([test $HAVE_PYTHON = no])
2837ovn_start
2838
2839# Logical network:
2840#
2841# Two logical switches ls1, ls2.
2842# One logical router lr0 connected to ls[12],
2843# with 2 subnets, 1 per logical switch:
2844#
2845# lrp1 on ls1 for subnet 192.168.1.1/24
2846# lrp2 on ls2 for subnet 192.168.2.1/24
2847#
2848# 4 VIFs, 2 per LS lp[12][12], first digit being LS.
2849# VIFs' fixed IP addresses are 192.168.[12].1[12].
2850#
2851# There is a secondary IP 192.168.1.100 that is unknown in NB and learned
2852# through ARP only, and it can move between lp11 and lp12.
2853#
2854ovn-nbctl lr-add lr0
2855for i in 1 2 ; do
2856 ovn-nbctl ls-add ls$i
2857 ovn-nbctl lrp-add lr0 lrp$i 00:00:00:00:ff:0$i 192.168.$i.1/24
2858 ovn-nbctl \
2859 -- lsp-add ls$i lrp$i-attachment \
2860 -- set Logical_Switch_Port lrp$i-attachment type=router \
2861 options:router-port=lrp$i \
2862 addresses=router
2863 for j in 1 2; do
2864 ovn-nbctl \
2865 -- lsp-add ls$i lp$i$j \
2866 -- lsp-set-addresses lp$i$j \
2867 "f0:00:00:00:00:$i$j 192.168.$i.1$j"
2868 done
2869done
2870
2871# Physical network:
2872# 2 hypervisors hv[12], lp?1 on hv1, lp?2 on hv2.
2873
2874# Given the name of a logical port, prints the name of the hypervisor
2875# on which it is located, e.g. "vif_to_hv 12" yields 2.
2876vif_to_hv() {
2877 echo ${1#?}
2878}
2879
2880# Given the name of a logical port, prints the name of its logical router
2881# port, e.g. "vif_to_lrp 12" yields 1.
2882vif_to_lrp() {
2883 echo ${1%?}
2884}
2885
2886# Given the name of a logical port, prints the name of its logical
2887# switch, e.g. "vif_to_ls 12" yields 1.
2888vif_to_ls() {
2889 echo ${1%?}
2890}
2891
2892net_add n1
2893for i in 1 2; do
2894 sim_add hv$i
2895 as hv$i
2896 ovs-vsctl add-br br-phys
2897 ovn_attach n1 br-phys 192.168.0.$i
2898done
2899for i in 1 2; do
2900 for j in 1 2; do
2901 hv=`vif_to_hv $i$j`
2902 as hv$hv ovs-vsctl \
2903 -- add-port br-int vif$i$j \
2904 -- set Interface vif$i$j \
2905 external-ids:iface-id=lp$i$j \
2906 options:tx_pcap=hv$hv/vif$i$j-tx.pcap \
2907 options:rxq_pcap=hv$hv/vif$i$j-rx.pcap \
2908 ofport-request=$i$j
2909 done
2910done
2911
2912# Pre-populate the hypervisors' ARP tables so that we don't lose any
2913# packets for ARP resolution (native tunneling doesn't queue packets
2914# for ARP resolution).
2915OVN_POPULATE_ARP
2916
2917# Allow some time for ovn-northd and ovn-controller to catch up.
2918# XXX This should be more systematic.
2919sleep 1
2920
2921# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
2922#
2923# This shell function causes a packet to be received on INPORT. The packet's
2924# content has Ethernet destination DST and source SRC (each exactly 12 hex
2925# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
2926# more) list the VIFs on which the packet should be received. INPORT and the
2927# OUTPORTs are specified as logical switch port numbers, e.g. 12 for vif12.
2928for i in 1 2; do
2929 for j in 1 2; do
2930 : > $i$j.expected
2931 done
2932done
2933test_ip() {
2934 # This packet has bad checksums but logical L3 routing doesn't check.
2935 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
2936 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
2937 shift; shift; shift; shift; shift
2938 hv=hv`vif_to_hv $inport`
2939 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
2940 in_ls=`vif_to_ls $inport`
2941 in_lrp=`vif_to_lrp $inport`
2942 for outport; do
2943 out_ls=`vif_to_ls $outport`
2944 if test $in_ls = $out_ls; then
2945 # Ports on the same logical switch receive exactly the same packet.
2946 echo $packet
2947 else
2948 # Routing decrements TTL and updates source and dest MAC
2949 # (and checksum).
2950 out_lrp=`vif_to_lrp $outport`
2951 echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
2952 fi >> $outport.expected
2953 done
2954}
2955
2956# test_arp INPORT SHA SPA TPA [REPLY_HA]
2957#
2958# Causes a packet to be received on INPORT. The packet is an ARP
2959# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
2960# it should be the hardware address of the target to expect to receive in an
2961# ARP reply; otherwise no reply is expected.
2962#
2963# INPORT is an logical switch port number, e.g. 11 for vif11.
2964# SHA and REPLY_HA are each 12 hex digits.
2965# SPA and TPA are each 8 hex digits.
2966test_arp() {
2967 local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5
2968 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
2969 hv=hv`vif_to_hv $inport`
2970 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
2971
2972 # Expect to receive the broadcast ARP on the other logical switch ports if
2973 # IP address is not configured to the switch patch port.
2974 local i=`vif_to_ls $inport`
2975 local j
2976 for j in 1 2; do
2977 if test $i$j != $inport; then
2978 echo $request >> $i$j$k.expected
2979 fi
2980 done
2981
2982 # Expect to receive the reply, if any.
2983 if test X$reply_ha != X; then
2984 lrp=`vif_to_lrp $inport`
2985 local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa}
2986 echo $reply >> $inport.expected
2987 fi
2988}
2989
2990ip_to_hex() {
2991 printf "%02x%02x%02x%02x" "$@"
2992}
2993
2994# lp11 send GARP request to announce ownership of 192.168.1.100.
2995
2996sha=f00000000011
2997spa=`ip_to_hex 192 168 1 100`
2998tpa=$spa
2999test_arp 11 $sha $spa $tpa
3000OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0])
3001ovn-nbctl --wait=hv sync
3002
3003# Send an IP packet from lp21 to 192.168.1.100, which should go to lp11.
3004
3005smac=f00000000021
3006dmac=00000000ff02
3007sip=`ip_to_hex 192 168 2 11`
3008dip=`ip_to_hex 192 168 1 100`
3009test_ip 21 $smac $dmac $sip $dip 11
3010
3011# lp12 send GARP request to announce ownership of 192.168.1.100.
3012
3013sha=f00000000012
3014test_arp 12 $sha $spa $tpa
3015OVS_WAIT_UNTIL([ovn-sbctl find mac_binding ip="192.168.1.100" | grep f0:00:00:00:00:12])
3016ovn-nbctl --wait=hv sync
3017
3018# Send an IP packet from lp21 to 192.168.1.100, which should go to lp12.
3019
3020test_ip 21 $smac $dmac $sip $dip 12
3021
3022# Now check the packets actually received against the ones expected.
3023for i in 1 2; do
3024 for j in 1 2; do
3025 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j`/vif$i$j-tx.pcap],
3026 [$i$j.expected])
3027 done
3028done
3029
3030# Gracefully terminate daemons
3031OVN_CLEANUP([hv1], [hv2])
3032
3033AT_CLEANUP
3034
685f4dfe
NS
3035# 3 hypervisors, one logical switch, 3 logical ports per hypervisor
3036AT_SETUP([ovn -- portsecurity : 3 HVs, 1 LS, 3 lports/HV])
685f4dfe
NS
3037AT_SKIP_IF([test $HAVE_PYTHON = no])
3038ovn_start
3039
3040# Create hypervisors hv[123].
3041# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
3042# Add all of the vifs to a single logical switch lsw0.
3043# Turn off port security on vifs vif[123]1
3044# Turn on l2 port security on vifs vif[123]2
3045# Turn of l2 and l3 port security on vifs vif[123]3
3046# Make vif13, vif2[23], vif3[123] destinations for unknown MACs.
ea46a4e9 3047ovn-nbctl ls-add lsw0
685f4dfe
NS
3048net_add n1
3049for i in 1 2 3; do
3050 sim_add hv$i
3051 as hv$i
3052 ovs-vsctl add-br br-phys
3053 ovn_attach n1 br-phys 192.168.0.$i
3054
3055 for j in 1 2 3; do
3056 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 3057 ovn-nbctl lsp-add lsw0 lp$i$j
685f4dfe 3058 if test $j = 1; then
31ed1192 3059 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" unknown
685f4dfe 3060 elif test $j = 2; then
31ed1192
JP
3061 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j"
3062 ovn-nbctl lsp-set-port-security lp$i$j f0:00:00:00:00:$i$j
685f4dfe
NS
3063 else
3064 extra_addr="f0:00:00:00:0$i:$i$j fe80::ea2a:eaff:fe28:$i$j"
31ed1192
JP
3065 ovn-nbctl lsp-set-addresses lp$i$j "f0:00:00:00:00:$i$j 192.168.0.$i$j" "$extra_addr"
3066 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
3067 fi
3068 done
3069done
3070
685f4dfe
NS
3071# Pre-populate the hypervisors' ARP tables so that we don't lose any
3072# packets for ARP resolution (native tunneling doesn't queue packets
3073# for ARP resolution).
74868f2c 3074OVN_POPULATE_ARP
685f4dfe
NS
3075
3076# Allow some time for ovn-northd and ovn-controller to catch up.
3077# XXX This should be more systematic.
3078sleep 1
685f4dfe
NS
3079
3080# Given the name of a logical port, prints the name of the hypervisor
3081# on which it is located.
3082vif_to_hv() {
3083 echo hv${1%?}
3084}
3085
685f4dfe
NS
3086for i in 1 2 3; do
3087 for j in 1 2 3; do
3088 : > $i$j.expected
3089 done
3090done
3091
3092# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3093#
3094# This shell function causes an ip packet to be received on INPORT.
3095# The packet's content has Ethernet destination DST and source SRC
3096# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
3097# The OUTPORTs (zero or more) list the VIFs on which the packet should
31ed1192
JP
3098# be received. INPORT and the OUTPORTs are specified as logical switch
3099# port numbers, e.g. 11 for vif11.
685f4dfe
NS
3100test_ip() {
3101 # This packet has bad checksums but logical L3 routing doesn't check.
3102 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
efe179e0 3103 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
685f4dfe
NS
3104 shift; shift; shift; shift; shift
3105 hv=`vif_to_hv $inport`
3106 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3107 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3108 for outport; do
e4543cfe 3109 echo $packet >> $outport.expected
685f4dfe
NS
3110 done
3111}
3112
3113# test_arp INPORT SHA SPA TPA DROP [REPLY_HA]
3114#
3115# Causes a packet to be received on INPORT. The packet is an ARP
3116# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
3117# it should be the hardware address of the target to expect to receive in an
3118# ARP reply; otherwise no reply is expected.
3119#
31ed1192 3120# INPORT is an logical switch port number, e.g. 11 for vif11.
685f4dfe
NS
3121# SHA and REPLY_HA are each 12 hex digits.
3122# SPA and TPA are each 8 hex digits.
3123test_arp() {
3124 local inport=$1 smac=$2 sha=$3 spa=$4 tpa=$5 drop=$6 reply_ha=$7
3125 local request=ffffffffffff${smac}08060001080006040001${sha}${spa}ffffffffffff${tpa}
3126 hv=`vif_to_hv $inport`
3127 as $hv ovs-appctl netdev-dummy/receive vif$inport $request
3128 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $request
3129 if test $drop != 1; then
e137131a 3130 if test X$reply_ha = X; then
685f4dfe
NS
3131 # Expect to receive the broadcast ARP on the other logical switch ports
3132 # if no reply is expected.
3133 local i j
3134 for i in 1 2 3; do
3135 for j in 1 2 3; do
3136 if test $i$j != $inport; then
3137 echo $request >> $i$j.expected
3138 fi
3139 done
3140 done
3141 else
3142 # Expect to receive the reply, if any.
3143 local reply=${smac}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
3144 echo $reply >> $inport.expected
3145 fi
3146 fi
3147}
3148
3149# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
3150# This function is similar to test_ip() except that it sends
3151# ipv6 packet
3152test_ipv6() {
3153 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
3154 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}0000000000000000
3155 shift; shift; shift; shift; shift
3156 hv=`vif_to_hv $inport`
3157 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3158 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3159 for outport; do
e4543cfe 3160 echo $packet >> $outport.expected
685f4dfe
NS
3161 done
3162}
3163
9e687b23
DL
3164# test_icmpv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
3165# This function is similar to test_ipv6() except it specifies the ICMPv6 type
3166# of the test packet
3167test_icmpv6() {
3168 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
3169 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}${icmp_type}00000000000000
3170 shift; shift; shift; shift; shift; shift
3171 hv=`vif_to_hv $inport`
3172 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
3173 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
3174 for outport; do
e4543cfe 3175 echo $packet >> $outport.expected
9e687b23
DL
3176 done
3177}
3178
685f4dfe
NS
3179ip_to_hex() {
3180 printf "%02x%02x%02x%02x" "$@"
3181}
3182
3183# no port security
3184sip=`ip_to_hex 192 168 0 12`
3185tip=`ip_to_hex 192 168 0 13`
3186# the arp packet should be allowed even if lp[123]1 is
3187# not configured with mac f00000000023 and ip 192.168.0.12
3188for i in 1 2 3; do
3189 test_arp ${i}1 f00000000023 f00000000023 $sip $tip 0 f00000000013
3190 for j in 1 2 3; do
3191 if test $i != $j; then
3192 test_ip ${i}1 f000000000${i}1 f000000000${j}1 $sip $tip ${j}1
3193 fi
3194 done
3195done
3196
3197# l2 port security
3198sip=`ip_to_hex 192 168 0 12`
3199tip=`ip_to_hex 192 168 0 13`
3200
3201# arp packet should be allowed since lp22 is configured with
3202# mac f00000000022
3203test_arp 22 f00000000022 f00000000022 $sip $tip 0 f00000000013
3204
3205# arp packet should not be allowed since lp32 is not configured with
3206# mac f00000000021
3207test_arp 32 f00000000021 f00000000021 $sip $tip 1
3208
3209# arp packet with sha set to f00000000021 should not be allowed
3210# for lp12
3211test_arp 12 f00000000012 f00000000021 $sip $tip 1
3212
3213# ip packets should be allowed and received since lp[123]2 do not
3214# have l3 port security
3215sip=`ip_to_hex 192 168 0 55`
3216tip=`ip_to_hex 192 168 0 66`
3217for i in 1 2 3; do
3218 for j in 1 2 3; do
3219 if test $i != $j; then
3220 test_ip ${i}2 f000000000${i}2 f000000000${j}2 $sip $tip ${j}2
3221 fi
3222 done
3223done
3224
3225# ipv6 packets should be received by lp[123]2
3226# lp[123]1 can send ipv6 traffic as there is no port security
3227sip=fe800000000000000000000000000000
3228tip=ff020000000000000000000000000000
3229
3230for i in 1 2 3; do
3231 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}2 $sip $tip ${i}2
3232done
3233
3234
3235# l2 and l3 port security
3236sip=`ip_to_hex 192 168 0 13`
3237tip=`ip_to_hex 192 168 0 22`
3238# arp packet should be allowed since lp13 is configured with
3239# f00000000013 and 192.168.0.13
3240test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3241
3242# the arp packet should be dropped because lp23 is not configured
3243# with mac f00000000022
3244sip=`ip_to_hex 192 168 0 13`
3245tip=`ip_to_hex 192 168 0 22`
3246test_arp 23 f00000000022 f00000000022 $sip $tip 1
3247
3248# the arp packet should be dropped because lp33 is not configured
3249# with ip 192.168.0.55
3250spa=`ip_to_hex 192 168 0 55`
3251tpa=`ip_to_hex 192 168 0 22`
3252test_arp 33 f00000000031 f00000000031 $spa $tpa 1
3253
3254# ip packets should not be received by lp[123]3 since
3255# l3 port security is enabled
3256sip=`ip_to_hex 192 168 0 55`
3257tip=`ip_to_hex 192 168 0 66`
3258for i in 1 2 3; do
3259 for j in 1 2 3; do
3260 test_ip ${i}2 f000000000${i}2 f000000000${j}3 $sip $tip
3261 done
3262done
3263
3264# ipv6 packets should be dropped for lp[123]3 since
3265# it is configured with only ipv4 address
3266sip=fe800000000000000000000000000000
3267tip=ff020000000000000000000000000000
3268
3269for i in 1 2 3; do
3270 test_ipv6 ${i}3 f000000000${i}3 f00000000022 $sip $tip
3271done
3272
3273# ipv6 packets should not be received by lp[123]3 with mac f000000000$[123]3
3274# lp[123]1 can send ipv6 traffic as there is no port security
3275for i in 1 2 3; do
3276 test_ipv6 ${i}1 f000000000${i}1 f000000000${i}3 $sip $tip
3277done
3278
3279# lp13 has extra port security with mac f0000000113 and ipv6 addr
3280# fe80::ea2a:eaff:fe28:0012
3281
3282# ipv4 packet should be dropped for lp13 with mac f0000000113
3283sip=`ip_to_hex 192 168 0 13`
3284tip=`ip_to_hex 192 168 0 23`
3285test_ip 13 f00000000113 f00000000023 $sip $tip
3286
6d53e8a9
BP
3287# ipv6 packet should be received by lp[123]3 with mac f00000000${i}${i}3
3288# and ip6.dst as fe80::ea2a:eaff:fe28:0${i}${i}3.
685f4dfe
NS
3289# lp11 can send ipv6 traffic as there is no port security
3290sip=ee800000000000000000000000000000
3291for i in 1 2 3; do
6d53e8a9
BP
3292 tip=fe80000000000000ea2aeafffe2800${i}3
3293 test_ipv6 11 f00000000011 f00000000${i}${i}3 $sip $tip ${i}3
685f4dfe
NS
3294done
3295
3296
3297# ipv6 packet should not be received by lp33 with mac f0000000333
3298# and ip6.dst as fe80::ea2a:eaff:fe28:0023 as it is
3299# configured with fe80::ea2a:eaff:fe28:0033
3300# lp11 can send ipv6 traffic as there is no port security
3301
3302sip=ee800000000000000000000000000000
3303tip=fe80000000000000ea2aeafffe280023
3304test_ipv6 11 f00000000011 f00000000333 $sip $tip
3305
6d53e8a9
BP
3306# ipv6 packet should be allowed for lp[123]3 with mac f0000000${i}${i}3
3307# and ip6.src fe80::ea2a:eaff:fe28:0${i}${i}3 and ip6.src ::.
685f4dfe
NS
3308# and should be dropped for any other ip6.src
3309# lp21 can receive ipv6 traffic as there is no port security
3310
3311tip=ee800000000000000000000000000000
3312for i in 1 2 3; do
3313 sip=fe80000000000000ea2aeafffe2800${i}3
3314 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 21
3315
9e687b23 3316 # Test ICMPv6 MLD reports (v1 and v2) and NS for DAD
685f4dfe 3317 sip=00000000000000000000000000000000
9e687b23
DL
3318 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 83 21
3319 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 8f 21
3320 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff0200000000000000ea2aeafffe2800 87 21
3321 # Traffic to non-multicast traffic should be dropped
3322 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip 83
3323 # Traffic of other ICMPv6 types should be dropped
3324 test_icmpv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip ff020000000000000000000000160000 80
685f4dfe
NS
3325
3326 # should be dropped
3327 sip=ae80000000000000ea2aeafffe2800aa
3328 test_ipv6 ${i}3 f00000000${i}${i}3 f00000000021 $sip $tip
3329done
3330
31ed1192
JP
3331# configure lsp13 to send and received IPv4 packets with an address range
3332ovn-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 3333
8ff5a966
NS
3334sleep 2
3335
7d9d86ad
NS
3336sip=`ip_to_hex 10 0 0 13`
3337tip=`ip_to_hex 192 168 0 22`
31ed1192 3338# arp packet with inner ip 10.0.0.13 should be allowed for lsp13
7d9d86ad
NS
3339test_arp 13 f00000000013 f00000000013 $sip $tip 0 f00000000022
3340
3341sip=`ip_to_hex 10 0 0 14`
3342tip=`ip_to_hex 192 168 0 23`
31ed1192 3343# IPv4 packet from lsp13 with src ip 10.0.0.14 destined to lsp23
7d9d86ad
NS
3344# with dst ip 192.168.0.23 should be allowed
3345test_ip 13 f00000000013 f00000000023 $sip $tip 23
3346
3347sip=`ip_to_hex 192 168 0 33`
3348tip=`ip_to_hex 10 0 0 15`
31ed1192
JP
3349# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3350# with dst ip 10.0.0.15 should be received by lsp13
7d9d86ad
NS
3351test_ip 33 f00000000033 f00000000013 $sip $tip 13
3352
3353sip=`ip_to_hex 192 168 0 33`
3354tip=`ip_to_hex 20 0 0 4`
31ed1192
JP
3355# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3356# with dst ip 20.0.0.4 should be received by lsp13
7d9d86ad
NS
3357test_ip 33 f00000000033 f00000000013 $sip $tip 13
3358
3359sip=`ip_to_hex 192 168 0 33`
3360tip=`ip_to_hex 20 0 0 5`
31ed1192
JP
3361# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3362# with dst ip 20.0.0.5 should not be received by lsp13
7d9d86ad
NS
3363test_ip 33 f00000000033 f00000000013 $sip $tip
3364
3365sip=`ip_to_hex 192 168 0 33`
3366tip=`ip_to_hex 20 0 0 255`
31ed1192
JP
3367# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3368# with dst ip 20.0.0.255 should be received by lsp13
7d9d86ad
NS
3369test_ip 33 f00000000033 f00000000013 $sip $tip 13
3370
3371sip=`ip_to_hex 192 168 0 33`
3372tip=`ip_to_hex 192 168 0 255`
31ed1192
JP
3373# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3374# with dst ip 192.168.0.255 should not be received by lsp13
7d9d86ad
NS
3375test_ip 33 f00000000033 f00000000013 $sip $tip
3376
3377sip=`ip_to_hex 192 168 0 33`
3378tip=`ip_to_hex 224 0 0 4`
31ed1192
JP
3379# IPv4 packet from lsp33 with src ip 192.168.0.33 destined to lsp13
3380# with dst ip 224.0.0.4 should be received by lsp13
7d9d86ad 3381test_ip 33 f00000000033 f00000000013 $sip $tip 13
685f4dfe 3382
bb0c41d3
RM
3383#dump information including flow counters
3384ovn-nbctl show
3385ovn-sbctl dump-flows -- list multicast_group
3386
3387echo "------ hv1 dump ------"
3388as hv1 ovs-vsctl show
6195e2e7 3389as hv1 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3390as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
3391
3392echo "------ hv2 dump ------"
3393as hv2 ovs-vsctl show
6195e2e7 3394as hv2 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3395as hv2 ovs-ofctl -O OpenFlow13 dump-flows br-int
3396
3397echo "------ hv3 dump ------"
3398as hv3 ovs-vsctl show
6195e2e7 3399as hv3 ovs-ofctl -O OpenFlow13 show br-int
bb0c41d3
RM
3400as hv3 ovs-ofctl -O OpenFlow13 dump-flows br-int
3401
685f4dfe
NS
3402# Now check the packets actually received against the ones expected.
3403for i in 1 2 3; do
3404 for j in 1 2 3; do
49d7c759 3405 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
685f4dfe
NS
3406 done
3407done
3408
7a8f15e0 3409OVN_CLEANUP([hv1],[hv2],[hv3])
d9c8c57c 3410
685f4dfe 3411AT_CLEANUP
509afdc3
GS
3412
3413AT_SETUP([ovn -- 2 HVs, 2 LS, 1 lport/LS, 2 peer LRs])
509afdc3
GS
3414AT_SKIP_IF([test $HAVE_PYTHON = no])
3415ovn_start
3416
3417# Logical network:
3418# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3419# network. R1 has a switchs ls1 (191.168.1.0/24) connected to it.
3420# R2 has ls2 (172.16.1.0/24) connected to it.
3421
3c1ae70a
JP
3422ls1_lp1_mac="f0:00:00:01:02:03"
3423rp_ls1_mac="00:00:00:01:02:03"
3424rp_ls2_mac="00:00:00:01:02:04"
3425ls2_lp1_mac="f0:00:00:01:02:04"
3426
3427ls1_lp1_ip="192.168.1.2"
3428ls2_lp1_ip="172.16.1.2"
3429
fa2a27b2
JP
3430ovn-nbctl lr-add R1
3431ovn-nbctl lr-add R2
509afdc3 3432
ea46a4e9
JP
3433ovn-nbctl ls-add ls1
3434ovn-nbctl ls-add ls2
509afdc3
GS
3435
3436# Connect ls1 to R1
3c1ae70a 3437ovn-nbctl lrp-add R1 ls1 $rp_ls1_mac 192.168.1.1/24
509afdc3 3438
31ed1192 3439ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3c1ae70a 3440 options:router-port=ls1 addresses=\"$rp_ls1_mac\"
509afdc3
GS
3441
3442# Connect ls2 to R2
3c1ae70a 3443ovn-nbctl lrp-add R2 ls2 $rp_ls2_mac 172.16.1.1/24
509afdc3 3444
31ed1192 3445ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
3c1ae70a 3446 options:router-port=ls2 addresses=\"$rp_ls2_mac\"
509afdc3
GS
3447
3448# Connect R1 to R2
4685e523
JP
3449ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3450ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
509afdc3 3451
6d9ecfa9
JP
3452ovn-nbctl lr-route-add R1 "0.0.0.0/0" 20.0.0.2
3453ovn-nbctl lr-route-add R2 "0.0.0.0/0" 20.0.0.1
509afdc3
GS
3454
3455# Create logical port ls1-lp1 in ls1
31ed1192 3456ovn-nbctl lsp-add ls1 ls1-lp1 \
3c1ae70a 3457-- lsp-set-addresses ls1-lp1 "$ls1_lp1_mac $ls1_lp1_ip"
509afdc3
GS
3458
3459# Create logical port ls2-lp1 in ls2
31ed1192 3460ovn-nbctl lsp-add ls2 ls2-lp1 \
3c1ae70a 3461-- lsp-set-addresses ls2-lp1 "$ls2_lp1_mac $ls2_lp1_ip"
509afdc3
GS
3462
3463# Create two hypervisor and create OVS ports corresponding to logical ports.
3464net_add n1
3465
3466sim_add hv1
3467as hv1
3468ovs-vsctl add-br br-phys
3469ovn_attach n1 br-phys 192.168.0.1
3470ovs-vsctl -- add-port br-int hv1-vif1 -- \
3471 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
3472 options:tx_pcap=hv1/vif1-tx.pcap \
3473 options:rxq_pcap=hv1/vif1-rx.pcap \
3474 ofport-request=1
3475
3476sim_add hv2
3477as hv2
3478ovs-vsctl add-br br-phys
3479ovn_attach n1 br-phys 192.168.0.2
3480ovs-vsctl -- add-port br-int hv2-vif1 -- \
3481 set interface hv2-vif1 external-ids:iface-id=ls2-lp1 \
3482 options:tx_pcap=hv2/vif1-tx.pcap \
3483 options:rxq_pcap=hv2/vif1-rx.pcap \
3484 ofport-request=1
3485
3486
3487# Pre-populate the hypervisors' ARP tables so that we don't lose any
3488# packets for ARP resolution (native tunneling doesn't queue packets
3489# for ARP resolution).
74868f2c 3490OVN_POPULATE_ARP
509afdc3
GS
3491
3492# Allow some time for ovn-northd and ovn-controller to catch up.
3493# XXX This should be more systematic.
3494sleep 1
3495
509afdc3 3496# Packet to send.
3c1ae70a
JP
3497packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3498 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3499 udp && udp.src==53 && udp.dst==4369"
3500as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
509afdc3
GS
3501
3502
3503echo "---------NB dump-----"
3504ovn-nbctl show
3505echo "---------------------"
3506ovn-nbctl list logical_router
3507echo "---------------------"
3508ovn-nbctl list logical_router_port
3509echo "---------------------"
3510
3511echo "---------SB dump-----"
3512ovn-sbctl list datapath_binding
3513echo "---------------------"
3514ovn-sbctl list port_binding
3515echo "---------------------"
3516
3517echo "------ hv1 dump ----------"
8dab1022 3518as hv1 ovs-ofctl show br-int
509afdc3
GS
3519as hv1 ovs-ofctl dump-flows br-int
3520echo "------ hv2 dump ----------"
8dab1022 3521as hv2 ovs-ofctl show br-int
509afdc3
GS
3522as hv2 ovs-ofctl dump-flows br-int
3523
3524# Packet to Expect
3c1ae70a
JP
3525# The TTL should be decremented by 2.
3526packet="eth.src==$rp_ls2_mac && eth.dst==$ls2_lp1_mac &&
3527 ip4 && ip.ttl==62 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3528 udp && udp.src==53 && udp.dst==4369"
3529echo $packet | ovstest test-ovn expr-to-packets > expected
509afdc3 3530
49d7c759 3531OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
509afdc3 3532
7ebfcd3d
NS
3533AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3534grep "reg0 == 172.16.1.2" | wc -l], [0], [1
3535])
3536
3537# Disable the ls2-lp1 port.
3538ovn-nbctl --wait=hv set logical_switch_port ls2-lp1 enabled=false
3539
3540AT_CHECK([ovn-sbctl dump-flows | grep lr_in_arp_resolve | \
3541grep "reg0 == 172.16.1.2" | wc -l], [0], [0
3542])
3543
3544# Generate the packet destined for ls2-lp1 and it should not be delivered.
3545# Packet to send.
3546packet="inport==\"ls1-lp1\" && eth.src==$ls1_lp1_mac && eth.dst==$rp_ls1_mac &&
3547 ip4 && ip.ttl==64 && ip4.src==$ls1_lp1_ip && ip4.dst==$ls2_lp1_ip &&
3548 udp && udp.src==53 && udp.dst==4369"
3549
3550as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
3551# The 2nd packet sent shound not be received.
3552OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
3553
7a8f15e0 3554OVN_CLEANUP([hv1],[hv2])
509afdc3
GS
3555
3556AT_CLEANUP
5412db30
J
3557
3558
4685e523
JP
3559AT_SETUP([ovn -- 1 HV, 1 LS, 2 lport/LS, 1 LR])
3560AT_KEYWORDS([router-admin-state])
3561AT_SKIP_IF([test $HAVE_PYTHON = no])
3562ovn_start
3563
3564# Logical network:
3565# One LR - R1 has switch ls1 with two subnets attached to it (191.168.1.0/24
3566# and 172.16.1.0/24) connected to it.
3567
3568ovn-nbctl lr-add R1
3569
3570ovn-nbctl ls-add ls1
3571
3572# Connect ls1 to R1
bf44c2cd 3573ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24 172.16.1.1/24
4685e523
JP
3574ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
3575 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
3576
3577# Create logical port ls1-lp1 in ls1
3578ovn-nbctl lsp-add ls1 ls1-lp1 \
3579 -- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
3580
3581# Create logical port ls1-lp2 in ls1
3582ovn-nbctl lsp-add ls1 ls1-lp2 \
3583 -- lsp-set-addresses ls1-lp2 "f0:00:00:01:02:04 172.16.1.2"
3584
3585# Create one hypervisor and create OVS ports corresponding to logical ports.
3586net_add n1
3587
3588sim_add hv1
3589as hv1
3590ovs-vsctl add-br br-phys
3591ovn_attach n1 br-phys 192.168.0.1
3592ovs-vsctl -- add-port br-int vif1 -- \
3593 set interface vif1 external-ids:iface-id=ls1-lp1 \
3594 options:tx_pcap=hv1/vif1-tx.pcap \
3595 options:rxq_pcap=hv1/vif1-rx.pcap \
3596 ofport-request=1
3597
3598ovs-vsctl -- add-port br-int vif2 -- \
3599 set interface vif2 external-ids:iface-id=ls1-lp2 \
3600 options:tx_pcap=hv1/vif2-tx.pcap \
3601 options:rxq_pcap=hv1/vif2-rx.pcap \
3602 ofport-request=1
3603
3604
3605# Allow some time for ovn-northd and ovn-controller to catch up.
3606# XXX This should be more systematic.
3607sleep 1
3608
3609# Send ip packets between the two ports.
3610ip_to_hex() {
3611 printf "%02x%02x%02x%02x" "$@"
3612}
4685e523
JP
3613
3614# Packet to send.
3615src_mac="f00000010203"
3616dst_mac="000000010203"
3617src_ip=`ip_to_hex 192 168 1 2`
3618dst_ip=`ip_to_hex 172 16 1 2`
3619packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3620as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3621
3622
3623echo "---------NB dump-----"
3624ovn-nbctl show
3625echo "---------------------"
3626ovn-nbctl list logical_router
3627echo "---------------------"
3628ovn-nbctl list logical_router_port
3629echo "---------------------"
3630
3631echo "---------SB dump-----"
3632ovn-sbctl list datapath_binding
3633echo "---------------------"
3634ovn-sbctl list logical_flow
3635echo "---------------------"
3636
3637echo "------ hv1 dump ----------"
3638as hv1 ovs-ofctl dump-flows br-int
3639
3640
3641#Disable router R1
3642ovn-nbctl set Logical_Router R1 enabled=false
3643
3b8cd0ea
BP
3644# Allow some time for ovn-northd and ovn-controller to catch up.
3645# XXX This should be more systematic.
3646sleep 1
3647
4685e523
JP
3648echo "---------SB dump-----"
3649ovn-sbctl list datapath_binding
3650echo "---------------------"
3651ovn-sbctl list logical_flow
3652echo "---------------------"
3653
3654echo "------ hv1 dump ----------"
3655as hv1 ovs-ofctl dump-flows br-int
3656
3657as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3658
3659# Packet to Expect
3660expect_src_mac="000000010203"
3661expect_dst_mac="f00000010204"
49d7c759 3662echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
4685e523 3663
49d7c759 3664OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
4685e523
JP
3665
3666
3667as hv1
3668OVS_APP_EXIT_AND_WAIT([ovn-controller])
3669OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3670OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3671
3672as ovn-sb
3673OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3674
3675as ovn-nb
3676OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3677
3678as northd
3679OVS_APP_EXIT_AND_WAIT([ovn-northd])
3680
3681as main
3682OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3683OVS_APP_EXIT_AND_WAIT([ovsdb-server])
3684
3685AT_CLEANUP
3686
3687
3688AT_SETUP([ovn -- 1 HV, 2 LSs, 1 lport/LS, 1 LR])
5412db30
J
3689AT_KEYWORDS([router-admin-state])
3690AT_SKIP_IF([test $HAVE_PYTHON = no])
3691ovn_start
3692
3693# Logical network:
3694# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
3695# and has switch ls2 (172.16.1.0/24) connected to it.
3696
fa2a27b2 3697ovn-nbctl lr-add R1
5412db30 3698
ea46a4e9
JP
3699ovn-nbctl ls-add ls1
3700ovn-nbctl ls-add ls2
5412db30
J
3701
3702# Connect ls1 to R1
bf44c2cd 3703ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3704ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 type=router \
31114af7 3705 options:router-port=ls1 addresses=\"00:00:00:01:02:03\"
5412db30
J
3706
3707# Connect ls2 to R1
bf44c2cd 3708ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3709ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 type=router \
31114af7 3710 options:router-port=ls2 addresses=\"00:00:00:01:02:04\"
5412db30
J
3711
3712# Create logical port ls1-lp1 in ls1
31ed1192
JP
3713ovn-nbctl lsp-add ls1 ls1-lp1 \
3714-- lsp-set-addresses ls1-lp1 "f0:00:00:01:02:03 192.168.1.2"
5412db30
J
3715
3716# Create logical port ls2-lp1 in ls2
31ed1192
JP
3717ovn-nbctl lsp-add ls2 ls2-lp1 \
3718-- lsp-set-addresses ls2-lp1 "f0:00:00:01:02:04 172.16.1.2"
5412db30
J
3719
3720# Create one hypervisor and create OVS ports corresponding to logical ports.
3721net_add n1
3722
3723sim_add hv1
3724as hv1
3725ovs-vsctl add-br br-phys
3726ovn_attach n1 br-phys 192.168.0.1
3727ovs-vsctl -- add-port br-int vif1 -- \
3728 set interface vif1 external-ids:iface-id=ls1-lp1 \
3729 options:tx_pcap=hv1/vif1-tx.pcap \
3730 options:rxq_pcap=hv1/vif1-rx.pcap \
3731 ofport-request=1
3732
3733ovs-vsctl -- add-port br-int vif2 -- \
3734 set interface vif2 external-ids:iface-id=ls2-lp1 \
3735 options:tx_pcap=hv1/vif2-tx.pcap \
3736 options:rxq_pcap=hv1/vif2-rx.pcap \
3737 ofport-request=1
3738
3739
3740# Allow some time for ovn-northd and ovn-controller to catch up.
3741# XXX This should be more systematic.
3742sleep 1
3743
3744# Send ip packets between the two ports.
3745ip_to_hex() {
3746 printf "%02x%02x%02x%02x" "$@"
3747}
5412db30
J
3748
3749# Packet to send.
3750src_mac="f00000010203"
3751dst_mac="000000010203"
3752src_ip=`ip_to_hex 192 168 1 2`
3753dst_ip=`ip_to_hex 172 16 1 2`
3754packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3755as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3756
3757
3758echo "---------NB dump-----"
3759ovn-nbctl show
3760echo "---------------------"
3761ovn-nbctl list logical_router
3762echo "---------------------"
3763ovn-nbctl list logical_router_port
3764echo "---------------------"
3765
3766echo "---------SB dump-----"
3767ovn-sbctl list datapath_binding
3768echo "---------------------"
3769ovn-sbctl list logical_flow
3770echo "---------------------"
3771
3772echo "------ hv1 dump ----------"
3773as hv1 ovs-ofctl dump-flows br-int
3774
5412db30
J
3775#Disable router R1
3776ovn-nbctl set Logical_Router R1 enabled=false
3777
3778echo "---------SB dump-----"
3779ovn-sbctl list datapath_binding
3780echo "---------------------"
3781ovn-sbctl list logical_flow
3782echo "---------------------"
3783
3784echo "------ hv1 dump ----------"
3785as hv1 ovs-ofctl dump-flows br-int
3786
a1361a6e
LR
3787# Allow some time for the disabling of logical router R1 to propagate.
3788# XXX This should be more systematic.
3789sleep 1
3790
5412db30
J
3791as hv1 ovs-appctl netdev-dummy/receive vif1 $packet
3792
3793# Packet to Expect
3794expect_src_mac="000000010204"
3795expect_dst_mac="f00000010204"
49d7c759 3796echo "${expect_dst_mac}${expect_src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
5412db30 3797
49d7c759 3798OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
5412db30 3799
7a8f15e0 3800OVN_CLEANUP([hv1])
5412db30
J
3801
3802AT_CLEANUP
3803
28dc3fe9 3804AT_SETUP([ovn -- 2 HVs, 3 LS, 1 lport/LS, 2 peer LRs, static routes])
28dc3fe9
SR
3805AT_SKIP_IF([test $HAVE_PYTHON = no])
3806ovn_start
3807
3808# Logical network:
3809# Two LRs - R1 and R2 that are connected to each other as peers in 20.0.0.0/24
3810# network. R1 has switchess foo (192.168.1.0/24)
3811# connected to it.
3812# R2 has alice (172.16.1.0/24) and bob (172.16.2.0/24) connected to it.
3813
fa2a27b2
JP
3814ovn-nbctl lr-add R1
3815ovn-nbctl lr-add R2
28dc3fe9 3816
ea46a4e9
JP
3817ovn-nbctl ls-add foo
3818ovn-nbctl ls-add alice
3819ovn-nbctl ls-add bob
28dc3fe9
SR
3820
3821# Connect foo to R1
bf44c2cd 3822ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
31ed1192 3823ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 3824 options:router-port=foo addresses=\"00:00:00:01:02:03\"
28dc3fe9
SR
3825
3826# Connect alice to R2
bf44c2cd 3827ovn-nbctl lrp-add R2 alice 00:00:00:01:02:04 172.16.1.1/24
31ed1192 3828ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 3829 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
28dc3fe9
SR
3830
3831# Connect bob to R2
bf44c2cd 3832ovn-nbctl lrp-add R2 bob 00:00:00:01:02:05 172.16.2.1/24
31ed1192 3833ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob type=router \
31114af7 3834 options:router-port=bob addresses=\"00:00:00:01:02:05\"
28dc3fe9
SR
3835
3836# Connect R1 to R2
4685e523
JP
3837ovn-nbctl lrp-add R1 R1_R2 00:00:00:02:03:04 20.0.0.1/24 peer=R2_R1
3838ovn-nbctl lrp-add R2 R2_R1 00:00:00:02:03:05 20.0.0.2/24 peer=R1_R2
28dc3fe9
SR
3839
3840#install static routes
e48ccf3c
JP
3841ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
3842ovn-nbctl lr-route-add R2 172.16.2.0/24 20.0.0.2 R1_R2
3843ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
28dc3fe9
SR
3844
3845# Create logical port foo1 in foo
31ed1192
JP
3846ovn-nbctl lsp-add foo foo1 \
3847-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
28dc3fe9
SR
3848
3849# Create logical port alice1 in alice
31ed1192
JP
3850ovn-nbctl lsp-add alice alice1 \
3851-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
28dc3fe9
SR
3852
3853# Create logical port bob1 in bob
31ed1192
JP
3854ovn-nbctl lsp-add bob bob1 \
3855-- lsp-set-addresses bob1 "f0:00:00:01:02:05 172.16.2.2"
28dc3fe9
SR
3856
3857# Create two hypervisor and create OVS ports corresponding to logical ports.
3858net_add n1
3859
3860sim_add hv1
3861as hv1
3862ovs-vsctl add-br br-phys
3863ovn_attach n1 br-phys 192.168.0.1
3864ovs-vsctl -- add-port br-int hv1-vif1 -- \
3865 set interface hv1-vif1 external-ids:iface-id=foo1 \
3866 options:tx_pcap=hv1/vif1-tx.pcap \
3867 options:rxq_pcap=hv1/vif1-rx.pcap \
3868 ofport-request=1
3869
3870ovs-vsctl -- add-port br-int hv1-vif2 -- \
3871 set interface hv1-vif2 external-ids:iface-id=alice1 \
3872 options:tx_pcap=hv1/vif2-tx.pcap \
3873 options:rxq_pcap=hv1/vif2-rx.pcap \
3874 ofport-request=2
3875
3876sim_add hv2
3877as hv2
3878ovs-vsctl add-br br-phys
3879ovn_attach n1 br-phys 192.168.0.2
3880ovs-vsctl -- add-port br-int hv2-vif1 -- \
3881 set interface hv2-vif1 external-ids:iface-id=bob1 \
3882 options:tx_pcap=hv2/vif1-tx.pcap \
3883 options:rxq_pcap=hv2/vif1-rx.pcap \
3884 ofport-request=1
3885
3886
3887# Pre-populate the hypervisors' ARP tables so that we don't lose any
3888# packets for ARP resolution (native tunneling doesn't queue packets
3889# for ARP resolution).
74868f2c 3890OVN_POPULATE_ARP
28dc3fe9
SR
3891
3892# Allow some time for ovn-northd and ovn-controller to catch up.
3893# XXX This should be more systematic.
3894sleep 1
3895
3896ip_to_hex() {
3897 printf "%02x%02x%02x%02x" "$@"
3898}
28dc3fe9
SR
3899
3900# Send ip packets between foo1 and alice1
3901src_mac="f00000010203"
3902dst_mac="000000010203"
3903src_ip=`ip_to_hex 192 168 1 2`
3904dst_ip=`ip_to_hex 172 16 1 2`
3905packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3906as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3907
3908# Send ip packets between foo1 and bob1
3909src_mac="f00000010203"
3910dst_mac="000000010203"
3911src_ip=`ip_to_hex 192 168 1 2`
3912dst_ip=`ip_to_hex 172 16 2 2`
3913packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
3914as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
3915
3916echo "---------NB dump-----"
3917ovn-nbctl show
3918echo "---------------------"
3919ovn-nbctl list logical_router
3920echo "---------------------"
3921ovn-nbctl list logical_router_port
3922echo "---------------------"
3923
3924echo "---------SB dump-----"
3925ovn-sbctl list datapath_binding
3926echo "---------------------"
3927ovn-sbctl list port_binding
3928echo "---------------------"
3929
3930echo "------ hv1 dump ----------"
3931as hv1 ovs-ofctl dump-flows br-int
3932echo "------ hv2 dump ----------"
3933as hv2 ovs-ofctl dump-flows br-int
3934
3935# Packet to Expect at bob1
3936src_mac="000000010205"
3937dst_mac="f00000010205"
3938src_ip=`ip_to_hex 192 168 1 2`
3939dst_ip=`ip_to_hex 172 16 2 2`
49d7c759 3940echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3941
49d7c759 3942OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
28dc3fe9
SR
3943
3944# Packet to Expect at alice1
3945src_mac="000000010204"
3946dst_mac="f00000010204"
3947src_ip=`ip_to_hex 192 168 1 2`
3948dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 3949echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
28dc3fe9 3950
49d7c759 3951OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
28dc3fe9 3952
7a8f15e0 3953OVN_CLEANUP([hv1],[hv2])
28dc3fe9
SR
3954
3955AT_CLEANUP
5412db30 3956
0ee8aaf6 3957AT_SETUP([ovn -- send gratuitous arp on localnet])
d08dbed7 3958AT_SKIP_IF([test $HAVE_PYTHON = no])
0ee8aaf6 3959ovn_start
ea46a4e9 3960ovn-nbctl ls-add lsw0
0ee8aaf6
RR
3961net_add n1
3962sim_add hv
3963as hv
3964ovs-vsctl \
3965 -- add-br br-phys \
3966 -- add-br br-eth0
3967
3968ovn_attach n1 br-phys 192.168.0.1
3969
3970AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
3971AT_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])
3972
3973# Create a vif.
31ed1192
JP
3974AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
3975AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.2"])
3976AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
0ee8aaf6
RR
3977
3978# Create a localnet port.
31ed1192
JP
3979AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
3980AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
3981AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
3982AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
0ee8aaf6
RR
3983
3984AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
3985
3986# Wait for packet to be received.
49d7c759
BP
3987echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
3988OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
0ee8aaf6 3989
5b57e12a
GL
3990# Check GARP packet when restart openflow connection.
3991as hv
3992OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
3993
3994OVS_WAIT_UNTIL([grep -c "waiting 4 seconds before reconnect" hv/ovn-controller.log])
3995
3996as hv
3997start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
3998
3999# Wait for packet to be received.
4000echo "fffffffffffff0000000000108060001080006040001f00000000001c0a80102000000000000c0a80102" > expected
4001OVN_CHECK_PACKETS([hv/snoopvif-tx.pcap], [expected])
4002
0ee8aaf6
RR
4003# Delete the localnet ports.
4004AT_CHECK([ovs-vsctl del-port localvif1])
31ed1192 4005AT_CHECK([ovn-nbctl lsp-del ln_port])
0ee8aaf6 4006
7a8f15e0 4007OVN_CLEANUP([hv])
0ee8aaf6
RR
4008
4009AT_CLEANUP
75cf9d2b
GS
4010
4011AT_SETUP([ovn -- 2 HVs, 3 LRs connected via LS, static routes])
75cf9d2b
GS
4012AT_SKIP_IF([test $HAVE_PYTHON = no])
4013ovn_start
4014
4015# Logical network:
4016# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
4017# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4018# connected to it. R2 has alice (172.16.1.0/24) and R3 has bob (10.32.1.0/24)
4019# connected to it.
4020
fa2a27b2
JP
4021ovn-nbctl lr-add R1
4022ovn-nbctl lr-add R2
4023ovn-nbctl lr-add R3
75cf9d2b 4024
ea46a4e9
JP
4025ovn-nbctl ls-add foo
4026ovn-nbctl ls-add alice
4027ovn-nbctl ls-add bob
4028ovn-nbctl ls-add join
75cf9d2b
GS
4029
4030# Connect foo to R1
31114af7 4031ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4032ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
31114af7 4033 options:router-port=foo addresses=\"00:00:01:01:02:03\"
75cf9d2b
GS
4034
4035# Connect alice to R2
31114af7 4036ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4037ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4038 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
75cf9d2b
GS
4039
4040# Connect bob to R3
31114af7 4041ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 10.32.1.1/24
31ed1192 4042ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
80f408f4 4043 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
75cf9d2b
GS
4044
4045# Connect R1 to join
31114af7 4046ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4047ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4048 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
75cf9d2b
GS
4049
4050# Connect R2 to join
31114af7 4051ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4052ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4053 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
75cf9d2b
GS
4054
4055# Connect R3 to join
31114af7 4056ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
31ed1192 4057ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
80f408f4 4058 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
75cf9d2b
GS
4059
4060#install static routes
e48ccf3c
JP
4061ovn-nbctl lr-route-add R1 172.16.1.0/24 20.0.0.2
4062ovn-nbctl lr-route-add R1 10.32.1.0/24 20.0.0.3
75cf9d2b 4063
e48ccf3c
JP
4064ovn-nbctl lr-route-add R2 192.168.1.0/24 20.0.0.1
4065ovn-nbctl lr-route-add R2 10.32.1.0/24 20.0.0.3
75cf9d2b 4066
e48ccf3c
JP
4067ovn-nbctl lr-route-add R3 192.168.1.0/24 20.0.0.1
4068ovn-nbctl lr-route-add R3 172.16.1.0/24 20.0.0.2
75cf9d2b
GS
4069
4070# Create logical port foo1 in foo
31ed1192
JP
4071ovn-nbctl lsp-add foo foo1 \
4072-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
75cf9d2b
GS
4073
4074# Create logical port alice1 in alice
31ed1192
JP
4075ovn-nbctl lsp-add alice alice1 \
4076-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
75cf9d2b
GS
4077
4078# Create logical port bob1 in bob
31ed1192
JP
4079ovn-nbctl lsp-add bob bob1 \
4080-- lsp-set-addresses bob1 "f0:00:00:01:02:05 10.32.1.2"
75cf9d2b
GS
4081
4082# Create two hypervisor and create OVS ports corresponding to logical ports.
4083net_add n1
4084
4085sim_add hv1
4086as hv1
4087ovs-vsctl add-br br-phys
4088ovn_attach n1 br-phys 192.168.0.1
4089ovs-vsctl -- add-port br-int hv1-vif1 -- \
4090 set interface hv1-vif1 external-ids:iface-id=foo1 \
4091 options:tx_pcap=hv1/vif1-tx.pcap \
4092 options:rxq_pcap=hv1/vif1-rx.pcap \
4093 ofport-request=1
4094
4095ovs-vsctl -- add-port br-int hv1-vif2 -- \
4096 set interface hv1-vif2 external-ids:iface-id=alice1 \
4097 options:tx_pcap=hv1/vif2-tx.pcap \
4098 options:rxq_pcap=hv1/vif2-rx.pcap \
4099 ofport-request=2
4100
4101sim_add hv2
4102as hv2
4103ovs-vsctl add-br br-phys
4104ovn_attach n1 br-phys 192.168.0.2
4105ovs-vsctl -- add-port br-int hv2-vif1 -- \
4106 set interface hv2-vif1 external-ids:iface-id=bob1 \
4107 options:tx_pcap=hv2/vif1-tx.pcap \
4108 options:rxq_pcap=hv2/vif1-rx.pcap \
4109 ofport-request=1
4110
4111
4112# Pre-populate the hypervisors' ARP tables so that we don't lose any
4113# packets for ARP resolution (native tunneling doesn't queue packets
4114# for ARP resolution).
74868f2c 4115OVN_POPULATE_ARP
75cf9d2b
GS
4116
4117# Allow some time for ovn-northd and ovn-controller to catch up.
4118# XXX This should be more systematic.
4119sleep 1
4120
4121ip_to_hex() {
4122 printf "%02x%02x%02x%02x" "$@"
4123}
75cf9d2b
GS
4124
4125# Send ip packets between foo1 and alice1
4126src_mac="f00000010203"
4127dst_mac="000001010203"
4128src_ip=`ip_to_hex 192 168 1 2`
4129dst_ip=`ip_to_hex 172 16 1 2`
4130packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4131as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4132as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4133
4134# Send ip packets between foo1 and bob1
4135src_mac="f00000010203"
4136dst_mac="000001010203"
4137src_ip=`ip_to_hex 192 168 1 2`
4138dst_ip=`ip_to_hex 10 32 1 2`
4139packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4140as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4141
4142echo "---------NB dump-----"
4143ovn-nbctl show
4144echo "---------------------"
4145ovn-nbctl list logical_router
4146echo "---------------------"
4147ovn-nbctl list logical_router_port
4148echo "---------------------"
4149
4150echo "---------SB dump-----"
4151ovn-sbctl list datapath_binding
4152echo "---------------------"
4153ovn-sbctl list port_binding
4154echo "---------------------"
4155ovn-sbctl dump-flows
4156echo "---------------------"
4157
4158echo "------ hv1 dump ----------"
4159as hv1 ovs-ofctl show br-int
4160as hv1 ovs-ofctl dump-flows br-int
4161echo "------ hv2 dump ----------"
4162as hv2 ovs-ofctl show br-int
4163as hv2 ovs-ofctl dump-flows br-int
4164echo "----------------------------"
4165
4166# Packet to Expect at bob1
4167src_mac="000003010203"
4168dst_mac="f00000010205"
4169src_ip=`ip_to_hex 192 168 1 2`
4170dst_ip=`ip_to_hex 10 32 1 2`
49d7c759 4171echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 4172
49d7c759 4173OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
75cf9d2b
GS
4174
4175# Packet to Expect at alice1
4176src_mac="000002010203"
4177dst_mac="f00000010204"
4178src_ip=`ip_to_hex 192 168 1 2`
4179dst_ip=`ip_to_hex 172 16 1 2`
49d7c759 4180echo "${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000" > expected
75cf9d2b 4181
49d7c759 4182OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
75cf9d2b 4183
7a8f15e0 4184OVN_CLEANUP([hv1],[hv2])
75cf9d2b
GS
4185
4186AT_CLEANUP
c1645003 4187
281977f7 4188AT_SETUP([ovn -- dhcpv4 : 1 HV, 2 LS, 2 LSPs/LS])
281977f7
NS
4189AT_SKIP_IF([test $HAVE_PYTHON = no])
4190ovn_start
4191
4192ovn-nbctl ls-add ls1
4193
4194ovn-nbctl lsp-add ls1 ls1-lp1 \
4195-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4196
4197ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
4198
4199ovn-nbctl lsp-add ls1 ls1-lp2 \
4200-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4201
4202ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
4203
4204ovn-nbctl ls-add ls2
4205ovn-nbctl lsp-add ls2 ls2-lp1 \
4206-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4207ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 30.0.0.6 40.0.0.4"
4208ovn-nbctl lsp-add ls2 ls2-lp2 \
4209-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4210ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 30.0.0.7"
4211
9060fc9a 4212d1="$(ovn-nbctl create DHCP_Options cidr=10.0.0.0/24 \
281977f7 4213options="\"server_id\"=\"10.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:01\" \
9060fc9a 4214\"lease_time\"=\"3600\" \"router\"=\"10.0.0.1\"")"
281977f7 4215
9060fc9a
MM
4216ovn-nbctl lsp-set-dhcpv4-options ls1-lp1 ${d1}
4217ovn-nbctl lsp-set-dhcpv4-options ls1-lp2 ${d1}
4218
4219d2="$(ovn-nbctl create DHCP_Options cidr=30.0.0.0/24 \
281977f7 4220options="\"server_id\"=\"30.0.0.1\" \"server_mac\"=\"ff:10:00:00:00:02\" \
9060fc9a
MM
4221\"lease_time\"=\"3600\"")"
4222
4223ovn-nbctl lsp-set-dhcpv4-options ls2-lp2 ${d2}
281977f7
NS
4224
4225net_add n1
4226sim_add hv1
4227
4228as hv1
4229ovs-vsctl add-br br-phys
4230ovn_attach n1 br-phys 192.168.0.1
4231ovs-vsctl -- add-port br-int hv1-vif1 -- \
4232 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4233 options:tx_pcap=hv1/vif1-tx.pcap \
4234 options:rxq_pcap=hv1/vif1-rx.pcap \
4235 ofport-request=1
4236
4237ovs-vsctl -- add-port br-int hv1-vif2 -- \
4238 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4239 options:tx_pcap=hv1/vif2-tx.pcap \
4240 options:rxq_pcap=hv1/vif2-rx.pcap \
4241 ofport-request=2
4242
4243ovs-vsctl -- add-port br-int hv1-vif3 -- \
4244 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4245 options:tx_pcap=hv1/vif3-tx.pcap \
4246 options:rxq_pcap=hv1/vif3-rx.pcap \
4247 ofport-request=3
4248
4249ovs-vsctl -- add-port br-int hv1-vif4 -- \
4250 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4251 options:tx_pcap=hv1/vif4-tx.pcap \
4252 options:rxq_pcap=hv1/vif4-rx.pcap \
4253 ofport-request=4
4254
74868f2c 4255OVN_POPULATE_ARP
281977f7
NS
4256
4257sleep 2
4258
4259as hv1 ovs-vsctl show
4260
281977f7
NS
4261# This shell function sends a DHCP request packet
4262# test_dhcp INPORT SRC_MAC DHCP_TYPE OFFER_IP ...
4263test_dhcp() {
213615b3
NS
4264 local inport=$1 src_mac=$2 dhcp_type=$3 offer_ip=$4 use_ip=$5
4265 shift; shift; shift; shift; shift;
4266 if test $use_ip != 0; then
4267 src_ip=$1
4268 dst_ip=$2
4269 shift; shift;
4270 else
4271 src_ip=`ip_to_hex 0 0 0 0`
4272 dst_ip=`ip_to_hex 255 255 255 255`
4273 fi
4274 local request=ffffffffffff${src_mac}0800451001100000000080110000${src_ip}${dst_ip}
281977f7 4275 # udp header and dhcp header
ab187e7e
BP
4276 request=${request}0044004300fc0000
4277 request=${request}010106006359aa760000000000000000000000000000000000000000${src_mac}
281977f7 4278 # client hardware padding
ab187e7e 4279 request=${request}00000000000000000000
281977f7 4280 # server hostname
ab187e7e
BP
4281 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4282 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4283 # boot file name
ab187e7e
BP
4284 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4285 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4286 request=${request}0000000000000000000000000000000000000000000000000000000000000000
4287 request=${request}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4288 # dhcp magic cookie
ab187e7e 4289 request=${request}63825363
281977f7 4290 # dhcp message type
ab187e7e 4291 request=${request}3501${dhcp_type}ff
281977f7
NS
4292
4293 if test $offer_ip != 0; then
213615b3 4294 local srv_mac=$1 srv_ip=$2 expected_dhcp_opts=$3
281977f7
NS
4295 # total IP length will be the IP length of the request packet
4296 # (which is 272 in our case) + 8 (padding bytes) + (expected_dhcp_opts / 2)
4297 ip_len=`expr 280 + ${#expected_dhcp_opts} / 2`
4298 udp_len=`expr $ip_len - 20`
04d60f6e
YT
4299 ip_len=$(printf "%x" $ip_len)
4300 udp_len=$(printf "%x" $udp_len)
281977f7
NS
4301 # $ip_len var will be in 3 digits i.e 134. So adding a '0' before $ip_len
4302 local reply=${src_mac}${srv_mac}080045100${ip_len}000000008011XXXX${srv_ip}${offer_ip}
4303 # udp header and dhcp header.
4304 # $udp_len var will be in 3 digits. So adding a '0' before $udp_len
ab187e7e 4305 reply=${reply}004300440${udp_len}0000020106006359aa760000000000000000
281977f7 4306 # your ip address
ab187e7e 4307 reply=${reply}${offer_ip}
281977f7 4308 # next server ip address, relay agent ip address, client mac address
ab187e7e 4309 reply=${reply}0000000000000000${src_mac}
281977f7 4310 # client hardware padding
ab187e7e 4311 reply=${reply}00000000000000000000
281977f7 4312 # server hostname
ab187e7e
BP
4313 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4314 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4315 # boot file name
ab187e7e
BP
4316 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4317 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4318 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
4319 reply=${reply}0000000000000000000000000000000000000000000000000000000000000000
281977f7 4320 # dhcp magic cookie
ab187e7e 4321 reply=${reply}63825363
281977f7
NS
4322 # dhcp message type
4323 local dhcp_reply_type=02
4324 if test $dhcp_type = 03; then
4325 dhcp_reply_type=05
4326 fi
ab187e7e 4327 reply=${reply}3501${dhcp_reply_type}${expected_dhcp_opts}00000000ff00000000
281977f7
NS
4328 echo $reply >> $inport.expected
4329 else
281977f7 4330 for outport; do
e4543cfe 4331 echo $request >> $outport.expected
281977f7
NS
4332 done
4333 fi
4334 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4335}
4336
4337reset_pcap_file() {
4338 local iface=$1
4339 local pcap_file=$2
4340 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4341options:rxq_pcap=dummy-rx.pcap
4342 rm -f ${pcap_file}*.pcap
4343 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4344options:rxq_pcap=${pcap_file}-rx.pcap
4345}
4346
4347ip_to_hex() {
4348 printf "%02x%02x%02x%02x" "$@"
4349}
4350
4351AT_CAPTURE_FILE([ofctl_monitor0.log])
4352as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4353--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4354
4355echo "---------NB dump-----"
4356ovn-nbctl show
4357echo "---------------------"
4358echo "---------SB dump-----"
4359ovn-sbctl list datapath_binding
4360echo "---------------------"
4361ovn-sbctl list logical_flow
4362echo "---------------------"
4363
4364echo "---------------------"
4365ovn-sbctl dump-flows
4366echo "---------------------"
4367
4368echo "------ hv1 dump ----------"
4369as hv1 ovs-ofctl dump-flows br-int
4370
4371# Send DHCPDISCOVER.
4372offer_ip=`ip_to_hex 10 0 0 4`
4373server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4374expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4375test_dhcp 1 f00000000001 01 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4376
4377# NXT_RESUMEs should be 1.
4378OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4379
4380$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
4381cat 1.expected | cut -c -48 > expout
4382AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
4383# Skipping the IPv4 checksum.
4384cat 1.expected | cut -c 53- > expout
4385AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
4386
4387# ovs-ofctl also resumes the packets and this causes other ports to receive
4388# the DHCP request packet. So reset the pcap files so that its easier to test.
4389reset_pcap_file hv1-vif1 hv1/vif1
4390reset_pcap_file hv1-vif2 hv1/vif2
4391rm -f 1.expected
4392rm -f 2.expected
4393
4394# Send DHCPREQUEST.
4395offer_ip=`ip_to_hex 10 0 0 6`
4396server_ip=`ip_to_hex 10 0 0 1`
7c76bf4e 4397expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
213615b3 4398test_dhcp 2 f00000000002 03 $offer_ip 0 ff1000000001 $server_ip $expected_dhcp_opts
281977f7
NS
4399
4400# NXT_RESUMEs should be 2.
4401OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4402
4403$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4404cat 2.expected | cut -c -48 > expout
4405AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4406# Skipping the IPv4 checksum.
4407cat 2.expected | cut -c 53- > expout
4408AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4409
4410reset_pcap_file hv1-vif1 hv1/vif1
4411reset_pcap_file hv1-vif2 hv1/vif2
4412rm -f 1.expected
4413rm -f 2.expected
4414
4415# Send Invalid DHCPv4 packet on ls1-lp2. It should be received by ovn-controller
4416# but should be resumed without the reply.
4417# ls1-lp1 (vif1-tx.pcap) should receive the DHCPv4 request packet twice,
4418# one from ovn-controller and the other from "ovs-ofctl resume."
4419offer_ip=0
213615b3 4420test_dhcp 2 f00000000002 08 $offer_ip 0 1 1
281977f7
NS
4421
4422# NXT_RESUMEs should be 3.
4423OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4424
4425# vif1-tx.pcap should have received the DHCPv4 (invalid) request packet
49d7c759 4426OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
281977f7
NS
4427
4428reset_pcap_file hv1-vif1 hv1/vif1
4429reset_pcap_file hv1-vif2 hv1/vif2
4430rm -f 1.expected
4431rm -f 2.expected
4432
4433# Send DHCPv4 packet on ls2-lp1. It doesn't have any DHCPv4 options defined.
4434# ls2-lp2 (vif4-tx.pcap) should receive the DHCPv4 request packet once.
4435
213615b3 4436test_dhcp 3 f00000000003 01 0 4 0
281977f7
NS
4437
4438# Send DHCPv4 packet on ls2-lp2. "router" DHCPv4 option is not defined for
4439# this lport.
213615b3 4440test_dhcp 4 f00000000004 01 0 3 0
281977f7
NS
4441
4442# NXT_RESUMEs should be 3.
4443OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4444
49d7c759
BP
4445OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [3.expected])
4446OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [4.expected])
281977f7 4447
213615b3
NS
4448# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.1.
4449offer_ip=`ip_to_hex 10 0 0 6`
4450server_ip=`ip_to_hex 10 0 0 1`
4451expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4452src_ip=$offer_ip
4453dst_ip=$server_ip
4454test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4455
4456# NXT_RESUMEs should be 4.
4457OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4458
4459$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4460cat 2.expected | cut -c -48 > expout
4461AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4462# Skipping the IPv4 checksum.
4463cat 2.expected | cut -c 53- > expout
4464AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4465
4466reset_pcap_file hv1-vif1 hv1/vif1
4467reset_pcap_file hv1-vif2 hv1/vif2
4468rm -f 1.expected
4469rm -f 2.expected
4470
4471# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 255.255.255.255.
4472offer_ip=`ip_to_hex 10 0 0 6`
4473server_ip=`ip_to_hex 10 0 0 1`
4474expected_dhcp_opts=330400000e100104ffffff0003040a00000136040a000001
4475src_ip=$offer_ip
4476dst_ip=`ip_to_hex 255 255 255 255`
4477test_dhcp 2 f00000000002 03 $offer_ip 1 $src_ip $dst_ip ff1000000001 $server_ip $expected_dhcp_opts
4478
4479# NXT_RESUMEs should be 5.
4480OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4481
4482$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
4483cat 2.expected | cut -c -48 > expout
4484AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
4485# Skipping the IPv4 checksum.
4486cat 2.expected | cut -c 53- > expout
4487AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
4488
4489reset_pcap_file hv1-vif1 hv1/vif1
4490reset_pcap_file hv1-vif2 hv1/vif2
4491rm -f 1.expected
4492rm -f 2.expected
4493
4494# Send DHCPREQUEST with ip4.src set to 10.0.0.6 and ip4.dst set to 10.0.0.4.
4495# The packet should not be received by ovn-controller.
4496src_ip=`ip_to_hex 10 0 0 6`
4497dst_ip=`ip_to_hex 10 0 0 4`
4498test_dhcp 2 f00000000002 03 0 1 $src_ip $dst_ip 1
4499
4500# NXT_RESUMEs should be 5.
4501OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4502
4503# vif1-tx.pcap should have received the DHCPv4 request packet
4504OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [1.expected])
4505
281977f7 4506as hv1
33ac3c83
NS
4507OVS_APP_EXIT_AND_WAIT([ovn-controller])
4508OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4509OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4510
4511as ovn-sb
4512OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4513
4514as ovn-nb
4515OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4516
4517as northd
4518OVS_APP_EXIT_AND_WAIT([ovn-northd])
4519
4520as main
4521OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4522OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4523
4524AT_CLEANUP
4525
40df4566 4526AT_SETUP([ovn -- dhcpv6 : 1 HV, 2 LS, 5 LSPs])
33ac3c83
NS
4527AT_SKIP_IF([test $HAVE_PYTHON = no])
4528ovn_start
4529
4530ovn-nbctl ls-add ls1
4531ovn-nbctl lsp-add ls1 ls1-lp1 \
4532-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4533
4534ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 ae70::4"
4535
4536ovn-nbctl lsp-add ls1 ls1-lp2 \
4537-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4538
4539ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 ae70::5"
4540
40df4566
ZKL
4541ovn-nbctl lsp-add ls1 ls1-lp3 \
4542-- lsp-set-addresses ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4543
4544ovn-nbctl lsp-set-port-security ls1-lp3 "f0:00:00:00:00:22 ae70::22"
4545
9060fc9a
MM
4546d1="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4547options="\"server_id\"=\"00:00:00:10:00:01\"")"
4548
4549ovn-nbctl lsp-set-dhcpv6-options ls1-lp1 ${d1}
4550ovn-nbctl lsp-set-dhcpv6-options ls1-lp2 ${d1}
4551
4552d2="$(ovn-nbctl create DHCP_Options cidr="ae70\:\:/64" \
4553options="\"dhcpv6_stateless\"=\"true\" \"server_id\"=\"00:00:00:10:00:01\"")"
33ac3c83 4554
9060fc9a 4555ovn-nbctl lsp-set-dhcpv6-options ls1-lp3 ${d2}
40df4566 4556
33ac3c83
NS
4557ovn-nbctl ls-add ls2
4558ovn-nbctl lsp-add ls2 ls2-lp1 \
4559-- lsp-set-addresses ls2-lp1 "f0:00:00:00:00:03 be70::3"
4560ovn-nbctl lsp-set-port-security ls2-lp1 "f0:00:00:00:00:03 be70::3"
4561ovn-nbctl lsp-add ls2 ls2-lp2 \
4562-- lsp-set-addresses ls2-lp2 "f0:00:00:00:00:04 be70::4"
4563ovn-nbctl lsp-set-port-security ls2-lp2 "f0:00:00:00:00:04 be70::4"
4564
4565net_add n1
4566sim_add hv1
4567
4568as hv1
4569ovs-vsctl add-br br-phys
4570ovn_attach n1 br-phys 192.168.0.1
4571ovs-vsctl -- add-port br-int hv1-vif1 -- \
4572 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
4573 options:tx_pcap=hv1/vif1-tx.pcap \
4574 options:rxq_pcap=hv1/vif1-rx.pcap \
4575 ofport-request=1
4576
4577ovs-vsctl -- add-port br-int hv1-vif2 -- \
4578 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
4579 options:tx_pcap=hv1/vif2-tx.pcap \
4580 options:rxq_pcap=hv1/vif2-rx.pcap \
4581 ofport-request=2
4582
4583ovs-vsctl -- add-port br-int hv1-vif3 -- \
4584 set interface hv1-vif3 external-ids:iface-id=ls2-lp1 \
4585 options:tx_pcap=hv1/vif3-tx.pcap \
4586 options:rxq_pcap=hv1/vif3-rx.pcap \
4587 ofport-request=3
4588
4589ovs-vsctl -- add-port br-int hv1-vif4 -- \
4590 set interface hv1-vif4 external-ids:iface-id=ls2-lp2 \
4591 options:tx_pcap=hv1/vif4-tx.pcap \
4592 options:rxq_pcap=hv1/vif4-rx.pcap \
4593 ofport-request=4
4594
40df4566
ZKL
4595ovs-vsctl -- add-port br-int hv1-vif5 -- \
4596 set interface hv1-vif5 external-ids:iface-id=ls1-lp3 \
4597 options:tx_pcap=hv1/vif5-tx.pcap \
4598 options:rxq_pcap=hv1/vif5-rx.pcap \
4599 ofport-request=5
4600
74868f2c 4601OVN_POPULATE_ARP
33ac3c83
NS
4602
4603sleep 2
4604
4605trim_zeros() {
4606 sed 's/\(00\)\{1,\}$//'
4607}
4608
4609# This shell function sends a DHCPv6 request packet
40df4566
ZKL
4610# test_dhcpv6 INPORT SRC_MAC SRC_LLA DHCPv6_MSG_TYPE OFFER_IP OUTPORT...
4611# The OUTPORTs (zero or more) list the VIFs on which the original DHCPv6
33ac3c83
NS
4612# packet should be received twice (one from ovn-controller and the other
4613# from the "ovs-ofctl monitor br-int resume"
4614test_dhcpv6() {
4615 local inport=$1 src_mac=$2 src_lla=$3 msg_code=$4 offer_ip=$5
4616 local request=ffffffffffff${src_mac}86dd00000000002a1101${src_lla}
4617 # dst ip ff02::1:2
ab187e7e 4618 request=${request}ff020000000000000000000000010002
33ac3c83 4619 # udp header and dhcpv6 header
ab187e7e 4620 request=${request}02220223002affff${msg_code}010203
33ac3c83 4621 # Client identifier
ab187e7e 4622 request=${request}0001000a00030001${src_mac}
33ac3c83 4623 # IA-NA (Identity Association for Non Temporary Address)
ab187e7e 4624 request=${request}0003000c0102030400000e1000001518
33ac3c83
NS
4625 shift; shift; shift; shift; shift;
4626 if test $offer_ip != 0; then
4627 local server_mac=000000100001
4628 local server_lla=fe80000000000000020000fffe100001
4629 local reply_code=07
4630 if test $msg_code = 01; then
4631 reply_code=02
4632 fi
40df4566
ZKL
4633 local msg_len=54
4634 if test $offer_ip = 1; then
4635 msg_len=28
4636 fi
4637 local reply=${src_mac}${server_mac}86dd0000000000${msg_len}1101${server_lla}${src_lla}
33ac3c83 4638 # udp header and dhcpv6 header
ab187e7e 4639 reply=${reply}0223022200${msg_len}ffff${reply_code}010203
33ac3c83 4640 # Client identifier
ab187e7e 4641 reply=${reply}0001000a00030001${src_mac}
33ac3c83 4642 # IA-NA
40df4566 4643 if test $offer_ip != 1; then
ab187e7e 4644 reply=${reply}0003002801020304ffffffffffffffff00050018${offer_ip}ffffffffffffffff
40df4566 4645 fi
33ac3c83 4646 # Server identifier
ab187e7e 4647 reply=${reply}0002000a00030001${server_mac}
33ac3c83
NS
4648 echo $reply | trim_zeros >> $inport.expected
4649 else
4650 for outport; do
4651 echo $request | trim_zeros >> $outport.expected
4652 done
4653 fi
4654
4655 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
4656}
4657
4658reset_pcap_file() {
4659 local iface=$1
4660 local pcap_file=$2
4661 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
4662options:rxq_pcap=dummy-rx.pcap
4663 rm -f ${pcap_file}*.pcap
4664 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
4665options:rxq_pcap=${pcap_file}-rx.pcap
4666}
4667
4668AT_CAPTURE_FILE([ofctl_monitor0.log])
4669as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
4670--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
4671
4672echo "---------NB dump-----"
4673ovn-nbctl show
4674echo "---------------------"
4675echo "---------SB dump-----"
4676ovn-sbctl list datapath_binding
4677echo "---------------------"
4678ovn-sbctl list logical_flow
4679echo "---------------------"
4680
4681echo "---------------------"
4682ovn-sbctl dump-flows
4683echo "---------------------"
4684
4685echo "------ hv1 dump ----------"
4686as hv1 ovs-ofctl dump-flows br-int
4687
4688src_mac=f00000000001
4689src_lla=fe80000000000000f20000fffe000001
4690offer_ip=ae700000000000000000000000000004
4691test_dhcpv6 1 $src_mac $src_lla 01 $offer_ip
4692
4693# NXT_RESUMEs should be 1.
4694OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4695
4696$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4697# cat 1.expected | trim_zeros > expout
4698cat 1.expected | cut -c -120 > expout
4699AT_CHECK([cat 1.packets | cut -c -120], [0], [expout])
4700# Skipping the UDP checksum
4701cat 1.expected | cut -c 125- > expout
4702AT_CHECK([cat 1.packets | cut -c 125-], [0], [expout])
4703
4704rm 1.expected
4705
4706# Send invalid packet on ls1-lp2. ovn-controller should resume the packet
4707# without any modifications and the packet should be received by ls1-lp1.
4708# ls1-lp1 will receive the packet twice, one from the ovn-controller after the
4709# resume and the other from ovs-ofctl monitor resume.
4710
4711reset_pcap_file hv1-vif1 hv1/vif1
4712reset_pcap_file hv1-vif2 hv1/vif2
4713
4714src_mac=f00000000002
4715src_lla=fe80000000000000f20000fffe000002
4716offer_ip=ae700000000000000000000000000005
4717# Set invalid msg_type
4718
4719test_dhcpv6 2 $src_mac $src_lla 10 0 1 1
4720
4721# NXT_RESUMEs should be 2.
4722OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4723
4724# vif2-tx.pcap should not have received the DHCPv6 reply packet
4725rm 2.packets
4726$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap | trim_zeros > 2.packets
4727AT_CHECK([cat 2.packets], [0], [])
4728
4729# vif1-tx.pcap should have received the DHCPv6 (invalid) request packet
4730$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap | trim_zeros > 1.packets
4731cat 1.expected > expout
4732AT_CHECK([cat 1.packets], [0], [expout])
4733
4734# Send DHCPv6 packet on ls2-lp1. native DHCPv6 is disabled on this port.
4735# There should be no DHCPv6 reply from ovn-controller and the request packet
4736# should be received by ls2-lp2.
4737
4738src_mac=f00000000003
4739src_lla=fe80000000000000f20000fffe000003
4740test_dhcpv6 3 $src_mac $src_lla 01 0 4
4741
4742# NXT_RESUMEs should be 2 only.
4743OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4744
4745# vif3-tx.pcap should not have received the DHCPv6 reply packet
4746$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap | trim_zeros > 3.packets
4747AT_CHECK([cat 3.packets], [0], [])
4748
4749# vif4-tx.pcap should have received the DHCPv6 request packet
4750$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif4-tx.pcap | trim_zeros > 4.packets
4751cat 4.expected > expout
4752AT_CHECK([cat 4.packets], [0], [expout])
4753
40df4566
ZKL
4754# Send DHCPv6 packet on ls1-lp3. native DHCPv6 works as stateless mode for this port.
4755# The DHCPv6 reply should doesn't contian offer_ip.
4756src_mac=f00000000022
4757src_lla=fe80000000000000f20000fffe000022
4758reset_pcap_file hv1-vif5 hv1/vif5
4759test_dhcpv6 5 $src_mac $src_lla 01 1 5
4760
4761# NXT_RESUMEs should be 3.
4762OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
4763
4764$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif5-tx.pcap | trim_zeros > 5.packets
4765# Skipping the UDP checksum
4766cat 5.expected | cut -c 1-120,125- > expout
4767AT_CHECK([cat 5.packets | cut -c 1-120,125- ], [0], [expout])
4768
33ac3c83 4769as hv1
281977f7
NS
4770OVS_APP_EXIT_AND_WAIT([ovn-controller])
4771OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4772OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4773
4774as ovn-sb
4775OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4776
4777as ovn-nb
4778OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4779
4780as northd
4781OVS_APP_EXIT_AND_WAIT([ovn-northd])
4782
4783as main
4784OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
4785OVS_APP_EXIT_AND_WAIT([ovsdb-server])
4786
4787AT_CLEANUP
4788
c1645003 4789AT_SETUP([ovn -- 2 HVs, 2 LRs connected via LS, gateway router])
c1645003
GS
4790AT_SKIP_IF([test $HAVE_PYTHON = no])
4791ovn_start
4792
4793# Logical network:
4794# Two LRs - R1 and R2 that are connected to each other via LS "join"
4795# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24)
4796# connected to it. R2 has alice (172.16.1.0/24) connected to it.
4797# R2 is a gateway router.
4798
4799
4800
4801# Create two hypervisor and create OVS ports corresponding to logical ports.
4802net_add n1
4803
4804sim_add hv1
4805as hv1
4806ovs-vsctl add-br br-phys
4807ovn_attach n1 br-phys 192.168.0.1
4808ovs-vsctl -- add-port br-int hv1-vif1 -- \
4809 set interface hv1-vif1 external-ids:iface-id=foo1 \
4810 options:tx_pcap=hv1/vif1-tx.pcap \
4811 options:rxq_pcap=hv1/vif1-rx.pcap \
4812 ofport-request=1
4813
4814
4815sim_add hv2
4816as hv2
4817ovs-vsctl add-br br-phys
4818ovn_attach n1 br-phys 192.168.0.2
4819ovs-vsctl -- add-port br-int hv2-vif1 -- \
4820 set interface hv2-vif1 external-ids:iface-id=alice1 \
4821 options:tx_pcap=hv2/vif1-tx.pcap \
4822 options:rxq_pcap=hv2/vif1-rx.pcap \
4823 ofport-request=1
4824
4825# Pre-populate the hypervisors' ARP tables so that we don't lose any
4826# packets for ARP resolution (native tunneling doesn't queue packets
4827# for ARP resolution).
74868f2c 4828OVN_POPULATE_ARP
c1645003
GS
4829
4830ovn-nbctl create Logical_Router name=R1
4831ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4832
ea46a4e9
JP
4833ovn-nbctl ls-add foo
4834ovn-nbctl ls-add alice
4835ovn-nbctl ls-add join
c1645003
GS
4836
4837# Connect foo to R1
31114af7 4838ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
31ed1192 4839ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
80f408f4 4840 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
c1645003
GS
4841
4842# Connect alice to R2
31114af7 4843ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
31ed1192 4844ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
80f408f4 4845 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
c1645003
GS
4846
4847# Connect R1 to join
31114af7 4848ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
31ed1192 4849ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
80f408f4 4850 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
c1645003
GS
4851
4852# Connect R2 to join
31114af7 4853ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
31ed1192 4854ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
80f408f4 4855 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
c1645003
GS
4856
4857
4858#install static routes
4859ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4860ip_prefix=172.16.1.0/24 nexthop=20.0.0.2 -- add Logical_Router \
4861R1 static_routes @lrt
4862
4863ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4864ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4865R2 static_routes @lrt
4866
4867# Create logical port foo1 in foo
31ed1192
JP
4868ovn-nbctl lsp-add foo foo1 \
4869-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
c1645003
GS
4870
4871# Create logical port alice1 in alice
31ed1192
JP
4872ovn-nbctl lsp-add alice alice1 \
4873-- lsp-set-addresses alice1 "f0:00:00:01:02:04 172.16.1.2"
c1645003
GS
4874
4875
4876# Allow some time for ovn-northd and ovn-controller to catch up.
4877# XXX This should be more systematic.
4878sleep 2
4879
4880ip_to_hex() {
4881 printf "%02x%02x%02x%02x" "$@"
4882}
c1645003
GS
4883
4884# Send ip packets between foo1 and alice1
4885src_mac="f00000010203"
4886dst_mac="000001010203"
4887src_ip=`ip_to_hex 192 168 1 2`
4888dst_ip=`ip_to_hex 172 16 1 2`
4889packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
4890
4891echo "---------NB dump-----"
4892ovn-nbctl show
4893echo "---------------------"
4894ovn-nbctl list logical_router
4895echo "---------------------"
4896ovn-nbctl list logical_router_port
4897echo "---------------------"
4898
4899echo "---------SB dump-----"
4900ovn-sbctl list datapath_binding
4901echo "---------------------"
4902ovn-sbctl list port_binding
4903echo "---------------------"
4904ovn-sbctl dump-flows
4905echo "---------------------"
4906ovn-sbctl list chassis
4907ovn-sbctl list encap
4908echo "---------------------"
4909
c1645003
GS
4910# Packet to Expect at alice1
4911src_mac="000002010203"
4912dst_mac="f00000010204"
4913src_ip=`ip_to_hex 192 168 1 2`
4914dst_ip=`ip_to_hex 172 16 1 2`
4915expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
4916
4917
4918as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
4919as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
4920
ab39371d
RM
4921echo "------ hv1 dump after packet 1 ----------"
4922as hv1 ovs-ofctl show br-int
4923as hv1 ovs-ofctl dump-flows br-int
4924echo "------ hv2 dump after packet 1 ----------"
4925as hv2 ovs-ofctl show br-int
4926as hv2 ovs-ofctl dump-flows br-int
4927echo "----------------------------"
4928
49d7c759
BP
4929echo $expected > expected
4930OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
c1645003 4931
34114cf8
GS
4932# Delete the router and re-create it. Things should work as before.
4933ovn-nbctl lr-del R2
4934ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
4935# Connect alice to R2
4936ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
4937# Connect R2 to join
4938ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
4939
4940ovn-nbctl -- --id=@lrt create Logical_Router_Static_Route \
4941ip_prefix=192.168.1.0/24 nexthop=20.0.0.1 -- add Logical_Router \
4942R2 static_routes @lrt
4943
4944# Wait for ovn-controller to catch up.
4945sleep 1
4946
4947# Send the packet again.
4948as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
ab39371d
RM
4949
4950echo "------ hv1 dump after packet 2 ----------"
4951as hv1 ovs-ofctl show br-int
4952as hv1 ovs-ofctl dump-flows br-int
4953echo "------ hv2 dump after packet 2 ----------"
4954as hv2 ovs-ofctl show br-int
4955as hv2 ovs-ofctl dump-flows br-int
4956echo "----------------------------"
4957
49d7c759
BP
4958echo $expected >> expected
4959OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
34114cf8 4960
7a8f15e0 4961OVN_CLEANUP([hv1],[hv2])
c1645003
GS
4962
4963AT_CLEANUP
bb3c4568
FF
4964
4965AT_SETUP([ovn -- icmp_reply: 1 HVs, 2 LSs, 1 lport/LS, 1 LR])
4966AT_KEYWORDS([router-icmp-reply])
4967AT_SKIP_IF([test $HAVE_PYTHON = no])
4968ovn_start
4969
4970# Logical network:
4971# One LR - R1 has switch ls1 (191.168.1.0/24) connected to it,
4972# and has switch ls2 (172.16.1.0/24) connected to it.
4973
fa2a27b2 4974ovn-nbctl lr-add R1
bb3c4568 4975
ea46a4e9
JP
4976ovn-nbctl ls-add ls1
4977ovn-nbctl ls-add ls2
bb3c4568
FF
4978
4979# Connect ls1 to R1
31114af7 4980ovn-nbctl lrp-add R1 ls1 00:00:00:01:02:f1 192.168.1.1/24
31ed1192 4981ovn-nbctl lsp-add ls1 rp-ls1 -- set Logical_Switch_Port rp-ls1 \
80f408f4 4982 type=router options:router-port=ls1 addresses=\"00:00:00:01:02:f1\"
bb3c4568
FF
4983
4984# Connect ls2 to R1
31114af7 4985ovn-nbctl lrp-add R1 ls2 00:00:00:01:02:f2 172.16.1.1/24
31ed1192 4986ovn-nbctl lsp-add ls2 rp-ls2 -- set Logical_Switch_Port rp-ls2 \
80f408f4 4987 type=router options:router-port=ls2 addresses=\"00:00:00:01:02:f2\"
bb3c4568
FF
4988
4989# Create logical port ls1-lp1 in ls1
31ed1192
JP
4990ovn-nbctl lsp-add ls1 ls1-lp1 \
4991-- lsp-set-addresses ls1-lp1 "00:00:00:01:02:03 192.168.1.2"
bb3c4568
FF
4992
4993# Create logical port ls2-lp1 in ls2
31ed1192
JP
4994ovn-nbctl lsp-add ls2 ls2-lp1 \
4995-- lsp-set-addresses ls2-lp1 "00:00:00:01:02:04 172.16.1.2"
bb3c4568
FF
4996
4997# Create one hypervisor and create OVS ports corresponding to logical ports.
4998net_add n1
4999
5000sim_add hv1
5001as hv1
5002ovs-vsctl add-br br-phys
5003ovn_attach n1 br-phys 192.168.0.1
5004ovs-vsctl -- add-port br-int vif1 -- \
5005 set interface vif1 external-ids:iface-id=ls1-lp1 \
5006 options:tx_pcap=hv1/vif1-tx.pcap \
5007 options:rxq_pcap=hv1/vif1-rx.pcap \
5008 ofport-request=1
5009
5010ovs-vsctl -- add-port br-int vif2 -- \
5011 set interface vif2 external-ids:iface-id=ls2-lp1 \
5012 options:tx_pcap=hv1/vif2-tx.pcap \
5013 options:rxq_pcap=hv1/vif2-rx.pcap \
5014 ofport-request=1
5015
5016
5017# Allow some time for ovn-northd and ovn-controller to catch up.
5018# XXX This should be more systematic.
5019sleep 1
5020
5021
5022ip_to_hex() {
5023 printf "%02x%02x%02x%02x" "$@"
5024}
bb3c4568
FF
5025for i in 1 2; do
5026 : > vif$i.expected
5027done
5028# test_ipv4_icmp_request INPORT ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM ICMP_CHKSUM [EXP_IP_CHKSUM EXP_ICMP_CHKSUM]
5029#
5030# Causes a packet to be received on INPORT. The packet is an ICMPv4
5031# request with ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHSUM and
5032# ICMP_CHKSUM as specified. If EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are
5033# provided, then it should be the ip and icmp checksums of the packet
5034# responded; otherwise, no reply is expected.
5035# In the absence of an ip checksum calculation helpers, this relies
5036# on the caller to provide the checksums for the ip and icmp headers.
5037# XXX This should be more systematic.
5038#
5039# INPORT is an lport number, e.g. 11 for vif11.
5040# ETH_SRC and ETH_DST are each 12 hex digits.
5041# IPV4_SRC and IPV4_DST are each 8 hex digits.
5042# IP_CHSUM and ICMP_CHKSUM are each 4 hex digits.
5043# EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits.
5044test_ipv4_icmp_request() {
5045 local inport=$1 eth_src=$2 eth_dst=$3 ipv4_src=$4 ipv4_dst=$5 ip_chksum=$6 icmp_chksum=$7
5046 local exp_ip_chksum=$8 exp_icmp_chksum=$9
5047 shift; shift; shift; shift; shift; shift; shift
5048 shift; shift
5049
5050 # Use ttl to exercise section 4.2.2.9 of RFC1812
5051 local ip_ttl=01
5052 local icmp_id=5fbf
5053 local icmp_seq=0001
5054 local icmp_data=$(seq 1 56 | xargs printf "%02x")
5055 local icmp_type_code_request=0800
5056 local icmp_payload=${icmp_type_code_request}${icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5057 local packet=${eth_dst}${eth_src}08004500005400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}${icmp_payload}
5058
5059 as hv1 ovs-appctl netdev-dummy/receive vif$inport $packet
5060 if test X$exp_icmp_chksum != X; then
5061 # Expect to receive the reply, if any. In same port where packet was sent.
5062 # Note: src and dst fields are expected to be reversed.
5063 local icmp_type_code_response=0000
5064 local reply_icmp_ttl=fe
5065 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_id}${icmp_seq}${icmp_data}
5066 local reply=${eth_src}${eth_dst}08004500005400004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
5067 echo $reply >> vif$inport.expected
5068 fi
5069}
5070
5071# Send ping packet to router's ip addresses, from each of the 2 logical ports.
5072rtr_l1_ip=$(ip_to_hex 192 168 1 1)
5073rtr_l2_ip=$(ip_to_hex 172 16 1 1)
5074l1_ip=$(ip_to_hex 192 168 1 2)
5075l2_ip=$(ip_to_hex 172 16 1 2)
5076
5077# Ping router ip address that is on same subnet as the logical port
5078test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l1_ip 0000 8510 02ff 8d10
5079test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l2_ip 0000 8510 02ff 8d10
5080
5081# Ping router ip address that is on the other side of the logical ports
5082test_ipv4_icmp_request 1 000000010203 0000000102f1 $l1_ip $rtr_l2_ip 0000 8510 02ff 8d10
5083test_ipv4_icmp_request 2 000000010204 0000000102f2 $l2_ip $rtr_l1_ip 0000 8510 02ff 8d10
5084
5085echo "---------NB dump-----"
5086ovn-nbctl show
5087echo "---------------------"
5088ovn-nbctl list logical_router
5089echo "---------------------"
5090ovn-nbctl list logical_router_port
5091echo "---------------------"
5092
5093echo "---------SB dump-----"
5094ovn-sbctl list datapath_binding
5095echo "---------------------"
5096ovn-sbctl list logical_flow
5097echo "---------------------"
5098
5099echo "------ hv1 dump ----------"
5100as hv1 ovs-ofctl dump-flows br-int
5101
5102# Now check the packets actually received against the ones expected.
5103for inport in 1 2; do
49d7c759 5104 OVN_CHECK_PACKETS([hv1/vif${inport}-tx.pcap], [vif$inport.expected])
bb3c4568
FF
5105done
5106
7a8f15e0 5107OVN_CLEANUP([hv1])
bb3c4568
FF
5108
5109AT_CLEANUP
94f79fcb
RB
5110
5111# 1 hypervisor, 1 port
5112# make sure that the port state is properly set to up and back down
5113# when created and deleted.
5114AT_SETUP([ovn -- port state up and down])
94f79fcb
RB
5115ovn_start
5116
5117ovn-nbctl ls-add ls1
5118ovn-nbctl lsp-add ls1 lp1
5119ovn-nbctl lsp-set-addresses lp1 unknown
5120
5121net_add n1
5122sim_add hv1
5123as hv1 ovs-vsctl add-br br-phys
5124as hv1 ovn_attach n1 br-phys 192.168.0.1
5125
5126as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5127OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5128
5129as hv1 ovs-vsctl del-port br-int vif1
5130OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5131
7a8f15e0 5132OVN_CLEANUP([hv1])
94f79fcb 5133
94f79fcb 5134AT_CLEANUP
e75451fe 5135
ccc6e1db
FF
5136# 1 hypervisor, 1 port
5137# make sure that the OF rules created to support a datapath are added/cleared
5138# when logical switch is created and removed.
5139AT_SETUP([ovn -- datapath rules added/removed])
1794d5f2 5140AT_KEYWORDS([cleanup])
ccc6e1db
FF
5141ovn_start
5142
5143net_add n1
5144sim_add hv1
5145as hv1 ovs-vsctl add-br br-phys
5146as hv1 ovn_attach n1 br-phys 192.168.0.1
5147
5148# This shell function checks if OF rules in br-int have clauses
5149# related to OVN datapaths. The caller determines if it should find
5150# a match in the output, or not.
5151#
5152# EXPECT_DATAPATH param determines whether flows that refer to
5153# datapath to should be present or not. 0 means
5154# they should not be.
5155# STAGE_INFO param is a simple string to help identify the stage
5156# in the test when this function was invoked.
5157test_datapath_in_of_rules() {
5158 local expect_datapath=$1 stage_info=$2
5159 echo "------ ovn-nbctl show ${stage_info} ------"
5160 ovn-nbctl show
5161 echo "------ ovn-sbctl show ${stage_info} ------"
5162 ovn-sbctl show
5163 echo "------ OF rules ${stage_info} ------"
5164 AT_CHECK([ovs-ofctl dump-flows br-int], [0], [stdout])
5165 # if there is a datapath mentioned in the output, check for the
5166 # magic keyword that represents one, based on the exit status of
5167 # a quiet grep
5168 if test $expect_datapath != 0; then
4618b102 5169 AT_CHECK([grep -q -i 'metadata=' stdout], [0], [ignore-nolog])
ccc6e1db 5170 else
4618b102 5171 AT_CHECK([grep -q -i 'metadata=' stdout], [1], [ignore-nolog])
ccc6e1db
FF
5172 fi
5173}
5174
5175test_datapath_in_of_rules 0 "before ls+port create"
5176
5177ovn-nbctl ls-add ls1
5178ovn-nbctl lsp-add ls1 lp1
5179ovn-nbctl lsp-set-addresses lp1 unknown
5180
5181as hv1 ovs-vsctl add-port br-int vif1 -- set Interface vif1 external-ids:iface-id=lp1
5182OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xup])
5183
5184test_datapath_in_of_rules 1 "after port is bound"
5185
5186as hv1 ovs-vsctl del-port br-int vif1
5187OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp1` = xdown])
5188
5189ovn-nbctl lsp-set-addresses lp1
5190ovn-nbctl lsp-del lp1
5191ovn-nbctl ls-del ls1
5192
5193# wait for earlier changes to take effect
5194AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
5195
5196# ensure OF rules are no longer present. There used to be a bug here.
5197test_datapath_in_of_rules 0 "after lport+ls removal"
5198
5199OVN_CLEANUP([hv1])
5200
5201AT_CLEANUP
5202
f8a8db39 5203AT_SETUP([ovn -- nd_na ])
e75451fe
ZKL
5204AT_SKIP_IF([test $HAVE_PYTHON = no])
5205ovn_start
5206
5207#TODO: since patch port for IPv6 logical router port is not ready not,
5208# so we are not going to test vifs on different lswitches cases. Try
5209# to update for that once relevant stuff implemented.
5210
5211# In this test cases we create 1 lswitch, it has 2 VIF ports attached
5212# with. NS packet we test, from one VIF for another VIF, will be replied
5213# by local ovn-controller, but not by target VIF.
5214
5215# Create hypervisors and logical switch lsw0.
5216ovn-nbctl ls-add lsw0
5217net_add n1
5218sim_add hv1
5219as hv1
5220ovs-vsctl add-br br-phys
5221ovn_attach n1 br-phys 192.168.0.2
5222
5223# Add vif1 to hv1 and lsw0, turn on l2 port security on vif1.
5224ovs-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
5225ovn-nbctl lsp-add lsw0 lp1
5226ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5227ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:94:05:98 192.168.0.3 fd81:ce49:a948:0:f816:3eff:fe94:598"
5228
5229# Add vif2 to hv1 and lsw0, turn on l2 port security on vif2.
5230ovs-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
5231ovn-nbctl lsp-add lsw0 lp2
5232ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5233ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:a1:f9:ae 192.168.0.4 fd81:ce49:a948:0:f816:3eff:fea1:f9ae"
5234
5235# Add ACL rule for ICMPv6 on lsw0
5236ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
5237ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
5238ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
5239
5240# Allow some time for ovn-northd and ovn-controller to catch up.
5241# XXX This should be more systematic.
5242sleep 1
5243
5244# Given the name of a logical port, prints the name of the hypervisor
5245# on which it is located.
5246vif_to_hv() {
5247 echo hv1${1%?}
5248}
e75451fe
ZKL
5249for i in 1 2; do
5250 : > $i.expected
5251done
5252
5253# Complete Neighbor Solicitation packet and Neighbor Advertisement packet
5254# vif1 -> NS -> vif2. vif1 <- NA <- ovn-controller.
5255# vif2 will not receive NS packet, since ovn-controller will reply for it.
5256ns_packet=3333ffa1f9aefa163e94059886dd6000000000203afffd81ce49a9480000f8163efffe940598fd81ce49a9480000f8163efffea1f9ae8700e01160000000fd81ce49a9480000f8163efffea1f9ae0101fa163e940598
5257na_packet=fa163e940598fa163ea1f9ae86dd6000000000203afffd81ce49a9480000f8163efffea1f9aefd81ce49a9480000f8163efffe9405988800e9ed60000000fd81ce49a9480000f8163efffea1f9ae0201fa163ea1f9ae
5258
5259as hv1 ovs-appctl netdev-dummy/receive vif1 $ns_packet
e4543cfe 5260echo $na_packet >> 1.expected
e75451fe 5261
e75451fe
ZKL
5262echo "------ hv1 dump ------"
5263as hv1 ovs-vsctl show
5264as hv1 ovs-ofctl -O OpenFlow13 show br-int
5265as hv1 ovs-ofctl -O OpenFlow13 dump-flows br-int
5266
5267for i in 1 2; do
49d7c759 5268 OVN_CHECK_PACKETS([hv1/vif$i-tx.pcap], [$i.expected])
e75451fe
ZKL
5269done
5270
7a8f15e0 5271OVN_CLEANUP([hv1])
e75451fe
ZKL
5272
5273AT_CLEANUP
7417d147
RM
5274
5275AT_SETUP([ovn -- address sets modification/removal smoke test])
7417d147
RM
5276ovn_start
5277
5278net_add n1
5279
5280sim_add hv1
5281as hv1
5282ovs-vsctl add-br br-phys
5283ovn_attach n1 br-phys 192.168.0.1
5284
5285row=`ovn-nbctl create Address_Set name=set1 addresses=\"1.1.1.1\"`
5286ovn-nbctl set Address_Set $row name=set1 addresses=\"1.1.1.1,1.1.1.2\"
5287ovn-nbctl destroy Address_Set $row
5288
5289sleep 1
5290
5291# A bug previously existed in the address set support code
5292# that caused ovn-controller to crash after an address set
5293# was updated and then removed. This test case ensures
5294# that ovn-controller is at least still running after
5295# creating, updating, and deleting an address set.
5296AT_CHECK([ovs-appctl -t ovn-controller version], [0], [ignore])
5297
5298OVN_CLEANUP([hv1])
5299
5300AT_CLEANUP
8639f9be
ND
5301
5302AT_SETUP([ovn -- ipam])
8639f9be
ND
5303AT_SKIP_IF([test $HAVE_PYTHON = no])
5304ovn_start
5305
5306# Add a port to a switch that does not have a subnet set, then set the
5307# subnet which should result in an address being allocated for the port.
5308ovn-nbctl ls-add sw0
5309ovn-nbctl lsp-add sw0 p0 -- lsp-set-addresses p0 dynamic
fd3b31e9 5310ovn-nbctl --wait=sb add Logical-Switch sw0 other_config subnet=192.168.1.0/24
8639f9be
ND
5311AT_CHECK([ovn-nbctl get Logical-Switch-Port p0 dynamic_addresses], [0],
5312 ["0a:00:00:00:00:01 192.168.1.2"
5313])
5314
5315# Add 9 more ports to sw0, addresses should all be unique.
5316for n in `seq 1 9`; do
11547f85 5317 ovn-nbctl --wait=sb lsp-add sw0 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5318done
5319AT_CHECK([ovn-nbctl get Logical-Switch-Port p1 dynamic_addresses], [0],
5320 ["0a:00:00:00:00:02 192.168.1.3"
5321])
5322AT_CHECK([ovn-nbctl get Logical-Switch-Port p2 dynamic_addresses], [0],
5323 ["0a:00:00:00:00:03 192.168.1.4"
5324])
5325AT_CHECK([ovn-nbctl get Logical-Switch-Port p3 dynamic_addresses], [0],
5326 ["0a:00:00:00:00:04 192.168.1.5"
5327])
5328AT_CHECK([ovn-nbctl get Logical-Switch-Port p4 dynamic_addresses], [0],
5329 ["0a:00:00:00:00:05 192.168.1.6"
5330])
5331AT_CHECK([ovn-nbctl get Logical-Switch-Port p5 dynamic_addresses], [0],
5332 ["0a:00:00:00:00:06 192.168.1.7"
5333])
5334AT_CHECK([ovn-nbctl get Logical-Switch-Port p6 dynamic_addresses], [0],
5335 ["0a:00:00:00:00:07 192.168.1.8"
5336])
5337AT_CHECK([ovn-nbctl get Logical-Switch-Port p7 dynamic_addresses], [0],
5338 ["0a:00:00:00:00:08 192.168.1.9"
5339])
5340AT_CHECK([ovn-nbctl get Logical-Switch-Port p8 dynamic_addresses], [0],
5341 ["0a:00:00:00:00:09 192.168.1.10"
5342])
5343AT_CHECK([ovn-nbctl get Logical-Switch-Port p9 dynamic_addresses], [0],
5344 ["0a:00:00:00:00:0a 192.168.1.11"
5345])
5346
5347# Trying similar tests with a second switch. MAC addresses should be unique
5348# across both switches but IP's only need to be unique within the same switch.
5349ovn-nbctl ls-add sw1
5350ovn-nbctl lsp-add sw1 p10 -- lsp-set-addresses p10 dynamic
11547f85 5351ovn-nbctl --wait=sb add Logical-Switch sw1 other_config subnet=192.168.1.0/24
8639f9be
ND
5352AT_CHECK([ovn-nbctl get Logical-Switch-Port p10 dynamic_addresses], [0],
5353 ["0a:00:00:00:00:0b 192.168.1.2"
5354])
5355
5356for n in `seq 11 19`; do
11547f85 5357 ovn-nbctl --wait=sb lsp-add sw1 "p$n" -- lsp-set-addresses "p$n" dynamic
8639f9be
ND
5358done
5359AT_CHECK([ovn-nbctl get Logical-Switch-Port p11 dynamic_addresses], [0],
5360 ["0a:00:00:00:00:0c 192.168.1.3"
5361])
5362AT_CHECK([ovn-nbctl get Logical-Switch-Port p12 dynamic_addresses], [0],
5363 ["0a:00:00:00:00:0d 192.168.1.4"
5364])
5365AT_CHECK([ovn-nbctl get Logical-Switch-Port p13 dynamic_addresses], [0],
5366 ["0a:00:00:00:00:0e 192.168.1.5"
5367])
5368AT_CHECK([ovn-nbctl get Logical-Switch-Port p14 dynamic_addresses], [0],
5369 ["0a:00:00:00:00:0f 192.168.1.6"
5370])
5371AT_CHECK([ovn-nbctl get Logical-Switch-Port p15 dynamic_addresses], [0],
5372 ["0a:00:00:00:00:10 192.168.1.7"
5373])
5374AT_CHECK([ovn-nbctl get Logical-Switch-Port p16 dynamic_addresses], [0],
5375 ["0a:00:00:00:00:11 192.168.1.8"
5376])
5377AT_CHECK([ovn-nbctl get Logical-Switch-Port p17 dynamic_addresses], [0],
5378 ["0a:00:00:00:00:12 192.168.1.9"
5379])
5380AT_CHECK([ovn-nbctl get Logical-Switch-Port p18 dynamic_addresses], [0],
5381 ["0a:00:00:00:00:13 192.168.1.10"
5382])
5383AT_CHECK([ovn-nbctl get Logical-Switch-Port p19 dynamic_addresses], [0],
5384 ["0a:00:00:00:00:14 192.168.1.11"
5385])
5386
5387# Change a port's address to test for multiple ip's for a single address entry
5388# and addresses set by the user.
451624fe 5389ovn-nbctl lsp-set-addresses p0 "0a:00:00:00:00:15 192.168.1.2 192.168.1.12 192.168.1.14"
11547f85 5390ovn-nbctl --wait=sb lsp-add sw0 p20 -- lsp-set-addresses p20 dynamic
8639f9be
ND
5391AT_CHECK([ovn-nbctl get Logical-Switch-Port p20 dynamic_addresses], [0],
5392 ["0a:00:00:00:00:16 192.168.1.13"
5393])
5394
5395# Test for logical router port address management.
5396ovn-nbctl create Logical_Router name=R1
5397ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw0 \
5398network="192.168.1.1/24" mac=\"0a:00:00:00:00:17\" \
5399-- add Logical_Router R1 ports @lrp -- lsp-add sw0 rp-sw0 \
5400-- set Logical_Switch_Port rp-sw0 type=router options:router-port=sw0
11547f85 5401ovn-nbctl --wait=sb lsp-add sw0 p21 -- lsp-set-addresses p21 dynamic
8639f9be
ND
5402AT_CHECK([ovn-nbctl get Logical-Switch-Port p21 dynamic_addresses], [0],
5403 ["0a:00:00:00:00:18 192.168.1.15"
5404])
5405
5406# Test for address reuse after logical port is deleted.
5407ovn-nbctl lsp-del p0
11547f85 5408ovn-nbctl --wait=sb lsp-add sw0 p23 -- lsp-set-addresses p23 dynamic
8639f9be
ND
5409AT_CHECK([ovn-nbctl get Logical-Switch-Port p23 dynamic_addresses], [0],
5410 ["0a:00:00:00:00:19 192.168.1.2"
5411])
5412
5413# Test for multiple addresses to one logical port.
5414ovn-nbctl lsp-add sw0 p25 -- lsp-set-addresses p25 \
5415"0a:00:00:00:00:1a 192.168.1.12" "0a:00:00:00:00:1b 192.168.1.14"
11547f85 5416ovn-nbctl --wait=sb lsp-add sw0 p26 -- lsp-set-addresses p26 dynamic
8639f9be
ND
5417AT_CHECK([ovn-nbctl get Logical-Switch-Port p26 dynamic_addresses], [0],
5418 ["0a:00:00:00:00:1c 192.168.1.16"
5419])
5420
5421# Test for exhausting subnet address space.
5422ovn-nbctl ls-add sw2 -- add Logical-Switch sw2 other_config subnet=172.16.1.0/30
11547f85 5423ovn-nbctl --wait=sb lsp-add sw2 p27 -- lsp-set-addresses p27 dynamic
8639f9be
ND
5424AT_CHECK([ovn-nbctl get Logical-Switch-Port p27 dynamic_addresses], [0],
5425 ["0a:00:00:00:00:1d 172.16.1.2"
5426])
5427
11547f85 5428ovn-nbctl --wait=sb lsp-add sw2 p28 -- lsp-set-addresses p28 dynamic
8639f9be 5429AT_CHECK([ovn-nbctl get Logical-Switch-Port p28 dynamic_addresses], [0],
7cc0741e 5430 ["0a:00:00:00:00:1e"
8639f9be
ND
5431])
5432
5433# Test that address management does not add duplicate MAC for lsp/lrp peers.
5434ovn-nbctl create Logical_Router name=R2
5435ovn-nbctl ls-add sw3
5436ovn-nbctl lsp-add sw3 p29 -- lsp-set-addresses p29 \
7cc0741e 5437"0a:00:00:00:00:1f"
8639f9be
ND
5438ovn-nbctl -- --id=@lrp create Logical_Router_port name=sw3 \
5439network="192.168.2.1/24" mac=\"0a:00:00:00:00:1f\" \
5440-- add Logical_Router R2 ports @lrp -- lsp-add sw3 rp-sw3 \
5441-- set Logical_Switch_Port rp-sw3 type=router options:router-port=sw3
11547f85 5442ovn-nbctl --wait=sb lsp-add sw0 p30 -- lsp-set-addresses p30 dynamic
8639f9be
ND
5443AT_CHECK([ovn-nbctl get Logical-Switch-Port p30 dynamic_addresses], [0],
5444 ["0a:00:00:00:00:20 192.168.1.17"
5445])
5446
6374d518
LR
5447# Test static MAC address with dynamically allocated IP
5448ovn-nbctl --wait=sb lsp-add sw0 p31 -- lsp-set-addresses p31 \
5449"fe:dc:ba:98:76:54 dynamic"
5450AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5451 ["fe:dc:ba:98:76:54 192.168.1.18"
5452])
5453
6c4f7a8a
NS
5454# Update the static MAC address with dynamically allocated IP and check
5455# if the MAC address is updated in 'Logical_Switch_Port.dynamic_adddresses'
5456ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:55 dynamic"
6c4f7a8a
NS
5457
5458AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5459 ["fe:dc:ba:98:76:55 192.168.1.18"
5460])
5461
5462ovn-nbctl --wait=sb lsp-set-addresses p31 "dynamic"
5463AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
451624fe 5464 ["0a:00:00:00:00:21 192.168.1.18"
6c4f7a8a
NS
5465])
5466
5467ovn-nbctl --wait=sb lsp-set-addresses p31 "fe:dc:ba:98:76:56 dynamic"
5468AT_CHECK([ovn-nbctl get Logical-Switch-Port p31 dynamic_addresses], [0],
5469 ["fe:dc:ba:98:76:56 192.168.1.18"
5470])
5471
161ea2c8
NS
5472
5473# Test the exclude_ips from the IPAM list
5474ovn-nbctl --wait=sb set logical_switch sw0 \
5475other_config:exclude_ips="192.168.1.19 192.168.1.21 192.168.1.23..192.168.1.50"
5476
5477ovn-nbctl --wait=sb lsp-add sw0 p32 -- lsp-set-addresses p32 \
5478"dynamic"
5479# 192.168.1.20 should be assigned as 192.168.1.19 is excluded.
5480AT_CHECK([ovn-nbctl get Logical-Switch-Port p32 dynamic_addresses], [0],
451624fe 5481 ["0a:00:00:00:00:22 192.168.1.20"
161ea2c8
NS
5482])
5483
5484ovn-nbctl --wait=sb lsp-add sw0 p33 -- lsp-set-addresses p33 \
5485"dynamic"
5486# 192.168.1.22 should be assigned as 192.168.1.21 is excluded.
5487AT_CHECK([ovn-nbctl get Logical-Switch-Port p33 dynamic_addresses], [0],
451624fe 5488 ["0a:00:00:00:00:23 192.168.1.22"
161ea2c8
NS
5489])
5490
5491ovn-nbctl --wait=sb lsp-add sw0 p34 -- lsp-set-addresses p34 \
5492"dynamic"
5493# 192.168.1.51 should be assigned as 192.168.1.23-192.168.1.50 is excluded.
5494AT_CHECK([ovn-nbctl get Logical-Switch-Port p34 dynamic_addresses], [0],
451624fe 5495 ["0a:00:00:00:00:24 192.168.1.51"
161ea2c8
NS
5496])
5497
5498# Now clear the exclude_ips list. 192.168.1.19 should be assigned.
5499ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="invalid"
5500ovn-nbctl --wait=sb lsp-add sw0 p35 -- lsp-set-addresses p35 \
5501"dynamic"
5502AT_CHECK([ovn-nbctl get Logical-Switch-Port p35 dynamic_addresses], [0],
451624fe 5503 ["0a:00:00:00:00:25 192.168.1.19"
161ea2c8
NS
5504])
5505
5506# Set invalid data in exclude_ips list. It should be ignored.
5507ovn-nbctl --wait=sb set Logical-switch sw0 other_config:exclude_ips="182.168.1.30"
5508ovn-nbctl --wait=sb lsp-add sw0 p36 -- lsp-set-addresses p36 \
5509"dynamic"
5510# 192.168.1.21 should be assigned as that's the next free one.
5511AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
451624fe 5512 ["0a:00:00:00:00:26 192.168.1.21"
161ea2c8
NS
5513])
5514
5515# Clear the dynamic addresses assignment request.
5516ovn-nbctl --wait=sb clear logical_switch_port p36 addresses
5517AT_CHECK([ovn-nbctl get Logical-Switch-Port p36 dynamic_addresses], [0],
5518 [[[]]
5519])
5520
7cc0741e
NS
5521# Set IPv6 prefix
5522ovn-nbctl --wait=sb set Logical-switch sw0 other_config:ipv6_prefix="aef0::"
5523ovn-nbctl --wait=sb lsp-add sw0 p37 -- lsp-set-addresses p37 \
5524"dynamic"
5525
5526# With prefix aef0 and mac 0a:00:00:00:00:26, the dynamic IPv6 should be
5527# - aef0::800:ff:fe00:26 (EUI64)
5528AT_CHECK([ovn-nbctl get Logical-Switch-Port p37 dynamic_addresses], [0],
451624fe 5529 ["0a:00:00:00:00:27 192.168.1.21 aef0::800:ff:fe00:27"
7cc0741e
NS
5530])
5531
5532ovn-nbctl --wait=sb ls-add sw4
451624fe
MM
5533ovn-nbctl --wait=sb set Logical-switch sw4 other_config:ipv6_prefix="bef0::" \
5534-- set Logical-switch sw4 other_config:subnet=192.168.2.0/30
7cc0741e
NS
5535ovn-nbctl --wait=sb lsp-add sw4 p38 -- lsp-set-addresses p38 \
5536"dynamic"
5537
5538AT_CHECK([ovn-nbctl get Logical-Switch-Port p38 dynamic_addresses], [0],
451624fe 5539 ["0a:00:00:00:00:28 192.168.2.2 bef0::800:ff:fe00:28"
7cc0741e
NS
5540])
5541
5542ovn-nbctl --wait=sb lsp-add sw4 p39 -- lsp-set-addresses p39 \
5543"f0:00:00:00:10:12 dynamic"
5544
5545AT_CHECK([ovn-nbctl get Logical-Switch-Port p39 dynamic_addresses], [0],
5546 ["f0:00:00:00:10:12 bef0::f200:ff:fe00:1012"
5547])
5548
451624fe
MM
5549# Test the case where IPv4 addresses are exhausted and IPv6 prefix is set
5550# p40 should not have an IPv4 address since the pool is exhausted
7cc0741e
NS
5551ovn-nbctl --wait=sb lsp-add sw4 p40 -- lsp-set-addresses p40 \
5552"dynamic"
7cc0741e 5553AT_CHECK([ovn-nbctl get Logical-Switch-Port p40 dynamic_addresses], [0],
451624fe
MM
5554 ["0a:00:00:00:00:29 bef0::800:ff:fe00:29"
5555])
5556
5557# Test dynamic changes on switch ports.
5558#
5559ovn-nbctl --wait=sb ls-add sw5
5560ovn-nbctl --wait=sb lsp-add sw5 p41 -- lsp-set-addresses p41 \
5561"dynamic"
5562# p41 will start with nothing
5563AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
7cc0741e
NS
5564 [[[]]
5565])
5566
451624fe
MM
5567# Set a subnet. Now p41 should have an ipv4 address, too
5568ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5569AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5570 ["0a:00:00:00:00:2a 192.168.1.2"
5571])
7cc0741e 5572
451624fe
MM
5573# Clear the other_config. The IPv4 address should be gone
5574ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5575AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5576 [[[]]
7cc0741e
NS
5577])
5578
451624fe
MM
5579# Set an IPv6 prefix. Now p41 should have an IPv6 address.
5580ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="aef0::"
7cc0741e 5581AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
451624fe
MM
5582 ["0a:00:00:00:00:2b aef0::800:ff:fe00:2b"
5583])
5584
5585# Change the MAC address to a static one. The IPv6 address should update.
5586ovn-nbctl --wait=sb lsp-set-addresses p41 "f0:00:00:00:10:2b dynamic"
5587AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5588 ["f0:00:00:00:10:2b aef0::f200:ff:fe00:102b"
5589])
5590
5591# Change the IPv6 prefix. The IPv6 address should update.
5592ovn-nbctl --wait=sb set Logical-Switch sw5 other_config:ipv6_prefix="bef0::"
5593AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5594 ["f0:00:00:00:10:2b bef0::f200:ff:fe00:102b"
5595])
5596
5597# Clear the other_config. The IPv6 address should be gone
5598ovn-nbctl --wait=sb clear Logical-Switch sw5 other_config
5599AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5600 [[[]]
5601])
5602
5603# Set the subnet again. Now p41 should get the IPv4 address again.
5604ovn-nbctl --wait=sb add Logical-Switch sw5 other_config subnet=192.168.1.0/24
5605AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5606 ["f0:00:00:00:10:2b 192.168.1.2"
5607])
5608
5609# Add another port with a conflicting static IPv4 address. p41 should update.
5610ovn-nbctl --wait=sb lsp-add sw5 p42 -- lsp-set-addresses p42 \
5611"f0:00:00:00:10:2c 192.168.1.2"
5612AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5613 ["f0:00:00:00:10:2b 192.168.1.3"
5614])
5615
5616# Add an excluded IP address that conflicts with p41. p41 should update.
5617ovn-nbctl --wait=sb add Logical-Switch sw5 other_config \
5618exclude_ips="192.168.1.3"
5619AT_CHECK([ovn-nbctl get Logical-Switch-Port p41 dynamic_addresses], [0],
5620 ["f0:00:00:00:10:2b 192.168.1.4"
7cc0741e
NS
5621])
5622
8639f9be
ND
5623as ovn-sb
5624OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5625
5626as ovn-nb
5627OVS_APP_EXIT_AND_WAIT([ovsdb-server])
5628
5629as northd
5630OVS_APP_EXIT_AND_WAIT([ovn-northd])
5631
5632AT_CLEANUP
5633
5634AT_SETUP([ovn -- ipam connectivity])
8639f9be
ND
5635AT_SKIP_IF([test $HAVE_PYTHON = no])
5636ovn_start
5637
5638ovn-nbctl lr-add R1
5639
5640# Test for a ping using dynamically allocated addresses.
5641ovn-nbctl ls-add foo -- add Logical_Switch foo other_config subnet=192.168.1.0/24
5642ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2.0/24
5643
5644# Connect foo to R1
5645ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
5646ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
20418099
MS
5647 options:router-port=foo \
5648 -- lsp-set-addresses rp-foo router
8639f9be
ND
5649
5650# Connect alice to R1
5651ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24
5652ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice type=router \
5653 options:router-port=alice addresses=\"00:00:00:01:02:04\"
5654
5655# Create logical port foo1 in foo
fd3b31e9 5656ovn-nbctl --wait=sb lsp-add foo foo1 \
8639f9be 5657-- lsp-set-addresses foo1 "dynamic"
8bc2c143 5658AT_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
5659
5660# Create logical port alice1 in alice
fd3b31e9 5661ovn-nbctl --wait=sb lsp-add alice alice1 \
8639f9be 5662-- lsp-set-addresses alice1 "dynamic"
8bc2c143 5663AT_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
5664
5665# Create logical port foo2 in foo
fd3b31e9 5666ovn-nbctl --wait=sb lsp-add foo foo2 \
8639f9be 5667-- lsp-set-addresses foo2 "dynamic"
8bc2c143 5668AT_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
5669
5670# Create a hypervisor and create OVS ports corresponding to logical ports.
5671net_add n1
5672
5673sim_add hv1
5674as hv1
5675ovs-vsctl add-br br-phys
5676ovn_attach n1 br-phys 192.168.0.1
5677ovs-vsctl -- add-port br-int hv1-vif1 -- \
5678 set interface hv1-vif1 external-ids:iface-id=foo1 \
5679 options:tx_pcap=hv1/vif1-tx.pcap \
5680 options:rxq_pcap=hv1/vif1-rx.pcap \
5681 ofport-request=1
5682
5683ovs-vsctl -- add-port br-int hv1-vif2 -- \
5684 set interface hv1-vif2 external-ids:iface-id=foo2 \
5685 options:tx_pcap=hv1/vif2-tx.pcap \
5686 options:rxq_pcap=hv1/vif2-rx.pcap \
5687 ofport-request=2
5688
5689ovs-vsctl -- add-port br-int hv1-vif3 -- \
5690 set interface hv1-vif3 external-ids:iface-id=alice1 \
5691 options:tx_pcap=hv1/vif3-tx.pcap \
5692 options:rxq_pcap=hv1/vif3-rx.pcap \
5693 ofport-request=3
5694
5695# Allow some time for ovn-northd and ovn-controller to catch up.
5696# XXX This should be more systematic.
5697sleep 1
5698
5699ip_to_hex() {
5700 printf "%02x%02x%02x%02x" "$@"
5701}
8639f9be
ND
5702
5703# Send ip packets between foo1 and foo2
5704src_mac="0a0000000001"
5705dst_mac="0a0000000003"
5706src_ip=`ip_to_hex 192 168 1 2`
5707dst_ip=`ip_to_hex 192 168 1 3`
5708packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5709as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5710
5711# Send ip packets between foo1 and alice1
5712src_mac="0a0000000001"
5713dst_mac="000000010203"
5714src_ip=`ip_to_hex 192 168 1 2`
5715dst_ip=`ip_to_hex 192 168 2 2`
5716packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5717as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
5718
5719echo "---------NB dump-----"
5720ovn-nbctl show
5721echo "---------------------"
5722ovn-nbctl list logical_router
5723echo "---------------------"
5724ovn-nbctl list logical_router_port
5725echo "---------------------"
5726
5727echo "---------SB dump-----"
5728ovn-sbctl list datapath_binding
5729echo "---------------------"
5730ovn-sbctl list port_binding
5731echo "---------------------"
5732
5733echo "------ hv1 dump ----------"
5734as hv1 ovs-ofctl dump-flows br-int
5735
5736# Packet to Expect at foo2
5737src_mac="0a0000000001"
5738dst_mac="0a0000000003"
5739src_ip=`ip_to_hex 192 168 1 2`
5740dst_ip=`ip_to_hex 192 168 1 3`
5741expected=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5742
e4543cfe
DDP
5743$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > received1.packets
5744echo $expected > expout
8639f9be
ND
5745AT_CHECK([cat received1.packets], [0], [expout])
5746
5747# Packet to Expect at alice1
5748src_mac="000000010204"
5749dst_mac="0a0000000002"
5750src_ip=`ip_to_hex 192 168 1 2`
5751dst_ip=`ip_to_hex 192 168 2 2`
5752expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
5753
e4543cfe
DDP
5754$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > received2.packets
5755echo $expected > expout
8639f9be
ND
5756AT_CHECK([cat received2.packets], [0], [expout])
5757
5758OVN_CLEANUP([hv1])
5759
5760AT_CLEANUP
f5792c3f
NS
5761
5762AT_SETUP([ovn -- ovs-vswitchd restart])
1794d5f2 5763AT_KEYWORDS([vswitchd])
f5792c3f
NS
5764AT_SKIP_IF([test $HAVE_PYTHON = no])
5765ovn_start
5766
5767ovn-nbctl ls-add ls1
5768
5769ovn-nbctl lsp-add ls1 ls1-lp1 \
5770-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5771
5772ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
5773
5774net_add n1
5775sim_add hv1
5776
5777as hv1
5778ovs-vsctl add-br br-phys
5779ovn_attach n1 br-phys 192.168.0.1
5780ovs-vsctl -- add-port br-int hv1-vif1 -- \
5781 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
5782 options:tx_pcap=hv1/vif1-tx.pcap \
5783 options:rxq_pcap=hv1/vif1-rx.pcap \
5784 ofport-request=1
5785
74868f2c 5786OVN_POPULATE_ARP
f5792c3f
NS
5787sleep 2
5788
5789as hv1 ovs-vsctl show
5790
5791echo "---------------------"
5792ovn-sbctl dump-flows
5793echo "---------------------"
5794
5795echo "------ hv1 dump ----------"
5796as hv1 ovs-ofctl dump-flows br-int
5797total_flows=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5798
5799echo "Total flows before vswitchd restart = " $total_flows
5800
5801# Code taken from ovs-save utility
5802save_flows () {
5803 echo "ovs-ofctl add-flows br-int - << EOF" > restore_flows.sh
5804 as hv1 ovs-ofctl dump-flows "br-int" | sed -e '/NXST_FLOW/d' \
5805 -e 's/\(idle\|hard\)_age=[^,]*,//g' >> restore_flows.sh
5806 echo "EOF" >> restore_flows.sh
5807}
5808
5809restart_vswitchd () {
5810 restore_flows=$1
5811
5812 if test $restore_flows = true; then
5813 save_flows
5814 fi
5815
5816 as hv1
5817 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
5818
5819 if test $restore_flows = true; then
5820 as hv1
5821 ovs-vsctl --no-wait set open_vswitch . other_config:flow-restore-wait="true"
5822 fi
5823
5824 as hv1
5825 start_daemon ovs-vswitchd --enable-dummy=system -vvconn -vofproto_dpif -vunixctl
5826 ovs-ofctl dump-flows br-int
5827
5828 if test $restore_flows = true; then
5829 sh ./restore_flows.sh
5830 echo "Flows after restore"
5831 as hv1
5832 ovs-ofctl dump-flows br-int
5833 ovs-vsctl --no-wait --if-exists remove open_vswitch . other_config \
5834 flow-restore-wait="true"
5835 fi
5836}
5837
5838# Save the flows, restart vswitchd and restore the flows
5839restart_vswitchd true
5840OVS_WAIT_UNTIL([
5841 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5842 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5843 test "${total_flows}" = "${total_flows_after_restart}"
5844])
5845
5846# Restart vswitchd without restoring
5847restart_vswitchd false
5848OVS_WAIT_UNTIL([
5849 total_flows_after_restart=`as hv1 ovs-ofctl dump-flows br-int | wc -l`
5850 echo "Total flows after vswitchd restart = " $total_flows_after_restart
5851 test "${total_flows}" = "${total_flows_after_restart}"
5852])
5853
5854OVN_CLEANUP([hv1])
5855AT_CLEANUP
47021598
CSV
5856
5857AT_SETUP([ovn -- send arp for nexthop])
47021598
CSV
5858AT_SKIP_IF([test $HAVE_PYTHON = no])
5859ovn_start
5860
5861# Topology: Two LSs - ls1 and ls2 are connected via router r0
5862
5863# Create logical switches
5864ovn-nbctl ls-add ls1
5865ovn-nbctl ls-add ls2
5866
5867# Create router
5868ovn-nbctl create Logical_Router name=lr0
5869
5870# Add router ls1p1 port to gateway router
5871ovn-nbctl lrp-add lr0 lrp-ls1lp1 f0:00:00:00:00:01 192.168.0.1/24
5872ovn-nbctl lsp-add ls1 ls1lp1 -- set Logical_Switch_Port ls1lp1 \
5873 type=router options:router-port=lrp-ls1lp1 \
5874 addresses='"f0:00:00:00:00:01 192.168.0.1"'
5875
5876# Add router ls2p2 port to gateway router
5877ovn-nbctl lrp-add lr0 lrp-ls2lp1 f0:00:00:00:00:02 192.168.1.1/24
5878ovn-nbctl lsp-add ls2 ls2lp1 -- set Logical_Switch_Port ls2lp1 \
5879 type=router options:router-port=lrp-ls2lp1 \
5880 addresses='"f0:00:00:00:00:02 192.168.1.1"'
5881
5882# Set default gateway (nexthop) to 192.168.1.254
5883ovn-nbctl lr-route-add lr0 "0.0.0.0/0" 192.168.1.254 lrp-ls2lp1
5884
5885# Create logical port ls1lp2 in ls1
5886ovn-nbctl lsp-add ls1 ls1lp2 \
5887-- lsp-set-addresses ls1lp2 "f0:00:00:00:00:03 192.168.0.2"
5888
5889# Create logical port ls2lp2 in ls2
5890ovn-nbctl lsp-add ls2 ls2lp2 \
5891-- lsp-set-addresses ls2lp2 "f0:00:00:00:00:04 192.168.1.10"
5892
5893net_add n1
5894sim_add hv1
5895as hv1
5896ovs-vsctl add-br br-phys
5897ovn_attach n1 br-phys 192.168.0.1
5898ovs-vsctl -- add-port br-int hv1-ls1lp2 -- \
5899 set interface hv1-ls1lp2 external-ids:iface-id=ls1lp2 \
5900 options:tx_pcap=hv1/ls1lp2-tx.pcap \
5901 options:rxq_pcap=hv1/ls1lp2-rx.pcap \
5902 ofport-request=1
5903ovs-vsctl -- add-port br-int hv1-ls2lp2 -- \
5904 set interface hv1-ls2lp2 external-ids:iface-id=ls2lp2 \
5905 options:tx_pcap=hv1/ls2lp2-tx.pcap \
5906 options:rxq_pcap=hv1/ls2lp2-rx.pcap \
5907 ofport-request=2
5908
5909# Allow some time for ovn-northd and ovn-controller to catch up.
5910# XXX This should be more systematic.
5911sleep 1
5912
5913echo "---------NB dump-----"
5914ovn-nbctl show
5915echo "---------------------"
5916ovn-nbctl list logical_router
5917echo "---------------------"
5918ovn-nbctl list logical_router_port
5919echo "---------------------"
5920
5921echo "---------SB dump-----"
5922ovn-sbctl list datapath_binding
5923echo "---------------------"
5924ovn-sbctl list port_binding
5925echo "---------------------"
5926ovn-sbctl dump-flows
5927echo "---------------------"
5928ovn-sbctl list chassis
5929ovn-sbctl list encap
5930echo "---------------------"
5931
5932echo "------Flows dump-----"
5933as hv1
5934ovs-ofctl dump-flows
5935echo "---------------------"
5936
5937ip_to_hex() {
5938 printf "%02x%02x%02x%02x" "$@"
5939}
5940
5941src_mac="f00000000003"
5942dst_mac="f00000000001"
5943src_ip=`ip_to_hex 192 168 0 2`
5944dst_ip=`ip_to_hex 8 8 8 8`
5945packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
5946
5947# Send IP packet destined to 8.8.8.8 from lsp1lp2
5948as hv1 ovs-appctl netdev-dummy/receive hv1-ls1lp2 $packet
5949
5950trim_zeros() {
5951 sed 's/\(00\)\{1,\}$//'
5952}
5953
5954# ARP packet should be received with Target IP Address set to 192.168.1.254 and
5955# not 8.8.8.8
5956
5957$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/ls2lp2-tx.pcap | trim_zeros > packets
5958expected="fffffffffffff0000000000208060001080006040001f00000000002c0a80101000000000000c0a801fe"
5959echo $expected > expout
5960AT_CHECK([cat packets], [0], [expout])
5961cat packets
5962
5963OVN_CLEANUP([hv1])
5964
5965AT_CLEANUP
8439c2eb
CSV
5966
5967AT_SETUP([ovn -- send gratuitous arp for nat ips in localnet])
8439c2eb
CSV
5968AT_SKIP_IF([test $HAVE_PYTHON = no])
5969ovn_start
5970# Create logical switch
5971ovn-nbctl ls-add ls0
5972# Create gateway router
5973ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
5974# Add router port to gateway router
5975ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
5976ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 5977 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
8439c2eb
CSV
5978# Add nat-address option
5979ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="f0:00:00:00:00:01 192.168.0.2"
5980
5981net_add n1
5982sim_add hv1
5983as hv1
5984ovs-vsctl \
5985 -- add-br br-phys \
5986 -- add-br br-eth0
5987
5988ovn_attach n1 br-phys 192.168.0.1
5989
5990AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
5991AT_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])
5992
5993# Create a localnet port.
5994AT_CHECK([ovn-nbctl lsp-add ls0 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# Wait for packet to be received.
6001OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6002trim_zeros() {
6003 sed 's/\(00\)\{1,\}$//'
6004}
6005$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6006expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6007echo $expected > expout
6008AT_CHECK([sort packets], [0], [expout])
6009cat packets
6010
6011OVN_CLEANUP([hv1])
6012
6013AT_CLEANUP
6e31816f 6014
e914fb54
MS
6015AT_SETUP([ovn -- send gratuitous arp with nat-addresses router in localnet])
6016AT_SKIP_IF([test $HAVE_PYTHON = no])
6017ovn_start
6018# Create logical switch
6019ovn-nbctl ls-add ls0
6020# Create gateway router
6021ovn-nbctl create Logical_Router name=lr0 options:chassis=hv1
6022# Add router port to gateway router
6023ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24
6024ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
d223b67b 6025 type=router options:router-port=lrp0 addresses='"f0:00:00:00:00:01"'
e914fb54
MS
6026# Add nat-address option
6027ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
6028# Add NAT rules
6029AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
6030AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.1])
6031# Add load balancers
6032AT_CHECK([ovn-nbctl lb-add lb0 192.168.0.3:80 10.0.0.2:80,10.0.0.3:80])
6033AT_CHECK([ovn-nbctl lr-lb-add lr0 lb0])
6034AT_CHECK([ovn-nbctl lb-add lb1 192.168.0.3:8080 10.0.0.2:8080,10.0.0.3:8080])
6035AT_CHECK([ovn-nbctl lr-lb-add lr0 lb1])
6036
6037net_add n1
6038sim_add hv1
6039as hv1
6040ovs-vsctl \
6041 -- add-br br-phys \
6042 -- add-br br-eth0
6043
6044ovn_attach n1 br-phys 192.168.0.1
6045
6046AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6047AT_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])
6048
6049# Create a localnet port.
6050AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
6051AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6052AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6053AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6054
6055
6056# Wait for packet to be received.
6057OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 50])
6058trim_zeros() {
6059 sed 's/\(00\)\{1,\}$//'
6060}
6061$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
6062expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
6063echo $expected > expout
6064expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
6065echo $expected >> expout
6066expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80003000000000000c0a80003"
6067echo $expected >> expout
6068AT_CHECK([sort packets], [0], [expout])
6069cat packets
6070
6071OVN_CLEANUP([hv1])
6072
6073AT_CLEANUP
6074
6e31816f 6075AT_SETUP([ovn -- delete mac bindings])
6e31816f
CSV
6076ovn_start
6077net_add n1
6078sim_add hv1
6079as hv1
6080ovs-vsctl -- add-br br-phys
6081ovn_attach n1 br-phys 192.168.0.1
6082# Create logical switch ls0
6083ovn-nbctl ls-add ls0
6084# Create ports lp0, lp1 in ls0
6085ovn-nbctl lsp-add ls0 lp0
6086ovn-nbctl lsp-add ls0 lp1
6087ovn-nbctl lsp-set-addresses lp0 "f0:00:00:00:00:01 192.168.0.1"
6088ovn-nbctl lsp-set-addresses lp1 "f0:00:00:00:00:02 192.168.0.2"
6089dp_uuid=`ovn-sbctl find datapath | grep uuid | cut -f2 -d ":" | cut -f2 -d " "`
6090ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp0 mac="mac1"
6091ovn-sbctl create MAC_Binding ip=10.0.0.1 datapath=$dp_uuid logical_port=lp1 mac="mac2"
6092ovn-sbctl find MAC_Binding
093aa761 6093# Delete port lp0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6094ovn-nbctl lsp-del lp0
6095ovn-sbctl find MAC_Binding
093aa761
BP
6096OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding logical_port=lp0 | wc -l` = 0])
6097# Delete logical switch ls0 and check that its MAC_Binding is deleted.
6e31816f
CSV
6098ovn-nbctl ls-del ls0
6099ovn-sbctl find MAC_Binding
093aa761 6100OVS_WAIT_UNTIL([test `ovn-sbctl find MAC_Binding | wc -l` = 0])
6e31816f
CSV
6101
6102OVN_CLEANUP([hv1])
6103
6104AT_CLEANUP
926c34fd
RM
6105
6106AT_SETUP([ovn -- conntrack zone allocation])
926c34fd
RM
6107AT_SKIP_IF([test $HAVE_PYTHON = no])
6108ovn_start
6109
6110# Logical network:
6111# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24)
6112# connected to a router R1.
6113# foo has foo1 to act as a client.
6114# bar has bar1, bar2, bar3 to act as servers.
6115
6116net_add n1
6117
6118sim_add hv1
6119as hv1
6120ovs-vsctl add-br br-phys
6121ovn_attach n1 br-phys 192.168.0.1
6122for i in foo1 bar1 bar2 bar3; do
6123 ovs-vsctl -- add-port br-int $i -- \
6124 set interface $i external-ids:iface-id=$i \
6125 options:tx_pcap=hv1/$i-tx.pcap \
6126 options:rxq_pcap=hv1/$i-rx.pcap
6127done
6128
6129ovn-nbctl create Logical_Router name=R1
6130ovn-nbctl ls-add foo
6131ovn-nbctl ls-add bar
6132
6133# Connect foo to R1
6134ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
6135ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
6136 type=router options:router-port=foo addresses=\"00:00:01:01:02:03\"
6137
6138# Connect bar to R1
6139ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24
6140ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \
6141 type=router options:router-port=bar addresses=\"00:00:01:01:02:04\"
6142
6143# Create logical port foo1 in foo
6144ovn-nbctl lsp-add foo foo1 \
6145-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
6146
6147# Create logical port bar1, bar2 and bar3 in bar
6148for i in `seq 1 3`; do
6149 ip=`expr $i + 1`
6150 ovn-nbctl lsp-add bar bar$i \
6151 -- lsp-set-addresses bar$i "f0:00:0a:01:02:$i 172.16.1.$ip"
6152done
6153
6154OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=0 | grep REG13 | wc -l` -eq 4])
6155
6156OVN_CLEANUP([hv1])
6157
6158AT_CLEANUP
b511690b
GS
6159
6160AT_SETUP([ovn -- tag allocation])
b511690b
GS
6161ovn_start
6162
6163AT_CHECK([ovn-nbctl ls-add ls0])
6164AT_CHECK([ovn-nbctl lsp-add ls0 parent1])
6165AT_CHECK([ovn-nbctl lsp-add ls0 parent2])
6166AT_CHECK([ovn-nbctl ls-add ls1])
6167
6168dnl When a tag is provided, no allocation is done
6169AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c0 parent1 3])
6170AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6171])
6172dnl The same 'tag' gets created in southbound database.
6173AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6174logical_port="c0"], [0], [3
6175])
6176
6177dnl Allocate tags and see it getting created in both NB and SB
6178AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c1 parent1 0])
6179AT_CHECK([ovn-nbctl lsp-get-tag c1], [0], [1
6180])
6181AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6182logical_port="c1"], [0], [1
6183])
6184
6185AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c2 parent1 0])
6186AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6187])
6188AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6189logical_port="c2"], [0], [2
6190])
6191AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c3 parent1 0])
6192AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6193])
6194AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6195logical_port="c3"], [0], [4
6196])
6197
6198dnl A different parent.
6199AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c4 parent2 0])
6200AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6201])
6202AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6203logical_port="c4"], [0], [1
6204])
6205
6206AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c5 parent2 0])
6207AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6208])
6209AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6210logical_port="c5"], [0], [2
6211])
6212
6213dnl Delete a logical port and create a new one.
6214AT_CHECK([ovn-nbctl --wait=sb lsp-del c1])
6215AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c6 parent1 0])
6216AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6217])
6218AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6219logical_port="c6"], [0], [1
6220])
6221
6222dnl Restart northd to see that the same allocation remains.
6223as northd
6224OVS_APP_EXIT_AND_WAIT([ovn-northd])
6225start_daemon ovn-northd \
6226 --ovnnb-db=unix:"$ovs_base"/ovn-nb/ovn-nb.sock \
6227 --ovnsb-db=unix:"$ovs_base"/ovn-sb/ovn-sb.sock
6228
6229dnl Create a switch to make sure that ovn-northd has run through the main loop.
6230AT_CHECK([ovn-nbctl --wait=sb ls-add ls-dummy])
6231AT_CHECK([ovn-nbctl lsp-get-tag c0], [0], [3
6232])
6233AT_CHECK([ovn-nbctl lsp-get-tag c6], [0], [1
6234])
6235AT_CHECK([ovn-nbctl lsp-get-tag c2], [0], [2
6236])
6237AT_CHECK([ovn-nbctl lsp-get-tag c3], [0], [4
6238])
6239AT_CHECK([ovn-nbctl lsp-get-tag c4], [0], [1
6240])
6241AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6242])
6243
6244dnl Create a switch port with a tag that has already been allocated.
6245dnl It should go through fine with a duplicate tag.
6246AT_CHECK([ovn-nbctl --wait=sb lsp-add ls1 c7 parent2 2])
6247AT_CHECK([ovn-nbctl lsp-get-tag c7], [0], [2
6248])
6249AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6250logical_port="c7"], [0], [2
6251])
6252AT_CHECK([ovn-nbctl lsp-get-tag c5], [0], [2
6253])
6254
6255AT_CHECK([ovn-nbctl ls-add ls2])
6256dnl When there is no parent_name provided (for say, 'localnet'), 'tag_request'
6257dnl gets copied to 'tag'
6258AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local0 "" 25])
6259AT_CHECK([ovn-nbctl lsp-get-tag local0], [0], [25
6260])
6261dnl The same 'tag' gets created in southbound database.
6262AT_CHECK([ovn-sbctl --data=bare --no-heading --columns=tag find port_binding \
6263logical_port="local0"], [0], [25
6264])
6265dnl If 'tag_request' is 0 for localnet, nothing gets written to 'tag'
6266AT_CHECK([ovn-nbctl --wait=sb lsp-add ls2 local1 "" 0])
6267AT_CHECK([ovn-nbctl lsp-get-tag local1])
6268dnl change the tag_request.
6269AT_CHECK([ovn-nbctl --wait=sb set logical_switch_port local1 tag_request=50])
6270AT_CHECK([ovn-nbctl lsp-get-tag local1], [0], [50
6271])
6272
6273AT_CLEANUP
57afd0c0
RR
6274
6275AT_SETUP([ovn -- lsp deletion and broadcast-flow deletion on localnet])
57afd0c0
RR
6276ovn_start
6277ovn-nbctl ls-add lsw0
6278net_add n1
6279for i in 1 2; do
6280 sim_add hv$i
6281 as hv$i
6282 ovs-vsctl add-br br-phys
6283 ovn_attach n1 br-phys 192.168.0.$i
6284 ovs-vsctl add-br br-eth0
6285 AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-eth0])
6286done
6287
6288# Create a localnet port.
6289AT_CHECK([ovn-nbctl lsp-add lsw0 ln_port])
6290AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
6291AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
6292AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
6293
6294
6295# Create 3 vifs.
6296AT_CHECK([ovn-nbctl lsp-add lsw0 localvif1])
6297AT_CHECK([ovn-nbctl lsp-set-addresses localvif1 "f0:00:00:00:00:01 192.168.1.1"])
6298AT_CHECK([ovn-nbctl lsp-set-port-security localvif1 "f0:00:00:00:00:01"])
6299AT_CHECK([ovn-nbctl lsp-add lsw0 localvif2])
6300AT_CHECK([ovn-nbctl lsp-set-addresses localvif2 "f0:00:00:00:00:01 192.168.1.2"])
6301AT_CHECK([ovn-nbctl lsp-set-port-security localvif2 "f0:00:00:00:00:02"])
6302AT_CHECK([ovn-nbctl lsp-add lsw0 localvif3])
6303AT_CHECK([ovn-nbctl lsp-set-addresses localvif3 "f0:00:00:00:00:03 192.168.1.3"])
6304AT_CHECK([ovn-nbctl lsp-set-port-security localvif3 "f0:00:00:00:00:03"])
6305
6306# Bind the localvif1 to hv1.
6307as hv1
6308AT_CHECK([ovs-vsctl add-port br-int localvif1 -- set Interface localvif1 external_ids:iface-id=localvif1])
6309
6310# On hv1, check that there are no flows outputting bcast to tunnel
6311OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6312
1ea9b847 6313# On hv2, check that no flow outputs bcast to tunnel to hv1.
57afd0c0 6314as hv2
1ea9b847 6315OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
57afd0c0
RR
6316
6317# Now bind vif2 on hv2.
6318AT_CHECK([ovs-vsctl add-port br-int localvif2 -- set Interface localvif2 external_ids:iface-id=localvif2])
6319
6320# At this point, the broadcast flow on vif2 should be deleted.
6321# because, there is now a localnet vif bound (table=32 programming logic)
6322OVS_WAIT_UNTIL([test `ovs-ofctl dump-flows br-int table=32 | ofctl_strip | grep output | wc -l` -eq 0])
6323
6324# Verify that the local net patch port exists on hv2.
6325OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6326
6327# Now bind vif3 on hv2.
6328AT_CHECK([ovs-vsctl add-port br-int localvif3 -- set Interface localvif3 external_ids:iface-id=localvif3])
6329
6330# Verify that the local net patch port still exists on hv2
6331OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6332
6333# Delete localvif2
6334AT_CHECK([ovn-nbctl lsp-del localvif2])
6335
6336# Verify that the local net patch port still exists on hv2,
6337# because, localvif3 is still bound.
6338OVS_WAIT_UNTIL([test `ovs-vsctl show | grep "Port patch-br-int-to-ln_port" | wc -l` -eq 1])
6339
57afd0c0 6340OVN_CLEANUP([hv1],[hv2])
1a03fc7d
BS
6341
6342AT_CLEANUP
6343
d383eed5
JP
6344
6345AT_SETUP([ovn -- ACL logging])
6346AT_KEYWORDS([ovn])
6347ovn_start
6348
6349net_add n1
6350
6351sim_add hv
6352as hv
6353ovs-vsctl add-br br-phys
6354ovn_attach n1 br-phys 192.168.0.1
6355for i in lp1 lp2; do
6356 ovs-vsctl -- add-port br-int $i -- \
6357 set interface $i external-ids:iface-id=$i \
6358 options:tx_pcap=hv/$i-tx.pcap \
6359 options:rxq_pcap=hv/$i-rx.pcap
6360done
6361
6362lp1_mac="f0:00:00:00:00:01"
6363lp1_ip="192.168.1.2"
6364
6365lp2_mac="f0:00:00:00:00:02"
6366lp2_ip="192.168.1.3"
6367
6368ovn-nbctl ls-add lsw0
6369ovn-nbctl --wait=sb lsp-add lsw0 lp1
6370ovn-nbctl --wait=sb lsp-add lsw0 lp2
6371ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6372ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6373ovn-nbctl --wait=sb sync
6374
6375ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6376ovn-nbctl --log --severity=alert --name=drop-flow acl-add lsw0 to-lport 1000 'tcp.dst==81' drop
6377
6378ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==82' allow
6379ovn-nbctl --log --severity=info --name=allow-flow acl-add lsw0 to-lport 1000 'tcp.dst==83' allow
6380
6381ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==84' allow-related
6382ovn-nbctl --log acl-add lsw0 to-lport 1000 'tcp.dst==85' allow-related
6383
6384ovn-nbctl acl-add lsw0 to-lport 1000 'tcp.dst==86' reject
6385ovn-nbctl --log --severity=alert --name=reject-flow acl-add lsw0 to-lport 1000 'tcp.dst==87' reject
6386
6387ovn-sbctl dump-flows
6388
6389
6390# Send packet that should be dropped without logging.
6391packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6392 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6393 tcp && tcp.flags==2 && tcp.src==4360 && tcp.dst==80"
6394as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6395
6396# Send packet that should be dropped with logging.
6397packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6398 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6399 tcp && tcp.flags==2 && tcp.src==4361 && tcp.dst==81"
6400as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6401
6402# Send packet that should be allowed without logging.
6403packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6404 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6405 tcp && tcp.flags==2 && tcp.src==4362 && tcp.dst==82"
6406as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6407
6408# Send packet that should be allowed with logging.
6409packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6410 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6411 tcp && tcp.flags==2 && tcp.src==4363 && tcp.dst==83"
6412as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6413
6414# Send packet that should allow related flows without logging.
6415packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6416 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6417 tcp && tcp.flags==2 && tcp.src==4364 && tcp.dst==84"
6418as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6419
6420# Send packet that should allow related flows with logging.
6421packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6422 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6423 tcp && tcp.flags==2 && tcp.src==4365 && tcp.dst==85"
6424as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6425
df48cfc7 6426# Send packet that should be rejected without logging.
d383eed5
JP
6427packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6428 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6429 tcp && tcp.flags==2 && tcp.src==4366 && tcp.dst==86"
6430as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6431
df48cfc7 6432# Send packet that should be rejected with logging.
d383eed5
JP
6433packet="inport==\"lp1\" && eth.src==$lp1_mac && eth.dst==$lp2_mac &&
6434 ip4 && ip.ttl==64 && ip4.src==$lp1_ip && ip4.dst==$lp2_ip &&
6435 tcp && tcp.flags==2 && tcp.src==4367 && tcp.dst==87"
6436as hv ovs-appctl -t ovn-controller inject-pkt "$packet"
6437
c1f272f9
NS
6438OVS_WAIT_UNTIL([ test 4 = $(grep -c 'acl_log' hv/ovn-controller.log) ])
6439
d383eed5
JP
6440AT_CHECK([grep 'acl_log' hv/ovn-controller.log | sed 's/.*name=/name=/'], [0], [dnl
6441name="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
6442name="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
6443name="<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
6444name="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
6445])
6446
6447OVN_CLEANUP([hv])
6448AT_CLEANUP
6449
6450
23749245
JP
6451AT_SETUP([ovn -- ACL rate-limited logging])
6452AT_KEYWORDS([ovn])
6453ovn_start
6454
6455net_add n1
6456
6457sim_add hv
6458as hv
6459ovs-vsctl add-br br-phys
6460ovn_attach n1 br-phys 192.168.0.1
6461for i in lp1 lp2; do
6462 ovs-vsctl -- add-port br-int $i -- \
6463 set interface $i external-ids:iface-id=$i \
6464 options:tx_pcap=hv/$i-tx.pcap \
6465 options:rxq_pcap=hv/$i-rx.pcap
6466done
6467
6468lp1_mac="f0:00:00:00:00:01"
6469lp1_ip="192.168.1.2"
6470
6471lp2_mac="f0:00:00:00:00:02"
6472lp2_ip="192.168.1.3"
6473
6474ovn-nbctl ls-add lsw0
6475ovn-nbctl --wait=sb lsp-add lsw0 lp1
6476ovn-nbctl --wait=sb lsp-add lsw0 lp2
6477ovn-nbctl lsp-set-addresses lp1 $lp1_mac
6478ovn-nbctl lsp-set-addresses lp2 $lp2_mac
6479ovn-nbctl --wait=sb sync
6480
6481
6482# Add an ACL that rate-limits logs at 10 per second.
6483ovn-nbctl meter-add http-rl1 drop 10 pktps
6484ovn-nbctl --log --severity=alert --meter=http-rl1 --name=http-acl1 acl-add lsw0 to-lport 1000 'tcp.dst==80' drop
6485
6486# Add an ACL that rate-limits logs at 5 per second.
6487ovn-nbctl meter-add http-rl2 drop 5 pktps
6488ovn-nbctl --log --severity=alert --meter=http-rl2 --name=http-acl2 acl-add lsw0 to-lport 1000 'tcp.dst==81' allow
6489
6490# Add an ACL that doesn't rate-limit logs.
6491ovn-nbctl --log --severity=alert --name=http-acl3 acl-add lsw0 to-lport 1000 'tcp.dst==82' drop
6492
6493
6494# For each ACL, send 100 packets.
6495for i in `seq 1 100`; do
6496 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)'
6497
6498 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)'
6499
6500 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)'
6501done
6502
6503# Print some information that may help debugging.
6504as hv ovs-appctl -t ovn-controller meter-table-list
6505as hv ovs-ofctl -O OpenFlow13 meter-stats br-int
6506
6507# The userspace meter implementation doesn't precisely enforce counts,
6508# so we just check that exactly 100 "http-acl3" actions were logged and
6509# that there were more "http-acl1" actions than "http-acl2" ones.
6510OVS_WAIT_UNTIL([ test 100 = $(grep -c 'http-acl3' hv/ovn-controller.log) ])
6511
6512n_acl1=$(grep -c 'http-acl1' hv/ovn-controller.log)
6513n_acl2=$(grep -c 'http-acl2' hv/ovn-controller.log)
6514n_acl3=$(grep -c 'http-acl3' hv/ovn-controller.log)
6515
6516AT_CHECK([ test $n_acl3 -gt $n_acl1 ], [0], [])
6517AT_CHECK([ test $n_acl1 -gt $n_acl2 ], [0], [])
6518
6519
6520OVN_CLEANUP([hv])
6521AT_CLEANUP
6522
6523
66d89287 6524AT_SETUP([ovn -- DSCP marking and meter check])
1a03fc7d
BS
6525AT_KEYWORDS([ovn])
6526ovn_start
6527
6528ovn-nbctl ls-add lsw0
6529ovn-nbctl --wait=sb lsp-add lsw0 lp1
6530ovn-nbctl --wait=sb lsp-add lsw0 lp2
e50ed58a 6531ovn-nbctl --wait=sb lsp-add lsw0 lp3
1a03fc7d
BS
6532ovn-nbctl lsp-set-addresses lp1 f0:00:00:00:00:01
6533ovn-nbctl lsp-set-addresses lp2 f0:00:00:00:00:02
e50ed58a 6534ovn-nbctl lsp-set-addresses lp3 f0:00:00:00:00:03
1a03fc7d
BS
6535ovn-nbctl lsp-set-port-security lp1 f0:00:00:00:00:01
6536ovn-nbctl lsp-set-port-security lp2 f0:00:00:00:00:02
6537ovn-nbctl --wait=sb sync
6538net_add n1
6539sim_add hv
6540as hv
6541ovs-vsctl add-br br-phys
6542ovn_attach n1 br-phys 192.168.0.1
6543ovs-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
6544ovs-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
6545
6546AT_CAPTURE_FILE([trace])
6547ovn_trace () {
6548 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
6549}
6550
6551# Extracts nw_tos from the final flow from ofproto/trace output and prints
6552# it on stdout. Prints "none" if no nw_tos was included.
6553get_final_nw_tos() {
6554 if flow=$(grep '^Final flow:' stdout); then :; else
6555 # The output didn't have a final flow.
6556 return 99
6557 fi
6558
6559 tos=$(echo "$flow" | sed -n 's/.*nw_tos=\([[0-9]]\{1,\}\).*/\1/p')
6560 case $tos in
6561 '') echo none ;;
5a0e4aec 6562 *) echo $tos ;;
1a03fc7d
BS
6563 esac
6564}
6565
6566# check_tos TOS
6567#
6568# Checks that a packet from 1.1.1.1 to 1.1.1.2 gets its DSCP set to TOS.
6569check_tos() {
6570 # First check with ovn-trace for logical flows.
6571 echo "checking for tos $1"
6572 (if test $1 != 0; then echo "ip.dscp = $1;"; fi;
6573 echo 'output("lp2");') > expout
6574 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])
6575
6576 # Then re-check with ofproto/trace for a physical packet.
6577 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])
6578 AT_CHECK_UNQUOTED([get_final_nw_tos], [0], [`expr $1 \* 4`
6579])
6580}
6581
6582# check at L2
6583AT_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");
6584])
6585AT_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])
6586AT_CHECK([get_final_nw_tos], [0], [none
6587])
6588
6589# check at L3 without dscp marking
6590check_tos 0
6591
6592# Mark DSCP with a valid value
e50ed58a 6593qos_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
6594AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6595])
1a03fc7d
BS
6596check_tos 48
6597
66d89287
GL
6598# check at hv without qos meter
6599AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6600])
6601
6602# Update the meter rate
6603ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=100
6604
6605# check at hv with a qos meter table
6606AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=100 | wc -l], [0], [1
6607])
6608AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6609])
6610
1a03fc7d
BS
6611# Update the DSCP marking
6612ovn-nbctl --wait=hv set QoS $qos_id action=dscp=63
6613check_tos 63
6614
66d89287
GL
6615# Update the meter rate
6616ovn-nbctl --wait=hv set QoS $qos_id bandwidth=rate=4294967295,burst=4294967295
6617
6618# check at hv with a qos meter table
6619AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep burst_size=4294967295 | wc -l], [0], [1
6620])
6621AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [1
6622])
6623
1a03fc7d
BS
6624ovn-nbctl --wait=hv set QoS $qos_id match="outport\=\=\"lp2\"" direction="to-lport"
6625check_tos 63
6626
6627# Disable DSCP marking
5ee33cbd
GL
6628ovn-nbctl --wait=hv qos-del lsw0
6629AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [0
6630])
1a03fc7d
BS
6631check_tos 0
6632
66d89287
GL
6633# check at hv without qos meter
6634AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6635])
6636
e50ed58a
GL
6637# check meter with chassis not resident
6638ovn-nbctl qos-add lsw0 to-lport 1001 'inport=="lp3" && is_chassis_resident("lp3")' rate=11123 burst=111230
6639AT_CHECK([as hv ovn-nbctl qos-list lsw0 | wc -l], [0], [1
6640])
6641
6642# check no meter table
6643AT_CHECK([as hv ovs-ofctl dump-flows br-int -O OpenFlow13 | grep meter | wc -l], [0], [0
6644])
6645AT_CHECK([as hv ovs-ofctl dump-meters br-int -O OpenFlow13 | grep rate=11123 | wc -l], [0], [0
6646])
6647
1a03fc7d 6648OVN_CLEANUP([hv])
57afd0c0 6649AT_CLEANUP
7fff4eb7
LR
6650
6651AT_SETUP([ovn -- read-only sb db:ptcp access])
6652AT_SKIP_IF([test $HAVE_PYTHON = no])
6653
6654: > .$1.db.~lock~
6655ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6656
6657# Add read-only remote to sb ovsdb-server
6658AT_CHECK(
6659 [ovsdb-tool transact ovn-sb.db \
6660 ['["OVN_Southbound",
6661 {"op": "insert",
6662 "table": "SB_Global",
6663 "row": {
6664 "connections": ["set", [["named-uuid", "xyz"]]]}},
6665 {"op": "insert",
6666 "table": "Connection",
6667 "uuid-name": "xyz",
6668 "row": {"target": "ptcp:0:127.0.0.1",
6669 "read_only": true}}]']], [0], [ignore], [ignore])
6670
6671start_daemon ovsdb-server --remote=punix:ovn-sb.sock --remote=db:OVN_Southbound,SB_Global,connections ovn-sb.db
6672
6673PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6674
6675# read-only accesses should succeed
6676AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list SB_Global], [0], [stdout], [ignore])
6677AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT list Connection], [0], [stdout], [ignore])
6678
6679# write access should fail
6680AT_CHECK([ovn-sbctl --db=tcp:127.0.0.1:$TCP_PORT chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6681[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6682])
6683
6684OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6685AT_CLEANUP
6686
6687AT_SETUP([ovn -- read-only sb db:pssl access])
6688AT_SKIP_IF([test $HAVE_PYTHON = no])
6689AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6690PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6691AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6692\\]"])
6693
6694: > .$1.db.~lock~
6695ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6696
6697# Add read-only remote to sb ovsdb-server
6698AT_CHECK(
6699 [ovsdb-tool transact ovn-sb.db \
6700 ['["OVN_Southbound",
6701 {"op": "insert",
6702 "table": "SB_Global",
6703 "row": {
6704 "connections": ["set", [["named-uuid", "xyz"]]]}},
6705 {"op": "insert",
6706 "table": "Connection",
6707 "uuid-name": "xyz",
6708 "row": {"target": "pssl:0:127.0.0.1",
6709 "read_only": true}}]']], [0], [ignore], [ignore])
6710
6711start_daemon ovsdb-server --remote=punix:ovn-sb.sock \
6712 --remote=db:OVN_Southbound,SB_Global,connections \
6713 --private-key="$PKIDIR/testpki-privkey2.pem" \
6714 --certificate="$PKIDIR/testpki-cert2.pem" \
6715 --ca-cert="$PKIDIR/testpki-cacert.pem" \
6716 ovn-sb.db
6717
6718PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6719
6720# read-only accesses should succeed
6721AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6722 --private-key=$PKIDIR/testpki-privkey.pem \
6723 --certificate=$PKIDIR/testpki-cert.pem \
6724 --ca-cert=$PKIDIR/testpki-cacert.pem \
6725 list SB_Global], [0], [stdout], [ignore])
6726AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6727 --private-key=$PKIDIR/testpki-privkey.pem \
6728 --certificate=$PKIDIR/testpki-cert.pem \
6729 --ca-cert=$PKIDIR/testpki-cacert.pem \
6730 list Connection], [0], [stdout], [ignore])
6731
6732# write access should fail
6733AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6734 --private-key=$PKIDIR/testpki-privkey.pem \
6735 --certificate=$PKIDIR/testpki-cert.pem \
6736 --ca-cert=$PKIDIR/testpki-cacert.pem \
6737 chassis-add ch vxlan 1.2.4.8], [1], [ignore],
6738[ovn-sbctl: transaction error: {"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}
6739])
6740
6741OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6742AT_CLEANUP
6743
821302cf
LR
6744AT_SETUP([ovn -- nb connection/ssl commands])
6745AT_SKIP_IF([test $HAVE_PYTHON = no])
6746AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6747PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6748AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6749\\]"])
6750
6751: > .$1.db.~lock~
6752ovsdb-tool create ovn-nb.db "$abs_top_srcdir"/ovn/ovn-nb.ovsschema
6753
6754# Start nb db server using db connection/ssl entries (unpopulated initially)
6755start_daemon ovsdb-server --remote=punix:ovnnb_db.sock \
6756 --remote=db:OVN_Northbound,NB_Global,connections \
6757 --private-key=db:OVN_Northbound,SSL,private_key \
6758 --certificate=db:OVN_Northbound,SSL,certificate \
6759 --ca-cert=db:OVN_Northbound,SSL,ca_cert \
6760 ovn-nb.db
6761
6762# Populate SSL configuration entries in nb db
6763AT_CHECK(
6764 [ovn-nbctl set-ssl $PKIDIR/testpki-privkey.pem \
6765 $PKIDIR/testpki-cert.pem \
6766 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6767
6768# Populate a passive SSL connection in nb db
6769AT_CHECK([ovn-nbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6770
6771PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6772
6773# Verify SSL connetivity to nb db server
6774AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6775 --private-key=$PKIDIR/testpki-privkey.pem \
6776 --certificate=$PKIDIR/testpki-cert.pem \
6777 --ca-cert=$PKIDIR/testpki-cacert.pem \
6778 list NB_Global],
6779 [0], [stdout], [ignore])
6780AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6781 --private-key=$PKIDIR/testpki-privkey.pem \
6782 --certificate=$PKIDIR/testpki-cert.pem \
6783 --ca-cert=$PKIDIR/testpki-cacert.pem \
6784 list Connection],
6785 [0], [stdout], [ignore])
6786AT_CHECK([ovn-nbctl --db=ssl:127.0.0.1:$TCP_PORT \
6787 --private-key=$PKIDIR/testpki-privkey.pem \
10471820
LR
6788 --certificate=$PKIDIR/testpki-cert.pem \
6789 --ca-cert=$PKIDIR/testpki-cacert.pem \
6790 get-connection],
6791 [0], [stdout], [ignore])
6792
6793OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6794AT_CLEANUP
6795
6796AT_SETUP([ovn -- sb connection/ssl commands])
6797AT_SKIP_IF([test $HAVE_PYTHON = no])
6798AT_SKIP_IF([test "$HAVE_OPENSSL" = no])
6799PKIDIR="$(cd $abs_top_builddir/tests && pwd)"
6800AT_SKIP_IF([expr "$PKIDIR" : ".*[ '\"
6801\\]"])
6802
6803: > .$1.db.~lock~
6804ovsdb-tool create ovn-sb.db "$abs_top_srcdir"/ovn/ovn-sb.ovsschema
6805
6806# Start sb db server using db connection/ssl entries (unpopulated initially)
6807start_daemon ovsdb-server --remote=punix:ovnsb_db.sock \
6808 --remote=db:OVN_Southbound,SB_Global,connections \
6809 --private-key=db:OVN_Southbound,SSL,private_key \
6810 --certificate=db:OVN_Southbound,SSL,certificate \
6811 --ca-cert=db:OVN_Southbound,SSL,ca_cert \
6812 ovn-sb.db
6813
6814# Populate SSL configuration entries in sb db
6815AT_CHECK(
6816 [ovn-sbctl set-ssl $PKIDIR/testpki-privkey.pem \
6817 $PKIDIR/testpki-cert.pem \
6818 $PKIDIR/testpki-cacert.pem], [0], [stdout], [ignore])
6819
6820# Populate a passive SSL connection in sb db
6821AT_CHECK([ovn-sbctl set-connection pssl:0:127.0.0.1], [0], [stdout], [ignore])
6822
6823PARSE_LISTENING_PORT([ovsdb-server.log], [TCP_PORT])
6824
6825# Verify SSL connetivity to sb db server
6826AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6827 --private-key=$PKIDIR/testpki-privkey.pem \
6828 --certificate=$PKIDIR/testpki-cert.pem \
6829 --ca-cert=$PKIDIR/testpki-cacert.pem \
6830 list SB_Global],
6831 [0], [stdout], [ignore])
6832AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6833 --private-key=$PKIDIR/testpki-privkey.pem \
6834 --certificate=$PKIDIR/testpki-cert.pem \
6835 --ca-cert=$PKIDIR/testpki-cacert.pem \
6836 list Connection],
6837 [0], [stdout], [ignore])
6838AT_CHECK([ovn-sbctl --db=ssl:127.0.0.1:$TCP_PORT \
6839 --private-key=$PKIDIR/testpki-privkey.pem \
821302cf
LR
6840 --certificate=$PKIDIR/testpki-cert.pem \
6841 --ca-cert=$PKIDIR/testpki-cacert.pem \
6842 get-connection],
6843 [0], [stdout], [ignore])
6844
6845OVS_APP_EXIT_AND_WAIT([ovsdb-server])
6846AT_CLEANUP
6847
75fd74f8
GS
6848AT_SETUP([ovn -- nested containers])
6849ovn_start
6850
6851# Physical network:
6852# 2 HVs. HV1 has 2 VMs - "VM1" and "bar3". HV2 has 1 VM - "VM2"
6853
6854# Logical network:
6855# 3 Logical switches - "mgmt" (172.16.1.0/24), "foo" (192.168.1.0/24)
6856# and "bar" (192.168.2.0/24). They are all connected to router R1.
6857
6858ovn-nbctl lr-add R1
6859ovn-nbctl ls-add mgmt
6860ovn-nbctl ls-add foo
6861ovn-nbctl ls-add bar
6862
6863# Connect mgmt to R1
6864ovn-nbctl lrp-add R1 mgmt 00:00:00:01:02:02 172.16.1.1/24
6865ovn-nbctl lsp-add mgmt rp-mgmt -- set Logical_Switch_Port rp-mgmt type=router \
6866 options:router-port=mgmt addresses=\"00:00:00:01:02:02\"
6867
6868# Connect foo to R1
6869ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
6870ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
6871 options:router-port=foo addresses=\"00:00:00:01:02:03\"
6872
6873# Connect bar to R1
6874ovn-nbctl lrp-add R1 bar 00:00:00:01:02:04 192.168.2.1/24
6875ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
6876 options:router-port=bar addresses=\"00:00:00:01:02:04\"
6877
6878# "mgmt" has VM1 and VM2 connected
6879ovn-nbctl lsp-add mgmt vm1 \
6880-- lsp-set-addresses vm1 "f0:00:00:01:02:03 172.16.1.2"
6881
6882ovn-nbctl lsp-add mgmt vm2 \
6883-- lsp-set-addresses vm2 "f0:00:00:01:02:04 172.16.1.3"
6884
6885# "foo1" and "foo2" are containers belonging to switch "foo"
6886# "foo1" has "VM1" as parent_port and "foo2" has "VM2" as parent_port.
6887ovn-nbctl lsp-add foo foo1 vm1 1 \
6888-- lsp-set-addresses foo1 "f0:00:00:01:02:05 192.168.1.2"
6889
6890ovn-nbctl lsp-add foo foo2 vm2 2 \
6891-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
6892
6893# "bar1" and "bar2" are containers belonging to switch "bar"
6894# "bar1" has "VM1" as parent_port and "bar2" has "VM2" as parent_port.
6895ovn-nbctl lsp-add bar bar1 vm1 2 \
6896-- lsp-set-addresses bar1 "f0:00:00:01:02:07 192.168.2.2"
6897
6898ovn-nbctl lsp-add bar bar2 vm2 1 \
6899-- lsp-set-addresses bar2 "f0:00:00:01:02:08 192.168.2.3"
6900
6901# bar3 is a standalone VM belonging to switch "bar"
6902ovn-nbctl lsp-add bar bar3 \
6903-- lsp-set-addresses bar3 "f0:00:00:01:02:09 192.168.2.4"
6904
6905# Create two hypervisor and create OVS ports corresponding to logical ports.
6906net_add n1
6907
6908sim_add hv1
6909as hv1
6910ovs-vsctl add-br br-phys
6911ovn_attach n1 br-phys 192.168.0.1
6912ovs-vsctl -- add-port br-int vm1 -- \
6913 set interface vm1 external-ids:iface-id=vm1 \
6914 options:tx_pcap=hv1/vm1-tx.pcap \
6915 options:rxq_pcap=hv1/vm1-rx.pcap \
6916 ofport-request=1
6917
6918ovs-vsctl -- add-port br-int bar3 -- \
6919 set interface bar3 external-ids:iface-id=bar3 \
6920 options:tx_pcap=hv1/bar3-tx.pcap \
6921 options:rxq_pcap=hv1/bar3-rx.pcap \
6922 ofport-request=2
6923
6924sim_add hv2
6925as hv2
6926ovs-vsctl add-br br-phys
6927ovn_attach n1 br-phys 192.168.0.2
6928ovs-vsctl -- add-port br-int vm2 -- \
6929 set interface vm2 external-ids:iface-id=vm2 \
6930 options:tx_pcap=hv2/vm2-tx.pcap \
6931 options:rxq_pcap=hv2/vm2-rx.pcap \
6932 ofport-request=1
6933
6934# Pre-populate the hypervisors' ARP tables so that we don't lose any
6935# packets for ARP resolution (native tunneling doesn't queue packets
6936# for ARP resolution).
74868f2c 6937OVN_POPULATE_ARP
75fd74f8
GS
6938
6939# Allow some time for ovn-northd and ovn-controller to catch up.
6940# XXX This should be more systematic.
6941sleep 1
6942
6943ip_to_hex() {
6944 printf "%02x%02x%02x%02x" "$@"
6945}
6946
6947# Send ip packets between foo1 and foo2 (same switch, different HVs and
6948# different VLAN tags).
6949src_mac="f00000010205"
6950dst_mac="f00000010206"
6951src_ip=`ip_to_hex 192 168 1 2`
6952dst_ip=`ip_to_hex 192 168 1 3`
6953packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6954as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6955
6956# expected packet at foo2
6957packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6958echo $packet > expected
6959OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6960
6961# Send ip packets between foo1 and bar2 (different switch, different HV)
6962src_mac="f00000010205"
6963dst_mac="000000010203"
6964src_ip=`ip_to_hex 192 168 1 2`
6965dst_ip=`ip_to_hex 192 168 2 3`
6966packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6967as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6968
6969# expected packet at bar2
6970src_mac="000000010204"
6971dst_mac="f00000010208"
6972packet=${dst_mac}${src_mac}8100000108004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6973echo $packet >> expected
6974OVN_CHECK_PACKETS([hv2/vm2-tx.pcap], [expected])
6975
6976# Send ip packets between foo1 and bar1
6977# (different switch, loopback to same vm but different tag)
6978src_mac="f00000010205"
6979dst_mac="000000010203"
6980src_ip=`ip_to_hex 192 168 1 2`
6981dst_ip=`ip_to_hex 192 168 2 2`
6982packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6983as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
6984
6985# expected packet at bar1
6986src_mac="000000010204"
6987dst_mac="f00000010207"
6988packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
6989echo $packet > expected1
6990OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
6991
6992# Send ip packets between bar1 and bar3
6993# (same switch. But one is container and another is a standalone VM)
6994src_mac="f00000010207"
6995dst_mac="f00000010209"
6996src_ip=`ip_to_hex 192 168 2 2`
6997dst_ip=`ip_to_hex 192 168 2 3`
6998packet=${dst_mac}${src_mac}8100000208004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
6999as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7000
7001# expected packet at bar3
7002packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7003echo $packet > expected
7004OVN_CHECK_PACKETS([hv1/bar3-tx.pcap], [expected])
7005
7006# Send ip packets between foo1 and vm1.
7007(different switch, container to the VM hosting it.)
7008src_mac="f00000010205"
7009dst_mac="000000010203"
7010src_ip=`ip_to_hex 192 168 1 2`
7011dst_ip=`ip_to_hex 172 16 1 2`
7012packet=${dst_mac}${src_mac}8100000108004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7013as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7014
7015# expected packet at vm1
7016src_mac="000000010202"
7017dst_mac="f00000010203"
7018packet=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7019echo $packet >> expected1
7020OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7021
7022# Send packets from vm1 to bar1.
7023(different switch, A hosting VM to a container inside it)
7024src_mac="f00000010203"
7025dst_mac="000000010202"
7026src_ip=`ip_to_hex 172 16 1 2`
7027dst_ip=`ip_to_hex 192 168 2 2`
7028packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7029as hv1 ovs-appctl netdev-dummy/receive vm1 $packet
7030
7031# expected packet at vm1
7032src_mac="000000010204"
7033dst_mac="f00000010207"
7034packet=${dst_mac}${src_mac}8100000208004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7035echo $packet >> expected1
7036OVN_CHECK_PACKETS([hv1/vm1-tx.pcap], [expected1])
7037
7038OVN_CLEANUP([hv1],[hv2])
7039
7040AT_CLEANUP
440a9f4b
GS
7041
7042AT_SETUP([ovn -- 3 HVs, 3 LRs connected via LS, source IP based routes])
7043AT_SKIP_IF([test $HAVE_PYTHON = no])
7044ovn_start
7045
7046# Logical network:
7047# Three LRs - R1, R2 and R3 that are connected to each other via LS "join"
7048# in 20.0.0.0/24 network. R1 has switchess foo (192.168.1.0/24) and bar
7049# (192.168.2.0/24) connected to it.
7050#
7051# R2 and R3 are gateway routers.
7052# R2 has alice (172.16.1.0/24) and R3 has bob (172.16.1.0/24)
7053# connected to it. Note how both alice and bob have the same subnet behind it.
7054# We are trying to simulate external network via those 2 switches. In real
7055# world the switch ports of these switches will have addresses set as "unknown"
7056# to make them learning switches. Or those switches will be "localnet" ones.
7057
7058# Create three hypervisors and create OVS ports corresponding to logical ports.
7059net_add n1
7060
7061sim_add hv1
7062as hv1
7063ovs-vsctl add-br br-phys
7064ovn_attach n1 br-phys 192.168.0.1
7065ovs-vsctl -- add-port br-int hv1-vif1 -- \
7066 set interface hv1-vif1 external-ids:iface-id=foo1 \
7067 options:tx_pcap=hv1/vif1-tx.pcap \
7068 options:rxq_pcap=hv1/vif1-rx.pcap \
7069 ofport-request=1
7070
7071ovs-vsctl -- add-port br-int hv1-vif2 -- \
7072 set interface hv1-vif2 external-ids:iface-id=bar1 \
7073 options:tx_pcap=hv1/vif2-tx.pcap \
7074 options:rxq_pcap=hv1/vif2-rx.pcap \
7075 ofport-request=2
7076
7077sim_add hv2
7078as hv2
7079ovs-vsctl add-br br-phys
7080ovn_attach n1 br-phys 192.168.0.2
7081ovs-vsctl -- add-port br-int hv2-vif1 -- \
7082 set interface hv2-vif1 external-ids:iface-id=alice1 \
7083 options:tx_pcap=hv2/vif1-tx.pcap \
7084 options:rxq_pcap=hv2/vif1-rx.pcap \
7085 ofport-request=1
7086
7087sim_add hv3
7088as hv3
7089ovs-vsctl add-br br-phys
7090ovn_attach n1 br-phys 192.168.0.3
7091ovs-vsctl -- add-port br-int hv3-vif1 -- \
7092 set interface hv3-vif1 external-ids:iface-id=bob1 \
7093 options:tx_pcap=hv3/vif1-tx.pcap \
7094 options:rxq_pcap=hv3/vif1-rx.pcap \
7095 ofport-request=1
7096
7097
7098ovn-nbctl create Logical_Router name=R1
7099ovn-nbctl create Logical_Router name=R2 options:chassis="hv2"
7100ovn-nbctl create Logical_Router name=R3 options:chassis="hv3"
7101
7102ovn-nbctl ls-add foo
7103ovn-nbctl ls-add bar
7104ovn-nbctl ls-add alice
7105ovn-nbctl ls-add bob
7106ovn-nbctl ls-add join
7107
7108# Connect foo to R1
7109ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7110ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
7111 options:router-port=foo addresses=\"00:00:01:01:02:03\"
7112
7113# Connect bar to R1
7114ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 192.168.2.1/24
7115ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar type=router \
7116 options:router-port=bar addresses=\"00:00:01:01:02:04\"
7117
7118# Connect alice to R2
7119ovn-nbctl lrp-add R2 alice 00:00:02:01:02:03 172.16.1.1/24
7120ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7121 type=router options:router-port=alice addresses=\"00:00:02:01:02:03\"
7122
7123# Connect bob to R3
7124ovn-nbctl lrp-add R3 bob 00:00:03:01:02:03 172.16.1.2/24
7125ovn-nbctl lsp-add bob rp-bob -- set Logical_Switch_Port rp-bob \
7126 type=router options:router-port=bob addresses=\"00:00:03:01:02:03\"
7127
7128# Connect R1 to join
7129ovn-nbctl lrp-add R1 R1_join 00:00:04:01:02:03 20.0.0.1/24
7130ovn-nbctl lsp-add join r1-join -- set Logical_Switch_Port r1-join \
7131 type=router options:router-port=R1_join addresses='"00:00:04:01:02:03"'
7132
7133# Connect R2 to join
7134ovn-nbctl lrp-add R2 R2_join 00:00:04:01:02:04 20.0.0.2/24
7135ovn-nbctl lsp-add join r2-join -- set Logical_Switch_Port r2-join \
7136 type=router options:router-port=R2_join addresses='"00:00:04:01:02:04"'
7137
7138# Connect R3 to join
7139ovn-nbctl lrp-add R3 R3_join 00:00:04:01:02:05 20.0.0.3/24
7140ovn-nbctl lsp-add join r3-join -- set Logical_Switch_Port r3-join \
7141 type=router options:router-port=R3_join addresses='"00:00:04:01:02:05"'
7142
7143# Install static routes with source ip address as the policy for routing.
7144# We want traffic from 'foo' to go via R2 and traffic of 'bar' to go via R3.
7145ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.1.0/24 20.0.0.2
7146ovn-nbctl --policy="src-ip" lr-route-add R1 192.168.2.0/24 20.0.0.3
7147
7148# Install static routes with destination ip address as the policy for routing.
7149ovn-nbctl lr-route-add R2 192.168.0.0/16 20.0.0.1
7150
7151ovn-nbctl lr-route-add R3 192.168.0.0/16 20.0.0.1
7152
7153# Create logical port foo1 in foo
7154ovn-nbctl lsp-add foo foo1 \
7155-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7156
7157# Create logical port bar1 in bar
7158ovn-nbctl lsp-add bar bar1 \
7159-- lsp-set-addresses bar1 "f0:00:00:01:02:04 192.168.2.2"
7160
7161# Create logical port alice1 in alice
7162ovn-nbctl lsp-add alice alice1 \
7163-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.3"
7164
7165# Create logical port bob1 in bob
7166ovn-nbctl lsp-add bob bob1 \
7167-- lsp-set-addresses bob1 "f0:00:00:01:02:06 172.16.1.4"
7168
7169# Pre-populate the hypervisors' ARP tables so that we don't lose any
7170# packets for ARP resolution (native tunneling doesn't queue packets
7171# for ARP resolution).
74868f2c 7172OVN_POPULATE_ARP
440a9f4b
GS
7173
7174# Allow some time for ovn-northd and ovn-controller to catch up.
7175# XXX This should be more systematic.
7176sleep 1
7177
7178ip_to_hex() {
7179 printf "%02x%02x%02x%02x" "$@"
7180}
7181trim_zeros() {
7182 sed 's/\(00\)\{1,\}$//'
7183}
7184
7185# Send ip packets between foo1 and bar1
7186# (East-west traffic should flow normally)
7187src_mac="f00000010203"
7188dst_mac="000001010203"
7189src_ip=`ip_to_hex 192 168 1 2`
7190dst_ip=`ip_to_hex 192 168 2 2`
7191packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7192as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7193
7194# Send ip packets between foo1 and alice1
7195src_mac="f00000010203"
7196dst_mac="000001010203"
7197src_ip=`ip_to_hex 192 168 1 2`
7198dst_ip=`ip_to_hex 172 16 1 3`
7199packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7200as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
2d9b49dd 7201as hv1 ovs-appctl ofproto/trace br-int in_port=1 $packet
440a9f4b
GS
7202
7203# Send ip packets between bar1 and bob1
7204src_mac="f00000010204"
7205dst_mac="000001010204"
7206src_ip=`ip_to_hex 192 168 2 2`
7207dst_ip=`ip_to_hex 172 16 1 4`
7208packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7209as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
7210#as hv1 ovs-appctl ofproto/trace br-int in_port=2 $packet
7211
7212# Packet to expect at bar1
7213src_mac="000001010204"
7214dst_mac="f00000010204"
7215src_ip=`ip_to_hex 192 168 1 2`
7216dst_ip=`ip_to_hex 192 168 2 2`
7217expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7218echo $expected > expected
7219OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
7220
7221# Packet to Expect at alice1
7222src_mac="000002010203"
7223dst_mac="f00000010205"
7224src_ip=`ip_to_hex 192 168 1 2`
7225dst_ip=`ip_to_hex 172 16 1 3`
7226expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7227echo $expected > expected
7228OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
7229
7230# Packet to Expect at bob1
7231src_mac="000003010203"
7232dst_mac="f00000010206"
7233src_ip=`ip_to_hex 192 168 2 2`
7234dst_ip=`ip_to_hex 172 16 1 4`
7235expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
7236echo $expected > expected
7237OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [expected])
7238
7239for sim in hv1 hv2 hv3; do
7240 as $sim
7241 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7242 OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7243 OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7244done
7245
7246as ovn-sb
7247OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7248
7249as ovn-nb
7250OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7251
7252as northd
7253OVS_APP_EXIT_AND_WAIT([ovn-northd])
7254
7255as main
7256OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7257OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7258
7259AT_CLEANUP
41a15b71 7260
302eda27
NS
7261AT_SETUP([ovn -- dns lookup : 1 HV, 2 LS, 2 LSPs/LS])
7262AT_SKIP_IF([test $HAVE_PYTHON = no])
7263ovn_start
7264
7265ovn-nbctl ls-add ls1
7266
7267ovn-nbctl lsp-add ls1 ls1-lp1 \
7268-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7269
7270ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4 aef0::4"
7271
7272ovn-nbctl lsp-add ls1 ls1-lp2 \
7273-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7274
7275ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6 20.0.0.4"
7276
7277DNS1=`ovn-nbctl create DNS records={}`
7278DNS2=`ovn-nbctl create DNS records={}`
7279
7280ovn-nbctl set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
7281ovn-nbctl set DNS $DNS1 records:vm2.ovn.org="10.0.0.6 20.0.0.4"
7282ovn-nbctl set DNS $DNS2 records:vm3.ovn.org="40.0.0.4"
7283
7284ovn-nbctl set Logical_switch ls1 dns_records="$DNS1"
7285
7286net_add n1
7287sim_add hv1
7288
7289as hv1
7290ovs-vsctl add-br br-phys
7291ovn_attach n1 br-phys 192.168.0.1
7292ovs-vsctl -- add-port br-int hv1-vif1 -- \
7293 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
7294 options:tx_pcap=hv1/vif1-tx.pcap \
7295 options:rxq_pcap=hv1/vif1-rx.pcap \
7296 ofport-request=1
7297
7298ovs-vsctl -- add-port br-int hv1-vif2 -- \
7299 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
7300 options:tx_pcap=hv1/vif2-tx.pcap \
7301 options:rxq_pcap=hv1/vif2-rx.pcap \
7302 ofport-request=2
7303
74868f2c 7304OVN_POPULATE_ARP
302eda27
NS
7305sleep 2
7306as hv1 ovs-vsctl show
7307
7308echo "*************************"
7309ovn-sbctl list DNS
7310echo "*************************"
7311
7312ip_to_hex() {
7313 printf "%02x%02x%02x%02x" "$@"
7314}
7315
7316reset_pcap_file() {
7317 local iface=$1
7318 local pcap_file=$2
7319 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7320options:rxq_pcap=dummy-rx.pcap
7321 rm -f ${pcap_file}*.pcap
7322 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7323options:rxq_pcap=${pcap_file}-rx.pcap
7324}
7325
7326# set_dns_params host_name
7327# Sets the dns_req_data and dns_resp_data
7328set_dns_params() {
7329 local hname=$1
7330 local ttl=00000e10
7331 an_count=0001
7332 type=0001
7333 case $hname in
7334 vm1)
7335 # vm1.ovn.org
7336 query_name=03766d31036f766e036f726700
7337 # IPv4 address - 10.0.0.4
7338 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7339 ;;
7340 vm2)
7341 # vm2.ovn.org
7342 query_name=03766d32036f766e036f726700
7343 # IPv4 address - 10.0.0.6
7344 expected_dns_answer=${query_name}00010001${ttl}00040a000006
7345 # IPv4 address - 20.0.0.4
7346 expected_dns_answer=${expected_dns_answer}${query_name}00010001${ttl}000414000004
7347 an_count=0002
7348 ;;
7349 vm3)
7350 # vm3.ovn.org
7351 query_name=03766d33036f766e036f726700
7352 # IPv4 address - 40.0.0.4
7353 expected_dns_answer=${query_name}00010001${ttl}000428000004
7354 ;;
7355 vm1_ipv6_only)
7356 # vm1.ovn.org
7357 query_name=03766d31036f766e036f726700
7358 # IPv6 address - aef0::4
7359 type=001c
7360 expected_dns_answer=${query_name}${type}0001${ttl}0010aef00000000000000000000000000004
7361 ;;
7362 vm1_ipv4_v6)
7363 # vm1.ovn.org
7364 query_name=03766d31036f766e036f726700
7365 type=00ff
7366 an_count=0002
7367 # IPv4 address - 10.0.0.4
7368 # IPv6 address - aef0::4
7369 expected_dns_answer=${query_name}00010001${ttl}00040a000004
7370 expected_dns_answer=${expected_dns_answer}${query_name}001c0001${ttl}0010
7371 expected_dns_answer=${expected_dns_answer}aef00000000000000000000000000004
7372 ;;
7373 vm1_invalid_type)
7374 # vm1.ovn.org
7375 query_name=03766d31036f766e036f726700
7376 # IPv6 address - aef0::4
7377 type=0002
7378 ;;
7379 vm1_incomplete)
7380 # set type to none
7381 type=''
7382 esac
7383 # TTL - 3600
7384 local dns_req_header=010201200001000000000000
7385 local dns_resp_header=010281200001${an_count}00000000
7386 dns_req_data=${dns_req_header}${query_name}${type}0001
7387 dns_resp_data=${dns_resp_header}${query_name}${type}0001${expected_dns_answer}
7388}
7389
7390# This shell function sends a DNS request packet
7391# test_dns INPORT SRC_MAC DST_MAC SRC_IP DST_IP DNS_QUERY EXPEC
7392test_dns() {
7393 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7394 local dns_query_data=$7
7395 shift; shift; shift; shift; shift; shift; shift;
7396 # Packet size => IPv4 header (20) + UDP header (8) +
7397 # DNS data (header + query)
7398 ip_len=`expr 28 + ${#dns_query_data} / 2`
7399 udp_len=`expr $ip_len - 20`
7400 ip_len=$(printf "%x" $ip_len)
7401 udp_len=$(printf "%x" $udp_len)
7402 local request=${dst_mac}${src_mac}0800450000${ip_len}0000000080110000
7403 request=${request}${src_ip}${dst_ip}9234003500${udp_len}0000
7404 # dns data
7405 request=${request}${dns_query_data}
7406
7407 if test $dns_reply != 0; then
7408 local dns_reply=$1
7409 ip_len=`expr 28 + ${#dns_reply} / 2`
7410 udp_len=`expr $ip_len - 20`
7411 ip_len=$(printf "%x" $ip_len)
7412 udp_len=$(printf "%x" $udp_len)
7413 local reply=${src_mac}${dst_mac}0800450000${ip_len}0000000080110000
7414 reply=${reply}${dst_ip}${src_ip}0035923400${udp_len}0000${dns_reply}
7415 echo $reply >> $inport.expected
7416 else
7417 for outport; do
7418 echo $request >> $outport.expected
7419 done
7420 fi
7421 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7422}
7423
f8e79d82
MM
7424test_dns6() {
7425 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 dns_reply=$6
7426 local dns_query_data=$7
7427 shift; shift; shift; shift; shift; shift; shift;
7428 # Packet size => UDP header (8) +
7429 # DNS data (header + query)
7430 ip_len=`expr 8 + ${#dns_query_data} / 2`
7431 udp_len=$ip_len
7432 ip_len=$(printf "%x" $ip_len)
7433 udp_len=$(printf "%x" $udp_len)
7434 local request=${dst_mac}${src_mac}86dd6000000000${ip_len}11ff${src_ip}${dst_ip}
7435 request=${request}9234003500${udp_len}0000
7436 #dns data
7437 request=${request}${dns_query_data}
7438
7439 if test $dns_reply != 0; then
7440 local dns_reply=$1
7441 ip_len=`expr 8 + ${#dns_reply} / 2`
7442 udp_len=$ip_len
7443 ip_len=$(printf "%x" $ip_len)
7444 udp_len=$(printf "%x" $udp_len)
7445 local reply=${src_mac}${dst_mac}86dd6000000000${ip_len}11ff${dst_ip}${src_ip}
7446 reply=${reply}0035923400${udp_len}0000${dns_reply}
7447 echo $reply >> $inport.expected
7448 else
7449 for outport; do
7450 echo $request >> $outport.expected
7451 done
7452 fi
7453 as hv1 ovs-appctl netdev-dummy/receive hv1-vif$inport $request
7454}
7455
302eda27
NS
7456AT_CAPTURE_FILE([ofctl_monitor0.log])
7457as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
7458--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
7459
7460set_dns_params vm2
7461src_ip=`ip_to_hex 10 0 0 4`
7462dst_ip=`ip_to_hex 10 0 0 1`
7463dns_reply=1
7464test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7465
7466# NXT_RESUMEs should be 1.
7467OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7468
7469$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7470cat 1.expected | cut -c -48 > expout
7471AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7472# Skipping the IPv4 checksum.
7473cat 1.expected | cut -c 53- > expout
7474AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7475
7476reset_pcap_file hv1-vif1 hv1/vif1
7477reset_pcap_file hv1-vif2 hv1/vif2
7478rm -f 1.expected
7479rm -f 2.expected
7480
7481set_dns_params vm1
7482src_ip=`ip_to_hex 10 0 0 6`
7483dst_ip=`ip_to_hex 10 0 0 1`
7484dns_reply=1
7485test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7486
7487# NXT_RESUMEs should be 2.
7488OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7489
7490$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7491cat 2.expected | cut -c -48 > expout
7492AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7493# Skipping the IPv4 checksum.
7494cat 2.expected | cut -c 53- > expout
7495AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7496
7497reset_pcap_file hv1-vif1 hv1/vif1
7498reset_pcap_file hv1-vif2 hv1/vif2
7499rm -f 1.expected
7500rm -f 2.expected
7501
7502# Clear the query name options for ls1-lp2
7503ovn-nbctl --wait=hv remove DNS $DNS1 records vm2.ovn.org
7504
7505set_dns_params vm2
7506src_ip=`ip_to_hex 10 0 0 4`
7507dst_ip=`ip_to_hex 10 0 0 1`
7508dns_reply=0
7509test_dns 1 f00000000001 f00000000002 $src_ip $dst_ip $dns_reply $dns_req_data
7510
7511# NXT_RESUMEs should be 3.
7512OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7513
7514$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7515AT_CHECK([cat 1.packets], [0], [])
7516
7517reset_pcap_file hv1-vif1 hv1/vif1
7518reset_pcap_file hv1-vif2 hv1/vif2
7519rm -f 1.expected
7520rm -f 2.expected
7521
7522# Clear the query name for ls1-lp1
7523# Since ls1 has no query names configued,
7524# ovn-northd should not add the DNS flows.
7525ovn-nbctl --wait=hv remove DNS $DNS1 records vm1.ovn.org
7526
7527set_dns_params vm1
7528src_ip=`ip_to_hex 10 0 0 6`
7529dst_ip=`ip_to_hex 10 0 0 1`
7530dns_reply=0
7531test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7532
7533# NXT_RESUMEs should be 3 only.
7534OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7535
7536$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7537AT_CHECK([cat 2.packets], [0], [])
7538
7539reset_pcap_file hv1-vif1 hv1/vif1
7540reset_pcap_file hv1-vif2 hv1/vif2
7541rm -f 1.expected
7542rm -f 2.expected
7543
7544# Test IPv6 (AAAA records) using IPv4 packet.
7545# Add back the DNS options for ls1-lp1.
4f4ac4bb 7546ovn-nbctl --wait=hv set DNS $DNS1 records:vm1.ovn.org="10.0.0.4 aef0::4"
302eda27
NS
7547
7548set_dns_params vm1_ipv6_only
7549src_ip=`ip_to_hex 10 0 0 6`
7550dst_ip=`ip_to_hex 10 0 0 1`
7551dns_reply=1
7552test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7553
7554# NXT_RESUMEs should be 4.
7555OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7556
7557$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7558cat 2.expected | cut -c -48 > expout
7559AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7560# Skipping the IPv4 checksum.
7561cat 2.expected | cut -c 53- > expout
7562AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7563
7564reset_pcap_file hv1-vif1 hv1/vif1
7565reset_pcap_file hv1-vif2 hv1/vif2
7566rm -f 1.expected
7567rm -f 2.expected
7568
7569# Test both IPv4 (A) and IPv6 (AAAA records) using IPv4 packet.
7570set_dns_params vm1_ipv4_v6
7571src_ip=`ip_to_hex 10 0 0 6`
7572dst_ip=`ip_to_hex 10 0 0 1`
7573dns_reply=1
7574test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7575
7576# NXT_RESUMEs should be 5.
7577OVS_WAIT_UNTIL([test 5 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7578
7579$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7580cat 2.expected | cut -c -48 > expout
7581AT_CHECK([cat 2.packets | cut -c -48], [0], [expout])
7582# Skipping the IPv4 checksum.
7583cat 2.expected | cut -c 53- > expout
7584AT_CHECK([cat 2.packets | cut -c 53-], [0], [expout])
7585
7586reset_pcap_file hv1-vif1 hv1/vif1
7587reset_pcap_file hv1-vif2 hv1/vif2
7588rm -f 1.expected
7589rm -f 2.expected
7590
7591# Invalid type.
7592set_dns_params vm1_invalid_type
7593src_ip=`ip_to_hex 10 0 0 6`
7594dst_ip=`ip_to_hex 10 0 0 1`
7595dns_reply=0
7596test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7597
7598# NXT_RESUMEs should be 6.
7599OVS_WAIT_UNTIL([test 6 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7600
7601$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7602AT_CHECK([cat 2.packets], [0], [])
7603
7604reset_pcap_file hv1-vif1 hv1/vif1
7605reset_pcap_file hv1-vif2 hv1/vif2
7606rm -f 1.expected
7607rm -f 2.expected
7608
7609# Incomplete DNS packet.
7610set_dns_params vm1_incomplete
7611src_ip=`ip_to_hex 10 0 0 6`
7612dst_ip=`ip_to_hex 10 0 0 1`
7613dns_reply=0
7614test_dns 2 f00000000002 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data
7615
7616# NXT_RESUMEs should be 7.
7617OVS_WAIT_UNTIL([test 7 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7618
7619$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
7620AT_CHECK([cat 2.packets], [0], [])
7621
7622reset_pcap_file hv1-vif1 hv1/vif1
7623reset_pcap_file hv1-vif2 hv1/vif2
7624rm -f 1.expected
7625rm -f 2.expected
7626
7627# Add one more DNS record to the ls1.
7628ovn-nbctl --wait=hv set Logical_switch ls1 dns_records="$DNS1 $DNS2"
7629
7630set_dns_params vm3
7631src_ip=`ip_to_hex 10 0 0 4`
7632dst_ip=`ip_to_hex 10 0 0 1`
7633dns_reply=1
7634test_dns 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7635
7636# NXT_RESUMEs should be 8.
7637OVS_WAIT_UNTIL([test 8 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7638
7639$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
7640cat 1.expected | cut -c -48 > expout
7641AT_CHECK([cat 1.packets | cut -c -48], [0], [expout])
7642# Skipping the IPv4 checksum.
7643cat 1.expected | cut -c 53- > expout
7644AT_CHECK([cat 1.packets | cut -c 53-], [0], [expout])
7645
7646reset_pcap_file hv1-vif1 hv1/vif1
7647reset_pcap_file hv1-vif2 hv1/vif2
7648rm -f 1.expected
7649rm -f 2.expected
7650
f8e79d82
MM
7651# Try DNS query over IPv6
7652set_dns_params vm1
7653src_ip=aef00000000000000000000000000004
7654dst_ip=aef00000000000000000000000000001
7655dns_reply=1
7656test_dns6 1 f00000000001 f000000000f0 $src_ip $dst_ip $dns_reply $dns_req_data $dns_resp_data
7657
7658# NXT_RESUMEs should be 9.
7659OVS_WAIT_UNTIL([test 9 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
7660
7661$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
b75f2651
MM
7662# Skipping the UDP checksum.
7663cat 1.expected | cut -c 1-120,125- > expout
7664AT_CHECK([cat 1.packets | cut -c 1-120,125-], [0], [expout])
f8e79d82
MM
7665
7666reset_pcap_file hv1-vif1 hv1/vif1
7667reset_pcap_file hv1-vif2 hv1/vif2
7668rm -f 1.expected
7669rm -f 2.expected
7670
302eda27
NS
7671as hv1
7672 OVS_APP_EXIT_AND_WAIT([ovn-controller])
7673OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7674OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7675
7676as ovn-sb
7677OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7678
7679as ovn-nb
7680OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7681
7682as northd
7683OVS_APP_EXIT_AND_WAIT([ovn-northd])
7684
7685as main
7686OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
7687OVS_APP_EXIT_AND_WAIT([ovsdb-server])
7688AT_CLEANUP
7689
75f9e007 7690AT_SETUP([ovn -- 4 HV, 1 LS, 1 LR, packet test with HA distributed router gateway port])
1da17a0b 7691AT_SKIP_IF([test $HAVE_PYTHON = no])
7692ovn_start
7693
7694net_add n1
7695
7696sim_add hv1
7697as hv1
7698ovs-vsctl add-br br-phys
7699ovn_attach n1 br-phys 192.168.0.1
7700ovs-vsctl -- add-port br-int hv1-vif1 -- \
7701 set interface hv1-vif1 external-ids:iface-id=foo1 \
7702 options:tx_pcap=hv1/vif1-tx.pcap \
7703 options:rxq_pcap=hv1/vif1-rx.pcap \
7704 ofport-request=1
7705
7706sim_add gw1
7707as gw1
7708ovs-vsctl add-br br-phys
7709ovn_attach n1 br-phys 192.168.0.2
7710
7711sim_add gw2
7712as gw2
7713ovs-vsctl add-br br-phys
7714ovn_attach n1 br-phys 192.168.0.4
7715
7716sim_add ext1
7717as ext1
7718ovs-vsctl add-br br-phys
7719ovn_attach n1 br-phys 192.168.0.3
7720ovs-vsctl -- add-port br-int ext1-vif1 -- \
7721 set interface ext1-vif1 external-ids:iface-id=outside1 \
7722 options:tx_pcap=ext1/vif1-tx.pcap \
7723 options:rxq_pcap=ext1/vif1-rx.pcap \
7724 ofport-request=1
7725
7726# Pre-populate the hypervisors' ARP tables so that we don't lose any
7727# packets for ARP resolution (native tunneling doesn't queue packets
7728# for ARP resolution).
74868f2c 7729OVN_POPULATE_ARP
1da17a0b 7730
7731ovn-nbctl create Logical_Router name=R1
7732
7733ovn-nbctl ls-add foo
7734ovn-nbctl ls-add alice
7735ovn-nbctl ls-add outside
7736
7737# Connect foo to R1
7738ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
7739ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
7740 type=router options:router-port=foo \
7741 -- lsp-set-addresses rp-foo router
7742
7743# Connect alice to R1 as distributed router gateway port on gw1
7744ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7745
7746ovn-nbctl \
7747 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7748 chassis_name=gw1 \
7749 priority=20 -- \
7750 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7751 chassis_name=gw2 \
7752 priority=10 -- \
7753 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7754
7755ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7756 type=router options:router-port=alice \
7757 -- lsp-set-addresses rp-alice router
7758
7759# Create logical port foo1 in foo
7760ovn-nbctl lsp-add foo foo1 \
7761-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7762
7763# Create logical port outside1 in outside
7764ovn-nbctl lsp-add outside outside1 \
7765-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7766
7767# Create localnet port in alice
7768ovn-nbctl lsp-add alice ln-alice
7769ovn-nbctl lsp-set-addresses ln-alice unknown
7770ovn-nbctl lsp-set-type ln-alice localnet
7771ovn-nbctl lsp-set-options ln-alice network_name=phys
7772
7773# Create localnet port in outside
7774ovn-nbctl lsp-add outside ln-outside
7775ovn-nbctl lsp-set-addresses ln-outside unknown
7776ovn-nbctl lsp-set-type ln-outside localnet
7777ovn-nbctl lsp-set-options ln-outside network_name=phys
7778
7779# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7780# mapping to the external network, is the one generating packets
7781as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7782as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7783as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7784
7785AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7786
7787# Allow some time for ovn-northd and ovn-controller to catch up.
7788# XXX This should be more systematic.
7789sleep 2
7790
7791ip_to_hex() {
7792 printf "%02x%02x%02x%02x" "$@"
7793}
7794
7795reset_pcap_file() {
7796 local iface=$1
7797 local pcap_file=$2
7798 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
7799options:rxq_pcap=dummy-rx.pcap
7800 rm -f ${pcap_file}*.pcap
7801 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
7802options:rxq_pcap=${pcap_file}-rx.pcap
7803}
7804
7805test_ip_packet()
7806{
7807 local active_gw=$1
7808 local backup_gw=$2
7809
7810 # Send ip packet between foo1 and outside1
7811 src_mac="f00000010203" # foo1 mac
7812 dst_mac="000001010203" # rp-foo mac (internal router leg)
7813 src_ip=`ip_to_hex 192 168 1 2`
7814 dst_ip=`ip_to_hex 172 16 1 3`
7815 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
7816
7817 # ARP request packet to expect at outside1
7818 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
7819
7820 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7821
7822 # Send ARP reply from outside1 back to the router
7823 # XXX: note, we could avoid this if we plug this port into a netns
7824 # and setup the IP address into the port, so the kernel would simply reply
7825 src_mac="000002010203"
7826 reply_mac="f00000010204"
7827 dst_ip=`ip_to_hex 172 16 1 3`
7828 src_ip=`ip_to_hex 172 16 1 1`
7829 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
7830
7831 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
7832
86c9d79a
NS
7833 OVS_WAIT_UNTIL([
7834 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
7835grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
7836 ])
7837
1da17a0b 7838 # Packet to Expect at ext1 chassis, outside1 port
7839 src_mac="000002010203"
7840 dst_mac="f00000010204"
7841 src_ip=`ip_to_hex 192 168 1 2`
7842 dst_ip=`ip_to_hex 172 16 1 3`
7843 expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
7844 echo $expected > ext1-vif1.expected
7845
7846 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
7847 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
7848 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
7849
7850 # Resend packet from foo1 to outside1
7851 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
7852
7853 sleep 1
7854
7855 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
7856 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
7857 AT_CHECK([grep $expected packets | sort], [0], [expout])
7858 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
7859 AT_CHECK([grep $expected packets | sort], [0], [])
7860}
7861
7862test_ip_packet gw1 gw2
7863
75f9e007
GZ
7864ovn-nbctl --timeout=3 --wait=hv \
7865 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7866 chassis_name=gw1 \
7867 priority=10 -- \
7868 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7869 chassis_name=gw2 \
7870 priority=20 -- \
7871 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7872
7873test_ip_packet gw2 gw1
7874
7875OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
7876AT_CLEANUP
7877
7878AT_SETUP([ovn -- 4 HV, 3 LS, 2 LR, packet test with HA distributed router gateway port])
7879AT_SKIP_IF([test $HAVE_PYTHON = no])
7880ovn_start
7881
7882net_add n1
7883
7884sim_add hv1
7885as hv1
7886ovs-vsctl add-br br-phys
7887ovn_attach n1 br-phys 192.168.0.1
7888ovs-vsctl -- add-port br-int hv1-vif1 -- \
7889 set interface hv1-vif1 external-ids:iface-id=foo1 \
7890 options:tx_pcap=hv1/vif1-tx.pcap \
7891 options:rxq_pcap=hv1/vif1-rx.pcap \
7892 ofport-request=1
7893
7894sim_add gw1
7895as gw1
7896ovs-vsctl add-br br-phys
7897ovn_attach n1 br-phys 192.168.0.2
7898
7899sim_add gw2
7900as gw2
7901ovs-vsctl add-br br-phys
7902ovn_attach n1 br-phys 192.168.0.4
7903
7904sim_add ext1
7905as ext1
7906ovs-vsctl add-br br-phys
7907ovn_attach n1 br-phys 192.168.0.3
7908ovs-vsctl -- add-port br-int ext1-vif1 -- \
7909 set interface ext1-vif1 external-ids:iface-id=outside1 \
7910 options:tx_pcap=ext1/vif1-tx.pcap \
7911 options:rxq_pcap=ext1/vif1-rx.pcap \
7912 ofport-request=1
7913
7914# Pre-populate the hypervisors' ARP tables so that we don't lose any
7915# packets for ARP resolution (native tunneling doesn't queue packets
7916# for ARP resolution).
74868f2c 7917OVN_POPULATE_ARP
75f9e007
GZ
7918
7919ovn-nbctl create Logical_Router name=R0
7920ovn-nbctl create Logical_Router name=R1
7921
7922ovn-nbctl ls-add foo
7923ovn-nbctl ls-add join
7924ovn-nbctl ls-add alice
7925ovn-nbctl ls-add outside
7926
7927#Connect foo to R0
7928ovn-nbctl lrp-add R0 R0-foo 00:00:01:01:02:03 192.168.1.1/24
7929ovn-nbctl lsp-add foo foo-R0 -- set Logical_Switch_Port foo-R0 \
7930 type=router options:router-port=R0-foo \
7931 -- lsp-set-addresses foo-R0 router
7932
7933#Connect R0 to join
7934ovn-nbctl lrp-add R0 R0-join 00:00:0d:01:02:03 100.60.1.1/24
7935ovn-nbctl lsp-add join join-R0 -- set Logical_Switch_Port join-R0 \
7936 type=router options:router-port=R0-join \
7937 -- lsp-set-addresses join-R0 router
7938
7939#Connect join to R1
7940ovn-nbctl lrp-add R1 R1-join 00:00:0e:01:02:03 100.60.1.2/24
7941ovn-nbctl lsp-add join join-R1 -- set Logical_Switch_Port join-R1 \
7942 type=router options:router-port=R1-join \
7943 -- lsp-set-addresses join-R1 router
7944
7945#add route rules
7946ovn-nbctl lr-route-add R0 0.0.0.0/0 100.60.1.2
7947ovn-nbctl lr-route-add R1 192.168.0.0/16 100.60.1.1
7948
7949# Connect alice to R1 as distributed router gateway port on gw1
7950ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24
7951
7952ovn-nbctl \
7953 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
7954 chassis_name=gw1 \
7955 priority=20 -- \
7956 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
7957 chassis_name=gw2 \
7958 priority=10 -- \
7959 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
7960
7961ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
7962 type=router options:router-port=alice \
7963 -- lsp-set-addresses rp-alice router
7964
7965# Create logical port foo1 in foo
7966ovn-nbctl lsp-add foo foo1 \
7967-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
7968
7969# Create logical port outside1 in outside
7970ovn-nbctl lsp-add outside outside1 \
7971-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
7972
7973# Create localnet port in alice
7974ovn-nbctl lsp-add alice ln-alice
7975ovn-nbctl lsp-set-addresses ln-alice unknown
7976ovn-nbctl lsp-set-type ln-alice localnet
7977ovn-nbctl lsp-set-options ln-alice network_name=phys
7978
7979# Create localnet port in outside
7980ovn-nbctl lsp-add outside ln-outside
7981ovn-nbctl lsp-set-addresses ln-outside unknown
7982ovn-nbctl lsp-set-type ln-outside localnet
7983ovn-nbctl lsp-set-options ln-outside network_name=phys
7984
7985# Create bridge-mappings on gw1, gw2 and ext1, hv1 doesn't need
7986# mapping to the external network, is the one generating packets
7987as gw1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7988as gw2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7989as ext1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
7990
7991AT_CHECK([ovn-nbctl --timeout=3 --wait=sb sync], [0], [ignore])
7992
7993# Allow some time for ovn-northd and ovn-controller to catch up.
7994# XXX This should be more systematic.
7995sleep 2
7996
7997ip_to_hex() {
7998 printf "%02x%02x%02x%02x" "$@"
7999}
8000
8001reset_pcap_file() {
8002 local iface=$1
8003 local pcap_file=$2
8004 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8005options:rxq_pcap=dummy-rx.pcap
8006 rm -f ${pcap_file}*.pcap
8007 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8008options:rxq_pcap=${pcap_file}-rx.pcap
8009}
8010
8011test_ip_packet()
8012{
8013 local active_gw=$1
8014 local backup_gw=$2
8015
8016 # Send ip packet between foo1 and outside1
8017 src_mac="f00000010203" # foo1 mac
8018 dst_mac="000001010203" # foo-R0 mac (internal router leg)
8019 src_ip=`ip_to_hex 192 168 1 2`
8020 dst_ip=`ip_to_hex 172 16 1 3`
8021 packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8022
8023 # ARP request packet to expect at outside1
8024 #arp_request=ffffffffffff${src_mac}08060001080006040001${src_mac}${src_ip}000000000000${dst_ip}
8025
8026 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8027
8028 # Send ARP reply from outside1 back to the router
8029 # XXX: note, we could avoid this if we plug this port into a netns
8030 # and setup the IP address into the port, so the kernel would simply reply
8031 src_mac="000002010203"
8032 reply_mac="f00000010204"
8033 dst_ip=`ip_to_hex 172 16 1 3`
8034 src_ip=`ip_to_hex 172 16 1 1`
8035 arp_reply=${src_mac}${reply_mac}08060001080006040002${reply_mac}${dst_ip}${src_mac}${src_ip}
8036
8037 as ext1 ovs-appctl netdev-dummy/receive ext1-vif1 $arp_reply
8038
86c9d79a
NS
8039 OVS_WAIT_UNTIL([
8040 test `as $active_gw ovs-ofctl dump-flows br-int | grep table=66 | \
8041grep actions=mod_dl_dst:f0:00:00:01:02:04 | wc -l` -eq 1
8042 ])
8043
75f9e007
GZ
8044 # Packet to Expect at ext1 chassis, outside1 port
8045 src_mac="000002010203"
8046 dst_mac="f00000010204"
8047 src_ip=`ip_to_hex 192 168 1 2`
8048 dst_ip=`ip_to_hex 172 16 1 3`
8049 expected=${dst_mac}${src_mac}08004500001c000000003e110200${src_ip}${dst_ip}0035111100080000
8050 echo $expected > ext1-vif1.expected
8051
8052 as $active_gw reset_pcap_file br-phys_n1 $active_gw/br-phys_n1
8053 as $backup_gw reset_pcap_file br-phys_n1 $backup_gw/br-phys_n1
8054 as ext1 reset_pcap_file ext1-vif1 ext1/vif1
8055
8056 # Resend packet from foo1 to outside1
8057 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8058
8059 sleep 1
8060
8061 OVN_CHECK_PACKETS([ext1/vif1-tx.pcap], [ext1-vif1.expected])
8062 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $active_gw/br-phys_n1-tx.pcap > packets
8063 AT_CHECK([grep $expected packets | sort], [0], [expout])
8064 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $backup_gw/br-phys_n1-tx.pcap > packets
8065 AT_CHECK([grep $expected packets | sort], [0], [])
8066}
8067
8068test_ip_packet gw1 gw2
8069
8e1d9349 8070ovn-nbctl --timeout=3 --wait=hv \
1da17a0b 8071 --id=@gc0 create Gateway_Chassis name=alice_gw1 \
8072 chassis_name=gw1 \
8073 priority=10 -- \
8074 --id=@gc1 create Gateway_Chassis name=alice_gw2 \
8075 chassis_name=gw2 \
8076 priority=20 -- \
8077 set Logical_Router_Port alice 'gateway_chassis=[@gc0,@gc1]'
8078
8079test_ip_packet gw2 gw1
8080
8081OVN_CLEANUP([hv1],[gw1],[gw2],[ext1])
8082AT_CLEANUP
8083
41a15b71
MS
8084AT_SETUP([ovn -- 1 LR with distributed router gateway port])
8085AT_SKIP_IF([test $HAVE_PYTHON = no])
8086ovn_start
8087
8088# Logical network:
8089# One LR R1 that has switches foo (192.168.1.0/24) and
8090# alice (172.16.1.0/24) connected to it. The logical port
8091# between R1 and alice has a "redirect-chassis" specified,
8092# i.e. it is the distributed router gateway port.
8093# Switch alice also has a localnet port defined.
8094# An additional switch outside has a localnet port and the
8095# same subnet as alice (172.16.1.0/24).
8096
8097# Physical network:
8098# Three hypervisors hv[123].
8099# hv1 hosts vif foo1.
8100# hv2 is the "redirect-chassis" that hosts the distributed
8101# router gateway port.
8102# hv3 hosts vif outside1.
8103# In order to show that connectivity works only through hv2,
8104# an initial round of tests is run without any bridge-mapping
8105# defined for the localnet on hv2. These tests are expected
8106# to fail.
8107# Subsequent tests are run after defining the bridge-mapping
8108# for the localnet on hv2. These tests are expected to succeed.
8109
8110# Create three hypervisors and create OVS ports corresponding
8a5a5e3c 8111# to logical ports.
41a15b71
MS
8112net_add n1
8113
8114sim_add hv1
8115as hv1
8116ovs-vsctl add-br br-phys
8117ovn_attach n1 br-phys 192.168.0.1
8118ovs-vsctl -- add-port br-int hv1-vif1 -- \
8119 set interface hv1-vif1 external-ids:iface-id=foo1 \
8120 options:tx_pcap=hv1/vif1-tx.pcap \
8121 options:rxq_pcap=hv1/vif1-rx.pcap \
8122 ofport-request=1
8123
8124sim_add hv2
8125as hv2
8126ovs-vsctl add-br br-phys
8127ovn_attach n1 br-phys 192.168.0.2
8128
8129sim_add hv3
8130as hv3
8131ovs-vsctl add-br br-phys
8132ovn_attach n1 br-phys 192.168.0.3
8133ovs-vsctl -- add-port br-int hv3-vif1 -- \
8134 set interface hv3-vif1 external-ids:iface-id=outside1 \
8135 options:tx_pcap=hv3/vif1-tx.pcap \
8136 options:rxq_pcap=hv3/vif1-rx.pcap \
8137 ofport-request=1
8138
8139# Pre-populate the hypervisors' ARP tables so that we don't lose any
8140# packets for ARP resolution (native tunneling doesn't queue packets
8141# for ARP resolution).
74868f2c 8142OVN_POPULATE_ARP
41a15b71
MS
8143
8144ovn-nbctl create Logical_Router name=R1
8145
8146ovn-nbctl ls-add foo
8147ovn-nbctl ls-add alice
8148ovn-nbctl ls-add outside
8149
8150# Connect foo to R1
8151ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24
8152ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \
8153 type=router options:router-port=foo \
8154 -- lsp-set-addresses rp-foo router
8155
8156# Connect alice to R1 as distributed router gateway port on hv2
8157ovn-nbctl lrp-add R1 alice 00:00:02:01:02:03 172.16.1.1/24 \
8158 -- set Logical_Router_Port alice options:redirect-chassis="hv2"
8159ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8160 type=router options:router-port=alice \
8161 -- lsp-set-addresses rp-alice router
8162
8163# Create logical port foo1 in foo
8164ovn-nbctl lsp-add foo foo1 \
8165-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8166
8167# Create logical port outside1 in outside
8168ovn-nbctl lsp-add outside outside1 \
8169-- lsp-set-addresses outside1 "f0:00:00:01:02:04 172.16.1.3"
8170
8171# Create localnet port in alice
8172ovn-nbctl lsp-add alice ln-alice
8173ovn-nbctl lsp-set-addresses ln-alice unknown
8174ovn-nbctl lsp-set-type ln-alice localnet
8175ovn-nbctl lsp-set-options ln-alice network_name=phys
8176
8177# Create localnet port in outside
8178ovn-nbctl lsp-add outside ln-outside
8179ovn-nbctl lsp-set-addresses ln-outside unknown
8180ovn-nbctl lsp-set-type ln-outside localnet
8181ovn-nbctl lsp-set-options ln-outside network_name=phys
8182
8183# Create bridge-mappings on hv1 and hv3, leaving hv2 for later
8184as hv1 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8185as hv3 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8186
8187
8188# Allow some time for ovn-northd and ovn-controller to catch up.
8189# XXX This should be more systematic.
8190sleep 2
8191
8192echo "---------NB dump-----"
8193ovn-nbctl show
8194echo "---------------------"
8195ovn-nbctl list logical_router
8196echo "---------------------"
8197ovn-nbctl list logical_router_port
8198echo "---------------------"
8199
8200echo "---------SB dump-----"
8201ovn-sbctl list datapath_binding
8202echo "---------------------"
8203ovn-sbctl list port_binding
8204echo "---------------------"
8205ovn-sbctl dump-flows
8206echo "---------------------"
8207ovn-sbctl list chassis
8208ovn-sbctl list encap
1da17a0b 8209echo "------ Gateway_Chassis dump (SBDB) -------"
8210ovn-sbctl list Gateway_Chassis
8211echo "------ Port_Binding chassisredirect -------"
8212ovn-sbctl find Port_Binding type=chassisredirect
8213echo "-------------------------------------------"
41a15b71
MS
8214
8215echo "------ hv1 dump ----------"
8216as hv1 ovs-ofctl show br-int
8217as hv1 ovs-ofctl dump-flows br-int
8218echo "------ hv2 dump ----------"
8219as hv2 ovs-ofctl show br-int
8220as hv2 ovs-ofctl dump-flows br-int
8221echo "------ hv3 dump ----------"
8222as hv3 ovs-ofctl show br-int
8223as hv3 ovs-ofctl dump-flows br-int
8224echo "--------------------------"
8225
1da17a0b 8226
41a15b71
MS
8227# Check that redirect mapping is programmed only on hv2
8228AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8229])
8230AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=33 | grep =0x3,metadata=0x1 | grep load:0x2- | wc -l], [0], [1
8231])
8232# Check that hv1 sends chassisredirect port traffic to hv2
8233AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | grep output | wc -l], [0], [1
8234])
8235AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=32 | grep =0x3,metadata=0x1 | wc -l], [0], [0
8236])
8237# Check that arp reply on distributed gateway port is only programmed on hv2
b0684540 8238AT_CHECK([as hv1 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [0
41a15b71 8239])
b0684540 8240AT_CHECK([as hv2 ovs-ofctl dump-flows br-int | grep arp | grep load:0x2- | grep =0x2,metadata=0x1 | wc -l], [0], [1
41a15b71
MS
8241])
8242
8243
8244ip_to_hex() {
8245 printf "%02x%02x%02x%02x" "$@"
8246}
8247
8248
8249: > hv2-vif1.expected
8250: > hv3-vif1.expected
8251
8252# test_arp INPORT SHA SPA TPA [REPLY_HA]
8253#
8254# Causes a packet to be received on INPORT. The packet is an ARP
8255# request with SHA, SPA, and TPA as specified. If REPLY_HA is provided, then
8256# it should be the hardware address of the target to expect to receive in an
8257# ARP reply; otherwise no reply is expected.
8258#
8259# INPORT is an logical switch port number, e.g. 11 for vif11.
8260# SHA and REPLY_HA are each 12 hex digits.
8261# SPA and TPA are each 8 hex digits.
8262test_arp() {
8263 local hv=$1 inport=$2 sha=$3 spa=$4 tpa=$5 reply_ha=$6
8264 local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa}
8265 as hv$hv ovs-appctl netdev-dummy/receive hv${hv}-vif$inport $request
8266
8267 if test X$reply_ha != X; then
8268 # Expect to receive the reply, if any.
8269 local reply=${sha}${reply_ha}08060001080006040002${reply_ha}${tpa}${sha}${spa}
8270 echo $reply >> hv${hv}-vif$inport.expected
8271 fi
8272}
8273
8274rtr_ip=$(ip_to_hex 172 16 1 1)
8275foo_ip=$(ip_to_hex 192 168 1 2)
8276outside_ip=$(ip_to_hex 172 16 1 3)
8277
8278echo $rtr_ip
8279echo $foo_ip
8280echo $outside_ip
8281
8282# ARP for router IP address from outside1, no response expected
8283test_arp 3 1 f00000010204 $outside_ip $rtr_ip
8284
8285# Now check the packets actually received against the ones expected.
8286OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8287
8288# Send ip packet between foo1 and outside1
8289src_mac="f00000010203"
8290dst_mac="000001010203"
8291src_ip=`ip_to_hex 192 168 1 2`
8292dst_ip=`ip_to_hex 172 16 1 3`
8293packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8294
8295# Now check the packets actually received against the ones expected.
8296OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8297
8298# Now add bridge-mappings on hv2, which should make everything work
8299as hv2 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
8300
8301# Allow some time for ovn-northd and ovn-controller to catch up.
8302# XXX This should be more systematic.
8303sleep 2
8304
8305# ARP for router IP address from outside1
8306test_arp 3 1 f00000010204 $outside_ip $rtr_ip 000002010203
8307
8308# Now check the packets actually received against the ones expected.
8309OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8310
8311# Send ip packet between foo1 and outside1
8312src_mac="f00000010203"
8313dst_mac="000001010203"
8314src_ip=`ip_to_hex 192 168 1 2`
8315dst_ip=`ip_to_hex 172 16 1 3`
8316packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8317
41a15b71
MS
8318# Packet to Expect at outside1
8319src_mac="000002010203"
8320dst_mac="f00000010204"
41a15b71
MS
8321expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8322
41a15b71
MS
8323as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8324
8325echo "------ hv1 dump ----------"
8326as hv1 ovs-ofctl show br-int
8327as hv1 ovs-ofctl dump-flows br-int
8328echo "------ hv2 dump ----------"
8329as hv2 ovs-ofctl show br-int
8330as hv2 ovs-ofctl dump-flows br-int
8331echo "------ hv3 dump ----------"
8332as hv3 ovs-ofctl show br-int
8333as hv3 ovs-ofctl dump-flows br-int
8334echo "----------------------------"
8335
8336echo $expected >> hv3-vif1.expected
8337OVN_CHECK_PACKETS([hv3/vif1-tx.pcap], [hv3-vif1.expected])
8338
8339#Check ovn-trace over "chassisredirect" port
8340AT_CAPTURE_FILE([trace])
8341ovn_trace () {
8342 ovn-trace --all "$@" | tee trace | sed '1,/Minimal trace/d'
8343}
8344
8345echo 'ip.ttl--;' > expout
8346echo 'eth.src = 00:00:02:01:02:03;' >> expout
8347echo 'eth.dst = f0:00:00:01:02:04;' >> expout
8348echo 'output("ln-alice");' >> expout
8349AT_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])
8350
8351# Create logical port alice1 in alice on hv1
8352as hv1 ovs-vsctl -- add-port br-int hv1-vif2 -- \
8353 set interface hv1-vif2 external-ids:iface-id=alice1 \
8354 options:tx_pcap=hv1/vif2-tx.pcap \
8355 options:rxq_pcap=hv1/vif2-rx.pcap \
8356 ofport-request=1
8357
8358ovn-nbctl lsp-add alice alice1 \
8359-- lsp-set-addresses alice1 "f0:00:00:01:02:05 172.16.1.4"
8360
8361# Create logical port foo2 in foo on hv2
8362as hv2 ovs-vsctl -- add-port br-int hv2-vif1 -- \
8363 set interface hv2-vif1 external-ids:iface-id=foo2 \
8364 options:tx_pcap=hv2/vif1-tx.pcap \
8365 options:rxq_pcap=hv2/vif1-rx.pcap \
8366 ofport-request=1
8367
8368ovn-nbctl lsp-add foo foo2 \
8369-- lsp-set-addresses foo2 "f0:00:00:01:02:06 192.168.1.3"
8370
8371# Allow some time for ovn-northd and ovn-controller to catch up.
8372# XXX This should be more systematic.
8373sleep 1
8374
8375: > hv1-vif2.expected
8376
8377# Send ip packet between alice1 and foo2
8378src_mac="f00000010205"
8379dst_mac="000002010203"
8380src_ip=`ip_to_hex 172 16 1 4`
8381dst_ip=`ip_to_hex 192 168 1 3`
8382packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8383
8384as hv1 ovs-appctl netdev-dummy/receive hv1-vif2 $packet
8385
8386# Packet to Expect at foo2
8387src_mac="000001010203"
8388dst_mac="f00000010206"
8389src_ip=`ip_to_hex 172 16 1 4`
8390dst_ip=`ip_to_hex 192 168 1 3`
8391expected=${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000
8392
8393echo $expected >> hv2-vif1.expected
f5f64552 8394OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [hv2-vif1.expected])
41a15b71 8395
0d31e5be 8396AT_CHECK([ovn-sbctl --bare --columns _uuid find Port_Binding logical_port=cr-alice | wc -l], [0], [1
415ed5d7 8397])
8398
8e1d9349 8399ovn-nbctl --timeout=3 --wait=sb remove Logical_Router_Port alice options redirect-chassis
415ed5d7 8400
0d31e5be 8401AT_CHECK([ovn-sbctl find Port_Binding logical_port=cr-alice | wc -l], [0], [0
415ed5d7 8402])
8403
41a15b71
MS
8404OVN_CLEANUP([hv1],[hv2],[hv3])
8405
8406AT_CLEANUP
26b9e08d
MS
8407
8408AT_SETUP([ovn -- send gratuitous arp for NAT rules on distributed router])
8409AT_SKIP_IF([test $HAVE_PYTHON = no])
8410ovn_start
8411# Create logical switches
8412ovn-nbctl ls-add ls0
8413ovn-nbctl ls-add ls1
8414# Create distributed router
8415ovn-nbctl create Logical_Router name=lr0
8416# Add distributed gateway port to distributed router
8417ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.1/24 \
8418 -- set Logical_Router_Port lrp0 options:redirect-chassis="hv2"
8419ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
8420 type=router options:router-port=lrp0 addresses="router"
8421# Add router port to ls1
8422ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
8423ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
8424 type=router options:router-port=lrp1 addresses="router"
f40c5588
MS
8425# Add logical ports for NAT rules
8426ovn-nbctl lsp-add ls1 foo1 \
8427-- lsp-set-addresses foo1 "00:00:00:00:00:03 10.0.0.3"
8428ovn-nbctl lsp-add ls1 foo2 \
8429-- lsp-set-addresses foo2 "00:00:00:00:00:04 10.0.0.4"
26b9e08d
MS
8430# Add nat-addresses option
8431ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8432# Add NAT rules
8433AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.1 10.0.0.0/24])
8434AT_CHECK([ovn-nbctl lr-nat-add lr0 dnat 192.168.0.2 10.0.0.2])
8435AT_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 8436AT_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
8437
8438net_add n1
8439sim_add hv1
8440as hv1
8441ovs-vsctl add-br br-phys
8442ovn_attach n1 br-phys 192.168.0.1
8443
8444AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8445AT_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])
8446
8447sim_add hv2
8448as hv2
8449ovs-vsctl add-br br-phys
8450ovn_attach n1 br-phys 192.168.0.2
8451# Initially test with no bridge-mapping on hv2, expect to receive no packets
8452
f40c5588
MS
8453sim_add hv3
8454as hv3
8455ovs-vsctl add-br br-phys
8456ovn_attach n1 br-phys 192.168.0.3
8457# Initially test with no bridge-mapping on hv3
8458
26b9e08d
MS
8459# Create a localnet port.
8460AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
8461AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
8462AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
8463AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
8464
8465# Allow some time for ovn-northd and ovn-controller to catch up.
8466# XXX This should be more systematic.
8467sleep 2
8468
8469# Expect no packets when hv2 bridge-mapping is not present
8470: > packets
8471OVN_CHECK_PACKETS([hv1/snoopvif-tx.pcap], [packets])
8472
8473# Add bridge-mapping on hv2
f40c5588 8474AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
26b9e08d
MS
8475
8476# Wait for packets to be received.
8477OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
8478trim_zeros() {
8479 sed 's/\(00\)\{1,\}$//'
8480}
8481$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8482expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80001000000000000c0a80001"
8483echo $expected > expout
8484expected="fffffffffffff0000000000108060001080006040001f00000000001c0a80002000000000000c0a80002"
8485echo $expected >> expout
8486AT_CHECK([sort packets], [0], [expout])
f40c5588 8487sort packets | cat
26b9e08d 8488
f40c5588
MS
8489# Temporarily remove nat-addresses option to avoid race conditions
8490# due to GARP backoff
8491ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses=""
8492
8493reset_pcap_file() {
8494 local iface=$1
8495 local pcap_file=$2
8496 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8497options:rxq_pcap=dummy-rx.pcap
8498 rm -f ${pcap_file}*.pcap
8499 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8500options:rxq_pcap=${pcap_file}-rx.pcap
8501}
8502
8503as hv1 reset_pcap_file snoopvif hv1/snoopvif
8504
8505# Add OVS ports for foo1 and foo2 on hv3
8506ovs-vsctl -- add-port br-int hv3-vif1 -- \
8507 set interface hv3-vif1 external-ids:iface-id=foo1 \
8508 ofport-request=1
8509ovs-vsctl -- add-port br-int hv3-vif2 -- \
8510 set interface hv3-vif2 external-ids:iface-id=foo2 \
8511 ofport-request=2
8512
8513# Add bridge-mapping on hv3
8514AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
8515
8516# Re-add nat-addresses option
8517ovn-nbctl lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
8518
8519# Wait for packets to be received.
8520OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 250])
8521trim_zeros() {
8522 sed 's/\(00\)\{1,\}$//'
8523}
8524
8525$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros > packets
8526expected="fffffffffffff0000000000308060001080006040001f00000000003c0a80003000000000000c0a80003"
8527echo $expected >> expout
8528expected="fffffffffffff0000000000408060001080006040001f00000000004c0a80004000000000000c0a80004"
8529echo $expected >> expout
8530AT_CHECK([sort packets], [0], [expout])
8531sort packets | cat
8532
8533OVN_CLEANUP([hv1],[hv2],[hv3])
26b9e08d
MS
8534
8535AT_CLEANUP
6b785fd8 8536
4364646c
ZKL
8537AT_SETUP([ovn -- IPv6 ND Router Solicitation responder])
8538AT_KEYWORDS([ovn-nd_ra])
8539AT_SKIP_IF([test $HAVE_PYTHON = no])
8540ovn_start
8541
8542# In this test case we create 1 lswitch with 3 VIF ports attached,
8543# and a lrouter connected to the lswitch.
8544# We generate the Router solicitation packet and verify the Router Advertisement
8545# reply packet from the ovn-controller.
8546
8547# Create hypervisor and logical switch lsw0, logical router lr0, attach lsw0
8548# onto lr0, set Logical_Router_Port.ipv6_ra_configs:address_mode column to
8549# 'slaac' to allow lrp0 send RA for SLAAC mode.
8550ovn-nbctl ls-add lsw0
8551ovn-nbctl lr-add lr0
8552ovn-nbctl lrp-add lr0 lrp0 fa:16:3e:00:00:01 fdad:1234:5678::1/64
8553ovn-nbctl set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode="slaac"
8554ovn-nbctl \
8555 -- lsp-add lsw0 lsp0 \
8556 -- set Logical_Switch_Port lsp0 type=router \
8557 options:router-port=lrp0 \
8558 addresses='"fa:16:3e:00:00:01 fdad:1234:5678::1"'
8559net_add n1
8560sim_add hv1
8561as hv1
8562ovs-vsctl add-br br-phys
8563ovn_attach n1 br-phys 192.168.0.2
8564
8565ovn-nbctl lsp-add lsw0 lp1
8566ovn-nbctl lsp-set-addresses lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8567ovn-nbctl lsp-set-port-security lp1 "fa:16:3e:00:00:02 10.0.0.12 fdad:1234:5678:0:f816:3eff:fe:2"
8568
8569ovn-nbctl lsp-add lsw0 lp2
8570ovn-nbctl lsp-set-addresses lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8571ovn-nbctl lsp-set-port-security lp2 "fa:16:3e:00:00:03 10.0.0.13 fdad:1234:5678:0:f816:3eff:fe:3"
8572
8573ovn-nbctl lsp-add lsw0 lp3
8574ovn-nbctl lsp-set-addresses lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8575ovn-nbctl lsp-set-port-security lp3 "fa:16:3e:00:00:04 10.0.0.14 fdad:1234:5678:0:f816:3eff:fe:4"
8576
8577# Add ACL rule for ICMPv6 on lsw0
8578ovn-nbctl acl-add lsw0 from-lport 1002 'ip6 && icmp6' allow-related
8579ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp1" && ip6 && icmp6' allow-related
8580ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp2" && ip6 && icmp6' allow-related
8581ovn-nbctl acl-add lsw0 to-lport 1002 'outport == "lp3" && ip6 && icmp6' allow-related
8582
8583ovs-vsctl -- add-port br-int hv1-vif1 -- \
8584 set interface hv1-vif1 external-ids:iface-id=lp1 \
8585 options:tx_pcap=hv1/vif1-tx.pcap \
8586 options:rxq_pcap=hv1/vif1-rx.pcap \
8587 ofport-request=1
8588
8589ovs-vsctl -- add-port br-int hv1-vif2 -- \
8590 set interface hv1-vif2 external-ids:iface-id=lp2 \
8591 options:tx_pcap=hv1/vif2-tx.pcap \
8592 options:rxq_pcap=hv1/vif2-rx.pcap \
8593 ofport-request=2
8594
8595ovs-vsctl -- add-port br-int hv1-vif3 -- \
8596 set interface hv1-vif3 external-ids:iface-id=lp3 \
8597 options:tx_pcap=hv1/vif3-tx.pcap \
8598 options:rxq_pcap=hv1/vif3-rx.pcap \
8599 ofport-request=3
8600
8601# Allow some time for ovn-northd and ovn-controller to catch up.
8602# XXX This should be more systematic.
8603sleep 1
8604
8605reset_pcap_file() {
8606 local iface=$1
8607 local pcap_file=$2
8608 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
8609options:rxq_pcap=dummy-rx.pcap
8610 rm -f ${pcap_file}*.pcap
8611 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
8612options:rxq_pcap=${pcap_file}-rx.pcap
8613}
8614
8615# Make sure that ovn-controller has installed the corresponding OF Flow.
8616OVS_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"`])
8617
8618# This shell function sends a Router Solicitation packet.
8619# test_ipv6_ra INPORT SRC_MAC SRC_LLA ADDR_MODE MTU RA_PREFIX_OPT
8620test_ipv6_ra() {
8621 local inport=$1 src_mac=$2 src_lla=$3 addr_mode=$4 mtu=$5 prefix_opt=$6
8622 local request=333300000002${src_mac}86dd6000000000103aff${src_lla}ff02000000000000000000000000000285000efc000000000101${src_mac}
8623
8624 local len=24
8625 local mtu_opt=""
8626 if test $mtu != 0; then
8627 len=`expr $len + 8`
8628 mtu_opt=05010000${mtu}
8629 fi
8630
8631 if test ${#prefix_opt} != 0; then
8632 prefix_opt=${prefix_opt}fdad1234567800000000000000000000
8633 len=`expr $len + ${#prefix_opt} / 2`
8634 fi
8635
8636 len=$(printf "%x" $len)
8637 local lrp_mac=fa163e000001
8638 local lrp_lla=fe80000000000000f8163efffe000001
8639 local reply=${src_mac}${lrp_mac}86dd6000000000${len}3aff${lrp_lla}${src_lla}8600XXXXff${addr_mode}ffff00000000000000000101${lrp_mac}${mtu_opt}${prefix_opt}
8640 echo $reply >> $inport.expected
8641
8642 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $request
8643}
8644
8645AT_CAPTURE_FILE([ofctl_monitor0.log])
8646as hv1 ovs-ofctl monitor br-int resume --detach --no-chdir \
8647--pidfile=ovs-ofctl0.pid 2> ofctl_monitor0.log
8648
8649# MTU is not set and the address mode is set to slaac
8650addr_mode=00
8651default_prefix_option_config=030440c0ffffffffffffffff00000000
8652src_mac=fa163e000002
8653src_lla=fe80000000000000f8163efffe000002
8654test_ipv6_ra 1 $src_mac $src_lla $addr_mode 0 $default_prefix_option_config
8655
8656# NXT_RESUME should be 1.
8657OVS_WAIT_UNTIL([test 1 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8658
8659$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8660
8661cat 1.expected | cut -c -112 > expout
8662AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8663
8664# Skipping the ICMPv6 checksum.
8665cat 1.expected | cut -c 117- > expout
8666AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8667
8668rm -f *.expected
8669reset_pcap_file hv1-vif1 hv1/vif1
8670reset_pcap_file hv1-vif2 hv1/vif2
8671reset_pcap_file hv1-vif3 hv1/vif3
8672
8673# Set the MTU to 1500
8674ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:mtu=1500
8675
8676# Make sure that ovn-controller has installed the corresponding OF Flow.
8677OVS_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"`])
8678
8679addr_mode=00
8680default_prefix_option_config=030440c0ffffffffffffffff00000000
8681src_mac=fa163e000003
8682src_lla=fe80000000000000f8163efffe000003
8683mtu=000005dc
8684
8685test_ipv6_ra 2 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8686
8687# NXT_RESUME should be 2.
8688OVS_WAIT_UNTIL([test 2 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8689
8690$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
8691
8692cat 2.expected | cut -c -112 > expout
8693AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
8694
8695# Skipping the ICMPv6 checksum.
8696cat 2.expected | cut -c 117- > expout
8697AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
8698
8699rm -f *.expected
8700reset_pcap_file hv1-vif1 hv1/vif1
8701reset_pcap_file hv1-vif2 hv1/vif2
8702reset_pcap_file hv1-vif3 hv1/vif3
8703
8704# Set the address mode to dhcpv6_stateful
8705ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateful
8706# Make sure that ovn-controller has installed the corresponding OF Flow.
8707OVS_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"`])
8708
8709addr_mode=80
8710default_prefix_option_config=""
8711src_mac=fa163e000004
8712src_lla=fe80000000000000f8163efffe000004
8713mtu=000005dc
8714
8715test_ipv6_ra 3 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8716
8717# NXT_RESUME should be 3.
8718OVS_WAIT_UNTIL([test 3 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8719
8720$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif3-tx.pcap > 3.packets
8721
8722cat 3.expected | cut -c -112 > expout
8723AT_CHECK([cat 3.packets | cut -c -112], [0], [expout])
8724
8725# Skipping the ICMPv6 checksum.
8726cat 3.expected | cut -c 117- > expout
8727AT_CHECK([cat 3.packets | cut -c 117-], [0], [expout])
8728
8729rm -f *.expected
8730reset_pcap_file hv1-vif1 hv1/vif1
8731reset_pcap_file hv1-vif2 hv1/vif2
8732reset_pcap_file hv1-vif3 hv1/vif3
8733
8734# Set the address mode to dhcpv6_stateless
8735ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=dhcpv6_stateless
8736# Make sure that ovn-controller has installed the corresponding OF Flow.
8737OVS_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"`])
8738
8739addr_mode=40
8740default_prefix_option_config=030440c0ffffffffffffffff00000000
8741src_mac=fa163e000002
8742src_lla=fe80000000000000f8163efffe000002
8743mtu=000005dc
8744
8745test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8746
8747# NXT_RESUME should be 4.
8748OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8749
8750$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8751
8752cat 1.expected | cut -c -112 > expout
8753AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
8754
8755# Skipping the ICMPv6 checksum.
8756cat 1.expected | cut -c 117- > expout
8757AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
8758
8759rm -f *.expected
8760reset_pcap_file hv1-vif1 hv1/vif1
8761reset_pcap_file hv1-vif2 hv1/vif2
8762reset_pcap_file hv1-vif3 hv1/vif3
8763
8764# Set the address mode to invalid.
8765ovn-nbctl --wait=hv set Logical_Router_Port lrp0 ipv6_ra_configs:address_mode=invalid
8766# Make sure that ovn-controller has not installed any OF Flow for IPv6 ND RA.
8767OVS_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"`])
8768
8769addr_mode=40
8770default_prefix_option_config=""
8771src_mac=fa163e000002
8772src_lla=fe80000000000000f8163efffe000002
8773mtu=000005dc
8774
8775test_ipv6_ra 1 $src_mac $src_lla $addr_mode $mtu $default_prefix_option_config
8776
8777# NXT_RESUME should be 4 only.
8778OVS_WAIT_UNTIL([test 4 = `cat ofctl_monitor*.log | grep -c NXT_RESUME`])
8779
8780$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif1-tx.pcap > 1.packets
8781AT_CHECK([cat 1.packets], [0], [])
8782
8783OVN_CLEANUP([hv1])
8784AT_CLEANUP
8785
6b785fd8
GS
8786AT_SETUP([ovn -- /32 router IP address])
8787AT_SKIP_IF([test $HAVE_PYTHON = no])
8788ovn_start
8789
8790# Logical network:
8791# 2 LS 'foo' and 'alice' connected via router R1.
8792# R1 connects to 'alice' with a /32 IP address. We use static routes and
8793# nexthop to push traffic to a logical port in switch 'alice'
8794
8795ovn-nbctl lr-add R1
8796
8797ovn-nbctl ls-add foo
8798ovn-nbctl ls-add alice
8799
8800# Connect foo to R1
8801ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
8802ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
8803 options:router-port=foo addresses=\"00:00:00:01:02:03\"
8804
8805# Connect alice to R1.
8806ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 172.16.1.1/32
8807ovn-nbctl lsp-add alice rp-alice -- set Logical_Switch_Port rp-alice \
8808 type=router options:router-port=alice addresses=\"00:00:00:01:02:04\"
8809
8810# Create logical port foo1 in foo
8811ovn-nbctl lsp-add foo foo1 \
8812-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2"
8813
8814# Create logical port alice1 in alice
8815ovn-nbctl lsp-add alice alice1 \
8816-- lsp-set-addresses alice1 "f0:00:00:01:02:04 10.0.0.2"
8817
8818#install default route in R1 to use alice1's IP address as nexthop
8819ovn-nbctl lr-route-add R1 0.0.0.0/0 10.0.0.2 alice
8820
8821# Create two hypervisor and create OVS ports corresponding to logical ports.
8822net_add n1
8823
8824sim_add hv1
8825as hv1
8826ovs-vsctl add-br br-phys
8827ovn_attach n1 br-phys 192.168.0.1
8828ovs-vsctl -- add-port br-int hv1-vif1 -- \
8829 set interface hv1-vif1 external-ids:iface-id=foo1 \
8830 options:tx_pcap=hv1/vif1-tx.pcap \
8831 options:rxq_pcap=hv1/vif1-rx.pcap \
8832 ofport-request=1
8833
8834sim_add hv2
8835as hv2
8836ovs-vsctl add-br br-phys
8837ovn_attach n1 br-phys 192.168.0.2
8838ovs-vsctl -- add-port br-int hv2-vif1 -- \
8839 set interface hv2-vif1 external-ids:iface-id=alice1 \
8840 options:tx_pcap=hv2/vif1-tx.pcap \
8841 options:rxq_pcap=hv2/vif1-rx.pcap \
8842 ofport-request=1
8843
8844
8845# Pre-populate the hypervisors' ARP tables so that we don't lose any
8846# packets for ARP resolution (native tunneling doesn't queue packets
8847# for ARP resolution).
74868f2c 8848OVN_POPULATE_ARP
6b785fd8
GS
8849
8850# Allow some time for ovn-northd and ovn-controller to catch up.
8851# XXX This should be more systematic.
8852sleep 1
8853
8854ip_to_hex() {
8855 printf "%02x%02x%02x%02x" "$@"
8856}
8857
8858# Send ip packets between foo1 and alice1
8859src_mac="f00000010203"
8860dst_mac="000000010203"
8861src_ip=`ip_to_hex 192 168 1 2`
8862dst_ip=`ip_to_hex 10 0 0 2`
8863packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
8864
8865# Send the first packet to trigger a ARP response and population of
8866# mac_bindings table.
8867as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8868OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="10.0.0.2" | wc -l` -gt 0])
b0b27a83 8869ovn-nbctl --wait=hv sync
6b785fd8
GS
8870# Send the second packet to reach the destination.
8871as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
8872
8873# Packet to Expect at 'alice1'
8874src_mac="000000010204"
8875dst_mac="f00000010204"
8876src_ip=`ip_to_hex 192 168 1 2`
8877dst_ip=`ip_to_hex 10 0 0 2`
8878echo "${dst_mac}${src_mac}08004500001c000000003f110100${src_ip}${dst_ip}0035111100080000" > expected
8879
8880OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
8881
8882OVN_CLEANUP([hv1],[hv2])
8883
8884AT_CLEANUP
2a38ef45
DA
8885
8886AT_SETUP([ovn -- 2 HVs, 1 lport/HV, localport ports])
8887AT_SKIP_IF([test $HAVE_PYTHON = no])
8888ovn_start
8889
8890ovn-nbctl ls-add ls1
8891
8892# Add localport to the switch
8893ovn-nbctl lsp-add ls1 lp01
8894ovn-nbctl lsp-set-addresses lp01 f0:00:00:00:00:01
8895ovn-nbctl lsp-set-type lp01 localport
8896
8897net_add n1
8898
8899for i in 1 2; do
8900 sim_add hv$i
8901 as hv$i
8902 ovs-vsctl add-br br-phys
8903 ovn_attach n1 br-phys 192.168.0.$i
8904 ovs-vsctl add-port br-int vif01 -- \
8905 set Interface vif01 external-ids:iface-id=lp01 \
8906 options:tx_pcap=hv${i}/vif01-tx.pcap \
8907 options:rxq_pcap=hv${i}/vif01-rx.pcap \
8908 ofport-request=${i}0
8909
8910 ovs-vsctl add-port br-int vif${i}1 -- \
8911 set Interface vif${i}1 external-ids:iface-id=lp${i}1 \
8912 options:tx_pcap=hv${i}/vif${i}1-tx.pcap \
8913 options:rxq_pcap=hv${i}/vif${i}1-rx.pcap \
8914 ofport-request=${i}1
8915
8916 ovn-nbctl lsp-add ls1 lp${i}1
8917 ovn-nbctl lsp-set-addresses lp${i}1 f0:00:00:00:00:${i}1
8918 ovn-nbctl lsp-set-port-security lp${i}1 f0:00:00:00:00:${i}1
8919
8920 OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up lp${i}1` = xup])
8921done
8922
8923ovn-nbctl --wait=sb sync
8924ovn-sbctl dump-flows
8925
74868f2c 8926OVN_POPULATE_ARP
2a38ef45
DA
8927
8928# Given the name of a logical port, prints the name of the hypervisor
8929# on which it is located.
8930vif_to_hv() {
8931 echo hv${1%?}
8932}
8933#
8934# test_packet INPORT DST SRC ETHTYPE EOUT LOUT DEFHV
8935#
8936# This shell function causes a packet to be received on INPORT. The packet's
8937# content has Ethernet destination DST and source SRC (each exactly 12 hex
8938# digits) and Ethernet type ETHTYPE (4 hex digits). INPORT is specified as
8939# logical switch port numbers, e.g. 11 for vif11.
8940#
8941# EOUT is the end-to-end output port, that is, where the packet will end up
8942# after possibly bouncing through one or more localnet ports. LOUT is the
8943# logical output port, which might be a localnet port, as seen by ovn-trace
8944# (which doesn't know what localnet ports are connected to and therefore can't
8945# figure out the end-to-end answer).
8946#
8947# DEFHV is the default hypervisor from where the packet is going to be sent
8948# if the source port is a localport.
8949for i in 1 2; do
8950 for j in 0 1; do
8951 : > $i$j.expected
8952 done
8953done
8954test_packet() {
8955 local inport=$1 dst=$2 src=$3 eth=$4 eout=$5 lout=$6 defhv=$7
8956 echo "$@"
8957
8958 # First try tracing the packet.
8959 uflow="inport==\"lp$inport\" && eth.dst==$dst && eth.src==$src && eth.type==0x$eth"
8960 if test $lout != drop; then
8961 echo "output(\"$lout\");"
8962 fi > expout
8963 AT_CAPTURE_FILE([trace])
8964 AT_CHECK([ovn-trace --all ls1 "$uflow" | tee trace | sed '1,/Minimal trace/d'], [0], [expout])
8965
8966 # Then actually send a packet, for an end-to-end test.
8967 local packet=$(echo $dst$src | sed 's/://g')${eth}
8968 hv=`vif_to_hv $inport`
8969 # If hypervisor 0 (localport) use the defhv parameter
da88b550 8970 if test $hv = hv0; then
2a38ef45
DA
8971 hv=$defhv
8972 fi
8973 vif=vif$inport
8974 as $hv ovs-appctl netdev-dummy/receive $vif $packet
8975 if test $eout != drop; then
8976 echo $packet >> ${eout#lp}.expected
8977 fi
8978}
8979
8980
8981# lp11 and lp21 are on different hypervisors
8982test_packet 11 f0:00:00:00:00:21 f0:00:00:00:00:11 1121 lp21 lp21
8983test_packet 21 f0:00:00:00:00:11 f0:00:00:00:00:21 2111 lp11 lp11
8984
8985# Both VIFs should be able to reach the localport on their own HV
8986test_packet 11 f0:00:00:00:00:01 f0:00:00:00:00:11 1101 lp01 lp01
8987test_packet 21 f0:00:00:00:00:01 f0:00:00:00:00:21 2101 lp01 lp01
8988
8989# Packet sent from localport on same hv should reach the vif
8990test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 lp11 lp11 hv1
8991test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 lp21 lp21 hv2
8992
8993# Packet sent from localport on different hv should be dropped
8994test_packet 01 f0:00:00:00:00:21 f0:00:00:00:00:01 0121 drop lp21 hv1
8995test_packet 01 f0:00:00:00:00:11 f0:00:00:00:00:01 0111 drop lp11 hv2
8996
8997# Now check the packets actually received against the ones expected.
8998for i in 1 2; do
8999 for j in 0 1; do
9000 OVN_CHECK_PACKETS([hv$i/vif$i$j-tx.pcap], [$i$j.expected])
9001 done
9002done
9003
9004OVN_CLEANUP([hv1],[hv2])
9005
9006AT_CLEANUP
1da17a0b 9007
9008AT_SETUP([ovn -- 1 LR with HA distributed router gateway port])
9009AT_SKIP_IF([test $HAVE_PYTHON = no])
9010ovn_start
9011
9012net_add n1
9013
9014# create gateways with external network connectivity
9015
9016for i in 1 2; do
9017 sim_add gw$i
9018 as gw$i
9019 ovs-vsctl add-br br-phys
9020 ovn_attach n1 br-phys 192.168.0.$i
9021 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9022done
9023
9024ovn-nbctl ls-add inside
9025ovn-nbctl ls-add outside
9026
9027# create hypervisors with a vif port each to an internal network
9028
9029for i in 1 2; do
9030 sim_add hv$i
9031 as hv$i
9032 ovs-vsctl add-br br-phys
9033 ovn_attach n1 br-phys 192.168.0.1$i
9034 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9035 set interface hv$i-vif1 external-ids:iface-id=inside$i \
9036 options:tx_pcap=hv$i/vif1-tx.pcap \
9037 options:rxq_pcap=hv$i/vif1-rx.pcap \
9038 ofport-request=1
9039
9040 ovn-nbctl lsp-add inside inside$i \
9041 -- lsp-set-addresses inside$i "f0:00:00:01:22:$i 192.168.1.10$i"
9042
9043done
9044
74868f2c 9045OVN_POPULATE_ARP
1da17a0b 9046
9047ovn-nbctl create Logical_Router name=R1
9048
9049# Connect inside to R1
9050ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9051ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9052 type=router options:router-port=inside \
9053 -- lsp-set-addresses rp-inside router
9054
9055# Connect outside to R1 as distributed router gateway port on gw1+gw2
9056ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9057
9058ovn-nbctl --id=@gc0 create Gateway_Chassis \
9059 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9060 --id=@gc1 create Gateway_Chassis \
9061 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9062 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9063
9064ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9065 type=router options:router-port=outside \
9066 -- lsp-set-addresses rp-outside router
9067
9068# Create localnet port in outside
9069ovn-nbctl lsp-add outside ln-outside
9070ovn-nbctl lsp-set-addresses ln-outside unknown
9071ovn-nbctl lsp-set-type ln-outside localnet
9072ovn-nbctl lsp-set-options ln-outside network_name=phys
9073
9074# Allow some time for ovn-northd and ovn-controller to catch up.
9075# XXX This should be more systematic.
8e1d9349 9076ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 9077
9078echo "---------NB dump-----"
9079ovn-nbctl show
9080echo "---------------------"
9081ovn-nbctl list logical_router
9082echo "---------------------"
9083ovn-nbctl list logical_router_port
9084echo "---------------------"
9085
9086echo "---------SB dump-----"
9087ovn-sbctl list datapath_binding
9088echo "---------------------"
9089ovn-sbctl list port_binding
9090echo "---------------------"
9091ovn-sbctl dump-flows
9092echo "---------------------"
9093ovn-sbctl list chassis
9094ovn-sbctl list encap
9095echo "---------------------"
9096echo "------ Gateway_Chassis dump (SBDB) -------"
9097ovn-sbctl list Gateway_Chassis
9098echo "------ Port_Binding chassisredirect -------"
9099ovn-sbctl find Port_Binding type=chassisredirect
9100echo "-------------------------------------------"
9101
3475695e
VA
9102for chassis in gw1 gw2 hv1 hv2; do
9103 as $chassis
9104 echo "------ $chassis dump ----------"
9105 ovs-ofctl show br-int
9106 ovs-ofctl dump-flows br-int
3475695e
VA
9107 echo "--------------------------"
9108done
508b7f96 9109function bfd_dump() {
9110 for chassis in gw1 gw2 hv1 hv2; do
9111 as $chassis
9112 echo "------ $chassis dump (BFD)----"
9113 echo "BFD (from $chassis):"
9114 # dump BFD config and status to the other chassis
9115 for chassis2 in gw1 gw2 hv1 hv2; do
9116 if [[ "$chassis" != "$chassis2" ]]; then
9117 echo " -> $chassis2:"
9118 echo " $(ovs-vsctl --bare --columns bfd,bfd_status find Interface name=ovn-$chassis2-0)"
9119 fi
9120 done
9121 echo "--------------------------"
9122 done
9123}
9124
9125bfd_dump
1da17a0b 9126
9127hv1_gw1_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9128hv1_gw2_ofport=$(as hv1 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9129hv2_gw1_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw1-0)
9130hv2_gw2_ofport=$(as hv2 ovs-vsctl --bare --columns ofport find Interface name=ovn-gw2-0)
9131
9132echo $hv1_gw1_ofport
9133echo $hv1_gw2_ofport
9134echo $hv2_gw1_ofport
9135echo $hv2_gw2_ofport
9136
9137echo "--- hv1 ---"
9138as hv1 ovs-ofctl dump-flows br-int table=32
9139
9140echo "--- hv2 ---"
9141as hv2 ovs-ofctl dump-flows br-int table=32
9142
508b7f96 9143gw1_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw1)
9144gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9145
1da17a0b 9146AT_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
9147])
9148
9149AT_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
9150])
9151
508b7f96 9152sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9153
9154# make sure that flows for handling the outside router port reside on gw1
66d89287 9155AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9156]])
66d89287 9157AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9158]])
9159
9160# make sure ARP responder flows for outside router port reside on gw1 too
9161AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[1
9162]])
9163AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=9 | grep arp_tpa=192.168.0.101 | wc -l], [0], [[0
9164]])
9165
9166
9167
9168# check that the chassis redirect port has been claimed by the gw1 chassis
9169AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9170 [0],[[1
9171]])
9172
9173
9174# at this point, we invert the priority of the gw chassis between gw1 and gw2
1da17a0b 9175
9176ovn-nbctl --id=@gc0 create Gateway_Chassis \
9177 name=outside_gw1 chassis_name=gw1 priority=10 -- \
9178 --id=@gc1 create Gateway_Chassis \
9179 name=outside_gw2 chassis_name=gw2 priority=20 -- \
9180 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9181
508b7f96 9182
1da17a0b 9183# XXX: Let the change propagate down to the ovn-controllers
8e1d9349 9184ovn-nbctl --wait=hv --timeout=3 sync
1da17a0b 9185
508b7f96 9186# we make sure that the hypervisors noticed, and inverted the slave ports
1da17a0b 9187AT_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
9188])
9189
9190AT_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
9191])
9192
508b7f96 9193# check that the chassis redirect port has been reclaimed by the gw2 chassis
9194AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw2_chassis | wc -l],
9195 [0],[[1
9196]])
1da17a0b 9197
3475695e
VA
9198# check BFD enablement on tunnel ports from gw1 #########
9199as gw1
9200for chassis in gw2 hv1 hv2; do
9201 echo "checking gw1 -> $chassis"
9202 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9203 [[enable=true
9204]])
9205done
9206
9207
9208# check BFD enablement on tunnel ports from gw2 ##########
9209as gw2
9210for chassis in gw1 hv1 hv2; do
9211 echo "checking gw2 -> $chassis"
9212 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9213 [[enable=true
9214]])
9215done
9216
9217# check BFD enablement on tunnel ports from hv1 ###########
9218as hv1
9219for chassis in gw1 gw2; do
9220 echo "checking hv1 -> $chassis"
9221 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9222 [[enable=true
9223]])
9224done
9225# make sure BFD is not enabled to hv2, we don't need it
9226AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv2-0],[0],
9227 [[enable=false
9228]])
9229
9230
9231# check BFD enablement on tunnel ports from hv2 ##########
9232as hv2
9233for chassis in gw1 gw2; do
9234 echo "checking hv2 -> $chassis"
9235 AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-$chassis-0],[0],
9236 [[enable=true
9237]])
9238done
9239# make sure BFD is not enabled to hv1, we don't need it
9240AT_CHECK([ovs-vsctl --bare --columns bfd find Interface name=ovn-hv1-0],[0],
9241 [[enable=false
9242]])
9243
508b7f96 9244sleep 3 # let BFD sessions settle so we get the right flows on the right chassis
9245
9246# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9247AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9248]])
66d89287 9249AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9250]])
9251
9252# disconnect GW2 from the network, GW1 should take over
9253as gw2
9254port=${sandbox}_br-phys
9255as main ovs-vsctl del-port n1 $port
9256sleep 4
9257
9258bfd_dump
9259
9260# make sure that flows for handling the outside router port reside on gw2 now
66d89287 9261AT_CHECK([as gw1 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[1
508b7f96 9262]])
66d89287 9263AT_CHECK([as gw2 ovs-ofctl dump-flows br-int table=24 | grep 00:00:02:01:02:04 | wc -l], [0], [[0
508b7f96 9264]])
9265
9266# check that the chassis redirect port has been reclaimed by the gw1 chassis
9267AT_CHECK([ovn-sbctl --columns chassis --bare find Port_Binding logical_port=cr-outside | grep $gw1_chassis | wc -l],
9268 [0],[[1
9269]])
9270
1da17a0b 9271OVN_CLEANUP([gw1],[gw2],[hv1],[hv2])
9272
9273AT_CLEANUP
acfc41ff
VAK
9274
9275AT_SETUP([ovn -- send gratuitous ARP for NAT rules on HA distributed router])
9276AT_SKIP_IF([test $HAVE_PYTHON = no])
9277ovn_start
9278ovn-nbctl ls-add ls0
9279ovn-nbctl ls-add ls1
9280ovn-nbctl create Logical_Router name=lr0
9281ovn-nbctl lrp-add lr0 lrp0 f0:00:00:00:00:01 192.168.0.100/24
9282
9283ovn-nbctl --id=@gc0 create Gateway_Chassis \
9284 name=outside_gw1 chassis_name=hv2 priority=10 -- \
9285 --id=@gc1 create Gateway_Chassis \
9286 name=outside_gw2 chassis_name=hv3 priority=1 -- \
9287 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9288
9289ovn-nbctl lsp-add ls0 lrp0-rp -- set Logical_Switch_Port lrp0-rp \
9290 type=router options:router-port=lrp0 addresses="router"
9291ovn-nbctl lrp-add lr0 lrp1 f0:00:00:00:00:02 10.0.0.1/24
9292ovn-nbctl lsp-add ls1 lrp1-rp -- set Logical_Switch_Port lrp1-rp \
9293 type=router options:router-port=lrp1 addresses="router"
9294
9295# Add NAT rules
9296AT_CHECK([ovn-nbctl lr-nat-add lr0 snat 192.168.0.100 10.0.0.0/24])
9297
9298net_add n1
9299sim_add hv1
9300as hv1
9301ovs-vsctl add-br br-phys
9302ovn_attach n1 br-phys 192.168.0.1
9303AT_CHECK([ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9304AT_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])
9305
9306sim_add hv2
9307as hv2
9308ovs-vsctl add-br br-phys
9309ovn_attach n1 br-phys 192.168.0.2
9310AT_CHECK([as hv2 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9311
9312sim_add hv3
9313as hv3
9314ovs-vsctl add-br br-phys
9315ovn_attach n1 br-phys 192.168.0.3
9316AT_CHECK([as hv3 ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-mappings=physnet1:br-phys])
9317
9318# Create a localnet port.
9319AT_CHECK([ovn-nbctl lsp-add ls0 ln_port])
9320AT_CHECK([ovn-nbctl lsp-set-addresses ln_port unknown])
9321AT_CHECK([ovn-nbctl lsp-set-type ln_port localnet])
9322AT_CHECK([ovn-nbctl lsp-set-options ln_port network_name=physnet1])
9323
9324# wait for earlier changes to take effect
6c8d3d69 9325AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
acfc41ff
VAK
9326
9327reset_pcap_file() {
9328 local iface=$1
9329 local pcap_file=$2
9330 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9331options:rxq_pcap=dummy-rx.pcap
9332 rm -f ${pcap_file}*.pcap
9333 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9334options:rxq_pcap=${pcap_file}-rx.pcap
9335}
9336
9337as hv1 reset_pcap_file snoopvif hv1/snoopvif
9338as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9339as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9340# add nat-addresses option
6c8d3d69 9341ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
acfc41ff
VAK
9342
9343# Wait for packets to be received through hv2.
9344OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9345trim_zeros() {
9346 sed 's/\(00\)\{1,\}$//'
9347}
9348
2db7bb2c 9349only_broadcast_from_lrp1() {
9350 grep "fffffffffffff00000000001"
9351}
9352
acfc41ff 9353garp="fffffffffffff0000000000108060001080006040001f00000000001c0a80064000000000000c0a80064"
2db7bb2c 9354echo $garp > expout
9355
9356$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoop_tx
acfc41ff
VAK
9357echo "packets on hv1-snoopvif:"
9358cat hv1_snoop_tx
9359AT_CHECK([sort hv1_snoop_tx], [0], [expout])
2db7bb2c 9360$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
9361echo "packets on hv2 br-phys tx"
9362cat hv2_br_phys_tx
9363AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [expout])
2db7bb2c 9364$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
9365echo "packets on hv3 br-phys tx"
9366cat hv3_br_phys_tx
9367AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [])
9368
9369
9370# at this point, we invert the priority of the gw chassis between hv2 and hv3
9371
9372ovn-nbctl --wait=hv \
9373 --id=@gc0 create Gateway_Chassis \
9374 name=outside_gw1 chassis_name=hv2 priority=1 -- \
9375 --id=@gc1 create Gateway_Chassis \
9376 name=outside_gw2 chassis_name=hv3 priority=10 -- \
9377 set Logical_Router_Port lrp0 'gateway_chassis=[@gc0,@gc1]'
9378
9379
9380as hv1 reset_pcap_file snoopvif hv1/snoopvif
9381as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9382as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9383
9384# Wait for packets to be received.
9385OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9386trim_zeros() {
9387 sed 's/\(00\)\{1,\}$//'
9388}
9389
2db7bb2c 9390$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
acfc41ff 9391AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
2db7bb2c 9392$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 9393AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
2db7bb2c 9394$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 9395AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
03b85a58
GL
9396
9397# change localnet port tag.
9398AT_CHECK([ovn-nbctl set Logical_Switch_Port ln_port tag=2014])
9399
9400# wait for earlier changes to take effect
6c8d3d69 9401AT_CHECK([ovn-nbctl --timeout=3 --wait=hv sync], [0], [ignore])
03b85a58
GL
9402
9403# update nat-addresses option
6c8d3d69
HZ
9404ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0
9405ovn-nbctl --wait=hv lsp-set-options lrp0-rp router-port=lrp0 nat-addresses="router"
03b85a58
GL
9406
9407as hv1 reset_pcap_file snoopvif hv1/snoopvif
9408as hv2 reset_pcap_file br-phys_n1 hv2/br-phys_n1
9409as hv3 reset_pcap_file br-phys_n1 hv3/br-phys_n1
9410
9411# Wait for packets to be received.
9412OVS_WAIT_UNTIL([test `wc -c < "hv1/snoopvif-tx.pcap"` -ge 100])
9413trim_zeros() {
9414 sed 's/\(00\)\{1,\}$//'
9415}
9416
9417garp="fffffffffffff00000000001810007de08060001080006040001f00000000001c0a80064000000000000c0a80064"
9418echo $garp > expout
9419
9420$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/snoopvif-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv1_snoopvif_tx
9421AT_CHECK([sort hv1_snoopvif_tx], [0], [expout])
9422$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv3/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv3_br_phys_tx
9423AT_CHECK([grep $garp hv3_br_phys_tx | sort], [0], [expout])
9424$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv2/br-phys_n1-tx.pcap | trim_zeros | only_broadcast_from_lrp1 | uniq > hv2_br_phys_tx
9425AT_CHECK([grep $garp hv2_br_phys_tx | sort], [0], [])
9426
acfc41ff
VAK
9427OVN_CLEANUP([hv1],[hv2],[hv3])
9428
9429AT_CLEANUP
79371ff5 9430
9431AT_SETUP([ovn -- ensure one gw controller restart in HA doesn't bounce the master])
9432AT_SKIP_IF([test $HAVE_PYTHON = no])
9433ovn_start
9434
9435net_add n1
9436
9437# create two gateways with external network connectivity
9438for i in 1 2; do
9439 sim_add gw$i
9440 as gw$i
9441 ovs-vsctl add-br br-phys
9442 ovn_attach n1 br-phys 192.168.0.$i
9443 ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9444done
9445
9446ovn-nbctl ls-add inside
9447ovn-nbctl ls-add outside
9448
9449# create one hypervisors with a vif port the internal network
9450sim_add hv1
9451as hv1
9452ovs-vsctl add-br br-phys
9453ovn_attach n1 br-phys 192.168.0.11
9454ovs-vsctl -- add-port br-int hv1-vif1 -- \
9455 set interface hv1-vif1 external-ids:iface-id=inside1 \
9456 options:tx_pcap=hv1/vif1-tx.pcap \
9457 options:rxq_pcap=hv1/vif1-rx.pcap \
9458 ofport-request=1
9459
9460ovn-nbctl lsp-add inside inside1 \
9461 -- lsp-set-addresses inside1 "f0:00:00:01:22:01 192.168.1.101"
9462
9463
74868f2c 9464OVN_POPULATE_ARP
79371ff5 9465
9466ovn-nbctl create Logical_Router name=R1
9467
9468# Connect inside to R1
9469ovn-nbctl lrp-add R1 inside 00:00:01:01:02:03 192.168.1.1/24
9470ovn-nbctl lsp-add inside rp-inside -- set Logical_Switch_Port rp-inside \
9471 type=router options:router-port=inside \
9472 -- lsp-set-addresses rp-inside router
9473
9474# Connect outside to R1 as distributed router gateway port on gw1+gw2
9475ovn-nbctl lrp-add R1 outside 00:00:02:01:02:04 192.168.0.101/24
9476
9477ovn-nbctl --id=@gc0 create Gateway_Chassis \
9478 name=outside_gw1 chassis_name=gw1 priority=20 -- \
9479 --id=@gc1 create Gateway_Chassis \
9480 name=outside_gw2 chassis_name=gw2 priority=10 -- \
9481 set Logical_Router_Port outside 'gateway_chassis=[@gc0,@gc1]'
9482
9483ovn-nbctl lsp-add outside rp-outside -- set Logical_Switch_Port rp-outside \
9484 type=router options:router-port=outside \
9485 -- lsp-set-addresses rp-outside router
9486
9487# Create localnet port in outside
9488ovn-nbctl lsp-add outside ln-outside
9489ovn-nbctl lsp-set-addresses ln-outside unknown
9490ovn-nbctl lsp-set-type ln-outside localnet
9491ovn-nbctl lsp-set-options ln-outside network_name=phys
9492
9493# Allow some time for ovn-northd and ovn-controller to catch up.
8e1d9349 9494ovn-nbctl --wait=hv --timeout=3 sync
79371ff5 9495
9496# currently when ovn-controller is restarted, the old entry is deleted
9497# and a new one is created, which leaves the Gateway_Chassis with
9498# an empty chassis for a while. NOTE: restarting ovn-controller in tests
9499# doesn't have the same effect because "name" is conserved, and the
9500# Chassis entry is not replaced.
9501
3a0c5805 9502> gw1/ovn-controller.log
325b2b1a 9503
79371ff5 9504gw2_chassis=$(ovn-sbctl --bare --columns=_uuid find Chassis name=gw2)
9505ovn-sbctl destroy Chassis $gw2_chassis
9506
9507# Ensure ovn-controller has processed latest sbdb update
9508# ovn-nbctl --wait=hv sync
9509
9510AT_CHECK([grep "Releasing lport" gw1/ovn-controller.log], [1], [])
9511
9512OVN_CLEANUP([gw1],[gw2],[hv1])
9513
9514AT_CLEANUP
63d91afa 9515
b1a3a6a4
NS
9516AT_SETUP([ovn -- IPv6 Neighbor Solicitation for unknown MAC])
9517AT_KEYWORDS([ovn-nd_ns for unknown mac])
9518AT_SKIP_IF([test $HAVE_PYTHON = no])
9519ovn_start
9520
9521ovn-nbctl ls-add sw0_ip6
9522ovn-nbctl lsp-add sw0_ip6 sw0_ip6-port1
9523ovn-nbctl lsp-set-addresses sw0_ip6-port1 \
9524"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9525
9526ovn-nbctl lsp-set-port-security sw0_ip6-port1 \
9527"50:64:00:00:00:02 aef0::5264:00ff:fe00:0002"
9528
9529ovn-nbctl lr-add lr0_ip6
847dc1c2 9530ovn-nbctl lrp-add lr0_ip6 lrp0_ip6 00:00:00:00:af:01 aef0:0:0:0:0:0:0:0/64
b1a3a6a4
NS
9531ovn-nbctl lsp-add sw0_ip6 lrp0_ip6-attachment
9532ovn-nbctl lsp-set-type lrp0_ip6-attachment router
bec7c641 9533ovn-nbctl lsp-set-addresses lrp0_ip6-attachment router
b1a3a6a4
NS
9534ovn-nbctl lsp-set-options lrp0_ip6-attachment router-port=lrp0_ip6
9535ovn-nbctl set logical_router_port lrp0_ip6 ipv6_ra_configs:address_mode=slaac
9536
9537ovn-nbctl ls-add public
9538ovn-nbctl lsp-add public ln-public
9539ovn-nbctl lsp-set-addresses ln-public unknown
9540ovn-nbctl lsp-set-type ln-public localnet
9541ovn-nbctl lsp-set-options ln-public network_name=phys
9542
9543ovn-nbctl lrp-add lr0_ip6 ip6_public 00:00:02:01:02:04 \
95442001:db8:1:0:200:02ff:fe01:0204/64 \
9545-- set Logical_Router_port ip6_public options:redirect-chassis="hv1"
9546
9547
9548ovn-nbctl lsp-add public rp-ip6_public -- set Logical_Switch_Port \
9549rp-ip6_public type=router options:router-port=ip6_public \
9550-- lsp-set-addresses rp-ip6_public router
9551
9552net_add n1
9553sim_add hv1
9554as hv1
9555ovs-vsctl add-br br-phys
9556ovn_attach n1 br-phys 192.168.0.2
9557
9558ovs-vsctl -- add-port br-int hv1-vif1 -- \
9559 set interface hv1-vif1 external-ids:iface-id=sw0_ip6-port1 \
9560 options:tx_pcap=hv1/vif1-tx.pcap \
9561 options:rxq_pcap=hv1/vif1-rx.pcap \
9562 ofport-request=1
9563ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
9564
86c9d79a 9565OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw0_ip6-port1` = xup])
bec7c641
NS
9566
9567# There should be 2 Neighbor Advertisement flows for the router port
9568# aef0:: ip address in logical switch pipeline with action nd_na_router.
9569AT_CHECK([ovn-sbctl dump-flows sw0_ip6 | grep ls_in_arp_rsp | \
9570grep "nd_na_router" | wc -l], [0], [2
9571])
9572
9573# There should be 4 Neighbor Advertisement flows with action nd_na_router
9574# in the router pipeline for the router lr0_ip6.
9575AT_CHECK([ovn-sbctl dump-flows lr0_ip6 | grep nd_na_router | \
9576wc -l], [0], [4
9577])
9578
86c9d79a
NS
9579cr_uuid=`ovn-sbctl find port_binding logical_port=cr-ip6_public | grep _uuid | cut -f2 -d ":"`
9580
9581# There is only one chassis.
9582chassis_uuid=`ovn-sbctl list chassis | grep _uuid | cut -f2 -d ":"`
9583OVS_WAIT_UNTIL([test $chassis_uuid = `ovn-sbctl get port_binding $cr_uuid chassis`])
b1a3a6a4
NS
9584
9585trim_zeros() {
9586 sed 's/\(00\)\{1,\}$//'
9587}
9588
9589# Test the IPv6 Neighbor Solicitation (NS) - nd_ns action for unknown MAC
9590# addresses. ovn-controller should generate an IPv6 NS request for IPv6
9591# packets whose MAC is unknown (in the ARP_REQUEST router pipeline stage.
9592# test_ipv6 INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
9593# This function sends ipv6 packet
9594test_ipv6() {
9595 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4
9596 dst_ip=20010db800010000020002fffe010205
9597
9598 local packet=${dst_mac}${src_mac}86dd6000000000083aff${src_ip}${dst_ip}
9599 packet=${packet}8000000000000000
9600 shift; shift; shift; shift
9601
9602 dst_mac=3333ff010205
9603 src_mac=000002010204
9604 mcast_node_ip=ff0200000000000000000001ff010205
9605 expected_packet=${dst_mac}${src_mac}86dd6000000000203aff${src_ip}
9606 expected_packet=${expected_packet}${mcast_node_ip}8700XXXX00000000${dst_ip}
9607 expected_packet=${expected_packet}0101${src_mac}
9608
9609 as hv1 ovs-appctl netdev-dummy/receive hv1-vif${inport} $packet
9610 echo $expected_packet >> ipv6_ns.expected
9611}
9612
9613src_mac=506400000002
9614dst_mac=00000000af01
9615src_ip=aef0000000000000526400fffe000002
9616# Send an IPv6 packet. Generated IPv6 Neighbor solicitation packet
9617# should be received by the ports attached to br-phys.
9618test_ipv6 1 $src_mac $dst_mac $src_ip 2
9619
86c9d79a
NS
9620OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys_n1-tx.pcap | cut -d " " -f1)])
9621OVS_WAIT_WHILE([test 24 = $(wc -c hv1/br-phys-tx.pcap | cut -d " " -f1)])
9622
b1a3a6a4
NS
9623$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys_n1-tx.pcap | \
9624trim_zeros > 1.packets
9625$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/br-phys-tx.pcap | \
9626trim_zeros > 2.packets
9627
9628cat ipv6_ns.expected | cut -c -112 > expout
9629AT_CHECK([cat 1.packets | cut -c -112], [0], [expout])
9630AT_CHECK([cat 2.packets | cut -c -112], [0], [expout])
9631
9632# Skipping the ICMPv6 checksum
9633cat ipv6_ns.expected | cut -c 117- > expout
9634AT_CHECK([cat 1.packets | cut -c 117-], [0], [expout])
9635AT_CHECK([cat 2.packets | cut -c 117-], [0], [expout])
9636
9637OVN_CLEANUP([hv1])
9638
9639AT_CLEANUP
9640
63d91afa
LR
9641AT_SETUP([ovn -- options:requested-chassis for logical port])
9642ovn_start
9643
9644net_add n1
9645
9646ovn-nbctl ls-add ls0
9647ovn-nbctl lsp-add ls0 lsp0
9648
9649# create two hypervisors, each with one vif port
9650sim_add hv1
9651as hv1
9652ovs-vsctl add-br br-phys
9653ovn_attach n1 br-phys 192.168.0.11
99cc5c92
NS
9654ovs-vsctl -- add-port br-int hv1-vif0 -- \
9655set Interface hv1-vif0 ofport-request=1
63d91afa
LR
9656
9657sim_add hv2
9658as hv2
9659ovs-vsctl add-br br-phys
9660ovn_attach n1 br-phys 192.168.0.12
99cc5c92
NS
9661ovs-vsctl -- add-port br-int hv2-vif0 -- \
9662set Interface hv2-vif0 ofport-request=1
63d91afa
LR
9663
9664# Allow only chassis hv1 to bind logical port lsp0.
9665ovn-nbctl lsp-set-options lsp0 requested-chassis=hv1
9666
9667# Allow some time for ovn-northd and ovn-controller to catch up.
9668ovn-nbctl --wait=hv --timeout=3 sync
9669
9670# Retrieve hv1 and hv2 chassis UUIDs from southbound database
2aa57f08
HZ
9671ovn-sbctl wait-until chassis hv1
9672ovn-sbctl wait-until chassis hv2
63d91afa
LR
9673hv1_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv1)
9674hv2_uuid=$(ovn-sbctl --bare --columns _uuid find chassis name=hv2)
9675
9676# (1) Chassis hv2 should not bind lsp0 when requested-chassis is hv1.
9677echo "verifying that hv2 does not bind lsp0 when hv2 physical/logical mapping is added"
9678as hv2
9679ovs-vsctl set interface hv2-vif0 external-ids:iface-id=lsp0
9680
9681OVS_WAIT_UNTIL([test 1 = $(grep -c "Not claiming lport lsp0" hv2/ovn-controller.log)])
9682AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
9683
99cc5c92
NS
9684# (2) Chassis hv2 should not add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9685AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9686AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9687
9688# (3) Chassis hv1 should bind lsp0 when physical to logical mapping exists on hv1.
63d91afa
LR
9689echo "verifying that hv1 binds lsp0 when hv1 physical/logical mapping is added"
9690as hv1
9691ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9692
9693OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
2aa57f08 9694AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
63d91afa 9695
99cc5c92
NS
9696# (4) Chassis hv1 should add flows in OFTABLE_PHY_TO_LOG and OFTABLE_LOG_TO_PHY tables.
9697as hv1 ovs-ofctl dump-flows br-int
9698AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9699AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9700
9701# (5) Chassis hv1 should release lsp0 binding and chassis hv2 should bind lsp0 when
63d91afa
LR
9702# the requested chassis for lsp0 is changed from hv1 to hv2.
9703echo "verifying that lsp0 binding moves when requested-chassis is changed"
9704
9705ovn-nbctl lsp-set-options lsp0 requested-chassis=hv2
9706OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
2aa57f08 9707OVS_WAIT_UNTIL([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv2_uuid"])
63d91afa 9708
99cc5c92
NS
9709# (6) Chassis hv2 should add flows and hv1 should not.
9710AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9711AT_CHECK([as hv2 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
9712
9713AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9714AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
9715
63d91afa
LR
9716OVN_CLEANUP([hv1],[hv2])
9717
9718AT_CLEANUP
bd32425f
RB
9719
9720AT_SETUP([ovn -- options:requested-chassis with hostname])
9721
9722ovn_start
9723
9724ovn-nbctl ls-add ls0
9725ovn-nbctl lsp-add ls0 lsp0
9726
9727net_add n1
9728sim_add hv1
9729as hv1
9730ovs-vsctl add-br br-phys
9731ovn_attach n1 br-phys 192.168.0.11
99cc5c92 9732ovs-vsctl -- add-port br-int hv1-vif0 -- set Interface hv1-vif0 ofport-request=1
bd32425f 9733
362ab40a 9734ovn-sbctl wait-until chassis hv1
bd32425f
RB
9735hv1_hostname=$(ovn-sbctl --bare --columns hostname find Chassis name=hv1)
9736echo "hv1_hostname=${hv1_hostname}"
9737ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=${hv1_hostname}
9738as hv1 ovs-vsctl set interface hv1-vif0 external-ids:iface-id=lsp0
9739
9740hv1_uuid=$(ovn-sbctl --bare --columns _uuid find Chassis name=hv1)
9741echo "hv1_uuid=${hv1_uuid}"
9742OVS_WAIT_UNTIL([test 1 = $(grep -c "Claiming lport lsp0" hv1/ovn-controller.log)])
9743AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x"$hv1_uuid"], [0], [])
99cc5c92
NS
9744AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [0], [ignore])
9745AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep actions=output:1], [0], [ignore])
bd32425f
RB
9746
9747ovn-nbctl --wait=hv --timeout=3 lsp-set-options lsp0 requested-chassis=non-existant-chassis
9748OVS_WAIT_UNTIL([test 1 = $(grep -c "Releasing lport lsp0 from this chassis" hv1/ovn-controller.log)])
9749ovn-nbctl --wait=hv --timeout=3 sync
9750AT_CHECK([test x$(ovn-sbctl --bare --columns chassis find port_binding logical_port=lsp0) = x], [0], [])
99cc5c92
NS
9751AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=0 | grep in_port=1], [1], [])
9752AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=65 | grep output], [1], [])
bd32425f
RB
9753
9754OVN_CLEANUP([hv1])
9755
9756AT_CLEANUP
4446661a
MM
9757
9758AT_SETUP([ovn -- IPv6 periodic RA])
9759ovn_start
9760
9761# This test sets up two hypervisors.
9762# hv1 and hv2 run ovn-controllers, and
9763# each has a VIF connected to the same
9764# logical switch in OVN. The logical
9765# switch is connected to a logical
9766# router port that is configured to send
9767# periodic router advertisements.
9768#
9769# The reason for having two ovn-controller
9770# hypervisors is to ensure that the
9771# periodic RAs being sent by each ovn-controller
9772# are kept to their local hypervisors. If the
9773# packets are not kept local, then each port
9774# will receive too many RAs.
9775
9776net_add n1
9777sim_add hv1
9778sim_add hv2
9779as hv1
9780ovs-vsctl add-br br-phys
9781ovn_attach n1 br-phys 192.168.0.2
9782as hv2
9783ovs-vsctl add-br br-phys
9784ovn_attach n1 br-phys 192.168.0.3
9785
9786ovn-nbctl lr-add ro
1ea1b0d0 9787ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64
4446661a
MM
9788
9789ovn-nbctl ls-add sw
9790ovn-nbctl lsp-add sw sw-ro
9791ovn-nbctl lsp-set-type sw-ro router
9792ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
9793ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
9794ovn-nbctl lsp-add sw sw-p1
9795ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
9796ovn-nbctl lsp-add sw sw-p2
9797ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"
9798
9799ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
9800ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
9801ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4
9802ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3
9803
86c9d79a
NS
9804for i in 1 2 ; do
9805 as hv$i
9806 ovs-vsctl -- add-port br-int hv$i-vif1 -- \
9807 set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
9808 options:tx_pcap=hv$i/vif1-tx.pcap \
9809 options:rxq_pcap=hv$i/vif1-rx.pcap \
4446661a
MM
9810 ofport-request=1
9811done
9812
86c9d79a
NS
9813OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup])
9814OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup])
4446661a
MM
9815
9816reset_pcap_file() {
9817 local iface=$1
9818 local pcap_file=$2
9819 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
9820options:rxq_pcap=dummy-rx.pcap
9821 rm -f ${pcap_file}*.pcap
9822 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
9823options:rxq_pcap=${pcap_file}-rx.pcap
9824
9825}
9826
9827construct_expected_ra() {
9828 local src_mac=000000000001
9829 local dst_mac=333300000001
9830 local src_addr=fe80000000000000020000fffe000001
9831 local dst_addr=ff020000000000000000000000000001
9832
9833 local mtu=$1
9834 local ra_mo=$2
9835 local ra_prefix_la=$3
9836
9837 local slla=0101${src_mac}
9838 local mtu_opt=""
9839 if test $mtu != 0; then
9840 mtu_opt=05010000${mtu}
9841 fi
9842 shift 3
9843
9844 local prefix=""
9845 while [[ $# -gt 0 ]] ; do
9846 local size=$1
9847 local net=$2
9848 prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
9849 shift 2
9850 done
9851
895ceaf7 9852 local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}
4446661a
MM
9853 local icmp=8600XXXX${ra}
9854
9855 local ip_len=$(expr ${#icmp} / 2)
1ea1b0d0 9856 ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')
4446661a
MM
9857
9858 local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
9859 local eth=${dst_mac}${src_mac}86dd${ip}
9860 local packet=${eth}
9861 echo $packet >> expected
9862}
9863
9864ra_test() {
9865 construct_expected_ra $@
9866
9867 for i in hv1 hv2 ; do
9868 OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)])
9869
9870 $PYTHON "$top_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets
9871
9872 cat expected | cut -c -112 > expout
9873 AT_CHECK([cat packets | cut -c -112], [0], [expout])
9874
9875 # Skip ICMPv6 checksum.
9876 cat expected | cut -c 117- > expout
9877 AT_CHECK([cat packets | cut -c 117-], [0], [expout])
9878
9879 rm -f packets
9880 as $i reset_pcap_file $i-vif1 $i/vif1
9881 done
9882
9883 rm -f expected
9884}
9885
9886# Baseline test with no MTU
9887ra_test 0 00 c0 40 aef00000000000000000000000000000
9888
9889# Now make sure an MTU option makes it
9890ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:mtu=1500
9891ra_test 000005dc 00 c0 40 aef00000000000000000000000000000
9892
9893# Now test for multiple network prefixes
9894ovn-nbctl --wait=hv set Logical_Router_port ro-sw networks='aef0\:\:1/64 fd0f\:\:1/48'
9895ra_test 000005dc 00 c0 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9896
9897# Test a different address mode now
9898ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateful
9899ra_test 000005dc 80 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9900
9901# And the other address mode
9902ovn-nbctl --wait=hv set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=dhcpv6_stateless
9903ra_test 000005dc 40 80 40 aef00000000000000000000000000000 30 fd0f0000000000000000000000000000
9904
9905OVN_CLEANUP([hv1],[hv2])
9906AT_CLEANUP
4826add0
LB
9907
9908AT_SETUP([ovn -- ACL reject rule test])
9909AT_KEYWORDS([acl-reject])
9910AT_SKIP_IF([test $HAVE_PYTHON = no])
9911ovn_start
9912
9913# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
9914#
9915# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
9916# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified.
9917# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp destination
9918# unreachable frame generated from ACL rule hit
9919#
9920# INPORT is a lport number, e.g. 11 for vif11.
9921# HV is a hypervisor number
9922# ETH_SRC and ETH_DST are each 12 hex digits.
9923# IPV4_SRC and IPV4_DST are each 8 hex digits.
9924# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
9925test_ip_packet() {
9926 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9927 local exp_ip_chksum=$8 exp_icmp_chksum=$9
9928 shift 9
9929
9930 local ip_ttl=ff
9931 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
9932
9933 local reply_icmp_ttl=ff
9934 local icmp_type_code_response=0301
9935 local icmp_data=00000000
9936 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
9937 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ipv4_dst}${ipv4_src}${reply_icmp_payload}
9938 echo $reply >> vif$inport.expected
9939
9940 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9941}
9942
c319fabc
LB
9943# test_ipv6_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST EXP_ICMP_CHKSUM
9944#
9945# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6 packet with
9946# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST as specified.
9947# EXP_ICMP_CHKSUM is the icmp6 checksums of the icmp6 destination unreachable frame generated from ACL rule hit
9948test_ipv6_packet() {
9949 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 exp_icmp_chksum=$7
9950 shift 7
9951
9952 local ip6_hdr=6000000000083aff${ipv6_src}${ipv6_dst}
9953 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}0000000000000000
9954
9955 local reply=${eth_src}${eth_dst}86dd6000000000303aff${ipv6_dst}${ipv6_src}0101${exp_icmp_chksum}00000000${ip6_hdr}
9956 echo $reply >> vif$inport.expected
9957
9958 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9959}
9960
c20ab6aa
LB
9961# 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
9962#
9963# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
9964# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
9965# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated from ACL rule hit
9966#
9967# INPORT is an lport number, e.g. 11 for vif11.
9968# HV is an hypervisor number
9969# ETH_SRC and ETH_DST are each 12 hex digits.
9970# IPV4_SRC and IPV4_DST are each 8 hex digits.
9971# TCP_SPORT and TCP_DPORT are 4 hex digits.
9972# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
9973test_tcp_syn_packet() {
9974 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_chksum=$7
9975 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
9976 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
9977 shift 12
9978
9979 local ip_ttl=ff
9980 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ipv4_dst}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
9981
9982 local tcp_rst_ttl=ff
9983 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
9984 echo $reply >> vif$inport.expected
9985
9986 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
9987}
9988
4826add0
LB
9989# Create hypervisors hv[123].
9990# Add vif1[123] to hv1, vif2[123] to hv2, vif3[123] to hv3.
9991# Add all of the vifs to a single logical switch sw0.
9992
9993net_add n1
9994ovn-nbctl ls-add sw0
9995for i in 1 2 3; do
9996 sim_add hv$i
9997 as hv$i
9998 ovs-vsctl add-br br-phys
9999 ovn_attach n1 br-phys 192.168.0.$i
10000
10001 for j in 1 2 3; do
10002 ovn-nbctl lsp-add sw0 sw0-p$i$j -- \
10003 lsp-set-addresses sw0-p$i$j "00:00:00:00:00:$i$j 192.168.1.$i$j"
10004
10005 ovs-vsctl -- add-port br-int vif$i$j -- \
10006 set interface vif$i$j \
10007 external-ids:iface-id=sw0-p$i$j \
10008 options:tx_pcap=hv$i/vif$i$j-tx.pcap \
10009 options:rxq_pcap=hv$i/vif$i$j-rx.pcap \
10010 ofport-request=$i$j
10011 done
10012done
10013
10014OVN_POPULATE_ARP
10015# allow some time for ovn-northd and ovn-controller to catch up.
10016sleep 1
10017
10018ip_to_hex() {
10019 printf "%02x%02x%02x%02x" "$@"
10020}
10021
10022for i in 1 2 3; do
10023 : > vif${i}1.expected
10024done
10025
10026ovn-nbctl --log acl-add sw0 to-lport 1000 "outport == \"sw0-p12\"" reject
10027ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p11\"" reject
10028ovn-nbctl --log acl-add sw0 from-lport 1000 "inport == \"sw0-p21\"" reject
732965bc
HZ
10029
10030# Allow some time for ovn-northd and ovn-controller to catch up.
10031ovn-nbctl --timeout=3 --wait=hv sync
4826add0
LB
10032
10033test_ip_packet 11 1 000000000011 000000000021 $(ip_to_hex 192 168 1 11) $(ip_to_hex 192 168 1 21) 0000 7d8d fcfe
10034test_ip_packet 21 2 000000000021 000000000011 $(ip_to_hex 192 168 1 21) $(ip_to_hex 192 168 1 11) 0000 7d8d fcfe
10035test_ip_packet 31 3 000000000031 000000000012 $(ip_to_hex 192 168 1 31) $(ip_to_hex 192 168 1 12) 0000 7d82 fcfe
10036
c319fabc
LB
10037test_ipv6_packet 11 1 000000000011 000000000021 fe80000000000000020001fffe000001 fe80000000000000020001fffe000002 6183
10038
c20ab6aa
LB
10039test_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
10040test_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
10041test_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
10042
4826add0
LB
10043for i in 1 2 3; do
10044 OVN_CHECK_PACKETS([hv$i/vif${i}1-tx.pcap], [vif${i}1.expected])
10045done
10046
10047OVN_CLEANUP([hv1], [hv2], [hv3])
10048AT_CLEANUP
689829d5
HZ
10049
10050AT_SETUP([ovn -- Port Groups])
10051AT_KEYWORDS([ovnpg])
10052AT_SKIP_IF([test $HAVE_PYTHON = no])
10053ovn_start
10054
10055# Logical network:
10056#
10057# Three logical switches ls1, ls2, ls3.
10058# One logical router lr0 connected to ls[123],
10059# with nine subnets, three per logical switch:
10060#
10061# lrp11 on ls1 for subnet 192.168.11.0/24
10062# lrp12 on ls1 for subnet 192.168.12.0/24
10063# lrp13 on ls1 for subnet 192.168.13.0/24
10064# ...
10065# lrp33 on ls3 for subnet 192.168.33.0/24
10066#
10067# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10068# digits are the subnet and the last digit distinguishes the VIF.
10069#
10070# This test will create two port groups and uses them in ACL.
10071
10072get_lsp_uuid () {
10073 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10074}
10075
10076pg1_ports=
10077pg2_ports=
10078for i in 1 2 3; do
10079 ovn-nbctl ls-add ls$i
10080 for j in 1 2 3; do
10081 for k in 1 2 3; do
10082 ovn-nbctl \
10083 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10084 -- lsp-set-addresses lp$i$j$k \
10085 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
689829d5
HZ
10086 # logical ports lp[12]?1 belongs to port group pg1
10087 if test $i != 3 && test $k == 1; then
10088 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10089 fi
10090 # logical ports lp[23]?2 belongs to port group pg2
10091 if test $i != 1 && test $k == 2; then
10092 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10093 fi
10094 done
10095 done
10096done
10097
10098ovn-nbctl lr-add lr0
10099for i in 1 2 3; do
10100 for j in 1 2 3; do
10101 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10102 ovn-nbctl \
10103 -- lsp-add ls$i lrp$i$j-attachment \
10104 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10105 options:router-port=lrp$i$j \
10106 addresses='"00:00:00:00:ff:'$i$j'"'
10107 done
10108done
10109
10110ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
10111ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10112
10113# create ACLs on all lswitches to drop traffic from pg2 to pg1
10114ovn-nbctl acl-add ls1 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10115ovn-nbctl acl-add ls2 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10116ovn-nbctl acl-add ls3 to-lport 1001 'outport == @pg1 && ip4.src == $pg2_ip4' drop
10117
10118# Physical network:
10119#
10120# Three hypervisors hv[123].
10121# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10122# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10123# lp?3[123] all on hv3.
10124
10125# Given the name of a logical port, prints the name of the hypervisor
10126# on which it is located.
10127vif_to_hv() {
10128 case $1 in dnl (
10129 ?11) echo 1 ;; dnl (
10130 ?12 | ?21 | ?22) echo 2 ;; dnl (
10131 ?13 | ?23 | ?3?) echo 3 ;;
10132 esac
10133}
10134
10135# Given the name of a logical port, prints the name of its logical router
10136# port, e.g. "vif_to_lrp 123" yields 12.
10137vif_to_lrp() {
10138 echo ${1%?}
10139}
10140
10141# Given the name of a logical port, prints the name of its logical
10142# switch, e.g. "vif_to_ls 123" yields 1.
10143vif_to_ls() {
10144 echo ${1%??}
10145}
10146
10147net_add n1
10148for i in 1 2 3; do
10149 sim_add hv$i
10150 as hv$i
10151 ovs-vsctl add-br br-phys
10152 ovn_attach n1 br-phys 192.168.0.$i
10153done
10154for i in 1 2 3; do
10155 for j in 1 2 3; do
10156 for k in 1 2 3; do
10157 hv=`vif_to_hv $i$j$k`
10158 as hv$hv ovs-vsctl \
10159 -- add-port br-int vif$i$j$k \
10160 -- set Interface vif$i$j$k \
10161 external-ids:iface-id=lp$i$j$k \
10162 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10163 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10164 ofport-request=$i$j$k
10165 done
10166 done
10167done
10168
10169# Pre-populate the hypervisors' ARP tables so that we don't lose any
10170# packets for ARP resolution (native tunneling doesn't queue packets
10171# for ARP resolution).
10172OVN_POPULATE_ARP
10173
10174# Allow some time for ovn-northd and ovn-controller to catch up.
10175# XXX This should be more systematic.
10176sleep 1
10177
10178# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10179#
10180# This shell function causes a packet to be received on INPORT. The packet's
10181# content has Ethernet destination DST and source SRC (each exactly 12 hex
10182# digits) and Ethernet type ETHTYPE (4 hex digits). The OUTPORTs (zero or
10183# more) list the VIFs on which the packet should be received. INPORT and the
10184# OUTPORTs are specified as logical switch port numbers, e.g. 123 for vif123.
10185for i in 1 2 3; do
10186 for j in 1 2 3; do
10187 for k in 1 2 3; do
10188 : > $i$j$k.expected
10189 done
10190 done
10191done
10192test_ip() {
10193 # This packet has bad checksums but logical L3 routing doesn't check.
10194 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10195 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000
10196 shift; shift; shift; shift; shift
10197 hv=hv`vif_to_hv $inport`
10198 as $hv ovs-appctl netdev-dummy/receive vif$inport $packet
10199 #as $hv ovs-appctl ofproto/trace br-int in_port=$inport $packet
10200 in_ls=`vif_to_ls $inport`
10201 in_lrp=`vif_to_lrp $inport`
10202 for outport; do
10203 out_ls=`vif_to_ls $outport`
10204 if test $in_ls = $out_ls; then
10205 # Ports on the same logical switch receive exactly the same packet.
10206 echo $packet
10207 else
10208 # Routing decrements TTL and updates source and dest MAC
10209 # (and checksum).
10210 out_lrp=`vif_to_lrp $outport`
10211 echo f00000000${outport}00000000ff${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000
10212 fi >> $outport.expected
10213 done
10214}
10215
10216as hv1 ovs-vsctl --columns=name,ofport list interface
10217as hv1 ovn-sbctl list port_binding
10218as hv1 ovn-sbctl list datapath_binding
10219as hv1 ovn-sbctl list port_group
10220as hv1 ovn-sbctl list address_set
10221as hv1 ovn-sbctl dump-flows
10222as hv1 ovs-ofctl dump-flows br-int
10223
10224# Send IP packets between all pairs of source and destination ports,
10225# packets matches ACL (pg2 to pg1) should be dropped
10226ip_to_hex() {
10227 printf "%02x%02x%02x%02x" "$@"
10228}
10229for is in 1 2 3; do
10230 for js in 1 2 3; do
10231 for ks in 1 2 3; do
10232 bcast=
10233 s=$is$js$ks
10234 smac=f00000000$s
10235 sip=`ip_to_hex 192 168 $is$js $ks`
10236 for id in 1 2 3; do
10237 for jd in 1 2 3; do
10238 for kd in 1 2 3; do
10239 d=$id$jd$kd
10240 dip=`ip_to_hex 192 168 $id$jd $kd`
10241 if test $is = $id; then dmac=f00000000$d; else dmac=00000000ff$is$js; fi
10242 if test $d != $s; then unicast=$d; else unicast=; fi
10243
10244 # packets matches ACL should be dropped
10245 if test $id != 3 && test $kd == 1; then
10246 if test $is != 1 && test $ks == 2; then
10247 unicast=
10248 fi
10249 fi
10250 test_ip $s $smac $dmac $sip $dip $unicast #1
10251 done
10252 done
10253 done
10254 done
10255 done
10256done
10257
10258# Allow some time for packet forwarding.
10259# XXX This can be improved.
10260sleep 1
10261
10262# Now check the packets actually received against the ones expected.
10263for i in 1 2 3; do
10264 for j in 1 2 3; do
10265 for k in 1 2 3; do
10266 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10267 [$i$j$k.expected])
10268 done
10269 done
10270done
10271
10272# Gracefully terminate daemons
10273OVN_CLEANUP([hv1], [hv2], [hv3])
10274AT_CLEANUP
1beb60af
HZ
10275
10276AT_SETUP([ovn -- ACLs on Port Groups])
10277AT_KEYWORDS([ovnpg_acl])
10278AT_SKIP_IF([test $HAVE_PYTHON = no])
10279ovn_start
10280
10281# Logical network:
10282#
10283# Three logical switches ls1, ls2, ls3.
10284# One logical router lr0 connected to ls[123],
10285# with nine subnets, three per logical switch:
10286#
10287# lrp11 on ls1 for subnet 192.168.11.0/24
10288# lrp12 on ls1 for subnet 192.168.12.0/24
10289# lrp13 on ls1 for subnet 192.168.13.0/24
10290# ...
10291# lrp33 on ls3 for subnet 192.168.33.0/24
10292#
10293# 27 VIFs, 9 per LS, 3 per subnet: lp[123][123][123], where the first two
10294# digits are the subnet and the last digit distinguishes the VIF.
10295#
10296# This test will create two port groups and ACLs will be applied on them.
10297
10298get_lsp_uuid () {
10299 ovn-nbctl lsp-list ls${1%??} | grep lp$1 | awk '{ print $1 }'
10300}
10301
10302pg1_ports=
10303pg2_ports=
10304for i in 1 2 3; do
10305 ovn-nbctl ls-add ls$i
10306 for j in 1 2 3; do
10307 for k in 1 2 3; do
10308 ovn-nbctl \
10309 -- lsp-add ls$i lp$i$j$k \
4357b6bc
BP
10310 -- lsp-set-addresses lp$i$j$k \
10311 "f0:00:00:00:0$i:$j$k 192.168.$i$j.$k"
1beb60af
HZ
10312 # logical ports lp[12]?1 belongs to port group pg1
10313 if test $i != 3 && test $k == 1; then
10314 pg1_ports="$pg1_ports `get_lsp_uuid $i$j$k`"
10315 fi
10316 # logical ports lp[23]?2 belongs to port group pg2
10317 if test $i != 1 && test $k == 2; then
10318 pg2_ports="$pg2_ports `get_lsp_uuid $i$j$k`"
10319 fi
10320 done
10321 done
10322done
10323
10324ovn-nbctl lr-add lr0
10325for i in 1 2 3; do
10326 for j in 1 2 3; do
10327 ovn-nbctl lrp-add lr0 lrp$i$j 00:00:00:00:ff:$i$j 192.168.$i$j.254/24
10328 ovn-nbctl \
10329 -- lsp-add ls$i lrp$i$j-attachment \
10330 -- set Logical_Switch_Port lrp$i$j-attachment type=router \
10331 options:router-port=lrp$i$j \
10332 addresses='"00:00:00:00:ff:'$i$j'"'
10333 done
10334done
10335
d87e0897 10336ovn-nbctl create Port_Group name=pg1 ports="$pg1_ports"
1beb60af
HZ
10337ovn-nbctl create Port_Group name=pg2 ports="$pg2_ports"
10338
10339# create ACLs on pg1 to drop traffic from pg2 to pg1
d87e0897
HZ
10340ovn-nbctl acl-add pg1 to-lport 1001 'outport == @pg1' drop
10341ovn-nbctl --type=port-group acl-add pg1 to-lport 1002 \
cdc9a84a 10342 'outport == @pg1 && ip4.src == $pg2_ip4' allow-related
1beb60af
HZ
10343
10344# Physical network:
10345#
10346# Three hypervisors hv[123].
10347# lp?1[123] spread across hv[123]: lp?11 on hv1, lp?12 on hv2, lp?13 on hv3.
10348# lp?2[123] spread across hv[23]: lp?21 and lp?22 on hv2, lp?23 on hv3.
10349# lp?3[123] all on hv3.
10350
10351# Given the name of a logical port, prints the name of the hypervisor
10352# on which it is located.
10353vif_to_hv() {
10354 case $1 in dnl (
10355 ?11) echo 1 ;; dnl (
10356 ?12 | ?21 | ?22) echo 2 ;; dnl (
10357 ?13 | ?23 | ?3?) echo 3 ;;
10358 esac
10359}
10360
10361# Given the name of a logical port, prints the name of its logical router
10362# port, e.g. "vif_to_lrp 123" yields 12.
10363vif_to_lrp() {
10364 echo ${1%?}
10365}
10366
10367# Given the name of a logical port, prints the name of its logical
10368# switch, e.g. "vif_to_ls 123" yields 1.
10369vif_to_ls() {
10370 echo ${1%??}
10371}
10372
10373net_add n1
10374for i in 1 2 3; do
10375 sim_add hv$i
10376 as hv$i
10377 ovs-vsctl add-br br-phys
10378 ovn_attach n1 br-phys 192.168.0.$i
10379done
10380for i in 1 2 3; do
10381 for j in 1 2 3; do
10382 for k in 1 2 3; do
10383 hv=`vif_to_hv $i$j$k`
10384 as hv$hv ovs-vsctl \
10385 -- add-port br-int vif$i$j$k \
10386 -- set Interface vif$i$j$k \
10387 external-ids:iface-id=lp$i$j$k \
10388 options:tx_pcap=hv$hv/vif$i$j$k-tx.pcap \
10389 options:rxq_pcap=hv$hv/vif$i$j$k-rx.pcap \
10390 ofport-request=$i$j$k
10391 done
10392 done
10393done
10394
10395# Pre-populate the hypervisors' ARP tables so that we don't lose any
10396# packets for ARP resolution (native tunneling doesn't queue packets
10397# for ARP resolution).
10398OVN_POPULATE_ARP
10399
10400# Allow some time for ovn-northd and ovn-controller to catch up.
10401# XXX This should be more systematic.
10402sleep 1
10403
cdc9a84a
HZ
10404lsp_to_mac() {
10405 echo f0:00:00:00:0${1:0:1}:${1:1:2}
10406}
10407
10408lrp_to_mac() {
10409 echo 00:00:00:00:ff:$1
10410}
10411
10412# test_icmp INPORT SRC_MAC DST_MAC SRC_IP DST_IP ICMP_TYPE OUTPORT...
1beb60af 10413#
cdc9a84a
HZ
10414# This shell function causes a ICMP packet to be received on INPORT.
10415# The OUTPORTs (zero or more) list the VIFs on which the packet should
10416# be received. INPORT and the OUTPORTs are specified as logical switch
10417# port numbers, e.g. 123 for vif123.
1beb60af
HZ
10418for i in 1 2 3; do
10419 for j in 1 2 3; do
10420 for k in 1 2 3; do
10421 : > $i$j$k.expected
10422 done
10423 done
10424done
cdc9a84a
HZ
10425
10426test_icmp() {
10427 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 icmp_type=$6
10428 local packet="inport==\"lp$inport\" && eth.src==$src_mac &&
10429 eth.dst==$dst_mac && ip.ttl==64 && ip4.src==$src_ip
10430 && ip4.dst==$dst_ip && icmp4.type==$icmp_type &&
10431 icmp4.code==0"
10432 shift; shift; shift; shift; shift; shift
1beb60af 10433 hv=hv`vif_to_hv $inport`
cdc9a84a 10434 as $hv ovs-appctl -t ovn-controller inject-pkt "$packet"
1beb60af
HZ
10435 in_ls=`vif_to_ls $inport`
10436 in_lrp=`vif_to_lrp $inport`
10437 for outport; do
10438 out_ls=`vif_to_ls $outport`
10439 if test $in_ls = $out_ls; then
10440 # Ports on the same logical switch receive exactly the same packet.
cdc9a84a 10441 echo $packet | ovstest test-ovn expr-to-packets
1beb60af
HZ
10442 else
10443 # Routing decrements TTL and updates source and dest MAC
10444 # (and checksum).
10445 out_lrp=`vif_to_lrp $outport`
cdc9a84a
HZ
10446 exp_smac=`lrp_to_mac $out_lrp`
10447 exp_dmac=`lsp_to_mac $outport`
10448 exp_packet="eth.src==$exp_smac && eth.dst==$exp_dmac &&
10449 ip.ttl==63 && ip4.src==$src_ip && ip4.dst==$dst_ip &&
10450 icmp4.type==$icmp_type && icmp4.code==0"
10451 echo $exp_packet | ovstest test-ovn expr-to-packets
10452
1beb60af
HZ
10453 fi >> $outport.expected
10454 done
10455}
10456
10457as hv1 ovs-vsctl --columns=name,ofport list interface
10458as hv1 ovn-sbctl list port_binding
10459as hv1 ovn-sbctl list datapath_binding
10460as hv1 ovn-sbctl list port_group
10461as hv1 ovn-sbctl list address_set
10462as hv1 ovn-sbctl dump-flows
10463as hv1 ovs-ofctl dump-flows br-int
10464
10465# Send IP packets between all pairs of source and destination ports,
10466# packets matches ACL1 but not ACL2 should be dropped
10467ip_to_hex() {
10468 printf "%02x%02x%02x%02x" "$@"
10469}
10470for is in 1 2 3; do
10471 for js in 1 2 3; do
10472 for ks in 1 2 3; do
10473 bcast=
10474 s=$is$js$ks
cdc9a84a
HZ
10475 slsp_mac=`lsp_to_mac $s`
10476 slrp_mac=`lrp_to_mac $is$js`
10477 sip=192.168.$is$js.$ks
1beb60af
HZ
10478 for id in 1 2 3; do
10479 for jd in 1 2 3; do
10480 for kd in 1 2 3; do
10481 d=$id$jd$kd
cdc9a84a
HZ
10482 dlsp_mac=`lsp_to_mac $d`
10483 dlrp_mac=`lrp_to_mac $id$jd`
10484 dip=192.168.$id$jd.$kd
10485 if test $is = $id; then dmac=$dlsp_mac; else dmac=$slrp_mac; fi
1beb60af
HZ
10486 if test $d != $s; then unicast=$d; else unicast=; fi
10487
10488 # packets matches ACL1 but not ACL2 should be dropped
10489 if test $id != 3 && test $kd == 1; then
10490 if test $is == 1 || test $ks != 2; then
10491 unicast=
10492 fi
10493 fi
cdc9a84a
HZ
10494 # icmp request (type = 8)
10495 test_icmp $s $slsp_mac $dmac $sip $dip 8 $unicast
10496
10497 # if packets are not dropped, test the return traffic (icmp echo)
10498 # to make sure stateful works, too.
10499 if test x$unicast != x; then
10500 if test $is = $id; then dmac=$slsp_mac; else dmac=$dlrp_mac; fi
10501 # icmp echo (type = 0)
10502 test_icmp $unicast $dlsp_mac $dmac $dip $sip 0 $s
10503 fi
1beb60af
HZ
10504 done
10505 done
10506 done
10507 done
10508 done
10509done
10510
10511# Allow some time for packet forwarding.
10512# XXX This can be improved.
10513sleep 1
10514
10515# Now check the packets actually received against the ones expected.
10516for i in 1 2 3; do
10517 for j in 1 2 3; do
10518 for k in 1 2 3; do
10519 OVN_CHECK_PACKETS([hv`vif_to_hv $i$j$k`/vif$i$j$k-tx.pcap],
10520 [$i$j$k.expected])
10521 done
10522 done
10523done
10524
10525# Gracefully terminate daemons
10526OVN_CLEANUP([hv1], [hv2], [hv3])
10527AT_CLEANUP
55b25947 10528
2342c266
JS
10529AT_SETUP([ovn -- Address Set generation from Port Groups (static addressing)])
10530ovn_start
10531
10532ovn-nbctl ls-add ls1
10533
10534ovn-nbctl lsp-add ls1 lp1
10535ovn-nbctl lsp-add ls1 lp2
10536ovn-nbctl lsp-add ls1 lp3
10537
10538ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 10.0.0.1 2001:db8::1"
10539ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 10.0.0.2 2001:db8::2"
10540ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 10.0.0.3 2001:db8::3"
10541
10542ovn-nbctl create Port_Group name=pg1
10543ovn-nbctl create Port_Group name=pg2
10544
10545ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10546ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10547ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10548ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10549
10550ovn-nbctl --wait=sb sync
10551
10552dnl Check if port group address sets were populated with ports' addresses
10553AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10554 [0], [[["10.0.0.1", "10.0.0.2"]]
10555])
10556AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10557 [0], [[["10.0.0.2", "10.0.0.3"]]
10558])
10559AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10560 [0], [[["2001:db8::1", "2001:db8::2"]]
10561])
10562AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10563 [0], [[["2001:db8::2", "2001:db8::3"]]
10564])
10565
10566ovn-nbctl --wait=sb lsp-set-addresses lp1 \
10567 "02:00:00:00:00:01 10.0.0.11 2001:db8::11"
10568
10569dnl Check if updated address got propagated to the port group address sets
10570AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10571 [0], [[["10.0.0.11", "10.0.0.2"]]
10572])
10573AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10574 [0], [[["2001:db8::11", "2001:db8::2"]]
10575])
10576
10577AT_CLEANUP
10578
984c7d5e
JS
10579AT_SETUP([ovn -- Address Set generation from Port Groups (dynamic addressing)])
10580ovn_start
10581
10582ovn-nbctl ls-add ls1
10583ovn-nbctl ls-add ls2
10584ovn-nbctl ls-add ls3
10585
10586ovn-nbctl set Logical_Switch ls1 \
10587 other_config:subnet=10.1.0.0/24 other_config:ipv6_prefix="2001:db8:1::"
10588ovn-nbctl set Logical_Switch ls2 \
10589 other_config:subnet=10.2.0.0/24 other_config:ipv6_prefix="2001:db8:2::"
10590ovn-nbctl set Logical_Switch ls3 \
10591 other_config:subnet=10.3.0.0/24 other_config:ipv6_prefix="2001:db8:3::"
10592
10593ovn-nbctl lsp-add ls1 lp1
10594ovn-nbctl lsp-add ls2 lp2
10595ovn-nbctl lsp-add ls3 lp3
10596
10597ovn-nbctl lsp-set-addresses lp1 "02:00:00:00:00:01 dynamic"
10598ovn-nbctl lsp-set-addresses lp2 "02:00:00:00:00:02 dynamic"
10599ovn-nbctl lsp-set-addresses lp3 "02:00:00:00:00:03 dynamic"
10600
10601ovn-nbctl create Port_Group name=pg1
10602ovn-nbctl create Port_Group name=pg2
10603
10604ovn-nbctl --id=@p get Logical_Switch_Port lp1 -- add Port_Group pg1 ports @p
10605ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg1 ports @p
10606ovn-nbctl --id=@p get Logical_Switch_Port lp2 -- add Port_Group pg2 ports @p
10607ovn-nbctl --id=@p get Logical_Switch_Port lp3 -- add Port_Group pg2 ports @p
10608
10609ovn-nbctl --wait=sb sync
10610
10611dnl Check if port group address sets were populated with ports' addresses
10612AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
10613 [0], [[["10.1.0.2", "10.2.0.2"]]
10614])
10615AT_CHECK([ovn-sbctl get Address_Set pg2_ip4 addresses],
10616 [0], [[["10.2.0.2", "10.3.0.2"]]
10617])
10618AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
10619 [0], [[["2001:db8:1::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
10620])
10621AT_CHECK([ovn-sbctl get Address_Set pg2_ip6 addresses],
10622 [0], [[["2001:db8:2::ff:fe00:2", "2001:db8:3::ff:fe00:3"]]
10623])
10624
10625ovn-nbctl set Logical_Switch ls1 \
10626 other_config:subnet=10.11.0.0/24 other_config:ipv6_prefix="2001:db8:11::"
10627
10628dnl Check if updated address got propagated to the port group address sets
10629AT_CHECK([ovn-sbctl get Address_Set pg1_ip4 addresses],
451624fe 10630 [0], [[["10.11.0.2", "10.2.0.2"]]
984c7d5e
JS
10631])
10632AT_CHECK([ovn-sbctl get Address_Set pg1_ip6 addresses],
451624fe 10633 [0], [[["2001:db8:11::ff:fe00:1", "2001:db8:2::ff:fe00:2"]]
984c7d5e
JS
10634])
10635
10636AT_CLEANUP
10637
55b25947
NS
10638AT_SETUP([ovn -- ACL conjunction])
10639ovn_start
10640
10641ovn-nbctl ls-add ls1
10642
10643ovn-nbctl lsp-add ls1 ls1-lp1 \
10644-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10645
10646ovn-nbctl lsp-set-port-security ls1-lp1 "f0:00:00:00:00:01 10.0.0.4"
10647
10648ovn-nbctl lsp-add ls1 ls1-lp2 \
10649-- lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10650
10651ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.6"
10652
10653net_add n1
10654sim_add hv1
10655
10656as hv1
10657ovs-vsctl add-br br-phys
10658ovn_attach n1 br-phys 192.168.0.1
10659ovs-vsctl -- add-port br-int hv1-vif1 -- \
10660 set interface hv1-vif1 external-ids:iface-id=ls1-lp1 \
10661 options:tx_pcap=hv1/vif1-tx.pcap \
10662 options:rxq_pcap=hv1/vif1-rx.pcap \
10663 ofport-request=1
10664
10665ovs-vsctl -- add-port br-int hv1-vif2 -- \
10666 set interface hv1-vif2 external-ids:iface-id=ls1-lp2 \
10667 options:tx_pcap=hv1/vif2-tx.pcap \
10668 options:rxq_pcap=hv1/vif2-rx.pcap \
10669 ofport-request=2
10670
10671ovn-nbctl create Address_Set name=set1 \
10672addresses=\"10.0.0.4\",\"10.0.0.5\",\"10.0.0.6\"
10673ovn-nbctl create Address_Set name=set2 \
10674addresses=\"10.0.0.7\",\"10.0.0.8\",\"10.0.0.9\"
10675ovn-nbctl acl-add ls1 to-lport 1002 \
10676'ip4 && ip4.src == $set1 && ip4.dst == $set1' allow
10677ovn-nbctl acl-add ls1 to-lport 1001 \
10678'ip4 && ip4.src == $set1 && ip4.dst == $set2' drop
10679
10680# test_ip INPORT SRC_MAC DST_MAC SRC_IP DST_IP OUTPORT...
10681#
10682# This shell function causes an ip packet to be received on INPORT.
10683# The packet's content has Ethernet destination DST and source SRC
10684# (each exactly 12 hex digits) and Ethernet type ETHTYPE (4 hex digits).
10685# The OUTPORTs (zero or more) list the VIFs on which the packet should
10686# be received. INPORT and the OUTPORTs are specified as logical switch
10687# port numbers, e.g. 11 for vif11.
10688test_ip() {
10689 # This packet has bad checksums but logical L3 routing doesn't check.
10690 local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5
10691 local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}\
10692${dst_ip}0035111100080000
10693 shift; shift; shift; shift; shift
10694 as hv1 ovs-appctl netdev-dummy/receive hv1-vif1 $packet
10695 for outport; do
10696 echo $packet >> $outport.expected
10697 done
10698}
10699
10700ip_to_hex() {
10701 printf "%02x%02x%02x%02x" "$@"
10702}
10703
10704reset_pcap_file() {
10705 local iface=$1
10706 local pcap_file=$2
10707 ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \
10708options:rxq_pcap=dummy-rx.pcap
10709 rm -f ${pcap_file}*.pcap
10710 ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \
10711options:rxq_pcap=${pcap_file}-rx.pcap
10712}
10713
10714
10715sip=`ip_to_hex 10 0 0 4`
10716dip=`ip_to_hex 10 0 0 6`
10717
10718test_ip 1 f00000000001 f00000000002 $sip $dip 2
10719
10720cat 2.expected > expout
10721$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10722AT_CHECK([cat 2.packets], [0], [expout])
10723
10724# There should be total of 12 flows present with conjunction action and 2 flows
10725# with conj match. Eg.
10726# table=44, priority=2002,conj_id=2,metadata=0x1 actions=resubmit(,45)
10727# table=44, priority=2001,conj_id=3,metadata=0x1 actions=drop
10728# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.6 actions=conjunction(2,2/2)
10729# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.4 actions=conjunction(2,2/2)
10730# priority=2002,ip,metadata=0x1,nw_dst=10.0.0.5 actions=conjunction(2,2/2)
10731# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.7 actions=conjunction(3,2/2)
10732# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.9 actions=conjunction(3,2/2)
10733# priority=2001,ip,metadata=0x1,nw_dst=10.0.0.8 actions=conjunction(3,2/2)
10734# priority=2002,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(2,1/2)
10735# priority=2002,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(2,1/2)
10736# priority=2002,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(2,1/2)
10737# priority=2001,ip,metadata=0x1,nw_src=10.0.0.6 actions=conjunction(3,1/2)
10738# priority=2001,ip,metadata=0x1,nw_src=10.0.0.4 actions=conjunction(3,1/2)
10739# priority=2001,ip,metadata=0x1,nw_src=10.0.0.5 actions=conjunction(3,1/2)
10740
10741OVS_WAIT_UNTIL([test 12 = `as hv1 ovs-ofctl dump-flows br-int | \
10742grep conjunction | wc -l`])
10743OVS_WAIT_UNTIL([test 2 = `as hv1 ovs-ofctl dump-flows br-int | \
10744grep conj_id | wc -l`])
10745
10746as hv1 ovs-ofctl dump-flows br-int
10747
10748# Set the ip address for ls1-lp2 from set2 so that the drop ACL flow is hit.
10749ovn-nbctl lsp-set-addresses ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10750ovn-nbctl lsp-set-port-security ls1-lp2 "f0:00:00:00:00:02 10.0.0.7 20.0.0.4"
10751
10752reset_pcap_file hv1-vif2 hv1/vif2
10753
10754rm -f 2.packets
10755
10756sip=`ip_to_hex 10 0 0 4`
10757dip=`ip_to_hex 10 0 0 7`
10758
10759test_ip 1 f00000000001 f00000000002 $sip $dip
10760$PYTHON "$top_srcdir/utilities/ovs-pcap.in" hv1/vif2-tx.pcap > 2.packets
10761AT_CHECK([cat 2.packets], [0], [])
10762
10763AT_CLEANUP
0e2751ed
LB
10764
10765AT_SETUP([ovn -- TTL exceeded])
10766AT_KEYWORDS([ttl-exceeded])
10767AT_SKIP_IF([test $HAVE_PYTHON = no])
10768ovn_start
10769
10770# test_ip_packet INPORT HV ETH_SRC ETH_DST IPV4_SRC IPV4_DST IPV4_ROUTER IP_CHKSUM EXP_IP_CHKSUM EXP_ICMP_CHKSUM
10771#
10772# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10773# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_DST, IP_CHKSUM as specified and TTL set to 1.
10774# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp time exceeded frame
10775# generated by OVN logical router
10776#
10777# INPORT is a lport number, e.g. 11 for vif11.
10778# HV is a hypervisor number
10779# ETH_SRC and ETH_DST are each 12 hex digits.
10780# IPV4_SRC, IPV4_DST and IPV4_ROUTER are each 8 hex digits.
10781# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10782test_ip_packet() {
10783 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ipv4_dst=$6 ip_router=$7 ip_chksum=$8
10784 local exp_ip_chksum=$9 exp_icmp_chksum=${10}
10785 shift 10
10786
10787 local ip_ttl=01
10788 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}01${ip_chksum}${ipv4_src}${ipv4_dst}
10789
10790 local reply_icmp_ttl=fe
10791 local icmp_type_code_response=0b00
10792 local icmp_data=00000000
10793 local reply_icmp_payload=${icmp_type_code_response}${exp_icmp_chksum}${icmp_data}
10794 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10795 echo $reply >> vif$inport.expected
10796
10797 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10798}
10799
e6a84e1e
LB
10800# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_ROUTER EXP_ICMP_CHKSUM
10801#
10802# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10803# packet with ETH_SRC, ETH_DST, IPV6_SRC and IPV6_DST as specified.
10804# IPV6_ROUTER and EXP_ICMP_CHKSUM are the source IP and checksum of the icmpv6 ttl exceeded
10805# packet sent by OVN logical router
10806test_ip6_packet() {
10807 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_dst=$6 ipv6_router=$7 exp_icmp_chksum=$8
10808 shift 8
10809
10810 local ip6_hdr=6000000000151101${ipv6_src}${ipv6_dst}
10811 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}dbb8303900155bac6b646f65206676676e6d66720a
10812
10813 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_router}${ipv6_src}0300${exp_icmp_chksum}00000000${ip6_hdr}
10814 echo $reply >> vif$inport.expected
10815
10816 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10817}
10818
0e2751ed
LB
10819ip_to_hex() {
10820 printf "%02x%02x%02x%02x" "$@"
10821}
10822
10823for i in 1 2; do
10824 net_add n$i
10825 ovn-nbctl ls-add sw$i
10826
10827 sim_add hv$i
10828 as hv$i
10829 ovs-vsctl add-br br-phys
10830 ovn_attach n$i br-phys 192.168.$i.1
10831
10832 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
e6a84e1e 10833 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
10834
10835 ovs-vsctl -- add-port br-int vif$i -- \
10836 set interface vif$i \
10837 external-ids:iface-id=sw$i-p${i}0 \
10838 options:tx_pcap=hv$i/vif$i-tx.pcap \
10839 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10840 ofport-request=$i
10841done
10842
10843ovn-nbctl lr-add lr0
10844for i in 1 2; do
e6a84e1e 10845 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
10846 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10847 -- set Logical_Switch_Port lrp$i-attachment type=router \
e6a84e1e 10848 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
0e2751ed
LB
10849done
10850
10851OVN_POPULATE_ARP
10852# allow some time for ovn-northd and ovn-controller to catch up.
10853ovn-nbctl --wait=hv sync
10854
10855test_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 10856test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000200000000000000000011 20010db8000100000000000000000001 d461
0e2751ed
LB
10857OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
10858
10859OVN_CLEANUP([hv1], [hv2])
10860AT_CLEANUP
86558ac2
LB
10861
10862AT_SETUP([ovn -- router port unreachable])
10863AT_KEYWORDS([router-port-unreachable])
10864AT_SKIP_IF([test $HAVE_PYTHON = no])
10865ovn_start
10866
10867# 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
10868#
10869# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv4 packet with
10870# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, L4_PROTCOL, IP_CHKSUM as specified.
10871# EXP_IP_CHKSUM and EXP_ICMP_CHKSUM are the ip and icmp checksums of the icmp frame generated by OVN logical router
10872# EXP_ICMP_CODE are code and type of the icmp frame generated by OVN logical router
10873#
10874# INPORT is a lport number, e.g. 11 for vif11.
10875# HV is a hypervisor number
10876# ETH_SRC and ETH_DST are each 12 hex digits.
10877# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10878# IP_CHKSUM, EXP_IP_CHSUM and EXP_ICMP_CHKSUM are each 4 hex digits
10879test_ip_packet() {
10880 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 l4_proto=$7 ip_chksum=$8
10881 local exp_ip_chksum=$9 exp_icmp_chksum=${10} exp_icmp_code=${11}
10882 shift 11
10883
10884 local ip_ttl=ff
10885 local packet=${eth_dst}${eth_src}08004500001400004000${ip_ttl}${l4_proto}${ip_chksum}${ipv4_src}${ip_router}
10886
10887 local reply_icmp_ttl=fe
10888 local icmp_data=00000000
10889 local reply_icmp_payload=${exp_icmp_code}${exp_icmp_chksum}${icmp_data}
10890 local reply=${eth_src}${eth_dst}08004500001c00004000${reply_icmp_ttl}01${exp_ip_chksum}${ip_router}${ipv4_src}${reply_icmp_payload}
10891 echo $reply >> vif$inport.expected
10892
10893 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10894}
10895
159932c9
LB
10896# 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
10897#
10898# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an TCP syn segment with
10899# ETH_SRC, ETH_DST, IPV4_SRC, IPV4_ROUTER, IP_CHKSUM, TCP_SPORT, TCP_DPORT, TCP_CHKSUM as specified.
10900# EXP_IP_CHKSUM and EXP_TCP_RST_CHKSUM are the ip and tcp checksums of the tcp reset segment generated by OVN logical router
10901#
10902# INPORT is an lport number, e.g. 11 for vif11.
10903# HV is an hypervisor number
10904# ETH_SRC and ETH_DST are each 12 hex digits.
10905# IPV4_SRC and IPV4_ROUTER are each 8 hex digits.
10906# TCP_SPORT and TCP_DPORT are 4 hex digits.
10907# IP_CHKSUM, TCP_CHKSUM, EXP_IP_CHSUM and EXP_TCP_RST_CHKSUM are each 4 hex digits
10908test_tcp_syn_packet() {
10909 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv4_src=$5 ip_router=$6 ip_chksum=$7
10910 local tcp_sport=$8 tcp_dport=$9 tcp_chksum=${10}
10911 local exp_ip_chksum=${11} exp_tcp_rst_chksum=${12}
10912 shift 12
10913
10914 local ip_ttl=ff
10915 local packet=${eth_dst}${eth_src}08004500002800004000${ip_ttl}06${ip_chksum}${ipv4_src}${ip_router}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10916
10917 local tcp_rst_ttl=fe
10918 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
10919 echo $reply >> vif$inport.expected
10920
10921 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10922}
10923
98af55fc
LB
10924# test_tcp6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_ROUTER TCP_SPORT TCP_DPORT TCP_CHKSUM EXP_TCP_RST_CHKSUM
10925#
10926# Causes a packet to be received on INPORT of the hypervisor HV. The packet is a TCP syn segment with
10927# ETH_SRC, ETH_DST, IPV6_SRC, IPV6_ROUTER, TCP_SPORT, TCP_DPORT and TCP_CHKSUM as specified.
10928# EXP_TCP_RST_CHKSUM is the tcp checksums of the tcp reset segment generated by OVN logical router
10929test_tcp6_packet() {
10930 local inport=$1 hv=$2 eth_src=$3 eth_dst=$4 ipv6_src=$5 ipv6_router=$6
10931 local tcp_sport=$7 tcp_dport=$8 tcp_chksum=$9
10932 local exp_tcp_rst_chksum=${10}
10933 shift 10
10934
10935 local ip6_hdr=60000000001406ff${ipv6_src}${ipv6_router}
10936 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${tcp_sport}${tcp_dport}000000010000000050027210${tcp_chksum}0000
10937
10938 local reply=${eth_src}${eth_dst}86dd60000000001406fe${ipv6_router}${ipv6_src}${tcp_dport}${tcp_sport}000000000000000150040000${exp_tcp_rst_chksum}0000
10939 echo $reply >> vif$inport.expected
10940
10941 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10942}
10943
4c25c3b8
LB
10944# test_ip6_packet INPORT HV ETH_SRC ETH_DST IPV6_SRC IPV6_DST IPV6_PROTO IPV6_LEN DATA EXP_ICMP_CODE EXP_ICMP_CHKSUM
10945#
10946# Causes a packet to be received on INPORT of the hypervisor HV. The packet is an IPv6
10947# packet with ETH_SRC, ETH_DST, IPV6_SRC, IPV6_DST, IPV6_PROTO, IPV6_LEN and DATA as specified.
10948# EXP_ICMP_CODE and EXP_ICMP_CHKSUM are the code and checksum of the icmp6 packet sent by OVN logical router
10949test_ip6_packet() {
10950 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
10951 local exp_icmp_code=${10} exp_icmp_chksum=${11}
10952 shift 11
10953
10954 local ip6_hdr=60000000${ipv6_len}${ipv6_proto}ff${ipv6_src}${ipv6_dst}
10955 local packet=${eth_dst}${eth_src}86dd${ip6_hdr}${data}
10956
10957 local reply=${eth_src}${eth_dst}86dd6000000000303afe${ipv6_dst}${ipv6_src}${exp_icmp_code}${exp_icmp_chksum}00000000${ip6_hdr}
10958 echo $reply >> vif$inport.expected
10959
10960 as hv$hv ovs-appctl netdev-dummy/receive vif$inport $packet
10961}
10962
86558ac2
LB
10963ip_to_hex() {
10964 printf "%02x%02x%02x%02x" "$@"
10965}
10966
10967for i in 1 2; do
10968 net_add n$i
10969 ovn-nbctl ls-add sw$i
10970
10971 sim_add hv$i
10972 as hv$i
10973 ovs-vsctl add-br br-phys
10974 ovn_attach n$i br-phys 192.168.$i.1
10975
10976 ovn-nbctl lsp-add sw$i sw$i-p${i}0 -- \
4c25c3b8 10977 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
10978
10979 ovs-vsctl -- add-port br-int vif$i -- \
10980 set interface vif$i \
10981 external-ids:iface-id=sw$i-p${i}0 \
10982 options:tx_pcap=hv$i/vif$i-tx.pcap \
10983 options:rxq_pcap=hv$i/vif$i-rx.pcap \
10984 ofport-request=$i
10985done
10986
10987ovn-nbctl lr-add lr0
10988for i in 1 2; do
4c25c3b8 10989 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
10990 ovn-nbctl -- lsp-add sw$i lrp$i-attachment \
10991 -- set Logical_Switch_Port lrp$i-attachment type=router \
4c25c3b8 10992 options:router-port=lrp$i addresses='"00:00:00:00:ff:0'$i' 192.168.'$i'.254 2001:db8:'$i'::1"'
86558ac2
LB
10993done
10994
10995OVN_POPULATE_ARP
10996# allow some time for ovn-northd and ovn-controller to catch up.
10997ovn-nbctl --wait=hv sync
10998
10999test_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 11000test_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 11001test_ip6_packet 1 1 000000000001 00000000ff01 20010db8000100000000000000000011 20010db8000100000000000000000001 11 0015 dbb8303900155bac6b646f65206676676e6d66720a 0104 d570
86558ac2
LB
11002OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [vif1.expected])
11003
159932c9 11004test_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 11005test_ip6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 84 0004 01020304 0103 627e
98af55fc 11006test_tcp6_packet 2 2 000000000002 00000000ff02 20010db8000200000000000000000011 20010db8000200000000000000000001 8b40 3039 0000 4486
159932c9
LB
11007OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [vif2.expected])
11008
86558ac2
LB
11009OVN_CLEANUP([hv1], [hv2])
11010AT_CLEANUP
96ea0ecb
MM
11011
11012AT_SETUP([ovn -- ovn-controller exit])
11013AT_SKIP_IF([test $HAVE_PYTHON = no])
11014ovn_start
11015# Logical network:
11016# One Logical Router: ro, with two logical switches sw1 and sw2.
11017# sw1 is for subnet 10.0.0.0/8
11018# sw2 is for subnet 20.0.0.0/8
11019# sw1 has a single port bound on hv1
11020# sw2 has a single port bound on hv2
11021
11022ovn-nbctl lr-add ro
11023ovn-nbctl ls-add sw1
11024ovn-nbctl ls-add sw2
11025
11026sw1_ro_mac=00:00:10:00:00:01
11027sw1_ro_ip=10.0.0.1
11028sw2_ro_mac=00:00:20:00:00:01
11029sw2_ro_ip=20.0.0.1
11030sw1_p1_mac=00:00:10:00:00:02
11031sw1_p1_ip=10.0.0.2
11032sw2_p1_mac=00:00:20:00:00:02
11033sw2_p1_ip=20.0.0.2
11034
11035ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11036ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11037ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11038 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11039ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11040 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11041
11042ovn-nbctl lsp-add sw1 sw1-p1 \
11043-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11044
11045ovn-nbctl lsp-add sw2 sw2-p1 \
11046-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11047
11048net_add n1
11049
11050sim_add hv1
11051as hv1
11052ovs-vsctl add-br br-phys
11053ovn_attach n1 br-phys 192.168.0.1
11054ovs-vsctl -- add-port br-int hv1-vif1 -- \
11055 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11056 options:tx_pcap=hv1/vif1-tx.pcap \
11057 options:rxq_pcap=hv1/vif1-rx.pcap \
11058 ofport-request=1
11059
11060sim_add hv2
11061as hv2
11062ovs-vsctl add-br br-phys
11063ovn_attach n1 br-phys 192.168.0.2
11064ovs-vsctl -- add-port br-int hv2-vif1 -- \
11065 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11066 options:tx_pcap=hv2/vif1-tx.pcap \
11067 options:rxq_pcap=hv2/vif1-rx.pcap \
11068 ofport-request=1
11069
11070OVN_POPULATE_ARP
11071
11072sleep 1
11073
11074packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11075 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11076 udp && udp.src==53 && udp.dst==4369"
11077
11078# Start by Sending the packet and make sure it makes it there as expected
11079as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11080
11081# Expected packet has TTL decreased by 1
11082expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11083 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11084 udp && udp.src==53 && udp.dst==4369"
11085echo $expected | ovstest test-ovn expr-to-packets > expected
11086
11087OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11088
11089# Stop ovn-controller on hv2
11090as hv2 ovs-appctl -t ovn-controller exit
11091
11092# Now send the packet again. This time, it should not arrive.
11093as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11094
11095OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11096
11097# Start ovn-controller again just so OVN_CLEANUP doesn't complain
11098as hv2 start_daemon ovn-controller
11099
11100OVN_CLEANUP([hv1],[hv2])
11101AT_CLEANUP
11102
11103AT_SETUP([ovn -- ovn-controller restart])
11104AT_SKIP_IF([test $HAVE_PYTHON = no])
11105ovn_start
11106
11107# Logical network:
11108# One Logical Router: ro, with two logical switches sw1 and sw2.
11109# sw1 is for subnet 10.0.0.0/8
11110# sw2 is for subnet 20.0.0.0/8
11111# sw1 has a single port bound on hv1
11112# sw2 has a single port bound on hv2
11113
11114ovn-nbctl lr-add ro
11115ovn-nbctl ls-add sw1
11116ovn-nbctl ls-add sw2
11117
11118sw1_ro_mac=00:00:10:00:00:01
11119sw1_ro_ip=10.0.0.1
11120sw2_ro_mac=00:00:20:00:00:01
11121sw2_ro_ip=20.0.0.1
11122sw1_p1_mac=00:00:10:00:00:02
11123sw1_p1_ip=10.0.0.2
11124sw2_p1_mac=00:00:20:00:00:02
11125sw2_p1_ip=20.0.0.2
11126
11127ovn-nbctl lrp-add ro ro-sw1 $sw1_ro_mac ${sw1_ro_ip}/8
11128ovn-nbctl lrp-add ro ro-sw2 $sw2_ro_mac ${sw2_ro_ip}/8
11129ovn-nbctl lsp-add sw1 sw1-ro -- set Logical_Switch_Port sw1-ro type=router \
11130 options:router-port=ro-sw1 addresses=\"$sw1_ro_mac\"
11131ovn-nbctl lsp-add sw2 sw2-ro -- set Logical_Switch_Port sw2-ro type=router \
11132 options:router-port=ro-sw2 addresses=\"$sw2_ro_mac\"
11133
11134ovn-nbctl lsp-add sw1 sw1-p1 \
11135-- lsp-set-addresses sw1-p1 "$sw1_p1_mac $sw1_p1_ip"
11136
11137ovn-nbctl lsp-add sw2 sw2-p1 \
11138-- lsp-set-addresses sw2-p1 "$sw2_p1_mac $sw2_p1_ip"
11139
11140net_add n1
11141
11142sim_add hv1
11143as hv1
11144ovs-vsctl add-br br-phys
11145ovn_attach n1 br-phys 192.168.0.1
11146ovs-vsctl -- add-port br-int hv1-vif1 -- \
11147 set interface hv1-vif1 external-ids:iface-id=sw1-p1 \
11148 options:tx_pcap=hv1/vif1-tx.pcap \
11149 options:rxq_pcap=hv1/vif1-rx.pcap \
11150 ofport-request=1
11151
11152sim_add hv2
11153as hv2
11154ovs-vsctl add-br br-phys
11155ovn_attach n1 br-phys 192.168.0.2
11156ovs-vsctl -- add-port br-int hv2-vif1 -- \
11157 set interface hv2-vif1 external-ids:iface-id=sw2-p1 \
11158 options:tx_pcap=hv2/vif1-tx.pcap \
11159 options:rxq_pcap=hv2/vif1-rx.pcap \
11160 ofport-request=1
11161
11162OVN_POPULATE_ARP
11163
11164sleep 1
11165
11166packet="inport==\"sw1-p1\" && eth.src==$sw1_p1_mac && eth.dst==$sw1_ro_mac &&
11167 ip4 && ip.ttl==64 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11168 udp && udp.src==53 && udp.dst==4369"
11169
11170# Start by Sending the packet and make sure it makes it there as expected
11171as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11172
11173# Expected packet has TTL decreased by 1
11174expected="eth.src==$sw2_ro_mac && eth.dst==$sw2_p1_mac &&
11175 ip4 && ip.ttl==63 && ip4.src==$sw1_p1_ip && ip4.dst==$sw2_p1_ip &&
11176 udp && udp.src==53 && udp.dst==4369"
11177echo $expected | ovstest test-ovn expr-to-packets > expected
11178
11179OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
11180
11181# Stop ovn-controller on hv2 with --restart flag
11182as hv2 ovs-appctl -t ovn-controller exit --restart
11183
11184# Now send the packet again. This time, it should still arrive
11185as hv1 ovs-appctl -t ovn-controller inject-pkt "$packet"
11186
11187cat expected expected > expected2
11188
11189OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected2])
11190
11191# Start ovn-controller again just so OVN_CLEANUP doesn't complain
11192as hv2 start_daemon ovn-controller
11193
11194OVN_CLEANUP([hv1],[hv2])
11195
11196AT_CLEANUP